aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_link.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-01-14 01:44:13 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-19 19:20:11 -0500
commit6c55c3cdc86881383075a933594748b30dd0054b (patch)
tree37c241021919fd1c8c673704d03b0afad678768e /drivers/net/bnx2x_link.c
parent632da4d66324b5baf947a048dd1f1e9093b6dd90 (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>
Diffstat (limited to 'drivers/net/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x_link.c43
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 */