xref: /dpdk/drivers/common/cnxk/roc_nix_rss.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
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 = (&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 				return rc;
71 			req = mbox_alloc_msg_nix_aq_enq(mbox);
72 			if (!req)
73 				return NIX_ERR_NO_MEM;
74 		}
75 		req->rss.rq = reta[idx];
76 		/* Fill AQ info */
77 		req->qidx = (group * nix->reta_sz) + idx;
78 		req->ctype = NIX_AQ_CTYPE_RSS;
79 		req->op = NIX_AQ_INSTOP_INIT;
80 
81 		if (!lock_rx_ctx)
82 			continue;
83 
84 		req = mbox_alloc_msg_nix_aq_enq(mbox);
85 		if (!req) {
86 			/* The shared memory buffer can be full.
87 			 * Flush it and retry
88 			 */
89 			rc = mbox_process(mbox);
90 			if (rc < 0)
91 				return rc;
92 			req = mbox_alloc_msg_nix_aq_enq(mbox);
93 			if (!req)
94 				return NIX_ERR_NO_MEM;
95 		}
96 		req->rss.rq = reta[idx];
97 		/* Fill AQ info */
98 		req->qidx = (group * nix->reta_sz) + idx;
99 		req->ctype = NIX_AQ_CTYPE_RSS;
100 		req->op = NIX_AQ_INSTOP_LOCK;
101 	}
102 
103 	rc = mbox_process(mbox);
104 	if (rc < 0)
105 		return rc;
106 
107 	return 0;
108 }
109 
110 static int
111 nix_rss_reta_set(struct nix *nix, uint8_t group,
112 		 uint16_t reta[ROC_NIX_RSS_RETA_MAX], uint8_t lock_rx_ctx)
113 {
114 	struct mbox *mbox = (&nix->dev)->mbox;
115 	struct nix_cn10k_aq_enq_req *req;
116 	uint16_t idx;
117 	int rc;
118 
119 	for (idx = 0; idx < nix->reta_sz; idx++) {
120 		req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
121 		if (!req) {
122 			/* The shared memory buffer can be full.
123 			 * Flush it and retry
124 			 */
125 			rc = mbox_process(mbox);
126 			if (rc < 0)
127 				return rc;
128 			req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
129 			if (!req)
130 				return NIX_ERR_NO_MEM;
131 		}
132 		req->rss.rq = reta[idx];
133 		/* Fill AQ info */
134 		req->qidx = (group * nix->reta_sz) + idx;
135 		req->ctype = NIX_AQ_CTYPE_RSS;
136 		req->op = NIX_AQ_INSTOP_INIT;
137 
138 		if (!lock_rx_ctx)
139 			continue;
140 
141 		req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
142 		if (!req) {
143 			/* The shared memory buffer can be full.
144 			 * Flush it and retry
145 			 */
146 			rc = mbox_process(mbox);
147 			if (rc < 0)
148 				return rc;
149 			req = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
150 			if (!req)
151 				return NIX_ERR_NO_MEM;
152 		}
153 		req->rss.rq = reta[idx];
154 		/* Fill AQ info */
155 		req->qidx = (group * nix->reta_sz) + idx;
156 		req->ctype = NIX_AQ_CTYPE_RSS;
157 		req->op = NIX_AQ_INSTOP_LOCK;
158 	}
159 
160 	rc = mbox_process(mbox);
161 	if (rc < 0)
162 		return rc;
163 
164 	return 0;
165 }
166 
167 int
168 roc_nix_rss_reta_set(struct roc_nix *roc_nix, uint8_t group,
169 		     uint16_t reta[ROC_NIX_RSS_RETA_MAX])
170 {
171 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
172 	int rc;
173 
174 	if (group >= ROC_NIX_RSS_GRPS)
175 		return NIX_ERR_PARAM;
176 
177 	if (roc_model_is_cn9k())
178 		rc = nix_cn9k_rss_reta_set(nix, group, reta,
179 					   roc_nix->lock_rx_ctx);
180 	else
181 		rc = nix_rss_reta_set(nix, group, reta, roc_nix->lock_rx_ctx);
182 	if (rc)
183 		return rc;
184 
185 	memcpy(&nix->reta[group], reta, ROC_NIX_RSS_RETA_MAX);
186 	return 0;
187 }
188 
189 int
190 roc_nix_rss_reta_get(struct roc_nix *roc_nix, uint8_t group,
191 		     uint16_t reta[ROC_NIX_RSS_RETA_MAX])
192 {
193 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
194 
195 	if (group >= ROC_NIX_RSS_GRPS)
196 		return NIX_ERR_PARAM;
197 
198 	memcpy(reta, &nix->reta[group], ROC_NIX_RSS_RETA_MAX);
199 	return 0;
200 }
201 
202 int
203 roc_nix_rss_flowkey_set(struct roc_nix *roc_nix, uint8_t *alg_idx,
204 			uint32_t flowkey, uint8_t group, int mcam_index)
205 {
206 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
207 	struct nix_rss_flowkey_cfg_rsp *rss_rsp;
208 	struct mbox *mbox = (&nix->dev)->mbox;
209 	struct nix_rss_flowkey_cfg *cfg;
210 	int rc = -ENOSPC;
211 
212 	if (group >= ROC_NIX_RSS_GRPS)
213 		return NIX_ERR_PARAM;
214 
215 	cfg = mbox_alloc_msg_nix_rss_flowkey_cfg(mbox);
216 	if (cfg == NULL)
217 		return rc;
218 	cfg->flowkey_cfg = flowkey;
219 	cfg->mcam_index = mcam_index; /* -1 indicates default group */
220 	cfg->group = group;	      /* 0 is default group */
221 	rc = mbox_process_msg(mbox, (void *)&rss_rsp);
222 	if (rc)
223 		return rc;
224 	if (alg_idx)
225 		*alg_idx = rss_rsp->alg_idx;
226 
227 	return rc;
228 }
229 
230 int
231 roc_nix_rss_default_setup(struct roc_nix *roc_nix, uint32_t flowkey)
232 {
233 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
234 	uint16_t idx, qcnt = nix->nb_rx_queues;
235 	uint16_t reta[ROC_NIX_RSS_RETA_MAX];
236 	uint8_t key[ROC_NIX_RSS_KEY_LEN];
237 	uint8_t alg_idx;
238 	int rc;
239 
240 	roc_nix_rss_key_default_fill(roc_nix, key);
241 	roc_nix_rss_key_set(roc_nix, key);
242 
243 	/* Update default RSS RETA */
244 	for (idx = 0; idx < nix->reta_sz; idx++)
245 		reta[idx] = idx % qcnt;
246 	rc = roc_nix_rss_reta_set(roc_nix, 0, reta);
247 	if (rc) {
248 		plt_err("Failed to set RSS reta table rc=%d", rc);
249 		goto fail;
250 	}
251 
252 	/* Update the default flowkey */
253 	rc = roc_nix_rss_flowkey_set(roc_nix, &alg_idx, flowkey,
254 				     ROC_NIX_RSS_GROUP_DEFAULT, -1);
255 	if (rc) {
256 		plt_err("Failed to set RSS flowkey rc=%d", rc);
257 		goto fail;
258 	}
259 
260 	nix->rss_alg_idx = alg_idx;
261 fail:
262 	return rc;
263 }
264