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