aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 940ef859dc60..5523da3afcdc 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -127,6 +127,17 @@ MODULE_PARM_DESC(debug, " Default debug msglevel");
127 127
128struct workqueue_struct *bnx2x_wq; 128struct workqueue_struct *bnx2x_wq;
129 129
130struct bnx2x_mac_vals {
131 u32 xmac_addr;
132 u32 xmac_val;
133 u32 emac_addr;
134 u32 emac_val;
135 u32 umac_addr;
136 u32 umac_val;
137 u32 bmac_addr;
138 u32 bmac_val[2];
139};
140
130enum bnx2x_board_type { 141enum bnx2x_board_type {
131 BCM57710 = 0, 142 BCM57710 = 0,
132 BCM57711, 143 BCM57711,
@@ -9420,12 +9431,19 @@ static inline void bnx2x_undi_int_disable(struct bnx2x *bp)
9420 bnx2x_undi_int_disable_e1h(bp); 9431 bnx2x_undi_int_disable_e1h(bp);
9421} 9432}
9422 9433
9423static void bnx2x_prev_unload_close_mac(struct bnx2x *bp) 9434static void bnx2x_prev_unload_close_mac(struct bnx2x *bp,
9435 struct bnx2x_mac_vals *vals)
9424{ 9436{
9425 u32 val, base_addr, offset, mask, reset_reg; 9437 u32 val, base_addr, offset, mask, reset_reg;
9426 bool mac_stopped = false; 9438 bool mac_stopped = false;
9427 u8 port = BP_PORT(bp); 9439 u8 port = BP_PORT(bp);
9428 9440
9441 /* reset addresses as they also mark which values were changed */
9442 vals->bmac_addr = 0;
9443 vals->umac_addr = 0;
9444 vals->xmac_addr = 0;
9445 vals->emac_addr = 0;
9446
9429 reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2); 9447 reset_reg = REG_RD(bp, MISC_REG_RESET_REG_2);
9430 9448
9431 if (!CHIP_IS_E3(bp)) { 9449 if (!CHIP_IS_E3(bp)) {
@@ -9447,14 +9465,18 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp)
9447 */ 9465 */
9448 wb_data[0] = REG_RD(bp, base_addr + offset); 9466 wb_data[0] = REG_RD(bp, base_addr + offset);
9449 wb_data[1] = REG_RD(bp, base_addr + offset + 0x4); 9467 wb_data[1] = REG_RD(bp, base_addr + offset + 0x4);
9468 vals->bmac_addr = base_addr + offset;
9469 vals->bmac_val[0] = wb_data[0];
9470 vals->bmac_val[1] = wb_data[1];
9450 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; 9471 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
9451 REG_WR(bp, base_addr + offset, wb_data[0]); 9472 REG_WR(bp, vals->bmac_addr, wb_data[0]);
9452 REG_WR(bp, base_addr + offset + 0x4, wb_data[1]); 9473 REG_WR(bp, vals->bmac_addr + 0x4, wb_data[1]);
9453 9474
9454 } 9475 }
9455 BNX2X_DEV_INFO("Disable emac Rx\n"); 9476 BNX2X_DEV_INFO("Disable emac Rx\n");
9456 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4, 0); 9477 vals->emac_addr = NIG_REG_NIG_EMAC0_EN + BP_PORT(bp)*4;
9457 9478 vals->emac_val = REG_RD(bp, vals->emac_addr);
9479 REG_WR(bp, vals->emac_addr, 0);
9458 mac_stopped = true; 9480 mac_stopped = true;
9459 } else { 9481 } else {
9460 if (reset_reg & MISC_REGISTERS_RESET_REG_2_XMAC) { 9482 if (reset_reg & MISC_REGISTERS_RESET_REG_2_XMAC) {
@@ -9465,14 +9487,18 @@ static void bnx2x_prev_unload_close_mac(struct bnx2x *bp)
9465 val & ~(1 << 1)); 9487 val & ~(1 << 1));
9466 REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI, 9488 REG_WR(bp, base_addr + XMAC_REG_PFC_CTRL_HI,
9467 val | (1 << 1)); 9489 val | (1 << 1));
9468 REG_WR(bp, base_addr + XMAC_REG_CTRL, 0); 9490 vals->xmac_addr = base_addr + XMAC_REG_CTRL;
9491 vals->xmac_val = REG_RD(bp, vals->xmac_addr);
9492 REG_WR(bp, vals->xmac_addr, 0);
9469 mac_stopped = true; 9493 mac_stopped = true;
9470 } 9494 }
9471 mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port; 9495 mask = MISC_REGISTERS_RESET_REG_2_UMAC0 << port;
9472 if (mask & reset_reg) { 9496 if (mask & reset_reg) {
9473 BNX2X_DEV_INFO("Disable umac Rx\n"); 9497 BNX2X_DEV_INFO("Disable umac Rx\n");
9474 base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0; 9498 base_addr = BP_PORT(bp) ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
9475 REG_WR(bp, base_addr + UMAC_REG_COMMAND_CONFIG, 0); 9499 vals->umac_addr = base_addr + UMAC_REG_COMMAND_CONFIG;
9500 vals->umac_val = REG_RD(bp, vals->umac_addr);
9501 REG_WR(bp, vals->umac_addr, 0);
9476 mac_stopped = true; 9502 mac_stopped = true;
9477 } 9503 }
9478 } 9504 }
@@ -9664,12 +9690,16 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
9664{ 9690{
9665 u32 reset_reg, tmp_reg = 0, rc; 9691 u32 reset_reg, tmp_reg = 0, rc;
9666 bool prev_undi = false; 9692 bool prev_undi = false;
9693 struct bnx2x_mac_vals mac_vals;
9694
9667 /* It is possible a previous function received 'common' answer, 9695 /* It is possible a previous function received 'common' answer,
9668 * but hasn't loaded yet, therefore creating a scenario of 9696 * but hasn't loaded yet, therefore creating a scenario of
9669 * multiple functions receiving 'common' on the same path. 9697 * multiple functions receiving 'common' on the same path.
9670 */ 9698 */
9671 BNX2X_DEV_INFO("Common unload Flow\n"); 9699 BNX2X_DEV_INFO("Common unload Flow\n");
9672 9700
9701 memset(&mac_vals, 0, sizeof(mac_vals));
9702
9673 if (bnx2x_prev_is_path_marked(bp)) 9703 if (bnx2x_prev_is_path_marked(bp))
9674 return bnx2x_prev_mcp_done(bp); 9704 return bnx2x_prev_mcp_done(bp);
9675 9705
@@ -9680,7 +9710,10 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
9680 u32 timer_count = 1000; 9710 u32 timer_count = 1000;
9681 9711
9682 /* Close the MAC Rx to prevent BRB from filling up */ 9712 /* Close the MAC Rx to prevent BRB from filling up */
9683 bnx2x_prev_unload_close_mac(bp); 9713 bnx2x_prev_unload_close_mac(bp, &mac_vals);
9714
9715 /* close LLH filters towards the BRB */
9716 bnx2x_set_rx_filter(&bp->link_params, 0);
9684 9717
9685 /* Check if the UNDI driver was previously loaded 9718 /* Check if the UNDI driver was previously loaded
9686 * UNDI driver initializes CID offset for normal bell to 0x7 9719 * UNDI driver initializes CID offset for normal bell to 0x7
@@ -9727,6 +9760,17 @@ static int bnx2x_prev_unload_common(struct bnx2x *bp)
9727 /* No packets are in the pipeline, path is ready for reset */ 9760 /* No packets are in the pipeline, path is ready for reset */
9728 bnx2x_reset_common(bp); 9761 bnx2x_reset_common(bp);
9729 9762
9763 if (mac_vals.xmac_addr)
9764 REG_WR(bp, mac_vals.xmac_addr, mac_vals.xmac_val);
9765 if (mac_vals.umac_addr)
9766 REG_WR(bp, mac_vals.umac_addr, mac_vals.umac_val);
9767 if (mac_vals.emac_addr)
9768 REG_WR(bp, mac_vals.emac_addr, mac_vals.emac_val);
9769 if (mac_vals.bmac_addr) {
9770 REG_WR(bp, mac_vals.bmac_addr, mac_vals.bmac_val[0]);
9771 REG_WR(bp, mac_vals.bmac_addr + 4, mac_vals.bmac_val[1]);
9772 }
9773
9730 rc = bnx2x_prev_mark_path(bp, prev_undi); 9774 rc = bnx2x_prev_mark_path(bp, prev_undi);
9731 if (rc) { 9775 if (rc) {
9732 bnx2x_prev_mcp_done(bp); 9776 bnx2x_prev_mcp_done(bp);