DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: zaiyuwang@trustnetic.com, Jiawen Wu <jiawenwu@trustnetic.com>,
	stable@dpdk.org
Subject: [PATCH 18/19] net/txgbe: switch to use FDIR on VF
Date: Mon, 27 Oct 2025 11:15:41 +0800	[thread overview]
Message-ID: <20251027031542.10512-19-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20251027031542.10512-1-jiawenwu@trustnetic.com>

Switch to use FDIR when ntuple filters are full on VF, just like PF. And
VF should request PF driver to configure the FDIR rule on hardware, so
new PF-VF mailbox API version 2.3 is added to implement it.

Fixes: 065d64788cdc ("net/txgbe: support flow filter for VF")
Cc: stable@dpdk.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/txgbe/base/txgbe_mbx.h  |  21 ++++
 drivers/net/txgbe/base/txgbe_vf.c   |  52 +++++++++-
 drivers/net/txgbe/base/txgbe_vf.h   |   1 +
 drivers/net/txgbe/txgbe_ethdev.c    |  22 ++--
 drivers/net/txgbe/txgbe_ethdev.h    |   6 +-
 drivers/net/txgbe/txgbe_ethdev_vf.c |  19 +++-
 drivers/net/txgbe/txgbe_fdir.c      | 150 +++++++++++++++++++++++++++-
 drivers/net/txgbe/txgbe_flow.c      |  74 +++++++++++---
 8 files changed, 318 insertions(+), 27 deletions(-)

diff --git a/drivers/net/txgbe/base/txgbe_mbx.h b/drivers/net/txgbe/base/txgbe_mbx.h
index 31e2d51658..b5b586bd30 100644
--- a/drivers/net/txgbe/base/txgbe_mbx.h
+++ b/drivers/net/txgbe/base/txgbe_mbx.h
@@ -20,6 +20,8 @@
 #define TXGBE_VT_MSGTYPE_NACK	0x40000000
 /* Indicates that VF is still clear to send requests */
 #define TXGBE_VT_MSGTYPE_CTS	0x20000000
+/* Messages below or'd with this are the specific case */
+#define TXGBE_VT_MSGTYPE_SPEC	0x10000000
 
 #define TXGBE_VT_MSGINFO_SHIFT	16
 /* bits 23:16 are used for extra info for certain messages */
@@ -39,6 +41,7 @@ enum txgbe_pfvf_api_rev {
 	txgbe_mbox_api_13,	/* API version 1.3, linux/freebsd VF driver */
 	txgbe_mbox_api_20,	/* API version 2.0, solaris Phase1 VF driver */
 	txgbe_mbox_api_21,	/* API version 2.1 */
+	txgbe_mbox_api_23,	/* API version 2.3 */
 	/* This value should always be last */
 	txgbe_mbox_api_unknown,	/* indicates that API version is not known */
 };
@@ -65,6 +68,9 @@ enum txgbe_pfvf_api_rev {
 /* mailbox API, version 2.1 VF requests */
 #define TXGBE_VF_SET_5TUPLE	0x20 /* VF request PF for 5-tuple filter */
 
+/* mailbox API, version 2.3 VF requests */
+#define TXGBE_VF_SET_FDIR	0x22 /* VF request PF for FDIR filter */
+
 #define TXGBE_VF_BACKUP		0x8001 /* VF requests backup */
 
 /* mode choices for TXGBE_VF_UPDATE_XCAST_MODE */
@@ -88,6 +94,21 @@ enum txgbevf_5tuple_msg {
 
 #define TXGBEVF_5T_ADD_SHIFT	31
 
+enum txgbevf_fdir_msg {
+	TXGBEVF_FDIR_REQ = 0,
+	TXGBEVF_FDIR_CMD,
+	TXGBEVF_FDIR_IP4SA,
+	TXGBEVF_FDIR_IP4DA,
+	TXGBEVF_FDIR_PORT,
+	TXGBEVF_FDIR_FLEX,
+	TXGBEVF_FDIR_IP4DM,
+	TXGBEVF_FDIR_IP4SM,
+	TXGBEVF_FDIR_PORTM,
+	TXGBEVF_FDIR_MAX /* must be last */
+};
+
+#define TXGBEVF_FDIR_ADD_SHIFT	31
+
 /* GET_QUEUES return data indices within the mailbox */
 #define TXGBE_VF_TX_QUEUES	1	/* number of Tx queues supported */
 #define TXGBE_VF_RX_QUEUES	2	/* number of Rx queues supported */
diff --git a/drivers/net/txgbe/base/txgbe_vf.c b/drivers/net/txgbe/base/txgbe_vf.c
index 5e41ba1a3e..7d418b9b37 100644
--- a/drivers/net/txgbe/base/txgbe_vf.c
+++ b/drivers/net/txgbe/base/txgbe_vf.c
@@ -358,6 +358,7 @@ s32 txgbevf_update_xcast_mode(struct txgbe_hw *hw, int xcast_mode)
 		/* Fall through */
 	case txgbe_mbox_api_13:
 	case txgbe_mbox_api_21:
+	case txgbe_mbox_api_23:
 		break;
 	default:
 		return TXGBE_ERR_FEATURE_NOT_SUPPORTED;
@@ -612,6 +613,7 @@ int txgbevf_get_queues(struct txgbe_hw *hw, unsigned int *num_tcs,
 	case txgbe_mbox_api_12:
 	case txgbe_mbox_api_13:
 	case txgbe_mbox_api_21:
+	case txgbe_mbox_api_23:
 		break;
 	default:
 		return 0;
@@ -662,6 +664,8 @@ int txgbevf_get_queues(struct txgbe_hw *hw, unsigned int *num_tcs,
 int
 txgbevf_add_5tuple_filter(struct txgbe_hw *hw, u32 *msg, u16 index)
 {
+	int err;
+
 	if (hw->api_version < txgbe_mbox_api_21)
 		return TXGBE_ERR_FEATURE_NOT_SUPPORTED;
 
@@ -669,13 +673,22 @@ txgbevf_add_5tuple_filter(struct txgbe_hw *hw, u32 *msg, u16 index)
 	msg[TXGBEVF_5T_CMD] = index;
 	msg[TXGBEVF_5T_CMD] |= 1 << TXGBEVF_5T_ADD_SHIFT;
 
-	return txgbevf_write_msg_read_ack(hw, msg, msg, TXGBEVF_5T_MAX);
+	err = txgbevf_write_msg_read_ack(hw, msg, msg, TXGBEVF_5T_MAX);
+	if (err)
+		return err;
+
+	msg[0] &= ~TXGBE_VT_MSGTYPE_CTS;
+	if (msg[0] != (TXGBE_VF_SET_5TUPLE | TXGBE_VT_MSGTYPE_ACK))
+		return TXGBE_ERR_NOSUPP;
+
+	return 0;
 }
 
 int
 txgbevf_del_5tuple_filter(struct txgbe_hw *hw, u16 index)
 {
 	u32 msg[2] = {0, 0};
+	int err;
 
 	if (hw->api_version < txgbe_mbox_api_21)
 		return TXGBE_ERR_FEATURE_NOT_SUPPORTED;
@@ -683,5 +696,40 @@ txgbevf_del_5tuple_filter(struct txgbe_hw *hw, u16 index)
 	msg[TXGBEVF_5T_REQ] = TXGBE_VF_SET_5TUPLE;
 	msg[TXGBEVF_5T_CMD] = index;
 
-	return txgbevf_write_msg_read_ack(hw, msg, msg, 2);
+	err = txgbevf_write_msg_read_ack(hw, msg, msg, 2);
+	if (err)
+		return err;
+
+	msg[0] &= ~TXGBE_VT_MSGTYPE_CTS;
+	if (msg[0] != (TXGBE_VF_SET_5TUPLE | TXGBE_VT_MSGTYPE_ACK))
+		return TXGBE_ERR_NOSUPP;
+
+	return 0;
+}
+
+int
+txgbevf_set_fdir(struct txgbe_hw *hw, u32 *msg, bool add)
+{
+	u16 msg_len = TXGBEVF_FDIR_MAX;
+	int err = 0;
+
+	if (hw->api_version < txgbe_mbox_api_23)
+		return TXGBE_ERR_FEATURE_NOT_SUPPORTED;
+
+	msg[TXGBEVF_FDIR_REQ] = TXGBE_VF_SET_FDIR;
+
+	if (add)
+		msg[TXGBEVF_FDIR_CMD] |= 1 << TXGBEVF_FDIR_ADD_SHIFT;
+	else
+		msg_len = 2;
+
+	err = txgbevf_write_msg_read_ack(hw, msg, msg, msg_len);
+	if (err)
+		return err;
+
+	msg[0] &= ~TXGBE_VT_MSGTYPE_CTS;
+	if (msg[0] == (TXGBE_VF_SET_FDIR | TXGBE_VT_MSGTYPE_NACK))
+		return TXGBE_ERR_FEATURE_NOT_SUPPORTED;
+
+	return 0;
 }
diff --git a/drivers/net/txgbe/base/txgbe_vf.h b/drivers/net/txgbe/base/txgbe_vf.h
index 1fac1c7e32..c67e2f59b3 100644
--- a/drivers/net/txgbe/base/txgbe_vf.h
+++ b/drivers/net/txgbe/base/txgbe_vf.h
@@ -60,5 +60,6 @@ int txgbevf_get_queues(struct txgbe_hw *hw, unsigned int *num_tcs,
 		       unsigned int *default_tc);
 int txgbevf_add_5tuple_filter(struct txgbe_hw *hw, u32 *msg, u16 index);
 int txgbevf_del_5tuple_filter(struct txgbe_hw *hw, u16 index);
+int txgbevf_set_fdir(struct txgbe_hw *hw, u32 *msg, bool add);
 
 #endif /* __TXGBE_VF_H__ */
diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 21f0711762..5d360f8305 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -90,8 +90,6 @@ static const struct reg_info *txgbe_regs_others[] = {
 				txgbe_regs_diagnostic,
 				NULL};
 
-static int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
-static int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
 static int txgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev);
 static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev);
 static int  txgbe_dev_set_link_up(struct rte_eth_dev *dev);
@@ -898,7 +896,7 @@ int txgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
-static int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev)
+int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
 	struct txgbe_fdir_filter *fdir_filter;
@@ -934,7 +932,7 @@ static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev)
 	return 0;
 }
 
-static int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
+int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
 {
 	struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(eth_dev);
 	struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
@@ -4478,6 +4476,7 @@ txgbe_add_5tuple_filter(struct rte_eth_dev *dev,
 {
 	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
 	int i, idx, shift;
+	int err;
 
 	/*
 	 * look for an unused 5tuple filter index,
@@ -4501,12 +4500,19 @@ txgbe_add_5tuple_filter(struct rte_eth_dev *dev,
 		return -ENOSYS;
 	}
 
-	if (txgbe_is_pf(TXGBE_DEV_HW(dev)))
+	if (txgbe_is_pf(TXGBE_DEV_HW(dev))) {
 		txgbe_inject_5tuple_filter(dev, filter);
-	else
-		txgbevf_inject_5tuple_filter(dev, filter);
+		return 0;
+	}
 
-	return 0;
+	err = txgbevf_inject_5tuple_filter(dev, filter);
+	if (err) {
+		filter_info->fivetuple_mask[i / (sizeof(uint32_t) * NBBY)] &=
+				~(1 << (i % (sizeof(uint32_t) * NBBY)));
+		TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	}
+
+	return err;
 }
 
 /*
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index 1e7cc5ea80..189fbac541 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -555,6 +555,8 @@ txgbe_dev_l2_tunnel_filter_del(struct rte_eth_dev *dev,
 			       struct txgbe_l2_tunnel_conf *l2_tunnel);
 void txgbe_filterlist_init(void);
 void txgbe_filterlist_flush(void);
+int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
+int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
 
 void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,
 			       uint8_t queue, uint8_t msix_vector);
@@ -570,7 +572,9 @@ int txgbe_fdir_set_flexbytes_offset(struct rte_eth_dev *dev,
 int txgbe_fdir_filter_program(struct rte_eth_dev *dev,
 			      struct txgbe_fdir_rule *rule,
 			      bool del, bool update);
-
+int txgbevf_fdir_filter_program(struct rte_eth_dev *dev,
+				struct txgbe_fdir_rule *rule,
+				bool del);
 void txgbe_configure_pb(struct rte_eth_dev *dev);
 void txgbe_configure_port(struct rte_eth_dev *dev);
 void txgbe_configure_dcb(struct rte_eth_dev *dev);
diff --git a/drivers/net/txgbe/txgbe_ethdev_vf.c b/drivers/net/txgbe/txgbe_ethdev_vf.c
index ae04054d02..0f914fa3f5 100644
--- a/drivers/net/txgbe/txgbe_ethdev_vf.c
+++ b/drivers/net/txgbe/txgbe_ethdev_vf.c
@@ -129,6 +129,7 @@ txgbevf_negotiate_api(struct txgbe_hw *hw)
 
 	/* start with highest supported, proceed down */
 	static const int sup_ver[] = {
+		txgbe_mbox_api_23,
 		txgbe_mbox_api_21,
 		txgbe_mbox_api_13,
 		txgbe_mbox_api_12,
@@ -162,6 +163,7 @@ int
 txgbevf_inject_5tuple_filter(struct rte_eth_dev *dev,
 			     struct txgbe_5tuple_filter *filter)
 {
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
 	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
 	uint32_t mask = TXGBE_5TFCTL0_MASK;
 	uint16_t index = filter->index;
@@ -194,9 +196,16 @@ txgbevf_inject_5tuple_filter(struct rte_eth_dev *dev,
 	msg[TXGBEVF_5T_SA] = be_to_le32(filter->filter_info.src_ip);
 
 	err = txgbevf_add_5tuple_filter(hw, msg, index);
-	if (err)
-		PMD_DRV_LOG(ERR, "VF request PF to add 5tuple filters failed.");
+	if (!err)
+		return 0;
+
+	if (msg[TXGBEVF_5T_REQ] & TXGBE_VT_MSGTYPE_SPEC) {
+		PMD_DRV_LOG(INFO, "5tuple filters are full, switch to FDIR");
+		filter_info->ntuple_is_full = true;
+		return -ENOSYS;
+	}
 
+	PMD_DRV_LOG(ERR, "VF request PF to add 5tuple filters failed.");
 	return err;
 }
 
@@ -367,6 +376,9 @@ eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)
 	memset(filter_info, 0,
 	       sizeof(struct txgbe_filter_info));
 
+	/* initialize flow director filter list & hash */
+	txgbe_fdir_filter_init(eth_dev);
+
 	/* initialize 5tuple filter list */
 	TAILQ_INIT(&filter_info->fivetuple_list);
 
@@ -860,6 +872,9 @@ txgbevf_dev_close(struct rte_eth_dev *dev)
 	rte_intr_callback_unregister(intr_handle,
 				     txgbevf_dev_interrupt_handler, dev);
 
+	/* remove all the fdir filters & hash */
+	txgbe_fdir_filter_uninit(dev);
+
 	/* Remove all ntuple filters of the device */
 	txgbe_ntuple_filter_uninit(dev);
 
diff --git a/drivers/net/txgbe/txgbe_fdir.c b/drivers/net/txgbe/txgbe_fdir.c
index 6b83a7379d..67f586ffc7 100644
--- a/drivers/net/txgbe/txgbe_fdir.c
+++ b/drivers/net/txgbe/txgbe_fdir.c
@@ -775,7 +775,7 @@ txgbe_insert_fdir_filter(struct txgbe_hw_fdir_info *fdir_info,
 
 	TAILQ_INSERT_TAIL(&fdir_info->fdir_list, fdir_filter, entries);
 
-	return 0;
+	return ret;
 }
 
 static inline int
@@ -795,7 +795,7 @@ txgbe_remove_fdir_filter(struct txgbe_hw_fdir_info *fdir_info,
 	TAILQ_REMOVE(&fdir_info->fdir_list, fdir_filter, entries);
 	rte_free(fdir_filter);
 
-	return 0;
+	return ret;
 }
 
 static void
@@ -929,6 +929,147 @@ txgbe_fdir_filter_program(struct rte_eth_dev *dev,
 	return err;
 }
 
+static void
+txgbevf_flush_fdir_filter(struct rte_eth_dev *dev)
+{
+	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+	uint32_t msg[2] = {0, 0};
+
+	/* flush bit */
+	msg[TXGBEVF_FDIR_CMD] = 1 << 16;
+
+	txgbevf_set_fdir(hw, msg, FALSE);
+}
+
+static int
+txgbevf_del_fdir_filter(struct rte_eth_dev *dev,
+			struct txgbe_fdir_rule *rule,
+			int id)
+{
+	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+	struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
+	uint32_t msg[2] = {0, 0};
+	int ret = 0;
+
+	/* node id [15:0] */
+	msg[TXGBEVF_FDIR_CMD] = id;
+
+	ret = txgbevf_set_fdir(hw, msg, FALSE);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "VF request PF to delete FDIR filters failed.");
+		return ret;
+	}
+
+	ret = txgbe_remove_fdir_filter(info, &rule->input);
+	if (ret < 0)
+		PMD_DRV_LOG(ERR, "Fail to delete FDIR filter!");
+
+	return 0;
+}
+
+static int
+txgbevf_add_fdir_filter(struct rte_eth_dev *dev,
+			struct txgbe_fdir_rule *rule,
+			int id)
+{
+	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+	uint32_t msg[TXGBEVF_FDIR_MAX];
+	int ret = 0;
+
+	memset(msg, 0, sizeof(msg));
+
+	/* node id [15:0] */
+	msg[TXGBEVF_FDIR_CMD] = id;
+	/* ring_idx [23:16] */
+	msg[TXGBEVF_FDIR_CMD] |= rule->queue << 16;
+	/* flow_type [30:24] */
+	msg[TXGBEVF_FDIR_CMD] |= rule->input.flow_type << 24;
+
+	msg[TXGBEVF_FDIR_IP4SA] = rule->input.src_ip[0];
+	msg[TXGBEVF_FDIR_IP4DA] = rule->input.dst_ip[0];
+	msg[TXGBEVF_FDIR_PORT] = (rule->input.dst_port << 16) |
+				rule->input.src_port;
+	if (rule->mask.flex_bytes_mask) {
+		/* base [1:0] */
+		msg[TXGBEVF_FDIR_FLEX] = txgbe_fdir_get_flex_base(rule);
+		/* offset [7:3] */
+		msg[TXGBEVF_FDIR_FLEX] |=
+			TXGBE_FDIRFLEXCFG_OFST(rule->flex_bytes_offset / 2);
+		/* flex bytes [31:16]*/
+		msg[TXGBEVF_FDIR_FLEX] |= rule->input.flex_bytes << 16;
+	}
+	msg[TXGBEVF_FDIR_IP4SM] = rule->mask.src_ipv4_mask;
+	msg[TXGBEVF_FDIR_IP4DM] = rule->mask.dst_ipv4_mask;
+	msg[TXGBEVF_FDIR_PORTM] = (rule->mask.dst_port_mask << 16) |
+				rule->mask.src_port_mask;
+
+	ret = txgbevf_set_fdir(hw, msg, TRUE);
+	if (ret)
+		PMD_DRV_LOG(ERR, "VF request PF to add FDIR filters failed.");
+
+	return ret;
+}
+
+int
+txgbevf_fdir_filter_program(struct rte_eth_dev *dev,
+			    struct txgbe_fdir_rule *rule,
+			    bool del)
+{
+	struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
+	struct txgbe_atr_input *input = &rule->input;
+	struct txgbe_fdir_filter *node;
+	uint32_t fdirhash;
+	int ret;
+
+	if (rule->mode != RTE_FDIR_MODE_PERFECT ||
+	    rule->fdirflags == TXGBE_FDIRPICMD_DROP)
+		return -ENOTSUP;
+
+	if (input->flow_type & TXGBE_ATR_FLOW_TYPE_IPV6)
+		return -ENOTSUP;
+
+	fdirhash = atr_compute_perfect_hash(input,
+			TXGBE_DEV_FDIR_CONF(dev)->pballoc);
+
+	ret = rte_hash_lookup(info->hash_handle, (const void *)input);
+	if (ret < 0) {
+		if (del) {
+			PMD_DRV_LOG(ERR, "No such fdir filter to delete!");
+			return ret;
+		}
+	} else {
+		if (!del) {
+			PMD_DRV_LOG(ERR, "Conflict with existing fdir filter!");
+			return -EINVAL;
+		}
+	}
+
+	if (del)
+		return txgbevf_del_fdir_filter(dev, rule, ret);
+
+	node = rte_zmalloc("txgbe_fdir",
+			   sizeof(struct txgbe_fdir_filter), 0);
+	if (!node)
+		return -ENOMEM;
+	rte_memcpy(&node->input, input,
+		   sizeof(struct txgbe_atr_input));
+	node->fdirflags = rule->fdirflags;
+	node->fdirhash = fdirhash;
+	node->queue = rule->queue;
+
+	ret = txgbe_insert_fdir_filter(info, node);
+	if (ret < 0) {
+		rte_free(node);
+		return ret;
+	}
+
+	ret = txgbevf_add_fdir_filter(dev, rule, ret);
+	if (ret)
+		txgbe_remove_fdir_filter(info, input);
+
+	return ret;
+}
+
 static int
 txgbe_fdir_flush(struct rte_eth_dev *dev)
 {
@@ -936,6 +1077,11 @@ txgbe_fdir_flush(struct rte_eth_dev *dev)
 	struct txgbe_hw_fdir_info *info = TXGBE_DEV_FDIR(dev);
 	int ret;
 
+	if (!txgbe_is_pf(hw)) {
+		txgbevf_flush_fdir_filter(dev);
+		return 0;
+	}
+
 	ret = txgbe_reinit_fdir_tables(hw);
 	if (ret < 0) {
 		PMD_INIT_LOG(ERR, "Failed to re-initialize FD table.");
diff --git a/drivers/net/txgbe/txgbe_flow.c b/drivers/net/txgbe/txgbe_flow.c
index cd05ceffed..5647165d52 100644
--- a/drivers/net/txgbe/txgbe_flow.c
+++ b/drivers/net/txgbe/txgbe_flow.c
@@ -828,6 +828,13 @@ txgbe_parse_ethertype_filter(struct rte_eth_dev *dev,
 {
 	int ret;
 
+	if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM,
+				   NULL, "Flow type not suppotted yet on VF");
+		return -rte_errno;
+	}
+
 	ret = cons_parse_ethertype_filter(attr, pattern,
 					actions, filter, error);
 
@@ -1114,6 +1121,13 @@ txgbe_parse_syn_filter(struct rte_eth_dev *dev,
 {
 	int ret;
 
+	if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM,
+				   NULL, "Flow type not suppotted yet on VF");
+		return -rte_errno;
+	}
+
 	ret = cons_parse_syn_filter(attr, pattern,
 					actions, filter, error);
 
@@ -1317,6 +1331,13 @@ txgbe_parse_l2_tn_filter(struct rte_eth_dev *dev,
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	uint16_t vf_num;
 
+	if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM,
+				   NULL, "Flow type not suppotted yet on VF");
+		return -rte_errno;
+	}
+
 	ret = cons_parse_l2_tn_filter(dev, attr, pattern,
 				actions, l2_tn_filter, error);
 
@@ -2960,6 +2981,9 @@ txgbe_parse_fdir_filter(struct rte_eth_dev *dev,
 		return ret;
 
 step_next:
+	if (!txgbe_is_pf(TXGBE_DEV_HW(dev)))
+		return ret;
+
 	if (fdir_conf->mode == RTE_FDIR_MODE_NONE) {
 		fdir_conf->mode = rule->mode;
 		ret = txgbe_fdir_configure(dev);
@@ -2988,6 +3012,13 @@ txgbe_parse_rss_filter(struct rte_eth_dev *dev,
 	const struct rte_flow_action_rss *rss;
 	uint16_t n;
 
+	if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
+		rte_flow_error_set(error, EINVAL,
+				   RTE_FLOW_ERROR_TYPE_ITEM,
+				   NULL, "Flow type not suppotted yet on VF");
+		return -rte_errno;
+	}
+
 	/**
 	 * rss only supports forwarding,
 	 * check if the first not void action is RSS.
@@ -3256,11 +3287,6 @@ txgbe_flow_create(struct rte_eth_dev *dev,
 		goto out;
 	}
 
-	if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
-		PMD_DRV_LOG(ERR, "Flow type not suppotted yet on VF.");
-		goto out;
-	}
-
 next:
 	memset(&ethertype_filter, 0, sizeof(struct rte_eth_ethertype_filter));
 	ret = txgbe_parse_ethertype_filter(dev, attr, pattern,
@@ -3317,6 +3343,27 @@ txgbe_flow_create(struct rte_eth_dev *dev,
 	ret = txgbe_parse_fdir_filter(dev, attr, pattern,
 				actions, &fdir_rule, error);
 	if (!ret) {
+		if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
+			ret = txgbevf_fdir_filter_program(dev, &fdir_rule, FALSE);
+			if (ret < 0)
+				goto out;
+
+			fdir_rule_ptr = rte_zmalloc("txgbe_fdir_filter",
+					    sizeof(struct txgbe_fdir_rule_ele), 0);
+			if (!fdir_rule_ptr) {
+				PMD_DRV_LOG(ERR, "failed to allocate memory");
+				goto out;
+			}
+			rte_memcpy(&fdir_rule_ptr->filter_info,
+				   &fdir_rule,
+				   sizeof(struct txgbe_fdir_rule));
+			TAILQ_INSERT_TAIL(&filter_fdir_list,
+					  fdir_rule_ptr, entries);
+			flow->rule = fdir_rule_ptr;
+			flow->filter_type = RTE_ETH_FILTER_FDIR;
+			return flow;
+		}
+
 		/* A mask cannot be deleted. */
 		if (fdir_rule.b_mask) {
 			if (!fdir_info->mask_added) {
@@ -3583,7 +3630,10 @@ txgbe_flow_destroy(struct rte_eth_dev *dev,
 		rte_memcpy(&fdir_rule,
 			&fdir_rule_ptr->filter_info,
 			sizeof(struct txgbe_fdir_rule));
-		ret = txgbe_fdir_filter_program(dev, &fdir_rule, TRUE, FALSE);
+		if (txgbe_is_pf(TXGBE_DEV_HW(dev)))
+			ret = txgbe_fdir_filter_program(dev, &fdir_rule, TRUE, FALSE);
+		else
+			ret = txgbevf_fdir_filter_program(dev, &fdir_rule, TRUE);
 		if (!ret) {
 			TAILQ_REMOVE(&filter_fdir_list,
 				fdir_rule_ptr, entries);
@@ -3656,12 +3706,6 @@ txgbe_flow_flush(struct rte_eth_dev *dev,
 
 	txgbe_clear_all_ntuple_filter(dev);
 
-	if (!txgbe_is_pf(TXGBE_DEV_HW(dev)))
-		goto out;
-
-	txgbe_clear_all_ethertype_filter(dev);
-	txgbe_clear_syn_filter(dev);
-
 	ret = txgbe_clear_all_fdir_filter(dev);
 	if (ret < 0) {
 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
@@ -3669,6 +3713,12 @@ txgbe_flow_flush(struct rte_eth_dev *dev,
 		return ret;
 	}
 
+	if (!txgbe_is_pf(TXGBE_DEV_HW(dev)))
+		goto out;
+
+	txgbe_clear_all_ethertype_filter(dev);
+	txgbe_clear_syn_filter(dev);
+
 	ret = txgbe_clear_all_l2_tn_filter(dev);
 	if (ret < 0) {
 		rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_HANDLE,
-- 
2.48.1


  parent reply	other threads:[~2025-10-27  3:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-27  3:15 [PATCH 00/19] Wangxun Fixes Jiawen Wu
2025-10-27  3:15 ` [PATCH 01/19] net/txgbe: fix hardware statistic rx_l3_l4_xsum_error Jiawen Wu
2025-10-27  3:15 ` [PATCH 02/19] net/ngbe: " Jiawen Wu
2025-10-27  3:15 ` [PATCH 03/19] net/txgbe: reduce memory size of ring descriptors Jiawen Wu
2025-10-27  3:15 ` [PATCH 04/19] net/ngbe: " Jiawen Wu
2025-10-27  3:15 ` [PATCH 05/19] net/txgbe: fix VF Rx buffer size in config register Jiawen Wu
2025-10-27  3:15 ` [PATCH 06/19] net/ngbe: " Jiawen Wu
2025-10-27  3:15 ` [PATCH 07/19] net/txgbe: remove duplicate txq assignment Jiawen Wu
2025-10-27  3:15 ` [PATCH 08/19] net/txgbe: add device arguments for FDIR Jiawen Wu
2025-10-27  3:15 ` [PATCH 09/19] net/txgbe: fix the maxinum number of FDIR filter Jiawen Wu
2025-10-27  3:15 ` [PATCH 10/19] net/txgbe: fix FDIR mode is not be cleared Jiawen Wu
2025-10-27  3:15 ` [PATCH 11/19] net/txgbe: fix FDIR drop action for L4 match packets Jiawen Wu
2025-10-27  3:15 ` [PATCH 12/19] net/txgbe: fix to create FDIR filter for tunnel SCTP packet Jiawen Wu
2025-10-27  3:15 ` [PATCH 13/19] net/txgbe: filter FDIR match flex bytes for tunnel packets Jiawen Wu
2025-10-27  3:15 ` [PATCH 14/19] net/txgbe: fix FDIR rule raw relative for L3 packets Jiawen Wu
2025-10-27  3:15 ` [PATCH 15/19] net/txgbe: fix FDIR input mask Jiawen Wu
2025-10-27  3:15 ` [PATCH 16/19] net/txgbe: switch to use FDIR when ntuple filter is full Jiawen Wu
2025-10-27  3:15 ` [PATCH 17/19] net/txgbe: fix VF-PF message for ntuple flow filter Jiawen Wu
2025-10-27  3:15 ` Jiawen Wu [this message]
2025-10-27  3:15 ` [PATCH 19/19] net/txgbe: remove unsupported flow action mark Jiawen Wu
2025-10-27 16:51 ` [PATCH 00/19] Wangxun Fixes Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251027031542.10512-19-jiawenwu@trustnetic.com \
    --to=jiawenwu@trustnetic.com \
    --cc=dev@dpdk.org \
    --cc=stable@dpdk.org \
    --cc=zaiyuwang@trustnetic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).