diff options
author | David S. Miller <davem@davemloft.net> | 2015-06-25 13:30:43 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-06-25 13:30:43 (GMT) |
commit | 011cb197a84ed547c2b6b12a86adbeec1be0fdaf (patch) | |
tree | 7497a7f26f8cd0fcfdca219b1986d3d4fd1652a7 | |
parent | b175c3a44fab06e1eccc793e3dadccbf6afc54cf (diff) | |
parent | 592b9b8d687827086344705631494e5f232bee50 (diff) | |
download | linux-011cb197a84ed547c2b6b12a86adbeec1be0fdaf.tar.xz |
Merge branch 'bnx2x'
Yuval Mintz says:
====================
bnx2x: various fixes
This patch series contains several small fixes [with the possible
exception of the first 2 link fixes] for various driver flows.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 58 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 43 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 57 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 2 |
6 files changed, 129 insertions, 51 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 7a4aaa3..b4bfdd2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -2418,10 +2418,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR) -#define HW_PRTY_ASSERT_SET_3 (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \ - AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \ - AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY | \ - AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY) +#define HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD \ + (AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \ + AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \ + AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY) + +#define HW_PRTY_ASSERT_SET_3 (HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD | \ + AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY) #define HW_PRTY_ASSERT_SET_4 (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | \ AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e2a6533..45e7c65 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3421,8 +3421,13 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, u32 wnd_sum = 0; /* Headers length */ - hlen = (int)(skb_transport_header(skb) - skb->data) + - tcp_hdrlen(skb); + if (xmit_type & XMIT_GSO_ENC) + hlen = (int)(skb_inner_transport_header(skb) - + skb->data) + + inner_tcp_hdrlen(skb); + else + hlen = (int)(skb_transport_header(skb) - + skb->data) + tcp_hdrlen(skb); /* Amount of data (w/o headers) on linear part of SKB*/ first_bd_sz = skb_headlen(skb) - hlen; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 48ed005..76b9052 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -257,14 +257,15 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); int cfg_idx = bnx2x_get_link_cfg_idx(bp); + u32 media_type; /* Dual Media boards present all available port types */ cmd->supported = bp->port.supported[cfg_idx] | (bp->port.supported[cfg_idx ^ 1] & (SUPPORTED_TP | SUPPORTED_FIBRE)); cmd->advertising = bp->port.advertising[cfg_idx]; - if (bp->link_params.phy[bnx2x_get_cur_phy_idx(bp)].media_type == - ETH_PHY_SFP_1G_FIBER) { + media_type = bp->link_params.phy[bnx2x_get_cur_phy_idx(bp)].media_type; + if (media_type == ETH_PHY_SFP_1G_FIBER) { cmd->supported &= ~(SUPPORTED_10000baseT_Full); cmd->advertising &= ~(ADVERTISED_10000baseT_Full); } @@ -312,12 +313,26 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->lp_advertising |= ADVERTISED_100baseT_Full; if (status & LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE) cmd->lp_advertising |= ADVERTISED_1000baseT_Half; - if (status & LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE) - cmd->lp_advertising |= ADVERTISED_1000baseT_Full; + if (status & LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE) { + if (media_type == ETH_PHY_KR) { + cmd->lp_advertising |= + ADVERTISED_1000baseKX_Full; + } else { + cmd->lp_advertising |= + ADVERTISED_1000baseT_Full; + } + } if (status & LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE) cmd->lp_advertising |= ADVERTISED_2500baseX_Full; - if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE) - cmd->lp_advertising |= ADVERTISED_10000baseT_Full; + if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE) { + if (media_type == ETH_PHY_KR) { + cmd->lp_advertising |= + ADVERTISED_10000baseKR_Full; + } else { + cmd->lp_advertising |= + ADVERTISED_10000baseT_Full; + } + } if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE) cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full; } @@ -564,15 +579,20 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported[cfg_idx] & - SUPPORTED_1000baseT_Full)) { + if (bp->port.supported[cfg_idx] & + SUPPORTED_1000baseT_Full) { + advertising = (ADVERTISED_1000baseT_Full | + ADVERTISED_TP); + + } else if (bp->port.supported[cfg_idx] & + SUPPORTED_1000baseKX_Full) { + advertising = ADVERTISED_1000baseKX_Full; + } else { DP(BNX2X_MSG_ETHTOOL, "1G full not supported\n"); return -EINVAL; } - advertising = (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); break; case SPEED_2500: @@ -600,17 +620,22 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } phy_idx = bnx2x_get_cur_phy_idx(bp); - if (!(bp->port.supported[cfg_idx] - & SUPPORTED_10000baseT_Full) || - (bp->link_params.phy[phy_idx].media_type == + if ((bp->port.supported[cfg_idx] & + SUPPORTED_10000baseT_Full) && + (bp->link_params.phy[phy_idx].media_type != ETH_PHY_SFP_1G_FIBER)) { + advertising = (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + } else if (bp->port.supported[cfg_idx] & + SUPPORTED_10000baseKR_Full) { + advertising = (ADVERTISED_10000baseKR_Full | + ADVERTISED_FIBRE); + } else { DP(BNX2X_MSG_ETHTOOL, "10G full not supported\n"); return -EINVAL; } - advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); break; default: @@ -633,6 +658,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) bp->link_params.multi_phy_config = new_multi_phy_config; if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_force_link_reset(bp); bnx2x_link_set(bp); } @@ -1204,6 +1230,7 @@ static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) { DP(BNX2X_MSG_ETHTOOL | BNX2X_MSG_NVM, "cannot get access to nvram interface\n"); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM); return -EBUSY; } @@ -1944,6 +1971,7 @@ static int bnx2x_set_pauseparam(struct net_device *dev, if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); + bnx2x_force_link_reset(bp); bnx2x_link_set(bp); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 21a0d6a..a0b03c2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -3392,9 +3392,9 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, case BNX2X_FLOW_CTRL_AUTO: switch (params->req_fc_auto_adv) { case BNX2X_FLOW_CTRL_BOTH: + case BNX2X_FLOW_CTRL_RX: *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; break; - case BNX2X_FLOW_CTRL_RX: case BNX2X_FLOW_CTRL_TX: *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; @@ -3488,14 +3488,21 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); } -static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) -{ /* LD LP */ +static void bnx2x_pause_resolve(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars, + u32 pause_result) +{ + struct bnx2x *bp = params->bp; + /* LD LP */ switch (pause_result) { /* ASYM P ASYM P */ case 0xb: /* 1 0 1 1 */ + DP(NETIF_MSG_LINK, "Flow Control: TX only\n"); vars->flow_ctrl = BNX2X_FLOW_CTRL_TX; break; case 0xe: /* 1 1 1 0 */ + DP(NETIF_MSG_LINK, "Flow Control: RX only\n"); vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; break; @@ -3503,10 +3510,22 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) case 0x7: /* 0 1 1 1 */ case 0xd: /* 1 1 0 1 */ case 0xf: /* 1 1 1 1 */ - vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; + /* If the user selected to advertise RX ONLY, + * although we advertised both, need to enable + * RX only. + */ + if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) { + DP(NETIF_MSG_LINK, "Flow Control: RX & TX\n"); + vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; + } else { + DP(NETIF_MSG_LINK, "Flow Control: RX only\n"); + vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; + } break; default: + DP(NETIF_MSG_LINK, "Flow Control: None\n"); + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; break; } if (pause_result & (1<<0)) @@ -3567,7 +3586,7 @@ static void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy, pause_result |= (lp_pause & MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result); - bnx2x_pause_resolve(vars, pause_result); + bnx2x_pause_resolve(phy, params, vars, pause_result); } @@ -5396,7 +5415,7 @@ static void bnx2x_update_adv_fc(struct bnx2x_phy *phy, MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result); } - bnx2x_pause_resolve(vars, pause_result); + bnx2x_pause_resolve(phy, params, vars, pause_result); } @@ -7129,7 +7148,7 @@ static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, pause_result |= (lp_pause & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; - bnx2x_pause_resolve(vars, pause_result); + bnx2x_pause_resolve(phy, params, vars, pause_result); DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", pause_result); } @@ -11474,7 +11493,9 @@ static const struct bnx2x_phy phy_warpcore = { SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | + SUPPORTED_1000baseKX_Full | SUPPORTED_10000baseT_Full | + SUPPORTED_10000baseKR_Full | SUPPORTED_20000baseKR2_Full | SUPPORTED_20000baseMLD2_Full | SUPPORTED_FIBRE | @@ -11980,8 +12001,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, break; case PORT_HW_CFG_NET_SERDES_IF_KR: phy->media_type = ETH_PHY_KR; - phy->supported &= (SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | + phy->supported &= (SUPPORTED_1000baseKX_Full | + SUPPORTED_10000baseKR_Full | SUPPORTED_FIBRE | SUPPORTED_Autoneg | SUPPORTED_Pause | @@ -11999,8 +12020,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->media_type = ETH_PHY_KR; phy->flags |= FLAGS_WC_DUAL_MODE; phy->supported &= (SUPPORTED_20000baseKR2_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseKR_Full | + SUPPORTED_1000baseKX_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE | SUPPORTED_Pause | diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 33501bc..3df03bb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -2287,13 +2287,11 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio, u32 mode) void bnx2x_calc_fc_adv(struct bnx2x *bp) { u8 cfg_idx = bnx2x_get_link_cfg_idx(bp); + + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | + ADVERTISED_Pause); switch (bp->link_vars.ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { - case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: - bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); - break; - case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause | ADVERTISED_Pause); @@ -2304,8 +2302,6 @@ void bnx2x_calc_fc_adv(struct bnx2x *bp) break; default: - bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); break; } } @@ -2351,12 +2347,16 @@ int bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) if (load_mode == LOAD_DIAG) { struct link_params *lp = &bp->link_params; lp->loopback_mode = LOOPBACK_XGXS; - /* do PHY loopback at 10G speed, if possible */ - if (lp->req_line_speed[cfx_idx] < SPEED_10000) { + /* Prefer doing PHY loopback at highest speed */ + if (lp->req_line_speed[cfx_idx] < SPEED_20000) { if (lp->speed_cap_mask[cfx_idx] & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + PORT_HW_CFG_SPEED_CAPABILITY_D0_20G) lp->req_line_speed[cfx_idx] = - SPEED_10000; + SPEED_20000; + else if (lp->speed_cap_mask[cfx_idx] & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + lp->req_line_speed[cfx_idx] = + SPEED_10000; else lp->req_line_speed[cfx_idx] = SPEED_1000; @@ -4867,9 +4867,7 @@ static bool bnx2x_check_blocks_with_parity3(struct bnx2x *bp, u32 sig, res = true; break; case AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY: - if (print) - _print_next_block((*par_num)++, - "MCP SCPAD"); + (*par_num)++; /* clear latched SCPAD PATIRY from MCP */ REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 1UL << 10); @@ -4931,6 +4929,7 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, (sig[3] & HW_PRTY_ASSERT_SET_3) || (sig[4] & HW_PRTY_ASSERT_SET_4)) { int par_num = 0; + DP(NETIF_MSG_HW, "Was parity error: HW block parity attention:\n" "[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x [4]:0x%08x\n", sig[0] & HW_PRTY_ASSERT_SET_0, @@ -4938,9 +4937,18 @@ static bool bnx2x_parity_attn(struct bnx2x *bp, bool *global, bool print, sig[2] & HW_PRTY_ASSERT_SET_2, sig[3] & HW_PRTY_ASSERT_SET_3, sig[4] & HW_PRTY_ASSERT_SET_4); - if (print) - netdev_err(bp->dev, - "Parity errors detected in blocks: "); + if (print) { + if (((sig[0] & HW_PRTY_ASSERT_SET_0) || + (sig[1] & HW_PRTY_ASSERT_SET_1) || + (sig[2] & HW_PRTY_ASSERT_SET_2) || + (sig[4] & HW_PRTY_ASSERT_SET_4)) || + (sig[3] & HW_PRTY_ASSERT_SET_3_WITHOUT_SCPAD)) { + netdev_err(bp->dev, + "Parity errors detected in blocks: "); + } else { + print = false; + } + } res |= bnx2x_check_blocks_with_parity0(bp, sig[0] & HW_PRTY_ASSERT_SET_0, &par_num, print); res |= bnx2x_check_blocks_with_parity1(bp, @@ -8431,7 +8439,7 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set) BNX2X_ETH_MAC, &ramrod_flags); } else { /* vf */ return bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr, - bp->fp->index, true); + bp->fp->index, set); } } @@ -11147,6 +11155,12 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) bp->port.advertising[idx] |= (ADVERTISED_1000baseT_Full | ADVERTISED_TP); + } else if (bp->port.supported[idx] & + SUPPORTED_1000baseKX_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_1000; + bp->port.advertising[idx] |= + ADVERTISED_1000baseKX_Full; } else { BNX2X_ERR("NVRAM config error. Invalid link_config 0x%x speed_cap_mask 0x%x\n", link_config, @@ -11179,6 +11193,13 @@ static void bnx2x_link_settings_requested(struct bnx2x *bp) bp->port.advertising[idx] |= (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); + } else if (bp->port.supported[idx] & + SUPPORTED_10000baseKR_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseKR_Full | + ADVERTISED_FIBRE); } else { BNX2X_ERR("NVRAM config error. Invalid link_config 0x%x speed_cap_mask 0x%x\n", link_config, diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 07cdf9b..4ad415a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -424,7 +424,7 @@ static void __bnx2x_vlan_mac_h_exec_pending(struct bnx2x *bp, o->head_exe_request = false; o->saved_ramrod_flags = 0; rc = bnx2x_exe_queue_step(bp, &o->exe_queue, &ramrod_flags); - if (rc != 0) { + if ((rc != 0) && (rc != 1)) { BNX2X_ERR("execution of pending commands failed with rc %d\n", rc); #ifdef BNX2X_STOP_ON_ERROR |