aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-07-11 13:32:12 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-11 13:32:12 -0400
commit4c17e1febd73c3b2467fd9f67e0017a82805196a (patch)
treee2a43c742866d3e36b86a9c2bcc4513f426a997d
parentde92cd6cf4899c0876a8f5519769a786ad7cdeea (diff)
parent9b0436c3f29483ca91d890b0072c0c02e2e535ed (diff)
Merge branch 'bnxt_en-Bug-fixes'
Michael Chan says: ==================== bnxt_en: Bug fixes. 3 bug fixes in this series. Fix a crash in bnxt_get_stats64() that can happen if the device is closing and freeing the statistics block at the same time. The 2nd one fixes ethtool -L failing when changing from combined to non-combined mode or vice versa. The last one fixes SRIOV failure on big-endian systems because we were setting a bitmap wrong in a firmware message. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c42
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.h4
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c3
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c2
4 files changed, 35 insertions, 16 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index a19f68f5862d..e7c8539cbddf 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -3458,13 +3458,18 @@ static int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp)
3458 req.ver_upd = DRV_VER_UPD; 3458 req.ver_upd = DRV_VER_UPD;
3459 3459
3460 if (BNXT_PF(bp)) { 3460 if (BNXT_PF(bp)) {
3461 DECLARE_BITMAP(vf_req_snif_bmap, 256); 3461 u32 data[8];
3462 u32 *data = (u32 *)vf_req_snif_bmap;
3463 int i; 3462 int i;
3464 3463
3465 memset(vf_req_snif_bmap, 0, sizeof(vf_req_snif_bmap)); 3464 memset(data, 0, sizeof(data));
3466 for (i = 0; i < ARRAY_SIZE(bnxt_vf_req_snif); i++) 3465 for (i = 0; i < ARRAY_SIZE(bnxt_vf_req_snif); i++) {
3467 __set_bit(bnxt_vf_req_snif[i], vf_req_snif_bmap); 3466 u16 cmd = bnxt_vf_req_snif[i];
3467 unsigned int bit, idx;
3468
3469 idx = cmd / 32;
3470 bit = cmd % 32;
3471 data[idx] |= 1 << bit;
3472 }
3468 3473
3469 for (i = 0; i < 8; i++) 3474 for (i = 0; i < 8; i++)
3470 req.vf_req_fwd[i] = cpu_to_le32(data[i]); 3475 req.vf_req_fwd[i] = cpu_to_le32(data[i]);
@@ -6279,6 +6284,12 @@ static int bnxt_open(struct net_device *dev)
6279 return __bnxt_open_nic(bp, true, true); 6284 return __bnxt_open_nic(bp, true, true);
6280} 6285}
6281 6286
6287static bool bnxt_drv_busy(struct bnxt *bp)
6288{
6289 return (test_bit(BNXT_STATE_IN_SP_TASK, &bp->state) ||
6290 test_bit(BNXT_STATE_READ_STATS, &bp->state));
6291}
6292
6282int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) 6293int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
6283{ 6294{
6284 int rc = 0; 6295 int rc = 0;
@@ -6297,7 +6308,7 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
6297 6308
6298 clear_bit(BNXT_STATE_OPEN, &bp->state); 6309 clear_bit(BNXT_STATE_OPEN, &bp->state);
6299 smp_mb__after_atomic(); 6310 smp_mb__after_atomic();
6300 while (test_bit(BNXT_STATE_IN_SP_TASK, &bp->state)) 6311 while (bnxt_drv_busy(bp))
6301 msleep(20); 6312 msleep(20);
6302 6313
6303 /* Flush rings and and disable interrupts */ 6314 /* Flush rings and and disable interrupts */
@@ -6358,8 +6369,15 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
6358 u32 i; 6369 u32 i;
6359 struct bnxt *bp = netdev_priv(dev); 6370 struct bnxt *bp = netdev_priv(dev);
6360 6371
6361 if (!bp->bnapi) 6372 set_bit(BNXT_STATE_READ_STATS, &bp->state);
6373 /* Make sure bnxt_close_nic() sees that we are reading stats before
6374 * we check the BNXT_STATE_OPEN flag.
6375 */
6376 smp_mb__after_atomic();
6377 if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
6378 clear_bit(BNXT_STATE_READ_STATS, &bp->state);
6362 return; 6379 return;
6380 }
6363 6381
6364 /* TODO check if we need to synchronize with bnxt_close path */ 6382 /* TODO check if we need to synchronize with bnxt_close path */
6365 for (i = 0; i < bp->cp_nr_rings; i++) { 6383 for (i = 0; i < bp->cp_nr_rings; i++) {
@@ -6406,6 +6424,7 @@ bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
6406 stats->tx_fifo_errors = le64_to_cpu(tx->tx_fifo_underruns); 6424 stats->tx_fifo_errors = le64_to_cpu(tx->tx_fifo_underruns);
6407 stats->tx_errors = le64_to_cpu(tx->tx_err); 6425 stats->tx_errors = le64_to_cpu(tx->tx_err);
6408 } 6426 }
6427 clear_bit(BNXT_STATE_READ_STATS, &bp->state);
6409} 6428}
6410 6429
6411static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) 6430static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask)
@@ -6904,16 +6923,13 @@ static void bnxt_sp_task(struct work_struct *work)
6904} 6923}
6905 6924
6906/* Under rtnl_lock */ 6925/* Under rtnl_lock */
6907int bnxt_reserve_rings(struct bnxt *bp, int tx, int rx, int tcs, int tx_xdp) 6926int bnxt_reserve_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
6927 int tx_xdp)
6908{ 6928{
6909 int max_rx, max_tx, tx_sets = 1; 6929 int max_rx, max_tx, tx_sets = 1;
6910 int tx_rings_needed; 6930 int tx_rings_needed;
6911 bool sh = true;
6912 int rc; 6931 int rc;
6913 6932
6914 if (!(bp->flags & BNXT_FLAG_SHARED_RINGS))
6915 sh = false;
6916
6917 if (tcs) 6933 if (tcs)
6918 tx_sets = tcs; 6934 tx_sets = tcs;
6919 6935
@@ -7121,7 +7137,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
7121 sh = true; 7137 sh = true;
7122 7138
7123 rc = bnxt_reserve_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings, 7139 rc = bnxt_reserve_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings,
7124 tc, bp->tx_nr_rings_xdp); 7140 sh, tc, bp->tx_nr_rings_xdp);
7125 if (rc) 7141 if (rc)
7126 return rc; 7142 return rc;
7127 7143
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index f872a7db2ca8..f34691f85602 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1117,6 +1117,7 @@ struct bnxt {
1117 unsigned long state; 1117 unsigned long state;
1118#define BNXT_STATE_OPEN 0 1118#define BNXT_STATE_OPEN 0
1119#define BNXT_STATE_IN_SP_TASK 1 1119#define BNXT_STATE_IN_SP_TASK 1
1120#define BNXT_STATE_READ_STATS 2
1120 1121
1121 struct bnxt_irq *irq_tbl; 1122 struct bnxt_irq *irq_tbl;
1122 int total_irqs; 1123 int total_irqs;
@@ -1300,7 +1301,8 @@ int bnxt_open_nic(struct bnxt *, bool, bool);
1300int bnxt_half_open_nic(struct bnxt *bp); 1301int bnxt_half_open_nic(struct bnxt *bp);
1301void bnxt_half_close_nic(struct bnxt *bp); 1302void bnxt_half_close_nic(struct bnxt *bp);
1302int bnxt_close_nic(struct bnxt *, bool, bool); 1303int bnxt_close_nic(struct bnxt *, bool, bool);
1303int bnxt_reserve_rings(struct bnxt *bp, int tx, int rx, int tcs, int tx_xdp); 1304int bnxt_reserve_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
1305 int tx_xdp);
1304int bnxt_setup_mq_tc(struct net_device *dev, u8 tc); 1306int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
1305int bnxt_get_max_rings(struct bnxt *, int *, int *, bool); 1307int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
1306void bnxt_restore_pf_fw_resources(struct bnxt *bp); 1308void bnxt_restore_pf_fw_resources(struct bnxt *bp);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index fd1181510b65..be6acadcb202 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -432,7 +432,8 @@ static int bnxt_set_channels(struct net_device *dev,
432 } 432 }
433 tx_xdp = req_rx_rings; 433 tx_xdp = req_rx_rings;
434 } 434 }
435 rc = bnxt_reserve_rings(bp, req_tx_rings, req_rx_rings, tcs, tx_xdp); 435 rc = bnxt_reserve_rings(bp, req_tx_rings, req_rx_rings, sh, tcs,
436 tx_xdp);
436 if (rc) { 437 if (rc) {
437 netdev_warn(dev, "Unable to allocate the requested rings\n"); 438 netdev_warn(dev, "Unable to allocate the requested rings\n");
438 return rc; 439 return rc;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 7d67552e70d7..3961a6807454 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -170,7 +170,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
170 if (!tc) 170 if (!tc)
171 tc = 1; 171 tc = 1;
172 rc = bnxt_reserve_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings, 172 rc = bnxt_reserve_rings(bp, bp->tx_nr_rings_per_tc, bp->rx_nr_rings,
173 tc, tx_xdp); 173 true, tc, tx_xdp);
174 if (rc) { 174 if (rc) {
175 netdev_warn(dev, "Unable to reserve enough TX rings to support XDP.\n"); 175 netdev_warn(dev, "Unable to reserve enough TX rings to support XDP.\n");
176 return rc; 176 return rc;