[dpdk-dev] [PATCH v2 5/5] i40evf: support of configurable crc stripping in VF

Helin Zhang helin.zhang at intel.com
Sun Sep 14 16:48:29 CEST 2014


Configurable crc stripping is supported in DPDK PF host,
while not in Linux PF host. Two functions have been
defined to talk with the those PF hosts respectively.

v2 changes:
* Put configuring crc stripping in VF into a single patch.

Signed-off-by: Helin Zhang <helin.zhang at intel.com>
Reviewed-by: Jingjing Wu <jingjing.wu at intel.com>
Reviewed-by: Jing Chen <jing.d.chen at intel.com>
---
 lib/librte_pmd_i40e/i40e_ethdev_vf.c | 133 +++++++++++++++++++++++++++--------
 1 file changed, 102 insertions(+), 31 deletions(-)

diff --git a/lib/librte_pmd_i40e/i40e_ethdev_vf.c b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
index 113bff8..af5a0f3 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev_vf.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
@@ -523,8 +523,9 @@ i40evf_config_vlan_pvid(struct rte_eth_dev *dev,
 	return err;
 }
 
+/* It configures VSI queues without extra configuration */
 static int
-i40evf_configure_queues(struct rte_eth_dev *dev)
+i40evf_configure_vsi_queues(struct rte_eth_dev *dev)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
 	struct i40e_rx_queue **rxq =
@@ -533,13 +534,13 @@ i40evf_configure_queues(struct rte_eth_dev *dev)
 		(struct i40e_tx_queue **)dev->data->tx_queues;
 	struct i40e_virtchnl_vsi_queue_config_info *vc_vqci;
 	struct i40e_virtchnl_queue_pair_info *vc_qpi;
-	int size, i, nb_qp, ret, num_rxq, num_txq;
 	struct vf_cmd_info args;
-	struct rte_pktmbuf_pool_private *mbp_priv;
+	int size, i, nb_qp, ret;
 
 	nb_qp = vf->num_queue_pairs;
-	size = sizeof(*vc_vqci) + sizeof(*vc_qpi) * nb_qp;
-	vc_vqci = rte_zmalloc("vc_vqci", size, 0);
+	size = sizeof(struct i40e_virtchnl_vsi_queue_config_info) +
+		sizeof(struct i40e_virtchnl_queue_pair_info) * nb_qp;
+	vc_vqci = rte_zmalloc("queue_info", size, 0);
 	if (!vc_vqci) {
 		PMD_DRV_LOG(ERR, "Failed to allocate memory for VF "
 					"configuring queues\n");
@@ -547,62 +548,132 @@ i40evf_configure_queues(struct rte_eth_dev *dev)
 	}
 	vc_vqci->vsi_id = vf->vsi_res->vsi_id;
 	vc_vqci->num_queue_pairs = nb_qp;
-	vc_qpi = vc_vqci->qpair;
 
-	num_rxq = dev->data->nb_rx_queues;
-	num_txq = dev->data->nb_tx_queues;
-	/*
-	 * PF host driver required to configure queues in pairs, which means
-	 * rxq_num should equals to txq_num. The actual usage won't always
-	 * work that way. The solution is fills 0 with HW ring option in case
-	 * they are not equal.
-	 */
-	for (i = 0; i < nb_qp; i++) {
-		/*Fill TX info */
+	for (i = 0, vc_qpi = vc_vqci->qpair; i < nb_qp; i++, vc_qpi++) {
 		vc_qpi->txq.vsi_id = vc_vqci->vsi_id;
 		vc_qpi->txq.queue_id = i;
-		if (i < num_txq) {
+		if (i < dev->data->nb_tx_queues) {
 			vc_qpi->txq.ring_len = txq[i]->nb_tx_desc;
 			vc_qpi->txq.dma_ring_addr = txq[i]->tx_ring_phys_addr;
-		} else {
-			vc_qpi->txq.ring_len = 0;
-			vc_qpi->txq.dma_ring_addr = 0;
 		}
 
-		/* Fill RX info */
 		vc_qpi->rxq.vsi_id = vc_vqci->vsi_id;
 		vc_qpi->rxq.queue_id = i;
 		vc_qpi->rxq.max_pkt_size = vf->max_pkt_len;
-		if (i < num_rxq) {
+		if (i < dev->data->nb_rx_queues) {
+			struct rte_pktmbuf_pool_private *mbp_priv;
+
+			vc_qpi->rxq.ring_len = rxq[i]->nb_rx_desc;
+			vc_qpi->rxq.dma_ring_addr = rxq[i]->rx_ring_phys_addr;
 			mbp_priv = rte_mempool_get_priv(rxq[i]->mp);
 			vc_qpi->rxq.databuffer_size =
 				mbp_priv->mbuf_data_room_size -
 					RTE_PKTMBUF_HEADROOM;
+		}
+	}
+	memset(&args, 0, sizeof(args));
+	args.ops = I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES;
+	args.in_args = (uint8_t *)vc_vqci;
+	args.in_args_size = size;
+	args.out_buffer = cmd_result_buffer;
+	args.out_size = I40E_AQ_BUF_SZ;
+	ret = i40evf_execute_vf_cmd(dev, &args);
+	if (ret)
+		PMD_DRV_LOG(ERR, "Failed to execute command of "
+			"I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES\n");
+	rte_free(vc_vqci);
+
+	return ret;
+}
+
+/* It configures VSI queues with extra configuration of crc stripping */
+static int
+i40evf_configure_vsi_queues_ex(struct rte_eth_dev *dev)
+{
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+	struct i40e_rx_queue **rxq =
+		(struct i40e_rx_queue **)dev->data->rx_queues;
+	struct i40e_tx_queue **txq =
+		(struct i40e_tx_queue **)dev->data->tx_queues;
+	struct i40e_virtchnl_vsi_queue_config_info *vc_vqci;
+	struct i40e_virtchnl_queue_pair_info *vc_qpi;
+	struct i40e_virtchnl_queue_pair_extra_info *vc_qpei;
+	struct vf_cmd_info args;
+	int size, i, nb_qp, ret;
+
+	nb_qp = vf->num_queue_pairs;
+	size = sizeof(struct i40e_virtchnl_vsi_queue_config_info) +
+		sizeof(struct i40e_virtchnl_queue_pair_info) * nb_qp +
+		sizeof(struct i40e_virtchnl_queue_pair_extra_info) * nb_qp;
+	vc_vqci = rte_zmalloc("queue_info", size, 0);
+	if (!vc_vqci) {
+		PMD_DRV_LOG(ERR, "Failed to allocate memory for VF "
+					"configuring queues\n");
+		return -ENOMEM;
+	}
+	vc_vqci->vsi_id = vf->vsi_res->vsi_id;
+	vc_vqci->num_queue_pairs = nb_qp;
+	vc_qpi = vc_vqci->qpair;
+	vc_qpei = (struct i40e_virtchnl_queue_pair_extra_info *)
+		(((uint8_t *)vc_vqci->qpair) +
+		sizeof(struct i40e_virtchnl_queue_pair_info) * nb_qp);
+
+	for (i = 0; i < nb_qp; i++, vc_qpi++, vc_qpei++) {
+		vc_qpi->txq.vsi_id = vc_vqci->vsi_id;
+		vc_qpi->txq.queue_id = i;
+		if (i < dev->data->nb_tx_queues) {
+			vc_qpi->txq.ring_len = txq[i]->nb_tx_desc;
+			vc_qpi->txq.dma_ring_addr = txq[i]->tx_ring_phys_addr;
+		}
+		vc_qpi->rxq.vsi_id = vc_vqci->vsi_id;
+		vc_qpi->rxq.queue_id = i;
+		vc_qpi->rxq.max_pkt_size = vf->max_pkt_len;
+		if (i < dev->data->nb_rx_queues) {
+			struct rte_pktmbuf_pool_private *mbp_priv;
+
 			vc_qpi->rxq.ring_len = rxq[i]->nb_rx_desc;
 			vc_qpi->rxq.dma_ring_addr = rxq[i]->rx_ring_phys_addr;
-		} else {
-			vc_qpi->rxq.ring_len = 0;
-			vc_qpi->rxq.dma_ring_addr = 0;
-			vc_qpi->rxq.databuffer_size = 0;
+			mbp_priv = rte_mempool_get_priv(rxq[i]->mp);
+			vc_qpi->rxq.databuffer_size =
+				mbp_priv->mbuf_data_room_size -
+					RTE_PKTMBUF_HEADROOM;
+			/*
+			 * It adds extra info for configuring VSI queues, which
+			 * is needed to enable the configurable crc stripping
+			 * in VF.
+			 */
+			vc_qpei->crcstrip =
+				dev->data->dev_conf.rxmode.hw_strip_crc;
 		}
-		vc_qpi++;
 	}
-
-	args.ops = I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES;
+	memset(&args, 0, sizeof(args));
+	args.ops =
+		(enum i40e_virtchnl_ops)I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EX;
 	args.in_args = (uint8_t *)vc_vqci;
 	args.in_args_size = size;
 	args.out_buffer = cmd_result_buffer;
 	args.out_size = I40E_AQ_BUF_SZ;
 	ret = i40evf_execute_vf_cmd(dev, &args);
 	if (ret)
-		PMD_DRV_LOG(ERR, "fail to execute command "
-				"OP_CONFIG_VSI_QUEUES\n");
+		PMD_DRV_LOG(ERR, "Failed to execute command of "
+			"I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EX\n");
 	rte_free(vc_vqci);
 
 	return ret;
 }
 
 static int
+i40evf_configure_queues(struct rte_eth_dev *dev)
+{
+	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+	if (vf->host_is_dpdk) /* To support DPDK PF host */
+		return i40evf_configure_vsi_queues_ex(dev);
+	else /* To support Linux PF host */
+		return i40evf_configure_vsi_queues(dev);
+}
+
+static int
 i40evf_config_irq_map(struct rte_eth_dev *dev)
 {
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-- 
1.8.1.4



More information about the dev mailing list