From: Pavan Chebbi Ntuple filters can be deleted when the interface is down. The current code blindly sends the filter delete command to FW. When the interface is down, all the VNICs are deleted in the FW. When the VNIC is freed in the FW, all the associated filters are also freed. We need not send the free command explicitly. Sending such command will generate FW error in the dmesg. In order to fix this, save a pointer to the corresponding VNIC of an Ntuple filter in the ntuple filter's base structure. Use this pointer to check if the VNIC is already freed whenever we are freeing the Ntuple filters. Now that we have access to the vnic itself, remove the redundant reference to fw_vnic_id from all places. Fixes: 8336a974f37d ("bnxt_en: Save user configured filters in a lookup list") Reviewed-by: Andy Gospodarek Signed-off-by: Pavan Chebbi Signed-off-by: Michael Chan --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 14 ++++++++++++-- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 7 +++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 8fc15a8353fc..1f05ecf367fe 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6184,6 +6184,7 @@ int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr) { struct hwrm_cfa_l2_filter_alloc_output *resp; struct hwrm_cfa_l2_filter_alloc_input *req; + u16 dst_id = INVALID_HW_RING_ID; u16 target_id = 0xffff; int rc; @@ -6205,7 +6206,10 @@ int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr) if (!BNXT_CHIP_TYPE_NITRO_A0(bp)) req->flags |= cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_OUTERMOST); - req->dst_id = cpu_to_le16(fltr->base.fw_vnic_id); + + if (fltr->base.vnic) + dst_id = fltr->base.vnic->fw_vnic_id; + req->dst_id = cpu_to_le16(dst_id); req->enables = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR | CFA_L2_FILTER_ALLOC_REQ_ENABLES_DST_ID | @@ -6240,6 +6244,9 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, int rc; set_bit(BNXT_FLTR_FW_DELETED, &fltr->base.state); + if (fltr->base.vnic->fw_vnic_id == INVALID_HW_RING_ID) + return 0; + rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE); if (rc) return rc; @@ -6291,6 +6298,7 @@ bnxt_cfg_rfs_ring_tbl_idx(struct bnxt *bp, if (ctx) { rss_ctx = ethtool_rxfh_context_priv(ctx); vnic = &rss_ctx->vnic; + fltr->base.vnic = vnic; req->dst_id = cpu_to_le16(vnic->fw_vnic_id); } @@ -6301,6 +6309,7 @@ bnxt_cfg_rfs_ring_tbl_idx(struct bnxt *bp, u32 enables; vnic = &bp->vnic_info[BNXT_VNIC_NTUPLE]; + fltr->base.vnic = vnic; req->dst_id = cpu_to_le16(vnic->fw_vnic_id); enables = CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_RFS_RING_TBL_IDX; req->enables |= cpu_to_le32(enables); @@ -6339,6 +6348,7 @@ int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, bnxt_cfg_rfs_ring_tbl_idx(bp, req, fltr); } else { vnic = &bp->vnic_info[fltr->base.rxq + 1]; + fltr->base.vnic = vnic; req->dst_id = cpu_to_le16(vnic->fw_vnic_id); } req->enables |= cpu_to_le32(BNXT_NTP_FLTR_FLAGS); @@ -6393,7 +6403,7 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx, if (IS_ERR(fltr)) return PTR_ERR(fltr); - fltr->base.fw_vnic_id = bp->vnic_info[vnic_id].fw_vnic_id; + fltr->base.vnic = &bp->vnic_info[vnic_id]; rc = bnxt_hwrm_l2_filter_alloc(bp, fltr); if (rc) bnxt_del_l2_filter(bp, fltr); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 6a18a1973fd5..ae4d01445cea 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1434,9 +1434,9 @@ struct bnxt_filter_base { #define BNXT_ACT_RSS_CTX 0x10 u16 sw_id; u16 rxq; - u16 fw_vnic_id; u16 rss_ctx_id; u16 vf_idx; + struct bnxt_vnic_info *vnic; unsigned long state; #define BNXT_FLTR_VALID 0 #define BNXT_FLTR_INSERTED 1 diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index d0363f410ddb..861965ca2e1e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1267,9 +1267,9 @@ static int bnxt_add_l2_cls_rule(struct bnxt *bp, u8 vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie); struct ethhdr *h_ether = &fs->h_u.ether_spec; struct ethhdr *m_ether = &fs->m_u.ether_spec; + struct bnxt_vnic_info *vnic = NULL; struct bnxt_l2_filter *fltr; struct bnxt_l2_key key; - u16 vnic_id; u8 flags; int rc; @@ -1291,17 +1291,16 @@ static int bnxt_add_l2_cls_rule(struct bnxt *bp, if (vf) { flags = BNXT_ACT_FUNC_DST; - vnic_id = 0xffff; vf--; } else { flags = BNXT_ACT_RING_DST; - vnic_id = bp->vnic_info[ring + 1].fw_vnic_id; + vnic = &bp->vnic_info[ring + 1]; } fltr = bnxt_alloc_new_l2_filter(bp, &key, flags); if (IS_ERR(fltr)) return PTR_ERR(fltr); - fltr->base.fw_vnic_id = vnic_id; + fltr->base.vnic = vnic; fltr->base.rxq = ring; fltr->base.vf_idx = vf; rc = bnxt_hwrm_l2_filter_alloc(bp, fltr); -- 2.51.0