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