1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2023 Google LLC 3 */ 4 5 #include "gve_rss.h" 6 7 int 8 gve_generate_rss_reta(struct rte_eth_dev *dev, struct gve_rss_config *config) 9 { 10 int i; 11 if (!config || !config->indir) 12 return -EINVAL; 13 14 for (i = 0; i < config->indir_size; i++) 15 config->indir[i] = i % dev->data->nb_rx_queues; 16 17 return 0; 18 } 19 20 21 int 22 gve_init_rss_config(struct gve_rss_config *gve_rss_conf, 23 uint16_t key_size, uint16_t indir_size) 24 { 25 int err; 26 27 gve_rss_conf->alg = GVE_RSS_HASH_TOEPLITZ; 28 29 gve_rss_conf->key_size = key_size; 30 gve_rss_conf->key = rte_zmalloc("rss key", 31 key_size * sizeof(*gve_rss_conf->key), 32 RTE_CACHE_LINE_SIZE); 33 if (!gve_rss_conf->key) 34 return -ENOMEM; 35 36 gve_rss_conf->indir_size = indir_size; 37 gve_rss_conf->indir = rte_zmalloc("rss reta", 38 indir_size * sizeof(*gve_rss_conf->indir), 39 RTE_CACHE_LINE_SIZE); 40 if (!gve_rss_conf->indir) { 41 err = -ENOMEM; 42 goto err_with_key; 43 } 44 45 return 0; 46 err_with_key: 47 rte_free(gve_rss_conf->key); 48 return err; 49 } 50 51 int 52 gve_init_rss_config_from_priv(struct gve_priv *priv, 53 struct gve_rss_config *gve_rss_conf) 54 { 55 int err = gve_init_rss_config(gve_rss_conf, priv->rss_config.key_size, 56 priv->rss_config.indir_size); 57 if (err) 58 return err; 59 60 gve_rss_conf->hash_types = priv->rss_config.hash_types; 61 gve_rss_conf->alg = priv->rss_config.alg; 62 memcpy(gve_rss_conf->key, priv->rss_config.key, 63 gve_rss_conf->key_size * sizeof(*gve_rss_conf->key)); 64 memcpy(gve_rss_conf->indir, priv->rss_config.indir, 65 gve_rss_conf->indir_size * sizeof(*gve_rss_conf->indir)); 66 67 return 0; 68 } 69 70 void 71 gve_free_rss_config(struct gve_rss_config *gve_rss_conf) 72 { 73 rte_free(gve_rss_conf->indir); 74 gve_rss_conf->indir = NULL; 75 rte_free(gve_rss_conf->key); 76 gve_rss_conf->key = NULL; 77 } 78 79 int 80 gve_update_priv_rss_config(struct gve_priv *priv, struct gve_rss_config *config) 81 { 82 struct gve_rss_config *priv_config = &priv->rss_config; 83 int key_bytes, indir_bytes; 84 85 if (!config) 86 return -EINVAL; 87 if (config->key_size == 0 || !config->key) 88 return -EINVAL; 89 if (config->indir_size == 0 || !config->indir) 90 return -EINVAL; 91 92 priv_config->hash_types = config->hash_types; 93 priv_config->alg = config->alg; 94 95 priv_config->key_size = config->key_size; 96 key_bytes = priv_config->key_size * sizeof(*priv_config->key); 97 if (!priv_config->key) 98 priv_config->key = rte_zmalloc("priv rss key", key_bytes, 99 RTE_CACHE_LINE_SIZE); 100 else 101 priv_config->key = rte_realloc(priv_config->key, key_bytes, 102 RTE_CACHE_LINE_SIZE); 103 if (!priv_config->key) 104 return -ENOMEM; 105 106 priv_config->indir_size = config->indir_size; 107 indir_bytes = priv_config->indir_size * sizeof(*priv_config->indir); 108 if (!priv_config->indir) 109 priv_config->indir = rte_zmalloc("priv rss reta", indir_bytes, 110 RTE_CACHE_LINE_SIZE); 111 else 112 priv_config->indir = rte_realloc(priv_config->indir, 113 indir_bytes, RTE_CACHE_LINE_SIZE); 114 115 if (!priv_config->indir) 116 return -ENOMEM; 117 118 memcpy(priv_config->indir, config->indir, 119 config->indir_size * sizeof(*priv_config->indir)); 120 memcpy(priv_config->key, config->key, 121 config->key_size * sizeof(*priv_config->key)); 122 123 return 0; 124 } 125 126 int 127 gve_update_rss_key(struct gve_priv *priv, struct gve_rss_config *gve_rss_conf, 128 struct rte_eth_rss_conf *rss_conf) 129 { 130 if (rss_conf->rss_key_len && rss_conf->rss_key) { 131 gve_rss_conf->key_size = rss_conf->rss_key_len; 132 memcpy(gve_rss_conf->key, rss_conf->rss_key, 133 gve_rss_conf->key_size * sizeof(*gve_rss_conf->key)); 134 } else if (priv->rss_config.key_size && priv->rss_config.key) { 135 gve_rss_conf->key_size = priv->rss_config.key_size; 136 memcpy(gve_rss_conf->key, priv->rss_config.key, 137 gve_rss_conf->key_size * sizeof(*gve_rss_conf->key)); 138 } else { 139 PMD_DRV_LOG(ERR, "RSS key must be set as part of initial RSS " 140 "configuration."); 141 return -EINVAL; 142 } 143 return 0; 144 } 145 146 int 147 gve_update_rss_hash_types(struct gve_priv *priv, 148 struct gve_rss_config *gve_rss_conf, struct rte_eth_rss_conf *rss_conf) 149 { 150 /* Initialize to 0 before modifying. */ 151 gve_rss_conf->hash_types = 0; 152 if (rss_conf->rss_hf) 153 rte_to_gve_rss_hf(rss_conf->rss_hf, gve_rss_conf); 154 else if (priv->rss_config.key_size && priv->rss_config.key) 155 gve_rss_conf->hash_types = priv->rss_config.hash_types; 156 else 157 gve_rss_conf->hash_types = GVE_RSS_OFFLOAD_DEFAULT; 158 return 0; 159 } 160 161 void 162 rte_to_gve_rss_hf(uint64_t rte_rss_hf, struct gve_rss_config *gve_rss_conf) 163 { 164 if (rte_rss_hf & RTE_ETH_RSS_IPV4) 165 gve_rss_conf->hash_types |= GVE_RSS_HASH_IPV4; 166 if (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) 167 gve_rss_conf->hash_types |= GVE_RSS_HASH_TCPV4; 168 if (rte_rss_hf & RTE_ETH_RSS_IPV6) 169 gve_rss_conf->hash_types |= GVE_RSS_HASH_IPV6; 170 if (rte_rss_hf & RTE_ETH_RSS_IPV6_EX) 171 gve_rss_conf->hash_types |= GVE_RSS_HASH_IPV6_EX; 172 if (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) 173 gve_rss_conf->hash_types |= GVE_RSS_HASH_TCPV6; 174 if (rte_rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) 175 gve_rss_conf->hash_types |= GVE_RSS_HASH_TCPV6_EX; 176 if (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) 177 gve_rss_conf->hash_types |= GVE_RSS_HASH_UDPV4; 178 if (rte_rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) 179 gve_rss_conf->hash_types |= GVE_RSS_HASH_UDPV6; 180 if (rte_rss_hf & RTE_ETH_RSS_IPV6_UDP_EX) 181 gve_rss_conf->hash_types |= GVE_RSS_HASH_UDPV6_EX; 182 } 183 184 void 185 gve_to_rte_rss_hf(uint16_t gve_rss_types, struct rte_eth_rss_conf *rss_conf) 186 { 187 if (gve_rss_types & GVE_RSS_HASH_IPV4) 188 rss_conf->rss_hf |= RTE_ETH_RSS_IPV4; 189 if (gve_rss_types & GVE_RSS_HASH_TCPV4) 190 rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP; 191 if (gve_rss_types & GVE_RSS_HASH_IPV6) 192 rss_conf->rss_hf |= RTE_ETH_RSS_IPV6; 193 if (gve_rss_types & GVE_RSS_HASH_IPV6_EX) 194 rss_conf->rss_hf |= RTE_ETH_RSS_IPV6_EX; 195 if (gve_rss_types & GVE_RSS_HASH_TCPV6) 196 rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP; 197 if (gve_rss_types & GVE_RSS_HASH_TCPV6_EX) 198 rss_conf->rss_hf |= RTE_ETH_RSS_IPV6_TCP_EX; 199 if (gve_rss_types & GVE_RSS_HASH_UDPV4) 200 rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP; 201 if (gve_rss_types & GVE_RSS_HASH_UDPV6) 202 rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP; 203 if (gve_rss_types & GVE_RSS_HASH_UDPV6_EX) 204 rss_conf->rss_hf |= RTE_ETH_RSS_IPV6_UDP_EX; 205 } 206 207