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 : : typedef void *(*nix_aq_enq_alloc_t)(struct mbox *mbox);
14 : :
15 : : static inline void
16 : : nix_aq_enq_write_rq_ena(void *msg, uint16_t qid, bool enable)
17 : : {
18 : : struct nix_aq_enq_req *aq = msg;
19 : :
20 : 0 : aq->qidx = qid;
21 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
22 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
23 : 0 : aq->rq.ena = enable;
24 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
25 : 0 : }
26 : :
27 : : static inline int
28 : 0 : nix_rq_bulk_ena_dis_fill(struct mbox *mbox, struct roc_nix_rq *rqs, int nb_rx_queues,
29 : : bool enable, nix_aq_enq_alloc_t alloc)
30 : : {
31 : : int i;
32 : :
33 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++) {
34 : : void *aq;
35 : : int rc;
36 : :
37 [ # # ]: 0 : if (rqs[i].qid == UINT16_MAX)
38 : 0 : continue;
39 : :
40 : 0 : aq = alloc(mbox);
41 [ # # ]: 0 : if (!aq) {
42 : 0 : rc = mbox_process(mbox);
43 [ # # ]: 0 : if (rc)
44 : 0 : return rc;
45 : 0 : aq = alloc(mbox);
46 [ # # ]: 0 : if (!aq)
47 : : return -ENOSPC;
48 : : }
49 : :
50 : 0 : nix_aq_enq_write_rq_ena(aq, rqs[i].qid, enable);
51 : : }
52 : :
53 : : return 0;
54 : : }
55 : :
56 : : static inline uint32_t
57 : : nix_qsize_to_val(enum nix_q_size qsize)
58 : : {
59 : 0 : return (16UL << (qsize * 2));
60 : : }
61 : :
62 : : static inline enum nix_q_size
63 : : nix_qsize_clampup(uint32_t val)
64 : : {
65 : : int i = nix_q_size_16;
66 : :
67 [ # # # # ]: 0 : for (; i < nix_q_size_max; i++)
68 [ # # # # ]: 0 : if (val <= nix_qsize_to_val(i))
69 : : break;
70 : :
71 [ # # # # ]: 0 : if (i >= nix_q_size_max)
72 : : i = nix_q_size_max - 1;
73 : :
74 : 0 : return i;
75 : : }
76 : :
77 : : void
78 [ # # ]: 0 : nix_rq_vwqe_flush(struct roc_nix_rq *rq, uint16_t vwqe_interval)
79 : : {
80 : : uint64_t wait_ns;
81 : :
82 [ # # ]: 0 : if (!roc_model_is_cn10k())
83 : : return;
84 : : /* Due to HW errata writes to VWQE_FLUSH might hang, so instead
85 : : * wait for max vwqe timeout interval.
86 : : */
87 [ # # ]: 0 : if (rq->vwqe_ena) {
88 : 0 : wait_ns = rq->vwqe_wait_tmo * (vwqe_interval + 1) * 100;
89 : 0 : plt_delay_us((wait_ns / 1E3) + 1);
90 : : }
91 : : }
92 : :
93 : : static int
94 : 0 : nix_rq_bulk_ena_dis(struct nix *nix, struct roc_nix_rq *rqs, int nb_rx_queues, bool enable)
95 : : {
96 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
97 : : nix_aq_enq_alloc_t alloc;
98 : : int rc;
99 : :
100 [ # # ]: 0 : if (roc_model_is_cn9k())
101 : : alloc = (nix_aq_enq_alloc_t)mbox_alloc_msg_nix_aq_enq;
102 [ # # ]: 0 : else if (roc_model_is_cn10k())
103 : : alloc = (nix_aq_enq_alloc_t)mbox_alloc_msg_nix_cn10k_aq_enq;
104 : : else /* CN20K */
105 : : alloc = (nix_aq_enq_alloc_t)mbox_alloc_msg_nix_cn20k_aq_enq;
106 : :
107 : 0 : rc = nix_rq_bulk_ena_dis_fill(mbox, rqs, nb_rx_queues, enable, alloc);
108 [ # # # # ]: 0 : if (!rc && mbox_nonempty_nolock(mbox, 0))
109 : 0 : rc = mbox_process(mbox);
110 : :
111 : : mbox_put(mbox);
112 : 0 : return rc;
113 : : }
114 : :
115 : : int
116 : 0 : nix_rq_ena_dis(struct dev *dev, struct roc_nix_rq *rq, bool enable)
117 : : {
118 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
119 : : int rc;
120 : :
121 : : /* Pkts will be dropped silently if RQ is disabled */
122 [ # # ]: 0 : if (roc_model_is_cn9k()) {
123 : : struct nix_aq_enq_req *aq;
124 : :
125 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
126 [ # # ]: 0 : if (!aq) {
127 : : rc = -ENOSPC;
128 : 0 : goto exit;
129 : : }
130 : :
131 : 0 : aq->qidx = rq->qid;
132 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
133 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
134 : :
135 : 0 : aq->rq.ena = enable;
136 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
137 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
138 : : struct nix_cn10k_aq_enq_req *aq;
139 : :
140 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
141 [ # # ]: 0 : if (!aq) {
142 : : rc = -ENOSPC;
143 : 0 : goto exit;
144 : : }
145 : :
146 : 0 : aq->qidx = rq->qid;
147 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
148 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
149 : :
150 : 0 : aq->rq.ena = enable;
151 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
152 : : } else {
153 : : struct nix_cn20k_aq_enq_req *aq;
154 : :
155 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
156 [ # # ]: 0 : if (!aq) {
157 : : rc = -ENOSPC;
158 : 0 : goto exit;
159 : : }
160 : :
161 : 0 : aq->qidx = rq->qid;
162 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
163 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
164 : :
165 : 0 : aq->rq.ena = enable;
166 : 0 : aq->rq_mask.ena = ~(aq->rq_mask.ena);
167 : : }
168 : :
169 : 0 : rc = mbox_process(mbox);
170 : 0 : exit:
171 : : mbox_put(mbox);
172 : 0 : return rc;
173 : : }
174 : :
175 : : int
176 : 0 : roc_nix_sq_ena_dis(struct roc_nix_sq *sq, bool enable)
177 : : {
178 : : int rc = 0;
179 : :
180 [ # # ]: 0 : if (!sq) {
181 : : rc = NIX_ERR_PARAM;
182 : 0 : goto done;
183 : : }
184 : :
185 : 0 : rc = roc_nix_tm_sq_aura_fc(sq, enable);
186 [ # # ]: 0 : if (rc)
187 : 0 : goto done;
188 : :
189 : 0 : sq->enable = enable;
190 : 0 : done:
191 : 0 : return rc;
192 : : }
193 : :
194 : : int
195 : 0 : roc_nix_rq_multi_ena_dis(struct roc_nix *roc_nix, struct roc_nix_rq *rqs, int nb_rx_queues,
196 : : bool enable)
197 : : {
198 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
199 : : struct roc_nix_rq *rq;
200 : : int rc, i;
201 : :
202 : 0 : rc = nix_rq_bulk_ena_dis(nix, rqs, nb_rx_queues, enable);
203 [ # # ]: 0 : if (rc) {
204 [ # # ]: 0 : plt_err("Failed to %s Rx queues rc=%d pf=%d vf=%d nb_rx_queues=%d",
205 : : enable ? "enable" : "disable", rc, nix->dev.pf, nix->dev.vf,
206 : : nb_rx_queues);
207 : 0 : return rc;
208 : : }
209 : :
210 [ # # ]: 0 : for (i = 0; i < nb_rx_queues; i++) {
211 : 0 : rq = &rqs[i];
212 : :
213 [ # # ]: 0 : if (rq->qid == UINT16_MAX)
214 : 0 : continue;
215 : :
216 : 0 : nix_rq_vwqe_flush(rq, nix->vwqe_interval);
217 : :
218 : : /* Check for meta aura if RQ is enabled */
219 [ # # # # ]: 0 : if (enable && nix->need_meta_aura) {
220 : 0 : rc = roc_nix_inl_meta_aura_check(rq->roc_nix, rq);
221 [ # # ]: 0 : if (rc) {
222 : 0 : plt_err("Failed meta aura check for rq=%u rc=%d pf=%d vf=%d",
223 : : rq->qid, rc, nix->dev.pf, nix->dev.vf);
224 : 0 : return rc;
225 : : }
226 : : }
227 : : }
228 : : return 0;
229 : : }
230 : :
231 : : int
232 : 0 : roc_nix_rq_ena_dis(struct roc_nix_rq *rq, bool enable)
233 : : {
234 : 0 : struct nix *nix = roc_nix_to_nix_priv(rq->roc_nix);
235 : : int rc;
236 : :
237 : 0 : rc = nix_rq_ena_dis(&nix->dev, rq, enable);
238 : 0 : nix_rq_vwqe_flush(rq, nix->vwqe_interval);
239 [ # # ]: 0 : if (rc)
240 : : return rc;
241 : :
242 : : /* Check for meta aura if RQ is enabled */
243 [ # # # # ]: 0 : if (enable && nix->need_meta_aura)
244 : 0 : rc = roc_nix_inl_meta_aura_check(rq->roc_nix, rq);
245 : : return rc;
246 : : }
247 : :
248 : : int
249 : 0 : roc_nix_rq_is_sso_enable(struct roc_nix *roc_nix, uint32_t qid)
250 : : {
251 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
252 : : struct dev *dev = &nix->dev;
253 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
254 : : bool sso_enable;
255 : : int rc;
256 : :
257 [ # # ]: 0 : if (roc_model_is_cn9k()) {
258 : : struct nix_aq_enq_rsp *rsp;
259 : : struct nix_aq_enq_req *aq;
260 : :
261 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
262 [ # # ]: 0 : if (!aq) {
263 : : rc = -ENOSPC;
264 : 0 : goto exit;
265 : : }
266 : :
267 : 0 : aq->qidx = qid;
268 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
269 : 0 : aq->op = NIX_AQ_INSTOP_READ;
270 : : rc = mbox_process_msg(mbox, (void *)&rsp);
271 [ # # ]: 0 : if (rc)
272 : 0 : goto exit;
273 : :
274 : 0 : sso_enable = rsp->rq.sso_ena;
275 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
276 : : struct nix_cn10k_aq_enq_rsp *rsp;
277 : : struct nix_cn10k_aq_enq_req *aq;
278 : :
279 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
280 [ # # ]: 0 : if (!aq) {
281 : : rc = -ENOSPC;
282 : 0 : goto exit;
283 : : }
284 : :
285 : 0 : aq->qidx = qid;
286 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
287 : 0 : aq->op = NIX_AQ_INSTOP_READ;
288 : :
289 : : rc = mbox_process_msg(mbox, (void *)&rsp);
290 [ # # ]: 0 : if (rc)
291 : 0 : goto exit;
292 : :
293 : 0 : sso_enable = rsp->rq.sso_ena;
294 : : } else {
295 : : struct nix_cn20k_aq_enq_rsp *rsp;
296 : : struct nix_cn20k_aq_enq_req *aq;
297 : :
298 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
299 [ # # ]: 0 : if (!aq) {
300 : : rc = -ENOSPC;
301 : 0 : goto exit;
302 : : }
303 : :
304 : 0 : aq->qidx = qid;
305 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
306 : 0 : aq->op = NIX_AQ_INSTOP_READ;
307 : :
308 : : rc = mbox_process_msg(mbox, (void *)&rsp);
309 [ # # ]: 0 : if (rc)
310 : 0 : goto exit;
311 : :
312 : 0 : sso_enable = rsp->rq.sso_ena;
313 : : }
314 : :
315 : 0 : rc = sso_enable ? true : false;
316 : 0 : exit:
317 : : mbox_put(mbox);
318 : 0 : return rc;
319 : : }
320 : :
321 : : static int
322 : 0 : nix_rq_aura_buf_type_update(struct roc_nix_rq *rq, bool set)
323 : : {
324 : 0 : struct roc_nix *roc_nix = rq->roc_nix;
325 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
326 : 0 : bool inl_inb_ena = roc_nix_inl_inb_is_enabled(roc_nix);
327 : : uint64_t lpb_aura = 0, vwqe_aura = 0, spb_aura = 0;
328 : 0 : struct mbox *mbox = nix->dev.mbox;
329 : : uint64_t aura_base;
330 : : int rc, count;
331 : :
332 [ # # ]: 0 : count = set ? 1 : -1;
333 : : /* For buf type set, use info from RQ context */
334 [ # # ]: 0 : if (set) {
335 : 0 : lpb_aura = rq->aura_handle;
336 [ # # ]: 0 : spb_aura = rq->spb_ena ? rq->spb_aura_handle : 0;
337 [ # # ]: 0 : vwqe_aura = rq->vwqe_ena ? rq->vwqe_aura_handle : 0;
338 : 0 : goto skip_ctx_read;
339 : : }
340 : :
341 [ # # ]: 0 : aura_base = roc_npa_aura_handle_to_base(rq->aura_handle);
342 [ # # ]: 0 : if (roc_model_is_cn9k()) {
343 : : struct nix_aq_enq_rsp *rsp;
344 : : struct nix_aq_enq_req *aq;
345 : :
346 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox_get(mbox));
347 [ # # ]: 0 : if (!aq) {
348 : : mbox_put(mbox);
349 : 0 : return -ENOSPC;
350 : : }
351 : :
352 : 0 : aq->qidx = rq->qid;
353 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
354 : 0 : aq->op = NIX_AQ_INSTOP_READ;
355 : : rc = mbox_process_msg(mbox, (void *)&rsp);
356 [ # # ]: 0 : if (rc) {
357 : : mbox_put(mbox);
358 : 0 : return rc;
359 : : }
360 : :
361 : : /* Get aura handle from aura */
362 [ # # ]: 0 : lpb_aura = roc_npa_aura_handle_gen(rsp->rq.lpb_aura, aura_base);
363 [ # # ]: 0 : if (rsp->rq.spb_ena)
364 : 0 : spb_aura = roc_npa_aura_handle_gen(rsp->rq.spb_aura, aura_base);
365 : : mbox_put(mbox);
366 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
367 : : struct nix_cn10k_aq_enq_rsp *rsp;
368 : : struct nix_cn10k_aq_enq_req *aq;
369 : :
370 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox_get(mbox));
371 [ # # ]: 0 : if (!aq) {
372 : : mbox_put(mbox);
373 : 0 : return -ENOSPC;
374 : : }
375 : :
376 : 0 : aq->qidx = rq->qid;
377 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
378 : 0 : aq->op = NIX_AQ_INSTOP_READ;
379 : :
380 : : rc = mbox_process_msg(mbox, (void *)&rsp);
381 [ # # ]: 0 : if (rc) {
382 : : mbox_put(mbox);
383 : 0 : return rc;
384 : : }
385 : :
386 : : /* Get aura handle from aura */
387 [ # # ]: 0 : lpb_aura = roc_npa_aura_handle_gen(rsp->rq.lpb_aura, aura_base);
388 [ # # ]: 0 : if (rsp->rq.spb_ena)
389 : 0 : spb_aura = roc_npa_aura_handle_gen(rsp->rq.spb_aura, aura_base);
390 [ # # ]: 0 : if (rsp->rq.vwqe_ena)
391 : 0 : vwqe_aura = roc_npa_aura_handle_gen(rsp->rq.wqe_aura, aura_base);
392 : :
393 : : mbox_put(mbox);
394 : : } else {
395 : : struct nix_cn20k_aq_enq_rsp *rsp;
396 : : struct nix_cn20k_aq_enq_req *aq;
397 : :
398 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox_get(mbox));
399 [ # # ]: 0 : if (!aq) {
400 : : mbox_put(mbox);
401 : 0 : return -ENOSPC;
402 : : }
403 : :
404 : 0 : aq->qidx = rq->qid;
405 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
406 : 0 : aq->op = NIX_AQ_INSTOP_READ;
407 : :
408 : : rc = mbox_process_msg(mbox, (void *)&rsp);
409 [ # # ]: 0 : if (rc) {
410 : : mbox_put(mbox);
411 : 0 : return rc;
412 : : }
413 : :
414 : : /* Get aura handle from aura */
415 [ # # ]: 0 : lpb_aura = roc_npa_aura_handle_gen(rsp->rq.lpb_aura, aura_base);
416 [ # # ]: 0 : if (rsp->rq.spb_ena)
417 : 0 : spb_aura = roc_npa_aura_handle_gen(rsp->rq.spb_aura, aura_base);
418 : :
419 : : mbox_put(mbox);
420 : : }
421 : :
422 : 0 : skip_ctx_read:
423 : : /* Update attributes for LPB aura */
424 [ # # ]: 0 : if (inl_inb_ena)
425 : 0 : roc_npa_buf_type_update(lpb_aura, ROC_NPA_BUF_TYPE_PACKET_IPSEC, count);
426 : : else
427 : 0 : roc_npa_buf_type_update(lpb_aura, ROC_NPA_BUF_TYPE_PACKET, count);
428 : :
429 : : /* Update attributes for SPB aura */
430 [ # # ]: 0 : if (spb_aura) {
431 [ # # ]: 0 : if (inl_inb_ena)
432 : 0 : roc_npa_buf_type_update(spb_aura, ROC_NPA_BUF_TYPE_PACKET_IPSEC, count);
433 : : else
434 : 0 : roc_npa_buf_type_update(spb_aura, ROC_NPA_BUF_TYPE_PACKET, count);
435 : : }
436 : :
437 : : /* Update attributes for VWQE aura */
438 [ # # ]: 0 : if (vwqe_aura) {
439 [ # # ]: 0 : if (inl_inb_ena)
440 : 0 : roc_npa_buf_type_update(vwqe_aura, ROC_NPA_BUF_TYPE_VWQE_IPSEC, count);
441 : : else
442 : 0 : roc_npa_buf_type_update(vwqe_aura, ROC_NPA_BUF_TYPE_VWQE, count);
443 : : }
444 : :
445 : : return 0;
446 : : }
447 : :
448 : : static int
449 : 0 : nix_rq_cn9k_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
450 : : {
451 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
452 : : struct nix_aq_enq_req *aq;
453 : : int rc;
454 : :
455 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
456 [ # # ]: 0 : if (!aq) {
457 : : rc = -ENOSPC;
458 : 0 : goto exit;
459 : : }
460 : :
461 : 0 : aq->qidx = rq->qid;
462 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
463 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
464 : :
465 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
466 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
467 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
468 : 0 : aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
469 : 0 : aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
470 : :
471 : : }
472 : :
473 [ # # # # ]: 0 : if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
474 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
475 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
476 : 0 : aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
477 : 0 : aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
478 : :
479 : : }
480 : :
481 [ # # # # ]: 0 : if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
482 : 0 : aq->rq.xqe_pass = rq->xqe_red_pass;
483 : 0 : aq->rq.xqe_drop = rq->xqe_red_drop;
484 : 0 : aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
485 : 0 : aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
486 : : }
487 : :
488 : 0 : rc = mbox_process(mbox);
489 : 0 : exit:
490 : : mbox_put(mbox);
491 : 0 : return rc;
492 : : }
493 : :
494 : : static int
495 : 0 : nix_rq_cn10k_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
496 : : {
497 : : struct nix_cn10k_aq_enq_req *aq;
498 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
499 : : int rc;
500 : :
501 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
502 [ # # ]: 0 : if (!aq) {
503 : : rc = -ENOSPC;
504 : 0 : goto exit;
505 : : }
506 : :
507 : 0 : aq->qidx = rq->qid;
508 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
509 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
510 : :
511 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
512 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
513 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
514 : 0 : aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
515 : 0 : aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
516 : : }
517 : :
518 [ # # # # ]: 0 : if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
519 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
520 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
521 : 0 : aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
522 : 0 : aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
523 : : }
524 : :
525 [ # # # # ]: 0 : if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
526 : 0 : aq->rq.xqe_pass = rq->xqe_red_pass;
527 : 0 : aq->rq.xqe_drop = rq->xqe_red_drop;
528 : 0 : aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
529 : 0 : aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
530 : : }
531 : :
532 : 0 : rc = mbox_process(mbox);
533 : 0 : exit:
534 : : mbox_put(mbox);
535 : 0 : return rc;
536 : : }
537 : :
538 : : static int
539 : 0 : nix_rq_cman_cfg(struct dev *dev, struct roc_nix_rq *rq)
540 : : {
541 : : struct nix_cn20k_aq_enq_req *aq;
542 : 0 : struct mbox *mbox = mbox_get(dev->mbox);
543 : : int rc;
544 : :
545 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
546 [ # # ]: 0 : if (!aq) {
547 : : rc = -ENOSPC;
548 : 0 : goto exit;
549 : : }
550 : :
551 : 0 : aq->qidx = rq->qid;
552 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
553 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
554 : :
555 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
556 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
557 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
558 : 0 : aq->rq_mask.lpb_pool_pass = ~(aq->rq_mask.lpb_pool_pass);
559 : 0 : aq->rq_mask.lpb_pool_drop = ~(aq->rq_mask.lpb_pool_drop);
560 : : }
561 : :
562 [ # # # # ]: 0 : if (rq->spb_red_pass && (rq->spb_red_pass >= rq->spb_red_drop)) {
563 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
564 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
565 : 0 : aq->rq_mask.spb_pool_pass = ~(aq->rq_mask.spb_pool_pass);
566 : 0 : aq->rq_mask.spb_pool_drop = ~(aq->rq_mask.spb_pool_drop);
567 : : }
568 : :
569 [ # # # # ]: 0 : if (rq->xqe_red_pass && (rq->xqe_red_pass >= rq->xqe_red_drop)) {
570 : 0 : aq->rq.xqe_pass = rq->xqe_red_pass;
571 : 0 : aq->rq.xqe_drop = rq->xqe_red_drop;
572 : 0 : aq->rq_mask.xqe_drop = ~(aq->rq_mask.xqe_drop);
573 : 0 : aq->rq_mask.xqe_pass = ~(aq->rq_mask.xqe_pass);
574 : : }
575 : :
576 : 0 : rc = mbox_process(mbox);
577 : 0 : exit:
578 : : mbox_put(mbox);
579 : 0 : return rc;
580 : : }
581 : :
582 : : int
583 : 0 : nix_rq_cn9k_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints,
584 : : bool cfg, bool ena)
585 : : {
586 : 0 : struct mbox *mbox = dev->mbox;
587 : : struct nix_aq_enq_req *aq;
588 : :
589 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
590 [ # # ]: 0 : if (!aq)
591 : : return -ENOSPC;
592 : :
593 : 0 : aq->qidx = rq->qid;
594 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
595 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
596 : :
597 [ # # ]: 0 : if (rq->sso_ena) {
598 : : /* SSO mode */
599 : 0 : aq->rq.sso_ena = 1;
600 : 0 : aq->rq.sso_tt = rq->tt;
601 : 0 : aq->rq.sso_grp = rq->hwgrp;
602 : 0 : aq->rq.ena_wqwd = 1;
603 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
604 : 0 : aq->rq.wqe_caching = rq->wqe_caching;
605 : :
606 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
607 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
608 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
609 : : } else {
610 : : /* CQ mode */
611 : 0 : aq->rq.sso_ena = 0;
612 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
613 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
614 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
615 : 0 : aq->rq.cq = rq->cqid;
616 : : }
617 : :
618 [ # # ]: 0 : if (rq->ipsech_ena)
619 : 0 : aq->rq.ipsech_ena = 1;
620 : :
621 : 0 : aq->rq.spb_ena = 0;
622 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
623 : :
624 : : /* Sizes must be aligned to 8 bytes */
625 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
626 : : return -EINVAL;
627 : :
628 : : /* Expressed in number of dwords */
629 : 0 : aq->rq.first_skip = rq->first_skip / 8;
630 : 0 : aq->rq.later_skip = rq->later_skip / 8;
631 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
632 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
633 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
634 : 0 : aq->rq.ena = ena;
635 : 0 : aq->rq.pb_caching = rq->pb_caching;
636 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
637 : 0 : aq->rq.rq_int_ena = 0;
638 : : /* Many to one reduction */
639 : 0 : aq->rq.qint_idx = rq->qid % qints;
640 : 0 : aq->rq.xqe_drop_ena = rq->xqe_drop_ena;
641 : :
642 : : /* If RED enabled, then fill enable for all cases */
643 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
644 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
645 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
646 : :
647 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
648 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
649 : : }
650 : :
651 [ # # ]: 0 : if (cfg) {
652 [ # # ]: 0 : if (rq->sso_ena) {
653 : : /* SSO mode */
654 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
655 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
656 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
657 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
658 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
659 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
660 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
661 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
662 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
663 : : } else {
664 : : /* CQ mode */
665 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
666 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
667 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
668 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
669 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
670 : : }
671 : :
672 [ # # ]: 0 : if (rq->ipsech_ena)
673 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
674 : :
675 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
676 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
677 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
678 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
679 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
680 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
681 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
682 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
683 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
684 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
685 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
686 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
687 : :
688 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
689 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
690 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
691 : :
692 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
693 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
694 : : }
695 : : }
696 : :
697 : : return 0;
698 : : }
699 : :
700 : : int
701 : 0 : nix_rq_cn10k_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg, bool ena)
702 : : {
703 : : struct nix_cn10k_aq_enq_req *aq;
704 : 0 : struct mbox *mbox = dev->mbox;
705 : :
706 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
707 [ # # ]: 0 : if (!aq)
708 : : return -ENOSPC;
709 : :
710 : 0 : aq->qidx = rq->qid;
711 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
712 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
713 : :
714 [ # # ]: 0 : if (rq->sso_ena) {
715 : : /* SSO mode */
716 : 0 : aq->rq.sso_ena = 1;
717 : 0 : aq->rq.sso_tt = rq->tt;
718 : 0 : aq->rq.sso_grp = rq->hwgrp;
719 : 0 : aq->rq.ena_wqwd = 1;
720 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
721 : 0 : aq->rq.wqe_caching = rq->wqe_caching;
722 : :
723 : 0 : aq->rq.xqe_drop_ena = 0;
724 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
725 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
726 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
727 : :
728 [ # # ]: 0 : if (rq->vwqe_ena) {
729 : 0 : aq->rq.vwqe_ena = true;
730 : 0 : aq->rq.vwqe_skip = rq->vwqe_first_skip;
731 : : /* Maximal Vector size is (2^(MAX_VSIZE_EXP+2)) */
732 : 0 : aq->rq.max_vsize_exp = rq->vwqe_max_sz_exp - 2;
733 : 0 : aq->rq.vtime_wait = rq->vwqe_wait_tmo;
734 : 0 : aq->rq.wqe_aura = roc_npa_aura_handle_to_aura(rq->vwqe_aura_handle);
735 : : }
736 : : } else {
737 : : /* CQ mode */
738 : 0 : aq->rq.sso_ena = 0;
739 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
740 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
741 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
742 : 0 : aq->rq.cq = rq->cqid;
743 [ # # ]: 0 : if (rq->xqe_drop_ena)
744 : 0 : aq->rq.xqe_drop_ena = 1;
745 : : }
746 : :
747 [ # # ]: 0 : if (rq->ipsech_ena) {
748 : 0 : aq->rq.ipsech_ena = 1;
749 : 0 : aq->rq.ipsecd_drop_en = 1;
750 : 0 : aq->rq.ena_wqwd = 1;
751 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
752 : 0 : aq->rq.wqe_caching = rq->wqe_caching;
753 : : }
754 : :
755 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
756 : :
757 : : /* Sizes must be aligned to 8 bytes */
758 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
759 : : return -EINVAL;
760 : :
761 : : /* Expressed in number of dwords */
762 : 0 : aq->rq.first_skip = rq->first_skip / 8;
763 : 0 : aq->rq.later_skip = rq->later_skip / 8;
764 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
765 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
766 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
767 : 0 : aq->rq.ena = ena;
768 : :
769 [ # # ]: 0 : if (rq->spb_ena) {
770 : : uint32_t spb_sizem1;
771 : :
772 : 0 : aq->rq.spb_ena = 1;
773 : 0 : aq->rq.spb_aura =
774 [ # # ]: 0 : roc_npa_aura_handle_to_aura(rq->spb_aura_handle);
775 : :
776 [ # # # # ]: 0 : if (rq->spb_size & 0x7 ||
777 : : rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE)
778 : : return -EINVAL;
779 : :
780 : 0 : spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */
781 : 0 : spb_sizem1 -= 1; /* Expressed in size minus one */
782 : 0 : aq->rq.spb_sizem1 = spb_sizem1 & 0x3F;
783 : 0 : aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7;
784 : : } else {
785 : 0 : aq->rq.spb_ena = 0;
786 : : }
787 : :
788 : 0 : aq->rq.pb_caching = rq->pb_caching;
789 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
790 : 0 : aq->rq.rq_int_ena = 0;
791 : : /* Many to one reduction */
792 : 0 : aq->rq.qint_idx = rq->qid % qints;
793 : 0 : aq->rq.lpb_drop_ena = rq->lpb_drop_ena;
794 : 0 : aq->rq.spb_drop_ena = rq->spb_drop_ena;
795 : :
796 : : /* If RED enabled, then fill enable for all cases */
797 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
798 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
799 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
800 : 0 : aq->rq.wqe_pool_pass = rq->red_pass;
801 : 0 : aq->rq.xqe_pass = rq->red_pass;
802 : :
803 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
804 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
805 : 0 : aq->rq.wqe_pool_drop = rq->red_drop;
806 : 0 : aq->rq.xqe_drop = rq->red_drop;
807 : : }
808 : :
809 [ # # ]: 0 : if (cfg) {
810 [ # # ]: 0 : if (rq->sso_ena) {
811 : : /* SSO mode */
812 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
813 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
814 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
815 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
816 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
817 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
818 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
819 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
820 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
821 [ # # ]: 0 : if (rq->vwqe_ena) {
822 : 0 : aq->rq_mask.vwqe_ena = ~aq->rq_mask.vwqe_ena;
823 : 0 : aq->rq_mask.vwqe_skip = ~aq->rq_mask.vwqe_skip;
824 : 0 : aq->rq_mask.max_vsize_exp =
825 : 0 : ~aq->rq_mask.max_vsize_exp;
826 : 0 : aq->rq_mask.vtime_wait =
827 : 0 : ~aq->rq_mask.vtime_wait;
828 : 0 : aq->rq_mask.wqe_aura = ~aq->rq_mask.wqe_aura;
829 : : }
830 : : } else {
831 : : /* CQ mode */
832 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
833 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
834 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
835 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
836 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
837 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
838 : : }
839 : :
840 [ # # ]: 0 : if (rq->ipsech_ena)
841 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
842 : :
843 [ # # ]: 0 : if (rq->spb_ena) {
844 : 0 : aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura;
845 : 0 : aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1;
846 : 0 : aq->rq_mask.spb_high_sizem1 =
847 : 0 : ~aq->rq_mask.spb_high_sizem1;
848 : : }
849 : :
850 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
851 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
852 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
853 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
854 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
855 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
856 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
857 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
858 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
859 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
860 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
861 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
862 : 0 : aq->rq_mask.lpb_drop_ena = ~aq->rq_mask.lpb_drop_ena;
863 : 0 : aq->rq_mask.spb_drop_ena = ~aq->rq_mask.spb_drop_ena;
864 : :
865 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
866 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
867 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
868 : 0 : aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass;
869 : 0 : aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass;
870 : :
871 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
872 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
873 : 0 : aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop;
874 : 0 : aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop;
875 : : }
876 : : }
877 : :
878 : : return 0;
879 : : }
880 : :
881 : : int
882 : 0 : nix_rq_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg, bool ena)
883 : : {
884 : : struct nix_cn20k_aq_enq_req *aq;
885 : 0 : struct mbox *mbox = dev->mbox;
886 : :
887 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
888 [ # # ]: 0 : if (!aq)
889 : : return -ENOSPC;
890 : :
891 : 0 : aq->qidx = rq->qid;
892 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
893 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
894 : :
895 [ # # ]: 0 : if (rq->sso_ena) {
896 : : /* SSO mode */
897 : 0 : aq->rq.sso_ena = 1;
898 : 0 : aq->rq.sso_tt = rq->tt;
899 : 0 : aq->rq.sso_grp = rq->hwgrp;
900 : 0 : aq->rq.ena_wqwd = 1;
901 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
902 : 0 : aq->rq.wqe_caching = rq->wqe_caching;
903 : :
904 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
905 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
906 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
907 : : } else {
908 : : /* CQ mode */
909 : 0 : aq->rq.sso_ena = 0;
910 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
911 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
912 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
913 : 0 : aq->rq.cq = rq->cqid;
914 : : }
915 : :
916 [ # # ]: 0 : if (rq->ipsech_ena) {
917 : 0 : aq->rq.ipsech_ena = 1;
918 : 0 : aq->rq.ipsecd_drop_en = 1;
919 : 0 : aq->rq.ena_wqwd = 1;
920 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
921 : 0 : aq->rq.wqe_caching = rq->wqe_caching;
922 : : }
923 : :
924 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
925 : :
926 : : /* Sizes must be aligned to 8 bytes */
927 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
928 : : return -EINVAL;
929 : :
930 : : /* Expressed in number of dwords */
931 : 0 : aq->rq.first_skip = rq->first_skip / 8;
932 : 0 : aq->rq.later_skip = rq->later_skip / 8;
933 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
934 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
935 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
936 : 0 : aq->rq.ena = ena;
937 : :
938 [ # # ]: 0 : if (rq->spb_ena) {
939 : : uint32_t spb_sizem1;
940 : :
941 : 0 : aq->rq.spb_ena = 1;
942 : 0 : aq->rq.spb_aura =
943 [ # # ]: 0 : roc_npa_aura_handle_to_aura(rq->spb_aura_handle);
944 : :
945 [ # # # # ]: 0 : if (rq->spb_size & 0x7 ||
946 : : rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE)
947 : : return -EINVAL;
948 : :
949 : 0 : spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */
950 : 0 : spb_sizem1 -= 1; /* Expressed in size minus one */
951 : 0 : aq->rq.spb_sizem1 = spb_sizem1 & 0x3F;
952 : 0 : aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7;
953 : : } else {
954 : 0 : aq->rq.spb_ena = 0;
955 : : }
956 : :
957 : 0 : aq->rq.pb_caching = rq->pb_caching;
958 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
959 : 0 : aq->rq.rq_int_ena = 0;
960 : : /* Many to one reduction */
961 : 0 : aq->rq.qint_idx = rq->qid % qints;
962 : 0 : aq->rq.xqe_drop_ena = 0;
963 : 0 : aq->rq.lpb_drop_ena = rq->lpb_drop_ena;
964 : 0 : aq->rq.spb_drop_ena = rq->spb_drop_ena;
965 : :
966 : : /* If RED enabled, then fill enable for all cases */
967 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
968 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
969 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
970 : 0 : aq->rq.wqe_pool_pass = rq->red_pass;
971 : 0 : aq->rq.xqe_pass = rq->red_pass;
972 : :
973 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
974 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
975 : 0 : aq->rq.wqe_pool_drop = rq->red_drop;
976 : 0 : aq->rq.xqe_drop = rq->red_drop;
977 : : }
978 : :
979 [ # # ]: 0 : if (cfg) {
980 [ # # ]: 0 : if (rq->sso_ena) {
981 : : /* SSO mode */
982 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
983 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
984 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
985 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
986 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
987 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
988 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
989 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
990 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
991 : : } else {
992 : : /* CQ mode */
993 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
994 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
995 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
996 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
997 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
998 : : }
999 : :
1000 [ # # ]: 0 : if (rq->ipsech_ena)
1001 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
1002 : :
1003 [ # # ]: 0 : if (rq->spb_ena) {
1004 : 0 : aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura;
1005 : 0 : aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1;
1006 : 0 : aq->rq_mask.spb_high_sizem1 =
1007 : 0 : ~aq->rq_mask.spb_high_sizem1;
1008 : : }
1009 : :
1010 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
1011 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
1012 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
1013 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
1014 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
1015 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
1016 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
1017 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
1018 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
1019 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
1020 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
1021 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
1022 : 0 : aq->rq_mask.lpb_drop_ena = ~aq->rq_mask.lpb_drop_ena;
1023 : 0 : aq->rq_mask.spb_drop_ena = ~aq->rq_mask.spb_drop_ena;
1024 : :
1025 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
1026 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
1027 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
1028 : 0 : aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass;
1029 : 0 : aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass;
1030 : :
1031 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
1032 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
1033 : 0 : aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop;
1034 : 0 : aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop;
1035 : : }
1036 : : }
1037 : :
1038 : : return 0;
1039 : : }
1040 : :
1041 : : int
1042 : 0 : roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
1043 : : {
1044 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1045 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1046 : : bool is_cn9k = roc_model_is_cn9k();
1047 : 0 : struct dev *dev = &nix->dev;
1048 : : int rc;
1049 : :
1050 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL) {
1051 : : mbox_put(mbox);
1052 : 0 : return NIX_ERR_PARAM;
1053 : : }
1054 : :
1055 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues) {
1056 : : mbox_put(mbox);
1057 : 0 : return NIX_ERR_QUEUE_INVALID_RANGE;
1058 : : }
1059 : :
1060 : 0 : rq->roc_nix = roc_nix;
1061 [ # # ]: 0 : rq->tc = ROC_NIX_PFC_CLASS_INVALID;
1062 : :
1063 : : /* Enable XQE/CQ drop on cn10k to count pkt drops only when inline is disabled */
1064 [ # # ]: 0 : if (roc_model_is_cn10k() &&
1065 [ # # # # ]: 0 : (roc_nix->force_tail_drop || !roc_nix_inl_inb_is_enabled(roc_nix)))
1066 : 0 : rq->xqe_drop_ena = roc_nix->dis_xqe_drop ? false : true;
1067 : :
1068 [ # # ]: 0 : if (is_cn9k)
1069 : 0 : rc = nix_rq_cn9k_cfg(dev, rq, nix->qints, false, ena);
1070 [ # # ]: 0 : else if (roc_model_is_cn10k())
1071 : 0 : rc = nix_rq_cn10k_cfg(dev, rq, nix->qints, false, ena);
1072 : : else
1073 : 0 : rc = nix_rq_cfg(dev, rq, nix->qints, false, ena);
1074 : :
1075 [ # # ]: 0 : if (rc) {
1076 : : mbox_put(mbox);
1077 : 0 : return rc;
1078 : : }
1079 : :
1080 : 0 : rc = mbox_process(mbox);
1081 [ # # ]: 0 : if (rc) {
1082 : : mbox_put(mbox);
1083 : 0 : return rc;
1084 : : }
1085 : : mbox_put(mbox);
1086 : :
1087 : : /* Update aura buf type to indicate its use */
1088 : 0 : nix_rq_aura_buf_type_update(rq, true);
1089 : :
1090 : : /* Check for meta aura if RQ is enabled */
1091 [ # # # # ]: 0 : if (ena && nix->need_meta_aura) {
1092 : 0 : rc = roc_nix_inl_meta_aura_check(roc_nix, rq);
1093 [ # # ]: 0 : if (rc)
1094 : : return rc;
1095 : : }
1096 : :
1097 : 0 : nix->rqs[rq->qid] = rq;
1098 : 0 : return nix_tel_node_add_rq(rq);
1099 : : }
1100 : :
1101 : : int
1102 : 0 : roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
1103 : : {
1104 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1105 [ # # ]: 0 : struct mbox *m_box = (&nix->dev)->mbox;
1106 : : bool is_cn9k = roc_model_is_cn9k();
1107 : 0 : struct dev *dev = &nix->dev;
1108 : : struct mbox *mbox;
1109 : : int rc;
1110 : :
1111 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL)
1112 : : return NIX_ERR_PARAM;
1113 : :
1114 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues)
1115 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1116 : :
1117 : : /* Clear attributes for existing aura's */
1118 : 0 : nix_rq_aura_buf_type_update(rq, false);
1119 : :
1120 : 0 : rq->roc_nix = roc_nix;
1121 : 0 : rq->tc = ROC_NIX_PFC_CLASS_INVALID;
1122 : :
1123 : : mbox = mbox_get(m_box);
1124 [ # # ]: 0 : if (is_cn9k)
1125 : 0 : rc = nix_rq_cn9k_cfg(dev, rq, nix->qints, true, ena);
1126 [ # # ]: 0 : else if (roc_model_is_cn10k())
1127 : 0 : rc = nix_rq_cn10k_cfg(dev, rq, nix->qints, true, ena);
1128 : : else
1129 : 0 : rc = nix_rq_cfg(dev, rq, nix->qints, true, ena);
1130 : :
1131 [ # # ]: 0 : if (rc) {
1132 : : mbox_put(mbox);
1133 : 0 : return rc;
1134 : : }
1135 : :
1136 : 0 : rc = mbox_process(mbox);
1137 [ # # ]: 0 : if (rc) {
1138 : : mbox_put(mbox);
1139 : 0 : return rc;
1140 : : }
1141 : : mbox_put(mbox);
1142 : :
1143 : : /* Update aura attribute to indicate its use */
1144 : 0 : nix_rq_aura_buf_type_update(rq, true);
1145 : :
1146 : : /* Check for meta aura if RQ is enabled */
1147 [ # # # # ]: 0 : if (ena && nix->need_meta_aura) {
1148 : 0 : rc = roc_nix_inl_meta_aura_check(roc_nix, rq);
1149 [ # # ]: 0 : if (rc)
1150 : : return rc;
1151 : : }
1152 : :
1153 : 0 : return nix_tel_node_add_rq(rq);
1154 : : }
1155 : :
1156 : : int
1157 [ # # ]: 0 : roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq)
1158 : : {
1159 : : bool is_cn9k = roc_model_is_cn9k();
1160 : : struct nix *nix;
1161 : : struct dev *dev;
1162 : : int rc;
1163 : :
1164 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL)
1165 : : return NIX_ERR_PARAM;
1166 : :
1167 : : nix = roc_nix_to_nix_priv(roc_nix);
1168 : :
1169 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues)
1170 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1171 : :
1172 : 0 : dev = &nix->dev;
1173 : :
1174 [ # # ]: 0 : if (is_cn9k)
1175 : 0 : rc = nix_rq_cn9k_cman_cfg(dev, rq);
1176 [ # # ]: 0 : else if (roc_model_is_cn10k())
1177 : 0 : rc = nix_rq_cn10k_cman_cfg(dev, rq);
1178 : : else
1179 : 0 : rc = nix_rq_cman_cfg(dev, rq);
1180 : :
1181 : : return rc;
1182 : : }
1183 : :
1184 : : int
1185 : 0 : roc_nix_rq_fini(struct roc_nix_rq *rq)
1186 : : {
1187 : 0 : struct nix *nix = roc_nix_to_nix_priv(rq->roc_nix);
1188 : : int rc;
1189 : :
1190 : : /* Disabling RQ is sufficient */
1191 : 0 : rc = roc_nix_rq_ena_dis(rq, false);
1192 [ # # ]: 0 : if (rc)
1193 : : return rc;
1194 : :
1195 : : /* Update aura attribute to indicate its use for */
1196 : 0 : nix_rq_aura_buf_type_update(rq, false);
1197 : :
1198 : 0 : nix->rqs[rq->qid] = NULL;
1199 : 0 : return 0;
1200 : : }
1201 : :
1202 : : static inline int
1203 : 0 : roc_nix_cn20k_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq)
1204 : : {
1205 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1206 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1207 : : volatile struct nix_cn20k_cq_ctx_s *cq_ctx;
1208 : : uint16_t drop_thresh = NIX_CQ_THRESH_LEVEL;
1209 : 0 : uint16_t cpt_lbpid = nix->cpt_lbpid;
1210 : : struct nix_cn20k_aq_enq_req *aq;
1211 : : enum nix_q_size qsize;
1212 : : size_t desc_sz;
1213 : : int rc;
1214 : :
1215 [ # # ]: 0 : if (cq == NULL)
1216 : : return NIX_ERR_PARAM;
1217 : :
1218 : 0 : qsize = nix_qsize_clampup(cq->nb_desc);
1219 : 0 : cq->nb_desc = nix_qsize_to_val(qsize);
1220 : 0 : cq->qmask = cq->nb_desc - 1;
1221 : 0 : cq->door = nix->base + NIX_LF_CQ_OP_DOOR;
1222 : 0 : cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
1223 : 0 : cq->wdata = (uint64_t)cq->qid << 32;
1224 : 0 : cq->roc_nix = roc_nix;
1225 : :
1226 : : /* CQE of W16 */
1227 : 0 : desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ;
1228 : 0 : cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN);
1229 [ # # ]: 0 : if (cq->desc_base == NULL) {
1230 : : rc = NIX_ERR_NO_MEM;
1231 : 0 : goto fail;
1232 : : }
1233 : :
1234 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox_get(mbox));
1235 [ # # ]: 0 : if (!aq) {
1236 : : mbox_put(mbox);
1237 : 0 : return -ENOSPC;
1238 : : }
1239 : :
1240 : 0 : aq->qidx = cq->qid;
1241 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1242 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1243 : : cq_ctx = &aq->cq;
1244 : :
1245 : 0 : cq_ctx->ena = 1;
1246 : 0 : cq_ctx->caching = 1;
1247 : 0 : cq_ctx->qsize = qsize;
1248 : 0 : cq_ctx->base = (uint64_t)cq->desc_base;
1249 : 0 : cq_ctx->avg_level = 0xff;
1250 : 0 : cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
1251 [ # # ]: 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
1252 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(roc_nix)) {
1253 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_CPT_DROP);
1254 : 0 : cq_ctx->cpt_drop_err_en = 1;
1255 : : /* Enable Late BP only when non zero CPT BPID */
1256 [ # # ]: 0 : if (cpt_lbpid) {
1257 : 0 : cq_ctx->lbp_ena = 1;
1258 : 0 : cq_ctx->lbpid_low = cpt_lbpid & 0x7;
1259 : 0 : cq_ctx->lbpid_med = (cpt_lbpid >> 3) & 0x7;
1260 : 0 : cq_ctx->lbpid_high = (cpt_lbpid >> 6) & 0x7;
1261 : 0 : cq_ctx->lbp_frac = NIX_CQ_LBP_THRESH_FRAC;
1262 : : }
1263 : : drop_thresh = NIX_CQ_SEC_BP_THRESH_LEVEL;
1264 : : }
1265 : :
1266 : : /* Many to one reduction */
1267 : 0 : cq_ctx->qint_idx = cq->qid % nix->qints;
1268 : : /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
1269 [ # # ]: 0 : cq_ctx->cint_idx = cq->qid;
1270 : :
1271 [ # # ]: 0 : if (roc_errata_nix_has_cq_min_size_4k()) {
1272 : : const float rx_cq_skid = NIX_CQ_FULL_ERRATA_SKID;
1273 : : uint16_t min_rx_drop;
1274 : :
1275 : 0 : min_rx_drop = ceil(rx_cq_skid / (float)cq->nb_desc);
1276 : 0 : cq_ctx->drop = min_rx_drop;
1277 : 0 : cq_ctx->drop_ena = 1;
1278 : 0 : cq->drop_thresh = min_rx_drop;
1279 : : } else {
1280 : 0 : cq->drop_thresh = drop_thresh;
1281 : : /* Drop processing or red drop cannot be enabled due to
1282 : : * due to packets coming for second pass from CPT.
1283 : : */
1284 [ # # ]: 0 : if (!roc_nix_inl_inb_is_enabled(roc_nix)) {
1285 : 0 : cq_ctx->drop = cq->drop_thresh;
1286 : 0 : cq_ctx->drop_ena = 1;
1287 : : }
1288 : : }
1289 : 0 : cq->bp_thresh = cq->drop_thresh;
1290 [ # # ]: 0 : cq_ctx->bp = cq->drop_thresh;
1291 : :
1292 [ # # ]: 0 : if (roc_feature_nix_has_cqe_stash()) {
1293 [ # # ]: 0 : if (cq_ctx->caching) {
1294 : 0 : cq_ctx->stashing = 1;
1295 : 0 : cq_ctx->stash_thresh = cq->stash_thresh;
1296 : : }
1297 : : }
1298 : :
1299 : 0 : rc = mbox_process(mbox);
1300 : : mbox_put(mbox);
1301 [ # # ]: 0 : if (rc)
1302 : 0 : goto free_mem;
1303 : :
1304 : 0 : return nix_tel_node_add_cq(cq);
1305 : :
1306 : : free_mem:
1307 : 0 : plt_free(cq->desc_base);
1308 : : fail:
1309 : : return rc;
1310 : : }
1311 : :
1312 : : int
1313 : 0 : roc_nix_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq)
1314 : : {
1315 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1316 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1317 : : volatile struct nix_cq_ctx_s *cq_ctx = NULL;
1318 : 0 : uint16_t cpt_lbpid = nix->cpt_lbpid;
1319 : : enum nix_q_size qsize;
1320 : : bool force_tail_drop;
1321 : : uint16_t drop_thresh;
1322 : : uint16_t bp_thresh;
1323 : : size_t desc_sz;
1324 : : int rc;
1325 : :
1326 [ # # ]: 0 : if (cq == NULL)
1327 : : return NIX_ERR_PARAM;
1328 : :
1329 [ # # ]: 0 : if (roc_model_is_cn20k())
1330 : 0 : return roc_nix_cn20k_cq_init(roc_nix, cq);
1331 : :
1332 : 0 : qsize = nix_qsize_clampup(cq->nb_desc);
1333 : 0 : cq->nb_desc = nix_qsize_to_val(qsize);
1334 : 0 : cq->qmask = cq->nb_desc - 1;
1335 : 0 : cq->door = nix->base + NIX_LF_CQ_OP_DOOR;
1336 : 0 : cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
1337 : 0 : cq->wdata = (uint64_t)cq->qid << 32;
1338 : 0 : cq->roc_nix = roc_nix;
1339 : :
1340 : : /* CQE of W16 */
1341 : 0 : desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ;
1342 : 0 : cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN);
1343 [ # # ]: 0 : if (cq->desc_base == NULL) {
1344 : : rc = NIX_ERR_NO_MEM;
1345 : 0 : goto fail;
1346 : : }
1347 : :
1348 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1349 : : struct nix_aq_enq_req *aq;
1350 : :
1351 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox_get(mbox));
1352 [ # # ]: 0 : if (!aq) {
1353 : : mbox_put(mbox);
1354 : 0 : return -ENOSPC;
1355 : : }
1356 : :
1357 : 0 : aq->qidx = cq->qid;
1358 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1359 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1360 : 0 : cq_ctx = &aq->cq;
1361 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
1362 : : struct nix_cn10k_aq_enq_req *aq;
1363 : :
1364 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox_get(mbox));
1365 [ # # ]: 0 : if (!aq) {
1366 : : mbox_put(mbox);
1367 : 0 : return -ENOSPC;
1368 : : }
1369 : :
1370 : 0 : aq->qidx = cq->qid;
1371 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1372 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1373 : 0 : cq_ctx = &aq->cq;
1374 : : }
1375 : :
1376 : 0 : force_tail_drop = roc_nix->force_tail_drop;
1377 : :
1378 : 0 : cq_ctx->ena = 1;
1379 : 0 : cq_ctx->caching = 1;
1380 : 0 : cq_ctx->qsize = qsize;
1381 : 0 : cq_ctx->base = (uint64_t)cq->desc_base;
1382 : 0 : cq_ctx->avg_level = 0xff;
1383 : 0 : cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
1384 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
1385 [ # # ]: 0 : drop_thresh = force_tail_drop ? NIX_CQ_THRESH_LEVEL_REF1 : NIX_CQ_THRESH_LEVEL;
1386 [ # # ]: 0 : bp_thresh = force_tail_drop ? NIX_CQ_BP_THRESH_LEVEL_REF1 : drop_thresh;
1387 : :
1388 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(roc_nix)) {
1389 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_CPT_DROP);
1390 : 0 : cq_ctx->cpt_drop_err_en = 1;
1391 : : /* Enable Late BP only when non zero CPT BPID */
1392 [ # # ]: 0 : if (cpt_lbpid) {
1393 : 0 : cq_ctx->lbp_ena = 1;
1394 : 0 : cq_ctx->lbpid_low = cpt_lbpid & 0x7;
1395 : 0 : cq_ctx->lbpid_med = (cpt_lbpid >> 3) & 0x7;
1396 : 0 : cq_ctx->lbpid_high = (cpt_lbpid >> 6) & 0x7;
1397 : 0 : cq_ctx->lbp_frac = force_tail_drop ? NIX_CQ_LBP_THRESH_FRAC_REF1 :
1398 : : NIX_CQ_LBP_THRESH_FRAC;
1399 : : }
1400 : :
1401 : : /* CQ drop is disabled by default when inline device in use and
1402 : : * force_tail_drop disabled, so will not configure drop threshold.
1403 : : */
1404 [ # # ]: 0 : drop_thresh = force_tail_drop ? NIX_CQ_SEC_THRESH_LEVEL_REF1 : 0;
1405 [ # # ]: 0 : bp_thresh = force_tail_drop ? NIX_CQ_SEC_BP_THRESH_LEVEL_REF1 :
1406 : : NIX_CQ_SEC_BP_THRESH_LEVEL;
1407 : : }
1408 : :
1409 : : /* Many to one reduction */
1410 : 0 : cq_ctx->qint_idx = cq->qid % nix->qints;
1411 : : /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
1412 [ # # ]: 0 : cq_ctx->cint_idx = cq->qid;
1413 : :
1414 [ # # ]: 0 : if (roc_errata_nix_has_cq_min_size_4k()) {
1415 : : const float rx_cq_skid = NIX_CQ_FULL_ERRATA_SKID;
1416 : : uint16_t min_rx_drop;
1417 : :
1418 : 0 : min_rx_drop = ceil(rx_cq_skid / (float)cq->nb_desc);
1419 : 0 : cq_ctx->drop = min_rx_drop;
1420 : 0 : cq_ctx->drop_ena = 1;
1421 : 0 : cq->drop_thresh = min_rx_drop;
1422 : : bp_thresh = min_rx_drop;
1423 : 0 : cq->bp_thresh = bp_thresh;
1424 : : } else {
1425 : 0 : cq->drop_thresh = drop_thresh;
1426 : 0 : cq->bp_thresh = bp_thresh;
1427 : : /* Drop processing or red drop cannot be enabled due to
1428 : : * due to packets coming for second pass from CPT.
1429 : : */
1430 [ # # # # ]: 0 : if (!roc_nix_inl_inb_is_enabled(roc_nix) || force_tail_drop) {
1431 : 0 : cq_ctx->drop = cq->drop_thresh;
1432 : 0 : cq_ctx->drop_ena = 1;
1433 : : }
1434 : : }
1435 [ # # ]: 0 : cq_ctx->bp = bp_thresh;
1436 : :
1437 [ # # ]: 0 : if (roc_feature_nix_has_cqe_stash()) {
1438 [ # # ]: 0 : if (cq_ctx->caching) {
1439 : 0 : cq_ctx->stashing = 1;
1440 : 0 : cq_ctx->stash_thresh = cq->stash_thresh;
1441 : : }
1442 : : }
1443 : :
1444 : 0 : rc = mbox_process(mbox);
1445 : : mbox_put(mbox);
1446 [ # # ]: 0 : if (rc)
1447 : 0 : goto free_mem;
1448 : :
1449 : 0 : return nix_tel_node_add_cq(cq);
1450 : :
1451 : : free_mem:
1452 : 0 : plt_free(cq->desc_base);
1453 : : fail:
1454 : : return rc;
1455 : : }
1456 : :
1457 : : int
1458 : 0 : roc_nix_cq_fini(struct roc_nix_cq *cq)
1459 : : {
1460 : : struct mbox *mbox;
1461 : : struct nix *nix;
1462 : : int rc;
1463 : :
1464 [ # # ]: 0 : if (cq == NULL)
1465 : : return NIX_ERR_PARAM;
1466 : :
1467 : 0 : nix = roc_nix_to_nix_priv(cq->roc_nix);
1468 : 0 : mbox = mbox_get((&nix->dev)->mbox);
1469 : :
1470 : : /* Disable CQ */
1471 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1472 : : struct nix_aq_enq_req *aq;
1473 : :
1474 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1475 [ # # ]: 0 : if (!aq) {
1476 : : mbox_put(mbox);
1477 : 0 : return -ENOSPC;
1478 : : }
1479 : :
1480 : 0 : aq->qidx = cq->qid;
1481 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1482 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1483 : 0 : aq->cq.ena = 0;
1484 : 0 : aq->cq.bp_ena = 0;
1485 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1486 : 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1487 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
1488 : : struct nix_cn10k_aq_enq_req *aq;
1489 : :
1490 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1491 [ # # ]: 0 : if (!aq) {
1492 : : mbox_put(mbox);
1493 : 0 : return -ENOSPC;
1494 : : }
1495 : :
1496 : 0 : aq->qidx = cq->qid;
1497 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1498 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1499 : 0 : aq->cq.ena = 0;
1500 : 0 : aq->cq.bp_ena = 0;
1501 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1502 [ # # ]: 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1503 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(cq->roc_nix)) {
1504 : 0 : aq->cq.lbp_ena = 0;
1505 : 0 : aq->cq_mask.lbp_ena = ~aq->cq_mask.lbp_ena;
1506 : : }
1507 : : } else {
1508 : : struct nix_cn20k_aq_enq_req *aq;
1509 : :
1510 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1511 [ # # ]: 0 : if (!aq) {
1512 : : mbox_put(mbox);
1513 : 0 : return -ENOSPC;
1514 : : }
1515 : :
1516 : 0 : aq->qidx = cq->qid;
1517 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1518 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1519 : 0 : aq->cq.ena = 0;
1520 : 0 : aq->cq.bp_ena = 0;
1521 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1522 [ # # ]: 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1523 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(cq->roc_nix)) {
1524 : 0 : aq->cq.lbp_ena = 0;
1525 : 0 : aq->cq_mask.lbp_ena = ~aq->cq_mask.lbp_ena;
1526 : : }
1527 : : }
1528 : :
1529 : 0 : rc = mbox_process(mbox);
1530 [ # # ]: 0 : if (rc) {
1531 : : mbox_put(mbox);
1532 : 0 : return rc;
1533 : : }
1534 : :
1535 : : mbox_put(mbox);
1536 : 0 : plt_free(cq->desc_base);
1537 : 0 : return 0;
1538 : : }
1539 : :
1540 : : static uint16_t
1541 : : sqes_per_sqb_calc(uint16_t sqb_size, enum roc_nix_sq_max_sqe_sz max_sqe_sz)
1542 : : {
1543 : : uint16_t sqes_per_sqb;
1544 : :
1545 : 0 : if (max_sqe_sz == roc_nix_maxsqesz_w16)
1546 : 0 : sqes_per_sqb = (sqb_size / 8) / 16;
1547 : : else
1548 : 0 : sqes_per_sqb = (sqb_size / 8) / 8;
1549 : :
1550 : : /* Reserve One SQE in each SQB to hold pointer for next SQB */
1551 : 0 : sqes_per_sqb -= 1;
1552 : : return sqes_per_sqb;
1553 : : }
1554 : :
1555 : : static uint16_t
1556 : : sq_desc_to_sqb(struct nix *nix, uint16_t sqes_per_sqb, uint32_t nb_desc)
1557 : : {
1558 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1559 : : uint16_t nb_sqb_bufs;
1560 : :
1561 : 0 : nb_desc = PLT_MAX(512U, nb_desc);
1562 : 0 : nb_sqb_bufs = PLT_DIV_CEIL(nb_desc, sqes_per_sqb);
1563 : :
1564 : 0 : nb_sqb_bufs += NIX_SQB_PREFETCH;
1565 : : /* Clamp up the SQB count */
1566 : 0 : nb_sqb_bufs = PLT_MAX(NIX_DEF_SQB, nb_sqb_bufs);
1567 : 0 : nb_sqb_bufs = PLT_MIN(roc_nix->max_sqb_count, (uint16_t)nb_sqb_bufs);
1568 : :
1569 : : return nb_sqb_bufs;
1570 : : }
1571 : :
1572 : : static uint16_t
1573 : : sqb_slack_adjust(struct nix *nix, uint16_t nb_sqb_bufs, bool sq_cnt_ena)
1574 : : {
1575 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1576 : : uint16_t thr;
1577 : :
1578 : 0 : thr = PLT_DIV_CEIL((nb_sqb_bufs * ROC_NIX_SQB_THRESH), 100);
1579 : 0 : if (roc_nix->sqb_slack)
1580 : 0 : nb_sqb_bufs += roc_nix->sqb_slack;
1581 [ # # # # : 0 : else if (!sq_cnt_ena)
# # ]
1582 : 0 : nb_sqb_bufs += PLT_MAX((int)thr, (int)ROC_NIX_SQB_SLACK_DFLT);
1583 : : return nb_sqb_bufs;
1584 : : }
1585 : :
1586 : : static int
1587 : 0 : sqb_pool_populate(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1588 : : {
1589 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1590 : : uint16_t sqes_per_sqb, count, nb_sqb_bufs;
1591 : : uint64_t blk_sz;
1592 : : uint64_t iova;
1593 : : int rc;
1594 : :
1595 : 0 : blk_sz = nix->sqb_size;
1596 [ # # ]: 0 : sqes_per_sqb = sqes_per_sqb_calc(blk_sz, sq->max_sqe_sz);
1597 : :
1598 : : /* Translate desc count to SQB count */
1599 : 0 : nb_sqb_bufs = sq_desc_to_sqb(nix, sqes_per_sqb, sq->nb_desc);
1600 : :
1601 [ # # ]: 0 : sq->sqes_per_sqb = sqes_per_sqb;
1602 : 0 : sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb);
1603 : 0 : sq->nb_sqb_bufs_adj = nb_sqb_bufs;
1604 : 0 : sq->nb_sqb_bufs = nb_sqb_bufs;
1605 : :
1606 : : /* Add slack to SQB's */
1607 [ # # ]: 0 : nb_sqb_bufs = sqb_slack_adjust(nix, nb_sqb_bufs, !!sq->sq_cnt_ptr);
1608 : :
1609 : : /* Explicitly set nat_align alone as by default pool is with both
1610 : : * nat_align and buf_offset = 1 which we don't want for SQB.
1611 : : */
1612 [ # # # # ]: 0 : if (roc_feature_npa_has_halo() && roc_nix->sqb_halo_ena) {
1613 : : struct npa_cn20k_halo_s halo;
1614 : :
1615 : : memset(&halo, 0, sizeof(struct npa_cn20k_halo_s));
1616 : 0 : halo.nat_align = 1;
1617 : 0 : halo.fc_ena = 1;
1618 : 0 : halo.fc_stype = 0x3; /* STSTP */
1619 : 0 : halo.fc_addr = (uint64_t)sq->fc;
1620 : : halo.fc_hyst_bits = 0; /* Store count on all updates */
1621 : 0 : halo.unified_ctx = 1;
1622 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, nb_sqb_bufs, NULL,
1623 : : (struct npa_pool_s *)&halo, ROC_NPA_HALO_F);
1624 : : } else {
1625 : : struct npa_pool_s pool;
1626 : : struct npa_aura_s aura;
1627 : :
1628 : : memset(&pool, 0, sizeof(struct npa_pool_s));
1629 : 0 : pool.nat_align = 1;
1630 : :
1631 : : memset(&aura, 0, sizeof(aura));
1632 : : /* Disable SQ pool FC updates when SQ count updates are used */
1633 [ # # ]: 0 : if (!sq->sq_cnt_ptr)
1634 : 0 : aura.fc_ena = 1;
1635 [ # # # # ]: 0 : if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp())
1636 : : aura.fc_stype = 0x0; /* STF */
1637 : : else
1638 : 0 : aura.fc_stype = 0x3; /* STSTP */
1639 : 0 : aura.fc_addr = (uint64_t)sq->fc;
1640 : 0 : aura.fc_hyst_bits = sq->fc_hyst_bits & 0xF;
1641 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, nb_sqb_bufs, &aura, &pool, 0);
1642 : : }
1643 : :
1644 [ # # ]: 0 : if (rc)
1645 : 0 : goto fail;
1646 : :
1647 : 0 : roc_npa_buf_type_update(sq->aura_handle, ROC_NPA_BUF_TYPE_SQB, 1);
1648 : 0 : sq->sqe_mem = plt_zmalloc(blk_sz * nb_sqb_bufs, blk_sz);
1649 [ # # ]: 0 : if (sq->sqe_mem == NULL) {
1650 : : rc = NIX_ERR_NO_MEM;
1651 : 0 : goto nomem;
1652 : : }
1653 : :
1654 : : /* Fill the initial buffers */
1655 : 0 : iova = (uint64_t)sq->sqe_mem;
1656 [ # # ]: 0 : for (count = 0; count < nb_sqb_bufs; count++) {
1657 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, iova);
1658 : 0 : iova += blk_sz;
1659 : : }
1660 : :
1661 [ # # ]: 0 : if (roc_npa_aura_op_available_wait(sq->aura_handle, nb_sqb_bufs, 0) !=
1662 : : nb_sqb_bufs) {
1663 : 0 : plt_err("Failed to free all pointers to the pool");
1664 : : rc = NIX_ERR_NO_MEM;
1665 : 0 : goto npa_fail;
1666 : : }
1667 : :
1668 : 0 : roc_npa_pool_op_range_set(sq->aura_handle, (uint64_t)sq->sqe_mem, iova);
1669 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
1670 : 0 : sq->aura_sqb_bufs = nb_sqb_bufs;
1671 : :
1672 : 0 : return rc;
1673 : : npa_fail:
1674 : 0 : plt_free(sq->sqe_mem);
1675 : 0 : nomem:
1676 : 0 : roc_npa_pool_destroy(sq->aura_handle);
1677 : : fail:
1678 : : return rc;
1679 : : }
1680 : :
1681 : : static int
1682 : 0 : sqb_pool_dyn_populate(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1683 : : {
1684 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1685 : : uint16_t count, nb_sqb_bufs;
1686 : : uint16_t max_sqb_count;
1687 : : struct npa_pool_s pool;
1688 : : struct npa_aura_s aura;
1689 : : uint16_t sqes_per_sqb;
1690 : : uint64_t blk_sz;
1691 : : uint64_t iova;
1692 : : int rc;
1693 : :
1694 : 0 : blk_sz = nix->sqb_size;
1695 [ # # ]: 0 : sqes_per_sqb = sqes_per_sqb_calc(blk_sz, sq->max_sqe_sz);
1696 : :
1697 : : /* Translate desc count to SQB count */
1698 [ # # ]: 0 : nb_sqb_bufs = sq_desc_to_sqb(nix, sqes_per_sqb, sq->nb_desc);
1699 : :
1700 : 0 : sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb);
1701 : 0 : sq->sqes_per_sqb = sqes_per_sqb;
1702 : 0 : sq->nb_sqb_bufs_adj = nb_sqb_bufs;
1703 : 0 : sq->nb_sqb_bufs = nb_sqb_bufs;
1704 : :
1705 : : /* Add slack to SQB's */
1706 [ # # ]: 0 : nb_sqb_bufs = sqb_slack_adjust(nix, nb_sqb_bufs, !!sq->sq_cnt_ptr);
1707 : :
1708 : : /* Explicitly set nat_align alone as by default pool is with both
1709 : : * nat_align and buf_offset = 1 which we don't want for SQB.
1710 : : */
1711 : : memset(&pool, 0, sizeof(struct npa_pool_s));
1712 : : pool.nat_align = 0;
1713 : :
1714 : : memset(&aura, 0, sizeof(aura));
1715 [ # # ]: 0 : if (!sq->sq_cnt_ptr)
1716 : 0 : aura.fc_ena = 1;
1717 [ # # # # ]: 0 : if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp())
1718 : : aura.fc_stype = 0x0; /* STF */
1719 : : else
1720 : 0 : aura.fc_stype = 0x3; /* STSTP */
1721 : 0 : aura.fc_addr = (uint64_t)sq->fc;
1722 [ # # ]: 0 : aura.fc_hyst_bits = sq->fc_hyst_bits & 0xF;
1723 : : max_sqb_count = sqb_slack_adjust(nix, roc_nix->max_sqb_count, false);
1724 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, max_sqb_count, &aura, &pool, 0);
1725 [ # # ]: 0 : if (rc)
1726 : 0 : goto fail;
1727 : :
1728 : 0 : roc_npa_buf_type_update(sq->aura_handle, ROC_NPA_BUF_TYPE_SQB, 1);
1729 [ # # ]: 0 : roc_npa_aura_op_cnt_set(sq->aura_handle, 0, nb_sqb_bufs);
1730 : :
1731 : : /* Fill the initial buffers */
1732 [ # # ]: 0 : for (count = 0; count < nb_sqb_bufs; count++) {
1733 : 0 : iova = (uint64_t)plt_zmalloc(blk_sz, ROC_ALIGN);
1734 [ # # ]: 0 : if (!iova) {
1735 : : rc = -ENOMEM;
1736 : 0 : goto nomem;
1737 : : }
1738 : 0 : plt_io_wmb();
1739 : :
1740 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, iova);
1741 : : }
1742 : :
1743 [ # # ]: 0 : if (roc_npa_aura_op_available_wait(sq->aura_handle, nb_sqb_bufs, 0) != nb_sqb_bufs) {
1744 : 0 : plt_err("Failed to free all pointers to the pool");
1745 : : rc = NIX_ERR_NO_MEM;
1746 : 0 : goto npa_fail;
1747 : : }
1748 : :
1749 : : /* Update aura count */
1750 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
1751 : 0 : roc_npa_pool_op_range_set(sq->aura_handle, 0, UINT64_MAX);
1752 : 0 : sq->aura_sqb_bufs = nb_sqb_bufs;
1753 : :
1754 : 0 : return rc;
1755 : : npa_fail:
1756 : 0 : nomem:
1757 : : while (count) {
1758 : : iova = roc_npa_aura_op_alloc(sq->aura_handle, 0);
1759 : : if (!iova)
1760 : : break;
1761 : : plt_free((uint64_t *)iova);
1762 : : count--;
1763 : : }
1764 [ # # ]: 0 : if (count)
1765 : 0 : plt_err("Failed to recover %u SQB's", count);
1766 : 0 : roc_npa_pool_destroy(sq->aura_handle);
1767 : : fail:
1768 : : return rc;
1769 : : }
1770 : :
1771 : : static int
1772 : 0 : sq_cn9k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum,
1773 : : uint16_t smq)
1774 : : {
1775 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1776 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1777 : : struct nix_aq_enq_req *aq;
1778 : :
1779 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1780 [ # # ]: 0 : if (!aq)
1781 : : return -ENOSPC;
1782 : :
1783 : 0 : aq->qidx = sq->qid;
1784 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1785 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1786 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1787 : :
1788 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1789 : 0 : aq->sq.smq = smq;
1790 : 0 : aq->sq.smq_rr_quantum = rr_quantum;
1791 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1792 : 0 : aq->sq.default_chan =
1793 : 0 : nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1794 : : else
1795 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1796 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1797 : 0 : aq->sq.ena = 1;
1798 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1799 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1800 : 0 : aq->sq.cq = sq->cqid;
1801 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1802 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1803 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1804 : 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1805 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1806 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1807 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1808 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1809 : :
1810 : : /* Many to one reduction */
1811 : 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1812 : :
1813 : 0 : return 0;
1814 : : }
1815 : :
1816 : : static int
1817 : 0 : sq_cn9k_fini(struct nix *nix, struct roc_nix_sq *sq)
1818 : : {
1819 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1820 : : struct nix_aq_enq_rsp *rsp;
1821 : : struct nix_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_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_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_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 : : static int
1906 : 0 : sq_cn10k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1907 : : {
1908 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1909 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1910 : : struct nix_cn10k_aq_enq_req *aq;
1911 : :
1912 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1913 [ # # ]: 0 : if (!aq)
1914 : : return -ENOSPC;
1915 : :
1916 : 0 : aq->qidx = sq->qid;
1917 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1918 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1919 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1920 : :
1921 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1922 : 0 : aq->sq.smq = smq;
1923 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1924 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1925 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1926 : : else
1927 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1928 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1929 : 0 : aq->sq.ena = 1;
1930 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1931 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1932 : 0 : aq->sq.cq = sq->cqid;
1933 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1934 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1935 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1936 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1937 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1938 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1939 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1940 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1941 : :
1942 : : /* Many to one reduction */
1943 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1944 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1945 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1946 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1947 : : * might result in software missing the interrupt.
1948 : : */
1949 : 0 : aq->sq.qint_idx = 0;
1950 : : }
1951 : : return 0;
1952 : : }
1953 : :
1954 : : static int
1955 : 0 : sq_cn10k_fini(struct nix *nix, struct roc_nix_sq *sq)
1956 : : {
1957 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1958 : : struct nix_cn10k_aq_enq_rsp *rsp;
1959 : : struct nix_cn10k_aq_enq_req *aq;
1960 : : uint16_t sqes_per_sqb;
1961 : : void *sqb_buf;
1962 : : int rc, count;
1963 : :
1964 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1965 [ # # ]: 0 : if (!aq) {
1966 : : mbox_put(mbox);
1967 : 0 : return -ENOSPC;
1968 : : }
1969 : :
1970 : 0 : aq->qidx = sq->qid;
1971 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1972 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1973 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1974 [ # # ]: 0 : if (rc) {
1975 : : mbox_put(mbox);
1976 : 0 : return rc;
1977 : : }
1978 : :
1979 : : /* Check if sq is already cleaned up */
1980 [ # # ]: 0 : if (!rsp->sq.ena) {
1981 : : mbox_put(mbox);
1982 : 0 : return 0;
1983 : : }
1984 : :
1985 : : /* Disable sq */
1986 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1987 [ # # ]: 0 : if (!aq) {
1988 : : mbox_put(mbox);
1989 : 0 : return -ENOSPC;
1990 : : }
1991 : :
1992 : 0 : aq->qidx = sq->qid;
1993 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1994 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1995 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1996 : 0 : aq->sq.ena = 0;
1997 : 0 : rc = mbox_process(mbox);
1998 [ # # ]: 0 : if (rc) {
1999 : : mbox_put(mbox);
2000 : 0 : return rc;
2001 : : }
2002 : :
2003 : : /* Read SQ and free sqb's */
2004 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
2005 [ # # ]: 0 : if (!aq) {
2006 : : mbox_put(mbox);
2007 : 0 : return -ENOSPC;
2008 : : }
2009 : :
2010 : 0 : aq->qidx = sq->qid;
2011 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2012 : 0 : aq->op = NIX_AQ_INSTOP_READ;
2013 : : rc = mbox_process_msg(mbox, (void *)&rsp);
2014 [ # # ]: 0 : if (rc) {
2015 : : mbox_put(mbox);
2016 : 0 : return rc;
2017 : : }
2018 : :
2019 [ # # ]: 0 : if (rsp->sq.smq_pend)
2020 : 0 : plt_err("SQ has pending SQE's");
2021 : :
2022 : 0 : count = rsp->sq.sqb_count;
2023 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2024 : : /* Free SQB's that are used */
2025 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
2026 [ # # ]: 0 : while (count) {
2027 : : void *next_sqb;
2028 : :
2029 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
2030 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
2031 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
2032 : : sqb_buf = next_sqb;
2033 : 0 : count--;
2034 : : }
2035 : :
2036 : : /* Free next to use sqb */
2037 [ # # ]: 0 : if (rsp->sq.next_sqb)
2038 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
2039 : : mbox_put(mbox);
2040 : 0 : return 0;
2041 : : }
2042 : :
2043 : : static int
2044 : 0 : sq_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
2045 : : {
2046 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
2047 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
2048 : : struct nix_cn20k_aq_enq_req *aq;
2049 : :
2050 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2051 [ # # ]: 0 : if (!aq)
2052 : : return -ENOSPC;
2053 : :
2054 : 0 : aq->qidx = sq->qid;
2055 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2056 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
2057 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
2058 : :
2059 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
2060 : 0 : aq->sq.smq = smq;
2061 : 0 : aq->sq.smq_rr_weight = rr_quantum;
2062 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
2063 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
2064 : : else
2065 : 0 : aq->sq.default_chan = nix->tx_chan_base;
2066 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
2067 : 0 : aq->sq.ena = 1;
2068 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
2069 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
2070 : 0 : aq->sq.cq = sq->cqid;
2071 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
2072 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
2073 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
2074 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
2075 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
2076 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
2077 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
2078 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
2079 : :
2080 : : /* HW atomic update of SQ count */
2081 [ # # ]: 0 : if (sq->sq_cnt_ptr) {
2082 : 0 : aq->sq.sq_count_iova = ((uintptr_t)sq->sq_cnt_ptr) >> 3;
2083 : 0 : aq->sq.update_sq_count = sq->update_sq_cnt;
2084 : : }
2085 : : /* Many to one reduction */
2086 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
2087 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
2088 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
2089 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
2090 : : * might result in software missing the interrupt.
2091 : : */
2092 : 0 : aq->sq.qint_idx = 0;
2093 : : }
2094 : : return 0;
2095 : : }
2096 : :
2097 : : static int
2098 : 0 : sq_fini(struct nix *nix, struct roc_nix_sq *sq)
2099 : : {
2100 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
2101 : : struct nix_cn20k_aq_enq_rsp *rsp;
2102 : : struct nix_cn20k_aq_enq_req *aq;
2103 : : uint16_t sqes_per_sqb;
2104 : : void *sqb_buf;
2105 : : int rc, count;
2106 : :
2107 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2108 [ # # ]: 0 : if (!aq) {
2109 : : mbox_put(mbox);
2110 : 0 : return -ENOSPC;
2111 : : }
2112 : :
2113 : 0 : aq->qidx = sq->qid;
2114 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2115 : 0 : aq->op = NIX_AQ_INSTOP_READ;
2116 : : rc = mbox_process_msg(mbox, (void *)&rsp);
2117 [ # # ]: 0 : if (rc) {
2118 : : mbox_put(mbox);
2119 : 0 : return rc;
2120 : : }
2121 : :
2122 : : /* Check if sq is already cleaned up */
2123 [ # # ]: 0 : if (!rsp->sq.ena) {
2124 : : mbox_put(mbox);
2125 : 0 : return 0;
2126 : : }
2127 : :
2128 : : /* Disable sq */
2129 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2130 [ # # ]: 0 : if (!aq) {
2131 : : mbox_put(mbox);
2132 : 0 : return -ENOSPC;
2133 : : }
2134 : :
2135 : 0 : aq->qidx = sq->qid;
2136 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2137 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
2138 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
2139 : 0 : aq->sq.ena = 0;
2140 : 0 : rc = mbox_process(mbox);
2141 [ # # ]: 0 : if (rc) {
2142 : : mbox_put(mbox);
2143 : 0 : return rc;
2144 : : }
2145 : :
2146 : : /* Read SQ and free sqb's */
2147 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2148 [ # # ]: 0 : if (!aq) {
2149 : : mbox_put(mbox);
2150 : 0 : return -ENOSPC;
2151 : : }
2152 : :
2153 : 0 : aq->qidx = sq->qid;
2154 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2155 : 0 : aq->op = NIX_AQ_INSTOP_READ;
2156 : : rc = mbox_process_msg(mbox, (void *)&rsp);
2157 [ # # ]: 0 : if (rc) {
2158 : : mbox_put(mbox);
2159 : 0 : return rc;
2160 : : }
2161 : :
2162 [ # # ]: 0 : if (aq->sq.smq_pend)
2163 : 0 : plt_err("SQ has pending SQE's");
2164 : :
2165 : 0 : count = aq->sq.sqb_count;
2166 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2167 : : /* Free SQB's that are used */
2168 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
2169 [ # # ]: 0 : while (count) {
2170 : : void *next_sqb;
2171 : :
2172 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
2173 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
2174 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
2175 : : sqb_buf = next_sqb;
2176 : 0 : count--;
2177 : : }
2178 : :
2179 : : /* Free next to use sqb */
2180 [ # # ]: 0 : if (rsp->sq.next_sqb)
2181 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
2182 : : mbox_put(mbox);
2183 : 0 : return 0;
2184 : : }
2185 : :
2186 : : int
2187 [ # # ]: 0 : roc_nix_sq_init(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
2188 : : {
2189 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2190 : 0 : bool sq_resize_ena = roc_nix->sq_resize_ena;
2191 : 0 : struct mbox *m_box = (&nix->dev)->mbox;
2192 : 0 : uint16_t qid, smq = UINT16_MAX;
2193 : 0 : uint32_t rr_quantum = 0;
2194 : : struct mbox *mbox;
2195 : : int rc;
2196 : :
2197 [ # # ]: 0 : if (sq == NULL)
2198 : : return NIX_ERR_PARAM;
2199 : :
2200 : 0 : qid = sq->qid;
2201 [ # # ]: 0 : if (qid >= nix->nb_tx_queues)
2202 : : return NIX_ERR_QUEUE_INVALID_RANGE;
2203 : :
2204 : 0 : sq->roc_nix = roc_nix;
2205 : 0 : sq->tc = ROC_NIX_PFC_CLASS_INVALID;
2206 : : /*
2207 : : * Allocate memory for flow control updates from HW.
2208 : : * Alloc one cache line, so that fits all FC_STYPE modes.
2209 : : */
2210 : 0 : sq->fc = plt_zmalloc(ROC_ALIGN, ROC_ALIGN);
2211 [ # # ]: 0 : if (sq->fc == NULL) {
2212 : : rc = NIX_ERR_NO_MEM;
2213 : 0 : goto fail;
2214 : : }
2215 : :
2216 [ # # ]: 0 : if (sq_resize_ena)
2217 : 0 : rc = sqb_pool_dyn_populate(roc_nix, sq);
2218 : : else
2219 : 0 : rc = sqb_pool_populate(roc_nix, sq);
2220 [ # # ]: 0 : if (rc)
2221 : 0 : goto nomem;
2222 : :
2223 : 0 : rc = nix_tm_leaf_data_get(nix, sq->qid, &rr_quantum, &smq);
2224 [ # # ]: 0 : if (rc) {
2225 : : rc = NIX_ERR_TM_LEAF_NODE_GET;
2226 : 0 : goto nomem;
2227 : : }
2228 : :
2229 : : mbox = mbox_get(m_box);
2230 : : /* Init SQ context */
2231 [ # # ]: 0 : if (roc_model_is_cn9k())
2232 : 0 : rc = sq_cn9k_init(nix, sq, rr_quantum, smq);
2233 [ # # ]: 0 : else if (roc_model_is_cn10k())
2234 : 0 : rc = sq_cn10k_init(nix, sq, rr_quantum, smq);
2235 : : else
2236 : 0 : rc = sq_init(nix, sq, rr_quantum, smq);
2237 : :
2238 [ # # ]: 0 : if (rc) {
2239 : : mbox_put(mbox);
2240 : 0 : goto nomem;
2241 : : }
2242 : :
2243 : :
2244 : 0 : rc = mbox_process(mbox);
2245 [ # # ]: 0 : if (rc) {
2246 : : mbox_put(mbox);
2247 : 0 : goto nomem;
2248 : : }
2249 : : mbox_put(mbox);
2250 : :
2251 : 0 : sq->enable = true;
2252 : 0 : nix->sqs[qid] = sq;
2253 [ # # ]: 0 : sq->io_addr = nix->base + NIX_LF_OP_SENDX(0);
2254 : : /* Evenly distribute LMT slot for each sq */
2255 [ # # ]: 0 : if (roc_model_is_cn9k()) {
2256 : : /* Multiple cores/SQ's can use same LMTLINE safely in CN9K */
2257 : 0 : sq->lmt_addr = (void *)(nix->lmt_base +
2258 : 0 : ((qid & RVU_CN9K_LMT_SLOT_MASK) << 12));
2259 : : }
2260 : :
2261 : 0 : rc = nix_tel_node_add_sq(sq);
2262 : 0 : return rc;
2263 : 0 : nomem:
2264 : 0 : plt_free(sq->fc);
2265 : : fail:
2266 : : return rc;
2267 : : }
2268 : :
2269 : : static void
2270 : 0 : nix_sqb_mem_dyn_free(uint64_t aura_handle, uint16_t count)
2271 : : {
2272 : : uint64_t iova;
2273 : :
2274 : : /* Recover SQB's and free them back */
2275 : : while (count) {
2276 : : iova = roc_npa_aura_op_alloc(aura_handle, 0);
2277 : : if (!iova)
2278 : : break;
2279 : : plt_free((uint64_t *)iova);
2280 : : count--;
2281 : : }
2282 [ # # ]: 0 : if (count)
2283 : 0 : plt_err("Failed to recover %u SQB's", count);
2284 : 0 : }
2285 : :
2286 : : int
2287 : 0 : roc_nix_sq_fini(struct roc_nix_sq *sq)
2288 : : {
2289 : : struct ndc_sync_op *ndc_req;
2290 : : struct roc_nix *roc_nix;
2291 : : bool sq_resize_ena;
2292 : : struct mbox *mbox;
2293 : : struct nix *nix;
2294 : : uint16_t qid;
2295 : : int rc = 0;
2296 : :
2297 [ # # ]: 0 : if (sq == NULL)
2298 : : return NIX_ERR_PARAM;
2299 : :
2300 : 0 : roc_nix = sq->roc_nix;
2301 : 0 : sq_resize_ena = roc_nix->sq_resize_ena;
2302 : :
2303 : : nix = roc_nix_to_nix_priv(roc_nix);
2304 : 0 : mbox = (&nix->dev)->mbox;
2305 : :
2306 : 0 : qid = sq->qid;
2307 : :
2308 : 0 : rc = nix_tm_sq_flush_pre(sq);
2309 : :
2310 : : /* Release SQ context */
2311 [ # # ]: 0 : if (roc_model_is_cn9k())
2312 : 0 : rc |= sq_cn9k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2313 [ # # ]: 0 : else if (roc_model_is_cn10k())
2314 : 0 : rc |= sq_cn10k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2315 : : else
2316 : 0 : rc |= sq_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2317 : :
2318 : : /* Sync NDC-NIX-TX for LF */
2319 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox_get(mbox));
2320 [ # # ]: 0 : if (ndc_req == NULL) {
2321 : : mbox_put(mbox);
2322 : 0 : return -ENOSPC;
2323 : : }
2324 : 0 : ndc_req->nix_lf_tx_sync = 1;
2325 [ # # ]: 0 : if (mbox_process(mbox))
2326 : 0 : rc |= NIX_ERR_NDC_SYNC;
2327 : : mbox_put(mbox);
2328 : :
2329 : 0 : rc |= nix_tm_sq_flush_post(sq);
2330 : :
2331 : : /* Restore limit to max SQB count that the pool was created
2332 : : * for aura drain to succeed.
2333 : : */
2334 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, sq->aura_sqb_bufs);
2335 : :
2336 [ # # ]: 0 : if (sq_resize_ena)
2337 : 0 : nix_sqb_mem_dyn_free(sq->aura_handle, sq->aura_sqb_bufs);
2338 : :
2339 : 0 : rc |= roc_npa_pool_destroy(sq->aura_handle);
2340 : 0 : plt_free(sq->fc);
2341 [ # # ]: 0 : if (!sq_resize_ena)
2342 : 0 : plt_free(sq->sqe_mem);
2343 : 0 : nix->sqs[qid] = NULL;
2344 : :
2345 : 0 : return rc;
2346 : : }
2347 : :
2348 : : static int
2349 : 0 : sqb_aura_dyn_expand(struct roc_nix_sq *sq, uint16_t count)
2350 : : {
2351 : 0 : struct nix *nix = roc_nix_to_nix_priv(sq->roc_nix);
2352 : : uint64_t *sqbs = NULL;
2353 : : uint16_t blk_sz;
2354 : : int i;
2355 : :
2356 : 0 : blk_sz = nix->sqb_size;
2357 : 0 : sqbs = calloc(1, count * sizeof(uint64_t));
2358 [ # # ]: 0 : if (!sqbs)
2359 : : return -ENOMEM;
2360 : :
2361 [ # # ]: 0 : for (i = 0; i < count; i++) {
2362 : 0 : sqbs[i] = (uint64_t)plt_zmalloc(blk_sz, ROC_ALIGN);
2363 [ # # ]: 0 : if (!sqbs[i])
2364 : : break;
2365 : : }
2366 : :
2367 [ # # ]: 0 : if (i != count) {
2368 : 0 : i = i - 1;
2369 [ # # ]: 0 : for (; i >= 0; i--)
2370 : 0 : plt_free((void *)sqbs[i]);
2371 : 0 : free(sqbs);
2372 : 0 : return -ENOMEM;
2373 : : }
2374 : :
2375 : 0 : plt_io_wmb();
2376 : :
2377 : : /* Add new buffers to sqb aura */
2378 [ # # ]: 0 : for (i = 0; i < count; i++)
2379 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, sqbs[i]);
2380 : 0 : free(sqbs);
2381 : :
2382 : : /* Adjust SQ info */
2383 : 0 : sq->nb_sqb_bufs += count;
2384 : 0 : sq->nb_sqb_bufs_adj += count;
2385 : 0 : sq->aura_sqb_bufs += count;
2386 : 0 : return 0;
2387 : : }
2388 : :
2389 : : static int
2390 : 0 : sqb_aura_dyn_contract(struct roc_nix_sq *sq, uint16_t count)
2391 : : {
2392 : 0 : struct nix *nix = roc_nix_to_nix_priv(sq->roc_nix);
2393 : : struct dev *dev = &nix->dev;
2394 : : struct ndc_sync_op *ndc_req;
2395 : : uint64_t *sqbs = NULL;
2396 : : struct mbox *mbox;
2397 : : uint64_t timeout; /* 10's of usec */
2398 : : uint64_t cycles;
2399 : : int i, rc;
2400 : :
2401 : 0 : mbox = dev->mbox;
2402 : : /* Sync NDC-NIX-TX for LF */
2403 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox_get(mbox));
2404 [ # # ]: 0 : if (ndc_req == NULL) {
2405 : : mbox_put(mbox);
2406 : 0 : return -EFAULT;
2407 : : }
2408 : :
2409 : 0 : ndc_req->nix_lf_tx_sync = 1;
2410 : 0 : rc = mbox_process(mbox);
2411 [ # # ]: 0 : if (rc) {
2412 : : mbox_put(mbox);
2413 : 0 : return rc;
2414 : : }
2415 : : mbox_put(mbox);
2416 : :
2417 : : /* Wait for enough time based on shaper min rate */
2418 : 0 : timeout = (sq->nb_desc * roc_nix_max_pkt_len(sq->roc_nix) * 8 * 1E5);
2419 : : /* Wait for worst case scenario of this SQ being last priority
2420 : : * and so have to wait for all other SQ's drain out by their own.
2421 : : */
2422 : 0 : timeout = timeout * nix->nb_tx_queues;
2423 : 0 : timeout = timeout / nix->tm_rate_min;
2424 [ # # ]: 0 : if (!timeout)
2425 : : timeout = 10000;
2426 : 0 : cycles = (timeout * 10 * plt_tsc_hz()) / (uint64_t)1E6;
2427 : 0 : cycles += plt_tsc_cycles();
2428 : :
2429 : 0 : sqbs = calloc(1, count * sizeof(uint64_t));
2430 [ # # ]: 0 : if (!sqbs)
2431 : : return -ENOMEM;
2432 : :
2433 : : i = 0;
2434 [ # # # # ]: 0 : while (i < count && plt_tsc_cycles() < cycles) {
2435 : 0 : sqbs[i] = roc_npa_aura_op_alloc(sq->aura_handle, 0);
2436 : : if (sqbs[i])
2437 : : i++;
2438 : : else
2439 : 0 : plt_delay_us(1);
2440 : : }
2441 : :
2442 [ # # ]: 0 : if (i != count) {
2443 : 0 : plt_warn("SQ %u busy, unable to recover %u SQB's(%u desc)", sq->qid, count,
2444 : : count * sq->sqes_per_sqb);
2445 : :
2446 : : /* Restore the SQB aura state and return */
2447 : : i--;
2448 : : for (; i >= 0; i--)
2449 : : roc_npa_aura_op_free(sq->aura_handle, 0, sqbs[i]);
2450 : 0 : free(sqbs);
2451 : 0 : return -EAGAIN;
2452 : : }
2453 : :
2454 : : /* Extracted necessary SQB's, on free them */
2455 : : for (i = 0; i < count; i++)
2456 : : plt_free((void *)sqbs[i]);
2457 : 0 : free(sqbs);
2458 : :
2459 : : /* Adjust SQ info */
2460 : 0 : sq->nb_sqb_bufs -= count;
2461 : 0 : sq->nb_sqb_bufs_adj -= count;
2462 : 0 : sq->aura_sqb_bufs -= count;
2463 : 0 : return 0;
2464 : : }
2465 : :
2466 : : int
2467 : 0 : roc_nix_sq_resize(struct roc_nix_sq *sq, uint32_t nb_desc)
2468 : : {
2469 : 0 : struct roc_nix *roc_nix = sq->roc_nix;
2470 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2471 : : uint16_t aura_sqb_bufs, nb_sqb_bufs, sqes_per_sqb;
2472 : : int64_t *regaddr;
2473 : : uint64_t wdata;
2474 : : uint16_t diff;
2475 : : int rc;
2476 : :
2477 [ # # ]: 0 : if (!roc_nix->sq_resize_ena)
2478 : : return -ENOTSUP;
2479 : :
2480 : 0 : sqes_per_sqb = sq->sqes_per_sqb;
2481 : :
2482 : : /* Calculate new nb_sqb_bufs */
2483 : : nb_sqb_bufs = sq_desc_to_sqb(nix, sqes_per_sqb, nb_desc);
2484 [ # # ]: 0 : aura_sqb_bufs = sqb_slack_adjust(nix, nb_sqb_bufs, !!sq->sq_cnt_ptr);
2485 : :
2486 [ # # ]: 0 : if (aura_sqb_bufs == sq->aura_sqb_bufs)
2487 : : return 0;
2488 : :
2489 : : /* Issue atomic op to make sure all inflight LMTST's are complete
2490 : : * assuming no new submissions will take place.
2491 : : */
2492 : : wdata = ((uint64_t)sq->qid) << 32;
2493 : : regaddr = (int64_t *)(nix->base + NIX_LF_SQ_OP_STATUS);
2494 : : roc_atomic64_add_nosync(wdata, regaddr);
2495 : :
2496 : : /* Expand or Contract SQB aura */
2497 [ # # ]: 0 : if (aura_sqb_bufs > sq->aura_sqb_bufs) {
2498 : : /* Increase the limit */
2499 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, aura_sqb_bufs);
2500 : 0 : diff = aura_sqb_bufs - sq->aura_sqb_bufs;
2501 [ # # ]: 0 : roc_npa_aura_op_cnt_set(sq->aura_handle, 1, diff);
2502 : :
2503 : 0 : rc = sqb_aura_dyn_expand(sq, diff);
2504 : : } else {
2505 : 0 : diff = sq->aura_sqb_bufs - aura_sqb_bufs;
2506 : 0 : rc = sqb_aura_dyn_contract(sq, diff);
2507 : :
2508 : : /* Decrease the limit */
2509 [ # # ]: 0 : if (!rc) {
2510 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, aura_sqb_bufs);
2511 [ # # ]: 0 : roc_npa_aura_op_cnt_set(sq->aura_handle, 1, -(int64_t)diff);
2512 : : }
2513 : : }
2514 : :
2515 : 0 : plt_io_wmb();
2516 [ # # ]: 0 : if (!rc) {
2517 : 0 : sq->nb_desc = nb_desc;
2518 [ # # ]: 0 : if (sq->sq_cnt_ptr)
2519 : 0 : plt_atomic_store_explicit((uint64_t __plt_atomic *)sq->sq_cnt_ptr, nb_desc,
2520 : : plt_memory_order_release);
2521 : 0 : *(uint64_t *)sq->fc = roc_npa_aura_op_cnt_get(sq->aura_handle);
2522 : : } else {
2523 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, sq->aura_sqb_bufs);
2524 : : }
2525 : :
2526 : 0 : plt_io_wmb();
2527 : 0 : return rc;
2528 : : }
2529 : :
2530 : : void
2531 : 0 : roc_nix_cq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2532 : : uint32_t *tail)
2533 : : {
2534 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2535 : : uint64_t reg, val;
2536 : : int64_t *addr;
2537 : :
2538 [ # # ]: 0 : if (head == NULL || tail == NULL)
2539 : : return;
2540 : :
2541 : : reg = (((uint64_t)qid) << 32);
2542 : : addr = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
2543 : : val = roc_atomic64_add_nosync(reg, addr);
2544 : : if (val &
2545 : : (BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) | BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR)))
2546 : : val = 0;
2547 : :
2548 : 0 : *tail = (uint32_t)(val & 0xFFFFF);
2549 : 0 : *head = (uint32_t)((val >> 20) & 0xFFFFF);
2550 : : }
2551 : :
2552 : : void
2553 : 0 : roc_nix_sq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2554 : : uint32_t *tail)
2555 : : {
2556 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2557 : 0 : struct roc_nix_sq *sq = nix->sqs[qid];
2558 : : uint16_t sqes_per_sqb, sqb_cnt;
2559 : : uint64_t reg, val;
2560 : : int64_t *addr;
2561 : :
2562 [ # # ]: 0 : if (head == NULL || tail == NULL)
2563 : : return;
2564 : :
2565 : : reg = (((uint64_t)qid) << 32);
2566 : : addr = (int64_t *)(nix->base + NIX_LF_SQ_OP_STATUS);
2567 : : val = roc_atomic64_add_nosync(reg, addr);
2568 : : if (val & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR)) {
2569 : : val = 0;
2570 : : return;
2571 : : }
2572 : :
2573 : : *tail = (uint32_t)((val >> 28) & 0x3F);
2574 : 0 : *head = (uint32_t)((val >> 20) & 0x3F);
2575 : : sqb_cnt = (uint16_t)(val & 0xFFFF);
2576 : :
2577 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2578 : :
2579 : : /* Update tail index as per used sqb count */
2580 : 0 : *tail += (sqes_per_sqb * (sqb_cnt - 1));
2581 : : }
2582 : :
2583 : : int
2584 : 0 : roc_nix_q_err_cb_register(struct roc_nix *roc_nix, q_err_get_t sq_err_handle)
2585 : : {
2586 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2587 : : struct dev *dev = &nix->dev;
2588 : :
2589 [ # # ]: 0 : if (sq_err_handle == NULL)
2590 : : return NIX_ERR_PARAM;
2591 : :
2592 : 0 : dev->ops->q_err_cb = (q_err_cb_t)sq_err_handle;
2593 : 0 : return 0;
2594 : : }
2595 : :
2596 : : void
2597 : 0 : roc_nix_q_err_cb_unregister(struct roc_nix *roc_nix)
2598 : : {
2599 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2600 : : struct dev *dev = &nix->dev;
2601 : :
2602 : 0 : dev->ops->q_err_cb = NULL;
2603 : 0 : }
2604 : :
2605 : : int
2606 : 0 : roc_nix_sq_cnt_update(struct roc_nix_sq *sq, bool enable)
2607 : : {
2608 : 0 : struct nix *nix = roc_nix_to_nix_priv(sq->roc_nix);
2609 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
2610 : 0 : int64_t __plt_atomic *sq_cntm = (int64_t __plt_atomic *)sq->sq_cnt_ptr;
2611 : : struct nix_cn20k_aq_enq_rsp *rsp;
2612 : : struct nix_cn20k_aq_enq_req *aq;
2613 : : int rc;
2614 : :
2615 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2616 [ # # ]: 0 : if (!aq) {
2617 : : mbox_put(mbox);
2618 : 0 : return -ENOSPC;
2619 : : }
2620 : :
2621 : 0 : aq->qidx = sq->qid;
2622 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2623 : 0 : aq->op = NIX_AQ_INSTOP_READ;
2624 : : rc = mbox_process_msg(mbox, (void *)&rsp);
2625 [ # # ]: 0 : if (rc) {
2626 : : mbox_put(mbox);
2627 : 0 : return rc;
2628 : : }
2629 : :
2630 : : /* Check if sq is already in same state */
2631 [ # # # # : 0 : if ((enable && rsp->sq.update_sq_count) || (!enable && !rsp->sq.update_sq_count)) {
# # # # ]
2632 : : mbox_put(mbox);
2633 : 0 : return 0;
2634 : : }
2635 : :
2636 : : /* Disable sq */
2637 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2638 [ # # ]: 0 : if (!aq) {
2639 : : mbox_put(mbox);
2640 : 0 : return -ENOSPC;
2641 : : }
2642 : :
2643 : 0 : aq->qidx = sq->qid;
2644 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2645 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
2646 : 0 : aq->sq_mask.update_sq_count = ~aq->sq_mask.update_sq_count;
2647 : 0 : aq->sq.update_sq_count = enable;
2648 [ # # ]: 0 : if (enable)
2649 : 0 : aq->sq.update_sq_count = sq->update_sq_cnt;
2650 : 0 : rc = mbox_process(mbox);
2651 [ # # ]: 0 : if (rc) {
2652 : : mbox_put(mbox);
2653 : 0 : return rc;
2654 : : }
2655 [ # # ]: 0 : if (enable)
2656 : 0 : plt_atomic_store_explicit(sq_cntm, sq->nb_desc, plt_memory_order_relaxed);
2657 : : else
2658 : 0 : plt_atomic_store_explicit(sq_cntm, 0, plt_memory_order_relaxed);
2659 : :
2660 : : mbox_put(mbox);
2661 : 0 : return 0;
2662 : : }
|