aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2011-05-31 17:29:05 -0400
committerDavid S. Miller <davem@davemloft.net>2011-06-01 16:10:57 -0400
commitfd36a2e69e05f42ddfe388efe14e068c0d0c6cb7 (patch)
tree7e97d10082179c5e41e9239925782cf6ea1e6de6 /drivers/net
parent020c7e3f3cd38d41104c7f55d3d5732c5ac939be (diff)
bnx2x: Fix link status sync
Fix link status synchronization between the primary function, and rest functions. 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')
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index e44c19d86c3..1816b2d5b71 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -1786,12 +1786,15 @@ void bnx2x_link_status_update(struct link_params *params,
1786 u8 link_10g; 1786 u8 link_10g;
1787 u8 port = params->port; 1787 u8 port = params->port;
1788 u32 sync_offset, media_types; 1788 u32 sync_offset, media_types;
1789 /* Update PHY configuration */
1790 set_phy_vars(params, vars);
1791
1789 vars->link_status = REG_RD(bp, params->shmem_base + 1792 vars->link_status = REG_RD(bp, params->shmem_base +
1790 offsetof(struct shmem_region, 1793 offsetof(struct shmem_region,
1791 port_mb[port].link_status)); 1794 port_mb[port].link_status));
1792 1795
1793 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); 1796 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1794 1797 vars->phy_flags = PHY_XGXS_FLAG;
1795 if (vars->link_up) { 1798 if (vars->link_up) {
1796 DP(NETIF_MSG_LINK, "phy link up\n"); 1799 DP(NETIF_MSG_LINK, "phy link up\n");
1797 1800
@@ -3436,7 +3439,11 @@ static int bnx2x_link_initialize(struct link_params *params,
3436 } 3439 }
3437 3440
3438 /* Init external phy*/ 3441 /* Init external phy*/
3439 if (!non_ext_phy) 3442 if (non_ext_phy) {
3443 if (params->phy[INT_PHY].supported &
3444 SUPPORTED_FIBRE)
3445 vars->link_status |= LINK_STATUS_SERDES_LINK;
3446 } else {
3440 for (phy_index = EXT_PHY1; phy_index < params->num_phys; 3447 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3441 phy_index++) { 3448 phy_index++) {
3442 /* 3449 /*
@@ -3445,6 +3452,10 @@ static int bnx2x_link_initialize(struct link_params *params,
3445 * need to initialize the first phy, since they are 3452 * need to initialize the first phy, since they are
3446 * connected. 3453 * connected.
3447 */ 3454 */
3455 if (params->phy[phy_index].supported &
3456 SUPPORTED_FIBRE)
3457 vars->link_status |= LINK_STATUS_SERDES_LINK;
3458
3448 if (phy_index == EXT_PHY2 && 3459 if (phy_index == EXT_PHY2 &&
3449 (bnx2x_phy_selection(params) == 3460 (bnx2x_phy_selection(params) ==
3450 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { 3461 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
@@ -3456,7 +3467,7 @@ static int bnx2x_link_initialize(struct link_params *params,
3456 &params->phy[phy_index], 3467 &params->phy[phy_index],
3457 params, vars); 3468 params, vars);
3458 } 3469 }
3459 3470 }
3460 /* Reset the interrupt indication after phy was initialized */ 3471 /* Reset the interrupt indication after phy was initialized */
3461 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + 3472 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
3462 params->port*4, 3473 params->port*4,
@@ -3464,6 +3475,7 @@ static int bnx2x_link_initialize(struct link_params *params,
3464 NIG_STATUS_XGXS0_LINK_STATUS | 3475 NIG_STATUS_XGXS0_LINK_STATUS |
3465 NIG_STATUS_SERDES0_LINK_STATUS | 3476 NIG_STATUS_SERDES0_LINK_STATUS |
3466 NIG_MASK_MI_INT)); 3477 NIG_MASK_MI_INT));
3478 bnx2x_update_mng(params, vars->link_status);
3467 return rc; 3479 return rc;
3468} 3480}
3469 3481
@@ -3507,7 +3519,12 @@ static int bnx2x_update_link_down(struct link_params *params,
3507 vars->mac_type = MAC_TYPE_NONE; 3519 vars->mac_type = MAC_TYPE_NONE;
3508 3520
3509 /* update shared memory */ 3521 /* update shared memory */
3510 vars->link_status = 0; 3522 vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
3523 LINK_STATUS_LINK_UP |
3524 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
3525 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
3526 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
3527 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
3511 vars->line_speed = 0; 3528 vars->line_speed = 0;
3512 bnx2x_update_mng(params, vars->link_status); 3529 bnx2x_update_mng(params, vars->link_status);
3513 3530
@@ -3597,7 +3614,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
3597 u8 is_mi_int = 0; 3614 u8 is_mi_int = 0;
3598 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; 3615 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
3599 u8 active_external_phy = INT_PHY; 3616 u8 active_external_phy = INT_PHY;
3600 vars->link_status = 0; 3617
3601 for (phy_index = INT_PHY; phy_index < params->num_phys; 3618 for (phy_index = INT_PHY; phy_index < params->num_phys;
3602 phy_index++) { 3619 phy_index++) {
3603 phy_vars[phy_index].flow_ctrl = 0; 3620 phy_vars[phy_index].flow_ctrl = 0;
@@ -3738,6 +3755,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
3738 if (params->phy[active_external_phy].supported & 3755 if (params->phy[active_external_phy].supported &
3739 SUPPORTED_FIBRE) 3756 SUPPORTED_FIBRE)
3740 vars->link_status |= LINK_STATUS_SERDES_LINK; 3757 vars->link_status |= LINK_STATUS_SERDES_LINK;
3758 else
3759 vars->link_status &= ~LINK_STATUS_SERDES_LINK;
3741 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", 3760 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
3742 active_external_phy); 3761 active_external_phy);
3743 } 3762 }