aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2011-10-27 01:09:47 -0400
committerDavid S. Miller <davem@davemloft.net>2011-10-27 16:14:15 -0400
commitce7c048928473220394bb126b08596e92e998a36 (patch)
treecd84a01e6c6dd20f889cf23b66d71b05a880e045
parenta9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506a (diff)
bnx2x: Fix RX/TX problem caused by the MAC layer
This patch fixes a problem in which the host stops receiving data after restarting the interface. This issue is caused by combination of incorrect data path tap closure, along with missing MAC reset. Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index a47db9dc6c50..23333e0a1ef4 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -1494,6 +1494,18 @@ static void bnx2x_set_xumac_nig(struct link_params *params,
1494 NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en); 1494 NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1495} 1495}
1496 1496
1497static void bnx2x_umac_disable(struct link_params *params)
1498{
1499 u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1500 struct bnx2x *bp = params->bp;
1501 if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
1502 (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1503 return;
1504
1505 /* Disable RX and TX */
1506 REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, 0);
1507}
1508
1497static void bnx2x_umac_enable(struct link_params *params, 1509static void bnx2x_umac_enable(struct link_params *params,
1498 struct link_vars *vars, u8 lb) 1510 struct link_vars *vars, u8 lb)
1499{ 1511{
@@ -1603,8 +1615,9 @@ static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
1603} 1615}
1604 1616
1605/* Define the XMAC mode */ 1617/* Define the XMAC mode */
1606static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed) 1618static void bnx2x_xmac_init(struct link_params *params, u32 max_speed)
1607{ 1619{
1620 struct bnx2x *bp = params->bp;
1608 u32 is_port4mode = bnx2x_is_4_port_mode(bp); 1621 u32 is_port4mode = bnx2x_is_4_port_mode(bp);
1609 1622
1610 /** 1623 /**
@@ -1614,7 +1627,8 @@ static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
1614 * ports of the path 1627 * ports of the path
1615 **/ 1628 **/
1616 1629
1617 if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) & 1630 if ((CHIP_NUM(bp) == CHIP_NUM_57840) &&
1631 (REG_RD(bp, MISC_REG_RESET_REG_2) &
1618 MISC_REGISTERS_RESET_REG_2_XMAC)) { 1632 MISC_REGISTERS_RESET_REG_2_XMAC)) {
1619 DP(NETIF_MSG_LINK, 1633 DP(NETIF_MSG_LINK,
1620 "XMAC already out of reset in 4-port mode\n"); 1634 "XMAC already out of reset in 4-port mode\n");
@@ -1681,10 +1695,6 @@ static void bnx2x_xmac_disable(struct link_params *params)
1681 (pfc_ctrl | (1<<1))); 1695 (pfc_ctrl | (1<<1)));
1682 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port); 1696 DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1683 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0); 1697 REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
1684 usleep_range(1000, 1000);
1685 bnx2x_set_xumac_nig(params, 0, 0);
1686 REG_WR(bp, xmac_base + XMAC_REG_CTRL,
1687 XMAC_CTRL_REG_SOFT_RESET);
1688 } 1698 }
1689} 1699}
1690 1700
@@ -1697,7 +1707,7 @@ static int bnx2x_xmac_enable(struct link_params *params,
1697 1707
1698 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; 1708 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1699 1709
1700 bnx2x_xmac_init(bp, vars->line_speed); 1710 bnx2x_xmac_init(params, vars->line_speed);
1701 1711
1702 /* 1712 /*
1703 * This register determines on which events the MAC will assert 1713 * This register determines on which events the MAC will assert
@@ -6310,8 +6320,10 @@ static int bnx2x_update_link_down(struct link_params *params,
6310 MISC_REGISTERS_RESET_REG_2_CLEAR, 6320 MISC_REGISTERS_RESET_REG_2_CLEAR,
6311 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 6321 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6312 } 6322 }
6313 if (CHIP_IS_E3(bp)) 6323 if (CHIP_IS_E3(bp)) {
6314 bnx2x_xmac_disable(params); 6324 bnx2x_xmac_disable(params);
6325 bnx2x_umac_disable(params);
6326 }
6315 6327
6316 return 0; 6328 return 0;
6317} 6329}
@@ -11810,8 +11822,10 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11810 /* Stop BigMac rx */ 11822 /* Stop BigMac rx */
11811 if (!CHIP_IS_E3(bp)) 11823 if (!CHIP_IS_E3(bp))
11812 bnx2x_bmac_rx_disable(bp, port); 11824 bnx2x_bmac_rx_disable(bp, port);
11813 else 11825 else {
11814 bnx2x_xmac_disable(params); 11826 bnx2x_xmac_disable(params);
11827 bnx2x_umac_disable(params);
11828 }
11815 /* disable emac */ 11829 /* disable emac */
11816 if (!CHIP_IS_E3(bp)) 11830 if (!CHIP_IS_E3(bp))
11817 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 11831 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
@@ -11849,14 +11863,21 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11849 if (params->phy[INT_PHY].link_reset) 11863 if (params->phy[INT_PHY].link_reset)
11850 params->phy[INT_PHY].link_reset( 11864 params->phy[INT_PHY].link_reset(
11851 &params->phy[INT_PHY], params); 11865 &params->phy[INT_PHY], params);
11852 /* reset BigMac */
11853 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
11854 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
11855 11866
11856 /* disable nig ingress interface */ 11867 /* disable nig ingress interface */
11857 if (!CHIP_IS_E3(bp)) { 11868 if (!CHIP_IS_E3(bp)) {
11869 /* reset BigMac */
11870 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
11871 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
11858 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); 11872 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
11859 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); 11873 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
11874 } else {
11875 u32 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
11876 bnx2x_set_xumac_nig(params, 0, 0);
11877 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
11878 MISC_REGISTERS_RESET_REG_2_XMAC)
11879 REG_WR(bp, xmac_base + XMAC_REG_CTRL,
11880 XMAC_CTRL_REG_SOFT_RESET);
11860 } 11881 }
11861 vars->link_up = 0; 11882 vars->link_up = 0;
11862 vars->phy_flags = 0; 11883 vars->phy_flags = 0;