Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <math.h>
6 : :
7 : : #include "roc_api.h"
8 : : #include "roc_priv.h"
9 : :
10 : : /* Default SQB slack per SQ */
11 : : #define ROC_NIX_SQB_SLACK_DFLT 24
12 : :
13 : : static inline uint32_t
14 : : nix_qsize_to_val(enum nix_q_size qsize)
15 : : {
16 : 0 : return (16UL << (qsize * 2));
17 : : }
18 : :
19 : : static inline enum nix_q_size
20 : : nix_qsize_clampup(uint32_t val)
21 : : {
22 : : int i = nix_q_size_16;
23 : :
24 [ # # # # ]: 0 : for (; i < nix_q_size_max; i++)
25 [ # # # # ]: 0 : if (val <= nix_qsize_to_val(i))
26 : : break;
27 : :
28 [ # # # # ]: 0 : if (i >= nix_q_size_max)
29 : : i = nix_q_size_max - 1;
30 : :
31 : 0 : return i;
32 : : }
33 : :
34 : : void
35 [ # # ]: 0 : nix_rq_vwqe_flush(struct roc_nix_rq *rq, uint16_t vwqe_interval)
36 : : {
37 : : uint64_t wait_ns;
38 : :
39 [ # # ]: 0 : if (!roc_model_is_cn10k())
40 : : return;
41 : : /* Due to HW errata writes to VWQE_FLUSH might hang, so instead
42 : : * wait for max vwqe timeout interval.
43 : : */
44 [ # # ]: 0 : if (rq->vwqe_ena) {
45 : 0 : wait_ns = rq->vwqe_wait_tmo * (vwqe_interval + 1) * 100;
46 : 0 : plt_delay_us((wait_ns / 1E3) + 1);
47 : : }
48 : : }
49 : :
50 : : int
51 : 0 : nix_rq_ena_dis(struct dev *dev, struct roc_nix_rq *rq, bool enable)
52 : : {
53 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
54 : : int rc;
55 : :
56 : : /* Pkts will be dropped silently if RQ is disabled */
57 [ # # ]: 0 : if (roc_model_is_cn9k()) {
58 : : struct nix_aq_enq_req *aq;
59 : :
60 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
61 [ # # ]: 0 : if (!aq) {
62 : : rc = -ENOSPC;
63 : 0 : goto exit;
64 : : }
65 : :
66 : 0 : aq->qidx = rq->qid;
67 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
68 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
69 : :
70 : 0 : aq->rq.ena = enable;
71 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
72 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
73 : : struct nix_cn10k_aq_enq_req *aq;
74 : :
75 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
76 [ # # ]: 0 : if (!aq) {
77 : : rc = -ENOSPC;
78 : 0 : goto exit;
79 : : }
80 : :
81 : 0 : aq->qidx = rq->qid;
82 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
83 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
84 : :
85 : 0 : aq->rq.ena = enable;
86 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
87 : : } else {
88 : : struct nix_cn20k_aq_enq_req *aq;
89 : :
90 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
91 [ # # ]: 0 : if (!aq) {
92 : : rc = -ENOSPC;
93 : 0 : goto exit;
94 : : }
95 : :
96 : 0 : aq->qidx = rq->qid;
97 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
98 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
99 : :
100 : 0 : aq->rq.ena = enable;
101 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
102 : : }
103 : :
104 : 0 : rc = mbox_process(mbox);
105 : 0 : exit:
106 : : mbox_put(mbox);
107 : 0 : return rc;
108 : : }
109 : :
110 : : int
111 : 0 : roc_nix_sq_ena_dis(struct roc_nix_sq *sq, bool enable)
112 : : {
113 : : int rc = 0;
114 : :
115 : 0 : rc = roc_nix_tm_sq_aura_fc(sq, enable);
116 [ # # ]: 0 : if (rc)
117 : 0 : goto done;
118 : :
119 : 0 : sq->enable = enable;
120 : 0 : done:
121 : 0 : return rc;
122 : : }
123 : :
124 : : int
125 : 0 : roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable)
126 : : {
127 : 0 : struct nix *nix = roc_nix_to_nix_priv(rq->roc_nix);
128 : : int rc;
129 : :
130 : 0 : rc = nix_rq_ena_dis(&nix->dev, rq, enable);
131 : 0 : nix_rq_vwqe_flush(rq, nix->vwqe_interval);
132 [ # # ]: 0 : if (rc)
133 : : return rc;
134 : :
135 : : /* Check for meta aura if RQ is enabled */
136 [ # # # # ]: 0 : if (enable && nix->need_meta_aura)
137 : 0 : rc = roc_nix_inl_meta_aura_check(rq->roc_nix, rq);
138 : : return rc;
139 : : }
140 : :
141 : : int
142 : 0 : roc_nix_rq_is_sso_enable(struct roc_nix *roc_nix, uint32_t qid)
143 : : {
144 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
145 : : struct dev *dev = &nix->dev;
146 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
147 : : bool sso_enable;
148 : : int rc;
149 : :
150 [ # # ]: 0 : if (roc_model_is_cn9k()) {
151 : : struct nix_aq_enq_rsp *rsp;
152 : : struct nix_aq_enq_req *aq;
153 : :
154 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
155 [ # # ]: 0 : if (!aq) {
156 : : rc = -ENOSPC;
157 : 0 : goto exit;
158 : : }
159 : :
160 : 0 : aq->qidx = qid;
161 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
162 : 0 : aq->op = NIX_AQ_INSTOP_READ;
163 : : rc = mbox_process_msg(mbox, (void *)&rsp);
164 [ # # ]: 0 : if (rc)
165 : 0 : goto exit;
166 : :
167 : 0 : sso_enable = rsp->rq.sso_ena;
168 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
169 : : struct nix_cn10k_aq_enq_rsp *rsp;
170 : : struct nix_cn10k_aq_enq_req *aq;
171 : :
172 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
173 [ # # ]: 0 : if (!aq) {
174 : : rc = -ENOSPC;
175 : 0 : goto exit;
176 : : }
177 : :
178 : 0 : aq->qidx = qid;
179 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
180 : 0 : aq->op = NIX_AQ_INSTOP_READ;
181 : :
182 : : rc = mbox_process_msg(mbox, (void *)&rsp);
183 [ # # ]: 0 : if (rc)
184 : 0 : goto exit;
185 : :
186 : 0 : sso_enable = rsp->rq.sso_ena;
187 : : } else {
188 : : struct nix_cn20k_aq_enq_rsp *rsp;
189 : : struct nix_cn20k_aq_enq_req *aq;
190 : :
191 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
192 [ # # ]: 0 : if (!aq) {
193 : : rc = -ENOSPC;
194 : 0 : goto exit;
195 : : }
196 : :
197 : 0 : aq->qidx = qid;
198 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
199 : 0 : aq->op = NIX_AQ_INSTOP_READ;
200 : :
201 : : rc = mbox_process_msg(mbox, (void *)&rsp);
202 [ # # ]: 0 : if (rc)
203 : 0 : goto exit;
204 : :
205 : 0 : sso_enable = rsp->rq.sso_ena;
206 : : }
207 : :
208 : 0 : rc = sso_enable ? true : false;
209 : 0 : exit:
210 : : mbox_put(mbox);
211 : 0 : return rc;
212 : : }
213 : :
214 : : static int
215 : 0 : nix_rq_aura_buf_type_update(struct roc_nix_rq *rq, bool set)
216 : : {
217 : 0 : struct roc_nix *roc_nix = rq->roc_nix;
218 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
219 : 0 : bool inl_inb_ena = roc_nix_inl_inb_is_enabled(roc_nix);
220 : : uint64_t lpb_aura = 0, vwqe_aura = 0, spb_aura = 0;
221 : 0 : struct mbox *mbox = nix->dev.mbox;
222 : : uint64_t aura_base;
223 : : int rc, count;
224 : :
225 [ # # ]: 0 : count = set ? 1 : -1;
226 : : /* For buf type set, use info from RQ context */
227 [ # # ]: 0 : if (set) {
228 : 0 : lpb_aura = rq->aura_handle;
229 [ # # ]: 0 : spb_aura = rq->spb_ena ? rq->spb_aura_handle : 0;
230 [ # # ]: 0 : vwqe_aura = rq->vwqe_ena ? rq->vwqe_aura_handle : 0;
231 : 0 : goto skip_ctx_read;
232 : : }
233 : :
234 [ # # ]: 0 : aura_base = roc_npa_aura_handle_to_base(rq->aura_handle);
235 [ # # ]: 0 : if (roc_model_is_cn9k()) {
236 : : struct nix_aq_enq_rsp *rsp;
237 : : struct nix_aq_enq_req *aq;
238 : :
239 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox_get(mbox));
240 [ # # ]: 0 : if (!aq) {
241 : : mbox_put(mbox);
242 : 0 : return -ENOSPC;
243 : : }
244 : :
245 : 0 : aq->qidx = rq->qid;
246 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
247 : 0 : aq->op = NIX_AQ_INSTOP_READ;
248 : : rc = mbox_process_msg(mbox, (void *)&rsp);
249 [ # # ]: 0 : if (rc) {
250 : : mbox_put(mbox);
251 : 0 : return rc;
252 : : }
253 : :
254 : : /* Get aura handle from aura */
255 [ # # ]: 0 : lpb_aura = roc_npa_aura_handle_gen(rsp->rq.lpb_aura, aura_base);
256 [ # # ]: 0 : if (rsp->rq.spb_ena)
257 : 0 : spb_aura = roc_npa_aura_handle_gen(rsp->rq.spb_aura, aura_base);
258 : : mbox_put(mbox);
259 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
260 : : struct nix_cn10k_aq_enq_rsp *rsp;
261 : : struct nix_cn10k_aq_enq_req *aq;
262 : :
263 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox_get(mbox));
264 [ # # ]: 0 : if (!aq) {
265 : : mbox_put(mbox);
266 : 0 : return -ENOSPC;
267 : : }
268 : :
269 : 0 : aq->qidx = rq->qid;
270 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
271 : 0 : aq->op = NIX_AQ_INSTOP_READ;
272 : :
273 : : rc = mbox_process_msg(mbox, (void *)&rsp);
274 [ # # ]: 0 : if (rc) {
275 : : mbox_put(mbox);
276 : 0 : return rc;
277 : : }
278 : :
279 : : /* Get aura handle from aura */
280 [ # # ]: 0 : lpb_aura = roc_npa_aura_handle_gen(rsp->rq.lpb_aura, aura_base);
281 [ # # ]: 0 : if (rsp->rq.spb_ena)
282 : 0 : spb_aura = roc_npa_aura_handle_gen(rsp->rq.spb_aura, aura_base);
283 [ # # ]: 0 : if (rsp->rq.vwqe_ena)
284 : 0 : vwqe_aura = roc_npa_aura_handle_gen(rsp->rq.wqe_aura, aura_base);
285 : :
286 : : mbox_put(mbox);
287 : : } else {
288 : : struct nix_cn20k_aq_enq_rsp *rsp;
289 : : struct nix_cn20k_aq_enq_req *aq;
290 : :
291 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox_get(mbox));
292 [ # # ]: 0 : if (!aq) {
293 : : mbox_put(mbox);
294 : 0 : return -ENOSPC;
295 : : }
296 : :
297 : 0 : aq->qidx = rq->qid;
298 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
299 : 0 : aq->op = NIX_AQ_INSTOP_READ;
300 : :
301 : : rc = mbox_process_msg(mbox, (void *)&rsp);
302 [ # # ]: 0 : if (rc) {
303 : : mbox_put(mbox);
304 : 0 : return rc;
305 : : }
306 : :
307 : : /* Get aura handle from aura */
308 [ # # ]: 0 : lpb_aura = roc_npa_aura_handle_gen(rsp->rq.lpb_aura, aura_base);
309 [ # # ]: 0 : if (rsp->rq.spb_ena)
310 : 0 : spb_aura = roc_npa_aura_handle_gen(rsp->rq.spb_aura, aura_base);
311 : :
312 : : mbox_put(mbox);
313 : : }
314 : :
315 : 0 : skip_ctx_read:
316 : : /* Update attributes for LPB aura */
317 [ # # ]: 0 : if (inl_inb_ena)
318 : 0 : roc_npa_buf_type_update(lpb_aura, ROC_NPA_BUF_TYPE_PACKET_IPSEC, count);
319 : : else
320 : 0 : roc_npa_buf_type_update(lpb_aura, ROC_NPA_BUF_TYPE_PACKET, count);
321 : :
322 : : /* Update attributes for SPB aura */
323 [ # # ]: 0 : if (spb_aura) {
324 [ # # ]: 0 : if (inl_inb_ena)
325 : 0 : roc_npa_buf_type_update(spb_aura, ROC_NPA_BUF_TYPE_PACKET_IPSEC, count);
326 : : else
327 : 0 : roc_npa_buf_type_update(spb_aura, ROC_NPA_BUF_TYPE_PACKET, count);
328 : : }
329 : :
330 : : /* Update attributes for VWQE aura */
331 [ # # ]: 0 : if (vwqe_aura) {
332 [ # # ]: 0 : if (inl_inb_ena)
333 : 0 : roc_npa_buf_type_update(vwqe_aura, ROC_NPA_BUF_TYPE_VWQE_IPSEC, count);
334 : : else
335 : 0 : roc_npa_buf_type_update(vwqe_aura, ROC_NPA_BUF_TYPE_VWQE, count);
336 : : }
337 : :
338 : : return 0;
339 : : }
340 : :
341 : : static int
342 : 0 : nix_rq_cn9k_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
343 : : {
344 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
345 : : struct nix_aq_enq_req *aq;
346 : : int rc;
347 : :
348 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
349 [ # # ]: 0 : if (!aq) {
350 : : rc = -ENOSPC;
351 : 0 : goto exit;
352 : : }
353 : :
354 : 0 : aq->qidx = rq->qid;
355 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
356 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
357 : :
358 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
359 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
360 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
361 : 0 : aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
362 : 0 : aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
363 : :
364 : : }
365 : :
366 [ # # # # ]: 0 : if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
367 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
368 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
369 : 0 : aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
370 : 0 : aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
371 : :
372 : : }
373 : :
374 [ # # # # ]: 0 : if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
375 : 0 : aq->rq.xqe_pass = rq->xqe_red_pass;
376 : 0 : aq->rq.xqe_drop = rq->xqe_red_drop;
377 : 0 : aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
378 : 0 : aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
379 : : }
380 : :
381 : 0 : rc = mbox_process(mbox);
382 : 0 : exit:
383 : : mbox_put(mbox);
384 : 0 : return rc;
385 : : }
386 : :
387 : : static int
388 : 0 : nix_rq_cn10k_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
389 : : {
390 : : struct nix_cn10k_aq_enq_req *aq;
391 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
392 : : int rc;
393 : :
394 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
395 [ # # ]: 0 : if (!aq) {
396 : : rc = -ENOSPC;
397 : 0 : goto exit;
398 : : }
399 : :
400 : 0 : aq->qidx = rq->qid;
401 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
402 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
403 : :
404 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
405 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
406 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
407 : 0 : aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
408 : 0 : aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
409 : : }
410 : :
411 [ # # # # ]: 0 : if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
412 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
413 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
414 : 0 : aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
415 : 0 : aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
416 : : }
417 : :
418 [ # # # # ]: 0 : if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
419 : 0 : aq->rq.xqe_pass = rq->xqe_red_pass;
420 : 0 : aq->rq.xqe_drop = rq->xqe_red_drop;
421 : 0 : aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
422 : 0 : aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
423 : : }
424 : :
425 : 0 : rc = mbox_process(mbox);
426 : 0 : exit:
427 : : mbox_put(mbox);
428 : 0 : return rc;
429 : : }
430 : :
431 : : static int
432 : 0 : nix_rq_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
433 : : {
434 : : struct nix_cn20k_aq_enq_req *aq;
435 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
436 : : int rc;
437 : :
438 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
439 [ # # ]: 0 : if (!aq) {
440 : : rc = -ENOSPC;
441 : 0 : goto exit;
442 : : }
443 : :
444 : 0 : aq->qidx = rq->qid;
445 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
446 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
447 : :
448 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
449 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
450 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
451 : 0 : aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
452 : 0 : aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
453 : : }
454 : :
455 [ # # # # ]: 0 : if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
456 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
457 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
458 : 0 : aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
459 : 0 : aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
460 : : }
461 : :
462 [ # # # # ]: 0 : if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
463 : 0 : aq->rq.xqe_pass = rq->xqe_red_pass;
464 : 0 : aq->rq.xqe_drop = rq->xqe_red_drop;
465 : 0 : aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
466 : 0 : aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
467 : : }
468 : :
469 : 0 : rc = mbox_process(mbox);
470 : 0 : exit:
471 : : mbox_put(mbox);
472 : 0 : return rc;
473 : : }
474 : :
475 : : int
476 : 0 : nix_rq_cn9k_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints,
477 : : bool cfg, bool ena)
478 : : {
479 : 0 : struct mbox *mbox = dev->mbox;
480 : : struct nix_aq_enq_req *aq;
481 : :
482 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
483 [ # # ]: 0 : if (!aq)
484 : : return -ENOSPC;
485 : :
486 : 0 : aq->qidx = rq->qid;
487 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
488 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
489 : :
490 [ # # ]: 0 : if (rq->sso_ena) {
491 : : /* SSO mode */
492 : 0 : aq->rq.sso_ena = 1;
493 : 0 : aq->rq.sso_tt = rq->tt;
494 : 0 : aq->rq.sso_grp = rq->hwgrp;
495 : 0 : aq->rq.ena_wqwd = 1;
496 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
497 : 0 : aq->rq.wqe_caching = 1;
498 : :
499 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
500 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
501 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
502 : : } else {
503 : : /* CQ mode */
504 : 0 : aq->rq.sso_ena = 0;
505 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
506 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
507 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
508 : 0 : aq->rq.cq = rq->cqid;
509 : : }
510 : :
511 [ # # ]: 0 : if (rq->ipsech_ena)
512 : 0 : aq->rq.ipsech_ena = 1;
513 : :
514 : 0 : aq->rq.spb_ena = 0;
515 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
516 : :
517 : : /* Sizes must be aligned to 8 bytes */
518 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
519 : : return -EINVAL;
520 : :
521 : : /* Expressed in number of dwords */
522 : 0 : aq->rq.first_skip = rq->first_skip / 8;
523 : 0 : aq->rq.later_skip = rq->later_skip / 8;
524 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
525 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
526 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
527 : 0 : aq->rq.ena = ena;
528 : 0 : aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
529 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
530 : 0 : aq->rq.rq_int_ena = 0;
531 : : /* Many to one reduction */
532 : 0 : aq->rq.qint_idx = rq->qid % qints;
533 : 0 : aq->rq.xqe_drop_ena = 1;
534 : :
535 : : /* If RED enabled, then fill enable for all cases */
536 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
537 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
538 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
539 : :
540 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
541 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
542 : : }
543 : :
544 [ # # ]: 0 : if (cfg) {
545 [ # # ]: 0 : if (rq->sso_ena) {
546 : : /* SSO mode */
547 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
548 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
549 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
550 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
551 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
552 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
553 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
554 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
555 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
556 : : } else {
557 : : /* CQ mode */
558 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
559 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
560 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
561 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
562 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
563 : : }
564 : :
565 [ # # ]: 0 : if (rq->ipsech_ena)
566 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
567 : :
568 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
569 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
570 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
571 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
572 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
573 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
574 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
575 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
576 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
577 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
578 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
579 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
580 : :
581 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
582 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
583 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
584 : :
585 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
586 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
587 : : }
588 : : }
589 : :
590 : : return 0;
591 : : }
592 : :
593 : : int
594 : 0 : nix_rq_cn10k_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg, bool ena)
595 : : {
596 : : struct nix_cn10k_aq_enq_req *aq;
597 : 0 : struct mbox *mbox = dev->mbox;
598 : :
599 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
600 [ # # ]: 0 : if (!aq)
601 : : return -ENOSPC;
602 : :
603 : 0 : aq->qidx = rq->qid;
604 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
605 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
606 : :
607 [ # # ]: 0 : if (rq->sso_ena) {
608 : : /* SSO mode */
609 : 0 : aq->rq.sso_ena = 1;
610 : 0 : aq->rq.sso_tt = rq->tt;
611 : 0 : aq->rq.sso_grp = rq->hwgrp;
612 : 0 : aq->rq.ena_wqwd = 1;
613 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
614 : 0 : aq->rq.wqe_caching = 1;
615 : :
616 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
617 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
618 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
619 : :
620 [ # # ]: 0 : if (rq->vwqe_ena) {
621 : 0 : aq->rq.vwqe_ena = true;
622 : 0 : aq->rq.vwqe_skip = rq->vwqe_first_skip;
623 : : /* Maximal Vector size is (2^(MAX_VSIZE_EXP+2)) */
624 : 0 : aq->rq.max_vsize_exp = rq->vwqe_max_sz_exp - 2;
625 : 0 : aq->rq.vtime_wait = rq->vwqe_wait_tmo;
626 : 0 : aq->rq.wqe_aura = roc_npa_aura_handle_to_aura(rq->vwqe_aura_handle);
627 : : }
628 : : } else {
629 : : /* CQ mode */
630 : 0 : aq->rq.sso_ena = 0;
631 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
632 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
633 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
634 : 0 : aq->rq.cq = rq->cqid;
635 : : }
636 : :
637 [ # # ]: 0 : if (rq->ipsech_ena) {
638 : 0 : aq->rq.ipsech_ena = 1;
639 : 0 : aq->rq.ipsecd_drop_en = 1;
640 : 0 : aq->rq.ena_wqwd = 1;
641 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
642 : 0 : aq->rq.wqe_caching = 1;
643 : : }
644 : :
645 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
646 : :
647 : : /* Sizes must be aligned to 8 bytes */
648 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
649 : : return -EINVAL;
650 : :
651 : : /* Expressed in number of dwords */
652 : 0 : aq->rq.first_skip = rq->first_skip / 8;
653 : 0 : aq->rq.later_skip = rq->later_skip / 8;
654 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
655 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
656 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
657 : 0 : aq->rq.ena = ena;
658 : :
659 [ # # ]: 0 : if (rq->spb_ena) {
660 : : uint32_t spb_sizem1;
661 : :
662 : 0 : aq->rq.spb_ena = 1;
663 : 0 : aq->rq.spb_aura =
664 [ # # ]: 0 : roc_npa_aura_handle_to_aura(rq->spb_aura_handle);
665 : :
666 [ # # # # ]: 0 : if (rq->spb_size & 0x7 ||
667 : : rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE)
668 : : return -EINVAL;
669 : :
670 : 0 : spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */
671 : 0 : spb_sizem1 -= 1; /* Expressed in size minus one */
672 : 0 : aq->rq.spb_sizem1 = spb_sizem1 & 0x3F;
673 : 0 : aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7;
674 : : } else {
675 : 0 : aq->rq.spb_ena = 0;
676 : : }
677 : :
678 : 0 : aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
679 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
680 : 0 : aq->rq.rq_int_ena = 0;
681 : : /* Many to one reduction */
682 : 0 : aq->rq.qint_idx = rq->qid % qints;
683 : 0 : aq->rq.xqe_drop_ena = 0;
684 : 0 : aq->rq.lpb_drop_ena = rq->lpb_drop_ena;
685 : 0 : aq->rq.spb_drop_ena = rq->spb_drop_ena;
686 : :
687 : : /* If RED enabled, then fill enable for all cases */
688 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
689 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
690 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
691 : 0 : aq->rq.wqe_pool_pass = rq->red_pass;
692 : 0 : aq->rq.xqe_pass = rq->red_pass;
693 : :
694 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
695 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
696 : 0 : aq->rq.wqe_pool_drop = rq->red_drop;
697 : 0 : aq->rq.xqe_drop = rq->red_drop;
698 : : }
699 : :
700 [ # # ]: 0 : if (cfg) {
701 [ # # ]: 0 : if (rq->sso_ena) {
702 : : /* SSO mode */
703 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
704 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
705 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
706 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
707 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
708 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
709 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
710 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
711 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
712 [ # # ]: 0 : if (rq->vwqe_ena) {
713 : 0 : aq->rq_mask.vwqe_ena = ~aq->rq_mask.vwqe_ena;
714 : 0 : aq->rq_mask.vwqe_skip = ~aq->rq_mask.vwqe_skip;
715 : 0 : aq->rq_mask.max_vsize_exp =
716 : 0 : ~aq->rq_mask.max_vsize_exp;
717 : 0 : aq->rq_mask.vtime_wait =
718 : 0 : ~aq->rq_mask.vtime_wait;
719 : 0 : aq->rq_mask.wqe_aura = ~aq->rq_mask.wqe_aura;
720 : : }
721 : : } else {
722 : : /* CQ mode */
723 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
724 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
725 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
726 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
727 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
728 : : }
729 : :
730 [ # # ]: 0 : if (rq->ipsech_ena)
731 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
732 : :
733 [ # # ]: 0 : if (rq->spb_ena) {
734 : 0 : aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura;
735 : 0 : aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1;
736 : 0 : aq->rq_mask.spb_high_sizem1 =
737 : 0 : ~aq->rq_mask.spb_high_sizem1;
738 : : }
739 : :
740 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
741 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
742 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
743 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
744 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
745 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
746 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
747 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
748 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
749 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
750 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
751 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
752 : 0 : aq->rq_mask.lpb_drop_ena = ~aq->rq_mask.lpb_drop_ena;
753 : 0 : aq->rq_mask.spb_drop_ena = ~aq->rq_mask.spb_drop_ena;
754 : :
755 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
756 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
757 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
758 : 0 : aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass;
759 : 0 : aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass;
760 : :
761 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
762 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
763 : 0 : aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop;
764 : 0 : aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop;
765 : : }
766 : : }
767 : :
768 : : return 0;
769 : : }
770 : :
771 : : int
772 : 0 : nix_rq_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg, bool ena)
773 : : {
774 : : struct nix_cn20k_aq_enq_req *aq;
775 : 0 : struct mbox *mbox = dev->mbox;
776 : :
777 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
778 [ # # ]: 0 : if (!aq)
779 : : return -ENOSPC;
780 : :
781 : 0 : aq->qidx = rq->qid;
782 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
783 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
784 : :
785 [ # # ]: 0 : if (rq->sso_ena) {
786 : : /* SSO mode */
787 : 0 : aq->rq.sso_ena = 1;
788 : 0 : aq->rq.sso_tt = rq->tt;
789 : 0 : aq->rq.sso_grp = rq->hwgrp;
790 : 0 : aq->rq.ena_wqwd = 1;
791 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
792 : 0 : aq->rq.wqe_caching = 1;
793 : :
794 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
795 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
796 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
797 : : } else {
798 : : /* CQ mode */
799 : 0 : aq->rq.sso_ena = 0;
800 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
801 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
802 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
803 : 0 : aq->rq.cq = rq->cqid;
804 : : }
805 : :
806 [ # # ]: 0 : if (rq->ipsech_ena) {
807 : 0 : aq->rq.ipsech_ena = 1;
808 : 0 : aq->rq.ipsecd_drop_en = 1;
809 : 0 : aq->rq.ena_wqwd = 1;
810 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
811 : 0 : aq->rq.wqe_caching = 1;
812 : : }
813 : :
814 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
815 : :
816 : : /* Sizes must be aligned to 8 bytes */
817 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
818 : : return -EINVAL;
819 : :
820 : : /* Expressed in number of dwords */
821 : 0 : aq->rq.first_skip = rq->first_skip / 8;
822 : 0 : aq->rq.later_skip = rq->later_skip / 8;
823 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
824 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
825 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
826 : 0 : aq->rq.ena = ena;
827 : :
828 [ # # ]: 0 : if (rq->spb_ena) {
829 : : uint32_t spb_sizem1;
830 : :
831 : 0 : aq->rq.spb_ena = 1;
832 : 0 : aq->rq.spb_aura =
833 [ # # ]: 0 : roc_npa_aura_handle_to_aura(rq->spb_aura_handle);
834 : :
835 [ # # # # ]: 0 : if (rq->spb_size & 0x7 ||
836 : : rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE)
837 : : return -EINVAL;
838 : :
839 : 0 : spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */
840 : 0 : spb_sizem1 -= 1; /* Expressed in size minus one */
841 : 0 : aq->rq.spb_sizem1 = spb_sizem1 & 0x3F;
842 : 0 : aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7;
843 : : } else {
844 : 0 : aq->rq.spb_ena = 0;
845 : : }
846 : :
847 : 0 : aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
848 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
849 : 0 : aq->rq.rq_int_ena = 0;
850 : : /* Many to one reduction */
851 : 0 : aq->rq.qint_idx = rq->qid % qints;
852 : 0 : aq->rq.xqe_drop_ena = 0;
853 : 0 : aq->rq.lpb_drop_ena = rq->lpb_drop_ena;
854 : 0 : aq->rq.spb_drop_ena = rq->spb_drop_ena;
855 : :
856 : : /* If RED enabled, then fill enable for all cases */
857 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
858 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
859 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
860 : 0 : aq->rq.wqe_pool_pass = rq->red_pass;
861 : 0 : aq->rq.xqe_pass = rq->red_pass;
862 : :
863 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
864 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
865 : 0 : aq->rq.wqe_pool_drop = rq->red_drop;
866 : 0 : aq->rq.xqe_drop = rq->red_drop;
867 : : }
868 : :
869 [ # # ]: 0 : if (cfg) {
870 [ # # ]: 0 : if (rq->sso_ena) {
871 : : /* SSO mode */
872 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
873 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
874 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
875 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
876 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
877 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
878 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
879 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
880 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
881 : : } else {
882 : : /* CQ mode */
883 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
884 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
885 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
886 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
887 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
888 : : }
889 : :
890 [ # # ]: 0 : if (rq->ipsech_ena)
891 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
892 : :
893 [ # # ]: 0 : if (rq->spb_ena) {
894 : 0 : aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura;
895 : 0 : aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1;
896 : 0 : aq->rq_mask.spb_high_sizem1 =
897 : 0 : ~aq->rq_mask.spb_high_sizem1;
898 : : }
899 : :
900 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
901 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
902 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
903 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
904 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
905 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
906 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
907 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
908 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
909 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
910 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
911 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
912 : 0 : aq->rq_mask.lpb_drop_ena = ~aq->rq_mask.lpb_drop_ena;
913 : 0 : aq->rq_mask.spb_drop_ena = ~aq->rq_mask.spb_drop_ena;
914 : :
915 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
916 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
917 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
918 : 0 : aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass;
919 : 0 : aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass;
920 : :
921 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
922 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
923 : 0 : aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop;
924 : 0 : aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop;
925 : : }
926 : : }
927 : :
928 : : return 0;
929 : : }
930 : :
931 : : int
932 : 0 : roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
933 : : {
934 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
935 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
936 : : bool is_cn9k = roc_model_is_cn9k();
937 : 0 : struct dev *dev = &nix->dev;
938 : : int rc;
939 : :
940 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL) {
941 : : mbox_put(mbox);
942 : 0 : return NIX_ERR_PARAM;
943 : : }
944 : :
945 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues) {
946 : : mbox_put(mbox);
947 : 0 : return NIX_ERR_QUEUE_INVALID_RANGE;
948 : : }
949 : :
950 : 0 : rq->roc_nix = roc_nix;
951 : 0 : rq->tc = ROC_NIX_PFC_CLASS_INVALID;
952 : :
953 [ # # ]: 0 : if (is_cn9k)
954 : 0 : rc = nix_rq_cn9k_cfg(dev, rq, nix->qints, false, ena);
955 [ # # ]: 0 : else if (roc_model_is_cn10k())
956 : 0 : rc = nix_rq_cn10k_cfg(dev, rq, nix->qints, false, ena);
957 : : else
958 : 0 : rc = nix_rq_cfg(dev, rq, nix->qints, false, ena);
959 : :
960 [ # # ]: 0 : if (rc) {
961 : : mbox_put(mbox);
962 : 0 : return rc;
963 : : }
964 : :
965 : 0 : rc = mbox_process(mbox);
966 [ # # ]: 0 : if (rc) {
967 : : mbox_put(mbox);
968 : 0 : return rc;
969 : : }
970 : : mbox_put(mbox);
971 : :
972 : : /* Update aura buf type to indicate its use */
973 : 0 : nix_rq_aura_buf_type_update(rq, true);
974 : :
975 : : /* Check for meta aura if RQ is enabled */
976 [ # # # # ]: 0 : if (ena && nix->need_meta_aura) {
977 : 0 : rc = roc_nix_inl_meta_aura_check(roc_nix, rq);
978 [ # # ]: 0 : if (rc)
979 : : return rc;
980 : : }
981 : :
982 : 0 : nix->rqs[rq->qid] = rq;
983 : 0 : return nix_tel_node_add_rq(rq);
984 : : }
985 : :
986 : : int
987 : 0 : roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
988 : : {
989 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
990 [ # # ]: 0 : struct mbox *m_box = (&nix->dev)->mbox;
991 : : bool is_cn9k = roc_model_is_cn9k();
992 : 0 : struct dev *dev = &nix->dev;
993 : : struct mbox *mbox;
994 : : int rc;
995 : :
996 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL)
997 : : return NIX_ERR_PARAM;
998 : :
999 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues)
1000 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1001 : :
1002 : : /* Clear attributes for existing aura's */
1003 : 0 : nix_rq_aura_buf_type_update(rq, false);
1004 : :
1005 : 0 : rq->roc_nix = roc_nix;
1006 : 0 : rq->tc = ROC_NIX_PFC_CLASS_INVALID;
1007 : :
1008 : : mbox = mbox_get(m_box);
1009 [ # # ]: 0 : if (is_cn9k)
1010 : 0 : rc = nix_rq_cn9k_cfg(dev, rq, nix->qints, true, ena);
1011 [ # # ]: 0 : else if (roc_model_is_cn10k())
1012 : 0 : rc = nix_rq_cn10k_cfg(dev, rq, nix->qints, true, ena);
1013 : : else
1014 : 0 : rc = nix_rq_cfg(dev, rq, nix->qints, true, ena);
1015 : :
1016 [ # # ]: 0 : if (rc) {
1017 : : mbox_put(mbox);
1018 : 0 : return rc;
1019 : : }
1020 : :
1021 : 0 : rc = mbox_process(mbox);
1022 [ # # ]: 0 : if (rc) {
1023 : : mbox_put(mbox);
1024 : 0 : return rc;
1025 : : }
1026 : : mbox_put(mbox);
1027 : :
1028 : : /* Update aura attribute to indicate its use */
1029 : 0 : nix_rq_aura_buf_type_update(rq, true);
1030 : :
1031 : : /* Check for meta aura if RQ is enabled */
1032 [ # # # # ]: 0 : if (ena && nix->need_meta_aura) {
1033 : 0 : rc = roc_nix_inl_meta_aura_check(roc_nix, rq);
1034 [ # # ]: 0 : if (rc)
1035 : : return rc;
1036 : : }
1037 : :
1038 : 0 : return nix_tel_node_add_rq(rq);
1039 : : }
1040 : :
1041 : : int
1042 [ # # ]: 0 : roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq)
1043 : : {
1044 : : bool is_cn9k = roc_model_is_cn9k();
1045 : : struct nix *nix;
1046 : : struct dev *dev;
1047 : : int rc;
1048 : :
1049 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL)
1050 : : return NIX_ERR_PARAM;
1051 : :
1052 : : nix = roc_nix_to_nix_priv(roc_nix);
1053 : :
1054 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues)
1055 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1056 : :
1057 : 0 : dev = &nix->dev;
1058 : :
1059 [ # # ]: 0 : if (is_cn9k)
1060 : 0 : rc = nix_rq_cn9k_cman_cfg(dev, rq);
1061 [ # # ]: 0 : else if (roc_model_is_cn10k())
1062 : 0 : rc = nix_rq_cn10k_cman_cfg(dev, rq);
1063 : : else
1064 : 0 : rc = nix_rq_cman_cfg(dev, rq);
1065 : :
1066 : : return rc;
1067 : : }
1068 : :
1069 : : int
1070 : 0 : roc_nix_rq_fini(struct roc_nix_rq *rq)
1071 : : {
1072 : 0 : struct nix *nix = roc_nix_to_nix_priv(rq->roc_nix);
1073 : : int rc;
1074 : :
1075 : : /* Disabling RQ is sufficient */
1076 : 0 : rc = roc_nix_rq_ena_dis(rq, false);
1077 [ # # ]: 0 : if (rc)
1078 : : return rc;
1079 : :
1080 : : /* Update aura attribute to indicate its use for */
1081 : 0 : nix_rq_aura_buf_type_update(rq, false);
1082 : :
1083 : 0 : nix->rqs[rq->qid] = NULL;
1084 : 0 : return 0;
1085 : : }
1086 : :
1087 : : static inline int
1088 : 0 : roc_nix_cn20k_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq)
1089 : : {
1090 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1091 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1092 : : volatile struct nix_cn20k_cq_ctx_s *cq_ctx;
1093 : : uint16_t drop_thresh = NIX_CQ_THRESH_LEVEL;
1094 : 0 : uint16_t cpt_lbpid = nix->cpt_lbpid;
1095 : : struct nix_cn20k_aq_enq_req *aq;
1096 : : enum nix_q_size qsize;
1097 : : size_t desc_sz;
1098 : : int rc;
1099 : :
1100 [ # # ]: 0 : if (cq == NULL)
1101 : : return NIX_ERR_PARAM;
1102 : :
1103 : 0 : qsize = nix_qsize_clampup(cq->nb_desc);
1104 : 0 : cq->nb_desc = nix_qsize_to_val(qsize);
1105 : 0 : cq->qmask = cq->nb_desc - 1;
1106 : 0 : cq->door = nix->base + NIX_LF_CQ_OP_DOOR;
1107 : 0 : cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
1108 : 0 : cq->wdata = (uint64_t)cq->qid << 32;
1109 : 0 : cq->roc_nix = roc_nix;
1110 : :
1111 : : /* CQE of W16 */
1112 : 0 : desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ;
1113 : 0 : cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN);
1114 [ # # ]: 0 : if (cq->desc_base == NULL) {
1115 : : rc = NIX_ERR_NO_MEM;
1116 : 0 : goto fail;
1117 : : }
1118 : :
1119 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox_get(mbox));
1120 [ # # ]: 0 : if (!aq) {
1121 : : mbox_put(mbox);
1122 : 0 : return -ENOSPC;
1123 : : }
1124 : :
1125 : 0 : aq->qidx = cq->qid;
1126 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1127 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1128 : : cq_ctx = &aq->cq;
1129 : :
1130 : 0 : cq_ctx->ena = 1;
1131 : 0 : cq_ctx->caching = 1;
1132 : 0 : cq_ctx->qsize = qsize;
1133 : 0 : cq_ctx->base = (uint64_t)cq->desc_base;
1134 : 0 : cq_ctx->avg_level = 0xff;
1135 : 0 : cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
1136 [ # # ]: 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
1137 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(roc_nix)) {
1138 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_CPT_DROP);
1139 : 0 : cq_ctx->cpt_drop_err_en = 1;
1140 : : /* Enable Late BP only when non zero CPT BPID */
1141 [ # # ]: 0 : if (cpt_lbpid) {
1142 : 0 : cq_ctx->lbp_ena = 1;
1143 : 0 : cq_ctx->lbpid_low = cpt_lbpid & 0x7;
1144 : 0 : cq_ctx->lbpid_med = (cpt_lbpid >> 3) & 0x7;
1145 : 0 : cq_ctx->lbpid_high = (cpt_lbpid >> 6) & 0x7;
1146 : 0 : cq_ctx->lbp_frac = NIX_CQ_LPB_THRESH_FRAC;
1147 : : }
1148 : : drop_thresh = NIX_CQ_SEC_THRESH_LEVEL;
1149 : : }
1150 : :
1151 : : /* Many to one reduction */
1152 : 0 : cq_ctx->qint_idx = cq->qid % nix->qints;
1153 : : /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
1154 [ # # ]: 0 : cq_ctx->cint_idx = cq->qid;
1155 : :
1156 [ # # ]: 0 : if (roc_errata_nix_has_cq_min_size_4k()) {
1157 : : const float rx_cq_skid = NIX_CQ_FULL_ERRATA_SKID;
1158 : : uint16_t min_rx_drop;
1159 : :
1160 : 0 : min_rx_drop = ceil(rx_cq_skid / (float)cq->nb_desc);
1161 : 0 : cq_ctx->drop = min_rx_drop;
1162 : 0 : cq_ctx->drop_ena = 1;
1163 : 0 : cq->drop_thresh = min_rx_drop;
1164 : : } else {
1165 : 0 : cq->drop_thresh = drop_thresh;
1166 : : /* Drop processing or red drop cannot be enabled due to
1167 : : * due to packets coming for second pass from CPT.
1168 : : */
1169 [ # # ]: 0 : if (!roc_nix_inl_inb_is_enabled(roc_nix)) {
1170 : 0 : cq_ctx->drop = cq->drop_thresh;
1171 : 0 : cq_ctx->drop_ena = 1;
1172 : : }
1173 : : }
1174 [ # # ]: 0 : cq_ctx->bp = cq->drop_thresh;
1175 : :
1176 [ # # ]: 0 : if (roc_feature_nix_has_cqe_stash()) {
1177 [ # # ]: 0 : if (cq_ctx->caching) {
1178 : 0 : cq_ctx->stashing = 1;
1179 : 0 : cq_ctx->stash_thresh = cq->stash_thresh;
1180 : : }
1181 : : }
1182 : :
1183 : 0 : rc = mbox_process(mbox);
1184 : : mbox_put(mbox);
1185 [ # # ]: 0 : if (rc)
1186 : 0 : goto free_mem;
1187 : :
1188 : 0 : return nix_tel_node_add_cq(cq);
1189 : :
1190 : : free_mem:
1191 : 0 : plt_free(cq->desc_base);
1192 : : fail:
1193 : : return rc;
1194 : : }
1195 : :
1196 : : int
1197 : 0 : roc_nix_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq)
1198 : : {
1199 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1200 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1201 : : volatile struct nix_cq_ctx_s *cq_ctx = NULL;
1202 : : uint16_t drop_thresh = NIX_CQ_THRESH_LEVEL;
1203 : 0 : uint16_t cpt_lbpid = nix->cpt_lbpid;
1204 : : enum nix_q_size qsize;
1205 : : size_t desc_sz;
1206 : : int rc;
1207 : :
1208 [ # # ]: 0 : if (cq == NULL)
1209 : : return NIX_ERR_PARAM;
1210 : :
1211 [ # # ]: 0 : if (roc_model_is_cn20k())
1212 : 0 : return roc_nix_cn20k_cq_init(roc_nix, cq);
1213 : :
1214 : 0 : qsize = nix_qsize_clampup(cq->nb_desc);
1215 : 0 : cq->nb_desc = nix_qsize_to_val(qsize);
1216 : 0 : cq->qmask = cq->nb_desc - 1;
1217 : 0 : cq->door = nix->base + NIX_LF_CQ_OP_DOOR;
1218 : 0 : cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
1219 : 0 : cq->wdata = (uint64_t)cq->qid << 32;
1220 : 0 : cq->roc_nix = roc_nix;
1221 : :
1222 : : /* CQE of W16 */
1223 : 0 : desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ;
1224 : 0 : cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN);
1225 [ # # ]: 0 : if (cq->desc_base == NULL) {
1226 : : rc = NIX_ERR_NO_MEM;
1227 : 0 : goto fail;
1228 : : }
1229 : :
1230 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1231 : : struct nix_aq_enq_req *aq;
1232 : :
1233 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox_get(mbox));
1234 [ # # ]: 0 : if (!aq) {
1235 : : mbox_put(mbox);
1236 : 0 : return -ENOSPC;
1237 : : }
1238 : :
1239 : 0 : aq->qidx = cq->qid;
1240 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1241 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1242 : 0 : cq_ctx = &aq->cq;
1243 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
1244 : : struct nix_cn10k_aq_enq_req *aq;
1245 : :
1246 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox_get(mbox));
1247 [ # # ]: 0 : if (!aq) {
1248 : : mbox_put(mbox);
1249 : 0 : return -ENOSPC;
1250 : : }
1251 : :
1252 : 0 : aq->qidx = cq->qid;
1253 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1254 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1255 : 0 : cq_ctx = &aq->cq;
1256 : : }
1257 : :
1258 : 0 : cq_ctx->ena = 1;
1259 : 0 : cq_ctx->caching = 1;
1260 : 0 : cq_ctx->qsize = qsize;
1261 : 0 : cq_ctx->base = (uint64_t)cq->desc_base;
1262 : 0 : cq_ctx->avg_level = 0xff;
1263 : 0 : cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
1264 [ # # ]: 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
1265 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(roc_nix)) {
1266 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_CPT_DROP);
1267 : 0 : cq_ctx->cpt_drop_err_en = 1;
1268 : : /* Enable Late BP only when non zero CPT BPID */
1269 [ # # ]: 0 : if (cpt_lbpid) {
1270 : 0 : cq_ctx->lbp_ena = 1;
1271 : 0 : cq_ctx->lbpid_low = cpt_lbpid & 0x7;
1272 : 0 : cq_ctx->lbpid_med = (cpt_lbpid >> 3) & 0x7;
1273 : 0 : cq_ctx->lbpid_high = (cpt_lbpid >> 6) & 0x7;
1274 : 0 : cq_ctx->lbp_frac = NIX_CQ_LPB_THRESH_FRAC;
1275 : : }
1276 : : drop_thresh = NIX_CQ_SEC_THRESH_LEVEL;
1277 : : }
1278 : :
1279 : : /* Many to one reduction */
1280 : 0 : cq_ctx->qint_idx = cq->qid % nix->qints;
1281 : : /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
1282 [ # # ]: 0 : cq_ctx->cint_idx = cq->qid;
1283 : :
1284 [ # # ]: 0 : if (roc_errata_nix_has_cq_min_size_4k()) {
1285 : : const float rx_cq_skid = NIX_CQ_FULL_ERRATA_SKID;
1286 : : uint16_t min_rx_drop;
1287 : :
1288 : 0 : min_rx_drop = ceil(rx_cq_skid / (float)cq->nb_desc);
1289 : 0 : cq_ctx->drop = min_rx_drop;
1290 : 0 : cq_ctx->drop_ena = 1;
1291 : 0 : cq->drop_thresh = min_rx_drop;
1292 : : } else {
1293 : 0 : cq->drop_thresh = drop_thresh;
1294 : : /* Drop processing or red drop cannot be enabled due to
1295 : : * due to packets coming for second pass from CPT.
1296 : : */
1297 [ # # ]: 0 : if (!roc_nix_inl_inb_is_enabled(roc_nix)) {
1298 : 0 : cq_ctx->drop = cq->drop_thresh;
1299 : 0 : cq_ctx->drop_ena = 1;
1300 : : }
1301 : : }
1302 [ # # ]: 0 : cq_ctx->bp = cq->drop_thresh;
1303 : :
1304 [ # # ]: 0 : if (roc_feature_nix_has_cqe_stash()) {
1305 [ # # ]: 0 : if (cq_ctx->caching) {
1306 : 0 : cq_ctx->stashing = 1;
1307 : 0 : cq_ctx->stash_thresh = cq->stash_thresh;
1308 : : }
1309 : : }
1310 : :
1311 : 0 : rc = mbox_process(mbox);
1312 : : mbox_put(mbox);
1313 [ # # ]: 0 : if (rc)
1314 : 0 : goto free_mem;
1315 : :
1316 : 0 : return nix_tel_node_add_cq(cq);
1317 : :
1318 : : free_mem:
1319 : 0 : plt_free(cq->desc_base);
1320 : : fail:
1321 : : return rc;
1322 : : }
1323 : :
1324 : : int
1325 : 0 : roc_nix_cq_fini(struct roc_nix_cq *cq)
1326 : : {
1327 : : struct mbox *mbox;
1328 : : struct nix *nix;
1329 : : int rc;
1330 : :
1331 [ # # ]: 0 : if (cq == NULL)
1332 : : return NIX_ERR_PARAM;
1333 : :
1334 : 0 : nix = roc_nix_to_nix_priv(cq->roc_nix);
1335 : 0 : mbox = mbox_get((&nix->dev)->mbox);
1336 : :
1337 : : /* Disable CQ */
1338 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1339 : : struct nix_aq_enq_req *aq;
1340 : :
1341 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1342 [ # # ]: 0 : if (!aq) {
1343 : : mbox_put(mbox);
1344 : 0 : return -ENOSPC;
1345 : : }
1346 : :
1347 : 0 : aq->qidx = cq->qid;
1348 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1349 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1350 : 0 : aq->cq.ena = 0;
1351 : 0 : aq->cq.bp_ena = 0;
1352 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1353 : 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1354 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
1355 : : struct nix_cn10k_aq_enq_req *aq;
1356 : :
1357 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1358 [ # # ]: 0 : if (!aq) {
1359 : : mbox_put(mbox);
1360 : 0 : return -ENOSPC;
1361 : : }
1362 : :
1363 : 0 : aq->qidx = cq->qid;
1364 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1365 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1366 : 0 : aq->cq.ena = 0;
1367 : 0 : aq->cq.bp_ena = 0;
1368 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1369 [ # # ]: 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1370 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(cq->roc_nix)) {
1371 : 0 : aq->cq.lbp_ena = 0;
1372 : 0 : aq->cq_mask.lbp_ena = ~aq->cq_mask.lbp_ena;
1373 : : }
1374 : : } else {
1375 : : struct nix_cn20k_aq_enq_req *aq;
1376 : :
1377 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1378 [ # # ]: 0 : if (!aq) {
1379 : : mbox_put(mbox);
1380 : 0 : return -ENOSPC;
1381 : : }
1382 : :
1383 : 0 : aq->qidx = cq->qid;
1384 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1385 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1386 : 0 : aq->cq.ena = 0;
1387 : 0 : aq->cq.bp_ena = 0;
1388 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1389 [ # # ]: 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1390 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(cq->roc_nix)) {
1391 : 0 : aq->cq.lbp_ena = 0;
1392 : 0 : aq->cq_mask.lbp_ena = ~aq->cq_mask.lbp_ena;
1393 : : }
1394 : : }
1395 : :
1396 : 0 : rc = mbox_process(mbox);
1397 [ # # ]: 0 : if (rc) {
1398 : : mbox_put(mbox);
1399 : 0 : return rc;
1400 : : }
1401 : :
1402 : : mbox_put(mbox);
1403 : 0 : plt_free(cq->desc_base);
1404 : 0 : return 0;
1405 : : }
1406 : :
1407 : : static int
1408 : 0 : sqb_pool_populate(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1409 : : {
1410 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1411 : : uint16_t sqes_per_sqb, count, nb_sqb_bufs, thr;
1412 : : struct npa_pool_s pool;
1413 : : struct npa_aura_s aura;
1414 : : uint64_t blk_sz;
1415 : : uint64_t iova;
1416 : : int rc;
1417 : :
1418 : 0 : blk_sz = nix->sqb_size;
1419 [ # # ]: 0 : if (sq->max_sqe_sz == roc_nix_maxsqesz_w16)
1420 : 0 : sqes_per_sqb = (blk_sz / 8) / 16;
1421 : : else
1422 : 0 : sqes_per_sqb = (blk_sz / 8) / 8;
1423 : :
1424 : : /* Reserve One SQE in each SQB to hold pointer for next SQB */
1425 : 0 : sqes_per_sqb -= 1;
1426 : :
1427 : 0 : sq->nb_desc = PLT_MAX(512U, sq->nb_desc);
1428 : 0 : nb_sqb_bufs = PLT_DIV_CEIL(sq->nb_desc, sqes_per_sqb);
1429 : 0 : thr = PLT_DIV_CEIL((nb_sqb_bufs * ROC_NIX_SQB_THRESH), 100);
1430 : 0 : nb_sqb_bufs += NIX_SQB_PREFETCH;
1431 : : /* Clamp up the SQB count */
1432 : 0 : nb_sqb_bufs = PLT_MAX(NIX_DEF_SQB, nb_sqb_bufs);
1433 : 0 : nb_sqb_bufs = PLT_MIN(roc_nix->max_sqb_count, (uint16_t)nb_sqb_bufs);
1434 : :
1435 [ # # ]: 0 : sq->nb_sqb_bufs = nb_sqb_bufs;
1436 : 0 : sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb);
1437 : 0 : sq->nb_sqb_bufs_adj = nb_sqb_bufs;
1438 : :
1439 [ # # ]: 0 : if (roc_nix->sqb_slack)
1440 : 0 : nb_sqb_bufs += roc_nix->sqb_slack;
1441 : : else
1442 : 0 : nb_sqb_bufs += PLT_MAX((int)thr, (int)ROC_NIX_SQB_SLACK_DFLT);
1443 : : /* Explicitly set nat_align alone as by default pool is with both
1444 : : * nat_align and buf_offset = 1 which we don't want for SQB.
1445 : : */
1446 : : memset(&pool, 0, sizeof(struct npa_pool_s));
1447 : 0 : pool.nat_align = 1;
1448 : :
1449 : : memset(&aura, 0, sizeof(aura));
1450 [ # # ]: 0 : aura.fc_ena = 1;
1451 [ # # # # ]: 0 : if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp())
1452 : : aura.fc_stype = 0x0; /* STF */
1453 : : else
1454 : 0 : aura.fc_stype = 0x3; /* STSTP */
1455 : 0 : aura.fc_addr = (uint64_t)sq->fc;
1456 : 0 : aura.fc_hyst_bits = sq->fc_hyst_bits & 0xF;
1457 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, nb_sqb_bufs, &aura, &pool, 0);
1458 [ # # ]: 0 : if (rc)
1459 : 0 : goto fail;
1460 : :
1461 : 0 : roc_npa_buf_type_update(sq->aura_handle, ROC_NPA_BUF_TYPE_SQB, 1);
1462 : 0 : sq->sqe_mem = plt_zmalloc(blk_sz * nb_sqb_bufs, blk_sz);
1463 [ # # ]: 0 : if (sq->sqe_mem == NULL) {
1464 : : rc = NIX_ERR_NO_MEM;
1465 : 0 : goto nomem;
1466 : : }
1467 : :
1468 : : /* Fill the initial buffers */
1469 : 0 : iova = (uint64_t)sq->sqe_mem;
1470 [ # # ]: 0 : for (count = 0; count < nb_sqb_bufs; count++) {
1471 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, iova);
1472 : 0 : iova += blk_sz;
1473 : : }
1474 : :
1475 [ # # ]: 0 : if (roc_npa_aura_op_available_wait(sq->aura_handle, nb_sqb_bufs, 0) !=
1476 : : nb_sqb_bufs) {
1477 : 0 : plt_err("Failed to free all pointers to the pool");
1478 : : rc = NIX_ERR_NO_MEM;
1479 : 0 : goto npa_fail;
1480 : : }
1481 : :
1482 : 0 : roc_npa_pool_op_range_set(sq->aura_handle, (uint64_t)sq->sqe_mem, iova);
1483 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
1484 : 0 : sq->aura_sqb_bufs = nb_sqb_bufs;
1485 : :
1486 : 0 : return rc;
1487 : : npa_fail:
1488 : 0 : plt_free(sq->sqe_mem);
1489 : 0 : nomem:
1490 : 0 : roc_npa_pool_destroy(sq->aura_handle);
1491 : : fail:
1492 : : return rc;
1493 : : }
1494 : :
1495 : : static int
1496 : 0 : sq_cn9k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum,
1497 : : uint16_t smq)
1498 : : {
1499 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1500 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1501 : : struct nix_aq_enq_req *aq;
1502 : :
1503 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1504 [ # # ]: 0 : if (!aq)
1505 : : return -ENOSPC;
1506 : :
1507 : 0 : aq->qidx = sq->qid;
1508 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1509 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1510 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1511 : :
1512 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1513 : 0 : aq->sq.smq = smq;
1514 : 0 : aq->sq.smq_rr_quantum = rr_quantum;
1515 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1516 : 0 : aq->sq.default_chan =
1517 : 0 : nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1518 : : else
1519 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1520 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1521 : 0 : aq->sq.ena = 1;
1522 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1523 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1524 : 0 : aq->sq.cq = sq->cqid;
1525 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1526 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1527 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1528 : 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1529 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1530 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1531 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1532 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1533 : :
1534 : : /* Many to one reduction */
1535 : 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1536 : :
1537 : 0 : return 0;
1538 : : }
1539 : :
1540 : : static int
1541 : 0 : sq_cn9k_fini(struct nix *nix, struct roc_nix_sq *sq)
1542 : : {
1543 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1544 : : struct nix_aq_enq_rsp *rsp;
1545 : : struct nix_aq_enq_req *aq;
1546 : : uint16_t sqes_per_sqb;
1547 : : void *sqb_buf;
1548 : : int rc, count;
1549 : :
1550 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1551 [ # # ]: 0 : if (!aq) {
1552 : : mbox_put(mbox);
1553 : 0 : return -ENOSPC;
1554 : : }
1555 : :
1556 : 0 : aq->qidx = sq->qid;
1557 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1558 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1559 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1560 [ # # ]: 0 : if (rc) {
1561 : : mbox_put(mbox);
1562 : 0 : return rc;
1563 : : }
1564 : :
1565 : : /* Check if sq is already cleaned up */
1566 [ # # ]: 0 : if (!rsp->sq.ena) {
1567 : : mbox_put(mbox);
1568 : 0 : return 0;
1569 : : }
1570 : :
1571 : : /* Disable sq */
1572 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1573 [ # # ]: 0 : if (!aq) {
1574 : : mbox_put(mbox);
1575 : 0 : return -ENOSPC;
1576 : : }
1577 : :
1578 : 0 : aq->qidx = sq->qid;
1579 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1580 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1581 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1582 : 0 : aq->sq.ena = 0;
1583 : 0 : rc = mbox_process(mbox);
1584 [ # # ]: 0 : if (rc) {
1585 : : mbox_put(mbox);
1586 : 0 : return rc;
1587 : : }
1588 : :
1589 : : /* Read SQ and free sqb's */
1590 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1591 [ # # ]: 0 : if (!aq) {
1592 : : mbox_put(mbox);
1593 : 0 : return -ENOSPC;
1594 : : }
1595 : :
1596 : 0 : aq->qidx = sq->qid;
1597 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1598 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1599 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1600 [ # # ]: 0 : if (rc) {
1601 : : mbox_put(mbox);
1602 : 0 : return rc;
1603 : : }
1604 : :
1605 [ # # ]: 0 : if (aq->sq.smq_pend)
1606 : 0 : plt_err("SQ has pending SQE's");
1607 : :
1608 : 0 : count = aq->sq.sqb_count;
1609 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1610 : : /* Free SQB's that are used */
1611 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1612 [ # # ]: 0 : while (count) {
1613 : : void *next_sqb;
1614 : :
1615 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1616 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1617 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1618 : : sqb_buf = next_sqb;
1619 : 0 : count--;
1620 : : }
1621 : :
1622 : : /* Free next to use sqb */
1623 [ # # ]: 0 : if (rsp->sq.next_sqb)
1624 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1625 : : mbox_put(mbox);
1626 : 0 : return 0;
1627 : : }
1628 : :
1629 : : static int
1630 : 0 : sq_cn10k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1631 : : {
1632 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1633 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1634 : : struct nix_cn10k_aq_enq_req *aq;
1635 : :
1636 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1637 [ # # ]: 0 : if (!aq)
1638 : : return -ENOSPC;
1639 : :
1640 : 0 : aq->qidx = sq->qid;
1641 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1642 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1643 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1644 : :
1645 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1646 : 0 : aq->sq.smq = smq;
1647 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1648 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1649 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1650 : : else
1651 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1652 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1653 : 0 : aq->sq.ena = 1;
1654 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1655 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1656 : 0 : aq->sq.cq = sq->cqid;
1657 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1658 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1659 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1660 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1661 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1662 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1663 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1664 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1665 : :
1666 : : /* Many to one reduction */
1667 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1668 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1669 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1670 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1671 : : * might result in software missing the interrupt.
1672 : : */
1673 : 0 : aq->sq.qint_idx = 0;
1674 : : }
1675 : : return 0;
1676 : : }
1677 : :
1678 : : static int
1679 : 0 : sq_cn10k_fini(struct nix *nix, struct roc_nix_sq *sq)
1680 : : {
1681 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1682 : : struct nix_cn10k_aq_enq_rsp *rsp;
1683 : : struct nix_cn10k_aq_enq_req *aq;
1684 : : uint16_t sqes_per_sqb;
1685 : : void *sqb_buf;
1686 : : int rc, count;
1687 : :
1688 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1689 [ # # ]: 0 : if (!aq) {
1690 : : mbox_put(mbox);
1691 : 0 : return -ENOSPC;
1692 : : }
1693 : :
1694 : 0 : aq->qidx = sq->qid;
1695 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1696 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1697 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1698 [ # # ]: 0 : if (rc) {
1699 : : mbox_put(mbox);
1700 : 0 : return rc;
1701 : : }
1702 : :
1703 : : /* Check if sq is already cleaned up */
1704 [ # # ]: 0 : if (!rsp->sq.ena) {
1705 : : mbox_put(mbox);
1706 : 0 : return 0;
1707 : : }
1708 : :
1709 : : /* Disable sq */
1710 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1711 [ # # ]: 0 : if (!aq) {
1712 : : mbox_put(mbox);
1713 : 0 : return -ENOSPC;
1714 : : }
1715 : :
1716 : 0 : aq->qidx = sq->qid;
1717 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1718 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1719 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1720 : 0 : aq->sq.ena = 0;
1721 : 0 : rc = mbox_process(mbox);
1722 [ # # ]: 0 : if (rc) {
1723 : : mbox_put(mbox);
1724 : 0 : return rc;
1725 : : }
1726 : :
1727 : : /* Read SQ and free sqb's */
1728 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1729 [ # # ]: 0 : if (!aq) {
1730 : : mbox_put(mbox);
1731 : 0 : return -ENOSPC;
1732 : : }
1733 : :
1734 : 0 : aq->qidx = sq->qid;
1735 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1736 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1737 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1738 [ # # ]: 0 : if (rc) {
1739 : : mbox_put(mbox);
1740 : 0 : return rc;
1741 : : }
1742 : :
1743 [ # # ]: 0 : if (aq->sq.smq_pend)
1744 : 0 : plt_err("SQ has pending SQE's");
1745 : :
1746 : 0 : count = aq->sq.sqb_count;
1747 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1748 : : /* Free SQB's that are used */
1749 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1750 [ # # ]: 0 : while (count) {
1751 : : void *next_sqb;
1752 : :
1753 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1754 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1755 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1756 : : sqb_buf = next_sqb;
1757 : 0 : count--;
1758 : : }
1759 : :
1760 : : /* Free next to use sqb */
1761 [ # # ]: 0 : if (rsp->sq.next_sqb)
1762 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1763 : : mbox_put(mbox);
1764 : 0 : return 0;
1765 : : }
1766 : :
1767 : : static int
1768 : 0 : sq_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1769 : : {
1770 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1771 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1772 : : struct nix_cn20k_aq_enq_req *aq;
1773 : :
1774 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1775 [ # # ]: 0 : if (!aq)
1776 : : return -ENOSPC;
1777 : :
1778 : 0 : aq->qidx = sq->qid;
1779 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1780 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1781 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1782 : :
1783 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1784 : 0 : aq->sq.smq = smq;
1785 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1786 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1787 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1788 : : else
1789 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1790 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1791 : 0 : aq->sq.ena = 1;
1792 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1793 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1794 : 0 : aq->sq.cq = sq->cqid;
1795 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1796 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1797 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1798 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1799 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1800 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1801 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1802 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1803 : :
1804 : : /* Many to one reduction */
1805 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1806 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1807 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1808 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1809 : : * might result in software missing the interrupt.
1810 : : */
1811 : 0 : aq->sq.qint_idx = 0;
1812 : : }
1813 : : return 0;
1814 : : }
1815 : :
1816 : : static int
1817 : 0 : sq_fini(struct nix *nix, struct roc_nix_sq *sq)
1818 : : {
1819 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1820 : : struct nix_cn20k_aq_enq_rsp *rsp;
1821 : : struct nix_cn20k_aq_enq_req *aq;
1822 : : uint16_t sqes_per_sqb;
1823 : : void *sqb_buf;
1824 : : int rc, count;
1825 : :
1826 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1827 [ # # ]: 0 : if (!aq) {
1828 : : mbox_put(mbox);
1829 : 0 : return -ENOSPC;
1830 : : }
1831 : :
1832 : 0 : aq->qidx = sq->qid;
1833 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1834 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1835 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1836 [ # # ]: 0 : if (rc) {
1837 : : mbox_put(mbox);
1838 : 0 : return rc;
1839 : : }
1840 : :
1841 : : /* Check if sq is already cleaned up */
1842 [ # # ]: 0 : if (!rsp->sq.ena) {
1843 : : mbox_put(mbox);
1844 : 0 : return 0;
1845 : : }
1846 : :
1847 : : /* Disable sq */
1848 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1849 [ # # ]: 0 : if (!aq) {
1850 : : mbox_put(mbox);
1851 : 0 : return -ENOSPC;
1852 : : }
1853 : :
1854 : 0 : aq->qidx = sq->qid;
1855 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1856 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1857 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1858 : 0 : aq->sq.ena = 0;
1859 : 0 : rc = mbox_process(mbox);
1860 [ # # ]: 0 : if (rc) {
1861 : : mbox_put(mbox);
1862 : 0 : return rc;
1863 : : }
1864 : :
1865 : : /* Read SQ and free sqb's */
1866 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1867 [ # # ]: 0 : if (!aq) {
1868 : : mbox_put(mbox);
1869 : 0 : return -ENOSPC;
1870 : : }
1871 : :
1872 : 0 : aq->qidx = sq->qid;
1873 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1874 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1875 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1876 [ # # ]: 0 : if (rc) {
1877 : : mbox_put(mbox);
1878 : 0 : return rc;
1879 : : }
1880 : :
1881 [ # # ]: 0 : if (aq->sq.smq_pend)
1882 : 0 : plt_err("SQ has pending SQE's");
1883 : :
1884 : 0 : count = aq->sq.sqb_count;
1885 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1886 : : /* Free SQB's that are used */
1887 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1888 [ # # ]: 0 : while (count) {
1889 : : void *next_sqb;
1890 : :
1891 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1892 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1893 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1894 : : sqb_buf = next_sqb;
1895 : 0 : count--;
1896 : : }
1897 : :
1898 : : /* Free next to use sqb */
1899 [ # # ]: 0 : if (rsp->sq.next_sqb)
1900 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1901 : : mbox_put(mbox);
1902 : 0 : return 0;
1903 : : }
1904 : :
1905 : : int
1906 [ # # ]: 0 : roc_nix_sq_init(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1907 : : {
1908 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1909 : 0 : struct mbox *m_box = (&nix->dev)->mbox;
1910 : 0 : uint16_t qid, smq = UINT16_MAX;
1911 : 0 : uint32_t rr_quantum = 0;
1912 : : struct mbox *mbox;
1913 : : int rc;
1914 : :
1915 [ # # ]: 0 : if (sq == NULL)
1916 : : return NIX_ERR_PARAM;
1917 : :
1918 : 0 : qid = sq->qid;
1919 [ # # ]: 0 : if (qid >= nix->nb_tx_queues)
1920 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1921 : :
1922 : 0 : sq->roc_nix = roc_nix;
1923 : 0 : sq->tc = ROC_NIX_PFC_CLASS_INVALID;
1924 : : /*
1925 : : * Allocate memory for flow control updates from HW.
1926 : : * Alloc one cache line, so that fits all FC_STYPE modes.
1927 : : */
1928 : 0 : sq->fc = plt_zmalloc(ROC_ALIGN, ROC_ALIGN);
1929 [ # # ]: 0 : if (sq->fc == NULL) {
1930 : : rc = NIX_ERR_NO_MEM;
1931 : 0 : goto fail;
1932 : : }
1933 : :
1934 : 0 : rc = sqb_pool_populate(roc_nix, sq);
1935 [ # # ]: 0 : if (rc)
1936 : 0 : goto nomem;
1937 : :
1938 : 0 : rc = nix_tm_leaf_data_get(nix, sq->qid, &rr_quantum, &smq);
1939 [ # # ]: 0 : if (rc) {
1940 : : rc = NIX_ERR_TM_LEAF_NODE_GET;
1941 : 0 : goto nomem;
1942 : : }
1943 : :
1944 : : mbox = mbox_get(m_box);
1945 : : /* Init SQ context */
1946 [ # # ]: 0 : if (roc_model_is_cn9k())
1947 : 0 : rc = sq_cn9k_init(nix, sq, rr_quantum, smq);
1948 [ # # ]: 0 : else if (roc_model_is_cn10k())
1949 : 0 : rc = sq_cn10k_init(nix, sq, rr_quantum, smq);
1950 : : else
1951 : 0 : rc = sq_init(nix, sq, rr_quantum, smq);
1952 : :
1953 [ # # ]: 0 : if (rc) {
1954 : : mbox_put(mbox);
1955 : 0 : goto nomem;
1956 : : }
1957 : :
1958 : :
1959 : 0 : rc = mbox_process(mbox);
1960 [ # # ]: 0 : if (rc) {
1961 : : mbox_put(mbox);
1962 : 0 : goto nomem;
1963 : : }
1964 : : mbox_put(mbox);
1965 : :
1966 : 0 : sq->enable = true;
1967 : 0 : nix->sqs[qid] = sq;
1968 [ # # ]: 0 : sq->io_addr = nix->base + NIX_LF_OP_SENDX(0);
1969 : : /* Evenly distribute LMT slot for each sq */
1970 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1971 : : /* Multiple cores/SQ's can use same LMTLINE safely in CN9K */
1972 : 0 : sq->lmt_addr = (void *)(nix->lmt_base +
1973 : 0 : ((qid & RVU_CN9K_LMT_SLOT_MASK) << 12));
1974 : : }
1975 : :
1976 : 0 : rc = nix_tel_node_add_sq(sq);
1977 : 0 : return rc;
1978 : 0 : nomem:
1979 : 0 : plt_free(sq->fc);
1980 : : fail:
1981 : : return rc;
1982 : : }
1983 : :
1984 : : int
1985 : 0 : roc_nix_sq_fini(struct roc_nix_sq *sq)
1986 : : {
1987 : : struct nix *nix;
1988 : : struct mbox *mbox;
1989 : : struct ndc_sync_op *ndc_req;
1990 : : uint16_t qid;
1991 : : int rc = 0;
1992 : :
1993 [ # # ]: 0 : if (sq == NULL)
1994 : : return NIX_ERR_PARAM;
1995 : :
1996 : 0 : nix = roc_nix_to_nix_priv(sq->roc_nix);
1997 : 0 : mbox = (&nix->dev)->mbox;
1998 : :
1999 : 0 : qid = sq->qid;
2000 : :
2001 : 0 : rc = nix_tm_sq_flush_pre(sq);
2002 : :
2003 : : /* Release SQ context */
2004 [ # # ]: 0 : if (roc_model_is_cn9k())
2005 : 0 : rc |= sq_cn9k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2006 [ # # ]: 0 : else if (roc_model_is_cn10k())
2007 : 0 : rc |= sq_cn10k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2008 : : else
2009 : 0 : rc |= sq_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2010 : :
2011 : : /* Sync NDC-NIX-TX for LF */
2012 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox_get(mbox));
2013 [ # # ]: 0 : if (ndc_req == NULL) {
2014 : : mbox_put(mbox);
2015 : 0 : return -ENOSPC;
2016 : : }
2017 : 0 : ndc_req->nix_lf_tx_sync = 1;
2018 [ # # ]: 0 : if (mbox_process(mbox))
2019 : 0 : rc |= NIX_ERR_NDC_SYNC;
2020 : : mbox_put(mbox);
2021 : :
2022 : 0 : rc |= nix_tm_sq_flush_post(sq);
2023 : :
2024 : : /* Restore limit to max SQB count that the pool was created
2025 : : * for aura drain to succeed.
2026 : : */
2027 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, NIX_MAX_SQB);
2028 : 0 : rc |= roc_npa_pool_destroy(sq->aura_handle);
2029 : 0 : plt_free(sq->fc);
2030 : 0 : plt_free(sq->sqe_mem);
2031 : 0 : nix->sqs[qid] = NULL;
2032 : :
2033 : 0 : return rc;
2034 : : }
2035 : :
2036 : : void
2037 : 0 : roc_nix_cq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2038 : : uint32_t *tail)
2039 : : {
2040 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2041 : : uint64_t reg, val;
2042 : : int64_t *addr;
2043 : :
2044 [ # # ]: 0 : if (head == NULL || tail == NULL)
2045 : : return;
2046 : :
2047 : : reg = (((uint64_t)qid) << 32);
2048 : : addr = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
2049 : : val = roc_atomic64_add_nosync(reg, addr);
2050 : : if (val &
2051 : : (BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) | BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR)))
2052 : : val = 0;
2053 : :
2054 : 0 : *tail = (uint32_t)(val & 0xFFFFF);
2055 : 0 : *head = (uint32_t)((val >> 20) & 0xFFFFF);
2056 : : }
2057 : :
2058 : : void
2059 : 0 : roc_nix_sq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2060 : : uint32_t *tail)
2061 : : {
2062 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2063 : 0 : struct roc_nix_sq *sq = nix->sqs[qid];
2064 : : uint16_t sqes_per_sqb, sqb_cnt;
2065 : : uint64_t reg, val;
2066 : : int64_t *addr;
2067 : :
2068 [ # # ]: 0 : if (head == NULL || tail == NULL)
2069 : : return;
2070 : :
2071 : : reg = (((uint64_t)qid) << 32);
2072 : : addr = (int64_t *)(nix->base + NIX_LF_SQ_OP_STATUS);
2073 : : val = roc_atomic64_add_nosync(reg, addr);
2074 : : if (val & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR)) {
2075 : : val = 0;
2076 : : return;
2077 : : }
2078 : :
2079 : : *tail = (uint32_t)((val >> 28) & 0x3F);
2080 : 0 : *head = (uint32_t)((val >> 20) & 0x3F);
2081 : : sqb_cnt = (uint16_t)(val & 0xFFFF);
2082 : :
2083 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2084 : :
2085 : : /* Update tail index as per used sqb count */
2086 : 0 : *tail += (sqes_per_sqb * (sqb_cnt - 1));
2087 : : }
2088 : :
2089 : : int
2090 : 0 : roc_nix_q_err_cb_register(struct roc_nix *roc_nix, q_err_get_t sq_err_handle)
2091 : : {
2092 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2093 : : struct dev *dev = &nix->dev;
2094 : :
2095 [ # # ]: 0 : if (sq_err_handle == NULL)
2096 : : return NIX_ERR_PARAM;
2097 : :
2098 : 0 : dev->ops->q_err_cb = (q_err_cb_t)sq_err_handle;
2099 : 0 : return 0;
2100 : : }
2101 : :
2102 : : void
2103 : 0 : roc_nix_q_err_cb_unregister(struct roc_nix *roc_nix)
2104 : : {
2105 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2106 : : struct dev *dev = &nix->dev;
2107 : :
2108 : 0 : dev->ops->q_err_cb = NULL;
2109 : 0 : }
|