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