Commit 6c55c3cdc86881383075a933594748b30dd0054b

Authored by Eilon Greenstein
Committed by David S. Miller
1 parent 632da4d663

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