diff options
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 57ff5b3bcce..46167c08172 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -57,8 +57,8 @@ #include "bnx2x_init_ops.h" #include "bnx2x_dump.h" -#define DRV_MODULE_VERSION "1.52.53-1" -#define DRV_MODULE_RELDATE "2010/18/04" +#define DRV_MODULE_VERSION "1.52.53-2" +#define DRV_MODULE_RELDATE "2010/21/07" #define BNX2X_BC_VER 0x040200 #include <linux/firmware.h> @@ -3789,6 +3789,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) struct eth_query_ramrod_data ramrod_data = {0}; int i, rc; + spin_lock_bh(&bp->stats_lock); + ramrod_data.drv_counter = bp->stats_counter++; ramrod_data.collect_port = bp->port.pmf ? 1 : 0; for_each_queue(bp, i) @@ -3802,6 +3804,8 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) bp->spq_left++; bp->stats_pending = 1; } + + spin_unlock_bh(&bp->stats_lock); } } @@ -4367,6 +4371,14 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) struct host_func_stats *fstats = bnx2x_sp(bp, func_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; int i; + u16 cur_stats_counter; + + /* Make sure we use the value of the counter + * used for sending the last stats ramrod. + */ + spin_lock_bh(&bp->stats_lock); + cur_stats_counter = bp->stats_counter - 1; + spin_unlock_bh(&bp->stats_lock); memcpy(&(fstats->total_bytes_received_hi), &(bnx2x_sp(bp, func_stats_base)->total_bytes_received_hi), @@ -4394,25 +4406,22 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) u32 diff; /* are storm stats valid? */ - if ((u16)(le16_to_cpu(xclient->stats_counter) + 1) != - bp->stats_counter) { + if (le16_to_cpu(xclient->stats_counter) != cur_stats_counter) { DP(BNX2X_MSG_STATS, "[%d] stats not updated by xstorm" " xstorm counter (0x%x) != stats_counter (0x%x)\n", - i, xclient->stats_counter, bp->stats_counter); + i, xclient->stats_counter, cur_stats_counter + 1); return -1; } - if ((u16)(le16_to_cpu(tclient->stats_counter) + 1) != - bp->stats_counter) { + if (le16_to_cpu(tclient->stats_counter) != cur_stats_counter) { DP(BNX2X_MSG_STATS, "[%d] stats not updated by tstorm" " tstorm counter (0x%x) != stats_counter (0x%x)\n", - i, tclient->stats_counter, bp->stats_counter); + i, tclient->stats_counter, cur_stats_counter + 1); return -2; } - if ((u16)(le16_to_cpu(uclient->stats_counter) + 1) != - bp->stats_counter) { + if (le16_to_cpu(uclient->stats_counter) != cur_stats_counter) { DP(BNX2X_MSG_STATS, "[%d] stats not updated by ustorm" " ustorm counter (0x%x) != stats_counter (0x%x)\n", - i, uclient->stats_counter, bp->stats_counter); + i, uclient->stats_counter, cur_stats_counter + 1); return -4; } @@ -4849,16 +4858,18 @@ static const struct { static void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event) { - enum bnx2x_stats_state state = bp->stats_state; + enum bnx2x_stats_state state; if (unlikely(bp->panic)) return; - bnx2x_stats_stm[state][event].action(bp); + /* Protect a state change flow */ + spin_lock_bh(&bp->stats_lock); + state = bp->stats_state; bp->stats_state = bnx2x_stats_stm[state][event].next_state; + spin_unlock_bh(&bp->stats_lock); - /* Make sure the state has been "changed" */ - smp_wmb(); + bnx2x_stats_stm[state][event].action(bp); if ((event != STATS_EVENT_UPDATE) || netif_msg_timer(bp)) DP(BNX2X_MSG_STATS, "state %d -> event %d -> state %d\n", @@ -9908,6 +9919,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) mutex_init(&bp->port.phy_mutex); mutex_init(&bp->fw_mb_mutex); + spin_lock_init(&bp->stats_lock); #ifdef BCM_CNIC mutex_init(&bp->cnic_mutex); #endif |