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