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