[dpdk-dev] [PATCH 2/4] ixgbe: VF RSS config on x550

Ananyev, Konstantin konstantin.ananyev at intel.com
Fri Oct 16 00:42:02 CEST 2015



> -----Original Message-----
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Wenzhuo Lu
> Sent: Monday, September 28, 2015 8:52 AM
> To: dev at dpdk.org
> Subject: [dpdk-dev] [PATCH 2/4] ixgbe: VF RSS config on x550
> 
> On x550, there're separate registers provided for VF RSS while on the other
> 10G NICs, for example, 82599, VF and PF share the same registers.
> This patch lets x550 use the VF specific registers when doing RSS configuration
> on VF. The behavior of other 10G NICs doesn't change.
> 
> Signed-off-by: Wenzhuo Lu <wenzhuo.lu at intel.com>
> ---
>  drivers/net/ixgbe/ixgbe_rxtx.c | 111 +++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 108 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index a746ae7..4a2d24a 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -2838,6 +2838,107 @@ ixgbe_rss_configure(struct rte_eth_dev *dev)
>  	ixgbe_hw_rss_hash_set(hw, &rss_conf);
>  }
> 
> +static void
> +ixgbevf_rss_disable_x550(struct rte_eth_dev *dev)
> +{
> +	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	uint32_t vfmrqc;
> +
> +	vfmrqc = IXGBE_READ_REG(hw, IXGBE_VFMRQC);
> +	vfmrqc &= ~IXGBE_MRQC_RSSEN;
> +	IXGBE_WRITE_REG(hw, IXGBE_VFMRQC, vfmrqc);
> +}
> +
> +static void
> +ixgbevf_hw_rss_hash_set_x550(struct ixgbe_hw *hw,
> +			struct rte_eth_rss_conf *rss_conf)
> +{
> +	uint8_t  *hash_key;
> +	uint32_t vfmrqc;
> +	uint32_t rss_key;
> +	uint64_t rss_hf;
> +	uint16_t i;
> +
> +	hash_key = rss_conf->rss_key;
> +	if (hash_key != NULL) {
> +		/* Fill in RSS hash key */
> +		for (i = 0; i < 10; i++) {
> +			rss_key  = hash_key[(i * 4)];
> +			rss_key |= hash_key[(i * 4) + 1] << 8;
> +			rss_key |= hash_key[(i * 4) + 2] << 16;
> +			rss_key |= hash_key[(i * 4) + 3] << 24;
> +			IXGBE_WRITE_REG_ARRAY(hw, IXGBE_VFRSSRK(0), i, rss_key);
> +		}
> +	}
> +
> +	/* Set configured hashing protocols in VFMRQC register */
> +	rss_hf = rss_conf->rss_hf;
> +	vfmrqc = IXGBE_MRQC_RSSEN; /* Enable RSS */
> +	if (rss_hf & ETH_RSS_IPV4)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV4;
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_TCP;
> +	if (rss_hf & ETH_RSS_IPV6)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV6;
> +	if (rss_hf & ETH_RSS_IPV6_EX)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX;
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_TCP;
> +	if (rss_hf & ETH_RSS_IPV6_TCP_EX)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_TCP;
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV4_UDP;
> +	if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_UDP;
> +	if (rss_hf & ETH_RSS_IPV6_UDP_EX)
> +		vfmrqc |= IXGBE_MRQC_RSS_FIELD_IPV6_EX_UDP;
> +	IXGBE_WRITE_REG(hw, IXGBE_VFMRQC, vfmrqc);
> +}

This function is identical to ixgbe_hw_rss_hash_set(), except the 2 HW register sets it updates:
IXGBE_VFMRQC vs IXGBE_MRQC and IXGBE_VFRSSRK(0) vs IXGBE_RSSRK(0).
Plus they botha re static functions, so why not addresses of these 2 HW registers as extra parameters
to the ixgbe_hw_rss_hash_set() and use it in all places.
That way you'll avoid quite big code duplication.

> +
> +static void
> +ixgbevf_rss_configure_x550(struct rte_eth_dev *dev)
> +{
> +	struct rte_eth_rss_conf rss_conf;
> +	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	uint32_t reta = 0;
> +	uint16_t i;
> +	uint16_t j;
> +
> +	PMD_INIT_FUNC_TRACE();
> +
> +	if (dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS) {
> +		ixgbevf_rss_disable_x550(dev);
> +		PMD_DRV_LOG(DEBUG, "RSS not configured\n");
> +		return;
> +	}
> +	/*
> +	 * Fill in redirection table
> +	 * The byte-swap is needed because NIC registers are in
> +	 * little-endian order.
> +	 */
> +	for (i = 0, j = 0; i < ETH_RSS_RETA_SIZE_64; i++, j++) {
> +		if (j == dev->data->nb_rx_queues)
> +			j = 0;
> +		reta = (reta << 8) | j;
> +		if ((i & 3) == 3)
> +			IXGBE_WRITE_REG(hw, IXGBE_VFRETA(i >> 2),
> +					rte_bswap32(reta));
> +	}
> +
> +	/*
> +	 * Configure the RSS key and the RSS protocols used to compute
> +	 * the RSS hash of input packets.
> +	 */
> +	rss_conf = dev->data->dev_conf.rx_adv_conf.rss_conf;
> +	if ((rss_conf.rss_hf & IXGBE_RSS_OFFLOAD_ALL) == 0) {
> +		ixgbevf_rss_disable_x550(dev);
> +		return;
> +	}
> +	if (rss_conf.rss_key == NULL)
> +		rss_conf.rss_key = rss_intel_key; /* Default hash key */
> +	ixgbevf_hw_rss_hash_set_x550(hw, &rss_conf);
> +}
> +

Same comment as above: > 90%of that function is just copy & paste of ixgbe_rss_configure().
Pls find a way to unify them and avoid unnecessary code duplication and growth.

>  #define NUM_VFTA_REGISTERS 128
>  #define NIC_RX_BUFFER_SIZE 0x200
>  #define X550_RX_BUFFER_SIZE 0x180
> @@ -3621,12 +3722,16 @@ ixgbe_alloc_rx_queue_mbufs(struct ixgbe_rx_queue *rxq)
>  static int
>  ixgbe_config_vf_rss(struct rte_eth_dev *dev)
>  {
> -	struct ixgbe_hw *hw;
> +	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
>  	uint32_t mrqc;
> 
> -	ixgbe_rss_configure(dev);
> +	if (hw->mac.type == ixgbe_mac_X550_vf ||
> +		hw->mac.type == ixgbe_mac_X550EM_x_vf) {
> +		ixgbevf_rss_configure_x550(dev);
> +		return 0;
> +	}
> 
> -	hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
> +	ixgbe_rss_configure(dev);
> 
>  	/* MRQC: enable VF RSS */
>  	mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
> --
> 1.9.3



More information about the dev mailing list