xref: /dpdk/drivers/net/mlx5/mlx5_rss.c (revision 0573873d5b7dda5ffb8b1e6733497df115a29073)
12f97422eSNelio Laranjeiro /*-
22f97422eSNelio Laranjeiro  *   BSD LICENSE
32f97422eSNelio Laranjeiro  *
42f97422eSNelio Laranjeiro  *   Copyright 2015 6WIND S.A.
52f97422eSNelio Laranjeiro  *   Copyright 2015 Mellanox.
62f97422eSNelio Laranjeiro  *
72f97422eSNelio Laranjeiro  *   Redistribution and use in source and binary forms, with or without
82f97422eSNelio Laranjeiro  *   modification, are permitted provided that the following conditions
92f97422eSNelio Laranjeiro  *   are met:
102f97422eSNelio Laranjeiro  *
112f97422eSNelio Laranjeiro  *     * Redistributions of source code must retain the above copyright
122f97422eSNelio Laranjeiro  *       notice, this list of conditions and the following disclaimer.
132f97422eSNelio Laranjeiro  *     * Redistributions in binary form must reproduce the above copyright
142f97422eSNelio Laranjeiro  *       notice, this list of conditions and the following disclaimer in
152f97422eSNelio Laranjeiro  *       the documentation and/or other materials provided with the
162f97422eSNelio Laranjeiro  *       distribution.
172f97422eSNelio Laranjeiro  *     * Neither the name of 6WIND S.A. nor the names of its
182f97422eSNelio Laranjeiro  *       contributors may be used to endorse or promote products derived
192f97422eSNelio Laranjeiro  *       from this software without specific prior written permission.
202f97422eSNelio Laranjeiro  *
212f97422eSNelio Laranjeiro  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
222f97422eSNelio Laranjeiro  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
232f97422eSNelio Laranjeiro  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
242f97422eSNelio Laranjeiro  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
252f97422eSNelio Laranjeiro  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
262f97422eSNelio Laranjeiro  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
272f97422eSNelio Laranjeiro  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
282f97422eSNelio Laranjeiro  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
292f97422eSNelio Laranjeiro  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
302f97422eSNelio Laranjeiro  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
312f97422eSNelio Laranjeiro  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
322f97422eSNelio Laranjeiro  */
332f97422eSNelio Laranjeiro 
342f97422eSNelio Laranjeiro #include <stddef.h>
352f97422eSNelio Laranjeiro #include <stdint.h>
362f97422eSNelio Laranjeiro #include <errno.h>
372f97422eSNelio Laranjeiro #include <string.h>
382f97422eSNelio Laranjeiro #include <assert.h>
392f97422eSNelio Laranjeiro 
402f97422eSNelio Laranjeiro /* Verbs header. */
412f97422eSNelio Laranjeiro /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
422f97422eSNelio Laranjeiro #ifdef PEDANTIC
432f97422eSNelio Laranjeiro #pragma GCC diagnostic ignored "-pedantic"
442f97422eSNelio Laranjeiro #endif
452f97422eSNelio Laranjeiro #include <infiniband/verbs.h>
462f97422eSNelio Laranjeiro #ifdef PEDANTIC
472f97422eSNelio Laranjeiro #pragma GCC diagnostic error "-pedantic"
482f97422eSNelio Laranjeiro #endif
492f97422eSNelio Laranjeiro 
502f97422eSNelio Laranjeiro /* DPDK headers don't like -pedantic. */
512f97422eSNelio Laranjeiro #ifdef PEDANTIC
522f97422eSNelio Laranjeiro #pragma GCC diagnostic ignored "-pedantic"
532f97422eSNelio Laranjeiro #endif
542f97422eSNelio Laranjeiro #include <rte_malloc.h>
552f97422eSNelio Laranjeiro #include <rte_ethdev.h>
562f97422eSNelio Laranjeiro #ifdef PEDANTIC
572f97422eSNelio Laranjeiro #pragma GCC diagnostic error "-pedantic"
582f97422eSNelio Laranjeiro #endif
592f97422eSNelio Laranjeiro 
602f97422eSNelio Laranjeiro #include "mlx5.h"
612f97422eSNelio Laranjeiro #include "mlx5_rxtx.h"
622f97422eSNelio Laranjeiro 
632f97422eSNelio Laranjeiro /**
64*0573873dSNelio Laranjeiro  * Get a RSS configuration hash key.
65*0573873dSNelio Laranjeiro  *
66*0573873dSNelio Laranjeiro  * @param priv
67*0573873dSNelio Laranjeiro  *   Pointer to private structure.
68*0573873dSNelio Laranjeiro  * @param rss_hf
69*0573873dSNelio Laranjeiro  *   RSS hash functions configuration must be retrieved for.
70*0573873dSNelio Laranjeiro  *
71*0573873dSNelio Laranjeiro  * @return
72*0573873dSNelio Laranjeiro  *   Pointer to a RSS configuration structure or NULL if rss_hf cannot
73*0573873dSNelio Laranjeiro  *   be matched.
74*0573873dSNelio Laranjeiro  */
75*0573873dSNelio Laranjeiro static struct rte_eth_rss_conf *
76*0573873dSNelio Laranjeiro rss_hash_get(struct priv *priv, uint64_t rss_hf)
77*0573873dSNelio Laranjeiro {
78*0573873dSNelio Laranjeiro 	unsigned int i;
79*0573873dSNelio Laranjeiro 
80*0573873dSNelio Laranjeiro 	for (i = 0; (i != hash_rxq_init_n); ++i) {
81*0573873dSNelio Laranjeiro 		uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf;
82*0573873dSNelio Laranjeiro 
83*0573873dSNelio Laranjeiro 		if (!(dpdk_rss_hf & rss_hf))
84*0573873dSNelio Laranjeiro 			continue;
85*0573873dSNelio Laranjeiro 		return (*priv->rss_conf)[i];
86*0573873dSNelio Laranjeiro 	}
87*0573873dSNelio Laranjeiro 	return NULL;
88*0573873dSNelio Laranjeiro }
89*0573873dSNelio Laranjeiro 
90*0573873dSNelio Laranjeiro /**
912f97422eSNelio Laranjeiro  * Register a RSS key.
922f97422eSNelio Laranjeiro  *
932f97422eSNelio Laranjeiro  * @param priv
942f97422eSNelio Laranjeiro  *   Pointer to private structure.
952f97422eSNelio Laranjeiro  * @param key
962f97422eSNelio Laranjeiro  *   Hash key to register.
972f97422eSNelio Laranjeiro  * @param key_len
982f97422eSNelio Laranjeiro  *   Hash key length in bytes.
99*0573873dSNelio Laranjeiro  * @param rss_hf
100*0573873dSNelio Laranjeiro  *   RSS hash functions the provided key applies to.
1012f97422eSNelio Laranjeiro  *
1022f97422eSNelio Laranjeiro  * @return
1032f97422eSNelio Laranjeiro  *   0 on success, errno value on failure.
1042f97422eSNelio Laranjeiro  */
1052f97422eSNelio Laranjeiro int
1062f97422eSNelio Laranjeiro rss_hash_rss_conf_new_key(struct priv *priv, const uint8_t *key,
107*0573873dSNelio Laranjeiro 			  unsigned int key_len, uint64_t rss_hf)
1082f97422eSNelio Laranjeiro {
109*0573873dSNelio Laranjeiro 	unsigned int i;
1102f97422eSNelio Laranjeiro 
111*0573873dSNelio Laranjeiro 	for (i = 0; (i != hash_rxq_init_n); ++i) {
112*0573873dSNelio Laranjeiro 		struct rte_eth_rss_conf *rss_conf;
113*0573873dSNelio Laranjeiro 		uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf;
114*0573873dSNelio Laranjeiro 
115*0573873dSNelio Laranjeiro 		if (!(dpdk_rss_hf & rss_hf))
116*0573873dSNelio Laranjeiro 			continue;
117*0573873dSNelio Laranjeiro 		rss_conf = rte_realloc((*priv->rss_conf)[i],
1182f97422eSNelio Laranjeiro 				       (sizeof(*rss_conf) + key_len),
1192f97422eSNelio Laranjeiro 				       0);
1202f97422eSNelio Laranjeiro 		if (!rss_conf)
1212f97422eSNelio Laranjeiro 			return ENOMEM;
1222f97422eSNelio Laranjeiro 		rss_conf->rss_key = (void *)(rss_conf + 1);
1232f97422eSNelio Laranjeiro 		rss_conf->rss_key_len = key_len;
124*0573873dSNelio Laranjeiro 		rss_conf->rss_hf = dpdk_rss_hf;
1252f97422eSNelio Laranjeiro 		memcpy(rss_conf->rss_key, key, key_len);
126*0573873dSNelio Laranjeiro 		(*priv->rss_conf)[i] = rss_conf;
127*0573873dSNelio Laranjeiro 	}
1282f97422eSNelio Laranjeiro 	return 0;
1292f97422eSNelio Laranjeiro }
1302f97422eSNelio Laranjeiro 
1312f97422eSNelio Laranjeiro /**
1322f97422eSNelio Laranjeiro  * DPDK callback to update the RSS hash configuration.
1332f97422eSNelio Laranjeiro  *
1342f97422eSNelio Laranjeiro  * @param dev
1352f97422eSNelio Laranjeiro  *   Pointer to Ethernet device structure.
1362f97422eSNelio Laranjeiro  * @param[in] rss_conf
1372f97422eSNelio Laranjeiro  *   RSS configuration data.
1382f97422eSNelio Laranjeiro  *
1392f97422eSNelio Laranjeiro  * @return
1402f97422eSNelio Laranjeiro  *   0 on success, negative errno value on failure.
1412f97422eSNelio Laranjeiro  */
1422f97422eSNelio Laranjeiro int
1432f97422eSNelio Laranjeiro mlx5_rss_hash_update(struct rte_eth_dev *dev,
1442f97422eSNelio Laranjeiro 		     struct rte_eth_rss_conf *rss_conf)
1452f97422eSNelio Laranjeiro {
1462f97422eSNelio Laranjeiro 	struct priv *priv = dev->data->dev_private;
1472f97422eSNelio Laranjeiro 	int err = 0;
1482f97422eSNelio Laranjeiro 
1492f97422eSNelio Laranjeiro 	priv_lock(priv);
1502f97422eSNelio Laranjeiro 
1512f97422eSNelio Laranjeiro 	assert(priv->rss_conf != NULL);
1522f97422eSNelio Laranjeiro 
1532f97422eSNelio Laranjeiro 	/* Apply configuration. */
1542f97422eSNelio Laranjeiro 	if (rss_conf->rss_key)
1552f97422eSNelio Laranjeiro 		err = rss_hash_rss_conf_new_key(priv,
1562f97422eSNelio Laranjeiro 						rss_conf->rss_key,
157*0573873dSNelio Laranjeiro 						rss_conf->rss_key_len,
158*0573873dSNelio Laranjeiro 						rss_conf->rss_hf);
1592f97422eSNelio Laranjeiro 	else
1602f97422eSNelio Laranjeiro 		err = rss_hash_rss_conf_new_key(priv,
1612f97422eSNelio Laranjeiro 						rss_hash_default_key,
162*0573873dSNelio Laranjeiro 						rss_hash_default_key_len,
163*0573873dSNelio Laranjeiro 						ETH_RSS_PROTO_MASK);
1642f97422eSNelio Laranjeiro 
1652f97422eSNelio Laranjeiro 	/* Store the configuration set into port configure.
1662f97422eSNelio Laranjeiro 	 * This will enable/disable hash RX queues associated to the protocols
1672f97422eSNelio Laranjeiro 	 * enabled/disabled by this update. */
1682f97422eSNelio Laranjeiro 	priv->dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
1692f97422eSNelio Laranjeiro 		rss_conf->rss_hf;
1702f97422eSNelio Laranjeiro 	priv_unlock(priv);
1712f97422eSNelio Laranjeiro 	assert(err >= 0);
1722f97422eSNelio Laranjeiro 	return -err;
1732f97422eSNelio Laranjeiro }
1742f97422eSNelio Laranjeiro 
1752f97422eSNelio Laranjeiro /**
1762f97422eSNelio Laranjeiro  * DPDK callback to get the RSS hash configuration.
1772f97422eSNelio Laranjeiro  *
1782f97422eSNelio Laranjeiro  * @param dev
1792f97422eSNelio Laranjeiro  *   Pointer to Ethernet device structure.
1802f97422eSNelio Laranjeiro  * @param[in, out] rss_conf
1812f97422eSNelio Laranjeiro  *   RSS configuration data.
1822f97422eSNelio Laranjeiro  *
1832f97422eSNelio Laranjeiro  * @return
1842f97422eSNelio Laranjeiro  *   0 on success, negative errno value on failure.
1852f97422eSNelio Laranjeiro  */
1862f97422eSNelio Laranjeiro int
1872f97422eSNelio Laranjeiro mlx5_rss_hash_conf_get(struct rte_eth_dev *dev,
1882f97422eSNelio Laranjeiro 		       struct rte_eth_rss_conf *rss_conf)
1892f97422eSNelio Laranjeiro {
1902f97422eSNelio Laranjeiro 	struct priv *priv = dev->data->dev_private;
191*0573873dSNelio Laranjeiro 	struct rte_eth_rss_conf *priv_rss_conf;
1922f97422eSNelio Laranjeiro 
1932f97422eSNelio Laranjeiro 	priv_lock(priv);
1942f97422eSNelio Laranjeiro 
1952f97422eSNelio Laranjeiro 	assert(priv->rss_conf != NULL);
1962f97422eSNelio Laranjeiro 
197*0573873dSNelio Laranjeiro 	priv_rss_conf = rss_hash_get(priv, rss_conf->rss_hf);
198*0573873dSNelio Laranjeiro 	if (!priv_rss_conf) {
199*0573873dSNelio Laranjeiro 		rss_conf->rss_hf = 0;
200*0573873dSNelio Laranjeiro 		priv_unlock(priv);
201*0573873dSNelio Laranjeiro 		return -EINVAL;
202*0573873dSNelio Laranjeiro 	}
2032f97422eSNelio Laranjeiro 	if (rss_conf->rss_key &&
204*0573873dSNelio Laranjeiro 	    rss_conf->rss_key_len >= priv_rss_conf->rss_key_len)
2052f97422eSNelio Laranjeiro 		memcpy(rss_conf->rss_key,
206*0573873dSNelio Laranjeiro 		       priv_rss_conf->rss_key,
207*0573873dSNelio Laranjeiro 		       priv_rss_conf->rss_key_len);
208*0573873dSNelio Laranjeiro 	rss_conf->rss_key_len = priv_rss_conf->rss_key_len;
209*0573873dSNelio Laranjeiro 	rss_conf->rss_hf = priv_rss_conf->rss_hf;
2102f97422eSNelio Laranjeiro 
2112f97422eSNelio Laranjeiro 	priv_unlock(priv);
2122f97422eSNelio Laranjeiro 	return 0;
2132f97422eSNelio Laranjeiro }
214