xref: /dpdk/drivers/common/cnxk/roc_nix_rss.c (revision 29a8df5cb664feb6f182c07868c49c0f5c9a4c46)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 
5 #include "roc_api.h"
6 #include "roc_priv.h"
7 
8 void
9 roc_nix_rss_key_default_fill(struct roc_nix *roc_nix,
10 			     uint8_t key[ROC_NIX_RSS_KEY_LEN])
11 {
12 	PLT_SET_USED(roc_nix);
13 	const uint8_t default_key[ROC_NIX_RSS_KEY_LEN] = {
14 		0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED,
15 		0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
16 		0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED,
17 		0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD,
18 		0xFE, 0xED, 0x0B, 0xAD, 0xFE, 0xED, 0x0B, 0xAD};
19 
20 	memcpy(key, default_key, ROC_NIX_RSS_KEY_LEN);
21 }
22 
23 void
24 roc_nix_rss_key_set(struct roc_nix *roc_nix,
25 		    const uint8_t key[ROC_NIX_RSS_KEY_LEN])
26 {
27 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
28 	const uint64_t *keyptr;
29 	uint64_t val;
30 	uint32_t idx;
31 
32 	keyptr = (const uint64_t *)key;
33 	for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) {
34 		val = plt_cpu_to_be_64(keyptr[idx]);
35 		plt_write64(val, nix->base + NIX_LF_RX_SECRETX(idx));
36 	}
37 }
38 
39 void
40 roc_nix_rss_key_get(struct roc_nix *roc_nix, uint8_t key[ROC_NIX_RSS_KEY_LEN])
41 {
42 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
43 	uint64_t *keyptr = (uint64_t *)key;
44 	uint64_t val;
45 	uint32_t idx;
46 
47 	for (idx = 0; idx < (ROC_NIX_RSS_KEY_LEN >> 3); idx++) {
48 		val = plt_read64(nix->base + NIX_LF_RX_SECRETX(idx));
49 		keyptr[idx] = plt_be_to_cpu_64(val);
50 	}
51 }
52 
53 static int
54 nix_cn9k_rss_reta_set(struct nix *nix, uint8_t group,
55 		      uint16_t reta[ROC_NIX_RSS_RETA_MAX], uint8_t lock_rx_ctx)
56 {
57 	struct mbox *mbox = mbox_get((&nix->dev)->mbox);
58 	struct nix_aq_enq_req *req;
59 	uint16_t idx;
60 	int rc;
61 
62 	for (idx = 0; idx < nix->reta_sz; idx++) {
63 		req = mbox_alloc_msg_nix_aq_enq(mbox);
64 		if (!req) {
65 			/* The shared memory buffer can be full.
66 			 * Flush it and retry
67 			 */
68 			rc = mbox_process(mbox);
69 			if (rc < 0)
70 				goto exit;
71 			req = mbox_alloc_msg_nix_aq_enq(mbox);
72 			if (!req) {
73 				rc = NIX_ERR_NO_MEM;
74 				goto exit;
75 			}
76 		}
77 		req->rss.rq = reta[idx];
78 		/* Fill AQ info */
79 		req->qidx = (group * nix->reta_sz) + idx;
80 		req->ctype = NIX_AQ_CTYPE_RSS;
81 		req->op = NIX_AQ_INSTOP_INIT;
82 
83 		if (!lock_rx_ctx)
84 			continue;
85 
86 		req = mbox_alloc_msg_nix_aq_enq(mbox);
87 		if (!req) {
88 			/* The shared memory buffer can be full.
89 			 * Flush it and retry
90 			 */
91 			rc = mbox_process(mbox);
92 			if (rc < 0)
93 				goto exit;
94 			req = mbox_alloc_msg_nix_aq_enq(mbox);
95 			if (!req) {
96 				rc = NIX_ERR_NO_MEM;
97 				goto exit;
98 			}
99 		}
100 		req->rss.rq = reta[idx];
101 		/* Fill AQ info */
102 		req->qidx = (group * nix->reta_sz) + idx;
103 		req->ctype = NIX_AQ_CTYPE_RSS;
104 		req->op = NIX_AQ_INSTOP_LOCK;
105 	}
106 
107 	rc = mbox_process(mbox);
108 	if (rc < 0)
109 		goto exit;
110 
111 	rc = 0;
112 exit:
113 	mbox_put(mbox);
114 	return rc;
115 }
116 
117 static int
118 nix_cn10k_rss_reta_set(struct nix *nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX],
119 		       uint8_t lock_rx_ctx, uint16_t pf_func)
120 {
121 	struct mbox *mbox = mbox_get((&nix->dev)->mbox);
122 	struct nix_cn10k_aq_enq_req *req;
123 	uint16_t idx;
124 	int rc;
125 
126 	for (idx = 0; idx < nix->reta_sz; idx++) {
127 		req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
128 		if (!req) {
129 			/* The shared memory buffer can be full.
130 			 * Flush it and retry
131 			 */
132 			rc = mbox_process(mbox);
133 			if (rc < 0)
134 				goto exit;
135 			req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
136 			if (!req) {
137 				rc =  NIX_ERR_NO_MEM;
138 				goto exit;
139 			}
140 		}
141 		if (pf_func)
142 			req->hdr.pcifunc = pf_func;
143 
144 		req->rss.rq = reta[idx];
145 		/* Fill AQ info */
146 		req->qidx = (group * nix->reta_sz) + idx;
147 		req->ctype = NIX_AQ_CTYPE_RSS;
148 		req->op = NIX_AQ_INSTOP_INIT;
149 
150 		if (!lock_rx_ctx)
151 			continue;
152 
153 		req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
154 		if (!req) {
155 			/* The shared memory buffer can be full.
156 			 * Flush it and retry
157 			 */
158 			rc = mbox_process(mbox);
159 			if (rc < 0)
160 				goto exit;
161 			req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
162 			if (!req) {
163 				rc =  NIX_ERR_NO_MEM;
164 				goto exit;
165 			}
166 		}
167 		if (pf_func)
168 			req->hdr.pcifunc = pf_func;
169 		req->rss.rq = reta[idx];
170 		/* Fill AQ info */
171 		req->qidx = (group * nix->reta_sz) + idx;
172 		req->ctype = NIX_AQ_CTYPE_RSS;
173 		req->op = NIX_AQ_INSTOP_LOCK;
174 	}
175 
176 	rc = mbox_process(mbox);
177 	if (rc < 0)
178 		goto exit;
179 
180 	rc = 0;
181 exit:
182 	mbox_put(mbox);
183 	return rc;
184 }
185 
186 static int
187 nix_rss_reta_set(struct nix *nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX],
188 		 uint8_t lock_rx_ctx, uint16_t pf_func)
189 {
190 	struct mbox *mbox = mbox_get((&nix->dev)->mbox);
191 	struct nix_cn20k_aq_enq_req *req;
192 	uint16_t idx;
193 	int rc;
194 
195 	for (idx = 0; idx < nix->reta_sz; idx++) {
196 		req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
197 		if (!req) {
198 			/* The shared memory buffer can be full.
199 			 * Flush it and retry
200 			 */
201 			rc = mbox_process(mbox);
202 			if (rc < 0)
203 				goto exit;
204 			req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
205 			if (!req) {
206 				rc =  NIX_ERR_NO_MEM;
207 				goto exit;
208 			}
209 		}
210 		req->rss.rq = reta[idx];
211 		/* Fill AQ info */
212 		req->qidx = (group * nix->reta_sz) + idx;
213 		req->ctype = NIX_AQ_CTYPE_RSS;
214 		req->op = NIX_AQ_INSTOP_INIT;
215 
216 		if (!lock_rx_ctx)
217 			continue;
218 
219 		req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
220 		if (!req) {
221 			/* The shared memory buffer can be full.
222 			 * Flush it and retry
223 			 */
224 			rc = mbox_process(mbox);
225 			if (rc < 0)
226 				goto exit;
227 			req = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
228 			if (!req) {
229 				rc =  NIX_ERR_NO_MEM;
230 				goto exit;
231 			}
232 		}
233 		if (pf_func)
234 			req->hdr.pcifunc = pf_func;
235 		req->rss.rq = reta[idx];
236 		/* Fill AQ info */
237 		req->qidx = (group * nix->reta_sz) + idx;
238 		req->ctype = NIX_AQ_CTYPE_RSS;
239 		req->op = NIX_AQ_INSTOP_LOCK;
240 	}
241 
242 	rc = mbox_process(mbox);
243 	if (rc < 0)
244 		goto exit;
245 
246 	rc = 0;
247 exit:
248 	mbox_put(mbox);
249 	return rc;
250 }
251 
252 int
253 nix_rss_reta_pffunc_set(struct roc_nix *roc_nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX],
254 			uint16_t pf_func)
255 {
256 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
257 	int rc;
258 
259 	if (group >= ROC_NIX_RSS_GRPS)
260 		return NIX_ERR_PARAM;
261 
262 	if (roc_model_is_cn9k())
263 		rc = nix_cn9k_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx);
264 	else if (roc_model_is_cn10k())
265 		rc = nix_cn10k_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx, pf_func);
266 	else
267 		rc = nix_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx, pf_func);
268 	if (rc)
269 		return rc;
270 
271 	memcpy(&nix->reta[group], reta, sizeof(uint16_t) * ROC_NIX_RSS_RETA_MAX);
272 	return 0;
273 }
274 
275 int
276 roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX])
277 {
278 	return nix_rss_reta_pffunc_set(roc_nix, group, reta, 0);
279 }
280 
281 int
282 roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group, uint16_t reta[ROC_NIX_RSS_RETA_MAX])
283 {
284 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
285 
286 	if (group >= ROC_NIX_RSS_GRPS)
287 		return NIX_ERR_PARAM;
288 
289 	memcpy(reta, &nix->reta[group], sizeof(uint16_t) * ROC_NIX_RSS_RETA_MAX);
290 	return 0;
291 }
292 
293 int
294 nix_rss_flowkey_pffunc_set(struct roc_nix *roc_nix, uint8_t *alg_idx, uint32_t flowkey,
295 			   uint8_t group, int mcam_index, uint16_t pf_func)
296 {
297 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
298 	struct nix_rss_flowkey_cfg_rsp *rss_rsp;
299 	struct mbox *mbox = mbox_get((&nix->dev)->mbox);
300 	struct nix_rss_flowkey_cfg *cfg;
301 	int rc = -ENOSPC;
302 
303 	if (group >= ROC_NIX_RSS_GRPS) {
304 		rc = NIX_ERR_PARAM;
305 		goto exit;
306 	}
307 
308 	cfg = mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
309 	if (cfg == NULL)
310 		goto exit;
311 	if (pf_func)
312 		cfg->hdr.pcifunc = pf_func;
313 
314 	cfg->flowkey_cfg = flowkey;
315 	cfg->mcam_index = mcam_index; /* -1 indicates default group */
316 	cfg->group = group;	      /* 0 is default group */
317 	rc = mbox_process_msg(mbox, (void *)&rss_rsp);
318 	if (rc)
319 		goto exit;
320 	if (alg_idx)
321 		*alg_idx = rss_rsp->alg_idx;
322 
323 exit:
324 	mbox_put(mbox);
325 	return rc;
326 }
327 
328 int
329 roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx, uint32_t flowkey, uint8_t group,
330 			int mcam_index)
331 {
332 	return nix_rss_flowkey_pffunc_set(roc_nix, alg_idx, flowkey, group, mcam_index, 0);
333 }
334 
335 int
336 roc_nix_rss_default_setup(struct roc_nix *roc_nix, uint32_t flowkey)
337 {
338 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
339 	uint16_t idx, qcnt = nix->nb_rx_queues;
340 	uint16_t reta[ROC_NIX_RSS_RETA_MAX];
341 	uint8_t key[ROC_NIX_RSS_KEY_LEN];
342 	uint8_t alg_idx;
343 	int rc;
344 
345 	roc_nix_rss_key_default_fill(roc_nix, key);
346 	roc_nix_rss_key_set(roc_nix, key);
347 
348 	/* Update default RSS RETA */
349 	for (idx = 0; idx < nix->reta_sz; idx++)
350 		reta[idx] = idx % qcnt;
351 	rc = roc_nix_rss_reta_set(roc_nix, 0, reta);
352 	if (rc) {
353 		plt_err("Failed to set RSS reta table rc=%d", rc);
354 		goto fail;
355 	}
356 
357 	/* Update the default flowkey */
358 	rc = roc_nix_rss_flowkey_set(roc_nix, &alg_idx, flowkey,
359 				     ROC_NIX_RSS_GROUP_DEFAULT, -1);
360 	if (rc) {
361 		plt_err("Failed to set RSS flowkey rc=%d", rc);
362 		goto fail;
363 	}
364 
365 	nix->rss_alg_idx = alg_idx;
366 fail:
367 	return rc;
368 }
369