DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1] net/ice: refactor DCF VLAN handling
@ 2021-01-18  8:24 Haiyue Wang
  2021-01-18 11:38 ` [dpdk-dev] [PATCH v2] " Haiyue Wang
  0 siblings, 1 reply; 3+ messages in thread
From: Haiyue Wang @ 2021-01-18  8:24 UTC (permalink / raw)
  To: dev; +Cc: qiming.yang, qi.z.zhang, qi.fu, Haiyue Wang

Since DCF always configure the outer VLAN offloads for the target AVF,
so rename the related variables to align with this design.

Also, the DCF needs to trace the AVF reset status to re-apply the VLAN
offload setting, refactor the reset event handling to support this.

Change the VF representor API 'ethdev' parameter to 'vf_rep_eth_dev' to
avoid introducing confusion with VF representor eth_dev ops name.

Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
 drivers/net/ice/ice_dcf_ethdev.c         |  47 ++++-
 drivers/net/ice/ice_dcf_ethdev.h         |  23 ++-
 drivers/net/ice/ice_dcf_parent.c         |  62 +++++--
 drivers/net/ice/ice_dcf_vf_representor.c | 218 +++++++++++++++++++----
 4 files changed, 298 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index a9e78064d..f9025d189 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -601,6 +601,9 @@ ice_dcf_dev_stop(struct rte_eth_dev *dev)
 		return 0;
 	}
 
+	/* Stop the VF representors for this device */
+	ice_dcf_vf_repr_stop_all(dcf_ad);
+
 	ice_dcf_stop_queues(dev);
 
 	rte_intr_efd_disable(intr_handle);
@@ -849,6 +852,30 @@ ice_dcf_stats_reset(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter)
+{
+	if (dcf_adapter->repr_infos) {
+		rte_free(dcf_adapter->repr_infos);
+		dcf_adapter->repr_infos = NULL;
+	}
+}
+
+static int
+ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter)
+{
+	dcf_adapter->repr_infos =
+			rte_calloc("ice_dcf_rep_info",
+				   dcf_adapter->real_hw.num_vfs,
+				   sizeof(dcf_adapter->repr_infos[0]), 0);
+	if (!dcf_adapter->repr_infos) {
+		PMD_DRV_LOG(ERR, "Failed to alloc memory for VF representors\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 static int
 ice_dcf_dev_close(struct rte_eth_dev *dev)
 {
@@ -857,6 +884,7 @@ ice_dcf_dev_close(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	ice_dcf_free_repr_info(adapter);
 	ice_dcf_uninit_parent_adapter(dev);
 	ice_dcf_uninit_hw(dev, &adapter->real_hw);
 
@@ -1000,21 +1028,26 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
 		return -ENODEV;
 
 	dcf_adapter = dcf_ethdev->data->dev_private;
+	ret = ice_dcf_init_repr_info(dcf_adapter);
+	if (ret)
+		return ret;
 
 	if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs ||
 	    eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) {
 		PMD_DRV_LOG(ERR, "the number of port representors is too large: %u",
 			    eth_da.nb_representor_ports);
+		ice_dcf_free_repr_info(dcf_adapter);
 		return -EINVAL;
 	}
 
 	dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID;
 
-	repr_param.adapter = dcf_adapter;
+	repr_param.dcf_eth_dev = dcf_ethdev;
 	repr_param.switch_domain_id = 0;
 
 	for (i = 0; i < eth_da.nb_representor_ports; i++) {
 		uint16_t vf_id = eth_da.representor_ports[i];
+		struct rte_eth_dev *vf_rep_eth_dev;
 
 		if (vf_id >= dcf_adapter->real_hw.num_vfs) {
 			PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)",
@@ -1041,6 +1074,18 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
 				    repr_name);
 			break;
 		}
+
+		vf_rep_eth_dev = rte_eth_dev_allocated(repr_name);
+		if (!vf_rep_eth_dev) {
+			PMD_DRV_LOG(ERR,
+				    "Failed to find the ethdev for DCF VF representor: %s",
+				    repr_name);
+			ret = -ENODEV;
+			break;
+		}
+
+		dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev;
+		dcf_adapter->num_reprs++;
 	}
 
 	return ret;
diff --git a/drivers/net/ice/ice_dcf_ethdev.h b/drivers/net/ice/ice_dcf_ethdev.h
index 7695815e1..e7c9d7fe4 100644
--- a/drivers/net/ice/ice_dcf_ethdev.h
+++ b/drivers/net/ice/ice_dcf_ethdev.h
@@ -17,30 +17,39 @@ struct ice_dcf_queue {
 	uint64_t dummy;
 };
 
+struct ice_dcf_repr_info {
+	struct rte_eth_dev *vf_rep_eth_dev;
+};
+
 struct ice_dcf_adapter {
 	struct ice_adapter parent; /* Must be first */
 	struct ice_dcf_hw real_hw;
+
+	int num_reprs;
+	struct ice_dcf_repr_info *repr_infos;
 };
 
 struct ice_dcf_vf_repr_param {
-	struct ice_dcf_adapter *adapter;
+	struct rte_eth_dev *dcf_eth_dev;
 	uint16_t switch_domain_id;
 	uint16_t vf_id;
 };
 
 struct ice_dcf_vlan {
+	bool port_vlan_ena;
+	bool stripping_ena;
+
 	uint16_t tpid;
 	uint16_t vid;
 };
 
 struct ice_dcf_vf_repr {
-	struct ice_dcf_adapter *dcf_adapter;
+	struct rte_eth_dev *dcf_eth_dev;
 	struct rte_ether_addr mac_addr;
 	uint16_t switch_domain_id;
 	uint16_t vf_id;
 
-	bool port_vlan_ena;
-	struct ice_dcf_vlan port_vlan_info;
+	struct ice_dcf_vlan outer_vlan_info; /* DCF always handle outer VLAN */
 };
 
 void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
@@ -48,7 +57,9 @@ void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 int ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev);
 void ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev);
 
-int ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param);
-int ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev);
+int ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param);
+int ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev);
+int ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev);
+void ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter);
 
 #endif /* _ICE_DCF_ETHDEV_H_ */
diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c
index 7d565028f..ddf24d3f8 100644
--- a/drivers/net/ice/ice_dcf_parent.c
+++ b/drivers/net/ice/ice_dcf_parent.c
@@ -14,6 +14,13 @@
 #define ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL	100000 /* us */
 static rte_spinlock_t vsi_update_lock = RTE_SPINLOCK_INITIALIZER;
 
+struct ice_dcf_reset_event_param {
+	struct ice_dcf_hw *dcf_hw;
+
+	bool vfr; /* VF reset event */
+	uint16_t vf_id; /* The reset VF ID */
+};
+
 static __rte_always_inline void
 ice_dcf_update_vsi_ctx(struct ice_hw *hw, uint16_t vsi_handle,
 		       uint16_t vsi_map)
@@ -110,31 +117,67 @@ ice_dcf_update_pf_vsi_map(struct ice_hw *hw, uint16_t pf_vsi_idx,
 static void*
 ice_dcf_vsi_update_service_handler(void *param)
 {
-	struct ice_dcf_hw *hw = param;
+	struct ice_dcf_reset_event_param *reset_param = param;
+	struct ice_dcf_hw *hw = reset_param->dcf_hw;
+	struct ice_dcf_adapter *adapter;
 
 	usleep(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL);
 
 	rte_spinlock_lock(&vsi_update_lock);
 
-	if (!ice_dcf_handle_vsi_update_event(hw)) {
-		struct ice_dcf_adapter *dcf_ad =
-			container_of(hw, struct ice_dcf_adapter, real_hw);
+	adapter = container_of(hw, struct ice_dcf_adapter, real_hw);
 
-		ice_dcf_update_vf_vsi_map(&dcf_ad->parent.hw,
+	if (!ice_dcf_handle_vsi_update_event(hw))
+		ice_dcf_update_vf_vsi_map(&adapter->parent.hw,
 					  hw->num_vfs, hw->vf_vsi_map);
+
+	if (reset_param->vfr && adapter->repr_infos) {
+		struct rte_eth_dev *vf_rep_eth_dev =
+			adapter->repr_infos[reset_param->vf_id].vf_rep_eth_dev;
+		if (vf_rep_eth_dev && vf_rep_eth_dev->data->dev_started) {
+			PMD_DRV_LOG(ERR, "VF representor %u is resetting",
+				    reset_param->vf_id);
+			ice_dcf_vf_repr_init_vlan(vf_rep_eth_dev);
+		}
 	}
 
 	rte_spinlock_unlock(&vsi_update_lock);
 
+	free(param);
+
 	return NULL;
 }
 
+static void
+start_vsi_reset_thread(struct ice_dcf_hw *dcf_hw, bool vfr, uint16_t vf_id)
+{
+	struct ice_dcf_reset_event_param *param;
+	pthread_t thread;
+	int ret;
+
+	param = malloc(sizeof(*param));
+	if (!param) {
+		PMD_DRV_LOG(ERR, "Failed to allocate the memory for reset handling");
+		return;
+	}
+
+	param->dcf_hw = dcf_hw;
+	param->vfr = vfr;
+	param->vf_id = vf_id;
+
+	ret = pthread_create(&thread, NULL,
+			     ice_dcf_vsi_update_service_handler, param);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to start the thread for reset handling");
+		free(param);
+	}
+}
+
 void
 ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 			    uint8_t *msg, uint16_t msglen)
 {
 	struct virtchnl_pf_event *pf_msg = (struct virtchnl_pf_event *)msg;
-	pthread_t thread;
 
 	if (msglen < sizeof(struct virtchnl_pf_event)) {
 		PMD_DRV_LOG(DEBUG, "Invalid event message length : %u", msglen);
@@ -144,8 +187,7 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 	switch (pf_msg->event) {
 	case VIRTCHNL_EVENT_RESET_IMPENDING:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
-		pthread_create(&thread, NULL,
-			       ice_dcf_vsi_update_service_handler, dcf_hw);
+		start_vsi_reset_thread(dcf_hw, false, 0);
 		break;
 	case VIRTCHNL_EVENT_LINK_CHANGE:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
@@ -157,8 +199,8 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_DCF_VSI_MAP_UPDATE event : VF%u with VSI num %u",
 			    pf_msg->event_data.vf_vsi_map.vf_id,
 			    pf_msg->event_data.vf_vsi_map.vsi_id);
-		pthread_create(&thread, NULL,
-			       ice_dcf_vsi_update_service_handler, dcf_hw);
+		start_vsi_reset_thread(dcf_hw, true,
+				       pf_msg->event_data.vf_vsi_map.vf_id);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "Unknown event received %u", pf_msg->event);
diff --git a/drivers/net/ice/ice_dcf_vf_representor.c b/drivers/net/ice/ice_dcf_vf_representor.c
index 09ca4df5a..970461f3e 100644
--- a/drivers/net/ice/ice_dcf_vf_representor.c
+++ b/drivers/net/ice/ice_dcf_vf_representor.c
@@ -27,8 +27,10 @@ ice_dcf_vf_repr_tx_burst(__rte_unused void *txq,
 }
 
 static int
-ice_dcf_vf_repr_dev_configure(__rte_unused struct rte_eth_dev *dev)
+ice_dcf_vf_repr_dev_configure(struct rte_eth_dev *dev)
 {
+	ice_dcf_vf_repr_init_vlan(dev);
+
 	return 0;
 }
 
@@ -106,13 +108,21 @@ ice_dcf_vf_repr_link_update(__rte_unused struct rte_eth_dev *ethdev,
 	return 0;
 }
 
+static __rte_always_inline struct ice_dcf_hw *
+ice_dcf_vf_repr_hw(struct ice_dcf_vf_repr *repr)
+{
+	struct ice_dcf_adapter *dcf_adapter =
+			repr->dcf_eth_dev->data->dev_private;
+
+	return &dcf_adapter->real_hw;
+}
+
 static int
 ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev,
 			     struct rte_eth_dev_info *dev_info)
 {
 	struct ice_dcf_vf_repr *repr = dev->data->dev_private;
-	struct ice_dcf_hw *dcf_hw =
-				&repr->dcf_adapter->real_hw;
+	struct ice_dcf_hw *dcf_hw = ice_dcf_vf_repr_hw(repr);
 
 	dev_info->device = dev->device;
 	dev_info->max_mac_addrs = 1;
@@ -190,25 +200,82 @@ ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static __rte_always_inline bool
+ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr)
+{
+	return !!(ice_dcf_vf_repr_hw(repr)->vf_res->vf_cap_flags &
+		  VIRTCHNL_VF_OFFLOAD_VLAN_V2);
+}
+
 static int
 ice_dcf_vlan_offload_config(struct ice_dcf_vf_repr *repr,
 			    struct virtchnl_dcf_vlan_offload *vlan_offload)
 {
 	struct dcf_virtchnl_cmd args;
+	int err;
 
 	memset(&args, 0, sizeof(args));
 	args.v_op = VIRTCHNL_OP_DCF_VLAN_OFFLOAD;
 	args.req_msg = (uint8_t *)vlan_offload;
 	args.req_msglen = sizeof(*vlan_offload);
 
-	return ice_dcf_execute_virtchnl_cmd(&repr->dcf_adapter->real_hw, &args);
+	err = ice_dcf_execute_virtchnl_cmd(ice_dcf_vf_repr_hw(repr), &args);
+	if (err)
+		PMD_DRV_LOG(ERR,
+			    "Failed to execute command of VIRTCHNL_OP_DCF_VLAN_OFFLOAD");
+
+	return err;
 }
 
-static __rte_always_inline bool
-ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr)
+static int
+ice_dcf_vf_repr_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
-	return !!(repr->dcf_adapter->real_hw.vf_res->vf_cap_flags &
-		  VIRTCHNL_VF_OFFLOAD_VLAN_V2);
+	struct ice_dcf_vf_repr *repr = dev->data->dev_private;
+	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+	struct virtchnl_dcf_vlan_offload vlan_offload;
+	int err;
+
+	if (!ice_dcf_vlan_offload_ena(repr))
+		return -ENOTSUP;
+
+	/* Vlan stripping setting */
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		bool enable = !!(dev_conf->rxmode.offloads &
+				 DEV_RX_OFFLOAD_VLAN_STRIP);
+
+		if (enable && repr->outer_vlan_info.port_vlan_ena) {
+			PMD_DRV_LOG(ERR,
+				    "Disable the port VLAN firstly\n");
+			return -EINVAL;
+		}
+
+		memset(&vlan_offload, 0, sizeof(vlan_offload));
+
+		if (enable)
+			vlan_offload.vlan_flags =
+					VIRTCHNL_DCF_VLAN_STRIP_INTO_RX_DESC <<
+					VIRTCHNL_DCF_VLAN_STRIP_MODE_S;
+		else if (repr->outer_vlan_info.stripping_ena && !enable)
+			vlan_offload.vlan_flags =
+					VIRTCHNL_DCF_VLAN_STRIP_DISABLE <<
+					VIRTCHNL_DCF_VLAN_STRIP_MODE_S;
+
+		if (vlan_offload.vlan_flags) {
+			vlan_offload.vf_id = repr->vf_id;
+			vlan_offload.tpid = repr->outer_vlan_info.tpid;
+			vlan_offload.vlan_flags |=
+					VIRTCHNL_DCF_VLAN_TYPE_OUTER <<
+					VIRTCHNL_DCF_VLAN_TYPE_S;
+
+			err = ice_dcf_vlan_offload_config(repr, &vlan_offload);
+			if (err)
+				return -EIO;
+
+			repr->outer_vlan_info.stripping_ena = enable;
+		}
+	}
+
+	return 0;
 }
 
 static int
@@ -222,26 +289,39 @@ ice_dcf_vf_repr_vlan_pvid_set(struct rte_eth_dev *dev,
 	if (!ice_dcf_vlan_offload_ena(repr))
 		return -ENOTSUP;
 
-	if (on && (pvid == 0 || pvid > RTE_ETHER_MAX_VLAN_ID))
+	if (repr->outer_vlan_info.stripping_ena) {
+		PMD_DRV_LOG(ERR,
+			    "Disable the VLAN stripping firstly\n");
+		return -EINVAL;
+	}
+
+	if (pvid > RTE_ETHER_MAX_VLAN_ID)
 		return -EINVAL;
 
 	memset(&vlan_offload, 0, sizeof(vlan_offload));
 
+	if (on)
+		vlan_offload.vlan_flags =
+				(VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED <<
+				 VIRTCHNL_DCF_VLAN_INSERT_MODE_S);
+	else
+		vlan_offload.vlan_flags =
+				(VIRTCHNL_DCF_VLAN_INSERT_DISABLE <<
+				 VIRTCHNL_DCF_VLAN_INSERT_MODE_S);
+
 	vlan_offload.vf_id = repr->vf_id;
-	vlan_offload.tpid = repr->port_vlan_info.tpid;
-	vlan_offload.vlan_flags = (VIRTCHNL_DCF_VLAN_TYPE_OUTER <<
-				   VIRTCHNL_DCF_VLAN_TYPE_S) |
-				  (VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED <<
-				   VIRTCHNL_DCF_VLAN_INSERT_MODE_S);
-	vlan_offload.vlan_id = on ? pvid : 0;
+	vlan_offload.tpid = repr->outer_vlan_info.tpid;
+	vlan_offload.vlan_flags |= (VIRTCHNL_DCF_VLAN_TYPE_OUTER <<
+				    VIRTCHNL_DCF_VLAN_TYPE_S);
+	vlan_offload.vlan_id = pvid;
 
 	err = ice_dcf_vlan_offload_config(repr, &vlan_offload);
 	if (!err) {
 		if (on) {
-			repr->port_vlan_ena = true;
-			repr->port_vlan_info.vid = pvid;
+			repr->outer_vlan_info.port_vlan_ena = true;
+			repr->outer_vlan_info.vid = pvid;
 		} else {
-			repr->port_vlan_ena = false;
+			repr->outer_vlan_info.port_vlan_ena = false;
 		}
 	}
 
@@ -272,13 +352,32 @@ ice_dcf_vf_repr_vlan_tpid_set(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	repr->port_vlan_info.tpid = tpid;
+	repr->outer_vlan_info.tpid = tpid;
 
-	if (repr->port_vlan_ena)
+	if (repr->outer_vlan_info.port_vlan_ena) {
 		err = ice_dcf_vf_repr_vlan_pvid_set(dev,
-						    repr->port_vlan_info.vid,
+						    repr->outer_vlan_info.vid,
 						    true);
-	return err;
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				    "Failed to reset port VLAN : %d\n",
+				    err);
+			return err;
+		}
+	}
+
+	if (repr->outer_vlan_info.stripping_ena) {
+		err = ice_dcf_vf_repr_vlan_offload_set(dev,
+						       ETH_VLAN_STRIP_MASK);
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				    "Failed to reset VLAN stripping : %d\n",
+				    err);
+			return err;
+		}
+	}
+
+	return 0;
 }
 
 static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = {
@@ -294,31 +393,33 @@ static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = {
 	.allmulticast_enable  = ice_dcf_vf_repr_allmulticast_enable,
 	.allmulticast_disable = ice_dcf_vf_repr_allmulticast_disable,
 	.link_update          = ice_dcf_vf_repr_link_update,
+	.vlan_offload_set     = ice_dcf_vf_repr_vlan_offload_set,
 	.vlan_pvid_set        = ice_dcf_vf_repr_vlan_pvid_set,
 	.vlan_tpid_set        = ice_dcf_vf_repr_vlan_tpid_set,
 };
 
 int
-ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param)
+ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param)
 {
-	struct ice_dcf_vf_repr *repr = ethdev->data->dev_private;
+	struct ice_dcf_vf_repr *repr = vf_rep_eth_dev->data->dev_private;
 	struct ice_dcf_vf_repr_param *param = init_param;
 
-	repr->dcf_adapter = param->adapter;
+	repr->dcf_eth_dev = param->dcf_eth_dev;
 	repr->switch_domain_id = param->switch_domain_id;
 	repr->vf_id = param->vf_id;
-	repr->port_vlan_ena = false;
-	repr->port_vlan_info.tpid = RTE_ETHER_TYPE_VLAN;
+	repr->outer_vlan_info.port_vlan_ena = false;
+	repr->outer_vlan_info.stripping_ena = false;
+	repr->outer_vlan_info.tpid = RTE_ETHER_TYPE_VLAN;
 
-	ethdev->dev_ops = &ice_dcf_vf_repr_dev_ops;
+	vf_rep_eth_dev->dev_ops = &ice_dcf_vf_repr_dev_ops;
 
-	ethdev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst;
-	ethdev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst;
+	vf_rep_eth_dev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst;
+	vf_rep_eth_dev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst;
 
-	ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
-	ethdev->data->representor_id = repr->vf_id;
+	vf_rep_eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+	vf_rep_eth_dev->data->representor_id = repr->vf_id;
 
-	ethdev->data->mac_addrs = &repr->mac_addr;
+	vf_rep_eth_dev->data->mac_addrs = &repr->mac_addr;
 
 	rte_eth_random_addr(repr->mac_addr.addr_bytes);
 
@@ -326,9 +427,56 @@ ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param)
 }
 
 int
-ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev)
+ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev)
 {
-	ethdev->data->mac_addrs = NULL;
+	vf_rep_eth_dev->data->mac_addrs = NULL;
 
 	return 0;
 }
+
+int
+ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev)
+{
+	struct ice_dcf_vf_repr *repr = vf_rep_eth_dev->data->dev_private;
+	int err;
+
+	err = ice_dcf_vf_repr_vlan_offload_set(vf_rep_eth_dev,
+					       ETH_VLAN_STRIP_MASK);
+	if (err) {
+		PMD_DRV_LOG(ERR, "Failed to set VLAN offload");
+		return err;
+	}
+
+	if (repr->outer_vlan_info.port_vlan_ena) {
+		err = ice_dcf_vf_repr_vlan_pvid_set(vf_rep_eth_dev,
+						    repr->outer_vlan_info.vid,
+						    true);
+		if (err) {
+			PMD_DRV_LOG(ERR, "Failed to enable port VLAN");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+void
+ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter)
+{
+	uint16_t vf_id;
+	int ret;
+
+	if (!dcf_adapter->repr_infos)
+		return;
+
+	for (vf_id = 0; vf_id < dcf_adapter->real_hw.num_vfs; vf_id++) {
+		struct rte_eth_dev *vf_rep_eth_dev =
+				dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev;
+		if (!vf_rep_eth_dev || vf_rep_eth_dev->data->dev_started == 0)
+			continue;
+
+		ret = ice_dcf_vf_repr_dev_stop(vf_rep_eth_dev);
+		if (!ret)
+			vf_rep_eth_dev->data->dev_started = 0;
+	}
+}
-- 
2.30.0


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

* [dpdk-dev] [PATCH v2] net/ice: refactor DCF VLAN handling
  2021-01-18  8:24 [dpdk-dev] [PATCH v1] net/ice: refactor DCF VLAN handling Haiyue Wang
@ 2021-01-18 11:38 ` Haiyue Wang
  2021-01-19  6:27   ` Zhang, Qi Z
  0 siblings, 1 reply; 3+ messages in thread
From: Haiyue Wang @ 2021-01-18 11:38 UTC (permalink / raw)
  To: dev; +Cc: qiming.yang, qi.z.zhang, qi.fu, Haiyue Wang

Since DCF always configure the outer VLAN offloads for the target AVF,
so rename the related variables to align with this design.

Also, the DCF needs to trace the AVF reset status to re-apply the VLAN
offload setting, refactor the reset event handling to support this.

Change the VF representor API 'ethdev' parameter to 'vf_rep_eth_dev' to
avoid introducing confusion with VF representor eth_dev ops name.

Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
v2: change the reset log from ERR to DEBUG level
---
 drivers/net/ice/ice_dcf_ethdev.c         |  47 ++++-
 drivers/net/ice/ice_dcf_ethdev.h         |  23 ++-
 drivers/net/ice/ice_dcf_parent.c         |  62 +++++--
 drivers/net/ice/ice_dcf_vf_representor.c | 218 +++++++++++++++++++----
 4 files changed, 298 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index a9e78064d..f9025d189 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -601,6 +601,9 @@ ice_dcf_dev_stop(struct rte_eth_dev *dev)
 		return 0;
 	}
 
+	/* Stop the VF representors for this device */
+	ice_dcf_vf_repr_stop_all(dcf_ad);
+
 	ice_dcf_stop_queues(dev);
 
 	rte_intr_efd_disable(intr_handle);
@@ -849,6 +852,30 @@ ice_dcf_stats_reset(struct rte_eth_dev *dev)
 	return 0;
 }
 
+static void
+ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter)
+{
+	if (dcf_adapter->repr_infos) {
+		rte_free(dcf_adapter->repr_infos);
+		dcf_adapter->repr_infos = NULL;
+	}
+}
+
+static int
+ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter)
+{
+	dcf_adapter->repr_infos =
+			rte_calloc("ice_dcf_rep_info",
+				   dcf_adapter->real_hw.num_vfs,
+				   sizeof(dcf_adapter->repr_infos[0]), 0);
+	if (!dcf_adapter->repr_infos) {
+		PMD_DRV_LOG(ERR, "Failed to alloc memory for VF representors\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 static int
 ice_dcf_dev_close(struct rte_eth_dev *dev)
 {
@@ -857,6 +884,7 @@ ice_dcf_dev_close(struct rte_eth_dev *dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	ice_dcf_free_repr_info(adapter);
 	ice_dcf_uninit_parent_adapter(dev);
 	ice_dcf_uninit_hw(dev, &adapter->real_hw);
 
@@ -1000,21 +1028,26 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
 		return -ENODEV;
 
 	dcf_adapter = dcf_ethdev->data->dev_private;
+	ret = ice_dcf_init_repr_info(dcf_adapter);
+	if (ret)
+		return ret;
 
 	if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs ||
 	    eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) {
 		PMD_DRV_LOG(ERR, "the number of port representors is too large: %u",
 			    eth_da.nb_representor_ports);
+		ice_dcf_free_repr_info(dcf_adapter);
 		return -EINVAL;
 	}
 
 	dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID;
 
-	repr_param.adapter = dcf_adapter;
+	repr_param.dcf_eth_dev = dcf_ethdev;
 	repr_param.switch_domain_id = 0;
 
 	for (i = 0; i < eth_da.nb_representor_ports; i++) {
 		uint16_t vf_id = eth_da.representor_ports[i];
+		struct rte_eth_dev *vf_rep_eth_dev;
 
 		if (vf_id >= dcf_adapter->real_hw.num_vfs) {
 			PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)",
@@ -1041,6 +1074,18 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
 				    repr_name);
 			break;
 		}
+
+		vf_rep_eth_dev = rte_eth_dev_allocated(repr_name);
+		if (!vf_rep_eth_dev) {
+			PMD_DRV_LOG(ERR,
+				    "Failed to find the ethdev for DCF VF representor: %s",
+				    repr_name);
+			ret = -ENODEV;
+			break;
+		}
+
+		dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev;
+		dcf_adapter->num_reprs++;
 	}
 
 	return ret;
diff --git a/drivers/net/ice/ice_dcf_ethdev.h b/drivers/net/ice/ice_dcf_ethdev.h
index 7695815e1..e7c9d7fe4 100644
--- a/drivers/net/ice/ice_dcf_ethdev.h
+++ b/drivers/net/ice/ice_dcf_ethdev.h
@@ -17,30 +17,39 @@ struct ice_dcf_queue {
 	uint64_t dummy;
 };
 
+struct ice_dcf_repr_info {
+	struct rte_eth_dev *vf_rep_eth_dev;
+};
+
 struct ice_dcf_adapter {
 	struct ice_adapter parent; /* Must be first */
 	struct ice_dcf_hw real_hw;
+
+	int num_reprs;
+	struct ice_dcf_repr_info *repr_infos;
 };
 
 struct ice_dcf_vf_repr_param {
-	struct ice_dcf_adapter *adapter;
+	struct rte_eth_dev *dcf_eth_dev;
 	uint16_t switch_domain_id;
 	uint16_t vf_id;
 };
 
 struct ice_dcf_vlan {
+	bool port_vlan_ena;
+	bool stripping_ena;
+
 	uint16_t tpid;
 	uint16_t vid;
 };
 
 struct ice_dcf_vf_repr {
-	struct ice_dcf_adapter *dcf_adapter;
+	struct rte_eth_dev *dcf_eth_dev;
 	struct rte_ether_addr mac_addr;
 	uint16_t switch_domain_id;
 	uint16_t vf_id;
 
-	bool port_vlan_ena;
-	struct ice_dcf_vlan port_vlan_info;
+	struct ice_dcf_vlan outer_vlan_info; /* DCF always handle outer VLAN */
 };
 
 void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
@@ -48,7 +57,9 @@ void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 int ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev);
 void ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev);
 
-int ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param);
-int ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev);
+int ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param);
+int ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev);
+int ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev);
+void ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter);
 
 #endif /* _ICE_DCF_ETHDEV_H_ */
diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c
index 7d565028f..476fd4906 100644
--- a/drivers/net/ice/ice_dcf_parent.c
+++ b/drivers/net/ice/ice_dcf_parent.c
@@ -14,6 +14,13 @@
 #define ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL	100000 /* us */
 static rte_spinlock_t vsi_update_lock = RTE_SPINLOCK_INITIALIZER;
 
+struct ice_dcf_reset_event_param {
+	struct ice_dcf_hw *dcf_hw;
+
+	bool vfr; /* VF reset event */
+	uint16_t vf_id; /* The reset VF ID */
+};
+
 static __rte_always_inline void
 ice_dcf_update_vsi_ctx(struct ice_hw *hw, uint16_t vsi_handle,
 		       uint16_t vsi_map)
@@ -110,31 +117,67 @@ ice_dcf_update_pf_vsi_map(struct ice_hw *hw, uint16_t pf_vsi_idx,
 static void*
 ice_dcf_vsi_update_service_handler(void *param)
 {
-	struct ice_dcf_hw *hw = param;
+	struct ice_dcf_reset_event_param *reset_param = param;
+	struct ice_dcf_hw *hw = reset_param->dcf_hw;
+	struct ice_dcf_adapter *adapter;
 
 	usleep(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL);
 
 	rte_spinlock_lock(&vsi_update_lock);
 
-	if (!ice_dcf_handle_vsi_update_event(hw)) {
-		struct ice_dcf_adapter *dcf_ad =
-			container_of(hw, struct ice_dcf_adapter, real_hw);
+	adapter = container_of(hw, struct ice_dcf_adapter, real_hw);
 
-		ice_dcf_update_vf_vsi_map(&dcf_ad->parent.hw,
+	if (!ice_dcf_handle_vsi_update_event(hw))
+		ice_dcf_update_vf_vsi_map(&adapter->parent.hw,
 					  hw->num_vfs, hw->vf_vsi_map);
+
+	if (reset_param->vfr && adapter->repr_infos) {
+		struct rte_eth_dev *vf_rep_eth_dev =
+			adapter->repr_infos[reset_param->vf_id].vf_rep_eth_dev;
+		if (vf_rep_eth_dev && vf_rep_eth_dev->data->dev_started) {
+			PMD_DRV_LOG(DEBUG, "VF%u representor is resetting",
+				    reset_param->vf_id);
+			ice_dcf_vf_repr_init_vlan(vf_rep_eth_dev);
+		}
 	}
 
 	rte_spinlock_unlock(&vsi_update_lock);
 
+	free(param);
+
 	return NULL;
 }
 
+static void
+start_vsi_reset_thread(struct ice_dcf_hw *dcf_hw, bool vfr, uint16_t vf_id)
+{
+	struct ice_dcf_reset_event_param *param;
+	pthread_t thread;
+	int ret;
+
+	param = malloc(sizeof(*param));
+	if (!param) {
+		PMD_DRV_LOG(ERR, "Failed to allocate the memory for reset handling");
+		return;
+	}
+
+	param->dcf_hw = dcf_hw;
+	param->vfr = vfr;
+	param->vf_id = vf_id;
+
+	ret = pthread_create(&thread, NULL,
+			     ice_dcf_vsi_update_service_handler, param);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to start the thread for reset handling");
+		free(param);
+	}
+}
+
 void
 ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 			    uint8_t *msg, uint16_t msglen)
 {
 	struct virtchnl_pf_event *pf_msg = (struct virtchnl_pf_event *)msg;
-	pthread_t thread;
 
 	if (msglen < sizeof(struct virtchnl_pf_event)) {
 		PMD_DRV_LOG(DEBUG, "Invalid event message length : %u", msglen);
@@ -144,8 +187,7 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 	switch (pf_msg->event) {
 	case VIRTCHNL_EVENT_RESET_IMPENDING:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
-		pthread_create(&thread, NULL,
-			       ice_dcf_vsi_update_service_handler, dcf_hw);
+		start_vsi_reset_thread(dcf_hw, false, 0);
 		break;
 	case VIRTCHNL_EVENT_LINK_CHANGE:
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
@@ -157,8 +199,8 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
 		PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_DCF_VSI_MAP_UPDATE event : VF%u with VSI num %u",
 			    pf_msg->event_data.vf_vsi_map.vf_id,
 			    pf_msg->event_data.vf_vsi_map.vsi_id);
-		pthread_create(&thread, NULL,
-			       ice_dcf_vsi_update_service_handler, dcf_hw);
+		start_vsi_reset_thread(dcf_hw, true,
+				       pf_msg->event_data.vf_vsi_map.vf_id);
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "Unknown event received %u", pf_msg->event);
diff --git a/drivers/net/ice/ice_dcf_vf_representor.c b/drivers/net/ice/ice_dcf_vf_representor.c
index 09ca4df5a..970461f3e 100644
--- a/drivers/net/ice/ice_dcf_vf_representor.c
+++ b/drivers/net/ice/ice_dcf_vf_representor.c
@@ -27,8 +27,10 @@ ice_dcf_vf_repr_tx_burst(__rte_unused void *txq,
 }
 
 static int
-ice_dcf_vf_repr_dev_configure(__rte_unused struct rte_eth_dev *dev)
+ice_dcf_vf_repr_dev_configure(struct rte_eth_dev *dev)
 {
+	ice_dcf_vf_repr_init_vlan(dev);
+
 	return 0;
 }
 
@@ -106,13 +108,21 @@ ice_dcf_vf_repr_link_update(__rte_unused struct rte_eth_dev *ethdev,
 	return 0;
 }
 
+static __rte_always_inline struct ice_dcf_hw *
+ice_dcf_vf_repr_hw(struct ice_dcf_vf_repr *repr)
+{
+	struct ice_dcf_adapter *dcf_adapter =
+			repr->dcf_eth_dev->data->dev_private;
+
+	return &dcf_adapter->real_hw;
+}
+
 static int
 ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev,
 			     struct rte_eth_dev_info *dev_info)
 {
 	struct ice_dcf_vf_repr *repr = dev->data->dev_private;
-	struct ice_dcf_hw *dcf_hw =
-				&repr->dcf_adapter->real_hw;
+	struct ice_dcf_hw *dcf_hw = ice_dcf_vf_repr_hw(repr);
 
 	dev_info->device = dev->device;
 	dev_info->max_mac_addrs = 1;
@@ -190,25 +200,82 @@ ice_dcf_vf_repr_dev_info_get(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static __rte_always_inline bool
+ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr)
+{
+	return !!(ice_dcf_vf_repr_hw(repr)->vf_res->vf_cap_flags &
+		  VIRTCHNL_VF_OFFLOAD_VLAN_V2);
+}
+
 static int
 ice_dcf_vlan_offload_config(struct ice_dcf_vf_repr *repr,
 			    struct virtchnl_dcf_vlan_offload *vlan_offload)
 {
 	struct dcf_virtchnl_cmd args;
+	int err;
 
 	memset(&args, 0, sizeof(args));
 	args.v_op = VIRTCHNL_OP_DCF_VLAN_OFFLOAD;
 	args.req_msg = (uint8_t *)vlan_offload;
 	args.req_msglen = sizeof(*vlan_offload);
 
-	return ice_dcf_execute_virtchnl_cmd(&repr->dcf_adapter->real_hw, &args);
+	err = ice_dcf_execute_virtchnl_cmd(ice_dcf_vf_repr_hw(repr), &args);
+	if (err)
+		PMD_DRV_LOG(ERR,
+			    "Failed to execute command of VIRTCHNL_OP_DCF_VLAN_OFFLOAD");
+
+	return err;
 }
 
-static __rte_always_inline bool
-ice_dcf_vlan_offload_ena(struct ice_dcf_vf_repr *repr)
+static int
+ice_dcf_vf_repr_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 {
-	return !!(repr->dcf_adapter->real_hw.vf_res->vf_cap_flags &
-		  VIRTCHNL_VF_OFFLOAD_VLAN_V2);
+	struct ice_dcf_vf_repr *repr = dev->data->dev_private;
+	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+	struct virtchnl_dcf_vlan_offload vlan_offload;
+	int err;
+
+	if (!ice_dcf_vlan_offload_ena(repr))
+		return -ENOTSUP;
+
+	/* Vlan stripping setting */
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		bool enable = !!(dev_conf->rxmode.offloads &
+				 DEV_RX_OFFLOAD_VLAN_STRIP);
+
+		if (enable && repr->outer_vlan_info.port_vlan_ena) {
+			PMD_DRV_LOG(ERR,
+				    "Disable the port VLAN firstly\n");
+			return -EINVAL;
+		}
+
+		memset(&vlan_offload, 0, sizeof(vlan_offload));
+
+		if (enable)
+			vlan_offload.vlan_flags =
+					VIRTCHNL_DCF_VLAN_STRIP_INTO_RX_DESC <<
+					VIRTCHNL_DCF_VLAN_STRIP_MODE_S;
+		else if (repr->outer_vlan_info.stripping_ena && !enable)
+			vlan_offload.vlan_flags =
+					VIRTCHNL_DCF_VLAN_STRIP_DISABLE <<
+					VIRTCHNL_DCF_VLAN_STRIP_MODE_S;
+
+		if (vlan_offload.vlan_flags) {
+			vlan_offload.vf_id = repr->vf_id;
+			vlan_offload.tpid = repr->outer_vlan_info.tpid;
+			vlan_offload.vlan_flags |=
+					VIRTCHNL_DCF_VLAN_TYPE_OUTER <<
+					VIRTCHNL_DCF_VLAN_TYPE_S;
+
+			err = ice_dcf_vlan_offload_config(repr, &vlan_offload);
+			if (err)
+				return -EIO;
+
+			repr->outer_vlan_info.stripping_ena = enable;
+		}
+	}
+
+	return 0;
 }
 
 static int
@@ -222,26 +289,39 @@ ice_dcf_vf_repr_vlan_pvid_set(struct rte_eth_dev *dev,
 	if (!ice_dcf_vlan_offload_ena(repr))
 		return -ENOTSUP;
 
-	if (on && (pvid == 0 || pvid > RTE_ETHER_MAX_VLAN_ID))
+	if (repr->outer_vlan_info.stripping_ena) {
+		PMD_DRV_LOG(ERR,
+			    "Disable the VLAN stripping firstly\n");
+		return -EINVAL;
+	}
+
+	if (pvid > RTE_ETHER_MAX_VLAN_ID)
 		return -EINVAL;
 
 	memset(&vlan_offload, 0, sizeof(vlan_offload));
 
+	if (on)
+		vlan_offload.vlan_flags =
+				(VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED <<
+				 VIRTCHNL_DCF_VLAN_INSERT_MODE_S);
+	else
+		vlan_offload.vlan_flags =
+				(VIRTCHNL_DCF_VLAN_INSERT_DISABLE <<
+				 VIRTCHNL_DCF_VLAN_INSERT_MODE_S);
+
 	vlan_offload.vf_id = repr->vf_id;
-	vlan_offload.tpid = repr->port_vlan_info.tpid;
-	vlan_offload.vlan_flags = (VIRTCHNL_DCF_VLAN_TYPE_OUTER <<
-				   VIRTCHNL_DCF_VLAN_TYPE_S) |
-				  (VIRTCHNL_DCF_VLAN_INSERT_PORT_BASED <<
-				   VIRTCHNL_DCF_VLAN_INSERT_MODE_S);
-	vlan_offload.vlan_id = on ? pvid : 0;
+	vlan_offload.tpid = repr->outer_vlan_info.tpid;
+	vlan_offload.vlan_flags |= (VIRTCHNL_DCF_VLAN_TYPE_OUTER <<
+				    VIRTCHNL_DCF_VLAN_TYPE_S);
+	vlan_offload.vlan_id = pvid;
 
 	err = ice_dcf_vlan_offload_config(repr, &vlan_offload);
 	if (!err) {
 		if (on) {
-			repr->port_vlan_ena = true;
-			repr->port_vlan_info.vid = pvid;
+			repr->outer_vlan_info.port_vlan_ena = true;
+			repr->outer_vlan_info.vid = pvid;
 		} else {
-			repr->port_vlan_ena = false;
+			repr->outer_vlan_info.port_vlan_ena = false;
 		}
 	}
 
@@ -272,13 +352,32 @@ ice_dcf_vf_repr_vlan_tpid_set(struct rte_eth_dev *dev,
 		return -EINVAL;
 	}
 
-	repr->port_vlan_info.tpid = tpid;
+	repr->outer_vlan_info.tpid = tpid;
 
-	if (repr->port_vlan_ena)
+	if (repr->outer_vlan_info.port_vlan_ena) {
 		err = ice_dcf_vf_repr_vlan_pvid_set(dev,
-						    repr->port_vlan_info.vid,
+						    repr->outer_vlan_info.vid,
 						    true);
-	return err;
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				    "Failed to reset port VLAN : %d\n",
+				    err);
+			return err;
+		}
+	}
+
+	if (repr->outer_vlan_info.stripping_ena) {
+		err = ice_dcf_vf_repr_vlan_offload_set(dev,
+						       ETH_VLAN_STRIP_MASK);
+		if (err) {
+			PMD_DRV_LOG(ERR,
+				    "Failed to reset VLAN stripping : %d\n",
+				    err);
+			return err;
+		}
+	}
+
+	return 0;
 }
 
 static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = {
@@ -294,31 +393,33 @@ static const struct eth_dev_ops ice_dcf_vf_repr_dev_ops = {
 	.allmulticast_enable  = ice_dcf_vf_repr_allmulticast_enable,
 	.allmulticast_disable = ice_dcf_vf_repr_allmulticast_disable,
 	.link_update          = ice_dcf_vf_repr_link_update,
+	.vlan_offload_set     = ice_dcf_vf_repr_vlan_offload_set,
 	.vlan_pvid_set        = ice_dcf_vf_repr_vlan_pvid_set,
 	.vlan_tpid_set        = ice_dcf_vf_repr_vlan_tpid_set,
 };
 
 int
-ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param)
+ice_dcf_vf_repr_init(struct rte_eth_dev *vf_rep_eth_dev, void *init_param)
 {
-	struct ice_dcf_vf_repr *repr = ethdev->data->dev_private;
+	struct ice_dcf_vf_repr *repr = vf_rep_eth_dev->data->dev_private;
 	struct ice_dcf_vf_repr_param *param = init_param;
 
-	repr->dcf_adapter = param->adapter;
+	repr->dcf_eth_dev = param->dcf_eth_dev;
 	repr->switch_domain_id = param->switch_domain_id;
 	repr->vf_id = param->vf_id;
-	repr->port_vlan_ena = false;
-	repr->port_vlan_info.tpid = RTE_ETHER_TYPE_VLAN;
+	repr->outer_vlan_info.port_vlan_ena = false;
+	repr->outer_vlan_info.stripping_ena = false;
+	repr->outer_vlan_info.tpid = RTE_ETHER_TYPE_VLAN;
 
-	ethdev->dev_ops = &ice_dcf_vf_repr_dev_ops;
+	vf_rep_eth_dev->dev_ops = &ice_dcf_vf_repr_dev_ops;
 
-	ethdev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst;
-	ethdev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst;
+	vf_rep_eth_dev->rx_pkt_burst = ice_dcf_vf_repr_rx_burst;
+	vf_rep_eth_dev->tx_pkt_burst = ice_dcf_vf_repr_tx_burst;
 
-	ethdev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
-	ethdev->data->representor_id = repr->vf_id;
+	vf_rep_eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
+	vf_rep_eth_dev->data->representor_id = repr->vf_id;
 
-	ethdev->data->mac_addrs = &repr->mac_addr;
+	vf_rep_eth_dev->data->mac_addrs = &repr->mac_addr;
 
 	rte_eth_random_addr(repr->mac_addr.addr_bytes);
 
@@ -326,9 +427,56 @@ ice_dcf_vf_repr_init(struct rte_eth_dev *ethdev, void *init_param)
 }
 
 int
-ice_dcf_vf_repr_uninit(struct rte_eth_dev *ethdev)
+ice_dcf_vf_repr_uninit(struct rte_eth_dev *vf_rep_eth_dev)
 {
-	ethdev->data->mac_addrs = NULL;
+	vf_rep_eth_dev->data->mac_addrs = NULL;
 
 	return 0;
 }
+
+int
+ice_dcf_vf_repr_init_vlan(struct rte_eth_dev *vf_rep_eth_dev)
+{
+	struct ice_dcf_vf_repr *repr = vf_rep_eth_dev->data->dev_private;
+	int err;
+
+	err = ice_dcf_vf_repr_vlan_offload_set(vf_rep_eth_dev,
+					       ETH_VLAN_STRIP_MASK);
+	if (err) {
+		PMD_DRV_LOG(ERR, "Failed to set VLAN offload");
+		return err;
+	}
+
+	if (repr->outer_vlan_info.port_vlan_ena) {
+		err = ice_dcf_vf_repr_vlan_pvid_set(vf_rep_eth_dev,
+						    repr->outer_vlan_info.vid,
+						    true);
+		if (err) {
+			PMD_DRV_LOG(ERR, "Failed to enable port VLAN");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+void
+ice_dcf_vf_repr_stop_all(struct ice_dcf_adapter *dcf_adapter)
+{
+	uint16_t vf_id;
+	int ret;
+
+	if (!dcf_adapter->repr_infos)
+		return;
+
+	for (vf_id = 0; vf_id < dcf_adapter->real_hw.num_vfs; vf_id++) {
+		struct rte_eth_dev *vf_rep_eth_dev =
+				dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev;
+		if (!vf_rep_eth_dev || vf_rep_eth_dev->data->dev_started == 0)
+			continue;
+
+		ret = ice_dcf_vf_repr_dev_stop(vf_rep_eth_dev);
+		if (!ret)
+			vf_rep_eth_dev->data->dev_started = 0;
+	}
+}
-- 
2.30.0


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

* Re: [dpdk-dev] [PATCH v2] net/ice: refactor DCF VLAN handling
  2021-01-18 11:38 ` [dpdk-dev] [PATCH v2] " Haiyue Wang
@ 2021-01-19  6:27   ` Zhang, Qi Z
  0 siblings, 0 replies; 3+ messages in thread
From: Zhang, Qi Z @ 2021-01-19  6:27 UTC (permalink / raw)
  To: Wang, Haiyue, dev; +Cc: Yang, Qiming, Fu, Qi



> -----Original Message-----
> From: Wang, Haiyue <haiyue.wang@intel.com>
> Sent: Monday, January 18, 2021 7:38 PM
> To: dev@dpdk.org
> Cc: Yang, Qiming <qiming.yang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>;
> Fu, Qi <qi.fu@intel.com>; Wang, Haiyue <haiyue.wang@intel.com>
> Subject: [PATCH v2] net/ice: refactor DCF VLAN handling
> 
> Since DCF always configure the outer VLAN offloads for the target AVF, so
> rename the related variables to align with this design.
> 
> Also, the DCF needs to trace the AVF reset status to re-apply the VLAN offload
> setting, refactor the reset event handling to support this.
> 
> Change the VF representor API 'ethdev' parameter to 'vf_rep_eth_dev' to avoid
> introducing confusion with VF representor eth_dev ops name.
> 
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>

Acked-by: Qi Zhang <qi.z.zhang@intel.com>]

Applied to dpdk-next-net-intel.

Thanks
Qi


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

end of thread, other threads:[~2021-01-19  6:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-18  8:24 [dpdk-dev] [PATCH v1] net/ice: refactor DCF VLAN handling Haiyue Wang
2021-01-18 11:38 ` [dpdk-dev] [PATCH v2] " Haiyue Wang
2021-01-19  6:27   ` Zhang, Qi Z

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).