[dpdk-dev] [PATCH v6 10/13] ixgbe: support VMDq RSS in non-SRIOV environment
Ananyev, Konstantin
konstantin.ananyev at intel.com
Wed Oct 21 12:05:54 CEST 2015
Hi
> -----Original Message-----
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Yuanhan Liu
> Sent: Friday, October 09, 2015 6:46 AM
> To: dev at dpdk.org
> Cc: Michael S. Tsirkin; marcel at redhat.com
> Subject: [dpdk-dev] [PATCH v6 10/13] ixgbe: support VMDq RSS in non-SRIOV environment
>
> From: Changchun Ouyang <changchun.ouyang at intel.com>
>
> In non-SRIOV environment, VMDq RSS could be enabled by MRQC register.
> In theory, the queue number per pool could be 2 or 4, but only 2 queues
> are available due to HW limitation, the same limit also exists in Linux
> ixgbe driver.
>
> Signed-off-by: Changchun Ouyang <changchun.ouyang at intel.com>
> Signed-off-by: Yuanhan Liu <yuanhan.liu at linux.intel.com>
> ---
> drivers/net/ixgbe/ixgbe_rxtx.c | 86 +++++++++++++++++++++++++++++++++++-------
> lib/librte_ether/rte_ethdev.c | 11 ++++++
> 2 files changed, 84 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index a598a72..e502fe8 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -3445,16 +3445,16 @@ void ixgbe_configure_dcb(struct rte_eth_dev *dev)
> return;
> }
>
> -/*
> - * VMDq only support for 10 GbE NIC.
> +/**
> + * Config pool for VMDq on 10 GbE NIC.
> */
> static void
> -ixgbe_vmdq_rx_hw_configure(struct rte_eth_dev *dev)
> +ixgbe_vmdq_pool_configure(struct rte_eth_dev *dev)
> {
> struct rte_eth_vmdq_rx_conf *cfg;
> struct ixgbe_hw *hw;
> enum rte_eth_nb_pools num_pools;
> - uint32_t mrqc, vt_ctl, vlanctrl;
> + uint32_t vt_ctl, vlanctrl;
> uint32_t vmolr = 0;
> int i;
>
> @@ -3463,12 +3463,6 @@ ixgbe_vmdq_rx_hw_configure(struct rte_eth_dev *dev)
> cfg = &dev->data->dev_conf.rx_adv_conf.vmdq_rx_conf;
> num_pools = cfg->nb_queue_pools;
>
> - ixgbe_rss_disable(dev);
> -
> - /* MRQC: enable vmdq */
> - mrqc = IXGBE_MRQC_VMDQEN;
> - IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
> -
> /* PFVTCTL: turn on virtualisation and set the default pool */
> vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN;
> if (cfg->enable_default_pool)
> @@ -3534,7 +3528,29 @@ ixgbe_vmdq_rx_hw_configure(struct rte_eth_dev *dev)
> IXGBE_WRITE_FLUSH(hw);
> }
>
> -/*
> +/**
> + * VMDq only support for 10 GbE NIC.
> + */
> +static void
> +ixgbe_vmdq_rx_hw_configure(struct rte_eth_dev *dev)
> +{
> + struct ixgbe_hw *hw;
> + uint32_t mrqc;
> +
> + PMD_INIT_FUNC_TRACE();
> + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +
> + ixgbe_rss_disable(dev);
> +
> + /* MRQC: enable vmdq */
> + mrqc = IXGBE_MRQC_VMDQEN;
> + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
> + IXGBE_WRITE_FLUSH(hw);
> +
> + ixgbe_vmdq_pool_configure(dev);
> +}
> +
> +/**
> * ixgbe_dcb_config_tx_hw_config - Configure general VMDq TX parameters
> * @hw: pointer to hardware structure
> */
> @@ -3639,6 +3655,41 @@ ixgbe_config_vf_rss(struct rte_eth_dev *dev)
> }
>
> static int
> +ixgbe_config_vmdq_rss(struct rte_eth_dev *dev)
> +{
> + struct ixgbe_hw *hw;
> + uint32_t mrqc;
> +
> + ixgbe_rss_configure(dev);
> +
> + hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +
> + /* MRQC: enable VMDQ RSS */
> + mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
> + mrqc &= ~IXGBE_MRQC_MRQE_MASK;
> +
> + switch (RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool) {
> + case 2:
> + mrqc |= IXGBE_MRQC_VMDQRSS64EN;
> + break;
> +
> + case 4:
> + mrqc |= IXGBE_MRQC_VMDQRSS32EN;
> + break;
> +
> + default:
> + PMD_INIT_LOG(ERR, "Invalid pool number in non-IOV mode with VMDQ RSS");
> + return -EINVAL;
> + }
> +
> + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
> +
> + ixgbe_vmdq_pool_configure(dev);
> +
> + return 0;
> +}
So ixgbe_config_vmdq_rss() checks nb_q_per_pool value, and might return an error if the value is invalid.
Though this return value seems just ignored by ixgbe_dev_mq_rx_configure() below.
Probably, it is better to move nb_q_per_pool value checking into rte_eth_dev_check_mq_mode(),
as is done for other modes?
I know it is no ideal, as it probably should be HW specific check,
but seems anyway better than just ignoring the error.
Konstantin
> +
> +static int
> ixgbe_config_vf_default(struct rte_eth_dev *dev)
> {
> struct ixgbe_hw *hw =
> @@ -3694,6 +3745,10 @@ ixgbe_dev_mq_rx_configure(struct rte_eth_dev *dev)
> ixgbe_vmdq_rx_hw_configure(dev);
> break;
>
> + case ETH_MQ_RX_VMDQ_RSS:
> + ixgbe_config_vmdq_rss(dev);
> + break;
> +
> case ETH_MQ_RX_NONE:
> /* if mq_mode is none, disable rss mode.*/
> default: ixgbe_rss_disable(dev);
> @@ -4186,6 +4241,8 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
>
> /* Setup RX queues */
> for (i = 0; i < dev->data->nb_rx_queues; i++) {
> + uint32_t psrtype = 0;
> +
> rxq = dev->data->rx_queues[i];
>
> /*
> @@ -4213,12 +4270,10 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
> if (rx_conf->header_split) {
> if (hw->mac.type == ixgbe_mac_82599EB) {
> /* Must setup the PSRTYPE register */
> - uint32_t psrtype;
> psrtype = IXGBE_PSRTYPE_TCPHDR |
> IXGBE_PSRTYPE_UDPHDR |
> IXGBE_PSRTYPE_IPV4HDR |
> IXGBE_PSRTYPE_IPV6HDR;
> - IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(rxq->reg_idx), psrtype);
> }
> srrctl = ((rx_conf->split_hdr_size <<
> IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
> @@ -4228,6 +4283,11 @@ ixgbe_dev_rx_init(struct rte_eth_dev *dev)
> #endif
> srrctl = IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
>
> + /* Set RQPL for VMDQ RSS according to max Rx queue */
> + psrtype |= (RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool >> 1) <<
> + IXGBE_PSRTYPE_RQPL_SHIFT;
> + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(rxq->reg_idx), psrtype);
> +
> /* Set if packets are dropped when no descriptors available */
> if (rxq->drop_en)
> srrctl |= IXGBE_SRRCTL_DROP_EN;
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index f593f6e..fe9dc5c 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1067,6 +1067,17 @@ rte_eth_dev_check_mq_mode(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
> return -EINVAL;
> }
> }
> +
> + if (dev_conf->rxmode.mq_mode == ETH_MQ_RX_VMDQ_RSS) {
> + uint32_t nb_queue_pools =
> + dev_conf->rx_adv_conf.vmdq_rx_conf.nb_queue_pools;
> + struct rte_eth_dev_info dev_info;
> +
> + rte_eth_dev_info_get(port_id, &dev_info);
> + dev->data->dev_conf.rxmode.mq_mode = ETH_MQ_RX_VMDQ_RSS;
> + RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool =
> + dev_info.vmdq_queue_num / nb_queue_pools;
> + }
> }
> return 0;
> }
> --
> 1.9.0
More information about the dev
mailing list