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 = rq->xqe_drop_ena;
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.xqe_drop_ena = 0;
617 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
618 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
619 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
620 : :
621 [ # # ]: 0 : if (rq->vwqe_ena) {
622 : 0 : aq->rq.vwqe_ena = true;
623 : 0 : aq->rq.vwqe_skip = rq->vwqe_first_skip;
624 : : /* Maximal Vector size is (2^(MAX_VSIZE_EXP+2)) */
625 : 0 : aq->rq.max_vsize_exp = rq->vwqe_max_sz_exp - 2;
626 : 0 : aq->rq.vtime_wait = rq->vwqe_wait_tmo;
627 : 0 : aq->rq.wqe_aura = roc_npa_aura_handle_to_aura(rq->vwqe_aura_handle);
628 : : }
629 : : } else {
630 : : /* CQ mode */
631 : 0 : aq->rq.sso_ena = 0;
632 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
633 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
634 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
635 : 0 : aq->rq.cq = rq->cqid;
636 [ # # ]: 0 : if (rq->xqe_drop_ena)
637 : 0 : aq->rq.xqe_drop_ena = 1;
638 : : }
639 : :
640 [ # # ]: 0 : if (rq->ipsech_ena) {
641 : 0 : aq->rq.ipsech_ena = 1;
642 : 0 : aq->rq.ipsecd_drop_en = 1;
643 : 0 : aq->rq.ena_wqwd = 1;
644 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
645 : 0 : aq->rq.wqe_caching = 1;
646 : : }
647 : :
648 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
649 : :
650 : : /* Sizes must be aligned to 8 bytes */
651 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
652 : : return -EINVAL;
653 : :
654 : : /* Expressed in number of dwords */
655 : 0 : aq->rq.first_skip = rq->first_skip / 8;
656 : 0 : aq->rq.later_skip = rq->later_skip / 8;
657 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
658 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
659 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
660 : 0 : aq->rq.ena = ena;
661 : :
662 [ # # ]: 0 : if (rq->spb_ena) {
663 : : uint32_t spb_sizem1;
664 : :
665 : 0 : aq->rq.spb_ena = 1;
666 : 0 : aq->rq.spb_aura =
667 [ # # ]: 0 : roc_npa_aura_handle_to_aura(rq->spb_aura_handle);
668 : :
669 [ # # # # ]: 0 : if (rq->spb_size & 0x7 ||
670 : : rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE)
671 : : return -EINVAL;
672 : :
673 : 0 : spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */
674 : 0 : spb_sizem1 -= 1; /* Expressed in size minus one */
675 : 0 : aq->rq.spb_sizem1 = spb_sizem1 & 0x3F;
676 : 0 : aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7;
677 : : } else {
678 : 0 : aq->rq.spb_ena = 0;
679 : : }
680 : :
681 : 0 : aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
682 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
683 : 0 : aq->rq.rq_int_ena = 0;
684 : : /* Many to one reduction */
685 : 0 : aq->rq.qint_idx = rq->qid % qints;
686 : 0 : aq->rq.lpb_drop_ena = rq->lpb_drop_ena;
687 : 0 : aq->rq.spb_drop_ena = rq->spb_drop_ena;
688 : :
689 : : /* If RED enabled, then fill enable for all cases */
690 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
691 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
692 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
693 : 0 : aq->rq.wqe_pool_pass = rq->red_pass;
694 : 0 : aq->rq.xqe_pass = rq->red_pass;
695 : :
696 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
697 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
698 : 0 : aq->rq.wqe_pool_drop = rq->red_drop;
699 : 0 : aq->rq.xqe_drop = rq->red_drop;
700 : : }
701 : :
702 [ # # ]: 0 : if (cfg) {
703 [ # # ]: 0 : if (rq->sso_ena) {
704 : : /* SSO mode */
705 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
706 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
707 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
708 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
709 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
710 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
711 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
712 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
713 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
714 [ # # ]: 0 : if (rq->vwqe_ena) {
715 : 0 : aq->rq_mask.vwqe_ena = ~aq->rq_mask.vwqe_ena;
716 : 0 : aq->rq_mask.vwqe_skip = ~aq->rq_mask.vwqe_skip;
717 : 0 : aq->rq_mask.max_vsize_exp =
718 : 0 : ~aq->rq_mask.max_vsize_exp;
719 : 0 : aq->rq_mask.vtime_wait =
720 : 0 : ~aq->rq_mask.vtime_wait;
721 : 0 : aq->rq_mask.wqe_aura = ~aq->rq_mask.wqe_aura;
722 : : }
723 : : } else {
724 : : /* CQ mode */
725 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
726 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
727 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
728 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
729 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
730 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
731 : : }
732 : :
733 [ # # ]: 0 : if (rq->ipsech_ena)
734 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
735 : :
736 [ # # ]: 0 : if (rq->spb_ena) {
737 : 0 : aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura;
738 : 0 : aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1;
739 : 0 : aq->rq_mask.spb_high_sizem1 =
740 : 0 : ~aq->rq_mask.spb_high_sizem1;
741 : : }
742 : :
743 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
744 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
745 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
746 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
747 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
748 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
749 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
750 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
751 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
752 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
753 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
754 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
755 : 0 : aq->rq_mask.lpb_drop_ena = ~aq->rq_mask.lpb_drop_ena;
756 : 0 : aq->rq_mask.spb_drop_ena = ~aq->rq_mask.spb_drop_ena;
757 : :
758 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
759 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
760 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
761 : 0 : aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass;
762 : 0 : aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass;
763 : :
764 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
765 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
766 : 0 : aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop;
767 : 0 : aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop;
768 : : }
769 : : }
770 : :
771 : : return 0;
772 : : }
773 : :
774 : : int
775 : 0 : nix_rq_cfg(struct dev *dev, struct roc_nix_rq *rq, uint16_t qints, bool cfg, bool ena)
776 : : {
777 : : struct nix_cn20k_aq_enq_req *aq;
778 : 0 : struct mbox *mbox = dev->mbox;
779 : :
780 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
781 [ # # ]: 0 : if (!aq)
782 : : return -ENOSPC;
783 : :
784 : 0 : aq->qidx = rq->qid;
785 : 0 : aq->ctype = NIX_AQ_CTYPE_RQ;
786 [ # # ]: 0 : aq->op = cfg ? NIX_AQ_INSTOP_WRITE : NIX_AQ_INSTOP_INIT;
787 : :
788 [ # # ]: 0 : if (rq->sso_ena) {
789 : : /* SSO mode */
790 : 0 : aq->rq.sso_ena = 1;
791 : 0 : aq->rq.sso_tt = rq->tt;
792 : 0 : aq->rq.sso_grp = rq->hwgrp;
793 : 0 : aq->rq.ena_wqwd = 1;
794 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
795 : 0 : aq->rq.wqe_caching = 1;
796 : :
797 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
798 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
799 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
800 : : } else {
801 : : /* CQ mode */
802 : 0 : aq->rq.sso_ena = 0;
803 : 0 : aq->rq.good_utag = rq->tag_mask >> 24;
804 : 0 : aq->rq.bad_utag = rq->tag_mask >> 24;
805 : 0 : aq->rq.ltag = rq->tag_mask & BITMASK_ULL(24, 0);
806 : 0 : aq->rq.cq = rq->cqid;
807 : : }
808 : :
809 [ # # ]: 0 : if (rq->ipsech_ena) {
810 : 0 : aq->rq.ipsech_ena = 1;
811 : 0 : aq->rq.ipsecd_drop_en = 1;
812 : 0 : aq->rq.ena_wqwd = 1;
813 : 0 : aq->rq.wqe_skip = rq->wqe_skip;
814 : 0 : aq->rq.wqe_caching = 1;
815 : : }
816 : :
817 [ # # ]: 0 : aq->rq.lpb_aura = roc_npa_aura_handle_to_aura(rq->aura_handle);
818 : :
819 : : /* Sizes must be aligned to 8 bytes */
820 [ # # # # : 0 : if (rq->first_skip & 0x7 || rq->later_skip & 0x7 || rq->lpb_size & 0x7)
# # ]
821 : : return -EINVAL;
822 : :
823 : : /* Expressed in number of dwords */
824 : 0 : aq->rq.first_skip = rq->first_skip / 8;
825 : 0 : aq->rq.later_skip = rq->later_skip / 8;
826 : 0 : aq->rq.flow_tagw = rq->flow_tag_width; /* 32-bits */
827 : 0 : aq->rq.lpb_sizem1 = rq->lpb_size / 8;
828 : 0 : aq->rq.lpb_sizem1 -= 1; /* Expressed in size minus one */
829 : 0 : aq->rq.ena = ena;
830 : :
831 [ # # ]: 0 : if (rq->spb_ena) {
832 : : uint32_t spb_sizem1;
833 : :
834 : 0 : aq->rq.spb_ena = 1;
835 : 0 : aq->rq.spb_aura =
836 [ # # ]: 0 : roc_npa_aura_handle_to_aura(rq->spb_aura_handle);
837 : :
838 [ # # # # ]: 0 : if (rq->spb_size & 0x7 ||
839 : : rq->spb_size > NIX_RQ_CN10K_SPB_MAX_SIZE)
840 : : return -EINVAL;
841 : :
842 : 0 : spb_sizem1 = rq->spb_size / 8; /* Expressed in no. of dwords */
843 : 0 : spb_sizem1 -= 1; /* Expressed in size minus one */
844 : 0 : aq->rq.spb_sizem1 = spb_sizem1 & 0x3F;
845 : 0 : aq->rq.spb_high_sizem1 = (spb_sizem1 >> 6) & 0x7;
846 : : } else {
847 : 0 : aq->rq.spb_ena = 0;
848 : : }
849 : :
850 : 0 : aq->rq.pb_caching = 0x2; /* First cache aligned block to LLC */
851 : 0 : aq->rq.xqe_imm_size = 0; /* No pkt data copy to CQE */
852 : 0 : aq->rq.rq_int_ena = 0;
853 : : /* Many to one reduction */
854 : 0 : aq->rq.qint_idx = rq->qid % qints;
855 : 0 : aq->rq.xqe_drop_ena = 0;
856 : 0 : aq->rq.lpb_drop_ena = rq->lpb_drop_ena;
857 : 0 : aq->rq.spb_drop_ena = rq->spb_drop_ena;
858 : :
859 : : /* If RED enabled, then fill enable for all cases */
860 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
861 : 0 : aq->rq.spb_pool_pass = rq->spb_red_pass;
862 : 0 : aq->rq.lpb_pool_pass = rq->red_pass;
863 : 0 : aq->rq.wqe_pool_pass = rq->red_pass;
864 : 0 : aq->rq.xqe_pass = rq->red_pass;
865 : :
866 : 0 : aq->rq.spb_pool_drop = rq->spb_red_drop;
867 : 0 : aq->rq.lpb_pool_drop = rq->red_drop;
868 : 0 : aq->rq.wqe_pool_drop = rq->red_drop;
869 : 0 : aq->rq.xqe_drop = rq->red_drop;
870 : : }
871 : :
872 [ # # ]: 0 : if (cfg) {
873 [ # # ]: 0 : if (rq->sso_ena) {
874 : : /* SSO mode */
875 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
876 : 0 : aq->rq_mask.sso_tt = ~aq->rq_mask.sso_tt;
877 : 0 : aq->rq_mask.sso_grp = ~aq->rq_mask.sso_grp;
878 : 0 : aq->rq_mask.ena_wqwd = ~aq->rq_mask.ena_wqwd;
879 : 0 : aq->rq_mask.wqe_skip = ~aq->rq_mask.wqe_skip;
880 : 0 : aq->rq_mask.wqe_caching = ~aq->rq_mask.wqe_caching;
881 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
882 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
883 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
884 : : } else {
885 : : /* CQ mode */
886 : 0 : aq->rq_mask.sso_ena = ~aq->rq_mask.sso_ena;
887 : 0 : aq->rq_mask.good_utag = ~aq->rq_mask.good_utag;
888 : 0 : aq->rq_mask.bad_utag = ~aq->rq_mask.bad_utag;
889 : 0 : aq->rq_mask.ltag = ~aq->rq_mask.ltag;
890 : 0 : aq->rq_mask.cq = ~aq->rq_mask.cq;
891 : : }
892 : :
893 [ # # ]: 0 : if (rq->ipsech_ena)
894 : 0 : aq->rq_mask.ipsech_ena = ~aq->rq_mask.ipsech_ena;
895 : :
896 [ # # ]: 0 : if (rq->spb_ena) {
897 : 0 : aq->rq_mask.spb_aura = ~aq->rq_mask.spb_aura;
898 : 0 : aq->rq_mask.spb_sizem1 = ~aq->rq_mask.spb_sizem1;
899 : 0 : aq->rq_mask.spb_high_sizem1 =
900 : 0 : ~aq->rq_mask.spb_high_sizem1;
901 : : }
902 : :
903 : 0 : aq->rq_mask.spb_ena = ~aq->rq_mask.spb_ena;
904 : 0 : aq->rq_mask.lpb_aura = ~aq->rq_mask.lpb_aura;
905 : 0 : aq->rq_mask.first_skip = ~aq->rq_mask.first_skip;
906 : 0 : aq->rq_mask.later_skip = ~aq->rq_mask.later_skip;
907 : 0 : aq->rq_mask.flow_tagw = ~aq->rq_mask.flow_tagw;
908 : 0 : aq->rq_mask.lpb_sizem1 = ~aq->rq_mask.lpb_sizem1;
909 : 0 : aq->rq_mask.ena = ~aq->rq_mask.ena;
910 : 0 : aq->rq_mask.pb_caching = ~aq->rq_mask.pb_caching;
911 : 0 : aq->rq_mask.xqe_imm_size = ~aq->rq_mask.xqe_imm_size;
912 : 0 : aq->rq_mask.rq_int_ena = ~aq->rq_mask.rq_int_ena;
913 : 0 : aq->rq_mask.qint_idx = ~aq->rq_mask.qint_idx;
914 : 0 : aq->rq_mask.xqe_drop_ena = ~aq->rq_mask.xqe_drop_ena;
915 : 0 : aq->rq_mask.lpb_drop_ena = ~aq->rq_mask.lpb_drop_ena;
916 : 0 : aq->rq_mask.spb_drop_ena = ~aq->rq_mask.spb_drop_ena;
917 : :
918 [ # # # # ]: 0 : if (rq->red_pass && (rq->red_pass >= rq->red_drop)) {
919 : 0 : aq->rq_mask.spb_pool_pass = ~aq->rq_mask.spb_pool_pass;
920 : 0 : aq->rq_mask.lpb_pool_pass = ~aq->rq_mask.lpb_pool_pass;
921 : 0 : aq->rq_mask.wqe_pool_pass = ~aq->rq_mask.wqe_pool_pass;
922 : 0 : aq->rq_mask.xqe_pass = ~aq->rq_mask.xqe_pass;
923 : :
924 : 0 : aq->rq_mask.spb_pool_drop = ~aq->rq_mask.spb_pool_drop;
925 : 0 : aq->rq_mask.lpb_pool_drop = ~aq->rq_mask.lpb_pool_drop;
926 : 0 : aq->rq_mask.wqe_pool_drop = ~aq->rq_mask.wqe_pool_drop;
927 : 0 : aq->rq_mask.xqe_drop = ~aq->rq_mask.xqe_drop;
928 : : }
929 : : }
930 : :
931 : : return 0;
932 : : }
933 : :
934 : : int
935 : 0 : roc_nix_rq_init(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
936 : : {
937 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
938 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
939 : : bool is_cn9k = roc_model_is_cn9k();
940 : 0 : struct dev *dev = &nix->dev;
941 : : int rc;
942 : :
943 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL) {
944 : : mbox_put(mbox);
945 : 0 : return NIX_ERR_PARAM;
946 : : }
947 : :
948 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues) {
949 : : mbox_put(mbox);
950 : 0 : return NIX_ERR_QUEUE_INVALID_RANGE;
951 : : }
952 : :
953 : 0 : rq->roc_nix = roc_nix;
954 [ # # ]: 0 : rq->tc = ROC_NIX_PFC_CLASS_INVALID;
955 : :
956 : : /* Enable XQE/CQ drop on cn10k to count pkt drops only when inline is disabled */
957 [ # # ]: 0 : if (roc_model_is_cn10k() &&
958 [ # # # # ]: 0 : (roc_nix->force_tail_drop || !roc_nix_inl_inb_is_enabled(roc_nix)))
959 : 0 : rq->xqe_drop_ena = roc_nix->dis_xqe_drop ? false : true;
960 : :
961 [ # # ]: 0 : if (is_cn9k)
962 : 0 : rc = nix_rq_cn9k_cfg(dev, rq, nix->qints, false, ena);
963 [ # # ]: 0 : else if (roc_model_is_cn10k())
964 : 0 : rc = nix_rq_cn10k_cfg(dev, rq, nix->qints, false, ena);
965 : : else
966 : 0 : rc = nix_rq_cfg(dev, rq, nix->qints, false, ena);
967 : :
968 [ # # ]: 0 : if (rc) {
969 : : mbox_put(mbox);
970 : 0 : return rc;
971 : : }
972 : :
973 : 0 : rc = mbox_process(mbox);
974 [ # # ]: 0 : if (rc) {
975 : : mbox_put(mbox);
976 : 0 : return rc;
977 : : }
978 : : mbox_put(mbox);
979 : :
980 : : /* Update aura buf type to indicate its use */
981 : 0 : nix_rq_aura_buf_type_update(rq, true);
982 : :
983 : : /* Check for meta aura if RQ is enabled */
984 [ # # # # ]: 0 : if (ena && nix->need_meta_aura) {
985 : 0 : rc = roc_nix_inl_meta_aura_check(roc_nix, rq);
986 [ # # ]: 0 : if (rc)
987 : : return rc;
988 : : }
989 : :
990 : 0 : nix->rqs[rq->qid] = rq;
991 : 0 : return nix_tel_node_add_rq(rq);
992 : : }
993 : :
994 : : int
995 : 0 : roc_nix_rq_modify(struct roc_nix *roc_nix, struct roc_nix_rq *rq, bool ena)
996 : : {
997 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
998 [ # # ]: 0 : struct mbox *m_box = (&nix->dev)->mbox;
999 : : bool is_cn9k = roc_model_is_cn9k();
1000 : 0 : struct dev *dev = &nix->dev;
1001 : : struct mbox *mbox;
1002 : : int rc;
1003 : :
1004 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL)
1005 : : return NIX_ERR_PARAM;
1006 : :
1007 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues)
1008 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1009 : :
1010 : : /* Clear attributes for existing aura's */
1011 : 0 : nix_rq_aura_buf_type_update(rq, false);
1012 : :
1013 : 0 : rq->roc_nix = roc_nix;
1014 : 0 : rq->tc = ROC_NIX_PFC_CLASS_INVALID;
1015 : :
1016 : : mbox = mbox_get(m_box);
1017 [ # # ]: 0 : if (is_cn9k)
1018 : 0 : rc = nix_rq_cn9k_cfg(dev, rq, nix->qints, true, ena);
1019 [ # # ]: 0 : else if (roc_model_is_cn10k())
1020 : 0 : rc = nix_rq_cn10k_cfg(dev, rq, nix->qints, true, ena);
1021 : : else
1022 : 0 : rc = nix_rq_cfg(dev, rq, nix->qints, true, ena);
1023 : :
1024 [ # # ]: 0 : if (rc) {
1025 : : mbox_put(mbox);
1026 : 0 : return rc;
1027 : : }
1028 : :
1029 : 0 : rc = mbox_process(mbox);
1030 [ # # ]: 0 : if (rc) {
1031 : : mbox_put(mbox);
1032 : 0 : return rc;
1033 : : }
1034 : : mbox_put(mbox);
1035 : :
1036 : : /* Update aura attribute to indicate its use */
1037 : 0 : nix_rq_aura_buf_type_update(rq, true);
1038 : :
1039 : : /* Check for meta aura if RQ is enabled */
1040 [ # # # # ]: 0 : if (ena && nix->need_meta_aura) {
1041 : 0 : rc = roc_nix_inl_meta_aura_check(roc_nix, rq);
1042 [ # # ]: 0 : if (rc)
1043 : : return rc;
1044 : : }
1045 : :
1046 : 0 : return nix_tel_node_add_rq(rq);
1047 : : }
1048 : :
1049 : : int
1050 [ # # ]: 0 : roc_nix_rq_cman_config(struct roc_nix *roc_nix, struct roc_nix_rq *rq)
1051 : : {
1052 : : bool is_cn9k = roc_model_is_cn9k();
1053 : : struct nix *nix;
1054 : : struct dev *dev;
1055 : : int rc;
1056 : :
1057 [ # # ]: 0 : if (roc_nix == NULL || rq == NULL)
1058 : : return NIX_ERR_PARAM;
1059 : :
1060 : : nix = roc_nix_to_nix_priv(roc_nix);
1061 : :
1062 [ # # ]: 0 : if (rq->qid >= nix->nb_rx_queues)
1063 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1064 : :
1065 : 0 : dev = &nix->dev;
1066 : :
1067 [ # # ]: 0 : if (is_cn9k)
1068 : 0 : rc = nix_rq_cn9k_cman_cfg(dev, rq);
1069 [ # # ]: 0 : else if (roc_model_is_cn10k())
1070 : 0 : rc = nix_rq_cn10k_cman_cfg(dev, rq);
1071 : : else
1072 : 0 : rc = nix_rq_cman_cfg(dev, rq);
1073 : :
1074 : : return rc;
1075 : : }
1076 : :
1077 : : int
1078 : 0 : roc_nix_rq_fini(struct roc_nix_rq *rq)
1079 : : {
1080 : 0 : struct nix *nix = roc_nix_to_nix_priv(rq->roc_nix);
1081 : : int rc;
1082 : :
1083 : : /* Disabling RQ is sufficient */
1084 : 0 : rc = roc_nix_rq_ena_dis(rq, false);
1085 [ # # ]: 0 : if (rc)
1086 : : return rc;
1087 : :
1088 : : /* Update aura attribute to indicate its use for */
1089 : 0 : nix_rq_aura_buf_type_update(rq, false);
1090 : :
1091 : 0 : nix->rqs[rq->qid] = NULL;
1092 : 0 : return 0;
1093 : : }
1094 : :
1095 : : static inline int
1096 : 0 : roc_nix_cn20k_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq)
1097 : : {
1098 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1099 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1100 : : volatile struct nix_cn20k_cq_ctx_s *cq_ctx;
1101 : : uint16_t drop_thresh = NIX_CQ_THRESH_LEVEL;
1102 : 0 : uint16_t cpt_lbpid = nix->cpt_lbpid;
1103 : : struct nix_cn20k_aq_enq_req *aq;
1104 : : enum nix_q_size qsize;
1105 : : size_t desc_sz;
1106 : : int rc;
1107 : :
1108 [ # # ]: 0 : if (cq == NULL)
1109 : : return NIX_ERR_PARAM;
1110 : :
1111 : 0 : qsize = nix_qsize_clampup(cq->nb_desc);
1112 : 0 : cq->nb_desc = nix_qsize_to_val(qsize);
1113 : 0 : cq->qmask = cq->nb_desc - 1;
1114 : 0 : cq->door = nix->base + NIX_LF_CQ_OP_DOOR;
1115 : 0 : cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
1116 : 0 : cq->wdata = (uint64_t)cq->qid << 32;
1117 : 0 : cq->roc_nix = roc_nix;
1118 : :
1119 : : /* CQE of W16 */
1120 : 0 : desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ;
1121 : 0 : cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN);
1122 [ # # ]: 0 : if (cq->desc_base == NULL) {
1123 : : rc = NIX_ERR_NO_MEM;
1124 : 0 : goto fail;
1125 : : }
1126 : :
1127 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox_get(mbox));
1128 [ # # ]: 0 : if (!aq) {
1129 : : mbox_put(mbox);
1130 : 0 : return -ENOSPC;
1131 : : }
1132 : :
1133 : 0 : aq->qidx = cq->qid;
1134 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1135 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1136 : : cq_ctx = &aq->cq;
1137 : :
1138 : 0 : cq_ctx->ena = 1;
1139 : 0 : cq_ctx->caching = 1;
1140 : 0 : cq_ctx->qsize = qsize;
1141 : 0 : cq_ctx->base = (uint64_t)cq->desc_base;
1142 : 0 : cq_ctx->avg_level = 0xff;
1143 : 0 : cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
1144 [ # # ]: 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
1145 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(roc_nix)) {
1146 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_CPT_DROP);
1147 : 0 : cq_ctx->cpt_drop_err_en = 1;
1148 : : /* Enable Late BP only when non zero CPT BPID */
1149 [ # # ]: 0 : if (cpt_lbpid) {
1150 : 0 : cq_ctx->lbp_ena = 1;
1151 : 0 : cq_ctx->lbpid_low = cpt_lbpid & 0x7;
1152 : 0 : cq_ctx->lbpid_med = (cpt_lbpid >> 3) & 0x7;
1153 : 0 : cq_ctx->lbpid_high = (cpt_lbpid >> 6) & 0x7;
1154 : 0 : cq_ctx->lbp_frac = NIX_CQ_LBP_THRESH_FRAC;
1155 : : }
1156 : : drop_thresh = NIX_CQ_SEC_BP_THRESH_LEVEL;
1157 : : }
1158 : :
1159 : : /* Many to one reduction */
1160 : 0 : cq_ctx->qint_idx = cq->qid % nix->qints;
1161 : : /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
1162 [ # # ]: 0 : cq_ctx->cint_idx = cq->qid;
1163 : :
1164 [ # # ]: 0 : if (roc_errata_nix_has_cq_min_size_4k()) {
1165 : : const float rx_cq_skid = NIX_CQ_FULL_ERRATA_SKID;
1166 : : uint16_t min_rx_drop;
1167 : :
1168 : 0 : min_rx_drop = ceil(rx_cq_skid / (float)cq->nb_desc);
1169 : 0 : cq_ctx->drop = min_rx_drop;
1170 : 0 : cq_ctx->drop_ena = 1;
1171 : 0 : cq->drop_thresh = min_rx_drop;
1172 : : } else {
1173 : 0 : cq->drop_thresh = drop_thresh;
1174 : : /* Drop processing or red drop cannot be enabled due to
1175 : : * due to packets coming for second pass from CPT.
1176 : : */
1177 [ # # ]: 0 : if (!roc_nix_inl_inb_is_enabled(roc_nix)) {
1178 : 0 : cq_ctx->drop = cq->drop_thresh;
1179 : 0 : cq_ctx->drop_ena = 1;
1180 : : }
1181 : : }
1182 : 0 : cq->bp_thresh = cq->drop_thresh;
1183 [ # # ]: 0 : cq_ctx->bp = cq->drop_thresh;
1184 : :
1185 [ # # ]: 0 : if (roc_feature_nix_has_cqe_stash()) {
1186 [ # # ]: 0 : if (cq_ctx->caching) {
1187 : 0 : cq_ctx->stashing = 1;
1188 : 0 : cq_ctx->stash_thresh = cq->stash_thresh;
1189 : : }
1190 : : }
1191 : :
1192 : 0 : rc = mbox_process(mbox);
1193 : : mbox_put(mbox);
1194 [ # # ]: 0 : if (rc)
1195 : 0 : goto free_mem;
1196 : :
1197 : 0 : return nix_tel_node_add_cq(cq);
1198 : :
1199 : : free_mem:
1200 : 0 : plt_free(cq->desc_base);
1201 : : fail:
1202 : : return rc;
1203 : : }
1204 : :
1205 : : int
1206 : 0 : roc_nix_cq_init(struct roc_nix *roc_nix, struct roc_nix_cq *cq)
1207 : : {
1208 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1209 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1210 : : volatile struct nix_cq_ctx_s *cq_ctx = NULL;
1211 : 0 : uint16_t cpt_lbpid = nix->cpt_lbpid;
1212 : : enum nix_q_size qsize;
1213 : : bool force_tail_drop;
1214 : : uint16_t drop_thresh;
1215 : : uint16_t bp_thresh;
1216 : : size_t desc_sz;
1217 : : int rc;
1218 : :
1219 [ # # ]: 0 : if (cq == NULL)
1220 : : return NIX_ERR_PARAM;
1221 : :
1222 [ # # ]: 0 : if (roc_model_is_cn20k())
1223 : 0 : return roc_nix_cn20k_cq_init(roc_nix, cq);
1224 : :
1225 : 0 : qsize = nix_qsize_clampup(cq->nb_desc);
1226 : 0 : cq->nb_desc = nix_qsize_to_val(qsize);
1227 : 0 : cq->qmask = cq->nb_desc - 1;
1228 : 0 : cq->door = nix->base + NIX_LF_CQ_OP_DOOR;
1229 : 0 : cq->status = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
1230 : 0 : cq->wdata = (uint64_t)cq->qid << 32;
1231 : 0 : cq->roc_nix = roc_nix;
1232 : :
1233 : : /* CQE of W16 */
1234 : 0 : desc_sz = cq->nb_desc * NIX_CQ_ENTRY_SZ;
1235 : 0 : cq->desc_base = plt_zmalloc(desc_sz, NIX_CQ_ALIGN);
1236 [ # # ]: 0 : if (cq->desc_base == NULL) {
1237 : : rc = NIX_ERR_NO_MEM;
1238 : 0 : goto fail;
1239 : : }
1240 : :
1241 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1242 : : struct nix_aq_enq_req *aq;
1243 : :
1244 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox_get(mbox));
1245 [ # # ]: 0 : if (!aq) {
1246 : : mbox_put(mbox);
1247 : 0 : return -ENOSPC;
1248 : : }
1249 : :
1250 : 0 : aq->qidx = cq->qid;
1251 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1252 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1253 : 0 : cq_ctx = &aq->cq;
1254 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
1255 : : struct nix_cn10k_aq_enq_req *aq;
1256 : :
1257 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox_get(mbox));
1258 [ # # ]: 0 : if (!aq) {
1259 : : mbox_put(mbox);
1260 : 0 : return -ENOSPC;
1261 : : }
1262 : :
1263 : 0 : aq->qidx = cq->qid;
1264 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1265 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1266 : 0 : cq_ctx = &aq->cq;
1267 : : }
1268 : :
1269 : 0 : force_tail_drop = roc_nix->force_tail_drop;
1270 : :
1271 : 0 : cq_ctx->ena = 1;
1272 : 0 : cq_ctx->caching = 1;
1273 : 0 : cq_ctx->qsize = qsize;
1274 : 0 : cq_ctx->base = (uint64_t)cq->desc_base;
1275 : 0 : cq_ctx->avg_level = 0xff;
1276 : 0 : cq_ctx->cq_err_int_ena = BIT(NIX_CQERRINT_CQE_FAULT);
1277 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_DOOR_ERR);
1278 [ # # ]: 0 : drop_thresh = force_tail_drop ? NIX_CQ_THRESH_LEVEL_REF1 : NIX_CQ_THRESH_LEVEL;
1279 [ # # ]: 0 : bp_thresh = force_tail_drop ? NIX_CQ_BP_THRESH_LEVEL_REF1 : drop_thresh;
1280 : :
1281 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(roc_nix)) {
1282 : 0 : cq_ctx->cq_err_int_ena |= BIT(NIX_CQERRINT_CPT_DROP);
1283 : 0 : cq_ctx->cpt_drop_err_en = 1;
1284 : : /* Enable Late BP only when non zero CPT BPID */
1285 [ # # ]: 0 : if (cpt_lbpid) {
1286 : 0 : cq_ctx->lbp_ena = 1;
1287 : 0 : cq_ctx->lbpid_low = cpt_lbpid & 0x7;
1288 : 0 : cq_ctx->lbpid_med = (cpt_lbpid >> 3) & 0x7;
1289 : 0 : cq_ctx->lbpid_high = (cpt_lbpid >> 6) & 0x7;
1290 : 0 : cq_ctx->lbp_frac = force_tail_drop ? NIX_CQ_LBP_THRESH_FRAC_REF1 :
1291 : : NIX_CQ_LBP_THRESH_FRAC;
1292 : : }
1293 : :
1294 : : /* CQ drop is disabled by default when inline device in use and
1295 : : * force_tail_drop disabled, so will not configure drop threshold.
1296 : : */
1297 [ # # ]: 0 : drop_thresh = force_tail_drop ? NIX_CQ_SEC_THRESH_LEVEL_REF1 : 0;
1298 [ # # ]: 0 : bp_thresh = force_tail_drop ? NIX_CQ_SEC_BP_THRESH_LEVEL_REF1 :
1299 : : NIX_CQ_SEC_BP_THRESH_LEVEL;
1300 : : }
1301 : :
1302 : : /* Many to one reduction */
1303 : 0 : cq_ctx->qint_idx = cq->qid % nix->qints;
1304 : : /* Map CQ0 [RQ0] to CINT0 and so on till max 64 irqs */
1305 [ # # ]: 0 : cq_ctx->cint_idx = cq->qid;
1306 : :
1307 [ # # ]: 0 : if (roc_errata_nix_has_cq_min_size_4k()) {
1308 : : const float rx_cq_skid = NIX_CQ_FULL_ERRATA_SKID;
1309 : : uint16_t min_rx_drop;
1310 : :
1311 : 0 : min_rx_drop = ceil(rx_cq_skid / (float)cq->nb_desc);
1312 : 0 : cq_ctx->drop = min_rx_drop;
1313 : 0 : cq_ctx->drop_ena = 1;
1314 : 0 : cq->drop_thresh = min_rx_drop;
1315 : : bp_thresh = min_rx_drop;
1316 : 0 : cq->bp_thresh = bp_thresh;
1317 : : } else {
1318 : 0 : cq->drop_thresh = drop_thresh;
1319 : 0 : cq->bp_thresh = bp_thresh;
1320 : : /* Drop processing or red drop cannot be enabled due to
1321 : : * due to packets coming for second pass from CPT.
1322 : : */
1323 [ # # # # ]: 0 : if (!roc_nix_inl_inb_is_enabled(roc_nix) || force_tail_drop) {
1324 : 0 : cq_ctx->drop = cq->drop_thresh;
1325 : 0 : cq_ctx->drop_ena = 1;
1326 : : }
1327 : : }
1328 [ # # ]: 0 : cq_ctx->bp = bp_thresh;
1329 : :
1330 [ # # ]: 0 : if (roc_feature_nix_has_cqe_stash()) {
1331 [ # # ]: 0 : if (cq_ctx->caching) {
1332 : 0 : cq_ctx->stashing = 1;
1333 : 0 : cq_ctx->stash_thresh = cq->stash_thresh;
1334 : : }
1335 : : }
1336 : :
1337 : 0 : rc = mbox_process(mbox);
1338 : : mbox_put(mbox);
1339 [ # # ]: 0 : if (rc)
1340 : 0 : goto free_mem;
1341 : :
1342 : 0 : return nix_tel_node_add_cq(cq);
1343 : :
1344 : : free_mem:
1345 : 0 : plt_free(cq->desc_base);
1346 : : fail:
1347 : : return rc;
1348 : : }
1349 : :
1350 : : int
1351 : 0 : roc_nix_cq_fini(struct roc_nix_cq *cq)
1352 : : {
1353 : : struct mbox *mbox;
1354 : : struct nix *nix;
1355 : : int rc;
1356 : :
1357 [ # # ]: 0 : if (cq == NULL)
1358 : : return NIX_ERR_PARAM;
1359 : :
1360 : 0 : nix = roc_nix_to_nix_priv(cq->roc_nix);
1361 : 0 : mbox = mbox_get((&nix->dev)->mbox);
1362 : :
1363 : : /* Disable CQ */
1364 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1365 : : struct nix_aq_enq_req *aq;
1366 : :
1367 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1368 [ # # ]: 0 : if (!aq) {
1369 : : mbox_put(mbox);
1370 : 0 : return -ENOSPC;
1371 : : }
1372 : :
1373 : 0 : aq->qidx = cq->qid;
1374 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1375 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1376 : 0 : aq->cq.ena = 0;
1377 : 0 : aq->cq.bp_ena = 0;
1378 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1379 : 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1380 [ # # ]: 0 : } else if (roc_model_is_cn10k()) {
1381 : : struct nix_cn10k_aq_enq_req *aq;
1382 : :
1383 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1384 [ # # ]: 0 : if (!aq) {
1385 : : mbox_put(mbox);
1386 : 0 : return -ENOSPC;
1387 : : }
1388 : :
1389 : 0 : aq->qidx = cq->qid;
1390 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1391 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1392 : 0 : aq->cq.ena = 0;
1393 : 0 : aq->cq.bp_ena = 0;
1394 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1395 [ # # ]: 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1396 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(cq->roc_nix)) {
1397 : 0 : aq->cq.lbp_ena = 0;
1398 : 0 : aq->cq_mask.lbp_ena = ~aq->cq_mask.lbp_ena;
1399 : : }
1400 : : } else {
1401 : : struct nix_cn20k_aq_enq_req *aq;
1402 : :
1403 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1404 [ # # ]: 0 : if (!aq) {
1405 : : mbox_put(mbox);
1406 : 0 : return -ENOSPC;
1407 : : }
1408 : :
1409 : 0 : aq->qidx = cq->qid;
1410 : 0 : aq->ctype = NIX_AQ_CTYPE_CQ;
1411 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1412 : 0 : aq->cq.ena = 0;
1413 : 0 : aq->cq.bp_ena = 0;
1414 : 0 : aq->cq_mask.ena = ~aq->cq_mask.ena;
1415 [ # # ]: 0 : aq->cq_mask.bp_ena = ~aq->cq_mask.bp_ena;
1416 [ # # # # ]: 0 : if (roc_feature_nix_has_late_bp() && roc_nix_inl_inb_is_enabled(cq->roc_nix)) {
1417 : 0 : aq->cq.lbp_ena = 0;
1418 : 0 : aq->cq_mask.lbp_ena = ~aq->cq_mask.lbp_ena;
1419 : : }
1420 : : }
1421 : :
1422 : 0 : rc = mbox_process(mbox);
1423 [ # # ]: 0 : if (rc) {
1424 : : mbox_put(mbox);
1425 : 0 : return rc;
1426 : : }
1427 : :
1428 : : mbox_put(mbox);
1429 : 0 : plt_free(cq->desc_base);
1430 : 0 : return 0;
1431 : : }
1432 : :
1433 : : static int
1434 : 0 : sqb_pool_populate(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1435 : : {
1436 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1437 : : uint16_t sqes_per_sqb, count, nb_sqb_bufs, thr;
1438 : : struct npa_pool_s pool;
1439 : : struct npa_aura_s aura;
1440 : : uint64_t blk_sz;
1441 : : uint64_t iova;
1442 : : int rc;
1443 : :
1444 : 0 : blk_sz = nix->sqb_size;
1445 [ # # ]: 0 : if (sq->max_sqe_sz == roc_nix_maxsqesz_w16)
1446 : 0 : sqes_per_sqb = (blk_sz / 8) / 16;
1447 : : else
1448 : 0 : sqes_per_sqb = (blk_sz / 8) / 8;
1449 : :
1450 : : /* Reserve One SQE in each SQB to hold pointer for next SQB */
1451 : 0 : sqes_per_sqb -= 1;
1452 : :
1453 : 0 : sq->nb_desc = PLT_MAX(512U, sq->nb_desc);
1454 : 0 : nb_sqb_bufs = PLT_DIV_CEIL(sq->nb_desc, sqes_per_sqb);
1455 : 0 : thr = PLT_DIV_CEIL((nb_sqb_bufs * ROC_NIX_SQB_THRESH), 100);
1456 : 0 : nb_sqb_bufs += NIX_SQB_PREFETCH;
1457 : : /* Clamp up the SQB count */
1458 : 0 : nb_sqb_bufs = PLT_MAX(NIX_DEF_SQB, nb_sqb_bufs);
1459 : 0 : nb_sqb_bufs = PLT_MIN(roc_nix->max_sqb_count, (uint16_t)nb_sqb_bufs);
1460 : :
1461 [ # # ]: 0 : sq->nb_sqb_bufs = nb_sqb_bufs;
1462 : 0 : sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb);
1463 : 0 : sq->nb_sqb_bufs_adj = nb_sqb_bufs;
1464 : :
1465 [ # # ]: 0 : if (roc_nix->sqb_slack)
1466 : 0 : nb_sqb_bufs += roc_nix->sqb_slack;
1467 : : else
1468 : 0 : nb_sqb_bufs += PLT_MAX((int)thr, (int)ROC_NIX_SQB_SLACK_DFLT);
1469 : : /* Explicitly set nat_align alone as by default pool is with both
1470 : : * nat_align and buf_offset = 1 which we don't want for SQB.
1471 : : */
1472 : : memset(&pool, 0, sizeof(struct npa_pool_s));
1473 : 0 : pool.nat_align = 1;
1474 : :
1475 : : memset(&aura, 0, sizeof(aura));
1476 [ # # ]: 0 : aura.fc_ena = 1;
1477 [ # # # # ]: 0 : if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp())
1478 : : aura.fc_stype = 0x0; /* STF */
1479 : : else
1480 : 0 : aura.fc_stype = 0x3; /* STSTP */
1481 : 0 : aura.fc_addr = (uint64_t)sq->fc;
1482 : 0 : aura.fc_hyst_bits = sq->fc_hyst_bits & 0xF;
1483 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, nb_sqb_bufs, &aura, &pool, 0);
1484 [ # # ]: 0 : if (rc)
1485 : 0 : goto fail;
1486 : :
1487 : 0 : roc_npa_buf_type_update(sq->aura_handle, ROC_NPA_BUF_TYPE_SQB, 1);
1488 : 0 : sq->sqe_mem = plt_zmalloc(blk_sz * nb_sqb_bufs, blk_sz);
1489 [ # # ]: 0 : if (sq->sqe_mem == NULL) {
1490 : : rc = NIX_ERR_NO_MEM;
1491 : 0 : goto nomem;
1492 : : }
1493 : :
1494 : : /* Fill the initial buffers */
1495 : 0 : iova = (uint64_t)sq->sqe_mem;
1496 [ # # ]: 0 : for (count = 0; count < nb_sqb_bufs; count++) {
1497 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, iova);
1498 : 0 : iova += blk_sz;
1499 : : }
1500 : :
1501 [ # # ]: 0 : if (roc_npa_aura_op_available_wait(sq->aura_handle, nb_sqb_bufs, 0) !=
1502 : : nb_sqb_bufs) {
1503 : 0 : plt_err("Failed to free all pointers to the pool");
1504 : : rc = NIX_ERR_NO_MEM;
1505 : 0 : goto npa_fail;
1506 : : }
1507 : :
1508 : 0 : roc_npa_pool_op_range_set(sq->aura_handle, (uint64_t)sq->sqe_mem, iova);
1509 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
1510 : 0 : sq->aura_sqb_bufs = nb_sqb_bufs;
1511 : :
1512 : 0 : return rc;
1513 : : npa_fail:
1514 : 0 : plt_free(sq->sqe_mem);
1515 : 0 : nomem:
1516 : 0 : roc_npa_pool_destroy(sq->aura_handle);
1517 : : fail:
1518 : : return rc;
1519 : : }
1520 : :
1521 : : static int
1522 : 0 : sq_cn9k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum,
1523 : : uint16_t smq)
1524 : : {
1525 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1526 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1527 : : struct nix_aq_enq_req *aq;
1528 : :
1529 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1530 [ # # ]: 0 : if (!aq)
1531 : : return -ENOSPC;
1532 : :
1533 : 0 : aq->qidx = sq->qid;
1534 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1535 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1536 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1537 : :
1538 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1539 : 0 : aq->sq.smq = smq;
1540 : 0 : aq->sq.smq_rr_quantum = rr_quantum;
1541 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1542 : 0 : aq->sq.default_chan =
1543 : 0 : nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1544 : : else
1545 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1546 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1547 : 0 : aq->sq.ena = 1;
1548 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1549 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1550 : 0 : aq->sq.cq = sq->cqid;
1551 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1552 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1553 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1554 : 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1555 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1556 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1557 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1558 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1559 : :
1560 : : /* Many to one reduction */
1561 : 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1562 : :
1563 : 0 : return 0;
1564 : : }
1565 : :
1566 : : static int
1567 : 0 : sq_cn9k_fini(struct nix *nix, struct roc_nix_sq *sq)
1568 : : {
1569 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1570 : : struct nix_aq_enq_rsp *rsp;
1571 : : struct nix_aq_enq_req *aq;
1572 : : uint16_t sqes_per_sqb;
1573 : : void *sqb_buf;
1574 : : int rc, count;
1575 : :
1576 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1577 [ # # ]: 0 : if (!aq) {
1578 : : mbox_put(mbox);
1579 : 0 : return -ENOSPC;
1580 : : }
1581 : :
1582 : 0 : aq->qidx = sq->qid;
1583 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1584 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1585 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1586 [ # # ]: 0 : if (rc) {
1587 : : mbox_put(mbox);
1588 : 0 : return rc;
1589 : : }
1590 : :
1591 : : /* Check if sq is already cleaned up */
1592 [ # # ]: 0 : if (!rsp->sq.ena) {
1593 : : mbox_put(mbox);
1594 : 0 : return 0;
1595 : : }
1596 : :
1597 : : /* Disable sq */
1598 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1599 [ # # ]: 0 : if (!aq) {
1600 : : mbox_put(mbox);
1601 : 0 : return -ENOSPC;
1602 : : }
1603 : :
1604 : 0 : aq->qidx = sq->qid;
1605 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1606 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1607 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1608 : 0 : aq->sq.ena = 0;
1609 : 0 : rc = mbox_process(mbox);
1610 [ # # ]: 0 : if (rc) {
1611 : : mbox_put(mbox);
1612 : 0 : return rc;
1613 : : }
1614 : :
1615 : : /* Read SQ and free sqb's */
1616 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1617 [ # # ]: 0 : if (!aq) {
1618 : : mbox_put(mbox);
1619 : 0 : return -ENOSPC;
1620 : : }
1621 : :
1622 : 0 : aq->qidx = sq->qid;
1623 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1624 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1625 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1626 [ # # ]: 0 : if (rc) {
1627 : : mbox_put(mbox);
1628 : 0 : return rc;
1629 : : }
1630 : :
1631 [ # # ]: 0 : if (aq->sq.smq_pend)
1632 : 0 : plt_err("SQ has pending SQE's");
1633 : :
1634 : 0 : count = aq->sq.sqb_count;
1635 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1636 : : /* Free SQB's that are used */
1637 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1638 [ # # ]: 0 : while (count) {
1639 : : void *next_sqb;
1640 : :
1641 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1642 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1643 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1644 : : sqb_buf = next_sqb;
1645 : 0 : count--;
1646 : : }
1647 : :
1648 : : /* Free next to use sqb */
1649 [ # # ]: 0 : if (rsp->sq.next_sqb)
1650 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1651 : : mbox_put(mbox);
1652 : 0 : return 0;
1653 : : }
1654 : :
1655 : : static int
1656 : 0 : sq_cn10k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1657 : : {
1658 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1659 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1660 : : struct nix_cn10k_aq_enq_req *aq;
1661 : :
1662 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1663 [ # # ]: 0 : if (!aq)
1664 : : return -ENOSPC;
1665 : :
1666 : 0 : aq->qidx = sq->qid;
1667 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1668 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1669 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1670 : :
1671 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1672 : 0 : aq->sq.smq = smq;
1673 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1674 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1675 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1676 : : else
1677 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1678 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1679 : 0 : aq->sq.ena = 1;
1680 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1681 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1682 : 0 : aq->sq.cq = sq->cqid;
1683 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1684 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1685 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1686 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1687 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1688 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1689 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1690 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1691 : :
1692 : : /* Many to one reduction */
1693 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1694 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1695 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1696 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1697 : : * might result in software missing the interrupt.
1698 : : */
1699 : 0 : aq->sq.qint_idx = 0;
1700 : : }
1701 : : return 0;
1702 : : }
1703 : :
1704 : : static int
1705 : 0 : sq_cn10k_fini(struct nix *nix, struct roc_nix_sq *sq)
1706 : : {
1707 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1708 : : struct nix_cn10k_aq_enq_rsp *rsp;
1709 : : struct nix_cn10k_aq_enq_req *aq;
1710 : : uint16_t sqes_per_sqb;
1711 : : void *sqb_buf;
1712 : : int rc, count;
1713 : :
1714 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1715 [ # # ]: 0 : if (!aq) {
1716 : : mbox_put(mbox);
1717 : 0 : return -ENOSPC;
1718 : : }
1719 : :
1720 : 0 : aq->qidx = sq->qid;
1721 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1722 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1723 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1724 [ # # ]: 0 : if (rc) {
1725 : : mbox_put(mbox);
1726 : 0 : return rc;
1727 : : }
1728 : :
1729 : : /* Check if sq is already cleaned up */
1730 [ # # ]: 0 : if (!rsp->sq.ena) {
1731 : : mbox_put(mbox);
1732 : 0 : return 0;
1733 : : }
1734 : :
1735 : : /* Disable sq */
1736 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1737 [ # # ]: 0 : if (!aq) {
1738 : : mbox_put(mbox);
1739 : 0 : return -ENOSPC;
1740 : : }
1741 : :
1742 : 0 : aq->qidx = sq->qid;
1743 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1744 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1745 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1746 : 0 : aq->sq.ena = 0;
1747 : 0 : rc = mbox_process(mbox);
1748 [ # # ]: 0 : if (rc) {
1749 : : mbox_put(mbox);
1750 : 0 : return rc;
1751 : : }
1752 : :
1753 : : /* Read SQ and free sqb's */
1754 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1755 [ # # ]: 0 : if (!aq) {
1756 : : mbox_put(mbox);
1757 : 0 : return -ENOSPC;
1758 : : }
1759 : :
1760 : 0 : aq->qidx = sq->qid;
1761 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1762 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1763 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1764 [ # # ]: 0 : if (rc) {
1765 : : mbox_put(mbox);
1766 : 0 : return rc;
1767 : : }
1768 : :
1769 [ # # ]: 0 : if (aq->sq.smq_pend)
1770 : 0 : plt_err("SQ has pending SQE's");
1771 : :
1772 : 0 : count = aq->sq.sqb_count;
1773 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1774 : : /* Free SQB's that are used */
1775 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1776 [ # # ]: 0 : while (count) {
1777 : : void *next_sqb;
1778 : :
1779 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1780 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1781 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1782 : : sqb_buf = next_sqb;
1783 : 0 : count--;
1784 : : }
1785 : :
1786 : : /* Free next to use sqb */
1787 [ # # ]: 0 : if (rsp->sq.next_sqb)
1788 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1789 : : mbox_put(mbox);
1790 : 0 : return 0;
1791 : : }
1792 : :
1793 : : static int
1794 : 0 : sq_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1795 : : {
1796 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1797 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1798 : : struct nix_cn20k_aq_enq_req *aq;
1799 : :
1800 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1801 [ # # ]: 0 : if (!aq)
1802 : : return -ENOSPC;
1803 : :
1804 : 0 : aq->qidx = sq->qid;
1805 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1806 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1807 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1808 : :
1809 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1810 : 0 : aq->sq.smq = smq;
1811 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1812 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1813 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1814 : : else
1815 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1816 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1817 : 0 : aq->sq.ena = 1;
1818 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1819 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1820 : 0 : aq->sq.cq = sq->cqid;
1821 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1822 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1823 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1824 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1825 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1826 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1827 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1828 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1829 : :
1830 : : /* Many to one reduction */
1831 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1832 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1833 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1834 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1835 : : * might result in software missing the interrupt.
1836 : : */
1837 : 0 : aq->sq.qint_idx = 0;
1838 : : }
1839 : : return 0;
1840 : : }
1841 : :
1842 : : static int
1843 : 0 : sq_fini(struct nix *nix, struct roc_nix_sq *sq)
1844 : : {
1845 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1846 : : struct nix_cn20k_aq_enq_rsp *rsp;
1847 : : struct nix_cn20k_aq_enq_req *aq;
1848 : : uint16_t sqes_per_sqb;
1849 : : void *sqb_buf;
1850 : : int rc, count;
1851 : :
1852 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1853 [ # # ]: 0 : if (!aq) {
1854 : : mbox_put(mbox);
1855 : 0 : return -ENOSPC;
1856 : : }
1857 : :
1858 : 0 : aq->qidx = sq->qid;
1859 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1860 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1861 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1862 [ # # ]: 0 : if (rc) {
1863 : : mbox_put(mbox);
1864 : 0 : return rc;
1865 : : }
1866 : :
1867 : : /* Check if sq is already cleaned up */
1868 [ # # ]: 0 : if (!rsp->sq.ena) {
1869 : : mbox_put(mbox);
1870 : 0 : return 0;
1871 : : }
1872 : :
1873 : : /* Disable sq */
1874 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1875 [ # # ]: 0 : if (!aq) {
1876 : : mbox_put(mbox);
1877 : 0 : return -ENOSPC;
1878 : : }
1879 : :
1880 : 0 : aq->qidx = sq->qid;
1881 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1882 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1883 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1884 : 0 : aq->sq.ena = 0;
1885 : 0 : rc = mbox_process(mbox);
1886 [ # # ]: 0 : if (rc) {
1887 : : mbox_put(mbox);
1888 : 0 : return rc;
1889 : : }
1890 : :
1891 : : /* Read SQ and free sqb's */
1892 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1893 [ # # ]: 0 : if (!aq) {
1894 : : mbox_put(mbox);
1895 : 0 : return -ENOSPC;
1896 : : }
1897 : :
1898 : 0 : aq->qidx = sq->qid;
1899 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1900 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1901 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1902 [ # # ]: 0 : if (rc) {
1903 : : mbox_put(mbox);
1904 : 0 : return rc;
1905 : : }
1906 : :
1907 [ # # ]: 0 : if (aq->sq.smq_pend)
1908 : 0 : plt_err("SQ has pending SQE's");
1909 : :
1910 : 0 : count = aq->sq.sqb_count;
1911 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1912 : : /* Free SQB's that are used */
1913 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1914 [ # # ]: 0 : while (count) {
1915 : : void *next_sqb;
1916 : :
1917 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1918 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1919 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1920 : : sqb_buf = next_sqb;
1921 : 0 : count--;
1922 : : }
1923 : :
1924 : : /* Free next to use sqb */
1925 [ # # ]: 0 : if (rsp->sq.next_sqb)
1926 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1927 : : mbox_put(mbox);
1928 : 0 : return 0;
1929 : : }
1930 : :
1931 : : int
1932 [ # # ]: 0 : roc_nix_sq_init(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1933 : : {
1934 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1935 : 0 : struct mbox *m_box = (&nix->dev)->mbox;
1936 : 0 : uint16_t qid, smq = UINT16_MAX;
1937 : 0 : uint32_t rr_quantum = 0;
1938 : : struct mbox *mbox;
1939 : : int rc;
1940 : :
1941 [ # # ]: 0 : if (sq == NULL)
1942 : : return NIX_ERR_PARAM;
1943 : :
1944 : 0 : qid = sq->qid;
1945 [ # # ]: 0 : if (qid >= nix->nb_tx_queues)
1946 : : return NIX_ERR_QUEUE_INVALID_RANGE;
1947 : :
1948 : 0 : sq->roc_nix = roc_nix;
1949 : 0 : sq->tc = ROC_NIX_PFC_CLASS_INVALID;
1950 : : /*
1951 : : * Allocate memory for flow control updates from HW.
1952 : : * Alloc one cache line, so that fits all FC_STYPE modes.
1953 : : */
1954 : 0 : sq->fc = plt_zmalloc(ROC_ALIGN, ROC_ALIGN);
1955 [ # # ]: 0 : if (sq->fc == NULL) {
1956 : : rc = NIX_ERR_NO_MEM;
1957 : 0 : goto fail;
1958 : : }
1959 : :
1960 : 0 : rc = sqb_pool_populate(roc_nix, sq);
1961 [ # # ]: 0 : if (rc)
1962 : 0 : goto nomem;
1963 : :
1964 : 0 : rc = nix_tm_leaf_data_get(nix, sq->qid, &rr_quantum, &smq);
1965 [ # # ]: 0 : if (rc) {
1966 : : rc = NIX_ERR_TM_LEAF_NODE_GET;
1967 : 0 : goto nomem;
1968 : : }
1969 : :
1970 : : mbox = mbox_get(m_box);
1971 : : /* Init SQ context */
1972 [ # # ]: 0 : if (roc_model_is_cn9k())
1973 : 0 : rc = sq_cn9k_init(nix, sq, rr_quantum, smq);
1974 [ # # ]: 0 : else if (roc_model_is_cn10k())
1975 : 0 : rc = sq_cn10k_init(nix, sq, rr_quantum, smq);
1976 : : else
1977 : 0 : rc = sq_init(nix, sq, rr_quantum, smq);
1978 : :
1979 [ # # ]: 0 : if (rc) {
1980 : : mbox_put(mbox);
1981 : 0 : goto nomem;
1982 : : }
1983 : :
1984 : :
1985 : 0 : rc = mbox_process(mbox);
1986 [ # # ]: 0 : if (rc) {
1987 : : mbox_put(mbox);
1988 : 0 : goto nomem;
1989 : : }
1990 : : mbox_put(mbox);
1991 : :
1992 : 0 : sq->enable = true;
1993 : 0 : nix->sqs[qid] = sq;
1994 [ # # ]: 0 : sq->io_addr = nix->base + NIX_LF_OP_SENDX(0);
1995 : : /* Evenly distribute LMT slot for each sq */
1996 [ # # ]: 0 : if (roc_model_is_cn9k()) {
1997 : : /* Multiple cores/SQ's can use same LMTLINE safely in CN9K */
1998 : 0 : sq->lmt_addr = (void *)(nix->lmt_base +
1999 : 0 : ((qid & RVU_CN9K_LMT_SLOT_MASK) << 12));
2000 : : }
2001 : :
2002 : 0 : rc = nix_tel_node_add_sq(sq);
2003 : 0 : return rc;
2004 : 0 : nomem:
2005 : 0 : plt_free(sq->fc);
2006 : : fail:
2007 : : return rc;
2008 : : }
2009 : :
2010 : : int
2011 : 0 : roc_nix_sq_fini(struct roc_nix_sq *sq)
2012 : : {
2013 : : struct nix *nix;
2014 : : struct mbox *mbox;
2015 : : struct ndc_sync_op *ndc_req;
2016 : : uint16_t qid;
2017 : : int rc = 0;
2018 : :
2019 [ # # ]: 0 : if (sq == NULL)
2020 : : return NIX_ERR_PARAM;
2021 : :
2022 : 0 : nix = roc_nix_to_nix_priv(sq->roc_nix);
2023 : 0 : mbox = (&nix->dev)->mbox;
2024 : :
2025 : 0 : qid = sq->qid;
2026 : :
2027 : 0 : rc = nix_tm_sq_flush_pre(sq);
2028 : :
2029 : : /* Release SQ context */
2030 [ # # ]: 0 : if (roc_model_is_cn9k())
2031 : 0 : rc |= sq_cn9k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2032 [ # # ]: 0 : else if (roc_model_is_cn10k())
2033 : 0 : rc |= sq_cn10k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2034 : : else
2035 : 0 : rc |= sq_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2036 : :
2037 : : /* Sync NDC-NIX-TX for LF */
2038 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox_get(mbox));
2039 [ # # ]: 0 : if (ndc_req == NULL) {
2040 : : mbox_put(mbox);
2041 : 0 : return -ENOSPC;
2042 : : }
2043 : 0 : ndc_req->nix_lf_tx_sync = 1;
2044 [ # # ]: 0 : if (mbox_process(mbox))
2045 : 0 : rc |= NIX_ERR_NDC_SYNC;
2046 : : mbox_put(mbox);
2047 : :
2048 : 0 : rc |= nix_tm_sq_flush_post(sq);
2049 : :
2050 : : /* Restore limit to max SQB count that the pool was created
2051 : : * for aura drain to succeed.
2052 : : */
2053 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, NIX_MAX_SQB);
2054 : 0 : rc |= roc_npa_pool_destroy(sq->aura_handle);
2055 : 0 : plt_free(sq->fc);
2056 : 0 : plt_free(sq->sqe_mem);
2057 : 0 : nix->sqs[qid] = NULL;
2058 : :
2059 : 0 : return rc;
2060 : : }
2061 : :
2062 : : void
2063 : 0 : roc_nix_cq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2064 : : uint32_t *tail)
2065 : : {
2066 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2067 : : uint64_t reg, val;
2068 : : int64_t *addr;
2069 : :
2070 [ # # ]: 0 : if (head == NULL || tail == NULL)
2071 : : return;
2072 : :
2073 : : reg = (((uint64_t)qid) << 32);
2074 : : addr = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
2075 : : val = roc_atomic64_add_nosync(reg, addr);
2076 : : if (val &
2077 : : (BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) | BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR)))
2078 : : val = 0;
2079 : :
2080 : 0 : *tail = (uint32_t)(val & 0xFFFFF);
2081 : 0 : *head = (uint32_t)((val >> 20) & 0xFFFFF);
2082 : : }
2083 : :
2084 : : void
2085 : 0 : roc_nix_sq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2086 : : uint32_t *tail)
2087 : : {
2088 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2089 : 0 : struct roc_nix_sq *sq = nix->sqs[qid];
2090 : : uint16_t sqes_per_sqb, sqb_cnt;
2091 : : uint64_t reg, val;
2092 : : int64_t *addr;
2093 : :
2094 [ # # ]: 0 : if (head == NULL || tail == NULL)
2095 : : return;
2096 : :
2097 : : reg = (((uint64_t)qid) << 32);
2098 : : addr = (int64_t *)(nix->base + NIX_LF_SQ_OP_STATUS);
2099 : : val = roc_atomic64_add_nosync(reg, addr);
2100 : : if (val & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR)) {
2101 : : val = 0;
2102 : : return;
2103 : : }
2104 : :
2105 : : *tail = (uint32_t)((val >> 28) & 0x3F);
2106 : 0 : *head = (uint32_t)((val >> 20) & 0x3F);
2107 : : sqb_cnt = (uint16_t)(val & 0xFFFF);
2108 : :
2109 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2110 : :
2111 : : /* Update tail index as per used sqb count */
2112 : 0 : *tail += (sqes_per_sqb * (sqb_cnt - 1));
2113 : : }
2114 : :
2115 : : int
2116 : 0 : roc_nix_q_err_cb_register(struct roc_nix *roc_nix, q_err_get_t sq_err_handle)
2117 : : {
2118 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2119 : : struct dev *dev = &nix->dev;
2120 : :
2121 [ # # ]: 0 : if (sq_err_handle == NULL)
2122 : : return NIX_ERR_PARAM;
2123 : :
2124 : 0 : dev->ops->q_err_cb = (q_err_cb_t)sq_err_handle;
2125 : 0 : return 0;
2126 : : }
2127 : :
2128 : : void
2129 : 0 : roc_nix_q_err_cb_unregister(struct roc_nix *roc_nix)
2130 : : {
2131 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2132 : : struct dev *dev = &nix->dev;
2133 : :
2134 : 0 : dev->ops->q_err_cb = NULL;
2135 : 0 : }
|