Commit 50f850fd authored by David S. Miller's avatar David S. Miller

Merge branch 'bnx2x'

Dmitry Kravkov says:

====================
Please consider applying the series of bnx2x fixes to net:
	* statistics may cause FW assert
	* missing fairness configuration in DCB flow
	* memory leak in sriov related part
	* Illegal PTE access
	* Pagefault crash in shutdown flow with cnic
v1->v2
	* fixed sparse error pointed by Joe Perches
	* added missing signed-off from Sergei Shtylyov
v2->v3
	* added missing signed-off from Sergei Shtylyov
	* fixed formatting from Sergei Shtylyov
v3->v4
	* patch 1/6: fixed declaration order
	* patch 2/6 replaced with: protect flows using set_bit constraints
v4->v5
	* patch 2/6: replace proprietary locking with semaphore
	* droped 1/6: since adds redundant code from Benjamin Poirier
The following patchset contains four netfilter fixes, they are:

* Fix possible invalid access and mangling of the TCPMSS option in
  xt_TCPMSS. This was spotted by Julian Anastasov.

* Fix possible off by one access and mangling of the TCP packet in
  xt_TCPOPTSTRIP, also spotted by Julian Anastasov.

* Fix possible information leak due to missing initialization of one
  padding field of several structures that are included in nfqueue and
  nflog netlink messages, from Dan Carpenter.

* Fix TCP window tracking with Fast Open, from Yuchung Cheng.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 205057ae 6ef5a92c
...@@ -1502,6 +1502,7 @@ struct bnx2x { ...@@ -1502,6 +1502,7 @@ struct bnx2x {
#define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21) #define BC_SUPPORTS_DCBX_MSG_NON_PMF (1 << 21)
#define IS_VF_FLAG (1 << 22) #define IS_VF_FLAG (1 << 22)
#define INTERRUPTS_ENABLED_FLAG (1 << 23) #define INTERRUPTS_ENABLED_FLAG (1 << 23)
#define BC_SUPPORTS_RMMOD_CMD (1 << 24)
#define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG) #define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG)
...@@ -1830,6 +1831,8 @@ struct bnx2x { ...@@ -1830,6 +1831,8 @@ struct bnx2x {
int fp_array_size; int fp_array_size;
u32 dump_preset_idx; u32 dump_preset_idx;
bool stats_started;
struct semaphore stats_sema;
}; };
/* Tx queues may be less or equal to Rx queues */ /* Tx queues may be less or equal to Rx queues */
...@@ -2451,4 +2454,6 @@ enum bnx2x_pci_bus_speed { ...@@ -2451,4 +2454,6 @@ enum bnx2x_pci_bus_speed {
BNX2X_PCI_LINK_SPEED_5000 = 5000, BNX2X_PCI_LINK_SPEED_5000 = 5000,
BNX2X_PCI_LINK_SPEED_8000 = 8000 BNX2X_PCI_LINK_SPEED_8000 = 8000
}; };
void bnx2x_set_local_cmng(struct bnx2x *bp);
#endif /* bnx2x.h */ #endif /* bnx2x.h */
...@@ -753,6 +753,10 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) ...@@ -753,6 +753,10 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
bnx2x_pfc_set_pfc(bp); bnx2x_pfc_set_pfc(bp);
bnx2x_dcbx_update_ets_params(bp); bnx2x_dcbx_update_ets_params(bp);
/* ets may affect cmng configuration: reinit it in hw */
bnx2x_set_local_cmng(bp);
bnx2x_dcbx_resume_hw_tx(bp); bnx2x_dcbx_resume_hw_tx(bp);
return; return;
......
...@@ -1300,6 +1300,9 @@ struct drv_func_mb { ...@@ -1300,6 +1300,9 @@ struct drv_func_mb {
#define DRV_MSG_CODE_EEE_RESULTS_ACK 0xda000000 #define DRV_MSG_CODE_EEE_RESULTS_ACK 0xda000000
#define DRV_MSG_CODE_RMMOD 0xdb000000
#define REQ_BC_VER_4_RMMOD_CMD 0x0007080f
#define DRV_MSG_CODE_SET_MF_BW 0xe0000000 #define DRV_MSG_CODE_SET_MF_BW 0xe0000000
#define REQ_BC_VER_4_SET_MF_BW 0x00060202 #define REQ_BC_VER_4_SET_MF_BW 0x00060202
#define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000 #define DRV_MSG_CODE_SET_MF_BW_ACK 0xe1000000
...@@ -1372,6 +1375,8 @@ struct drv_func_mb { ...@@ -1372,6 +1375,8 @@ struct drv_func_mb {
#define FW_MSG_CODE_EEE_RESULS_ACK 0xda100000 #define FW_MSG_CODE_EEE_RESULS_ACK 0xda100000
#define FW_MSG_CODE_RMMOD_ACK 0xdb100000
#define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000 #define FW_MSG_CODE_SET_MF_BW_SENT 0xe0000000
#define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000 #define FW_MSG_CODE_SET_MF_BW_DONE 0xe1000000
......
...@@ -2476,7 +2476,7 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) ...@@ -2476,7 +2476,7 @@ static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type)
input.port_rate = bp->link_vars.line_speed; input.port_rate = bp->link_vars.line_speed;
if (cmng_type == CMNG_FNS_MINMAX) { if (cmng_type == CMNG_FNS_MINMAX && input.port_rate) {
int vn; int vn;
/* read mf conf from shmem */ /* read mf conf from shmem */
...@@ -2533,6 +2533,21 @@ static void storm_memset_cmng(struct bnx2x *bp, ...@@ -2533,6 +2533,21 @@ static void storm_memset_cmng(struct bnx2x *bp,
} }
} }
/* init cmng mode in HW according to local configuration */
void bnx2x_set_local_cmng(struct bnx2x *bp)
{
int cmng_fns = bnx2x_get_cmng_fns_mode(bp);
if (cmng_fns != CMNG_FNS_NONE) {
bnx2x_cmng_fns_init(bp, false, cmng_fns);
storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
} else {
/* rate shaping and fairness are disabled */
DP(NETIF_MSG_IFUP,
"single function mode without fairness\n");
}
}
/* This function is called upon link interrupt */ /* This function is called upon link interrupt */
static void bnx2x_link_attn(struct bnx2x *bp) static void bnx2x_link_attn(struct bnx2x *bp)
{ {
...@@ -2568,17 +2583,8 @@ static void bnx2x_link_attn(struct bnx2x *bp) ...@@ -2568,17 +2583,8 @@ static void bnx2x_link_attn(struct bnx2x *bp)
bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
} }
if (bp->link_vars.link_up && bp->link_vars.line_speed) { if (bp->link_vars.link_up && bp->link_vars.line_speed)
int cmng_fns = bnx2x_get_cmng_fns_mode(bp); bnx2x_set_local_cmng(bp);
if (cmng_fns != CMNG_FNS_NONE) {
bnx2x_cmng_fns_init(bp, false, cmng_fns);
storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp));
} else
/* rate shaping and fairness are disabled */
DP(NETIF_MSG_IFUP,
"single function mode without fairness\n");
}
__bnx2x_link_report(bp); __bnx2x_link_report(bp);
...@@ -10362,6 +10368,10 @@ static void bnx2x_get_common_hwinfo(struct bnx2x *bp) ...@@ -10362,6 +10368,10 @@ static void bnx2x_get_common_hwinfo(struct bnx2x *bp)
bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ? bp->flags |= (val >= REQ_BC_VER_4_DCBX_ADMIN_MSG_NON_PMF) ?
BC_SUPPORTS_DCBX_MSG_NON_PMF : 0; BC_SUPPORTS_DCBX_MSG_NON_PMF : 0;
bp->flags |= (val >= REQ_BC_VER_4_RMMOD_CMD) ?
BC_SUPPORTS_RMMOD_CMD : 0;
boot_mode = SHMEM_RD(bp, boot_mode = SHMEM_RD(bp,
dev_info.port_feature_config[BP_PORT(bp)].mba_config) & dev_info.port_feature_config[BP_PORT(bp)].mba_config) &
PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK; PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK;
...@@ -11524,6 +11534,7 @@ static int bnx2x_init_bp(struct bnx2x *bp) ...@@ -11524,6 +11534,7 @@ static int bnx2x_init_bp(struct bnx2x *bp)
mutex_init(&bp->port.phy_mutex); mutex_init(&bp->port.phy_mutex);
mutex_init(&bp->fw_mb_mutex); mutex_init(&bp->fw_mb_mutex);
spin_lock_init(&bp->stats_lock); spin_lock_init(&bp->stats_lock);
sema_init(&bp->stats_sema, 1);
INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task);
INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task); INIT_DELAYED_WORK(&bp->sp_rtnl_task, bnx2x_sp_rtnl_task);
...@@ -12817,13 +12828,17 @@ static void __bnx2x_remove(struct pci_dev *pdev, ...@@ -12817,13 +12828,17 @@ static void __bnx2x_remove(struct pci_dev *pdev,
bnx2x_dcbnl_update_applist(bp, true); bnx2x_dcbnl_update_applist(bp, true);
#endif #endif
if (IS_PF(bp) &&
!BP_NOMCP(bp) &&
(bp->flags & BC_SUPPORTS_RMMOD_CMD))
bnx2x_fw_command(bp, DRV_MSG_CODE_RMMOD, 0);
/* Close the interface - either directly or implicitly */ /* Close the interface - either directly or implicitly */
if (remove_netdev) { if (remove_netdev) {
unregister_netdev(dev); unregister_netdev(dev);
} else { } else {
rtnl_lock(); rtnl_lock();
if (netif_running(dev)) dev_close(dev);
bnx2x_close(dev);
rtnl_unlock(); rtnl_unlock();
} }
......
...@@ -3463,7 +3463,7 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp) ...@@ -3463,7 +3463,7 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp)
alloc_mem_err: alloc_mem_err:
BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping, BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping,
sizeof(struct bnx2x_vf_mbx_msg)); sizeof(struct bnx2x_vf_mbx_msg));
BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping, BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping,
sizeof(union pf_vf_bulletin)); sizeof(union pf_vf_bulletin));
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -221,7 +221,8 @@ static int bnx2x_stats_comp(struct bnx2x *bp) ...@@ -221,7 +221,8 @@ static int bnx2x_stats_comp(struct bnx2x *bp)
* Statistics service functions * Statistics service functions
*/ */
static void bnx2x_stats_pmf_update(struct bnx2x *bp) /* should be called under stats_sema */
static void __bnx2x_stats_pmf_update(struct bnx2x *bp)
{ {
struct dmae_command *dmae; struct dmae_command *dmae;
u32 opcode; u32 opcode;
...@@ -518,7 +519,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp) ...@@ -518,7 +519,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp)
*stats_comp = 0; *stats_comp = 0;
} }
static void bnx2x_stats_start(struct bnx2x *bp) /* should be called under stats_sema */
static void __bnx2x_stats_start(struct bnx2x *bp)
{ {
/* vfs travel through here as part of the statistics FSM, but no action /* vfs travel through here as part of the statistics FSM, but no action
* is required * is required
...@@ -534,13 +536,34 @@ static void bnx2x_stats_start(struct bnx2x *bp) ...@@ -534,13 +536,34 @@ static void bnx2x_stats_start(struct bnx2x *bp)
bnx2x_hw_stats_post(bp); bnx2x_hw_stats_post(bp);
bnx2x_storm_stats_post(bp); bnx2x_storm_stats_post(bp);
bp->stats_started = true;
}
static void bnx2x_stats_start(struct bnx2x *bp)
{
if (down_timeout(&bp->stats_sema, HZ/10))
BNX2X_ERR("Unable to acquire stats lock\n");
__bnx2x_stats_start(bp);
up(&bp->stats_sema);
} }
static void bnx2x_stats_pmf_start(struct bnx2x *bp) static void bnx2x_stats_pmf_start(struct bnx2x *bp)
{ {
if (down_timeout(&bp->stats_sema, HZ/10))
BNX2X_ERR("Unable to acquire stats lock\n");
bnx2x_stats_comp(bp); bnx2x_stats_comp(bp);
bnx2x_stats_pmf_update(bp); __bnx2x_stats_pmf_update(bp);
bnx2x_stats_start(bp); __bnx2x_stats_start(bp);
up(&bp->stats_sema);
}
static void bnx2x_stats_pmf_update(struct bnx2x *bp)
{
if (down_timeout(&bp->stats_sema, HZ/10))
BNX2X_ERR("Unable to acquire stats lock\n");
__bnx2x_stats_pmf_update(bp);
up(&bp->stats_sema);
} }
static void bnx2x_stats_restart(struct bnx2x *bp) static void bnx2x_stats_restart(struct bnx2x *bp)
...@@ -550,8 +573,11 @@ static void bnx2x_stats_restart(struct bnx2x *bp) ...@@ -550,8 +573,11 @@ static void bnx2x_stats_restart(struct bnx2x *bp)
*/ */
if (IS_VF(bp)) if (IS_VF(bp))
return; return;
if (down_timeout(&bp->stats_sema, HZ/10))
BNX2X_ERR("Unable to acquire stats lock\n");
bnx2x_stats_comp(bp); bnx2x_stats_comp(bp);
bnx2x_stats_start(bp); __bnx2x_stats_start(bp);
up(&bp->stats_sema);
} }
static void bnx2x_bmac_stats_update(struct bnx2x *bp) static void bnx2x_bmac_stats_update(struct bnx2x *bp)
...@@ -888,9 +914,7 @@ static int bnx2x_storm_stats_validate_counters(struct bnx2x *bp) ...@@ -888,9 +914,7 @@ static int bnx2x_storm_stats_validate_counters(struct bnx2x *bp)
/* Make sure we use the value of the counter /* Make sure we use the value of the counter
* used for sending the last stats ramrod. * used for sending the last stats ramrod.
*/ */
spin_lock_bh(&bp->stats_lock);
cur_stats_counter = bp->stats_counter - 1; cur_stats_counter = bp->stats_counter - 1;
spin_unlock_bh(&bp->stats_lock);
/* are storm stats valid? */ /* are storm stats valid? */
if (le16_to_cpu(counters->xstats_counter) != cur_stats_counter) { if (le16_to_cpu(counters->xstats_counter) != cur_stats_counter) {
...@@ -1227,12 +1251,18 @@ static void bnx2x_stats_update(struct bnx2x *bp) ...@@ -1227,12 +1251,18 @@ static void bnx2x_stats_update(struct bnx2x *bp)
{ {
u32 *stats_comp = bnx2x_sp(bp, stats_comp); u32 *stats_comp = bnx2x_sp(bp, stats_comp);
if (bnx2x_edebug_stats_stopped(bp)) /* we run update from timer context, so give up
* if somebody is in the middle of transition
*/
if (down_trylock(&bp->stats_sema))
return; return;
if (bnx2x_edebug_stats_stopped(bp) || !bp->stats_started)
goto out;
if (IS_PF(bp)) { if (IS_PF(bp)) {
if (*stats_comp != DMAE_COMP_VAL) if (*stats_comp != DMAE_COMP_VAL)
return; goto out;
if (bp->port.pmf) if (bp->port.pmf)
bnx2x_hw_stats_update(bp); bnx2x_hw_stats_update(bp);
...@@ -1242,7 +1272,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) ...@@ -1242,7 +1272,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
BNX2X_ERR("storm stats were not updated for 3 times\n"); BNX2X_ERR("storm stats were not updated for 3 times\n");
bnx2x_panic(); bnx2x_panic();
} }
return; goto out;
} }
} else { } else {
/* vf doesn't collect HW statistics, and doesn't get completions /* vf doesn't collect HW statistics, and doesn't get completions
...@@ -1256,7 +1286,7 @@ static void bnx2x_stats_update(struct bnx2x *bp) ...@@ -1256,7 +1286,7 @@ static void bnx2x_stats_update(struct bnx2x *bp)
/* vf is done */ /* vf is done */
if (IS_VF(bp)) if (IS_VF(bp))
return; goto out;
if (netif_msg_timer(bp)) { if (netif_msg_timer(bp)) {
struct bnx2x_eth_stats *estats = &bp->eth_stats; struct bnx2x_eth_stats *estats = &bp->eth_stats;
...@@ -1267,6 +1297,9 @@ static void bnx2x_stats_update(struct bnx2x *bp) ...@@ -1267,6 +1297,9 @@ static void bnx2x_stats_update(struct bnx2x *bp)
bnx2x_hw_stats_post(bp); bnx2x_hw_stats_post(bp);
bnx2x_storm_stats_post(bp); bnx2x_storm_stats_post(bp);
out:
up(&bp->stats_sema);
} }
static void bnx2x_port_stats_stop(struct bnx2x *bp) static void bnx2x_port_stats_stop(struct bnx2x *bp)
...@@ -1332,6 +1365,11 @@ static void bnx2x_stats_stop(struct bnx2x *bp) ...@@ -1332,6 +1365,11 @@ static void bnx2x_stats_stop(struct bnx2x *bp)
{ {
int update = 0; int update = 0;
if (down_timeout(&bp->stats_sema, HZ/10))
BNX2X_ERR("Unable to acquire stats lock\n");
bp->stats_started = false;
bnx2x_stats_comp(bp); bnx2x_stats_comp(bp);
if (bp->port.pmf) if (bp->port.pmf)
...@@ -1348,6 +1386,8 @@ static void bnx2x_stats_stop(struct bnx2x *bp) ...@@ -1348,6 +1386,8 @@ static void bnx2x_stats_stop(struct bnx2x *bp)
bnx2x_hw_stats_post(bp); bnx2x_hw_stats_post(bp);
bnx2x_stats_comp(bp); bnx2x_stats_comp(bp);
} }
up(&bp->stats_sema);
} }
static void bnx2x_stats_do_nothing(struct bnx2x *bp) static void bnx2x_stats_do_nothing(struct bnx2x *bp)
...@@ -1376,15 +1416,17 @@ static const struct { ...@@ -1376,15 +1416,17 @@ static const struct {
void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event)
{ {
enum bnx2x_stats_state state; enum bnx2x_stats_state state;
void (*action)(struct bnx2x *bp);
if (unlikely(bp->panic)) if (unlikely(bp->panic))
return; return;
spin_lock_bh(&bp->stats_lock); spin_lock_bh(&bp->stats_lock);
state = bp->stats_state; state = bp->stats_state;
bp->stats_state = bnx2x_stats_stm[state][event].next_state; bp->stats_state = bnx2x_stats_stm[state][event].next_state;
action = bnx2x_stats_stm[state][event].action;
spin_unlock_bh(&bp->stats_lock); spin_unlock_bh(&bp->stats_lock);
bnx2x_stats_stm[state][event].action(bp); action(bp);
if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp))
DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n",
......
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