diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2011-05-31 17:29:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-01 16:10:57 -0400 |
commit | fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7 (patch) | |
tree | 7e97d10082179c5e41e9239925782cf6ea1e6de6 /drivers/net | |
parent | 020c7e3f3cd38d41104c7f55d3d5732c5ac939be (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.c | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index e44c19d86c39..1816b2d5b714 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 | ¶ms->phy[phy_index], | 3467 | ¶ms->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 | } |