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 * Register a RSS key. 65 * 66 * @param priv 67 * Pointer to private structure. 68 * @param key 69 * Hash key to register. 70 * @param key_len 71 * Hash key length in bytes. 72 * 73 * @return 74 * 0 on success, errno value on failure. 75 */ 76 int 77 rss_hash_rss_conf_new_key(struct priv *priv, const uint8_t *key, 78 unsigned int key_len) 79 { 80 struct rte_eth_rss_conf *rss_conf; 81 82 rss_conf = rte_realloc(priv->rss_conf, 83 (sizeof(*rss_conf) + key_len), 84 0); 85 if (!rss_conf) 86 return ENOMEM; 87 rss_conf->rss_key = (void *)(rss_conf + 1); 88 rss_conf->rss_key_len = key_len; 89 memcpy(rss_conf->rss_key, key, key_len); 90 priv->rss_conf = rss_conf; 91 return 0; 92 } 93 94 /** 95 * DPDK callback to update the RSS hash configuration. 96 * 97 * @param dev 98 * Pointer to Ethernet device structure. 99 * @param[in] rss_conf 100 * RSS configuration data. 101 * 102 * @return 103 * 0 on success, negative errno value on failure. 104 */ 105 int 106 mlx5_rss_hash_update(struct rte_eth_dev *dev, 107 struct rte_eth_rss_conf *rss_conf) 108 { 109 struct priv *priv = dev->data->dev_private; 110 int err = 0; 111 112 priv_lock(priv); 113 114 assert(priv->rss_conf != NULL); 115 116 /* Apply configuration. */ 117 if (rss_conf->rss_key) 118 err = rss_hash_rss_conf_new_key(priv, 119 rss_conf->rss_key, 120 rss_conf->rss_key_len); 121 else 122 err = rss_hash_rss_conf_new_key(priv, 123 rss_hash_default_key, 124 rss_hash_default_key_len); 125 126 /* Store the configuration set into port configure. 127 * This will enable/disable hash RX queues associated to the protocols 128 * enabled/disabled by this update. */ 129 priv->dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf = 130 rss_conf->rss_hf; 131 priv_unlock(priv); 132 assert(err >= 0); 133 return -err; 134 } 135 136 /** 137 * DPDK callback to get the RSS hash configuration. 138 * 139 * @param dev 140 * Pointer to Ethernet device structure. 141 * @param[in, out] rss_conf 142 * RSS configuration data. 143 * 144 * @return 145 * 0 on success, negative errno value on failure. 146 */ 147 int 148 mlx5_rss_hash_conf_get(struct rte_eth_dev *dev, 149 struct rte_eth_rss_conf *rss_conf) 150 { 151 struct priv *priv = dev->data->dev_private; 152 153 priv_lock(priv); 154 155 assert(priv->rss_conf != NULL); 156 157 if (rss_conf->rss_key && 158 rss_conf->rss_key_len >= priv->rss_conf->rss_key_len) 159 memcpy(rss_conf->rss_key, 160 priv->rss_conf->rss_key, 161 priv->rss_conf->rss_key_len); 162 rss_conf->rss_key_len = priv->rss_conf->rss_key_len; 163 /* FIXME: rss_hf should be more specific. */ 164 rss_conf->rss_hf = ETH_RSS_PROTO_MASK; 165 166 priv_unlock(priv); 167 return 0; 168 } 169