1 /*- 2 * BSD LICENSE 3 * 4 * Copyright 2015 6WIND S.A. 5 * Copyright 2015 Mellanox. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of 6WIND S.A. nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <stddef.h> 35 #include <stdint.h> 36 #include <errno.h> 37 #include <string.h> 38 #include <assert.h> 39 40 /* Verbs header. */ 41 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ 42 #ifdef PEDANTIC 43 #pragma GCC diagnostic ignored "-pedantic" 44 #endif 45 #include <infiniband/verbs.h> 46 #ifdef PEDANTIC 47 #pragma GCC diagnostic error "-pedantic" 48 #endif 49 50 /* DPDK headers don't like -pedantic. */ 51 #ifdef PEDANTIC 52 #pragma GCC diagnostic ignored "-pedantic" 53 #endif 54 #include <rte_malloc.h> 55 #include <rte_ethdev.h> 56 #ifdef PEDANTIC 57 #pragma GCC diagnostic error "-pedantic" 58 #endif 59 60 #include "mlx5.h" 61 #include "mlx5_rxtx.h" 62 63 /** 64 * Get a RSS configuration hash key. 65 * 66 * @param priv 67 * Pointer to private structure. 68 * @param rss_hf 69 * RSS hash functions configuration must be retrieved for. 70 * 71 * @return 72 * Pointer to a RSS configuration structure or NULL if rss_hf cannot 73 * be matched. 74 */ 75 static struct rte_eth_rss_conf * 76 rss_hash_get(struct priv *priv, uint64_t rss_hf) 77 { 78 unsigned int i; 79 80 for (i = 0; (i != hash_rxq_init_n); ++i) { 81 uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf; 82 83 if (!(dpdk_rss_hf & rss_hf)) 84 continue; 85 return (*priv->rss_conf)[i]; 86 } 87 return NULL; 88 } 89 90 /** 91 * Register a RSS key. 92 * 93 * @param priv 94 * Pointer to private structure. 95 * @param key 96 * Hash key to register. 97 * @param key_len 98 * Hash key length in bytes. 99 * @param rss_hf 100 * RSS hash functions the provided key applies to. 101 * 102 * @return 103 * 0 on success, errno value on failure. 104 */ 105 int 106 rss_hash_rss_conf_new_key(struct priv *priv, const uint8_t *key, 107 unsigned int key_len, uint64_t rss_hf) 108 { 109 unsigned int i; 110 111 for (i = 0; (i != hash_rxq_init_n); ++i) { 112 struct rte_eth_rss_conf *rss_conf; 113 uint64_t dpdk_rss_hf = hash_rxq_init[i].dpdk_rss_hf; 114 115 if (!(dpdk_rss_hf & rss_hf)) 116 continue; 117 rss_conf = rte_realloc((*priv->rss_conf)[i], 118 (sizeof(*rss_conf) + key_len), 119 0); 120 if (!rss_conf) 121 return ENOMEM; 122 rss_conf->rss_key = (void *)(rss_conf + 1); 123 rss_conf->rss_key_len = key_len; 124 rss_conf->rss_hf = dpdk_rss_hf; 125 memcpy(rss_conf->rss_key, key, key_len); 126 (*priv->rss_conf)[i] = rss_conf; 127 } 128 return 0; 129 } 130 131 /** 132 * DPDK callback to update the RSS hash configuration. 133 * 134 * @param dev 135 * Pointer to Ethernet device structure. 136 * @param[in] rss_conf 137 * RSS configuration data. 138 * 139 * @return 140 * 0 on success, negative errno value on failure. 141 */ 142 int 143 mlx5_rss_hash_update(struct rte_eth_dev *dev, 144 struct rte_eth_rss_conf *rss_conf) 145 { 146 struct priv *priv = dev->data->dev_private; 147 int err = 0; 148 149 priv_lock(priv); 150 151 assert(priv->rss_conf != NULL); 152 153 /* Apply configuration. */ 154 if (rss_conf->rss_key) 155 err = rss_hash_rss_conf_new_key(priv, 156 rss_conf->rss_key, 157 rss_conf->rss_key_len, 158 rss_conf->rss_hf); 159 else 160 err = rss_hash_rss_conf_new_key(priv, 161 rss_hash_default_key, 162 rss_hash_default_key_len, 163 ETH_RSS_PROTO_MASK); 164 165 /* Store the configuration set into port configure. 166 * This will enable/disable hash RX queues associated to the protocols 167 * enabled/disabled by this update. */ 168 priv->dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 169 rss_conf->rss_hf; 170 priv_unlock(priv); 171 assert(err >= 0); 172 return -err; 173 } 174 175 /** 176 * DPDK callback to get the RSS hash configuration. 177 * 178 * @param dev 179 * Pointer to Ethernet device structure. 180 * @param[in, out] rss_conf 181 * RSS configuration data. 182 * 183 * @return 184 * 0 on success, negative errno value on failure. 185 */ 186 int 187 mlx5_rss_hash_conf_get(struct rte_eth_dev *dev, 188 struct rte_eth_rss_conf *rss_conf) 189 { 190 struct priv *priv = dev->data->dev_private; 191 struct rte_eth_rss_conf *priv_rss_conf; 192 193 priv_lock(priv); 194 195 assert(priv->rss_conf != NULL); 196 197 priv_rss_conf = rss_hash_get(priv, rss_conf->rss_hf); 198 if (!priv_rss_conf) { 199 rss_conf->rss_hf = 0; 200 priv_unlock(priv); 201 return -EINVAL; 202 } 203 if (rss_conf->rss_key && 204 rss_conf->rss_key_len >= priv_rss_conf->rss_key_len) 205 memcpy(rss_conf->rss_key, 206 priv_rss_conf->rss_key, 207 priv_rss_conf->rss_key_len); 208 rss_conf->rss_key_len = priv_rss_conf->rss_key_len; 209 rss_conf->rss_hf = priv_rss_conf->rss_hf; 210 211 priv_unlock(priv); 212 return 0; 213 } 214