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

Reply via email to