All of lore.kernel.org
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] net/iavf: support enhanced VLAN offload
@ 2020-09-02  8:28 Qiming Yang
  0 siblings, 0 replies; only message in thread
From: Qiming Yang @ 2020-09-02  8:28 UTC (permalink / raw)
  To: dev; +Cc: qi.z.zhang, Qiming Yang

This patch add VIRTCHNL_VF_OFFLOAD_VLAN_V2 series virtual channel
support, included get VLAN offload capability, support VLAN filter
and double VLAN strip.

Signed-off-by: Qiming Yang <qiming.yang@intel.com>
---
 drivers/net/iavf/iavf.h        |  5 ++
 drivers/net/iavf/iavf_ethdev.c | 70 ++++++++++++++++++++-------
 drivers/net/iavf/iavf_vchnl.c  | 87 ++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+), 17 deletions(-)

diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index 9ad331ee9..8c10f7e59 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -149,6 +149,7 @@ struct iavf_info {
 	struct iavf_parser_list dist_parser_list;
 
 	struct iavf_fdir_info fdir; /* flow director info */
+	struct virtchnl_vlan_caps *vlan_cap;
 };
 
 #define IAVF_MAX_PKT_TYPE 1024
@@ -279,4 +280,8 @@ int iavf_add_del_rss_cfg(struct iavf_adapter *adapter,
 int iavf_add_del_mc_addr_list(struct iavf_adapter *adapter,
 			struct rte_ether_addr *mc_addrs,
 			uint32_t mc_addrs_num, bool add);
+int iavf_get_vlan_offload_capa(struct rte_eth_dev *dev);
+int iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid,
+			 bool add, bool qinq);
+int iavf_switch_vlan_strip(struct iavf_adapter *adapter, bool qinq, bool on);
 #endif /* _IAVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 28ca3fa8f..af9698009 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -807,14 +807,22 @@ iavf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 	struct iavf_adapter *adapter =
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+	int qinq = dev->data->dev_conf.rxmode.offloads &
+		   DEV_RX_OFFLOAD_VLAN_EXTEND;
 	int err;
 
-	if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
-		return -ENOTSUP;
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
+		err = iavf_add_del_vlan_v2(adapter, vlan_id, on, qinq);
+		if (err)
+			return -EIO;
+		return 0;
+	}
 
-	err = iavf_add_del_vlan(adapter, vlan_id, on);
-	if (err)
-		return -EIO;
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {
+		err = iavf_add_del_vlan(adapter, vlan_id, on);
+		if (err)
+			return -EIO;
+	}
 	return 0;
 }
 
@@ -825,22 +833,48 @@ iavf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
 	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+	int qinq = dev->data->dev_conf.rxmode.offloads &
+		   DEV_RX_OFFLOAD_VLAN_EXTEND;
+	bool on;
 	int err;
 
-	if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
-		return -ENOTSUP;
-
-	/* Vlan stripping setting */
-	if (mask & ETH_VLAN_STRIP_MASK) {
-		/* Enable or disable VLAN stripping */
-		if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
-			err = iavf_enable_vlan_strip(adapter);
-		else
-			err = iavf_disable_vlan_strip(adapter);
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) {
+		/* Double vlan stripping setting */
+		if (mask & ETH_QINQ_STRIP_MASK) {
+			/* Enable or disable inner VLAN stripping */
+			on = dev_conf->rxmode.offloads &
+			     DEV_RX_OFFLOAD_QINQ_STRIP;
+			err = iavf_switch_vlan_strip(adapter, qinq, on);
+			if (err)
+				return -EIO;
+		}
+		/* Single vlan stripping setting */
+		if (mask & ETH_VLAN_STRIP_MASK) {
+			/* Enable or disable VLAN stripping */
+			on = dev_conf->rxmode.offloads &
+			     DEV_RX_OFFLOAD_VLAN_STRIP;
+			err = iavf_switch_vlan_strip(adapter, qinq, on);
+			if (err)
+				return -EIO;
+		}
+		return 0;
+	}
 
-		if (err)
-			return -EIO;
+	if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {
+		/* Vlan stripping setting */
+		if (mask & ETH_VLAN_STRIP_MASK) {
+			/* Enable or disable VLAN stripping */
+			if (dev_conf->rxmode.offloads &
+			    DEV_RX_OFFLOAD_VLAN_STRIP)
+				err = iavf_enable_vlan_strip(adapter);
+			else
+				err = iavf_disable_vlan_strip(adapter);
+
+			if (err)
+				return -EIO;
+		}
 	}
+
 	return 0;
 }
 
@@ -1453,6 +1487,8 @@ iavf_dev_init(struct rte_eth_dev *eth_dev)
 		return ret;
 	}
 
+	iavf_get_vlan_offload_capa(eth_dev);
+
 	return 0;
 }
 
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
index 6b57ecbba..74e73b0d3 100644
--- a/drivers/net/iavf/iavf_vchnl.c
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -314,6 +314,93 @@ iavf_disable_vlan_strip(struct iavf_adapter *adapter)
 	return ret;
 }
 
+int
+iavf_get_vlan_offload_capa(struct rte_eth_dev *dev)
+{
+	struct iavf_adapter *adapter =
+		IAVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+	struct virtchnl_vlan_caps *vlan_cap = NULL;
+	struct iavf_cmd_info args;
+	int ret;
+
+	memset(&args, 0, sizeof(args));
+	args.ops = VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS;
+	args.in_args = NULL;
+	args.in_args_size = 0;
+	args.out_buffer = vf->aq_resp;
+	args.out_size = IAVF_AQ_BUF_SZ;
+	ret = iavf_execute_vf_cmd(adapter, &args);
+	if (ret)
+		PMD_DRV_LOG(ERR, "Failed to execute command of"
+				 " OP_GET_OFFLOAD_VLAN_V2_CAPS");
+	vlan_cap = (struct virtchnl_vlan_caps *)args.out_buffer;
+	vf->vlan_cap = vlan_cap;
+
+	return ret;
+}
+
+int
+iavf_add_del_vlan_v2(struct iavf_adapter *adapter, uint16_t vlanid,
+		     bool add, bool qinq)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+	struct virtchnl_vlan_filter vlan_filter;
+	struct iavf_cmd_info args;
+	int err;
+
+	if (qinq) {
+		vlan_filter.inner.id = vlanid;
+		vlan_filter.inner.ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
+	} else {
+		vlan_filter.outer.id = vlanid;
+		vlan_filter.outer.ethertype = VIRTCHNL_VLAN_ETHERTYPE_8100;
+	}
+
+	args.ops = add ? VIRTCHNL_OP_ADD_VLAN_V2 : VIRTCHNL_OP_DEL_VLAN_V2;
+	args.in_args = (uint8_t *)&vlan_filter;
+	args.in_args_size = sizeof(vlan_filter);
+	args.out_buffer = vf->aq_resp;
+	args.out_size = IAVF_AQ_BUF_SZ;
+	err = iavf_execute_vf_cmd(adapter, &args);
+	if (err)
+		PMD_DRV_LOG(ERR, "fail to execute command %s",
+			    add ? "OP_ADD_VLAN" :  "OP_DEL_VLAN");
+
+	return err;
+}
+
+int
+iavf_switch_vlan_strip(struct iavf_adapter *adapter, bool qinq, bool on)
+{
+	struct iavf_info *vf = IAVF_DEV_PRIVATE_TO_VF(adapter);
+	struct virtchnl_vlan_strip vlan_strip;
+	struct iavf_cmd_info args;
+	int ret;
+
+	memset(&args, 0, sizeof(args));
+	vlan_strip.vsi_id = vf->vsi_res->vsi_id;
+	if (qinq)
+		vlan_strip.inner_ethertype_setting =
+			VIRTCHNL_VLAN_ETHERTYPE_8100;
+	else
+		vlan_strip.outer_ethertype_setting =
+			VIRTCHNL_VLAN_ETHERTYPE_8100;
+	args.ops = on ? VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2
+		   : VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2;
+	args.in_args = (uint8_t *)&vlan_strip;
+	args.in_args_size = sizeof(vlan_strip);
+	args.out_buffer = vf->aq_resp;
+	args.out_size = IAVF_AQ_BUF_SZ;
+	ret = iavf_execute_vf_cmd(adapter, &args);
+	if (ret)
+		PMD_DRV_LOG(ERR, "fail to execute command %s",
+			    on ? "VIRTCHNL_OP_ENABLE_VLAN_STRIPPING_V2"
+			    :  "VIRTCHNL_OP_DISABLE_VLAN_STRIPPING_V2");
+
+	return ret;
+}
+
 #define VIRTCHNL_VERSION_MAJOR_START 1
 #define VIRTCHNL_VERSION_MINOR_START 1
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-09-02  8:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-02  8:28 [dpdk-dev] [PATCH] net/iavf: support enhanced VLAN offload Qiming Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.