Commit 6c55c3cd authored by Eilon Greenstein's avatar Eilon Greenstein Committed by David S. Miller

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: default avatarYaniv Rosner <yanivr@broadcom.com>
Signed-off-by: default avatarEilon Greenstein <eilong@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 632da4d6
...@@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params, ...@@ -317,6 +317,9 @@ static u8 bnx2x_emac_enable(struct link_params *params,
val &= ~0x810; val &= ~0x810;
EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
/* enable emac */
REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
/* enable emac for jumbo packets */ /* enable emac for jumbo packets */
EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
(EMAC_RX_MTU_SIZE_JUMBO_ENA | (EMAC_RX_MTU_SIZE_JUMBO_ENA |
...@@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1609,7 +1612,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
u32 gp_status) u32 gp_status)
{ {
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
u16 new_line_speed;
u8 rc = 0; u8 rc = 0;
vars->link_status = 0; vars->link_status = 0;
...@@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1629,7 +1632,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
switch (gp_status & GP_STATUS_SPEED_MASK) { switch (gp_status & GP_STATUS_SPEED_MASK) {
case GP_STATUS_10M: case GP_STATUS_10M:
vars->line_speed = SPEED_10; new_line_speed = SPEED_10;
if (vars->duplex == DUPLEX_FULL) if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_10TFD; vars->link_status |= LINK_10TFD;
else else
...@@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1637,7 +1640,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break; break;
case GP_STATUS_100M: case GP_STATUS_100M:
vars->line_speed = SPEED_100; new_line_speed = SPEED_100;
if (vars->duplex == DUPLEX_FULL) if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_100TXFD; vars->link_status |= LINK_100TXFD;
else else
...@@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1646,7 +1649,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_1G: case GP_STATUS_1G:
case GP_STATUS_1G_KX: case GP_STATUS_1G_KX:
vars->line_speed = SPEED_1000; new_line_speed = SPEED_1000;
if (vars->duplex == DUPLEX_FULL) if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_1000TFD; vars->link_status |= LINK_1000TFD;
else else
...@@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1654,7 +1657,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break; break;
case GP_STATUS_2_5G: case GP_STATUS_2_5G:
vars->line_speed = SPEED_2500; new_line_speed = SPEED_2500;
if (vars->duplex == DUPLEX_FULL) if (vars->duplex == DUPLEX_FULL)
vars->link_status |= LINK_2500TFD; vars->link_status |= LINK_2500TFD;
else else
...@@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1671,32 +1674,32 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
case GP_STATUS_10G_KX4: case GP_STATUS_10G_KX4:
case GP_STATUS_10G_HIG: case GP_STATUS_10G_HIG:
case GP_STATUS_10G_CX4: case GP_STATUS_10G_CX4:
vars->line_speed = SPEED_10000; new_line_speed = SPEED_10000;
vars->link_status |= LINK_10GTFD; vars->link_status |= LINK_10GTFD;
break; break;
case GP_STATUS_12G_HIG: case GP_STATUS_12G_HIG:
vars->line_speed = SPEED_12000; new_line_speed = SPEED_12000;
vars->link_status |= LINK_12GTFD; vars->link_status |= LINK_12GTFD;
break; break;
case GP_STATUS_12_5G: case GP_STATUS_12_5G:
vars->line_speed = SPEED_12500; new_line_speed = SPEED_12500;
vars->link_status |= LINK_12_5GTFD; vars->link_status |= LINK_12_5GTFD;
break; break;
case GP_STATUS_13G: case GP_STATUS_13G:
vars->line_speed = SPEED_13000; new_line_speed = SPEED_13000;
vars->link_status |= LINK_13GTFD; vars->link_status |= LINK_13GTFD;
break; break;
case GP_STATUS_15G: case GP_STATUS_15G:
vars->line_speed = SPEED_15000; new_line_speed = SPEED_15000;
vars->link_status |= LINK_15GTFD; vars->link_status |= LINK_15GTFD;
break; break;
case GP_STATUS_16G: case GP_STATUS_16G:
vars->line_speed = SPEED_16000; new_line_speed = SPEED_16000;
vars->link_status |= LINK_16GTFD; vars->link_status |= LINK_16GTFD;
break; break;
...@@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params, ...@@ -1708,6 +1711,15 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
break; break;
} }
/* Upon link speed change set the NIG into drain mode.
Comes to deals with possible FIFO glitch due to clk change
when speed is decreased without link down indicator */
if (new_line_speed != vars->line_speed) {
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
+ params->port*4, 0);
msleep(1);
}
vars->line_speed = new_line_speed;
vars->link_status |= LINK_STATUS_SERDES_LINK; vars->link_status |= LINK_STATUS_SERDES_LINK;
if ((params->req_line_speed == SPEED_AUTO_NEG) && if ((params->req_line_speed == SPEED_AUTO_NEG) &&
...@@ -4194,6 +4206,11 @@ static u8 bnx2x_update_link_down(struct link_params *params, ...@@ -4194,6 +4206,11 @@ static u8 bnx2x_update_link_down(struct link_params *params,
/* activate nig drain */ /* activate nig drain */
REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
/* disable emac */
REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
msleep(10);
/* reset BigMac */ /* reset BigMac */
bnx2x_bmac_rx_disable(bp, params->port); bnx2x_bmac_rx_disable(bp, params->port);
REG_WR(bp, GRCBASE_MISC + REG_WR(bp, GRCBASE_MISC +
...@@ -4238,6 +4255,7 @@ static u8 bnx2x_update_link_up(struct link_params *params, ...@@ -4238,6 +4255,7 @@ static u8 bnx2x_update_link_up(struct link_params *params,
/* update shared memory */ /* update shared memory */
bnx2x_update_mng(params, vars->link_status); bnx2x_update_mng(params, vars->link_status);
msleep(20);
return rc; return rc;
} }
/* This function should called upon link interrupt */ /* This function should called upon link interrupt */
...@@ -4276,6 +4294,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) ...@@ -4276,6 +4294,9 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
/* disable emac */
REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
/* Check external link change only for non-direct */ /* Check external link change only for non-direct */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment