Commit 6c55c3cdc86881383075a933594748b30dd0054b
Committed by
David S. Miller
1 parent
632da4d663
Exists in
master
and in
39 other branches
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>
Showing 1 changed file with 32 additions and 11 deletions Side-by-side Diff
drivers/net/bnx2x_link.c
... | ... | @@ -317,6 +317,9 @@ |
317 | 317 | val &= ~0x810; |
318 | 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 | 323 | /* enable emac for jumbo packets */ |
321 | 324 | EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, |
322 | 325 | (EMAC_RX_MTU_SIZE_JUMBO_ENA | |
... | ... | @@ -1609,7 +1612,7 @@ |
1609 | 1612 | u32 gp_status) |
1610 | 1613 | { |
1611 | 1614 | struct bnx2x *bp = params->bp; |
1612 | - | |
1615 | + u16 new_line_speed; | |
1613 | 1616 | u8 rc = 0; |
1614 | 1617 | vars->link_status = 0; |
1615 | 1618 | |
... | ... | @@ -1629,7 +1632,7 @@ |
1629 | 1632 | |
1630 | 1633 | switch (gp_status & GP_STATUS_SPEED_MASK) { |
1631 | 1634 | case GP_STATUS_10M: |
1632 | - vars->line_speed = SPEED_10; | |
1635 | + new_line_speed = SPEED_10; | |
1633 | 1636 | if (vars->duplex == DUPLEX_FULL) |
1634 | 1637 | vars->link_status |= LINK_10TFD; |
1635 | 1638 | else |
... | ... | @@ -1637,7 +1640,7 @@ |
1637 | 1640 | break; |
1638 | 1641 | |
1639 | 1642 | case GP_STATUS_100M: |
1640 | - vars->line_speed = SPEED_100; | |
1643 | + new_line_speed = SPEED_100; | |
1641 | 1644 | if (vars->duplex == DUPLEX_FULL) |
1642 | 1645 | vars->link_status |= LINK_100TXFD; |
1643 | 1646 | else |
... | ... | @@ -1646,7 +1649,7 @@ |
1646 | 1649 | |
1647 | 1650 | case GP_STATUS_1G: |
1648 | 1651 | case GP_STATUS_1G_KX: |
1649 | - vars->line_speed = SPEED_1000; | |
1652 | + new_line_speed = SPEED_1000; | |
1650 | 1653 | if (vars->duplex == DUPLEX_FULL) |
1651 | 1654 | vars->link_status |= LINK_1000TFD; |
1652 | 1655 | else |
... | ... | @@ -1654,7 +1657,7 @@ |
1654 | 1657 | break; |
1655 | 1658 | |
1656 | 1659 | case GP_STATUS_2_5G: |
1657 | - vars->line_speed = SPEED_2500; | |
1660 | + new_line_speed = SPEED_2500; | |
1658 | 1661 | if (vars->duplex == DUPLEX_FULL) |
1659 | 1662 | vars->link_status |= LINK_2500TFD; |
1660 | 1663 | else |
1661 | 1664 | |
1662 | 1665 | |
1663 | 1666 | |
1664 | 1667 | |
1665 | 1668 | |
... | ... | @@ -1671,32 +1674,32 @@ |
1671 | 1674 | case GP_STATUS_10G_KX4: |
1672 | 1675 | case GP_STATUS_10G_HIG: |
1673 | 1676 | case GP_STATUS_10G_CX4: |
1674 | - vars->line_speed = SPEED_10000; | |
1677 | + new_line_speed = SPEED_10000; | |
1675 | 1678 | vars->link_status |= LINK_10GTFD; |
1676 | 1679 | break; |
1677 | 1680 | |
1678 | 1681 | case GP_STATUS_12G_HIG: |
1679 | - vars->line_speed = SPEED_12000; | |
1682 | + new_line_speed = SPEED_12000; | |
1680 | 1683 | vars->link_status |= LINK_12GTFD; |
1681 | 1684 | break; |
1682 | 1685 | |
1683 | 1686 | case GP_STATUS_12_5G: |
1684 | - vars->line_speed = SPEED_12500; | |
1687 | + new_line_speed = SPEED_12500; | |
1685 | 1688 | vars->link_status |= LINK_12_5GTFD; |
1686 | 1689 | break; |
1687 | 1690 | |
1688 | 1691 | case GP_STATUS_13G: |
1689 | - vars->line_speed = SPEED_13000; | |
1692 | + new_line_speed = SPEED_13000; | |
1690 | 1693 | vars->link_status |= LINK_13GTFD; |
1691 | 1694 | break; |
1692 | 1695 | |
1693 | 1696 | case GP_STATUS_15G: |
1694 | - vars->line_speed = SPEED_15000; | |
1697 | + new_line_speed = SPEED_15000; | |
1695 | 1698 | vars->link_status |= LINK_15GTFD; |
1696 | 1699 | break; |
1697 | 1700 | |
1698 | 1701 | case GP_STATUS_16G: |
1699 | - vars->line_speed = SPEED_16000; | |
1702 | + new_line_speed = SPEED_16000; | |
1700 | 1703 | vars->link_status |= LINK_16GTFD; |
1701 | 1704 | break; |
1702 | 1705 | |
... | ... | @@ -1708,6 +1711,15 @@ |
1708 | 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 | 1723 | vars->link_status |= LINK_STATUS_SERDES_LINK; |
1712 | 1724 | |
1713 | 1725 | if ((params->req_line_speed == SPEED_AUTO_NEG) && |
... | ... | @@ -4194,6 +4206,11 @@ |
4194 | 4206 | /* activate nig drain */ |
4195 | 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 | 4214 | /* reset BigMac */ |
4198 | 4215 | bnx2x_bmac_rx_disable(bp, params->port); |
4199 | 4216 | REG_WR(bp, GRCBASE_MISC + |
... | ... | @@ -4238,6 +4255,7 @@ |
4238 | 4255 | |
4239 | 4256 | /* update shared memory */ |
4240 | 4257 | bnx2x_update_mng(params, vars->link_status); |
4258 | + msleep(20); | |
4241 | 4259 | return rc; |
4242 | 4260 | } |
4243 | 4261 | /* This function should called upon link interrupt */ |
... | ... | @@ -4275,6 +4293,9 @@ |
4275 | 4293 | DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", |
4276 | 4294 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), |
4277 | 4295 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); |
4296 | + | |
4297 | + /* disable emac */ | |
4298 | + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); | |
4278 | 4299 | |
4279 | 4300 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
4280 | 4301 |