diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-01-14 01:44:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-19 19:20:11 -0500 |
commit | 6c55c3cdc86881383075a933594748b30dd0054b (patch) | |
tree | 37c241021919fd1c8c673704d03b0afad678768e | |
parent | 632da4d66324b5baf947a048dd1f1e9093b6dd90 (diff) |
bnx2x: 1G-10G toggling race
The HW should be configured so fast toggling between 1G and 10G will not be
missed. Make sure that the HW is re-configured in full
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/bnx2x_link.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index fefa6ab13064..d9e1cfcd06dd 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params, | |||
317 | val &= ~0x810; | 317 | val &= ~0x810; |
318 | EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); | 318 | EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); |
319 | 319 | ||
320 | /* enable emac */ | ||
321 | REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1); | ||
322 | |||
320 | /* enable emac for jumbo packets */ | 323 | /* enable emac for jumbo packets */ |
321 | EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, | 324 | EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, |
322 | (EMAC_RX_MTU_SIZE_JUMBO_ENA | | 325 | (EMAC_RX_MTU_SIZE_JUMBO_ENA | |
@@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1609 | u32 gp_status) | 1612 | u32 gp_status) |
1610 | { | 1613 | { |
1611 | struct bnx2x *bp = params->bp; | 1614 | struct bnx2x *bp = params->bp; |
1612 | 1615 | u16 new_line_speed; | |
1613 | u8 rc = 0; | 1616 | u8 rc = 0; |
1614 | vars->link_status = 0; | 1617 | vars->link_status = 0; |
1615 | 1618 | ||
@@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1629 | 1632 | ||
1630 | switch (gp_status & GP_STATUS_SPEED_MASK) { | 1633 | switch (gp_status & GP_STATUS_SPEED_MASK) { |
1631 | case GP_STATUS_10M: | 1634 | case GP_STATUS_10M: |
1632 | vars->line_speed = SPEED_10; | 1635 | new_line_speed = SPEED_10; |
1633 | if (vars->duplex == DUPLEX_FULL) | 1636 | if (vars->duplex == DUPLEX_FULL) |
1634 | vars->link_status |= LINK_10TFD; | 1637 | vars->link_status |= LINK_10TFD; |
1635 | else | 1638 | else |
@@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1637 | break; | 1640 | break; |
1638 | 1641 | ||
1639 | case GP_STATUS_100M: | 1642 | case GP_STATUS_100M: |
1640 | vars->line_speed = SPEED_100; | 1643 | new_line_speed = SPEED_100; |
1641 | if (vars->duplex == DUPLEX_FULL) | 1644 | if (vars->duplex == DUPLEX_FULL) |
1642 | vars->link_status |= LINK_100TXFD; | 1645 | vars->link_status |= LINK_100TXFD; |
1643 | else | 1646 | else |
@@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1646 | 1649 | ||
1647 | case GP_STATUS_1G: | 1650 | case GP_STATUS_1G: |
1648 | case GP_STATUS_1G_KX: | 1651 | case GP_STATUS_1G_KX: |
1649 | vars->line_speed = SPEED_1000; | 1652 | new_line_speed = SPEED_1000; |
1650 | if (vars->duplex == DUPLEX_FULL) | 1653 | if (vars->duplex == DUPLEX_FULL) |
1651 | vars->link_status |= LINK_1000TFD; | 1654 | vars->link_status |= LINK_1000TFD; |
1652 | else | 1655 | else |
@@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1654 | break; | 1657 | break; |
1655 | 1658 | ||
1656 | case GP_STATUS_2_5G: | 1659 | case GP_STATUS_2_5G: |
1657 | vars->line_speed = SPEED_2500; | 1660 | new_line_speed = SPEED_2500; |
1658 | if (vars->duplex == DUPLEX_FULL) | 1661 | if (vars->duplex == DUPLEX_FULL) |
1659 | vars->link_status |= LINK_2500TFD; | 1662 | vars->link_status |= LINK_2500TFD; |
1660 | else | 1663 | else |
@@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1671 | case GP_STATUS_10G_KX4: | 1674 | case GP_STATUS_10G_KX4: |
1672 | case GP_STATUS_10G_HIG: | 1675 | case GP_STATUS_10G_HIG: |
1673 | case GP_STATUS_10G_CX4: | 1676 | case GP_STATUS_10G_CX4: |
1674 | vars->line_speed = SPEED_10000; | 1677 | new_line_speed = SPEED_10000; |
1675 | vars->link_status |= LINK_10GTFD; | 1678 | vars->link_status |= LINK_10GTFD; |
1676 | break; | 1679 | break; |
1677 | 1680 | ||
1678 | case GP_STATUS_12G_HIG: | 1681 | case GP_STATUS_12G_HIG: |
1679 | vars->line_speed = SPEED_12000; | 1682 | new_line_speed = SPEED_12000; |
1680 | vars->link_status |= LINK_12GTFD; | 1683 | vars->link_status |= LINK_12GTFD; |
1681 | break; | 1684 | break; |
1682 | 1685 | ||
1683 | case GP_STATUS_12_5G: | 1686 | case GP_STATUS_12_5G: |
1684 | vars->line_speed = SPEED_12500; | 1687 | new_line_speed = SPEED_12500; |
1685 | vars->link_status |= LINK_12_5GTFD; | 1688 | vars->link_status |= LINK_12_5GTFD; |
1686 | break; | 1689 | break; |
1687 | 1690 | ||
1688 | case GP_STATUS_13G: | 1691 | case GP_STATUS_13G: |
1689 | vars->line_speed = SPEED_13000; | 1692 | new_line_speed = SPEED_13000; |
1690 | vars->link_status |= LINK_13GTFD; | 1693 | vars->link_status |= LINK_13GTFD; |
1691 | break; | 1694 | break; |
1692 | 1695 | ||
1693 | case GP_STATUS_15G: | 1696 | case GP_STATUS_15G: |
1694 | vars->line_speed = SPEED_15000; | 1697 | new_line_speed = SPEED_15000; |
1695 | vars->link_status |= LINK_15GTFD; | 1698 | vars->link_status |= LINK_15GTFD; |
1696 | break; | 1699 | break; |
1697 | 1700 | ||
1698 | case GP_STATUS_16G: | 1701 | case GP_STATUS_16G: |
1699 | vars->line_speed = SPEED_16000; | 1702 | new_line_speed = SPEED_16000; |
1700 | vars->link_status |= LINK_16GTFD; | 1703 | vars->link_status |= LINK_16GTFD; |
1701 | break; | 1704 | break; |
1702 | 1705 | ||
@@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1708 | break; | 1711 | break; |
1709 | } | 1712 | } |
1710 | 1713 | ||
1714 | /* Upon link speed change set the NIG into drain mode. | ||
1715 | Comes to deals with possible FIFO glitch due to clk change | ||
1716 | when speed is decreased without link down indicator */ | ||
1717 | if (new_line_speed != vars->line_speed) { | ||
1718 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE | ||
1719 | + params->port*4, 0); | ||
1720 | msleep(1); | ||
1721 | } | ||
1722 | vars->line_speed = new_line_speed; | ||
1711 | vars->link_status |= LINK_STATUS_SERDES_LINK; | 1723 | vars->link_status |= LINK_STATUS_SERDES_LINK; |
1712 | 1724 | ||
1713 | if ((params->req_line_speed == SPEED_AUTO_NEG) && | 1725 | if ((params->req_line_speed == SPEED_AUTO_NEG) && |
@@ -4194,6 +4206,11 @@ static u8 bnx2x_update_link_down(struct link_params *params, | |||
4194 | /* activate nig drain */ | 4206 | /* activate nig drain */ |
4195 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); | 4207 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); |
4196 | 4208 | ||
4209 | /* disable emac */ | ||
4210 | REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); | ||
4211 | |||
4212 | msleep(10); | ||
4213 | |||
4197 | /* reset BigMac */ | 4214 | /* reset BigMac */ |
4198 | bnx2x_bmac_rx_disable(bp, params->port); | 4215 | bnx2x_bmac_rx_disable(bp, params->port); |
4199 | REG_WR(bp, GRCBASE_MISC + | 4216 | REG_WR(bp, GRCBASE_MISC + |
@@ -4238,6 +4255,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, | |||
4238 | 4255 | ||
4239 | /* update shared memory */ | 4256 | /* update shared memory */ |
4240 | bnx2x_update_mng(params, vars->link_status); | 4257 | bnx2x_update_mng(params, vars->link_status); |
4258 | msleep(20); | ||
4241 | return rc; | 4259 | return rc; |
4242 | } | 4260 | } |
4243 | /* This function should called upon link interrupt */ | 4261 | /* This function should called upon link interrupt */ |
@@ -4276,6 +4294,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4276 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), | 4294 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), |
4277 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); | 4295 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); |
4278 | 4296 | ||
4297 | /* disable emac */ | ||
4298 | REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); | ||
4299 | |||
4279 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | 4300 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
4280 | 4301 | ||
4281 | /* Check external link change only for non-direct */ | 4302 | /* Check external link change only for non-direct */ |