// ========== Copyright Header Begin ========================================== // // OpenSPARC T2 Processor File: niu_mac_reset.vr // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved // 4150 Network Circle, Santa Clara, California 95054, U.S.A. // // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // For the avoidance of doubt, and except that if any non-GPL license // choice is available it will apply instead, Sun elects to use only // the General Public License version 2 (GPLv2) at this time for any // software where a choice of GPL license versions is made // available with the language indicating that GPLv2 or any later version // may be used, or where a choice of which version of the GPL is applied is // otherwise unspecified. // // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, // CA 95054 USA or visit www.sun.com if you need additional information or // have any questions. // // ========== Copyright Header End ============================================ #include #include "mac_defines.vri" #include "pio_driver.vrh" #include "mac_pio_class.vrh" #include "xmac_util.vrh" #include "bmac_util.vrh" #include "pcs_util.vrh" #include "xpcs_util.vrh" #include "pktConfig.vrh" #include "mac_init_class.vrh" #include "pkt_configurator.vrh" extern mac_util_class mac_util; extern bmac_util_class bmac_util; extern pcs_util_class pcs_util; extern xpcs_util_class xpcs_util; extern pio_drv pio_driver_class; extern mac_pio_cl mac_pio_class; extern mac_init_class mac_init; extern bit[3:0] rtl_mac; class niu_mac_reset_class { bit keep_resetting = 0; string name = "niu_mac_reset_class"; integer time_out = 0; bit [31:0] XMAC_CONFIG_reinit_values; bit [31:0] RxMAC_CONFIG_reinit_values; bit [31:0] TxMAC_CONFIG_reinit_values; integer max_mac_DAs; pkt_configurator pkt_cfgrator; task mac_reset_periodically(integer interval = 20000); task mac_warm_reset_rx(bit[1:0] mac_id); task mac_warm_reset_tx(bit[1:0] mac_id); task new(pkt_configurator pkt_cfgrator_in = null) { pkt_cfgrator = pkt_cfgrator_in; } } task niu_mac_reset_class::mac_warm_reset_rx(bit[1:0] mac_id) { bit [31:0] rd_data; bit [31:0] bmac_rd_data; bit[39:0] base_addr; bit[47:0] mac_addr; integer ii, tbl_num; integer timeout_iterations = 10; integer timeout_cnt = 0; bit mpr; /* The following information is extracted from MAC PRM version 4.9 22.11 MAC Warm Reset Sequence To apply MAC Warm Reset, Software should perform MAC Stop Sequence first followed by Software Reset sequence second. ################################## # MAC Stop Sequence ################################## =====> Transmit xMAC Stop Sequence Program XMAC_CONFIG register (FZC_MAC+00060) bit 0 (tx_enable) to ?0?. Software should wait for one max_pkt_size time for xMAC to stop gracefully. Use xtlm_state== 0 in xMAC State Machines Register (FZC_MAC+0x001A8) as stop_done indicator. =====> Receive xMAC Stop Sequence Program XMAC_CONFIG register (FZC_MAC+00060) bit 8 (rx_enable) to ?0?. Software should wait for one max_pkt_size time for xMAC to stop gracefully. Use xrlm_state== 0 in xMAC State Machines Register (FZC_MAC+0x001A8) as stop_done indicator. -----> Transmit bMAC Stop Sequence Program TxMAC_CONFIG register (FZC_MAC+0C060) bit 0 (tx_enable) to ?0?. Software should wait for one max_pkt_size time for bMAC to stop gracefully. Use tlm_state== 0 in bMAC State Machines Register (FZC_MAC+0x0C3A0) as stop_done indicator. -----> Receive bMAC Stop Sequence Program RxMAC_CONFIG register (FZC_MAC+0C068) bit 0 (rx_enable) to ?0?. Software should wait for one max_pkt_size time for bMAC to stop gracefully. Use rlm_state== 0 in bMAC State Machines Register (FZC_MAC+0x0C3A0) as stop_done indicator. ################################ # MAC Software Reset Sequence ################################ =====> Transmit xMAC Software Reset Sequence Software should write ?1? to bit 0 (TxMacSoftRst) and bit 1 (TxMacRegRst) in register XTxMAC_SW_RST (FZC_MAC+00000). Use TxMacSoftRst==0 and TxMacRegRst==0 as reset_done indicator. =====> Receive xMAC Software Reset Sequencef Software should write ?1? to bit 0 (RxMacSoftRst) and bit 1 (RxMacRegRst) in register XRxMAC_SW_RST (FZC_MAC+00008). Use RxMacSoftRst==0 and RxMacRegRst==0 as reset_done indicator. -----> Transmit bMAC Software Reset Sequence Software should write ?1? to bit 0 (txmac_sw_rst) in register BTxMAC_SW_RST (FZC_MAC+0C000). Use txmac_sw_rst==0 as reset_done indicator. -----> Receive bMAC Software Reset Sequence Software should write ?1? to bit 0 (rxmac_sw_rst) in register BRxMAC_SW_RST (FZC_MAC+0C008). Use rxmac_sw_rst==0 as reset_done indicator. */ printf("<%0d> niu_mac_reset_class::mac_warm_reset_rx mac_id:%0d \n", get_time(LO), mac_id); if(mac_id == 0 | mac_id == 1) max_mac_DAs = 16; else max_mac_DAs = 8; base_addr = bmac_util.get_mac_reg_base(mac_id); if ( (mac_id ==0 | mac_id == 1) && rtl_mac[mac_id]) { // STEP 1 // Receive xMAC Stop Sequence mac_pio_class.xmac_pio_rd( base_addr + XMAC_CONFIG, rd_data,1'b0 ); XMAC_CONFIG_reinit_values = rd_data; rd_data[8] = 0; // RxMacEnable mac_pio_class.xmac_pio_wr( base_addr + XMAC_CONFIG, rd_data); printf ("niu_mac_reset_class::mac_warm_reset_rx XMAC_CONFIG(addr=0x%h) for Port %0d after disabling rx bits = 0x%h\n", base_addr + XMAC_CONFIG, mac_id, rd_data); // STEP 2 // wait for one max_pkt_size time for xMAC to stop gracefully repeat (3000) @(posedge CLOCK); // STEP 3 // poll state machine register rd_data[7] = 1; // xrlm_state while(rd_data[7] !== 0) { repeat (100) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + XMAC_SM_REG, rd_data,1'b0 ); printf ("niu_mac_reset_class::mac_warm_reset_rx max=%0d XMAC_SM_REG=0x%h time=%0d\n", mac_id, rd_data, get_time(LO)); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> %s ERROR timeout for XMAC_SM_REG:xrlm_state[bit 7] to go 0 rd_data:%h\n", get_time(LO), name, rd_data); } } // STEP 4 // Receive xMAC Software Reset Sequence mac_pio_class.xmac_pio_rd( base_addr + XRxMAC_SW_RST, rd_data,1'b0 ); rd_data[0] = 1; // RxMacSoftRst rd_data[1] = 1; // RxMacRegRst mac_pio_class.xmac_pio_wr( base_addr + XRxMAC_SW_RST, rd_data); // STEP 5 // poll RxMacSoftRst and RxMacRegRst done rd_data[0] = 1; rd_data[1] = 1; timeout_cnt = 0; while(rd_data[0] !== 0 | rd_data[1] !== 0) { repeat (100) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + XRxMAC_SW_RST, rd_data,1'b0 ); printf ("niu_mac_reset_class::mac_warm_reset_rx max=%0d XRxMAC_SW_RST=0x%h time=%0d to_cnt=%0d\n", mac_id, rd_data, get_time(LO), timeout_cnt); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> %s ERROR timeout for XTxMAC_SW_RST:rx_reset[bit 0,1] to go 0 rd_data:%h\n", get_time(LO), name, rd_data); } } } else if ( (mac_id ==2 | mac_id == 3) && rtl_mac[mac_id]) { // STEP 1 // Receive bMAC Stop Sequence mac_pio_class.bmac_pio_rd(base_addr + RxMAC_CONFIG, bmac_rd_data, 0); RxMAC_CONFIG_reinit_values = bmac_rd_data; bmac_rd_data[0] = 0; // rx_enable = 0 mac_pio_class.bmac_pio_wr(base_addr + RxMAC_CONFIG, bmac_rd_data); // STEP 2 // wait for one max_pkt_size time for bMAC to stop gracefully repeat(30000) @(posedge CLOCK); // STEP 3 // Use rlm_state== 0 in bMAC State Machines Register (FZC_MAC+0x0C3A0) as stop_done indicator. // poll rlm_state bits 26:23 bmac_rd_data[26:23] = 4'b1111; while(bmac_rd_data[26:23] !== 0) { repeat (1000) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + BMAC_SM_REG, bmac_rd_data,1'b0 ); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> niu_mac_reset_class::mac_warm_reset_rx ERROR timeout in BMAC_SM_REG bits 26:23 rd_data:%h\n", get_time(LO), bmac_rd_data); } } // STEP 4 // Receive bMAC Software Reset Sequence mac_pio_class.bmac_pio_rd(base_addr + BRxMAC_SW_RST, bmac_rd_data, 0); bmac_rd_data[0] = 1; // rxmac_sw_rst = 1 mac_pio_class.bmac_pio_wr(base_addr + BRxMAC_SW_RST, bmac_rd_data); // STEP 5 // poll reset done while(bmac_rd_data[0] !== 0) { repeat (100) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + BRxMAC_SW_RST, bmac_rd_data,1'b0 ); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> %s : ERROR : timeout waiting for BRxMAC_SW_RST:rx_reset[bit 0] to go 0 rd_data:%h\n", get_time(LO), name, bmac_rd_data); } } } // mac_init.init_mac(); //for(mac_id = 0; mac_id < 4; mac_id++) { base_addr = bmac_util.get_mac_reg_base(mac_id); if (rtl_mac[mac_id]) { for(ii=0;ii %s: mac_id:%0d ii:%0d mpr:%0d, tbl_num:%0d\n", get_time(LO), name, mac_id, ii, mpr, tbl_num); if(pkt_cfgrator!=null) pkt_cfgrator.prog_mac_reg(mac_id, ii, {mpr, tbl_num, 48'hf00102030420+ii}); } } if ( (mac_id == 0 | mac_id == 1) && rtl_mac[mac_id]) { if(get_plus_arg(CHECK,"JUMBO_FRAME_EN")) { mac_pio_class.xmac_pio_wr(base_addr + XMAC_MAX, 32'h0000_3FFF); printf("INFO: xmac_init: Setting up MAC to support JUMBO_FRAMES\n"); } mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT1,32'h0000_0000); mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT2,32'h0000_0000); mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT3,32'h0000_0000); mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT4,32'h0000_0000); mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT5,32'h0000_0000); mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT6,32'h0000_0000); mac_pio_class.xmac_pio_wr(base_addr + RxMAC_HIST_CNT7,32'h0000_0000); mac_pio_class.xmac_pio_rd( base_addr + XMAC_CONFIG, rd_data,1'b0 ); printf ("TEST XMAC_CONFIG(addr=0x%h) for Port %0d after enabling addr filtering = 0x%h\n", base_addr + XMAC_CONFIG, mac_id,rd_data); mac_pio_class.xmac_pio_wr( base_addr + XMAC_ADDR_CMPEN_LSB , 32'hFFFF_FFFF); printf ("TEST XMAC_CONFIG(addr=0x%h) port:%0d restoring original values = 0x%h\n", base_addr + XMAC_CONFIG, mac_id,rd_data); rd_data = XMAC_CONFIG_reinit_values; // Restore original values mac_pio_class.xmac_pio_wr( base_addr + XMAC_CONFIG, rd_data); } if ((mac_id == 2 | mac_id == 3) && rtl_mac[mac_id]) { mac_pio_class.bmac_pio_rd(base_addr + RxMAC_CONFIG, bmac_rd_data, 0); printf("<%0d> %s: Restoring original values for RxMAC_CONFIG port:%0d value:%h\n", get_time(LO), name, mac_id, RxMAC_CONFIG_reinit_values); bmac_rd_data = RxMAC_CONFIG_reinit_values; mac_pio_class.bmac_pio_wr(base_addr + RxMAC_CONFIG, bmac_rd_data); mac_pio_class.bmac_pio_wr(base_addr + BMAC_ALTAD_CMPEN, 32'hffffffff); } //} // for } task niu_mac_reset_class::mac_warm_reset_tx(bit [1:0] mac_id) { bit [31:0] rd_data; bit [31:0] bmac_rd_data; bit[39:0] base_addr; bit[47:0] mac_addr; integer ii, tbl_num; integer timeout_iterations = 100; integer timeout_cnt = 0; bit mpr; /* The following information is extracted from MAC PRM version 4.9 22.11 MAC Warm Reset Sequence To apply MAC Warm Reset, Software should perform MAC Stop Sequence first followed by Software Reset sequence second. ################################## # MAC Stop Sequence ################################## =====> Transmit xMAC Stop Sequence Program XMAC_CONFIG register (FZC_MAC+00060) bit 0 (tx_enable) to ?0?. Software should wait for one max_pkt_size time for xMAC to stop gracefully. Use xtlm_state== 0 in xMAC State Machines Register (FZC_MAC+0x001A8) as stop_done indicator. =====> Receive xMAC Stop Sequence Program XMAC_CONFIG register (FZC_MAC+00060) bit 8 (rx_enable) to ?0?. Software should wait for one max_pkt_size time for xMAC to stop gracefully. Use xrlm_state== 0 in xMAC State Machines Register (FZC_MAC+0x001A8) as stop_done indicator. -----> Transmit bMAC Stop Sequence Program TxMAC_CONFIG register (FZC_MAC+0C060) bit 0 (tx_enable) to ?0?. Software should wait for one max_pkt_size time for bMAC to stop gracefully. Use tlm_state== 0 in bMAC State Machines Register (FZC_MAC+0x0C3A0) as stop_done indicator. -----> Receive bMAC Stop Sequence Program RxMAC_CONFIG register (FZC_MAC+0C068) bit 0 (rx_enable) to ?0?. Software should wait for one max_pkt_size time for bMAC to stop gracefully. Use rlm_state== 0 in bMAC State Machines Register (FZC_MAC+0x0C3A0) as stop_done indicator. ################################ # MAC Software Reset Sequence ################################ =====> Transmit xMAC Software Reset Sequence Software should write ?1? to bit 0 (TxMacSoftRst) and bit 1 (TxMacRegRst) in register XTxMAC_SW_RST (FZC_MAC+00000). Use TxMacSoftRst==0 and TxMacRegRst==0 as reset_done indicator. =====> Receive xMAC Software Reset Sequencef Software should write ?1? to bit 0 (RxMacSoftRst) and bit 1 (RxMacRegRst) in register XRxMAC_SW_RST (FZC_MAC+00008). Use RxMacSoftRst==0 and RxMacRegRst==0 as reset_done indicator. -----> Transmit bMAC Software Reset Sequence Software should write ?1? to bit 0 (txmac_sw_rst) in register BTxMAC_SW_RST (FZC_MAC+0C000). Use txmac_sw_rst==0 as reset_done indicator. -----> Receive bMAC Software Reset Sequence Software should write ?1? to bit 0 (rxmac_sw_rst) in register BRxMAC_SW_RST (FZC_MAC+0C008). Use rxmac_sw_rst==0 as reset_done indicator. */ printf("<%0d> niu_mac_reset_class::mac_warm_reset_tx mac_id:%0d \n", get_time(LO), mac_id); if(mac_id == 0 | mac_id == 1) max_mac_DAs = 16; else max_mac_DAs = 8; base_addr = bmac_util.get_mac_reg_base(mac_id); if ( (mac_id ==0 | mac_id == 1) && rtl_mac[mac_id]) { // STEP 1 // Transmit xMAC Stop Sequence mac_pio_class.xmac_pio_rd( base_addr + XMAC_CONFIG, rd_data,1'b0 ); XMAC_CONFIG_reinit_values = rd_data; rd_data[0] = 0; // tx_enable mac_pio_class.xmac_pio_wr( base_addr + XMAC_CONFIG, rd_data); printf ("niu_mac_reset_class::mac_warm_reset_tx XMAC_CONFIG(addr=0x%h) for Port %0d after disabling tx bits = 0x%h\n", base_addr + XMAC_CONFIG, mac_id, rd_data); // STEP 2 // wait for one max_pkt_size time for xMAC to stop gracefully repeat (3000) @(posedge CLOCK); // STEP 3 // poll state machine register rd_data[2:0] = 3'b111; // xtlm_state while(rd_data[2:0] !== 3'b000) { repeat (100) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + XMAC_SM_REG, rd_data,1'b0 ); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> %s : ERROR : timeout waiting for XMAC_SM_REG:xrlm_state[bit 7] to go 0 rd_data:%h\n", get_time(LO), name, rd_data); } } // STEP 4 // Receive xMAC Software Reset Sequence mac_pio_class.xmac_pio_rd( base_addr + XTxMAC_SW_RST, rd_data,1'b0 ); rd_data[0] = 1; // TxMacSoftRst rd_data[1] = 1; // TxMacRegRst mac_pio_class.xmac_pio_wr( base_addr + XTxMAC_SW_RST, rd_data); // STEP 5 // poll TxMacSoftRst and TxMacRegRst done rd_data[0] = 1; rd_data[1] = 1; timeout_cnt = 0; while(rd_data[0] !== 0 | rd_data[1] !== 0) { repeat (100) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + XTxMAC_SW_RST, rd_data,1'b0 ); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> %s : ERROR : timeout waiting for XTxMAC_SW_RST:rx_reset[bit 0,1] to go 0 rd_data:%h\n", get_time(LO), name, rd_data); } } } else if ( (mac_id ==2 | mac_id == 3) && rtl_mac[mac_id]) { // STEP 1 // Receive bMAC Stop Sequence mac_pio_class.bmac_pio_rd(base_addr + TxMAC_CONFIG, bmac_rd_data, 0); TxMAC_CONFIG_reinit_values = bmac_rd_data; bmac_rd_data[0] = 0; // rx_enable = 0 mac_pio_class.bmac_pio_wr(base_addr + TxMAC_CONFIG, bmac_rd_data); // STEP 2 // wait for one max_pkt_size time for bMAC to stop gracefully repeat(30000) @(posedge CLOCK); // STEP 3 // Use tlm_state== 0 in bMAC State Machines Register (FZC_MAC+0x0C3A0) as stop_done indicator. // poll tlm_state bits 19:16 bmac_rd_data[19:16] = 4'b1111; while(bmac_rd_data[19:16] !== 0) { repeat (1000) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + BMAC_SM_REG, bmac_rd_data,1'b0 ); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> niu_mac_reset_class::mac_warm_reset_tx ERROR timeout in BMAC_SM_REG bits 19:16 rd_data:%h\n", get_time(LO), bmac_rd_data); } } // STEP 4 // Transmit bMAC Software Reset Sequence mac_pio_class.bmac_pio_rd(base_addr + BTxMAC_SW_RST, bmac_rd_data, 0); bmac_rd_data[0] = 1; // rxmac_sw_rst = 1 mac_pio_class.bmac_pio_wr(base_addr + BTxMAC_SW_RST, bmac_rd_data); // STEP 5 // poll reset done bmac_rd_data[0] = 1; while(bmac_rd_data[0] !== 0) { repeat (100) @(posedge CLOCK); mac_pio_class.xmac_pio_rd( base_addr + BTxMAC_SW_RST, bmac_rd_data,1'b0 ); timeout_cnt++; if(timeout_cnt > timeout_iterations) { printf("<%0d> %s : ERROR : timeout waiting for BTxMAC_SW_RST:rx_reset[bit 0] to go 0 rd_data:%h\n", get_time(LO), name, bmac_rd_data); } } } // mac_init.init_mac(); base_addr = bmac_util.get_mac_reg_base(mac_id); if (rtl_mac[mac_id]) { for(ii=0;ii %s: Restoring original values for XMAC_CONFIG port:%0d value:%h\n", get_time(LO), name, mac_id, XMAC_CONFIG_reinit_values); mac_pio_class.xmac_pio_wr( base_addr + XMAC_CONFIG, rd_data); mac_pio_class.xmac_pio_wr( base_addr + XMAC_ADDR_CMPEN_LSB , 32'hFFFF_FFFF); } if ((mac_id == 2 | mac_id == 3) && rtl_mac[mac_id]) { mac_pio_class.bmac_pio_rd(base_addr + RxMAC_CONFIG, bmac_rd_data, 0); bmac_rd_data[3] = 0; // Turn off the promiscuous mode mac_pio_class.bmac_pio_wr(base_addr + RxMAC_CONFIG, bmac_rd_data); mac_pio_class.bmac_pio_wr(base_addr + BMAC_ALTAD_CMPEN, 32'hffffffff); bmac_rd_data = TxMAC_CONFIG_reinit_values; mac_pio_class.bmac_pio_wr(base_addr + TxMAC_CONFIG, bmac_rd_data); } } task niu_mac_reset_class :: mac_reset_periodically(integer interval = 3000) { integer i; bit [1:0] mac_id = 0; printf("niu_mac_reset_class::mac_reset_periodically interval:%0d\n", interval); repeat(10000) @(posedge CLOCK); // Initial delay while(1) { repeat(100) @(posedge CLOCK); // to Avoid infinite loop repeat(interval) @(posedge CLOCK); if(keep_resetting) { mac_warm_reset_rx(mac_id); repeat(3000) @(posedge CLOCK); mac_warm_reset_tx(mac_id); } mac_id++; } }