xref: /dpdk/drivers/net/gve/gve_rss.c (revision d6ac6f456398b0ab797b6edae96f7baf4d118c16)
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