1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2023 Google LLC
3 */
4
5 #include "gve_rss.h"
6
7 int
gve_generate_rss_reta(struct rte_eth_dev * dev,struct gve_rss_config * config)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
gve_init_rss_config(struct gve_rss_config * gve_rss_conf,uint16_t key_size,uint16_t indir_size)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
gve_init_rss_config_from_priv(struct gve_priv * priv,struct gve_rss_config * gve_rss_conf)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
gve_free_rss_config(struct gve_rss_config * gve_rss_conf)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
gve_update_priv_rss_config(struct gve_priv * priv,struct gve_rss_config * config)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
gve_update_rss_key(struct gve_priv * priv,struct gve_rss_config * gve_rss_conf,struct rte_eth_rss_conf * rss_conf)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
gve_update_rss_hash_types(struct gve_priv * priv,struct gve_rss_config * gve_rss_conf,struct rte_eth_rss_conf * rss_conf)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
rte_to_gve_rss_hf(uint64_t rte_rss_hf,struct gve_rss_config * gve_rss_conf)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
gve_to_rte_rss_hf(uint16_t gve_rss_types,struct rte_eth_rss_conf * rss_conf)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