Skip to content

Commit 80d021b

Browse files
committed
Merge branch 'bnxt_en-fix-queue-reset-when-queue-active'
David Wei says: ==================== fix bnxt_en queue reset when queue is active The current bnxt_en queue API implementation is buggy when resetting a queue that has active traffic. The problem is that there is no FW involved to stop the flow of packets and relying on napi_disable() isn't enough. To fix this, call bnxt_hwrm_vnic_update() with MRU set to 0 for both the default and the ntuple vnic to stop the flow of packets. This works for any Rx queue and not only those that have ntuple rules since every Rx queue is either in the default or the ntuple vnic. For bnxt_hwrm_vnic_update() to work, proper flushing must be done by the FW. A FW flag is there to indicate support and queue_mgmt_ops is keyed behind this. The first three patches are from Michael Chan and adds the prerequisite vnic functions and FW flags indicating that it will properly flush during vnic update. Tested on BCM957504 while iperf3 is active: 1. Reset a queue that has an ntuple rule steering flow into it 2. Reset all queues in order, one at a time In both cases the flow is not interrupted. Sending this to net-next as there is no in-tree kernel consumer of queue API just yet, and there is a patch that changes when the queue_mgmt_ops is registered. Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com> --- v3: - include patches from Michael Chan that adds a FW flag for vnic flush capability - key support for queue_mgmt_ops behind this new flag v2: - split setting vnic->mru into a separate patch (Wojciech) - clarify why napi_enable()/disable() is removed ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 969afb4 + 97cbf3d commit 80d021b

File tree

3 files changed

+300
-146
lines changed

3 files changed

+300
-146
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6579,7 +6579,8 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
65796579
req->dflt_ring_grp = cpu_to_le16(bp->grp_info[grp_idx].fw_grp_id);
65806580
req->lb_rule = cpu_to_le16(0xffff);
65816581
vnic_mru:
6582-
req->mru = cpu_to_le16(bp->dev->mtu + ETH_HLEN + VLAN_HLEN);
6582+
vnic->mru = bp->dev->mtu + ETH_HLEN + VLAN_HLEN;
6583+
req->mru = cpu_to_le16(vnic->mru);
65836584

65846585
req->vnic_id = cpu_to_le16(vnic->fw_vnic_id);
65856586
#ifdef CONFIG_BNXT_SRIOV
@@ -6715,6 +6716,8 @@ static int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
67156716
bp->rss_cap |= BNXT_RSS_CAP_ESP_V4_RSS_CAP;
67166717
if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPSEC_ESP_SPI_IPV6_CAP)
67176718
bp->rss_cap |= BNXT_RSS_CAP_ESP_V6_RSS_CAP;
6719+
if (flags & VNIC_QCAPS_RESP_FLAGS_RE_FLUSH_CAP)
6720+
bp->fw_cap |= BNXT_FW_CAP_VNIC_RE_FLUSH;
67186721
}
67196722
hwrm_req_drop(bp, req);
67206723
return rc;
@@ -10089,6 +10092,26 @@ static int __bnxt_setup_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic)
1008910092
return rc;
1009010093
}
1009110094

10095+
int bnxt_hwrm_vnic_update(struct bnxt *bp, struct bnxt_vnic_info *vnic,
10096+
u8 valid)
10097+
{
10098+
struct hwrm_vnic_update_input *req;
10099+
int rc;
10100+
10101+
rc = hwrm_req_init(bp, req, HWRM_VNIC_UPDATE);
10102+
if (rc)
10103+
return rc;
10104+
10105+
req->vnic_id = cpu_to_le32(vnic->fw_vnic_id);
10106+
10107+
if (valid & VNIC_UPDATE_REQ_ENABLES_MRU_VALID)
10108+
req->mru = cpu_to_le16(vnic->mru);
10109+
10110+
req->enables = cpu_to_le32(valid);
10111+
10112+
return hwrm_req_send(bp, req);
10113+
}
10114+
1009210115
int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
1009310116
{
1009410117
int rc;
@@ -15154,7 +15177,8 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
1515415177
struct bnxt *bp = netdev_priv(dev);
1515515178
struct bnxt_rx_ring_info *rxr, *clone;
1515615179
struct bnxt_cp_ring_info *cpr;
15157-
int rc;
15180+
struct bnxt_vnic_info *vnic;
15181+
int i, rc;
1515815182

1515915183
rxr = &bp->rx_ring[idx];
1516015184
clone = qmem;
@@ -15179,11 +15203,16 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
1517915203
if (bp->flags & BNXT_FLAG_AGG_RINGS)
1518015204
bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
1518115205

15182-
napi_enable(&rxr->bnapi->napi);
15183-
1518415206
cpr = &rxr->bnapi->cp_ring;
1518515207
cpr->sw_stats->rx.rx_resets++;
1518615208

15209+
for (i = 0; i <= BNXT_VNIC_NTUPLE; i++) {
15210+
vnic = &bp->vnic_info[i];
15211+
vnic->mru = bp->dev->mtu + ETH_HLEN + VLAN_HLEN;
15212+
bnxt_hwrm_vnic_update(bp, vnic,
15213+
VNIC_UPDATE_REQ_ENABLES_MRU_VALID);
15214+
}
15215+
1518715216
return 0;
1518815217

1518915218
err_free_hwrm_rx_ring:
@@ -15195,9 +15224,17 @@ static int bnxt_queue_stop(struct net_device *dev, void *qmem, int idx)
1519515224
{
1519615225
struct bnxt *bp = netdev_priv(dev);
1519715226
struct bnxt_rx_ring_info *rxr;
15227+
struct bnxt_vnic_info *vnic;
15228+
int i;
15229+
15230+
for (i = 0; i <= BNXT_VNIC_NTUPLE; i++) {
15231+
vnic = &bp->vnic_info[i];
15232+
vnic->mru = 0;
15233+
bnxt_hwrm_vnic_update(bp, vnic,
15234+
VNIC_UPDATE_REQ_ENABLES_MRU_VALID);
15235+
}
1519815236

1519915237
rxr = &bp->rx_ring[idx];
15200-
napi_disable(&rxr->bnapi->napi);
1520115238
bnxt_hwrm_rx_ring_free(bp, rxr, false);
1520215239
bnxt_hwrm_rx_agg_ring_free(bp, rxr, false);
1520315240
rxr->rx_next_cons = 0;
@@ -15681,7 +15718,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1568115718
dev->stat_ops = &bnxt_stat_ops;
1568215719
dev->watchdog_timeo = BNXT_TX_TIMEOUT;
1568315720
dev->ethtool_ops = &bnxt_ethtool_ops;
15684-
dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops;
1568515721
pci_set_drvdata(pdev, dev);
1568615722

1568715723
rc = bnxt_alloc_hwrm_resources(bp);
@@ -15862,6 +15898,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1586215898

1586315899
if (BNXT_SUPPORTS_NTUPLE_VNIC(bp))
1586415900
bp->rss_cap |= BNXT_RSS_CAP_MULTI_RSS_CTX;
15901+
if (BNXT_SUPPORTS_QUEUE_API(bp))
15902+
dev->queue_mgmt_ops = &bnxt_queue_mgmt_ops;
1586515903

1586615904
rc = register_netdev(dev);
1586715905
if (rc)

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,7 @@ struct bnxt_vnic_info {
12501250
#define BNXT_MAX_CTX_PER_VNIC 8
12511251
u16 fw_rss_cos_lb_ctx[BNXT_MAX_CTX_PER_VNIC];
12521252
u16 fw_l2_ctx_id;
1253+
u16 mru;
12531254
#define BNXT_MAX_UC_ADDRS 4
12541255
struct bnxt_l2_filter *l2_filters[BNXT_MAX_UC_ADDRS];
12551256
/* index 0 always dev_addr */
@@ -2437,6 +2438,7 @@ struct bnxt {
24372438
#define BNXT_FW_CAP_VNIC_TUNNEL_TPA BIT_ULL(37)
24382439
#define BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO BIT_ULL(38)
24392440
#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V3 BIT_ULL(39)
2441+
#define BNXT_FW_CAP_VNIC_RE_FLUSH BIT_ULL(40)
24402442

24412443
u32 fw_dbg_cap;
24422444

@@ -2449,6 +2451,9 @@ struct bnxt {
24492451
#define BNXT_SUPPORTS_MULTI_RSS_CTX(bp) \
24502452
(BNXT_PF(bp) && BNXT_SUPPORTS_NTUPLE_VNIC(bp) && \
24512453
((bp)->rss_cap & BNXT_RSS_CAP_MULTI_RSS_CTX))
2454+
#define BNXT_SUPPORTS_QUEUE_API(bp) \
2455+
(BNXT_PF(bp) && BNXT_SUPPORTS_NTUPLE_VNIC(bp) && \
2456+
((bp)->fw_cap & BNXT_FW_CAP_VNIC_RE_FLUSH))
24522457

24532458
u32 hwrm_spec_code;
24542459
u16 hwrm_cmd_seq;
@@ -2838,6 +2843,8 @@ int bnxt_hwrm_free_wol_fltr(struct bnxt *bp);
28382843
int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp, bool all);
28392844
int bnxt_hwrm_func_qcaps(struct bnxt *bp);
28402845
int bnxt_hwrm_fw_set_time(struct bnxt *);
2846+
int bnxt_hwrm_vnic_update(struct bnxt *bp, struct bnxt_vnic_info *vnic,
2847+
u8 valid);
28412848
int bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
28422849
int __bnxt_setup_vnic_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
28432850
void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,

0 commit comments

Comments
 (0)