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
roc_nix_rss_key_default_fill(struct roc_nix * roc_nix,uint8_t key[ROC_NIX_RSS_KEY_LEN])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
roc_nix_rss_key_set(struct roc_nix * roc_nix,const uint8_t key[ROC_NIX_RSS_KEY_LEN])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
roc_nix_rss_key_get(struct roc_nix * roc_nix,uint8_t key[ROC_NIX_RSS_KEY_LEN])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
nix_cn9k_rss_reta_set(struct nix * nix,uint8_t group,uint16_t reta[ROC_NIX_RSS_RETA_MAX],uint8_t lock_rx_ctx)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
nix_rss_reta_set(struct nix * nix,uint8_t group,uint16_t reta[ROC_NIX_RSS_RETA_MAX],uint8_t lock_rx_ctx)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
roc_nix_rss_reta_set(struct roc_nix * roc_nix,uint8_t group,uint16_t reta[ROC_NIX_RSS_RETA_MAX])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
roc_nix_rss_reta_get(struct roc_nix * roc_nix,uint8_t group,uint16_t reta[ROC_NIX_RSS_RETA_MAX])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
roc_nix_rss_flowkey_set(struct roc_nix * roc_nix,uint8_t * alg_idx,uint32_t flowkey,uint8_t group,int mcam_index)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
roc_nix_rss_default_setup(struct roc_nix * roc_nix,uint32_t flowkey)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