netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support
@ 2023-12-23  4:21 Michael Chan
  2023-12-23  4:21 ` [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure Michael Chan
                   ` (13 more replies)
  0 siblings, 14 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:21 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 1772 bytes --]

The current driver only supports ntuple filters added by aRFS.  This
patch series adds basic support for user defined TCP/UDP ntuple filters
added by the user using ethtool.  Many of the patches are refactoring
patches to make the existing code more general to support both aRFS
and user defined filters.  aRFS filters always have the Toeplitz hash
value from the NIC.  A Toepliz hash function is added in patch 5 to
get the same hash value for user defined filters.  The hash is used
to store all ntuple filters in the table and all filters must be
hashed identically using the same function and key.

v2: Fix compile error in patch #4 when CONFIG_BNXT_SRIOV is disabled.

Michael Chan (12):
  bnxt_en: Refactor bnxt_ntuple_filter structure.
  bnxt_en: Add bnxt_l2_filter hash table.
  bnxt_en: Re-structure the bnxt_ntuple_filter structure.
  bnxt_en: Refactor L2 filter alloc/free firmware commands.
  bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function
  bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct.
  bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer().
  bnxt_en: Refactor the hash table logic for ntuple filters.
  bnxt_en: Refactor ntuple filter removal logic in
    bnxt_cfg_ntp_filters().
  bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter
    structure.
  bnxt_en: Add support for ntuple filters added from ethtool.
  bnxt_en: Add support for ntuple filter deletion by ethtool.

Pavan Chebbi (1):
  bnxt_en: Add function to calculate Toeplitz hash

 drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 719 +++++++++++++-----
 drivers/net/ethernet/broadcom/bnxt/bnxt.h     |  92 ++-
 .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 371 +++++++--
 3 files changed, 936 insertions(+), 246 deletions(-)

-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
@ 2023-12-23  4:21 ` Michael Chan
  2023-12-25 17:43   ` Simon Horman
  2023-12-23  4:21 ` [PATCH net-next v2 02/13] bnxt_en: Add bnxt_l2_filter hash table Michael Chan
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:21 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 7110 bytes --]

This is in preparation to support user defined L2 (ether) filters,
which will have many similarities with ntuple filters.  Refactor
bnxt_ntuple_filter structure to have a bnxt_filter_base structure
that can be re-used by the L2 filters.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 39 ++++++++++---------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h     | 25 +++++++++---
 .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 10 ++---
 3 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 1f956929191d..bf3b9b2cad76 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4803,8 +4803,8 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool irq_reinit)
 		struct bnxt_ntuple_filter *fltr;
 
 		head = &bp->ntp_fltr_hash_tbl[i];
-		hlist_for_each_entry_safe(fltr, tmp, head, hash) {
-			hlist_del(&fltr->hash);
+		hlist_for_each_entry_safe(fltr, tmp, head, base.hash) {
+			hlist_del(&fltr->base.hash);
 			kfree(fltr);
 		}
 	}
@@ -5301,7 +5301,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 	if (rc)
 		return rc;
 
-	req->ntuple_filter_id = fltr->filter_id;
+	req->ntuple_filter_id = fltr->base.filter_id;
 	return hwrm_req_send(bp, req);
 }
 
@@ -5342,9 +5342,9 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 
 	if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2) {
 		flags = CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX;
-		req->dst_id = cpu_to_le16(fltr->rxq);
+		req->dst_id = cpu_to_le16(fltr->base.rxq);
 	} else {
-		vnic = &bp->vnic_info[fltr->rxq + 1];
+		vnic = &bp->vnic_info[fltr->base.rxq + 1];
 		req->dst_id = cpu_to_le16(vnic->fw_vnic_id);
 	}
 	req->flags = cpu_to_le32(flags);
@@ -5389,7 +5389,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	resp = hwrm_req_hold(bp, req);
 	rc = hwrm_req_send(bp, req);
 	if (!rc)
-		fltr->filter_id = resp->ntuple_filter_id;
+		fltr->base.filter_id = resp->ntuple_filter_id;
 	hwrm_req_drop(bp, req);
 	return rc;
 }
@@ -13653,9 +13653,9 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	idx = skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK;
 	head = &bp->ntp_fltr_hash_tbl[idx];
 	rcu_read_lock();
-	hlist_for_each_entry_rcu(fltr, head, hash) {
+	hlist_for_each_entry_rcu(fltr, head, base.hash) {
 		if (bnxt_fltr_match(fltr, new_fltr)) {
-			rc = fltr->sw_id;
+			rc = fltr->base.sw_id;
 			rcu_read_unlock();
 			goto err_free;
 		}
@@ -13671,17 +13671,18 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 		goto err_free;
 	}
 
-	new_fltr->sw_id = (u16)bit_id;
+	new_fltr->base.sw_id = (u16)bit_id;
 	new_fltr->flow_id = flow_id;
 	new_fltr->l2_fltr_idx = l2_idx;
-	new_fltr->rxq = rxq_index;
-	hlist_add_head_rcu(&new_fltr->hash, head);
+	new_fltr->base.rxq = rxq_index;
+	new_fltr->base.type = BNXT_FLTR_TYPE_NTUPLE;
+	hlist_add_head_rcu(&new_fltr->base.hash, head);
 	bp->ntp_fltr_count++;
 	spin_unlock_bh(&bp->ntp_fltr_lock);
 
 	bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT);
 
-	return new_fltr->sw_id;
+	return new_fltr->base.sw_id;
 
 err_free:
 	kfree(new_fltr);
@@ -13699,13 +13700,13 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 		int rc;
 
 		head = &bp->ntp_fltr_hash_tbl[i];
-		hlist_for_each_entry_safe(fltr, tmp, head, hash) {
+		hlist_for_each_entry_safe(fltr, tmp, head, base.hash) {
 			bool del = false;
 
-			if (test_bit(BNXT_FLTR_VALID, &fltr->state)) {
-				if (rps_may_expire_flow(bp->dev, fltr->rxq,
+			if (test_bit(BNXT_FLTR_VALID, &fltr->base.state)) {
+				if (rps_may_expire_flow(bp->dev, fltr->base.rxq,
 							fltr->flow_id,
-							fltr->sw_id)) {
+							fltr->base.sw_id)) {
 					bnxt_hwrm_cfa_ntuple_filter_free(bp,
 									 fltr);
 					del = true;
@@ -13716,16 +13717,16 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 				if (rc)
 					del = true;
 				else
-					set_bit(BNXT_FLTR_VALID, &fltr->state);
+					set_bit(BNXT_FLTR_VALID, &fltr->base.state);
 			}
 
 			if (del) {
 				spin_lock_bh(&bp->ntp_fltr_lock);
-				hlist_del_rcu(&fltr->hash);
+				hlist_del_rcu(&fltr->base.hash);
 				bp->ntp_fltr_count--;
 				spin_unlock_bh(&bp->ntp_fltr_lock);
 				synchronize_rcu();
-				clear_bit(fltr->sw_id, bp->ntp_fltr_bmap);
+				clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
 				kfree(fltr);
 			}
 		}
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index d0f3e74fa025..4653abbd2fe4 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1332,21 +1332,34 @@ struct bnxt_pf_info {
 	struct bnxt_vf_info	*vf;
 };
 
-struct bnxt_ntuple_filter {
+struct bnxt_filter_base {
 	struct hlist_node	hash;
-	u8			dst_mac_addr[ETH_ALEN];
-	u8			src_mac_addr[ETH_ALEN];
-	struct flow_keys	fkeys;
 	__le64			filter_id;
+	u8			type;
+#define BNXT_FLTR_TYPE_NTUPLE	1
+#define BNXT_FLTR_TYPE_L2	2
+	u8			flags;
+#define BNXT_ACT_DROP		1
+#define BNXT_ACT_RING_DST	2
+#define BNXT_ACT_FUNC_DST	4
 	u16			sw_id;
-	u8			l2_fltr_idx;
 	u16			rxq;
-	u32			flow_id;
+	u16			fw_vnic_id;
+	u16			vf_idx;
 	unsigned long		state;
 #define BNXT_FLTR_VALID		0
 #define BNXT_FLTR_UPDATE	1
 };
 
+struct bnxt_ntuple_filter {
+	struct bnxt_filter_base	base;
+	u8			dst_mac_addr[ETH_ALEN];
+	u8			src_mac_addr[ETH_ALEN];
+	struct flow_keys	fkeys;
+	u8			l2_fltr_idx;
+	u32			flow_id;
+};
+
 struct bnxt_link_info {
 	u8			phy_type;
 	u8			media_type;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 7e49953a93fa..65edad2cfeab 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1024,10 +1024,10 @@ static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd,
 
 		head = &bp->ntp_fltr_hash_tbl[i];
 		rcu_read_lock();
-		hlist_for_each_entry_rcu(fltr, head, hash) {
+		hlist_for_each_entry_rcu(fltr, head, base.hash) {
 			if (j == cmd->rule_cnt)
 				break;
-			rule_locs[j++] = fltr->sw_id;
+			rule_locs[j++] = fltr->base.sw_id;
 		}
 		rcu_read_unlock();
 		if (j == cmd->rule_cnt)
@@ -1053,8 +1053,8 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 
 		head = &bp->ntp_fltr_hash_tbl[i];
 		rcu_read_lock();
-		hlist_for_each_entry_rcu(fltr, head, hash) {
-			if (fltr->sw_id == fs->location)
+		hlist_for_each_entry_rcu(fltr, head, base.hash) {
+			if (fltr->base.sw_id == fs->location)
 				goto fltr_found;
 		}
 		rcu_read_unlock();
@@ -1107,7 +1107,7 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 		fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0);
 	}
 
-	fs->ring_cookie = fltr->rxq;
+	fs->ring_cookie = fltr->base.rxq;
 	rc = 0;
 
 fltr_err:
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 02/13] bnxt_en: Add bnxt_l2_filter hash table.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
  2023-12-23  4:21 ` [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure Michael Chan
@ 2023-12-23  4:21 ` Michael Chan
  2023-12-25 17:44   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure Michael Chan
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:21 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 11756 bytes --]

The current driver only has an array of 4 additional L2 unicast
addresses to support the netdev uc address list.  Generalize and
expand this infrastructure with an L2 address hash table so we can
support an expanded list of unicast addresses (for bridges,
macvlans, OVS, etc).  The L2 hash table infrastructure will also
allow more generalized n-tuple filter support.

This patch creates the bnxt_l2_filter structure and the hash table.
This L2 filter structure has the same bnxt_filter_base structure
as used in the bnxt_ntuple_filter structure.

All currently supported L2 filters will now have an entry in this
new table.

Note that L2 filters may be created for the VF.  VF filters should
not be freed when the PF goes down.  Add some logic in
bnxt_free_l2_filters() to allow keeping the VF filters or to free
everything during rmmod.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 175 ++++++++++++++++++++--
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  30 +++-
 2 files changed, 191 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index bf3b9b2cad76..8e9a02629450 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4789,7 +4789,7 @@ static void bnxt_clear_ring_indices(struct bnxt *bp)
 	}
 }
 
-static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool irq_reinit)
+static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool all)
 {
 #ifdef CONFIG_RFS_ACCEL
 	int i;
@@ -4804,14 +4804,19 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool irq_reinit)
 
 		head = &bp->ntp_fltr_hash_tbl[i];
 		hlist_for_each_entry_safe(fltr, tmp, head, base.hash) {
+			if (!all && (fltr->base.flags & BNXT_ACT_FUNC_DST))
+				continue;
 			hlist_del(&fltr->base.hash);
+			clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
+			bp->ntp_fltr_count--;
 			kfree(fltr);
 		}
 	}
-	if (irq_reinit) {
-		bitmap_free(bp->ntp_fltr_bmap);
-		bp->ntp_fltr_bmap = NULL;
-	}
+	if (!all)
+		return;
+
+	bitmap_free(bp->ntp_fltr_bmap);
+	bp->ntp_fltr_bmap = NULL;
 	bp->ntp_fltr_count = 0;
 #endif
 }
@@ -4821,7 +4826,7 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
 #ifdef CONFIG_RFS_ACCEL
 	int i, rc = 0;
 
-	if (!(bp->flags & BNXT_FLAG_RFS))
+	if (!(bp->flags & BNXT_FLAG_RFS) || bp->ntp_fltr_bmap)
 		return 0;
 
 	for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++)
@@ -4839,6 +4844,38 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
 #endif
 }
 
+static void bnxt_free_l2_filters(struct bnxt *bp, bool all)
+{
+	int i;
+
+	for (i = 0; i < BNXT_L2_FLTR_HASH_SIZE; i++) {
+		struct hlist_head *head;
+		struct hlist_node *tmp;
+		struct bnxt_l2_filter *fltr;
+
+		head = &bp->l2_fltr_hash_tbl[i];
+		hlist_for_each_entry_safe(fltr, tmp, head, base.hash) {
+			if (!all && (fltr->base.flags & BNXT_ACT_FUNC_DST))
+				continue;
+			hlist_del(&fltr->base.hash);
+			if (fltr->base.flags) {
+				clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
+				bp->ntp_fltr_count--;
+			}
+			kfree(fltr);
+		}
+	}
+}
+
+static void bnxt_init_l2_fltr_tbl(struct bnxt *bp)
+{
+	int i;
+
+	for (i = 0; i < BNXT_L2_FLTR_HASH_SIZE; i++)
+		INIT_HLIST_HEAD(&bp->l2_fltr_hash_tbl[i]);
+	get_random_bytes(&bp->hash_seed, sizeof(bp->hash_seed));
+}
+
 static void bnxt_free_mem(struct bnxt *bp, bool irq_re_init)
 {
 	bnxt_free_vnic_attributes(bp);
@@ -4846,7 +4883,8 @@ static void bnxt_free_mem(struct bnxt *bp, bool irq_re_init)
 	bnxt_free_rx_rings(bp);
 	bnxt_free_cp_rings(bp);
 	bnxt_free_all_cp_arrays(bp);
-	bnxt_free_ntp_fltrs(bp, irq_re_init);
+	bnxt_free_ntp_fltrs(bp, false);
+	bnxt_free_l2_filters(bp, false);
 	if (irq_re_init) {
 		bnxt_free_ring_stats(bp);
 		if (!(bp->phy_flags & BNXT_PHY_FL_PORT_STATS_NO_RESET) ||
@@ -5290,6 +5328,92 @@ static int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, u16 vnic_id)
 	return hwrm_req_send_silent(bp, req);
 }
 
+void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr)
+{
+	if (!atomic_dec_and_test(&fltr->refcnt))
+		return;
+	spin_lock_bh(&bp->ntp_fltr_lock);
+	hlist_del_rcu(&fltr->base.hash);
+	if (fltr->base.flags) {
+		clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
+		bp->ntp_fltr_count--;
+	}
+	spin_unlock_bh(&bp->ntp_fltr_lock);
+	kfree_rcu(fltr, base.rcu);
+}
+
+static struct bnxt_l2_filter *__bnxt_lookup_l2_filter(struct bnxt *bp,
+						      struct bnxt_l2_key *key,
+						      u32 idx)
+{
+	struct hlist_head *head = &bp->l2_fltr_hash_tbl[idx];
+	struct bnxt_l2_filter *fltr;
+
+	hlist_for_each_entry_rcu(fltr, head, base.hash) {
+		struct bnxt_l2_key *l2_key = &fltr->l2_key;
+
+		if (ether_addr_equal(l2_key->dst_mac_addr, key->dst_mac_addr) &&
+		    l2_key->vlan == key->vlan)
+			return fltr;
+	}
+	return NULL;
+}
+
+static struct bnxt_l2_filter *bnxt_lookup_l2_filter(struct bnxt *bp,
+						    struct bnxt_l2_key *key,
+						    u32 idx)
+{
+	struct bnxt_l2_filter *fltr = NULL;
+
+	rcu_read_lock();
+	fltr = __bnxt_lookup_l2_filter(bp, key, idx);
+	if (fltr)
+		atomic_inc(&fltr->refcnt);
+	rcu_read_unlock();
+	return fltr;
+}
+
+static int bnxt_init_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr,
+			       struct bnxt_l2_key *key, u32 idx)
+{
+	struct hlist_head *head;
+
+	ether_addr_copy(fltr->l2_key.dst_mac_addr, key->dst_mac_addr);
+	fltr->l2_key.vlan = key->vlan;
+	fltr->base.type = BNXT_FLTR_TYPE_L2;
+	head = &bp->l2_fltr_hash_tbl[idx];
+	hlist_add_head_rcu(&fltr->base.hash, head);
+	atomic_set(&fltr->refcnt, 1);
+	return 0;
+}
+
+static struct bnxt_l2_filter *bnxt_alloc_l2_filter(struct bnxt *bp,
+						   struct bnxt_l2_key *key,
+						   gfp_t gfp)
+{
+	struct bnxt_l2_filter *fltr;
+	u32 idx;
+	int rc;
+
+	idx = jhash2(&key->filter_key, BNXT_L2_KEY_SIZE, bp->hash_seed) &
+	      BNXT_L2_FLTR_HASH_MASK;
+	fltr = bnxt_lookup_l2_filter(bp, key, idx);
+	if (fltr)
+		return fltr;
+
+	fltr = kzalloc(sizeof(*fltr), gfp);
+	if (!fltr)
+		return ERR_PTR(-ENOMEM);
+	spin_lock_bh(&bp->ntp_fltr_lock);
+	rc = bnxt_init_l2_filter(bp, fltr, key, idx);
+	spin_unlock_bh(&bp->ntp_fltr_lock);
+	if (rc) {
+		bnxt_del_l2_filter(bp, fltr);
+		fltr = ERR_PTR(rc);
+	}
+	return fltr;
+}
+
 #ifdef CONFIG_RFS_ACCEL
 static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 					    struct bnxt_ntuple_filter *fltr)
@@ -5330,6 +5454,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	struct hwrm_cfa_ntuple_filter_alloc_output *resp;
 	struct hwrm_cfa_ntuple_filter_alloc_input *req;
 	struct flow_keys *keys = &fltr->fkeys;
+	struct bnxt_l2_filter *l2_fltr;
 	struct bnxt_vnic_info *vnic;
 	u32 flags = 0;
 	int rc;
@@ -5338,7 +5463,9 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	if (rc)
 		return rc;
 
-	req->l2_filter_id = bp->vnic_info[0].fw_l2_filter_id[fltr->l2_fltr_idx];
+	l2_fltr = bp->vnic_info[0].l2_filters[fltr->l2_fltr_idx];
+	req->l2_filter_id = l2_fltr->base.filter_id;
+
 
 	if (bp->fw_cap & BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2) {
 		flags = CFA_NTUPLE_FILTER_ALLOC_REQ_FLAGS_DEST_RFS_RING_IDX;
@@ -5400,8 +5527,16 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
 {
 	struct hwrm_cfa_l2_filter_alloc_output *resp;
 	struct hwrm_cfa_l2_filter_alloc_input *req;
+	struct bnxt_l2_filter *fltr;
+	struct bnxt_l2_key key;
 	int rc;
 
+	ether_addr_copy(key.dst_mac_addr, mac_addr);
+	key.vlan = 0;
+	fltr = bnxt_alloc_l2_filter(bp, &key, GFP_KERNEL);
+	if (IS_ERR(fltr))
+		return PTR_ERR(fltr);
+
 	rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_ALLOC);
 	if (rc)
 		return rc;
@@ -5425,9 +5560,13 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
 
 	resp = hwrm_req_hold(bp, req);
 	rc = hwrm_req_send(bp, req);
-	if (!rc)
-		bp->vnic_info[vnic_id].fw_l2_filter_id[idx] =
-							resp->l2_filter_id;
+	if (rc) {
+		bnxt_del_l2_filter(bp, fltr);
+	} else {
+		fltr->base.filter_id = resp->l2_filter_id;
+		set_bit(BNXT_FLTR_VALID, &fltr->base.state);
+		bp->vnic_info[vnic_id].l2_filters[idx] = fltr;
+	}
 	hwrm_req_drop(bp, req);
 	return rc;
 }
@@ -5447,9 +5586,13 @@ static int bnxt_hwrm_clear_vnic_filter(struct bnxt *bp)
 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
 
 		for (j = 0; j < vnic->uc_filter_count; j++) {
-			req->l2_filter_id = vnic->fw_l2_filter_id[j];
+			struct bnxt_l2_filter *fltr;
+
+			fltr = vnic->l2_filters[j];
+			req->l2_filter_id = fltr->base.filter_id;
 
 			rc = hwrm_req_send(bp, req);
+			bnxt_del_l2_filter(bp, fltr);
 		}
 		vnic->uc_filter_count = 0;
 	}
@@ -11759,9 +11902,12 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp)
 		return rc;
 	hwrm_req_hold(bp, req);
 	for (i = 1; i < vnic->uc_filter_count; i++) {
-		req->l2_filter_id = vnic->fw_l2_filter_id[i];
+		struct bnxt_l2_filter *fltr = vnic->l2_filters[i];
+
+		req->l2_filter_id = fltr->base.filter_id;
 
 		rc = hwrm_req_send(bp, req);
+		bnxt_del_l2_filter(bp, fltr);
 	}
 	hwrm_req_drop(bp, req);
 
@@ -13901,6 +14047,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
 
 	bnxt_ptp_clear(bp);
 	unregister_netdev(dev);
+	bnxt_free_l2_filters(bp, true);
+	bnxt_free_ntp_fltrs(bp, true);
 	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
 	/* Flush any pending tasks */
 	cancel_work_sync(&bp->sp_task);
@@ -14450,6 +14598,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	if (rc)
 		goto init_err_pci_clean;
 
+	bnxt_init_l2_fltr_tbl(bp);
 	bnxt_set_rx_skb_mode(bp, false);
 	bnxt_set_tpa_flags(bp);
 	bnxt_set_ring_params(bp);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 4653abbd2fe4..77c7084e47cd 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1219,7 +1219,7 @@ struct bnxt_vnic_info {
 	u16		fw_rss_cos_lb_ctx[BNXT_MAX_CTX_PER_VNIC];
 	u16		fw_l2_ctx_id;
 #define BNXT_MAX_UC_ADDRS	4
-	__le64		fw_l2_filter_id[BNXT_MAX_UC_ADDRS];
+	struct bnxt_l2_filter *l2_filters[BNXT_MAX_UC_ADDRS];
 				/* index 0 always dev_addr */
 	u16		uc_filter_count;
 	u8		*uc_list;
@@ -1349,6 +1349,8 @@ struct bnxt_filter_base {
 	unsigned long		state;
 #define BNXT_FLTR_VALID		0
 #define BNXT_FLTR_UPDATE	1
+
+	struct rcu_head         rcu;
 };
 
 struct bnxt_ntuple_filter {
@@ -1360,6 +1362,24 @@ struct bnxt_ntuple_filter {
 	u32			flow_id;
 };
 
+struct bnxt_l2_key {
+	union {
+		struct {
+			u8	dst_mac_addr[ETH_ALEN];
+			u16	vlan;
+		};
+		u32	filter_key;
+	};
+};
+
+#define BNXT_L2_KEY_SIZE	(sizeof(struct bnxt_l2_key) / 4)
+
+struct bnxt_l2_filter {
+	struct bnxt_filter_base	base;
+	struct bnxt_l2_key	l2_key;
+	atomic_t		refcnt;
+};
+
 struct bnxt_link_info {
 	u8			phy_type;
 	u8			media_type;
@@ -2388,6 +2408,13 @@ struct bnxt {
 	unsigned long		*ntp_fltr_bmap;
 	int			ntp_fltr_count;
 
+#define BNXT_L2_FLTR_MAX_FLTR	1024
+#define BNXT_L2_FLTR_HASH_SIZE	32
+#define BNXT_L2_FLTR_HASH_MASK	(BNXT_L2_FLTR_HASH_SIZE - 1)
+	struct hlist_head	l2_fltr_hash_tbl[BNXT_L2_FLTR_HASH_SIZE];
+
+	u32			hash_seed;
+
 	/* To protect link related settings during link changes and
 	 * ethtool settings changes.
 	 */
@@ -2595,6 +2622,7 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
 int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
 			    int bmap_size, bool async_only);
 int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp);
+void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
  2023-12-23  4:21 ` [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure Michael Chan
  2023-12-23  4:21 ` [PATCH net-next v2 02/13] bnxt_en: Add bnxt_l2_filter hash table Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 17:45   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 04/13] bnxt_en: Refactor L2 filter alloc/free firmware commands Michael Chan
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 6642 bytes --]

With the new bnxt_l2_filter structure, we can now re-structure the
bnxt_ntuple_filter structure to point to the bnxt_l2_filter structure.
We eliminate the L2 ether address info from the ntuple filter structure
as we can get the information from the L2 filter structure.  Note that
the source L2 MAC address is no longer used.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 62 ++++++++++++++---------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  4 +-
 2 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 8e9a02629450..62e4f35c6f0f 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4804,6 +4804,7 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool all)
 
 		head = &bp->ntp_fltr_hash_tbl[i];
 		hlist_for_each_entry_safe(fltr, tmp, head, base.hash) {
+			bnxt_del_l2_filter(bp, fltr->l2_fltr);
 			if (!all && (fltr->base.flags & BNXT_ACT_FUNC_DST))
 				continue;
 			hlist_del(&fltr->base.hash);
@@ -5373,6 +5374,20 @@ static struct bnxt_l2_filter *bnxt_lookup_l2_filter(struct bnxt *bp,
 	return fltr;
 }
 
+#ifdef CONFIG_RFS_ACCEL
+static struct bnxt_l2_filter *
+bnxt_lookup_l2_filter_from_key(struct bnxt *bp, struct bnxt_l2_key *key)
+{
+	struct bnxt_l2_filter *fltr;
+	u32 idx;
+
+	idx = jhash2(&key->filter_key, BNXT_L2_KEY_SIZE, bp->hash_seed) &
+	      BNXT_L2_FLTR_HASH_MASK;
+	fltr = bnxt_lookup_l2_filter(bp, key, idx);
+	return fltr;
+}
+#endif
+
 static int bnxt_init_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr,
 			       struct bnxt_l2_key *key, u32 idx)
 {
@@ -5432,7 +5447,6 @@ static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 #define BNXT_NTP_FLTR_FLAGS					\
 	(CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_L2_FILTER_ID |	\
 	 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_ETHERTYPE |	\
-	 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_MACADDR |	\
 	 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_IPADDR_TYPE |	\
 	 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR |	\
 	 CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_SRC_IPADDR_MASK |	\
@@ -5463,7 +5477,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	if (rc)
 		return rc;
 
-	l2_fltr = bp->vnic_info[0].l2_filters[fltr->l2_fltr_idx];
+	l2_fltr = fltr->l2_fltr;
 	req->l2_filter_id = l2_fltr->base.filter_id;
 
 
@@ -5478,7 +5492,6 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	req->enables = cpu_to_le32(BNXT_NTP_FLTR_FLAGS);
 
 	req->ethertype = htons(ETH_P_IP);
-	memcpy(req->src_macaddr, fltr->src_mac_addr, ETH_ALEN);
 	req->ip_addr_type = CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV4;
 	req->ip_protocol = keys->basic.ip_proto;
 
@@ -13730,8 +13743,7 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
 
 	if (keys1->ports.ports == keys2->ports.ports &&
 	    keys1->control.flags == keys2->control.flags &&
-	    ether_addr_equal(f1->src_mac_addr, f2->src_mac_addr) &&
-	    ether_addr_equal(f1->dst_mac_addr, f2->dst_mac_addr))
+	    f1->l2_fltr == f2->l2_fltr)
 		return true;
 
 	return false;
@@ -13744,29 +13756,32 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	struct bnxt_ntuple_filter *fltr, *new_fltr;
 	struct flow_keys *fkeys;
 	struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb);
-	int rc = 0, idx, bit_id, l2_idx = 0;
+	struct bnxt_l2_filter *l2_fltr;
+	int rc = 0, idx, bit_id;
 	struct hlist_head *head;
 	u32 flags;
 
-	if (!ether_addr_equal(dev->dev_addr, eth->h_dest)) {
-		struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
-		int off = 0, j;
+	if (ether_addr_equal(dev->dev_addr, eth->h_dest)) {
+		l2_fltr = bp->vnic_info[0].l2_filters[0];
+		atomic_inc(&l2_fltr->refcnt);
+	} else {
+		struct bnxt_l2_key key;
 
-		netif_addr_lock_bh(dev);
-		for (j = 0; j < vnic->uc_filter_count; j++, off += ETH_ALEN) {
-			if (ether_addr_equal(eth->h_dest,
-					     vnic->uc_list + off)) {
-				l2_idx = j + 1;
-				break;
-			}
-		}
-		netif_addr_unlock_bh(dev);
-		if (!l2_idx)
+		ether_addr_copy(key.dst_mac_addr, eth->h_dest);
+		key.vlan = 0;
+		l2_fltr = bnxt_lookup_l2_filter_from_key(bp, &key);
+		if (!l2_fltr)
+			return -EINVAL;
+		if (l2_fltr->base.flags & BNXT_ACT_FUNC_DST) {
+			bnxt_del_l2_filter(bp, l2_fltr);
 			return -EINVAL;
+		}
 	}
 	new_fltr = kzalloc(sizeof(*new_fltr), GFP_ATOMIC);
-	if (!new_fltr)
+	if (!new_fltr) {
+		bnxt_del_l2_filter(bp, l2_fltr);
 		return -ENOMEM;
+	}
 
 	fkeys = &new_fltr->fkeys;
 	if (!skb_flow_dissect_flow_keys(skb, fkeys, 0)) {
@@ -13793,8 +13808,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 		goto err_free;
 	}
 
-	memcpy(new_fltr->dst_mac_addr, eth->h_dest, ETH_ALEN);
-	memcpy(new_fltr->src_mac_addr, eth->h_source, ETH_ALEN);
+	new_fltr->l2_fltr = l2_fltr;
 
 	idx = skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK;
 	head = &bp->ntp_fltr_hash_tbl[idx];
@@ -13819,9 +13833,9 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 
 	new_fltr->base.sw_id = (u16)bit_id;
 	new_fltr->flow_id = flow_id;
-	new_fltr->l2_fltr_idx = l2_idx;
 	new_fltr->base.rxq = rxq_index;
 	new_fltr->base.type = BNXT_FLTR_TYPE_NTUPLE;
+	new_fltr->base.flags = BNXT_ACT_RING_DST;
 	hlist_add_head_rcu(&new_fltr->base.hash, head);
 	bp->ntp_fltr_count++;
 	spin_unlock_bh(&bp->ntp_fltr_lock);
@@ -13831,6 +13845,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	return new_fltr->base.sw_id;
 
 err_free:
+	bnxt_del_l2_filter(bp, l2_fltr);
 	kfree(new_fltr);
 	return rc;
 }
@@ -13871,6 +13886,7 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 				hlist_del_rcu(&fltr->base.hash);
 				bp->ntp_fltr_count--;
 				spin_unlock_bh(&bp->ntp_fltr_lock);
+				bnxt_del_l2_filter(bp, fltr->l2_fltr);
 				synchronize_rcu();
 				clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
 				kfree(fltr);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 77c7084e47cd..72e99f2a5c68 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1355,10 +1355,8 @@ struct bnxt_filter_base {
 
 struct bnxt_ntuple_filter {
 	struct bnxt_filter_base	base;
-	u8			dst_mac_addr[ETH_ALEN];
-	u8			src_mac_addr[ETH_ALEN];
 	struct flow_keys	fkeys;
-	u8			l2_fltr_idx;
+	struct bnxt_l2_filter	*l2_fltr;
 	u32			flow_id;
 };
 
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 04/13] bnxt_en: Refactor L2 filter alloc/free firmware commands.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (2 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-23  4:22 ` [PATCH net-next v2 05/13] bnxt_en: Add function to calculate Toeplitz hash Michael Chan
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 9439 bytes --]

Refactor the L2 filter alloc/free logic so that these filters can be
added/deleted by the user.

The bp->ntp_fltr_bmap allocated size is also increased to allow enough
IDs for L2 filters.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
v2: Fix compile error when CONFIG_BNXT_SRIOV is disabled (reported by
    kernel test robot).
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 163 +++++++++++++++-------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |   3 +
 2 files changed, 112 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 62e4f35c6f0f..571f2c443c2e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4834,7 +4834,7 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
 		INIT_HLIST_HEAD(&bp->ntp_fltr_hash_tbl[i]);
 
 	bp->ntp_fltr_count = 0;
-	bp->ntp_fltr_bmap = bitmap_zalloc(BNXT_NTP_FLTR_MAX_FLTR, GFP_KERNEL);
+	bp->ntp_fltr_bmap = bitmap_zalloc(BNXT_MAX_FLTR, GFP_KERNEL);
 
 	if (!bp->ntp_fltr_bmap)
 		rc = -ENOMEM;
@@ -5396,6 +5396,15 @@ static int bnxt_init_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr,
 	ether_addr_copy(fltr->l2_key.dst_mac_addr, key->dst_mac_addr);
 	fltr->l2_key.vlan = key->vlan;
 	fltr->base.type = BNXT_FLTR_TYPE_L2;
+	if (fltr->base.flags) {
+		int bit_id;
+
+		bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap,
+						 BNXT_MAX_FLTR, 0);
+		if (bit_id < 0)
+			return -ENOMEM;
+		fltr->base.sw_id = (u16)bit_id;
+	}
 	head = &bp->l2_fltr_hash_tbl[idx];
 	hlist_add_head_rcu(&fltr->base.hash, head);
 	atomic_set(&fltr->refcnt, 1);
@@ -5429,6 +5438,96 @@ static struct bnxt_l2_filter *bnxt_alloc_l2_filter(struct bnxt *bp,
 	return fltr;
 }
 
+static u16 bnxt_vf_target_id(struct bnxt_pf_info *pf, u16 vf_idx)
+{
+#ifdef CONFIG_BNXT_SRIOV
+	struct bnxt_vf_info *vf = &pf->vf[vf_idx];
+
+	return vf->fw_fid;
+#else
+	return INVALID_HW_RING_ID;
+#endif
+}
+
+int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr)
+{
+	struct hwrm_cfa_l2_filter_free_input *req;
+	u16 target_id = 0xffff;
+	int rc;
+
+	if (fltr->base.flags & BNXT_ACT_FUNC_DST) {
+		struct bnxt_pf_info *pf = &bp->pf;
+
+		if (fltr->base.vf_idx >= pf->active_vfs)
+			return -EINVAL;
+
+		target_id = bnxt_vf_target_id(pf, fltr->base.vf_idx);
+		if (target_id == INVALID_HW_RING_ID)
+			return -EINVAL;
+	}
+
+	rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_FREE);
+	if (rc)
+		return rc;
+
+	req->target_id = cpu_to_le16(target_id);
+	req->l2_filter_id = fltr->base.filter_id;
+	return hwrm_req_send(bp, req);
+}
+
+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 target_id = 0xffff;
+	int rc;
+
+	if (fltr->base.flags & BNXT_ACT_FUNC_DST) {
+		struct bnxt_pf_info *pf = &bp->pf;
+
+		if (fltr->base.vf_idx >= pf->active_vfs)
+			return -EINVAL;
+
+		target_id = bnxt_vf_target_id(pf, fltr->base.vf_idx);
+	}
+	rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_ALLOC);
+	if (rc)
+		return rc;
+
+	req->target_id = cpu_to_le16(target_id);
+	req->flags = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX);
+
+	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);
+	req->enables =
+		cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR |
+			    CFA_L2_FILTER_ALLOC_REQ_ENABLES_DST_ID |
+			    CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR_MASK);
+	ether_addr_copy(req->l2_addr, fltr->l2_key.dst_mac_addr);
+	eth_broadcast_addr(req->l2_addr_mask);
+
+	if (fltr->l2_key.vlan) {
+		req->enables |=
+			cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_IVLAN |
+				CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_IVLAN_MASK |
+				CFA_L2_FILTER_ALLOC_REQ_ENABLES_NUM_VLANS);
+		req->num_vlans = 1;
+		req->l2_ivlan = cpu_to_le16(fltr->l2_key.vlan);
+		req->l2_ivlan_mask = cpu_to_le16(0xfff);
+	}
+
+	resp = hwrm_req_hold(bp, req);
+	rc = hwrm_req_send(bp, req);
+	if (!rc) {
+		fltr->base.filter_id = resp->l2_filter_id;
+		set_bit(BNXT_FLTR_VALID, &fltr->base.state);
+	}
+	hwrm_req_drop(bp, req);
+	return rc;
+}
+
 #ifdef CONFIG_RFS_ACCEL
 static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 					    struct bnxt_ntuple_filter *fltr)
@@ -5538,8 +5637,6 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
 				     const u8 *mac_addr)
 {
-	struct hwrm_cfa_l2_filter_alloc_output *resp;
-	struct hwrm_cfa_l2_filter_alloc_input *req;
 	struct bnxt_l2_filter *fltr;
 	struct bnxt_l2_key key;
 	int rc;
@@ -5550,66 +5647,33 @@ static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
 	if (IS_ERR(fltr))
 		return PTR_ERR(fltr);
 
-	rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_ALLOC);
+	fltr->base.fw_vnic_id = bp->vnic_info[vnic_id].fw_vnic_id;
+	rc = bnxt_hwrm_l2_filter_alloc(bp, fltr);
 	if (rc)
-		return rc;
-
-	req->flags = cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_FLAGS_PATH_RX);
-	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(bp->vnic_info[vnic_id].fw_vnic_id);
-	req->enables =
-		cpu_to_le32(CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR |
-			    CFA_L2_FILTER_ALLOC_REQ_ENABLES_DST_ID |
-			    CFA_L2_FILTER_ALLOC_REQ_ENABLES_L2_ADDR_MASK);
-	memcpy(req->l2_addr, mac_addr, ETH_ALEN);
-	req->l2_addr_mask[0] = 0xff;
-	req->l2_addr_mask[1] = 0xff;
-	req->l2_addr_mask[2] = 0xff;
-	req->l2_addr_mask[3] = 0xff;
-	req->l2_addr_mask[4] = 0xff;
-	req->l2_addr_mask[5] = 0xff;
-
-	resp = hwrm_req_hold(bp, req);
-	rc = hwrm_req_send(bp, req);
-	if (rc) {
 		bnxt_del_l2_filter(bp, fltr);
-	} else {
-		fltr->base.filter_id = resp->l2_filter_id;
-		set_bit(BNXT_FLTR_VALID, &fltr->base.state);
+	else
 		bp->vnic_info[vnic_id].l2_filters[idx] = fltr;
-	}
-	hwrm_req_drop(bp, req);
 	return rc;
 }
 
 static int bnxt_hwrm_clear_vnic_filter(struct bnxt *bp)
 {
-	struct hwrm_cfa_l2_filter_free_input *req;
 	u16 i, j, num_of_vnics = 1; /* only vnic 0 supported */
-	int rc;
+	int rc = 0;
 
 	/* Any associated ntuple filters will also be cleared by firmware. */
-	rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_FREE);
-	if (rc)
-		return rc;
-	hwrm_req_hold(bp, req);
 	for (i = 0; i < num_of_vnics; i++) {
 		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
 
 		for (j = 0; j < vnic->uc_filter_count; j++) {
-			struct bnxt_l2_filter *fltr;
-
-			fltr = vnic->l2_filters[j];
-			req->l2_filter_id = fltr->base.filter_id;
+			struct bnxt_l2_filter *fltr = vnic->l2_filters[j];
 
-			rc = hwrm_req_send(bp, req);
+			bnxt_hwrm_l2_filter_free(bp, fltr);
 			bnxt_del_l2_filter(bp, fltr);
 		}
 		vnic->uc_filter_count = 0;
 	}
-	hwrm_req_drop(bp, req);
+
 	return rc;
 }
 
@@ -11898,7 +11962,6 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp)
 {
 	struct net_device *dev = bp->dev;
 	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
-	struct hwrm_cfa_l2_filter_free_input *req;
 	struct netdev_hw_addr *ha;
 	int i, off = 0, rc;
 	bool uc_update;
@@ -11910,19 +11973,12 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp)
 	if (!uc_update)
 		goto skip_uc;
 
-	rc = hwrm_req_init(bp, req, HWRM_CFA_L2_FILTER_FREE);
-	if (rc)
-		return rc;
-	hwrm_req_hold(bp, req);
 	for (i = 1; i < vnic->uc_filter_count; i++) {
 		struct bnxt_l2_filter *fltr = vnic->l2_filters[i];
 
-		req->l2_filter_id = fltr->base.filter_id;
-
-		rc = hwrm_req_send(bp, req);
+		bnxt_hwrm_l2_filter_free(bp, fltr);
 		bnxt_del_l2_filter(bp, fltr);
 	}
-	hwrm_req_drop(bp, req);
 
 	vnic->uc_filter_count = 1;
 
@@ -13823,8 +13879,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	rcu_read_unlock();
 
 	spin_lock_bh(&bp->ntp_fltr_lock);
-	bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap,
-					 BNXT_NTP_FLTR_MAX_FLTR, 0);
+	bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, BNXT_MAX_FLTR, 0);
 	if (bit_id < 0) {
 		spin_unlock_bh(&bp->ntp_fltr_lock);
 		rc = -ENOMEM;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 72e99f2a5c68..5d67b8299328 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2398,6 +2398,7 @@ struct bnxt {
 	int			db_size;
 
 #define BNXT_NTP_FLTR_MAX_FLTR	4096
+#define BNXT_MAX_FLTR		(BNXT_NTP_FLTR_MAX_FLTR + BNXT_L2_FLTR_MAX_FLTR)
 #define BNXT_NTP_FLTR_HASH_SIZE	512
 #define BNXT_NTP_FLTR_HASH_MASK	(BNXT_NTP_FLTR_HASH_SIZE - 1)
 	struct hlist_head	ntp_fltr_hash_tbl[BNXT_NTP_FLTR_HASH_SIZE];
@@ -2621,6 +2622,8 @@ int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
 			    int bmap_size, bool async_only);
 int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp);
 void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr);
+int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr);
+int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 05/13] bnxt_en: Add function to calculate Toeplitz hash
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (3 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 04/13] bnxt_en: Refactor L2 filter alloc/free firmware commands Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-23  4:22 ` [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function Michael Chan
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 6140 bytes --]

From: Pavan Chebbi <pavan.chebbi@broadcom.com>

For ntuple filters added by aRFS, the Toeplitz hash calculated by our
NIC is available and is used to store the ntuple filter for quick
retrieval.  In the next patches, user defined ntuple filter support
will be added and we need to calculate the same hash for these
filters.  The same hash function needs to be used so we can detect
duplicates.

Add the function bnxt_toeplitz() to calculate the Toeplitz hash for
user defined ntuple filters.  bnxt_toeplitz() uses the same Toeplitz
key and the same key length as the NIC.

bnxt_get_ntp_filter_idx() is added to return the hash index.  For
aRFS, the hash comes from the NIC.  For user defined ntuple, we call
bnxt_toeplitz() to calculate the hash index.

Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 100 +++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  11 +++
 2 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 571f2c443c2e..e9b382832a14 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4199,13 +4199,22 @@ static void bnxt_init_vnics(struct bnxt *bp)
 		vnic->fw_l2_ctx_id = INVALID_HW_RING_ID;
 
 		if (bp->vnic_info[i].rss_hash_key) {
-			if (i == 0)
+			if (!i) {
+				u8 *key = (void *)vnic->rss_hash_key;
+				int k;
+
+				bp->toeplitz_prefix = 0;
 				get_random_bytes(vnic->rss_hash_key,
 					      HW_HASH_KEY_SIZE);
-			else
+				for (k = 0; k < 8; k++) {
+					bp->toeplitz_prefix <<= 8;
+					bp->toeplitz_prefix |= key[k];
+				}
+			} else {
 				memcpy(vnic->rss_hash_key,
 				       bp->vnic_info[0].rss_hash_key,
 				       HW_HASH_KEY_SIZE);
+			}
 		}
 	}
 }
@@ -5374,6 +5383,79 @@ static struct bnxt_l2_filter *bnxt_lookup_l2_filter(struct bnxt *bp,
 	return fltr;
 }
 
+#define BNXT_IPV4_4TUPLE(bp, fkeys)					\
+	(((fkeys)->basic.ip_proto == IPPROTO_TCP &&			\
+	  (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4) ||	\
+	 ((fkeys)->basic.ip_proto == IPPROTO_UDP &&			\
+	  (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4))
+
+#define BNXT_IPV6_4TUPLE(bp, fkeys)					\
+	(((fkeys)->basic.ip_proto == IPPROTO_TCP &&			\
+	  (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6) ||	\
+	 ((fkeys)->basic.ip_proto == IPPROTO_UDP &&			\
+	  (bp)->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6))
+
+static u32 bnxt_get_rss_flow_tuple_len(struct bnxt *bp, struct flow_keys *fkeys)
+{
+	if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
+		if (BNXT_IPV4_4TUPLE(bp, fkeys))
+			return sizeof(fkeys->addrs.v4addrs) +
+			       sizeof(fkeys->ports);
+
+		if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4)
+			return sizeof(fkeys->addrs.v4addrs);
+	}
+
+	if (fkeys->basic.n_proto == htons(ETH_P_IPV6)) {
+		if (BNXT_IPV6_4TUPLE(bp, fkeys))
+			return sizeof(fkeys->addrs.v6addrs) +
+			       sizeof(fkeys->ports);
+
+		if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6)
+			return sizeof(fkeys->addrs.v6addrs);
+	}
+
+	return 0;
+}
+
+static u32 bnxt_toeplitz(struct bnxt *bp, struct flow_keys *fkeys,
+			 const unsigned char *key)
+{
+	u64 prefix = bp->toeplitz_prefix, hash = 0;
+	struct bnxt_ipv4_tuple tuple4;
+	struct bnxt_ipv6_tuple tuple6;
+	int i, j, len = 0;
+	u8 *four_tuple;
+
+	len = bnxt_get_rss_flow_tuple_len(bp, fkeys);
+	if (!len)
+		return 0;
+
+	if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
+		tuple4.v4addrs = fkeys->addrs.v4addrs;
+		tuple4.ports = fkeys->ports;
+		four_tuple = (unsigned char *)&tuple4;
+	} else {
+		tuple6.v6addrs = fkeys->addrs.v6addrs;
+		tuple6.ports = fkeys->ports;
+		four_tuple = (unsigned char *)&tuple6;
+	}
+
+	for (i = 0, j = 8; i < len; i++, j++) {
+		u8 byte = four_tuple[i];
+		int bit;
+
+		for (bit = 0; bit < 8; bit++, prefix <<= 1, byte <<= 1) {
+			if (byte & 0x80)
+				hash ^= prefix;
+		}
+		prefix |= (j < HW_HASH_KEY_SIZE) ? key[j] : 0;
+	}
+
+	/* The valid part of the hash is in the upper 32 bits. */
+	return (hash >> 32) & BNXT_NTP_FLTR_HASH_MASK;
+}
+
 #ifdef CONFIG_RFS_ACCEL
 static struct bnxt_l2_filter *
 bnxt_lookup_l2_filter_from_key(struct bnxt *bp, struct bnxt_l2_key *key)
@@ -13774,6 +13856,18 @@ static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
 	}
 }
 
+static u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
+				   const struct sk_buff *skb)
+{
+	struct bnxt_vnic_info *vnic;
+
+	if (skb)
+		return skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK;
+
+	vnic = &bp->vnic_info[0];
+	return bnxt_toeplitz(bp, fkeys, (void *)vnic->rss_hash_key);
+}
+
 #ifdef CONFIG_RFS_ACCEL
 static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
 			    struct bnxt_ntuple_filter *f2)
@@ -13866,7 +13960,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 
 	new_fltr->l2_fltr = l2_fltr;
 
-	idx = skb_get_hash_raw(skb) & BNXT_NTP_FLTR_HASH_MASK;
+	idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
 	head = &bp->ntp_fltr_hash_tbl[idx];
 	rcu_read_lock();
 	hlist_for_each_entry_rcu(fltr, head, base.hash) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 5d67b8299328..3f4e4708f7d8 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1370,6 +1370,16 @@ struct bnxt_l2_key {
 	};
 };
 
+struct bnxt_ipv4_tuple {
+	struct flow_dissector_key_ipv4_addrs v4addrs;
+	struct flow_dissector_key_ports ports;
+};
+
+struct bnxt_ipv6_tuple {
+	struct flow_dissector_key_ipv6_addrs v6addrs;
+	struct flow_dissector_key_ports ports;
+};
+
 #define BNXT_L2_KEY_SIZE	(sizeof(struct bnxt_l2_key) / 4)
 
 struct bnxt_l2_filter {
@@ -2413,6 +2423,7 @@ struct bnxt {
 	struct hlist_head	l2_fltr_hash_tbl[BNXT_L2_FLTR_HASH_SIZE];
 
 	u32			hash_seed;
+	u64			toeplitz_prefix;
 
 	/* To protect link related settings during link changes and
 	 * ethtool settings changes.
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (4 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 05/13] bnxt_en: Add function to calculate Toeplitz hash Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 16:56   ` Simon Horman
  2023-12-25 17:45   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct Michael Chan
                   ` (7 subsequent siblings)
  13 siblings, 2 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 1879 bytes --]

Add the helper function to look up the ntuple filter from the
hash index and use it in bnxt_rx_flow_steer().  The helper function
will also be used by user defined ntuple filters in the next
patches.

Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 26 +++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index e9b382832a14..7027391316e5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -13899,6 +13899,21 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
 	return false;
 }
 
+static struct bnxt_ntuple_filter *
+bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
+				struct bnxt_ntuple_filter *fltr, u32 idx)
+{
+	struct bnxt_ntuple_filter *f;
+	struct hlist_head *head;
+
+	head = &bp->ntp_fltr_hash_tbl[idx];
+	hlist_for_each_entry_rcu(f, head, base.hash) {
+		if (bnxt_fltr_match(f, fltr))
+			return f;
+	}
+	return NULL;
+}
+
 static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 			      u16 rxq_index, u32 flow_id)
 {
@@ -13963,12 +13978,11 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
 	head = &bp->ntp_fltr_hash_tbl[idx];
 	rcu_read_lock();
-	hlist_for_each_entry_rcu(fltr, head, base.hash) {
-		if (bnxt_fltr_match(fltr, new_fltr)) {
-			rc = fltr->base.sw_id;
-			rcu_read_unlock();
-			goto err_free;
-		}
+	fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx);
+	if (fltr) {
+		rcu_read_unlock();
+		rc = fltr->base.sw_id;
+		goto err_free;
 	}
 	rcu_read_unlock();
 
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (5 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 17:02   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer() Michael Chan
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 2871 bytes --]

Change the unused flag to BNXT_FLTR_INSERTED.  To prepare for multiple
pathways that an ntuple filter can be deleted, we add this flag.  These
filter structures can be retreived from the RCU hash table but only
the caller that sees that the BNXT_FLTR_INSERTED flag is set can delete
the filter structure and clear the flag under spinlock.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 ++++++++++
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  2 +-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 7027391316e5..0aecf89b4fb9 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5343,6 +5343,10 @@ void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr)
 	if (!atomic_dec_and_test(&fltr->refcnt))
 		return;
 	spin_lock_bh(&bp->ntp_fltr_lock);
+	if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) {
+		spin_unlock_bh(&bp->ntp_fltr_lock);
+		return;
+	}
 	hlist_del_rcu(&fltr->base.hash);
 	if (fltr->base.flags) {
 		clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
@@ -5489,6 +5493,7 @@ static int bnxt_init_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr,
 	}
 	head = &bp->l2_fltr_hash_tbl[idx];
 	hlist_add_head_rcu(&fltr->base.hash, head);
+	set_bit(BNXT_FLTR_INSERTED, &fltr->base.state);
 	atomic_set(&fltr->refcnt, 1);
 	return 0;
 }
@@ -14000,6 +14005,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	new_fltr->base.type = BNXT_FLTR_TYPE_NTUPLE;
 	new_fltr->base.flags = BNXT_ACT_RING_DST;
 	hlist_add_head_rcu(&new_fltr->base.hash, head);
+	set_bit(BNXT_FLTR_INSERTED, &new_fltr->base.state);
 	bp->ntp_fltr_count++;
 	spin_unlock_bh(&bp->ntp_fltr_lock);
 
@@ -14046,6 +14052,10 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 
 			if (del) {
 				spin_lock_bh(&bp->ntp_fltr_lock);
+				if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) {
+					spin_unlock_bh(&bp->ntp_fltr_lock);
+					continue;
+				}
 				hlist_del_rcu(&fltr->base.hash);
 				bp->ntp_fltr_count--;
 				spin_unlock_bh(&bp->ntp_fltr_lock);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 3f4e4708f7d8..867cab036e13 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1348,7 +1348,7 @@ struct bnxt_filter_base {
 	u16			vf_idx;
 	unsigned long		state;
 #define BNXT_FLTR_VALID		0
-#define BNXT_FLTR_UPDATE	1
+#define BNXT_FLTR_INSERTED	1
 
 	struct rcu_head         rcu;
 };
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer().
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (6 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 17:11   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 09/13] bnxt_en: Refactor the hash table logic for ntuple filters Michael Chan
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 8706 bytes --]

Add a new function bnxt_insert_ntp_filter() to insert the ntuple filter
into the hash table and other basic setup.  We'll use this function
to insert a user defined filter from ethtool.

Also, export bnxt_lookup_ntp_filter_from_idx() and bnxt_get_ntp_filter_idx()
for similar purposes.  All ntuple related functions are now no longer
compiled only for CONFIG_RFS_ACCEL

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 87 +++++++++--------------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  6 ++
 2 files changed, 41 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 0aecf89b4fb9..097d440339b0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4800,7 +4800,6 @@ static void bnxt_clear_ring_indices(struct bnxt *bp)
 
 static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool all)
 {
-#ifdef CONFIG_RFS_ACCEL
 	int i;
 
 	/* Under rtnl_lock and all our NAPIs have been disabled.  It's
@@ -4828,12 +4827,10 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool all)
 	bitmap_free(bp->ntp_fltr_bmap);
 	bp->ntp_fltr_bmap = NULL;
 	bp->ntp_fltr_count = 0;
-#endif
 }
 
 static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
 {
-#ifdef CONFIG_RFS_ACCEL
 	int i, rc = 0;
 
 	if (!(bp->flags & BNXT_FLAG_RFS) || bp->ntp_fltr_bmap)
@@ -4849,9 +4846,6 @@ static int bnxt_alloc_ntp_fltrs(struct bnxt *bp)
 		rc = -ENOMEM;
 
 	return rc;
-#else
-	return 0;
-#endif
 }
 
 static void bnxt_free_l2_filters(struct bnxt *bp, bool all)
@@ -5615,7 +5609,6 @@ int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr)
 	return rc;
 }
 
-#ifdef CONFIG_RFS_ACCEL
 static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 					    struct bnxt_ntuple_filter *fltr)
 {
@@ -5719,7 +5712,6 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	hwrm_req_drop(bp, req);
 	return rc;
 }
-#endif
 
 static int bnxt_hwrm_set_vnic_filter(struct bnxt *bp, u16 vnic_id, u16 idx,
 				     const u8 *mac_addr)
@@ -9677,7 +9669,6 @@ static int bnxt_setup_vnic(struct bnxt *bp, u16 vnic_id)
 
 static int bnxt_alloc_rfs_vnics(struct bnxt *bp)
 {
-#ifdef CONFIG_RFS_ACCEL
 	int i, rc = 0;
 
 	if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS)
@@ -9706,9 +9697,6 @@ static int bnxt_alloc_rfs_vnics(struct bnxt *bp)
 			break;
 	}
 	return rc;
-#else
-	return 0;
-#endif
 }
 
 /* Allow PF, trusted VFs and VFs with default VLAN to be in promiscuous mode */
@@ -10036,7 +10024,6 @@ static int bnxt_setup_int_mode(struct bnxt *bp)
 	return rc;
 }
 
-#ifdef CONFIG_RFS_ACCEL
 static unsigned int bnxt_get_max_func_rss_ctxs(struct bnxt *bp)
 {
 	return bp->hw_resc.max_rsscos_ctxs;
@@ -10046,7 +10033,6 @@ static unsigned int bnxt_get_max_func_vnics(struct bnxt *bp)
 {
 	return bp->hw_resc.max_vnics;
 }
-#endif
 
 unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp)
 {
@@ -12160,7 +12146,6 @@ static bool bnxt_rfs_supported(struct bnxt *bp)
 /* If runtime conditions support RFS */
 static bool bnxt_rfs_capable(struct bnxt *bp)
 {
-#ifdef CONFIG_RFS_ACCEL
 	int vnics, max_vnics, max_rss_ctxs;
 
 	if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS)
@@ -12196,9 +12181,6 @@ static bool bnxt_rfs_capable(struct bnxt *bp)
 	netdev_warn(bp->dev, "Unable to reserve resources to support NTUPLE filters.\n");
 	bnxt_hwrm_reserve_rings(bp, 0, 0, 0, 0, 0, 1);
 	return false;
-#else
-	return false;
-#endif
 }
 
 static netdev_features_t bnxt_fix_features(struct net_device *dev,
@@ -13861,8 +13843,8 @@ static int bnxt_setup_tc(struct net_device *dev, enum tc_setup_type type,
 	}
 }
 
-static u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
-				   const struct sk_buff *skb)
+u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
+			    const struct sk_buff *skb)
 {
 	struct bnxt_vnic_info *vnic;
 
@@ -13873,7 +13855,30 @@ static u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
 	return bnxt_toeplitz(bp, fkeys, (void *)vnic->rss_hash_key);
 }
 
-#ifdef CONFIG_RFS_ACCEL
+int bnxt_insert_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr,
+			   u32 idx)
+{
+	struct hlist_head *head;
+	int bit_id;
+
+	spin_lock_bh(&bp->ntp_fltr_lock);
+	bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, BNXT_MAX_FLTR, 0);
+	if (bit_id < 0) {
+		spin_unlock_bh(&bp->ntp_fltr_lock);
+		return -ENOMEM;
+	}
+
+	fltr->base.sw_id = (u16)bit_id;
+	fltr->base.type = BNXT_FLTR_TYPE_NTUPLE;
+	fltr->base.flags |= BNXT_ACT_RING_DST;
+	head = &bp->ntp_fltr_hash_tbl[idx];
+	hlist_add_head_rcu(&fltr->base.hash, head);
+	set_bit(BNXT_FLTR_INSERTED, &fltr->base.state);
+	bp->ntp_fltr_count++;
+	spin_unlock_bh(&bp->ntp_fltr_lock);
+	return 0;
+}
+
 static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
 			    struct bnxt_ntuple_filter *f2)
 {
@@ -13904,7 +13909,7 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
 	return false;
 }
 
-static struct bnxt_ntuple_filter *
+struct bnxt_ntuple_filter *
 bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
 				struct bnxt_ntuple_filter *fltr, u32 idx)
 {
@@ -13919,6 +13924,7 @@ bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
 	return NULL;
 }
 
+#ifdef CONFIG_RFS_ACCEL
 static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 			      u16 rxq_index, u32 flow_id)
 {
@@ -13927,8 +13933,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	struct flow_keys *fkeys;
 	struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb);
 	struct bnxt_l2_filter *l2_fltr;
-	int rc = 0, idx, bit_id;
-	struct hlist_head *head;
+	int rc = 0, idx;
 	u32 flags;
 
 	if (ether_addr_equal(dev->dev_addr, eth->h_dest)) {
@@ -13981,7 +13986,6 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	new_fltr->l2_fltr = l2_fltr;
 
 	idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
-	head = &bp->ntp_fltr_hash_tbl[idx];
 	rcu_read_lock();
 	fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx);
 	if (fltr) {
@@ -13991,33 +13995,20 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	}
 	rcu_read_unlock();
 
-	spin_lock_bh(&bp->ntp_fltr_lock);
-	bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, BNXT_MAX_FLTR, 0);
-	if (bit_id < 0) {
-		spin_unlock_bh(&bp->ntp_fltr_lock);
-		rc = -ENOMEM;
-		goto err_free;
-	}
-
-	new_fltr->base.sw_id = (u16)bit_id;
 	new_fltr->flow_id = flow_id;
 	new_fltr->base.rxq = rxq_index;
-	new_fltr->base.type = BNXT_FLTR_TYPE_NTUPLE;
-	new_fltr->base.flags = BNXT_ACT_RING_DST;
-	hlist_add_head_rcu(&new_fltr->base.hash, head);
-	set_bit(BNXT_FLTR_INSERTED, &new_fltr->base.state);
-	bp->ntp_fltr_count++;
-	spin_unlock_bh(&bp->ntp_fltr_lock);
-
-	bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT);
-
-	return new_fltr->base.sw_id;
+	rc = bnxt_insert_ntp_filter(bp, new_fltr, idx);
+	if (!rc) {
+		bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT);
+		return new_fltr->base.sw_id;
+	}
 
 err_free:
 	bnxt_del_l2_filter(bp, l2_fltr);
 	kfree(new_fltr);
 	return rc;
 }
+#endif
 
 static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 {
@@ -14070,14 +14061,6 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 		netdev_info(bp->dev, "Receive PF driver unload event!\n");
 }
 
-#else
-
-static void bnxt_cfg_ntp_filters(struct bnxt *bp)
-{
-}
-
-#endif /* CONFIG_RFS_ACCEL */
-
 static int bnxt_udp_tunnel_set_port(struct net_device *netdev, unsigned int table,
 				    unsigned int entry, struct udp_tunnel_info *ti)
 {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 867cab036e13..73e2fe705caf 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2678,6 +2678,12 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
 int bnxt_fw_init_one(struct bnxt *bp);
 bool bnxt_hwrm_reset_permitted(struct bnxt *bp);
 int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
+struct bnxt_ntuple_filter *bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
+				struct bnxt_ntuple_filter *fltr, u32 idx);
+u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
+			    const struct sk_buff *skb);
+int bnxt_insert_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr,
+			   u32 idx);
 int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
 int bnxt_restore_pf_fw_resources(struct bnxt *bp);
 int bnxt_get_port_parent_id(struct net_device *dev,
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 09/13] bnxt_en: Refactor the hash table logic for ntuple filters.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (7 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer() Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-23  4:22 ` [PATCH net-next v2 10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters() Michael Chan
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 4879 bytes --]

Generalize the ethtool logic that walks the ntuple hash table now that
we have the common bnxt_filter_base structure.  This will allow the code
to easily extend to cover user defined ntuple or ether filters.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |  1 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.h     |  1 +
 .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 85 +++++++++++++------
 3 files changed, 59 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 097d440339b0..1e5bf8b7dd55 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5615,6 +5615,7 @@ static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 	struct hwrm_cfa_ntuple_filter_free_input *req;
 	int rc;
 
+	set_bit(BNXT_FLTR_FW_DELETED, &fltr->base.state);
 	rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE);
 	if (rc)
 		return rc;
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 73e2fe705caf..f37d98d7962a 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1349,6 +1349,7 @@ struct bnxt_filter_base {
 	unsigned long		state;
 #define BNXT_FLTR_VALID		0
 #define BNXT_FLTR_INSERTED	1
+#define BNXT_FLTR_FW_DELETED	2
 
 	struct rcu_head         rcu;
 };
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 65edad2cfeab..8cc762a12a3e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1012,28 +1012,60 @@ static int bnxt_set_channels(struct net_device *dev,
 }
 
 #ifdef CONFIG_RFS_ACCEL
-static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd,
-			    u32 *rule_locs)
+static u32 bnxt_get_all_fltr_ids_rcu(struct bnxt *bp, struct hlist_head tbl[],
+				     int tbl_size, u32 *ids, u32 start,
+				     u32 id_cnt)
 {
-	int i, j = 0;
+	int i, j = start;
 
-	cmd->data = bp->ntp_fltr_count;
-	for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) {
+	if (j >= id_cnt)
+		return j;
+	for (i = 0; i < tbl_size; i++) {
 		struct hlist_head *head;
-		struct bnxt_ntuple_filter *fltr;
+		struct bnxt_filter_base *fltr;
 
-		head = &bp->ntp_fltr_hash_tbl[i];
-		rcu_read_lock();
-		hlist_for_each_entry_rcu(fltr, head, base.hash) {
-			if (j == cmd->rule_cnt)
-				break;
-			rule_locs[j++] = fltr->base.sw_id;
+		head = &tbl[i];
+		hlist_for_each_entry_rcu(fltr, head, hash) {
+			if (!fltr->flags ||
+			    test_bit(BNXT_FLTR_FW_DELETED, &fltr->state))
+				continue;
+			ids[j++] = fltr->sw_id;
+			if (j == id_cnt)
+				return j;
 		}
-		rcu_read_unlock();
-		if (j == cmd->rule_cnt)
-			break;
 	}
-	cmd->rule_cnt = j;
+	return j;
+}
+
+static struct bnxt_filter_base *bnxt_get_one_fltr_rcu(struct bnxt *bp,
+						      struct hlist_head tbl[],
+						      int tbl_size, u32 id)
+{
+	int i;
+
+	for (i = 0; i < tbl_size; i++) {
+		struct hlist_head *head;
+		struct bnxt_filter_base *fltr;
+
+		head = &tbl[i];
+		hlist_for_each_entry_rcu(fltr, head, hash) {
+			if (fltr->flags && fltr->sw_id == id)
+				return fltr;
+		}
+	}
+	return NULL;
+}
+
+static int bnxt_grxclsrlall(struct bnxt *bp, struct ethtool_rxnfc *cmd,
+			    u32 *rule_locs)
+{
+	cmd->data = bp->ntp_fltr_count;
+	rcu_read_lock();
+	cmd->rule_cnt = bnxt_get_all_fltr_ids_rcu(bp, bp->ntp_fltr_hash_tbl,
+						  BNXT_NTP_FLTR_HASH_SIZE,
+						  rule_locs, 0, cmd->rule_cnt);
+	rcu_read_unlock();
+
 	return 0;
 }
 
@@ -1041,27 +1073,24 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 {
 	struct ethtool_rx_flow_spec *fs =
 		(struct ethtool_rx_flow_spec *)&cmd->fs;
+	struct bnxt_filter_base *fltr_base;
 	struct bnxt_ntuple_filter *fltr;
 	struct flow_keys *fkeys;
-	int i, rc = -EINVAL;
+	int rc = -EINVAL;
 
 	if (fs->location >= BNXT_NTP_FLTR_MAX_FLTR)
 		return rc;
 
-	for (i = 0; i < BNXT_NTP_FLTR_HASH_SIZE; i++) {
-		struct hlist_head *head;
-
-		head = &bp->ntp_fltr_hash_tbl[i];
-		rcu_read_lock();
-		hlist_for_each_entry_rcu(fltr, head, base.hash) {
-			if (fltr->base.sw_id == fs->location)
-				goto fltr_found;
-		}
+	rcu_read_lock();
+	fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl,
+					  BNXT_NTP_FLTR_HASH_SIZE,
+					  fs->location);
+	if (!fltr_base) {
 		rcu_read_unlock();
+		return rc;
 	}
-	return rc;
+	fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
 
-fltr_found:
 	fkeys = &fltr->fkeys;
 	if (fkeys->basic.n_proto == htons(ETH_P_IP)) {
 		if (fkeys->basic.ip_proto == IPPROTO_TCP)
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters().
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (8 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 09/13] bnxt_en: Refactor the hash table logic for ntuple filters Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 17:44   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 11/13] bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter structure Michael Chan
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 3939 bytes --]

Refactor the logic into a new function bnxt_del_ntp_filters().  The
same call will be used when the user deletes an ntuple filter.

The bnxt_hwrm_cfa_ntuple_filter_free() function to call fw to free
the ntuple filter is exported so that the ethtool logic can call it.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 35 ++++++++++++-----------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  3 ++
 2 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 1e5bf8b7dd55..79a1081c25f5 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5609,8 +5609,8 @@ int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr)
 	return rc;
 }
 
-static int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
-					    struct bnxt_ntuple_filter *fltr)
+int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
+				     struct bnxt_ntuple_filter *fltr)
 {
 	struct hwrm_cfa_ntuple_filter_free_input *req;
 	int rc;
@@ -14011,6 +14011,21 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 }
 #endif
 
+void bnxt_del_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr)
+{
+	spin_lock_bh(&bp->ntp_fltr_lock);
+	if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) {
+		spin_unlock_bh(&bp->ntp_fltr_lock);
+		return;
+	}
+	hlist_del_rcu(&fltr->base.hash);
+	bp->ntp_fltr_count--;
+	spin_unlock_bh(&bp->ntp_fltr_lock);
+	bnxt_del_l2_filter(bp, fltr->l2_fltr);
+	clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
+	kfree_rcu(fltr, base.rcu);
+}
+
 static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 {
 	int i;
@@ -14042,20 +14057,8 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 					set_bit(BNXT_FLTR_VALID, &fltr->base.state);
 			}
 
-			if (del) {
-				spin_lock_bh(&bp->ntp_fltr_lock);
-				if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) {
-					spin_unlock_bh(&bp->ntp_fltr_lock);
-					continue;
-				}
-				hlist_del_rcu(&fltr->base.hash);
-				bp->ntp_fltr_count--;
-				spin_unlock_bh(&bp->ntp_fltr_lock);
-				bnxt_del_l2_filter(bp, fltr->l2_fltr);
-				synchronize_rcu();
-				clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
-				kfree(fltr);
-			}
+			if (del)
+				bnxt_del_ntp_filter(bp, fltr);
 		}
 	}
 	if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event))
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index f37d98d7962a..60f62bc36d2c 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2636,6 +2636,8 @@ int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp);
 void bnxt_del_l2_filter(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr);
+int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
+				     struct bnxt_ntuple_filter *fltr);
 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
@@ -2685,6 +2687,7 @@ u32 bnxt_get_ntp_filter_idx(struct bnxt *bp, struct flow_keys *fkeys,
 			    const struct sk_buff *skb);
 int bnxt_insert_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr,
 			   u32 idx);
+void bnxt_del_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr);
 int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
 int bnxt_restore_pf_fw_resources(struct bnxt *bp);
 int bnxt_get_port_parent_id(struct net_device *dev,
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 11/13] bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter structure.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (9 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters() Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-23  4:22 ` [PATCH net-next v2 12/13] bnxt_en: Add support for ntuple filters added from ethtool Michael Chan
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 10160 bytes --]

aRFS filters match all 5 tuples.  User defined ntuple filters may
specify some of the tuples as wildcards.  To support that, we add the
ntuple_flags to the bnxt_ntuple_filter struct to specify which tuple
fields are to be matched.  The matching tuple fields will then be
passed to the firmware in bnxt_hwrm_cfa_ntuple_filter_alloc() to create
the proper filter.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     | 81 +++++++++++++------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h     | 10 +++
 .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 58 +++++++------
 3 files changed, 99 insertions(+), 50 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 79a1081c25f5..b949ab124dda 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5642,6 +5642,14 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 #define BNXT_NTP_TUNNEL_FLTR_FLAG				\
 		CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE
 
+void bnxt_fill_ipv6_mask(__be32 mask[4])
+{
+	int i;
+
+	for (i = 0; i < 4; i++)
+		mask[i] = cpu_to_be32(~0);
+}
+
 static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 					     struct bnxt_ntuple_filter *fltr)
 {
@@ -5676,24 +5684,28 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 	req->ip_protocol = keys->basic.ip_proto;
 
 	if (keys->basic.n_proto == htons(ETH_P_IPV6)) {
-		int i;
-
 		req->ethertype = htons(ETH_P_IPV6);
 		req->ip_addr_type =
 			CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6;
-		*(struct in6_addr *)&req->src_ipaddr[0] =
-			keys->addrs.v6addrs.src;
-		*(struct in6_addr *)&req->dst_ipaddr[0] =
-			keys->addrs.v6addrs.dst;
-		for (i = 0; i < 4; i++) {
-			req->src_ipaddr_mask[i] = cpu_to_be32(0xffffffff);
-			req->dst_ipaddr_mask[i] = cpu_to_be32(0xffffffff);
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
+			*(struct in6_addr *)&req->src_ipaddr[0] =
+				keys->addrs.v6addrs.src;
+			bnxt_fill_ipv6_mask(req->src_ipaddr_mask);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
+			*(struct in6_addr *)&req->dst_ipaddr[0] =
+				keys->addrs.v6addrs.dst;
+			bnxt_fill_ipv6_mask(req->dst_ipaddr_mask);
 		}
 	} else {
-		req->src_ipaddr[0] = keys->addrs.v4addrs.src;
-		req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
-		req->dst_ipaddr[0] = keys->addrs.v4addrs.dst;
-		req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
+			req->src_ipaddr[0] = keys->addrs.v4addrs.src;
+			req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
+			req->dst_ipaddr[0] = keys->addrs.v4addrs.dst;
+			req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
+		}
 	}
 	if (keys->control.flags & FLOW_DIS_ENCAPSULATION) {
 		req->enables |= cpu_to_le32(BNXT_NTP_TUNNEL_FLTR_FLAG);
@@ -5701,10 +5713,14 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
 			CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL;
 	}
 
-	req->src_port = keys->ports.src;
-	req->src_port_mask = cpu_to_be16(0xffff);
-	req->dst_port = keys->ports.dst;
-	req->dst_port_mask = cpu_to_be16(0xffff);
+	if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
+		req->src_port = keys->ports.src;
+		req->src_port_mask = cpu_to_be16(0xffff);
+	}
+	if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
+		req->dst_port = keys->ports.dst;
+		req->dst_port_mask = cpu_to_be16(0xffff);
+	}
 
 	resp = hwrm_req_hold(bp, req);
 	rc = hwrm_req_send(bp, req);
@@ -13886,24 +13902,38 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
 	struct flow_keys *keys1 = &f1->fkeys;
 	struct flow_keys *keys2 = &f2->fkeys;
 
+	if (f1->ntuple_flags != f2->ntuple_flags)
+		return false;
+
 	if (keys1->basic.n_proto != keys2->basic.n_proto ||
 	    keys1->basic.ip_proto != keys2->basic.ip_proto)
 		return false;
 
 	if (keys1->basic.n_proto == htons(ETH_P_IP)) {
-		if (keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src ||
-		    keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst)
+		if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) &&
+		     keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src) ||
+		    ((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) &&
+		     keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst))
 			return false;
 	} else {
-		if (memcmp(&keys1->addrs.v6addrs.src, &keys2->addrs.v6addrs.src,
-			   sizeof(keys1->addrs.v6addrs.src)) ||
-		    memcmp(&keys1->addrs.v6addrs.dst, &keys2->addrs.v6addrs.dst,
-			   sizeof(keys1->addrs.v6addrs.dst)))
+		if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) &&
+		     memcmp(&keys1->addrs.v6addrs.src,
+			    &keys2->addrs.v6addrs.src,
+			    sizeof(keys1->addrs.v6addrs.src))) ||
+		    ((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) &&
+		     memcmp(&keys1->addrs.v6addrs.dst,
+			    &keys2->addrs.v6addrs.dst,
+			    sizeof(keys1->addrs.v6addrs.dst))))
 			return false;
 	}
 
-	if (keys1->ports.ports == keys2->ports.ports &&
-	    keys1->control.flags == keys2->control.flags &&
+	if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) &&
+	     keys1->ports.src != keys2->ports.src) ||
+	    ((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) &&
+	     keys1->ports.dst != keys2->ports.dst))
+		return false;
+
+	if (keys1->control.flags == keys2->control.flags &&
 	    f1->l2_fltr == f2->l2_fltr)
 		return true;
 
@@ -13985,6 +14015,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
 	}
 
 	new_fltr->l2_fltr = l2_fltr;
+	new_fltr->ntuple_flags = BNXT_NTUPLE_MATCH_ALL;
 
 	idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
 	rcu_read_lock();
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 60f62bc36d2c..dc1bc163c82f 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1358,6 +1358,15 @@ struct bnxt_ntuple_filter {
 	struct bnxt_filter_base	base;
 	struct flow_keys	fkeys;
 	struct bnxt_l2_filter	*l2_fltr;
+	u32			ntuple_flags;
+#define BNXT_NTUPLE_MATCH_SRC_IP	1
+#define BNXT_NTUPLE_MATCH_DST_IP	2
+#define BNXT_NTUPLE_MATCH_SRC_PORT	4
+#define BNXT_NTUPLE_MATCH_DST_PORT	8
+#define BNXT_NTUPLE_MATCH_ALL		(BNXT_NTUPLE_MATCH_SRC_IP |	\
+					 BNXT_NTUPLE_MATCH_DST_IP |	\
+					 BNXT_NTUPLE_MATCH_SRC_PORT |	\
+					 BNXT_NTUPLE_MATCH_DST_PORT)
 	u32			flow_id;
 };
 
@@ -2638,6 +2647,7 @@ int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 				     struct bnxt_ntuple_filter *fltr);
+void bnxt_fill_ipv6_mask(__be32 mask[4]);
 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 8cc762a12a3e..558dd1f9a18e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1100,20 +1100,23 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 		else
 			goto fltr_err;
 
-		fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src;
-		fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0);
-
-		fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst;
-		fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0);
-
-		fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src;
-		fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0);
-
-		fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst;
-		fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0);
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
+			fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src;
+			fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
+			fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst;
+			fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
+			fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src;
+			fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
+			fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst;
+			fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0);
+		}
 	} else {
-		int i;
-
 		if (fkeys->basic.ip_proto == IPPROTO_TCP)
 			fs->flow_type = TCP_V6_FLOW;
 		else if (fkeys->basic.ip_proto == IPPROTO_UDP)
@@ -1121,19 +1124,24 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 		else
 			goto fltr_err;
 
-		*(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] =
-			fkeys->addrs.v6addrs.src;
-		*(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] =
-			fkeys->addrs.v6addrs.dst;
-		for (i = 0; i < 4; i++) {
-			fs->m_u.tcp_ip6_spec.ip6src[i] = cpu_to_be32(~0);
-			fs->m_u.tcp_ip6_spec.ip6dst[i] = cpu_to_be32(~0);
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
+			*(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] =
+				fkeys->addrs.v6addrs.src;
+			bnxt_fill_ipv6_mask(fs->m_u.tcp_ip6_spec.ip6src);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
+			*(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] =
+				fkeys->addrs.v6addrs.dst;
+			bnxt_fill_ipv6_mask(fs->m_u.tcp_ip6_spec.ip6dst);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
+			fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src;
+			fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(~0);
+		}
+		if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
+			fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst;
+			fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0);
 		}
-		fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src;
-		fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(~0);
-
-		fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst;
-		fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0);
 	}
 
 	fs->ring_cookie = fltr->base.rxq;
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 12/13] bnxt_en: Add support for ntuple filters added from ethtool.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (10 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 11/13] bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter structure Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 17:37   ` Simon Horman
  2023-12-23  4:22 ` [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool Michael Chan
  2024-01-02 14:00 ` [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support patchwork-bot+netdevbpf
  13 siblings, 1 reply; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 9631 bytes --]

Add support for adding user defined ntuple TCP/UDP filters.  These
filters are similar to aRFS filters except that they don't get aged.
Source IP, destination IP, source port, or destination port can be
unspecifed as wildcard.  At least one of these tuples must be specifed.
If a tuple is specified, the full mask must be specified.

All ntuple related ethtool functions are now no longer compiled only
for CONFIG_RFS_ACCEL.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |   6 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.h     |   3 +
 .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 199 +++++++++++++++++-
 3 files changed, 201 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index b949ab124dda..827821e89c40 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5650,8 +5650,8 @@ void bnxt_fill_ipv6_mask(__be32 mask[4])
 		mask[i] = cpu_to_be32(~0);
 }
 
-static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
-					     struct bnxt_ntuple_filter *fltr)
+int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
+				      struct bnxt_ntuple_filter *fltr)
 {
 	struct hwrm_cfa_ntuple_filter_alloc_output *resp;
 	struct hwrm_cfa_ntuple_filter_alloc_input *req;
@@ -14072,6 +14072,8 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
 			bool del = false;
 
 			if (test_bit(BNXT_FLTR_VALID, &fltr->base.state)) {
+				if (fltr->base.flags & BNXT_ACT_NO_AGING)
+					continue;
 				if (rps_may_expire_flow(bp->dev, fltr->base.rxq,
 							fltr->flow_id,
 							fltr->base.sw_id)) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index dc1bc163c82f..b8ef1717cb65 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1342,6 +1342,7 @@ struct bnxt_filter_base {
 #define BNXT_ACT_DROP		1
 #define BNXT_ACT_RING_DST	2
 #define BNXT_ACT_FUNC_DST	4
+#define BNXT_ACT_NO_AGING	8
 	u16			sw_id;
 	u16			rxq;
 	u16			fw_vnic_id;
@@ -2647,6 +2648,8 @@ int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr);
 int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
 				     struct bnxt_ntuple_filter *fltr);
+int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
+				      struct bnxt_ntuple_filter *fltr);
 void bnxt_fill_ipv6_mask(__be32 mask[4]);
 int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 558dd1f9a18e..c3b9be328b87 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1011,7 +1011,6 @@ static int bnxt_set_channels(struct net_device *dev,
 	return rc;
 }
 
-#ifdef CONFIG_RFS_ACCEL
 static u32 bnxt_get_all_fltr_ids_rcu(struct bnxt *bp, struct hlist_head tbl[],
 				     int tbl_size, u32 *ids, u32 start,
 				     u32 id_cnt)
@@ -1152,7 +1151,195 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 
 	return rc;
 }
-#endif
+
+#define IPV4_ALL_MASK		((__force __be32)~0)
+#define L4_PORT_ALL_MASK	((__force __be16)~0)
+
+static bool ipv6_mask_is_full(__be32 mask[4])
+{
+	return (mask[0] & mask[1] & mask[2] & mask[3]) == IPV4_ALL_MASK;
+}
+
+static bool ipv6_mask_is_zero(__be32 mask[4])
+{
+	return !(mask[0] | mask[1] | mask[2] | mask[3]);
+}
+
+static int bnxt_add_ntuple_cls_rule(struct bnxt *bp,
+				    struct ethtool_rx_flow_spec *fs)
+{
+	u8 vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie);
+	u32 ring = ethtool_get_flow_spec_ring(fs->ring_cookie);
+	struct bnxt_ntuple_filter *new_fltr, *fltr;
+	struct bnxt_l2_filter *l2_fltr;
+	u32 flow_type = fs->flow_type;
+	struct flow_keys *fkeys;
+	u32 idx;
+	int rc;
+
+	if (!bp->vnic_info)
+		return -EAGAIN;
+
+	if ((flow_type & (FLOW_MAC_EXT | FLOW_EXT)) || vf)
+		return -EOPNOTSUPP;
+
+	new_fltr = kzalloc(sizeof(*new_fltr), GFP_KERNEL);
+	if (!new_fltr)
+		return -ENOMEM;
+
+	l2_fltr = bp->vnic_info[0].l2_filters[0];
+	atomic_inc(&l2_fltr->refcnt);
+	new_fltr->l2_fltr = l2_fltr;
+	fkeys = &new_fltr->fkeys;
+
+	rc = -EOPNOTSUPP;
+	switch (flow_type) {
+	case TCP_V4_FLOW:
+	case UDP_V4_FLOW: {
+		struct ethtool_tcpip4_spec *ip_spec = &fs->h_u.tcp_ip4_spec;
+		struct ethtool_tcpip4_spec *ip_mask = &fs->m_u.tcp_ip4_spec;
+
+		fkeys->basic.ip_proto = IPPROTO_TCP;
+		if (flow_type == UDP_V4_FLOW)
+			fkeys->basic.ip_proto = IPPROTO_UDP;
+		fkeys->basic.n_proto = htons(ETH_P_IP);
+
+		if (ip_mask->ip4src == IPV4_ALL_MASK) {
+			fkeys->addrs.v4addrs.src = ip_spec->ip4src;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_IP;
+		} else if (ip_mask->ip4src) {
+			goto ntuple_err;
+		}
+		if (ip_mask->ip4dst == IPV4_ALL_MASK) {
+			fkeys->addrs.v4addrs.dst = ip_spec->ip4dst;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_IP;
+		} else if (ip_mask->ip4dst) {
+			goto ntuple_err;
+		}
+
+		if (ip_mask->psrc == L4_PORT_ALL_MASK) {
+			fkeys->ports.src = ip_spec->psrc;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_PORT;
+		} else if (ip_mask->psrc) {
+			goto ntuple_err;
+		}
+		if (ip_mask->pdst == L4_PORT_ALL_MASK) {
+			fkeys->ports.dst = ip_spec->pdst;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_PORT;
+		} else if (ip_mask->pdst) {
+			goto ntuple_err;
+		}
+		break;
+	}
+	case TCP_V6_FLOW:
+	case UDP_V6_FLOW: {
+		struct ethtool_tcpip6_spec *ip_spec = &fs->h_u.tcp_ip6_spec;
+		struct ethtool_tcpip6_spec *ip_mask = &fs->m_u.tcp_ip6_spec;
+
+		fkeys->basic.ip_proto = IPPROTO_TCP;
+		if (flow_type == UDP_V6_FLOW)
+			fkeys->basic.ip_proto = IPPROTO_UDP;
+		fkeys->basic.n_proto = htons(ETH_P_IPV6);
+
+		if (ipv6_mask_is_full(ip_mask->ip6src)) {
+			fkeys->addrs.v6addrs.src =
+				*(struct in6_addr *)&ip_spec->ip6src;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_IP;
+		} else if (!ipv6_mask_is_zero(ip_mask->ip6src)) {
+			goto ntuple_err;
+		}
+		if (ipv6_mask_is_full(ip_mask->ip6dst)) {
+			fkeys->addrs.v6addrs.dst =
+				*(struct in6_addr *)&ip_spec->ip6dst;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_IP;
+		} else if (!ipv6_mask_is_zero(ip_mask->ip6dst)) {
+			goto ntuple_err;
+		}
+
+		if (ip_mask->psrc == L4_PORT_ALL_MASK) {
+			fkeys->ports.src = ip_spec->psrc;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_PORT;
+		} else if (ip_mask->psrc) {
+			goto ntuple_err;
+		}
+		if (ip_mask->pdst == L4_PORT_ALL_MASK) {
+			fkeys->ports.dst = ip_spec->pdst;
+			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_PORT;
+		} else if (ip_mask->pdst) {
+			goto ntuple_err;
+		}
+		break;
+	}
+	default:
+		rc = -EOPNOTSUPP;
+		goto ntuple_err;
+	}
+	if (!new_fltr->ntuple_flags)
+		goto ntuple_err;
+
+	idx = bnxt_get_ntp_filter_idx(bp, fkeys, NULL);
+	rcu_read_lock();
+	fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx);
+	if (fltr) {
+		rcu_read_unlock();
+		rc = -EEXIST;
+		goto ntuple_err;
+	}
+	rcu_read_unlock();
+
+	new_fltr->base.rxq = ring;
+	new_fltr->base.flags = BNXT_ACT_NO_AGING;
+	__set_bit(BNXT_FLTR_VALID, &new_fltr->base.state);
+	rc = bnxt_insert_ntp_filter(bp, new_fltr, idx);
+	if (!rc) {
+		rc = bnxt_hwrm_cfa_ntuple_filter_alloc(bp, new_fltr);
+		if (rc) {
+			bnxt_del_ntp_filter(bp, new_fltr);
+			return rc;
+		}
+		fs->location = new_fltr->base.sw_id;
+		return 0;
+	}
+
+ntuple_err:
+	atomic_dec(&l2_fltr->refcnt);
+	kfree(new_fltr);
+	return rc;
+}
+
+static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd)
+{
+	struct ethtool_rx_flow_spec *fs = &cmd->fs;
+	u32 ring, flow_type;
+	int rc;
+	u8 vf;
+
+	if (!netif_running(bp->dev))
+		return -EAGAIN;
+	if (!(bp->flags & BNXT_FLAG_RFS))
+		return -EPERM;
+	if (fs->location != RX_CLS_LOC_ANY)
+		return -EINVAL;
+
+	ring = ethtool_get_flow_spec_ring(fs->ring_cookie);
+	vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie);
+	if (BNXT_VF(bp) && vf)
+		return -EINVAL;
+	if (BNXT_PF(bp) && vf > bp->pf.active_vfs)
+		return -EINVAL;
+	if (!vf && ring >= bp->rx_nr_rings)
+		return -EINVAL;
+
+	flow_type = fs->flow_type;
+	if (flow_type & (FLOW_MAC_EXT | FLOW_RSS))
+		return -EINVAL;
+	flow_type &= ~FLOW_EXT;
+	if (flow_type == ETHER_FLOW)
+		rc = -EOPNOTSUPP;
+	else
+		rc = bnxt_add_ntuple_cls_rule(bp, fs);
+	return rc;
+}
 
 static u64 get_ethtool_ipv4_rss(struct bnxt *bp)
 {
@@ -1302,14 +1489,13 @@ static int bnxt_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
 	int rc = 0;
 
 	switch (cmd->cmd) {
-#ifdef CONFIG_RFS_ACCEL
 	case ETHTOOL_GRXRINGS:
 		cmd->data = bp->rx_nr_rings;
 		break;
 
 	case ETHTOOL_GRXCLSRLCNT:
 		cmd->rule_cnt = bp->ntp_fltr_count;
-		cmd->data = BNXT_NTP_FLTR_MAX_FLTR;
+		cmd->data = BNXT_NTP_FLTR_MAX_FLTR | RX_CLS_LOC_SPECIAL;
 		break;
 
 	case ETHTOOL_GRXCLSRLALL:
@@ -1319,7 +1505,6 @@ static int bnxt_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
 	case ETHTOOL_GRXCLSRULE:
 		rc = bnxt_grxclsrule(bp, cmd);
 		break;
-#endif
 
 	case ETHTOOL_GRXFH:
 		rc = bnxt_grxfh(bp, cmd);
@@ -1343,6 +1528,10 @@ static int bnxt_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
 		rc = bnxt_srxfh(bp, cmd);
 		break;
 
+	case ETHTOOL_SRXCLSRLINS:
+		rc = bnxt_srxclsrlins(bp, cmd);
+		break;
+
 	default:
 		rc = -EOPNOTSUPP;
 		break;
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool.
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (11 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 12/13] bnxt_en: Add support for ntuple filters added from ethtool Michael Chan
@ 2023-12-23  4:22 ` Michael Chan
  2023-12-25 17:41   ` Simon Horman
  2024-01-04 22:59   ` Jakub Kicinski
  2024-01-02 14:00 ` [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support patchwork-bot+netdevbpf
  13 siblings, 2 replies; 27+ messages in thread
From: Michael Chan @ 2023-12-23  4:22 UTC (permalink / raw)
  To: davem; +Cc: netdev, edumazet, kuba, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 1839 bytes --]

Add logic to delete a user specified ntuple filter from ethtool.

Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
---
 .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 29 +++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index c3b9be328b87..5629ba9f4b2e 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -1341,6 +1341,31 @@ static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd)
 	return rc;
 }
 
+static int bnxt_srxclsrldel(struct bnxt *bp, struct ethtool_rxnfc *cmd)
+{
+	struct ethtool_rx_flow_spec *fs = &cmd->fs;
+	struct bnxt_filter_base *fltr_base;
+
+	rcu_read_lock();
+	fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl,
+					  BNXT_NTP_FLTR_HASH_SIZE,
+					  fs->location);
+	if (fltr_base) {
+		struct bnxt_ntuple_filter *fltr;
+
+		fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
+		rcu_read_unlock();
+		if (!(fltr->base.flags & BNXT_ACT_NO_AGING))
+			return -EINVAL;
+		bnxt_hwrm_cfa_ntuple_filter_free(bp, fltr);
+		bnxt_del_ntp_filter(bp, fltr);
+		return 0;
+	}
+
+	rcu_read_unlock();
+	return -ENOENT;
+}
+
 static u64 get_ethtool_ipv4_rss(struct bnxt *bp)
 {
 	if (bp->rss_hash_cfg & VNIC_RSS_CFG_REQ_HASH_TYPE_IPV4)
@@ -1532,6 +1557,10 @@ static int bnxt_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
 		rc = bnxt_srxclsrlins(bp, cmd);
 		break;
 
+	case ETHTOOL_SRXCLSRLDEL:
+		rc = bnxt_srxclsrldel(bp, cmd);
+		break;
+
 	default:
 		rc = -EOPNOTSUPP;
 		break;
-- 
2.30.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function
  2023-12-23  4:22 ` [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function Michael Chan
@ 2023-12-25 16:56   ` Simon Horman
  2023-12-25 17:45   ` Simon Horman
  1 sibling, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 16:56 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:03PM -0800, Michael Chan wrote:
> Add the helper function to look up the ntuple filter from the
> hash index and use it in bnxt_rx_flow_steer().  The helper function
> will also be used by user defined ntuple filters in the next
> patches.
> 
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>
> ---
>  drivers/net/ethernet/broadcom/bnxt/bnxt.c | 26 +++++++++++++++++------
>  1 file changed, 20 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> index e9b382832a14..7027391316e5 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> @@ -13899,6 +13899,21 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
>  	return false;
>  }
>  
> +static struct bnxt_ntuple_filter *
> +bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
> +				struct bnxt_ntuple_filter *fltr, u32 idx)
> +{
> +	struct bnxt_ntuple_filter *f;
> +	struct hlist_head *head;
> +
> +	head = &bp->ntp_fltr_hash_tbl[idx];
> +	hlist_for_each_entry_rcu(f, head, base.hash) {
> +		if (bnxt_fltr_match(f, fltr))
> +			return f;
> +	}
> +	return NULL;
> +}
> +
>  static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
>  			      u16 rxq_index, u32 flow_id)
>  {
> @@ -13963,12 +13978,11 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
>  	idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
>  	head = &bp->ntp_fltr_hash_tbl[idx];
>  	rcu_read_lock();
> -	hlist_for_each_entry_rcu(fltr, head, base.hash) {
> -		if (bnxt_fltr_match(fltr, new_fltr)) {
> -			rc = fltr->base.sw_id;
> -			rcu_read_unlock();
> -			goto err_free;
> -		}
> +	fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx);
> +	if (fltr) {
> +		rcu_read_unlock();
> +		rc = fltr->base.sw_id;

Hi Michael,

prior to this patch rc was set inside the RCU read-side critical section,
now it is outside. Is that intentional?

> +		goto err_free;
>  	}
>  	rcu_read_unlock();
>  

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct.
  2023-12-23  4:22 ` [PATCH net-next v2 07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct Michael Chan
@ 2023-12-25 17:02   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:02 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:04PM -0800, Michael Chan wrote:
> Change the unused flag to BNXT_FLTR_INSERTED.  To prepare for multiple
> pathways that an ntuple filter can be deleted, we add this flag.  These
> filter structures can be retreived from the RCU hash table but only
> the caller that sees that the BNXT_FLTR_INSERTED flag is set can delete
> the filter structure and clear the flag under spinlock.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

...

> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
> index 3f4e4708f7d8..867cab036e13 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
> @@ -1348,7 +1348,7 @@ struct bnxt_filter_base {
>  	u16			vf_idx;
>  	unsigned long		state;
>  #define BNXT_FLTR_VALID		0
> -#define BNXT_FLTR_UPDATE	1
> +#define BNXT_FLTR_INSERTED	1

Hi Michael,

a minor nit from my side, which I don't think you need to bother with
unless you need to create v3 for some other reason.

I think that either the hunk above should be squashed into patch 1 of this
series. Or, better IMHO, BNXT_FLTR_UPDATE should simply be dropped from
patch 1.

>  
>  	struct rcu_head         rcu;
>  };

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer().
  2023-12-23  4:22 ` [PATCH net-next v2 08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer() Michael Chan
@ 2023-12-25 17:11   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:11 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:05PM -0800, Michael Chan wrote:
> Add a new function bnxt_insert_ntp_filter() to insert the ntuple filter
> into the hash table and other basic setup.  We'll use this function
> to insert a user defined filter from ethtool.
> 
> Also, export bnxt_lookup_ntp_filter_from_idx() and bnxt_get_ntp_filter_idx()
> for similar purposes.  All ntuple related functions are now no longer
> compiled only for CONFIG_RFS_ACCEL
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

...

> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c

...

> @@ -13991,33 +13995,20 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
>  	}
>  	rcu_read_unlock();
>  
> -	spin_lock_bh(&bp->ntp_fltr_lock);
> -	bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap, BNXT_MAX_FLTR, 0);
> -	if (bit_id < 0) {
> -		spin_unlock_bh(&bp->ntp_fltr_lock);
> -		rc = -ENOMEM;
> -		goto err_free;
> -	}
> -
> -	new_fltr->base.sw_id = (u16)bit_id;
>  	new_fltr->flow_id = flow_id;
>  	new_fltr->base.rxq = rxq_index;
> -	new_fltr->base.type = BNXT_FLTR_TYPE_NTUPLE;
> -	new_fltr->base.flags = BNXT_ACT_RING_DST;
> -	hlist_add_head_rcu(&new_fltr->base.hash, head);
> -	set_bit(BNXT_FLTR_INSERTED, &new_fltr->base.state);
> -	bp->ntp_fltr_count++;
> -	spin_unlock_bh(&bp->ntp_fltr_lock);
> -
> -	bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT);
> -
> -	return new_fltr->base.sw_id;
> +	rc = bnxt_insert_ntp_filter(bp, new_fltr, idx);
> +	if (!rc) {
> +		bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT);
> +		return new_fltr->base.sw_id;
> +	}

Hi Michael,

FIWIW, I think the following would be a more idomatic flow.
(Completely untested!)

	rc = bnxt_insert_ntp_filter(bp, new_fltr, idx);
	if (rc)
		goto err_free;

	bnxt_queue_sp_work(bp, BNXT_RX_NTP_FLTR_SP_EVENT);

	return new_fltr->base.sw_id;

>  
>  err_free:
>  	bnxt_del_l2_filter(bp, l2_fltr);
>  	kfree(new_fltr);
>  	return rc;
>  }
> +#endif
>  
>  static void bnxt_cfg_ntp_filters(struct bnxt *bp)
>  {

...

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 12/13] bnxt_en: Add support for ntuple filters added from ethtool.
  2023-12-23  4:22 ` [PATCH net-next v2 12/13] bnxt_en: Add support for ntuple filters added from ethtool Michael Chan
@ 2023-12-25 17:37   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:37 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:09PM -0800, Michael Chan wrote:
> Add support for adding user defined ntuple TCP/UDP filters.  These
> filters are similar to aRFS filters except that they don't get aged.
> Source IP, destination IP, source port, or destination port can be
> unspecifed as wildcard.  At least one of these tuples must be specifed.
> If a tuple is specified, the full mask must be specified.
> 
> All ntuple related ethtool functions are now no longer compiled only
> for CONFIG_RFS_ACCEL.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

...

> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

...

> +static int bnxt_add_ntuple_cls_rule(struct bnxt *bp,
> +				    struct ethtool_rx_flow_spec *fs)
> +{
> +	u8 vf = ethtool_get_flow_spec_ring_vf(fs->ring_cookie);
> +	u32 ring = ethtool_get_flow_spec_ring(fs->ring_cookie);
> +	struct bnxt_ntuple_filter *new_fltr, *fltr;
> +	struct bnxt_l2_filter *l2_fltr;
> +	u32 flow_type = fs->flow_type;
> +	struct flow_keys *fkeys;
> +	u32 idx;
> +	int rc;
> +
> +	if (!bp->vnic_info)
> +		return -EAGAIN;
> +
> +	if ((flow_type & (FLOW_MAC_EXT | FLOW_EXT)) || vf)
> +		return -EOPNOTSUPP;
> +
> +	new_fltr = kzalloc(sizeof(*new_fltr), GFP_KERNEL);
> +	if (!new_fltr)
> +		return -ENOMEM;
> +
> +	l2_fltr = bp->vnic_info[0].l2_filters[0];
> +	atomic_inc(&l2_fltr->refcnt);
> +	new_fltr->l2_fltr = l2_fltr;
> +	fkeys = &new_fltr->fkeys;
> +
> +	rc = -EOPNOTSUPP;
> +	switch (flow_type) {
> +	case TCP_V4_FLOW:
> +	case UDP_V4_FLOW: {
> +		struct ethtool_tcpip4_spec *ip_spec = &fs->h_u.tcp_ip4_spec;
> +		struct ethtool_tcpip4_spec *ip_mask = &fs->m_u.tcp_ip4_spec;
> +
> +		fkeys->basic.ip_proto = IPPROTO_TCP;
> +		if (flow_type == UDP_V4_FLOW)
> +			fkeys->basic.ip_proto = IPPROTO_UDP;
> +		fkeys->basic.n_proto = htons(ETH_P_IP);
> +
> +		if (ip_mask->ip4src == IPV4_ALL_MASK) {
> +			fkeys->addrs.v4addrs.src = ip_spec->ip4src;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_IP;
> +		} else if (ip_mask->ip4src) {
> +			goto ntuple_err;
> +		}
> +		if (ip_mask->ip4dst == IPV4_ALL_MASK) {
> +			fkeys->addrs.v4addrs.dst = ip_spec->ip4dst;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_IP;
> +		} else if (ip_mask->ip4dst) {
> +			goto ntuple_err;
> +		}
> +
> +		if (ip_mask->psrc == L4_PORT_ALL_MASK) {
> +			fkeys->ports.src = ip_spec->psrc;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_PORT;
> +		} else if (ip_mask->psrc) {
> +			goto ntuple_err;
> +		}
> +		if (ip_mask->pdst == L4_PORT_ALL_MASK) {
> +			fkeys->ports.dst = ip_spec->pdst;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_PORT;
> +		} else if (ip_mask->pdst) {
> +			goto ntuple_err;
> +		}
> +		break;
> +	}
> +	case TCP_V6_FLOW:
> +	case UDP_V6_FLOW: {
> +		struct ethtool_tcpip6_spec *ip_spec = &fs->h_u.tcp_ip6_spec;
> +		struct ethtool_tcpip6_spec *ip_mask = &fs->m_u.tcp_ip6_spec;
> +
> +		fkeys->basic.ip_proto = IPPROTO_TCP;
> +		if (flow_type == UDP_V6_FLOW)
> +			fkeys->basic.ip_proto = IPPROTO_UDP;
> +		fkeys->basic.n_proto = htons(ETH_P_IPV6);
> +
> +		if (ipv6_mask_is_full(ip_mask->ip6src)) {
> +			fkeys->addrs.v6addrs.src =
> +				*(struct in6_addr *)&ip_spec->ip6src;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_IP;
> +		} else if (!ipv6_mask_is_zero(ip_mask->ip6src)) {
> +			goto ntuple_err;
> +		}
> +		if (ipv6_mask_is_full(ip_mask->ip6dst)) {
> +			fkeys->addrs.v6addrs.dst =
> +				*(struct in6_addr *)&ip_spec->ip6dst;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_IP;
> +		} else if (!ipv6_mask_is_zero(ip_mask->ip6dst)) {
> +			goto ntuple_err;
> +		}
> +
> +		if (ip_mask->psrc == L4_PORT_ALL_MASK) {
> +			fkeys->ports.src = ip_spec->psrc;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_SRC_PORT;
> +		} else if (ip_mask->psrc) {
> +			goto ntuple_err;
> +		}
> +		if (ip_mask->pdst == L4_PORT_ALL_MASK) {
> +			fkeys->ports.dst = ip_spec->pdst;
> +			new_fltr->ntuple_flags |= BNXT_NTUPLE_MATCH_DST_PORT;
> +		} else if (ip_mask->pdst) {
> +			goto ntuple_err;
> +		}
> +		break;
> +	}
> +	default:
> +		rc = -EOPNOTSUPP;
> +		goto ntuple_err;
> +	}
> +	if (!new_fltr->ntuple_flags)
> +		goto ntuple_err;
> +
> +	idx = bnxt_get_ntp_filter_idx(bp, fkeys, NULL);
> +	rcu_read_lock();
> +	fltr = bnxt_lookup_ntp_filter_from_idx(bp, new_fltr, idx);
> +	if (fltr) {
> +		rcu_read_unlock();
> +		rc = -EEXIST;
> +		goto ntuple_err;
> +	}
> +	rcu_read_unlock();
> +
> +	new_fltr->base.rxq = ring;
> +	new_fltr->base.flags = BNXT_ACT_NO_AGING;
> +	__set_bit(BNXT_FLTR_VALID, &new_fltr->base.state);
> +	rc = bnxt_insert_ntp_filter(bp, new_fltr, idx);
> +	if (!rc) {
> +		rc = bnxt_hwrm_cfa_ntuple_filter_alloc(bp, new_fltr);
> +		if (rc) {
> +			bnxt_del_ntp_filter(bp, new_fltr);
> +			return rc;
> +		}
> +		fs->location = new_fltr->base.sw_id;
> +		return 0;
> +	}
> +

Hi Michael.

FWIIW, I think the following flow would be more idiomatic.
Although the asymmetry of the bnxt_del_ntp_filter() call
in one error path is still a bit awkward.

(Completely untested!)

	rc = bnxt_insert_ntp_filter(bp, new_fltr, idx);
	if (rc)
		goto ntuple_err;

	rc = bnxt_hwrm_cfa_ntuple_filter_alloc(bp, new_fltr);
	if (rc) {
		bnxt_del_ntp_filter(bp, new_fltr);
		return rc;
	}

	fs->location = new_fltr->base.sw_id;
	return 0;

unlock_err:
	rcu_read_unlock();
> +ntuple_err:
> +	atomic_dec(&l2_fltr->refcnt);
> +	kfree(new_fltr);
> +	return rc;
> +}

...

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool.
  2023-12-23  4:22 ` [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool Michael Chan
@ 2023-12-25 17:41   ` Simon Horman
  2024-01-04 22:59   ` Jakub Kicinski
  1 sibling, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:41 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:10PM -0800, Michael Chan wrote:
> Add logic to delete a user specified ntuple filter from ethtool.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>
> ---
>  .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 29 +++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
> index c3b9be328b87..5629ba9f4b2e 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
> @@ -1341,6 +1341,31 @@ static int bnxt_srxclsrlins(struct bnxt *bp, struct ethtool_rxnfc *cmd)
>  	return rc;
>  }
>  
> +static int bnxt_srxclsrldel(struct bnxt *bp, struct ethtool_rxnfc *cmd)
> +{
> +	struct ethtool_rx_flow_spec *fs = &cmd->fs;
> +	struct bnxt_filter_base *fltr_base;
> +
> +	rcu_read_lock();
> +	fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl,
> +					  BNXT_NTP_FLTR_HASH_SIZE,
> +					  fs->location);
> +	if (fltr_base) {
> +		struct bnxt_ntuple_filter *fltr;
> +
> +		fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
> +		rcu_read_unlock();
> +		if (!(fltr->base.flags & BNXT_ACT_NO_AGING))
> +			return -EINVAL;
> +		bnxt_hwrm_cfa_ntuple_filter_free(bp, fltr);
> +		bnxt_del_ntp_filter(bp, fltr);
> +		return 0;
> +	}
> +
> +	rcu_read_unlock();
> +	return -ENOENT;
> +}
> +

Hi Michael,

FWIIW, I think it would be more idoiomatic to handle
the error case inside the if condition.

(Completely untested!)

static int bnxt_srxclsrldel(struct bnxt *bp, struct ethtool_rxnfc *cmd)
{
	struct ethtool_rx_flow_spec *fs = &cmd->fs;
	struct bnxt_filter_base *fltr_base;
	struct bnxt_ntuple_filter *fltr;

	rcu_read_lock();
	fltr_base = bnxt_get_one_fltr_rcu(bp, bp->ntp_fltr_hash_tbl,
					  BNXT_NTP_FLTR_HASH_SIZE,
					  fs->location);
	if (!fltr_base) {
		rcu_read_unlock();
		return -ENOENT;
	}

	fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
	rcu_read_unlock();

	if (!(fltr->base.flags & BNXT_ACT_NO_AGING))
		return -EINVAL;

	bnxt_hwrm_cfa_ntuple_filter_free(bp, fltr);
	bnxt_del_ntp_filter(bp, fltr);

	return 0;
}

...

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure.
  2023-12-23  4:21 ` [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure Michael Chan
@ 2023-12-25 17:43   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:43 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:21:58PM -0800, Michael Chan wrote:
> This is in preparation to support user defined L2 (ether) filters,
> which will have many similarities with ntuple filters.  Refactor
> bnxt_ntuple_filter structure to have a bnxt_filter_base structure
> that can be re-used by the L2 filters.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters().
  2023-12-23  4:22 ` [PATCH net-next v2 10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters() Michael Chan
@ 2023-12-25 17:44   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:44 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:07PM -0800, Michael Chan wrote:
> Refactor the logic into a new function bnxt_del_ntp_filters().  The
> same call will be used when the user deletes an ntuple filter.
> 
> The bnxt_hwrm_cfa_ntuple_filter_free() function to call fw to free
> the ntuple filter is exported so that the ethtool logic can call it.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Reviewed-by: Simon Horman <horms@kernel.org>

...

> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c

...

> @@ -14011,6 +14011,21 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
>  }
>  #endif
>  
> +void bnxt_del_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr)
> +{
> +	spin_lock_bh(&bp->ntp_fltr_lock);
> +	if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) {
> +		spin_unlock_bh(&bp->ntp_fltr_lock);
> +		return;
> +	}
> +	hlist_del_rcu(&fltr->base.hash);
> +	bp->ntp_fltr_count--;
> +	spin_unlock_bh(&bp->ntp_fltr_lock);
> +	bnxt_del_l2_filter(bp, fltr->l2_fltr);
> +	clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
> +	kfree_rcu(fltr, base.rcu);
> +}
> +
>  static void bnxt_cfg_ntp_filters(struct bnxt *bp)
>  {
>  	int i;
> @@ -14042,20 +14057,8 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp)
>  					set_bit(BNXT_FLTR_VALID, &fltr->base.state);
>  			}
>  
> -			if (del) {
> -				spin_lock_bh(&bp->ntp_fltr_lock);
> -				if (!test_and_clear_bit(BNXT_FLTR_INSERTED, &fltr->base.state)) {
> -					spin_unlock_bh(&bp->ntp_fltr_lock);
> -					continue;
> -				}
> -				hlist_del_rcu(&fltr->base.hash);
> -				bp->ntp_fltr_count--;
> -				spin_unlock_bh(&bp->ntp_fltr_lock);
> -				bnxt_del_l2_filter(bp, fltr->l2_fltr);
> -				synchronize_rcu();

Nice to see a use of synchronize_rcu() disappear :)

> -				clear_bit(fltr->base.sw_id, bp->ntp_fltr_bmap);
> -				kfree(fltr);
> -			}
> +			if (del)
> +				bnxt_del_ntp_filter(bp, fltr);
>  		}
>  	}
>  	if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event))

...

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 02/13] bnxt_en: Add bnxt_l2_filter hash table.
  2023-12-23  4:21 ` [PATCH net-next v2 02/13] bnxt_en: Add bnxt_l2_filter hash table Michael Chan
@ 2023-12-25 17:44   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:44 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:21:59PM -0800, Michael Chan wrote:
> The current driver only has an array of 4 additional L2 unicast
> addresses to support the netdev uc address list.  Generalize and
> expand this infrastructure with an L2 address hash table so we can
> support an expanded list of unicast addresses (for bridges,
> macvlans, OVS, etc).  The L2 hash table infrastructure will also
> allow more generalized n-tuple filter support.
> 
> This patch creates the bnxt_l2_filter structure and the hash table.
> This L2 filter structure has the same bnxt_filter_base structure
> as used in the bnxt_ntuple_filter structure.
> 
> All currently supported L2 filters will now have an entry in this
> new table.
> 
> Note that L2 filters may be created for the VF.  VF filters should
> not be freed when the PF goes down.  Add some logic in
> bnxt_free_l2_filters() to allow keeping the VF filters or to free
> everything during rmmod.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure.
  2023-12-23  4:22 ` [PATCH net-next v2 03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure Michael Chan
@ 2023-12-25 17:45   ` Simon Horman
  0 siblings, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:45 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:00PM -0800, Michael Chan wrote:
> With the new bnxt_l2_filter structure, we can now re-structure the
> bnxt_ntuple_filter structure to point to the bnxt_l2_filter structure.
> We eliminate the L2 ether address info from the ntuple filter structure
> as we can get the information from the L2 filter structure.  Note that
> the source L2 MAC address is no longer used.
> 
> Reviewed-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function
  2023-12-23  4:22 ` [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function Michael Chan
  2023-12-25 16:56   ` Simon Horman
@ 2023-12-25 17:45   ` Simon Horman
  1 sibling, 0 replies; 27+ messages in thread
From: Simon Horman @ 2023-12-25 17:45 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

On Fri, Dec 22, 2023 at 08:22:03PM -0800, Michael Chan wrote:
> Add the helper function to look up the ntuple filter from the
> hash index and use it in bnxt_rx_flow_steer().  The helper function
> will also be used by user defined ntuple filters in the next
> patches.
> 
> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
> Signed-off-by: Michael Chan <michael.chan@broadcom.com>

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support
  2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
                   ` (12 preceding siblings ...)
  2023-12-23  4:22 ` [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool Michael Chan
@ 2024-01-02 14:00 ` patchwork-bot+netdevbpf
  13 siblings, 0 replies; 27+ messages in thread
From: patchwork-bot+netdevbpf @ 2024-01-02 14:00 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, kuba, pabeni, pavan.chebbi,
	andrew.gospodarek

Hello:

This series was applied to netdev/net-next.git (main)
by David S. Miller <davem@davemloft.net>:

On Fri, 22 Dec 2023 20:21:57 -0800 you wrote:
> The current driver only supports ntuple filters added by aRFS.  This
> patch series adds basic support for user defined TCP/UDP ntuple filters
> added by the user using ethtool.  Many of the patches are refactoring
> patches to make the existing code more general to support both aRFS
> and user defined filters.  aRFS filters always have the Toeplitz hash
> value from the NIC.  A Toepliz hash function is added in patch 5 to
> get the same hash value for user defined filters.  The hash is used
> to store all ntuple filters in the table and all filters must be
> hashed identically using the same function and key.
> 
> [...]

Here is the summary with links:
  - [net-next,v2,01/13] bnxt_en: Refactor bnxt_ntuple_filter structure.
    https://git.kernel.org/netdev/net-next/c/992d38d2b988
  - [net-next,v2,02/13] bnxt_en: Add bnxt_l2_filter hash table.
    https://git.kernel.org/netdev/net-next/c/1f6e77cb9b32
  - [net-next,v2,03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure.
    https://git.kernel.org/netdev/net-next/c/bfeabf7e4615
  - [net-next,v2,04/13] bnxt_en: Refactor L2 filter alloc/free firmware commands.
    https://git.kernel.org/netdev/net-next/c/96c9bedc755e
  - [net-next,v2,05/13] bnxt_en: Add function to calculate Toeplitz hash
    https://git.kernel.org/netdev/net-next/c/d3c982851c15
  - [net-next,v2,06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function
    https://git.kernel.org/netdev/net-next/c/cb5bdd292dc0
  - [net-next,v2,07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct.
    https://git.kernel.org/netdev/net-next/c/ee908d05dd2a
  - [net-next,v2,08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer().
    https://git.kernel.org/netdev/net-next/c/59cde76f33fa
  - [net-next,v2,09/13] bnxt_en: Refactor the hash table logic for ntuple filters.
    https://git.kernel.org/netdev/net-next/c/80cfde29ce1f
  - [net-next,v2,10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters().
    https://git.kernel.org/netdev/net-next/c/4faeadfd7ed6
  - [net-next,v2,11/13] bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter structure.
    https://git.kernel.org/netdev/net-next/c/300c19180098
  - [net-next,v2,12/13] bnxt_en: Add support for ntuple filters added from ethtool.
    https://git.kernel.org/netdev/net-next/c/c029bc30b9f6
  - [net-next,v2,13/13] bnxt_en: Add support for ntuple filter deletion by ethtool.
    https://git.kernel.org/netdev/net-next/c/8d7ba028aa9a

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool.
  2023-12-23  4:22 ` [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool Michael Chan
  2023-12-25 17:41   ` Simon Horman
@ 2024-01-04 22:59   ` Jakub Kicinski
  2024-01-04 23:37     ` Michael Chan
  1 sibling, 1 reply; 27+ messages in thread
From: Jakub Kicinski @ 2024-01-04 22:59 UTC (permalink / raw)
  To: Michael Chan
  Cc: davem, netdev, edumazet, pabeni, pavan.chebbi, andrew.gospodarek

On Fri, 22 Dec 2023 20:22:10 -0800 Michael Chan wrote:
> +	if (fltr_base) {
> +		struct bnxt_ntuple_filter *fltr;
> +
> +		fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
> +		rcu_read_unlock();
> +		if (!(fltr->base.flags & BNXT_ACT_NO_AGING))
> +			return -EINVAL;

This looks pretty suspicious, you drop the RCU lock before ever using
the object. I'm guessing the filter may be form aRFS and that's why
we need RCU? Shouldn't you hold the RCU lock when checking that
NO_AGING is set? If it's an aRFS flow it may disappear..

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool.
  2024-01-04 22:59   ` Jakub Kicinski
@ 2024-01-04 23:37     ` Michael Chan
  0 siblings, 0 replies; 27+ messages in thread
From: Michael Chan @ 2024-01-04 23:37 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, pavan.chebbi, andrew.gospodarek

[-- Attachment #1: Type: text/plain, Size: 937 bytes --]

On Thu, Jan 4, 2024 at 2:59 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Fri, 22 Dec 2023 20:22:10 -0800 Michael Chan wrote:
> > +     if (fltr_base) {
> > +             struct bnxt_ntuple_filter *fltr;
> > +
> > +             fltr = container_of(fltr_base, struct bnxt_ntuple_filter, base);
> > +             rcu_read_unlock();
> > +             if (!(fltr->base.flags & BNXT_ACT_NO_AGING))
> > +                     return -EINVAL;
>
> This looks pretty suspicious, you drop the RCU lock before ever using
> the object. I'm guessing the filter may be form aRFS and that's why
> we need RCU? Shouldn't you hold the RCU lock when checking that
> NO_AGING is set? If it's an aRFS flow it may disappear..

I think you are right.  The RCU lock should be released after checking
the flags.

There is also another unused variable detected by the kernel test
robot.  I will post the fixes in a day or two.  Thanks.

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4209 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2024-01-04 23:37 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-23  4:21 [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support Michael Chan
2023-12-23  4:21 ` [PATCH net-next v2 01/13] bnxt_en: Refactor bnxt_ntuple_filter structure Michael Chan
2023-12-25 17:43   ` Simon Horman
2023-12-23  4:21 ` [PATCH net-next v2 02/13] bnxt_en: Add bnxt_l2_filter hash table Michael Chan
2023-12-25 17:44   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 03/13] bnxt_en: Re-structure the bnxt_ntuple_filter structure Michael Chan
2023-12-25 17:45   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 04/13] bnxt_en: Refactor L2 filter alloc/free firmware commands Michael Chan
2023-12-23  4:22 ` [PATCH net-next v2 05/13] bnxt_en: Add function to calculate Toeplitz hash Michael Chan
2023-12-23  4:22 ` [PATCH net-next v2 06/13] bnxt_en: Add bnxt_lookup_ntp_filter_from_idx() function Michael Chan
2023-12-25 16:56   ` Simon Horman
2023-12-25 17:45   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 07/13] bnxt_en: Add new BNXT_FLTR_INSERTED flag to bnxt_filter_base struct Michael Chan
2023-12-25 17:02   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 08/13] bnxt_en: Refactor filter insertion logic in bnxt_rx_flow_steer() Michael Chan
2023-12-25 17:11   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 09/13] bnxt_en: Refactor the hash table logic for ntuple filters Michael Chan
2023-12-23  4:22 ` [PATCH net-next v2 10/13] bnxt_en: Refactor ntuple filter removal logic in bnxt_cfg_ntp_filters() Michael Chan
2023-12-25 17:44   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 11/13] bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter structure Michael Chan
2023-12-23  4:22 ` [PATCH net-next v2 12/13] bnxt_en: Add support for ntuple filters added from ethtool Michael Chan
2023-12-25 17:37   ` Simon Horman
2023-12-23  4:22 ` [PATCH net-next v2 13/13] bnxt_en: Add support for ntuple filter deletion by ethtool Michael Chan
2023-12-25 17:41   ` Simon Horman
2024-01-04 22:59   ` Jakub Kicinski
2024-01-04 23:37     ` Michael Chan
2024-01-02 14:00 ` [PATCH net-next v2 00/13] bnxt_en: Add basic ntuple filter support patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).