diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 17 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 3 |
4 files changed, 22 insertions, 3 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index a923bc4d5a1f..4046f97378c2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2760,6 +2760,7 @@ load_error2: bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); + bnx2x_del_all_napi(bp); /* clear pf_load status, as it was already set */ if (IS_PF(bp)) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 31c5787970db..77ebae0ac64a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -8647,7 +8647,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params) MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC6, &rx_tx_in_reset); - if (!rx_tx_in_reset) { + if ((!rx_tx_in_reset) && + (params->link_flags & + PHY_INITIALIZED)) { bnx2x_warpcore_reset_lane(bp, phy, 1); bnx2x_warpcore_config_sfi(phy, params); bnx2x_warpcore_reset_lane(bp, phy, 0); @@ -12527,6 +12529,8 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; vars->phy_flags = 0; + vars->check_kr2_recovery_cnt = 0; + params->link_flags = PHY_INITIALIZED; /* Driver opens NIG-BRB filters */ bnx2x_set_rx_filter(params, 1); /* Check if link flap can be avoided */ @@ -12691,6 +12695,7 @@ int bnx2x_lfa_reset(struct link_params *params, struct bnx2x *bp = params->bp; vars->link_up = 0; vars->phy_flags = 0; + params->link_flags &= ~PHY_INITIALIZED; if (!params->lfa_base) return bnx2x_link_reset(params, vars, 1); /* @@ -13411,6 +13416,7 @@ static void bnx2x_disable_kr2(struct link_params *params, vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; bnx2x_update_link_attr(params, vars->link_attr_sync); + vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; /* Restart AN on leading lane */ bnx2x_warpcore_restart_AN_KR(phy, params); } @@ -13439,6 +13445,15 @@ static void bnx2x_check_kr2_wa(struct link_params *params, return; } + /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery + * since some switches tend to reinit the AN process and clear the + * advertised BP/NP after ~2 seconds causing the KR2 to be disabled + * and recovered many times + */ + if (vars->check_kr2_recovery_cnt > 0) { + vars->check_kr2_recovery_cnt--; + return; + } lane = bnx2x_get_warpcore_lane(phy, params); CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, lane); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index be5c195d03dd..56c2aae4e2c8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -309,6 +309,7 @@ struct link_params { req_flow_ctrl is set to AUTO */ u16 link_flags; #define LINK_FLAGS_INT_DISABLED (1<<0) +#define PHY_INITIALIZED (1<<1) u32 lfa_base; }; @@ -342,7 +343,8 @@ struct link_vars { u32 link_status; u32 eee_status; u8 fault_detected; - u8 rsrv1; + u8 check_kr2_recovery_cnt; +#define CHECK_KR2_RECOVERY_CNT 5 u16 periodic_flags; #define PERIODIC_FLAGS_LINK_EVENT 0x0001 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 364e37ecbc5c..198f6f1c9ad5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -459,8 +459,9 @@ struct bnx2x_fw_port_stats_old { #define UPDATE_QSTAT(s, t) \ do { \ - qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \ qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \ + qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \ + + ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \ } while (0) #define UPDATE_QSTAT_OLD(f) \ |