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 = 1;
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 = 0x2; /* First cache aligned block to LLC */
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 = 1;
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 = 1;
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 = 0x2; /* First cache aligned block to LLC */
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 = 1;
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 = 1;
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 = 0x2; /* First cache aligned block to LLC */
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 : : struct npa_pool_s pool;
1490 : : struct npa_aura_s aura;
1491 : : uint64_t blk_sz;
1492 : : uint64_t iova;
1493 : : int rc;
1494 : :
1495 : 0 : blk_sz = nix->sqb_size;
1496 [ # # ]: 0 : sqes_per_sqb = sqes_per_sqb_calc(blk_sz, sq->max_sqe_sz);
1497 : :
1498 : : /* Translate desc count to SQB count */
1499 : 0 : nb_sqb_bufs = sq_desc_to_sqb(nix, sqes_per_sqb, sq->nb_desc);
1500 : :
1501 [ # # ]: 0 : sq->sqes_per_sqb = sqes_per_sqb;
1502 : 0 : sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb);
1503 : 0 : sq->nb_sqb_bufs_adj = nb_sqb_bufs;
1504 : 0 : sq->nb_sqb_bufs = nb_sqb_bufs;
1505 : :
1506 : : /* Add slack to SQB's */
1507 [ # # ]: 0 : nb_sqb_bufs = sqb_slack_adjust(nix, nb_sqb_bufs, !!sq->sq_cnt_ptr);
1508 : :
1509 : : /* Explicitly set nat_align alone as by default pool is with both
1510 : : * nat_align and buf_offset = 1 which we don't want for SQB.
1511 : : */
1512 : : memset(&pool, 0, sizeof(struct npa_pool_s));
1513 : 0 : pool.nat_align = 1;
1514 : :
1515 : : memset(&aura, 0, sizeof(aura));
1516 : : /* Disable SQ pool FC updates when SQ count updates are used */
1517 [ # # ]: 0 : if (!sq->sq_cnt_ptr)
1518 : 0 : aura.fc_ena = 1;
1519 [ # # # # ]: 0 : if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp())
1520 : : aura.fc_stype = 0x0; /* STF */
1521 : : else
1522 : 0 : aura.fc_stype = 0x3; /* STSTP */
1523 : 0 : aura.fc_addr = (uint64_t)sq->fc;
1524 : 0 : aura.fc_hyst_bits = sq->fc_hyst_bits & 0xF;
1525 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, nb_sqb_bufs, &aura, &pool, 0);
1526 [ # # ]: 0 : if (rc)
1527 : 0 : goto fail;
1528 : :
1529 : 0 : roc_npa_buf_type_update(sq->aura_handle, ROC_NPA_BUF_TYPE_SQB, 1);
1530 : 0 : sq->sqe_mem = plt_zmalloc(blk_sz * nb_sqb_bufs, blk_sz);
1531 [ # # ]: 0 : if (sq->sqe_mem == NULL) {
1532 : : rc = NIX_ERR_NO_MEM;
1533 : 0 : goto nomem;
1534 : : }
1535 : :
1536 : : /* Fill the initial buffers */
1537 : 0 : iova = (uint64_t)sq->sqe_mem;
1538 [ # # ]: 0 : for (count = 0; count < nb_sqb_bufs; count++) {
1539 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, iova);
1540 : 0 : iova += blk_sz;
1541 : : }
1542 : :
1543 [ # # ]: 0 : if (roc_npa_aura_op_available_wait(sq->aura_handle, nb_sqb_bufs, 0) !=
1544 : : nb_sqb_bufs) {
1545 : 0 : plt_err("Failed to free all pointers to the pool");
1546 : : rc = NIX_ERR_NO_MEM;
1547 : 0 : goto npa_fail;
1548 : : }
1549 : :
1550 : 0 : roc_npa_pool_op_range_set(sq->aura_handle, (uint64_t)sq->sqe_mem, iova);
1551 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
1552 : 0 : sq->aura_sqb_bufs = nb_sqb_bufs;
1553 : :
1554 : 0 : return rc;
1555 : : npa_fail:
1556 : 0 : plt_free(sq->sqe_mem);
1557 : 0 : nomem:
1558 : 0 : roc_npa_pool_destroy(sq->aura_handle);
1559 : : fail:
1560 : : return rc;
1561 : : }
1562 : :
1563 : : static int
1564 : 0 : sqb_pool_dyn_populate(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
1565 : : {
1566 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
1567 : : uint16_t count, nb_sqb_bufs;
1568 : : uint16_t max_sqb_count;
1569 : : struct npa_pool_s pool;
1570 : : struct npa_aura_s aura;
1571 : : uint16_t sqes_per_sqb;
1572 : : uint64_t blk_sz;
1573 : : uint64_t iova;
1574 : : int rc;
1575 : :
1576 : 0 : blk_sz = nix->sqb_size;
1577 [ # # ]: 0 : sqes_per_sqb = sqes_per_sqb_calc(blk_sz, sq->max_sqe_sz);
1578 : :
1579 : : /* Translate desc count to SQB count */
1580 [ # # ]: 0 : nb_sqb_bufs = sq_desc_to_sqb(nix, sqes_per_sqb, sq->nb_desc);
1581 : :
1582 : 0 : sq->sqes_per_sqb_log2 = (uint16_t)plt_log2_u32(sqes_per_sqb);
1583 : 0 : sq->sqes_per_sqb = sqes_per_sqb;
1584 : 0 : sq->nb_sqb_bufs_adj = nb_sqb_bufs;
1585 : 0 : sq->nb_sqb_bufs = nb_sqb_bufs;
1586 : :
1587 : : /* Add slack to SQB's */
1588 [ # # ]: 0 : nb_sqb_bufs = sqb_slack_adjust(nix, nb_sqb_bufs, !!sq->sq_cnt_ptr);
1589 : :
1590 : : /* Explicitly set nat_align alone as by default pool is with both
1591 : : * nat_align and buf_offset = 1 which we don't want for SQB.
1592 : : */
1593 : : memset(&pool, 0, sizeof(struct npa_pool_s));
1594 : : pool.nat_align = 0;
1595 : :
1596 : : memset(&aura, 0, sizeof(aura));
1597 [ # # ]: 0 : if (!sq->sq_cnt_ptr)
1598 : 0 : aura.fc_ena = 1;
1599 [ # # # # ]: 0 : if (roc_model_is_cn9k() || roc_errata_npa_has_no_fc_stype_ststp())
1600 : : aura.fc_stype = 0x0; /* STF */
1601 : : else
1602 : 0 : aura.fc_stype = 0x3; /* STSTP */
1603 : 0 : aura.fc_addr = (uint64_t)sq->fc;
1604 [ # # ]: 0 : aura.fc_hyst_bits = sq->fc_hyst_bits & 0xF;
1605 : : max_sqb_count = sqb_slack_adjust(nix, roc_nix->max_sqb_count, false);
1606 : 0 : rc = roc_npa_pool_create(&sq->aura_handle, blk_sz, max_sqb_count, &aura, &pool, 0);
1607 [ # # ]: 0 : if (rc)
1608 : 0 : goto fail;
1609 : :
1610 : 0 : roc_npa_buf_type_update(sq->aura_handle, ROC_NPA_BUF_TYPE_SQB, 1);
1611 [ # # ]: 0 : roc_npa_aura_op_cnt_set(sq->aura_handle, 0, nb_sqb_bufs);
1612 : :
1613 : : /* Fill the initial buffers */
1614 [ # # ]: 0 : for (count = 0; count < nb_sqb_bufs; count++) {
1615 : 0 : iova = (uint64_t)plt_zmalloc(blk_sz, ROC_ALIGN);
1616 [ # # ]: 0 : if (!iova) {
1617 : : rc = -ENOMEM;
1618 : 0 : goto nomem;
1619 : : }
1620 : 0 : plt_io_wmb();
1621 : :
1622 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, iova);
1623 : : }
1624 : :
1625 [ # # ]: 0 : if (roc_npa_aura_op_available_wait(sq->aura_handle, nb_sqb_bufs, 0) != nb_sqb_bufs) {
1626 : 0 : plt_err("Failed to free all pointers to the pool");
1627 : : rc = NIX_ERR_NO_MEM;
1628 : 0 : goto npa_fail;
1629 : : }
1630 : :
1631 : : /* Update aura count */
1632 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, nb_sqb_bufs);
1633 : 0 : roc_npa_pool_op_range_set(sq->aura_handle, 0, UINT64_MAX);
1634 : 0 : sq->aura_sqb_bufs = nb_sqb_bufs;
1635 : :
1636 : 0 : return rc;
1637 : : npa_fail:
1638 : 0 : nomem:
1639 : : while (count) {
1640 : : iova = roc_npa_aura_op_alloc(sq->aura_handle, 0);
1641 : : if (!iova)
1642 : : break;
1643 : : plt_free((uint64_t *)iova);
1644 : : count--;
1645 : : }
1646 [ # # ]: 0 : if (count)
1647 : 0 : plt_err("Failed to recover %u SQB's", count);
1648 : 0 : roc_npa_pool_destroy(sq->aura_handle);
1649 : : fail:
1650 : : return rc;
1651 : : }
1652 : :
1653 : : static int
1654 : 0 : sq_cn9k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum,
1655 : : uint16_t smq)
1656 : : {
1657 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1658 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1659 : : struct nix_aq_enq_req *aq;
1660 : :
1661 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1662 [ # # ]: 0 : if (!aq)
1663 : : return -ENOSPC;
1664 : :
1665 : 0 : aq->qidx = sq->qid;
1666 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1667 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1668 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1669 : :
1670 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1671 : 0 : aq->sq.smq = smq;
1672 : 0 : aq->sq.smq_rr_quantum = rr_quantum;
1673 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1674 : 0 : aq->sq.default_chan =
1675 : 0 : 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 : :
1695 : 0 : return 0;
1696 : : }
1697 : :
1698 : : static int
1699 : 0 : sq_cn9k_fini(struct nix *nix, struct roc_nix_sq *sq)
1700 : : {
1701 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1702 : : struct nix_aq_enq_rsp *rsp;
1703 : : struct nix_aq_enq_req *aq;
1704 : : uint16_t sqes_per_sqb;
1705 : : void *sqb_buf;
1706 : : int rc, count;
1707 : :
1708 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1709 [ # # ]: 0 : if (!aq) {
1710 : : mbox_put(mbox);
1711 : 0 : return -ENOSPC;
1712 : : }
1713 : :
1714 : 0 : aq->qidx = sq->qid;
1715 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1716 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1717 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1718 [ # # ]: 0 : if (rc) {
1719 : : mbox_put(mbox);
1720 : 0 : return rc;
1721 : : }
1722 : :
1723 : : /* Check if sq is already cleaned up */
1724 [ # # ]: 0 : if (!rsp->sq.ena) {
1725 : : mbox_put(mbox);
1726 : 0 : return 0;
1727 : : }
1728 : :
1729 : : /* Disable sq */
1730 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1731 [ # # ]: 0 : if (!aq) {
1732 : : mbox_put(mbox);
1733 : 0 : return -ENOSPC;
1734 : : }
1735 : :
1736 : 0 : aq->qidx = sq->qid;
1737 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1738 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1739 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1740 : 0 : aq->sq.ena = 0;
1741 : 0 : rc = mbox_process(mbox);
1742 [ # # ]: 0 : if (rc) {
1743 : : mbox_put(mbox);
1744 : 0 : return rc;
1745 : : }
1746 : :
1747 : : /* Read SQ and free sqb's */
1748 : 0 : aq = mbox_alloc_msg_nix_aq_enq(mbox);
1749 [ # # ]: 0 : if (!aq) {
1750 : : mbox_put(mbox);
1751 : 0 : return -ENOSPC;
1752 : : }
1753 : :
1754 : 0 : aq->qidx = sq->qid;
1755 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1756 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1757 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1758 [ # # ]: 0 : if (rc) {
1759 : : mbox_put(mbox);
1760 : 0 : return rc;
1761 : : }
1762 : :
1763 [ # # ]: 0 : if (aq->sq.smq_pend)
1764 : 0 : plt_err("SQ has pending SQE's");
1765 : :
1766 : 0 : count = aq->sq.sqb_count;
1767 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1768 : : /* Free SQB's that are used */
1769 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1770 [ # # ]: 0 : while (count) {
1771 : : void *next_sqb;
1772 : :
1773 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1774 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1775 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1776 : : sqb_buf = next_sqb;
1777 : 0 : count--;
1778 : : }
1779 : :
1780 : : /* Free next to use sqb */
1781 [ # # ]: 0 : if (rsp->sq.next_sqb)
1782 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1783 : : mbox_put(mbox);
1784 : 0 : return 0;
1785 : : }
1786 : :
1787 : : static int
1788 : 0 : sq_cn10k_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1789 : : {
1790 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1791 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1792 : : struct nix_cn10k_aq_enq_req *aq;
1793 : :
1794 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1795 [ # # ]: 0 : if (!aq)
1796 : : return -ENOSPC;
1797 : :
1798 : 0 : aq->qidx = sq->qid;
1799 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1800 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1801 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1802 : :
1803 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1804 : 0 : aq->sq.smq = smq;
1805 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1806 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1807 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1808 : : else
1809 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1810 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1811 : 0 : aq->sq.ena = 1;
1812 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1813 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1814 : 0 : aq->sq.cq = sq->cqid;
1815 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1816 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1817 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1818 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1819 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1820 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1821 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1822 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1823 : :
1824 : : /* Many to one reduction */
1825 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1826 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1827 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1828 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1829 : : * might result in software missing the interrupt.
1830 : : */
1831 : 0 : aq->sq.qint_idx = 0;
1832 : : }
1833 : : return 0;
1834 : : }
1835 : :
1836 : : static int
1837 : 0 : sq_cn10k_fini(struct nix *nix, struct roc_nix_sq *sq)
1838 : : {
1839 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1840 : : struct nix_cn10k_aq_enq_rsp *rsp;
1841 : : struct nix_cn10k_aq_enq_req *aq;
1842 : : uint16_t sqes_per_sqb;
1843 : : void *sqb_buf;
1844 : : int rc, count;
1845 : :
1846 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1847 [ # # ]: 0 : if (!aq) {
1848 : : mbox_put(mbox);
1849 : 0 : return -ENOSPC;
1850 : : }
1851 : :
1852 : 0 : aq->qidx = sq->qid;
1853 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1854 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1855 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1856 [ # # ]: 0 : if (rc) {
1857 : : mbox_put(mbox);
1858 : 0 : return rc;
1859 : : }
1860 : :
1861 : : /* Check if sq is already cleaned up */
1862 [ # # ]: 0 : if (!rsp->sq.ena) {
1863 : : mbox_put(mbox);
1864 : 0 : return 0;
1865 : : }
1866 : :
1867 : : /* Disable sq */
1868 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1869 [ # # ]: 0 : if (!aq) {
1870 : : mbox_put(mbox);
1871 : 0 : return -ENOSPC;
1872 : : }
1873 : :
1874 : 0 : aq->qidx = sq->qid;
1875 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1876 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
1877 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
1878 : 0 : aq->sq.ena = 0;
1879 : 0 : rc = mbox_process(mbox);
1880 [ # # ]: 0 : if (rc) {
1881 : : mbox_put(mbox);
1882 : 0 : return rc;
1883 : : }
1884 : :
1885 : : /* Read SQ and free sqb's */
1886 : 0 : aq = mbox_alloc_msg_nix_cn10k_aq_enq(mbox);
1887 [ # # ]: 0 : if (!aq) {
1888 : : mbox_put(mbox);
1889 : 0 : return -ENOSPC;
1890 : : }
1891 : :
1892 : 0 : aq->qidx = sq->qid;
1893 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1894 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1895 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1896 [ # # ]: 0 : if (rc) {
1897 : : mbox_put(mbox);
1898 : 0 : return rc;
1899 : : }
1900 : :
1901 [ # # ]: 0 : if (rsp->sq.smq_pend)
1902 : 0 : plt_err("SQ has pending SQE's");
1903 : :
1904 : 0 : count = rsp->sq.sqb_count;
1905 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
1906 : : /* Free SQB's that are used */
1907 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
1908 [ # # ]: 0 : while (count) {
1909 : : void *next_sqb;
1910 : :
1911 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
1912 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
1913 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
1914 : : sqb_buf = next_sqb;
1915 : 0 : count--;
1916 : : }
1917 : :
1918 : : /* Free next to use sqb */
1919 [ # # ]: 0 : if (rsp->sq.next_sqb)
1920 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
1921 : : mbox_put(mbox);
1922 : 0 : return 0;
1923 : : }
1924 : :
1925 : : static int
1926 : 0 : sq_init(struct nix *nix, struct roc_nix_sq *sq, uint32_t rr_quantum, uint16_t smq)
1927 : : {
1928 : : struct roc_nix *roc_nix = nix_priv_to_roc_nix(nix);
1929 : 0 : struct mbox *mbox = (&nix->dev)->mbox;
1930 : : struct nix_cn20k_aq_enq_req *aq;
1931 : :
1932 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1933 [ # # ]: 0 : if (!aq)
1934 : : return -ENOSPC;
1935 : :
1936 : 0 : aq->qidx = sq->qid;
1937 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1938 : 0 : aq->op = NIX_AQ_INSTOP_INIT;
1939 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1940 : :
1941 : 0 : aq->sq.max_sqe_size = sq->max_sqe_sz;
1942 : 0 : aq->sq.smq = smq;
1943 : 0 : aq->sq.smq_rr_weight = rr_quantum;
1944 [ # # ]: 0 : if (roc_nix_is_sdp(roc_nix))
1945 : 0 : aq->sq.default_chan = nix->tx_chan_base + (sq->qid % nix->tx_chan_cnt);
1946 : : else
1947 : 0 : aq->sq.default_chan = nix->tx_chan_base;
1948 : 0 : aq->sq.sqe_stype = NIX_STYPE_STF;
1949 : 0 : aq->sq.ena = 1;
1950 : 0 : aq->sq.sso_ena = !!sq->sso_ena;
1951 : 0 : aq->sq.cq_ena = !!sq->cq_ena;
1952 : 0 : aq->sq.cq = sq->cqid;
1953 : 0 : aq->sq.cq_limit = sq->cq_drop_thresh;
1954 [ # # ]: 0 : if (aq->sq.max_sqe_size == NIX_MAXSQESZ_W8)
1955 : 0 : aq->sq.sqe_stype = NIX_STYPE_STP;
1956 [ # # ]: 0 : aq->sq.sqb_aura = roc_npa_aura_handle_to_aura(sq->aura_handle);
1957 : 0 : aq->sq.sq_int_ena = BIT(NIX_SQINT_LMT_ERR);
1958 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SQB_ALLOC_FAIL);
1959 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_SEND_ERR);
1960 : 0 : aq->sq.sq_int_ena |= BIT(NIX_SQINT_MNQ_ERR);
1961 : :
1962 : : /* HW atomic update of SQ count */
1963 [ # # ]: 0 : if (sq->sq_cnt_ptr) {
1964 : 0 : aq->sq.sq_count_iova = ((uintptr_t)sq->sq_cnt_ptr) >> 3;
1965 : 0 : aq->sq.update_sq_count = sq->update_sq_cnt;
1966 : : }
1967 : : /* Many to one reduction */
1968 [ # # ]: 0 : aq->sq.qint_idx = sq->qid % nix->qints;
1969 [ # # ]: 0 : if (roc_errata_nix_assign_incorrect_qint()) {
1970 : : /* Assigning QINT 0 to all the SQs, an errata exists where NIXTX can
1971 : : * send incorrect QINT_IDX when reporting queue interrupt (QINT). This
1972 : : * might result in software missing the interrupt.
1973 : : */
1974 : 0 : aq->sq.qint_idx = 0;
1975 : : }
1976 : : return 0;
1977 : : }
1978 : :
1979 : : static int
1980 : 0 : sq_fini(struct nix *nix, struct roc_nix_sq *sq)
1981 : : {
1982 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
1983 : : struct nix_cn20k_aq_enq_rsp *rsp;
1984 : : struct nix_cn20k_aq_enq_req *aq;
1985 : : uint16_t sqes_per_sqb;
1986 : : void *sqb_buf;
1987 : : int rc, count;
1988 : :
1989 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
1990 [ # # ]: 0 : if (!aq) {
1991 : : mbox_put(mbox);
1992 : 0 : return -ENOSPC;
1993 : : }
1994 : :
1995 : 0 : aq->qidx = sq->qid;
1996 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
1997 : 0 : aq->op = NIX_AQ_INSTOP_READ;
1998 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1999 [ # # ]: 0 : if (rc) {
2000 : : mbox_put(mbox);
2001 : 0 : return rc;
2002 : : }
2003 : :
2004 : : /* Check if sq is already cleaned up */
2005 [ # # ]: 0 : if (!rsp->sq.ena) {
2006 : : mbox_put(mbox);
2007 : 0 : return 0;
2008 : : }
2009 : :
2010 : : /* Disable sq */
2011 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2012 [ # # ]: 0 : if (!aq) {
2013 : : mbox_put(mbox);
2014 : 0 : return -ENOSPC;
2015 : : }
2016 : :
2017 : 0 : aq->qidx = sq->qid;
2018 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2019 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
2020 : 0 : aq->sq_mask.ena = ~aq->sq_mask.ena;
2021 : 0 : aq->sq.ena = 0;
2022 : 0 : rc = mbox_process(mbox);
2023 [ # # ]: 0 : if (rc) {
2024 : : mbox_put(mbox);
2025 : 0 : return rc;
2026 : : }
2027 : :
2028 : : /* Read SQ and free sqb's */
2029 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2030 [ # # ]: 0 : if (!aq) {
2031 : : mbox_put(mbox);
2032 : 0 : return -ENOSPC;
2033 : : }
2034 : :
2035 : 0 : aq->qidx = sq->qid;
2036 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2037 : 0 : aq->op = NIX_AQ_INSTOP_READ;
2038 : : rc = mbox_process_msg(mbox, (void *)&rsp);
2039 [ # # ]: 0 : if (rc) {
2040 : : mbox_put(mbox);
2041 : 0 : return rc;
2042 : : }
2043 : :
2044 [ # # ]: 0 : if (aq->sq.smq_pend)
2045 : 0 : plt_err("SQ has pending SQE's");
2046 : :
2047 : 0 : count = aq->sq.sqb_count;
2048 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2049 : : /* Free SQB's that are used */
2050 : 0 : sqb_buf = (void *)rsp->sq.head_sqb;
2051 [ # # ]: 0 : while (count) {
2052 : : void *next_sqb;
2053 : :
2054 : 0 : next_sqb = *(void **)((uint64_t *)sqb_buf +
2055 : 0 : (uint32_t)((sqes_per_sqb - 1) * (0x2 >> sq->max_sqe_sz) * 8));
2056 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, (uint64_t)sqb_buf);
2057 : : sqb_buf = next_sqb;
2058 : 0 : count--;
2059 : : }
2060 : :
2061 : : /* Free next to use sqb */
2062 [ # # ]: 0 : if (rsp->sq.next_sqb)
2063 : 0 : roc_npa_aura_op_free(sq->aura_handle, 1, rsp->sq.next_sqb);
2064 : : mbox_put(mbox);
2065 : 0 : return 0;
2066 : : }
2067 : :
2068 : : int
2069 [ # # ]: 0 : roc_nix_sq_init(struct roc_nix *roc_nix, struct roc_nix_sq *sq)
2070 : : {
2071 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2072 : 0 : bool sq_resize_ena = roc_nix->sq_resize_ena;
2073 : 0 : struct mbox *m_box = (&nix->dev)->mbox;
2074 : 0 : uint16_t qid, smq = UINT16_MAX;
2075 : 0 : uint32_t rr_quantum = 0;
2076 : : struct mbox *mbox;
2077 : : int rc;
2078 : :
2079 [ # # ]: 0 : if (sq == NULL)
2080 : : return NIX_ERR_PARAM;
2081 : :
2082 : 0 : qid = sq->qid;
2083 [ # # ]: 0 : if (qid >= nix->nb_tx_queues)
2084 : : return NIX_ERR_QUEUE_INVALID_RANGE;
2085 : :
2086 : 0 : sq->roc_nix = roc_nix;
2087 : 0 : sq->tc = ROC_NIX_PFC_CLASS_INVALID;
2088 : : /*
2089 : : * Allocate memory for flow control updates from HW.
2090 : : * Alloc one cache line, so that fits all FC_STYPE modes.
2091 : : */
2092 : 0 : sq->fc = plt_zmalloc(ROC_ALIGN, ROC_ALIGN);
2093 [ # # ]: 0 : if (sq->fc == NULL) {
2094 : : rc = NIX_ERR_NO_MEM;
2095 : 0 : goto fail;
2096 : : }
2097 : :
2098 [ # # ]: 0 : if (sq_resize_ena)
2099 : 0 : rc = sqb_pool_dyn_populate(roc_nix, sq);
2100 : : else
2101 : 0 : rc = sqb_pool_populate(roc_nix, sq);
2102 [ # # ]: 0 : if (rc)
2103 : 0 : goto nomem;
2104 : :
2105 : 0 : rc = nix_tm_leaf_data_get(nix, sq->qid, &rr_quantum, &smq);
2106 [ # # ]: 0 : if (rc) {
2107 : : rc = NIX_ERR_TM_LEAF_NODE_GET;
2108 : 0 : goto nomem;
2109 : : }
2110 : :
2111 : : mbox = mbox_get(m_box);
2112 : : /* Init SQ context */
2113 [ # # ]: 0 : if (roc_model_is_cn9k())
2114 : 0 : rc = sq_cn9k_init(nix, sq, rr_quantum, smq);
2115 [ # # ]: 0 : else if (roc_model_is_cn10k())
2116 : 0 : rc = sq_cn10k_init(nix, sq, rr_quantum, smq);
2117 : : else
2118 : 0 : rc = sq_init(nix, sq, rr_quantum, smq);
2119 : :
2120 [ # # ]: 0 : if (rc) {
2121 : : mbox_put(mbox);
2122 : 0 : goto nomem;
2123 : : }
2124 : :
2125 : :
2126 : 0 : rc = mbox_process(mbox);
2127 [ # # ]: 0 : if (rc) {
2128 : : mbox_put(mbox);
2129 : 0 : goto nomem;
2130 : : }
2131 : : mbox_put(mbox);
2132 : :
2133 : 0 : sq->enable = true;
2134 : 0 : nix->sqs[qid] = sq;
2135 [ # # ]: 0 : sq->io_addr = nix->base + NIX_LF_OP_SENDX(0);
2136 : : /* Evenly distribute LMT slot for each sq */
2137 [ # # ]: 0 : if (roc_model_is_cn9k()) {
2138 : : /* Multiple cores/SQ's can use same LMTLINE safely in CN9K */
2139 : 0 : sq->lmt_addr = (void *)(nix->lmt_base +
2140 : 0 : ((qid & RVU_CN9K_LMT_SLOT_MASK) << 12));
2141 : : }
2142 : :
2143 : 0 : rc = nix_tel_node_add_sq(sq);
2144 : 0 : return rc;
2145 : 0 : nomem:
2146 : 0 : plt_free(sq->fc);
2147 : : fail:
2148 : : return rc;
2149 : : }
2150 : :
2151 : : static void
2152 : 0 : nix_sqb_mem_dyn_free(uint64_t aura_handle, uint16_t count)
2153 : : {
2154 : : uint64_t iova;
2155 : :
2156 : : /* Recover SQB's and free them back */
2157 : : while (count) {
2158 : : iova = roc_npa_aura_op_alloc(aura_handle, 0);
2159 : : if (!iova)
2160 : : break;
2161 : : plt_free((uint64_t *)iova);
2162 : : count--;
2163 : : }
2164 [ # # ]: 0 : if (count)
2165 : 0 : plt_err("Failed to recover %u SQB's", count);
2166 : 0 : }
2167 : :
2168 : : int
2169 : 0 : roc_nix_sq_fini(struct roc_nix_sq *sq)
2170 : : {
2171 : : struct ndc_sync_op *ndc_req;
2172 : : struct roc_nix *roc_nix;
2173 : : bool sq_resize_ena;
2174 : : struct mbox *mbox;
2175 : : struct nix *nix;
2176 : : uint16_t qid;
2177 : : int rc = 0;
2178 : :
2179 [ # # ]: 0 : if (sq == NULL)
2180 : : return NIX_ERR_PARAM;
2181 : :
2182 : 0 : roc_nix = sq->roc_nix;
2183 : 0 : sq_resize_ena = roc_nix->sq_resize_ena;
2184 : :
2185 : : nix = roc_nix_to_nix_priv(roc_nix);
2186 : 0 : mbox = (&nix->dev)->mbox;
2187 : :
2188 : 0 : qid = sq->qid;
2189 : :
2190 : 0 : rc = nix_tm_sq_flush_pre(sq);
2191 : :
2192 : : /* Release SQ context */
2193 [ # # ]: 0 : if (roc_model_is_cn9k())
2194 : 0 : rc |= sq_cn9k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2195 [ # # ]: 0 : else if (roc_model_is_cn10k())
2196 : 0 : rc |= sq_cn10k_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2197 : : else
2198 : 0 : rc |= sq_fini(roc_nix_to_nix_priv(sq->roc_nix), sq);
2199 : :
2200 : : /* Sync NDC-NIX-TX for LF */
2201 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox_get(mbox));
2202 [ # # ]: 0 : if (ndc_req == NULL) {
2203 : : mbox_put(mbox);
2204 : 0 : return -ENOSPC;
2205 : : }
2206 : 0 : ndc_req->nix_lf_tx_sync = 1;
2207 [ # # ]: 0 : if (mbox_process(mbox))
2208 : 0 : rc |= NIX_ERR_NDC_SYNC;
2209 : : mbox_put(mbox);
2210 : :
2211 : 0 : rc |= nix_tm_sq_flush_post(sq);
2212 : :
2213 : : /* Restore limit to max SQB count that the pool was created
2214 : : * for aura drain to succeed.
2215 : : */
2216 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, sq->aura_sqb_bufs);
2217 : :
2218 [ # # ]: 0 : if (sq_resize_ena)
2219 : 0 : nix_sqb_mem_dyn_free(sq->aura_handle, sq->aura_sqb_bufs);
2220 : :
2221 : 0 : rc |= roc_npa_pool_destroy(sq->aura_handle);
2222 : 0 : plt_free(sq->fc);
2223 [ # # ]: 0 : if (!sq_resize_ena)
2224 : 0 : plt_free(sq->sqe_mem);
2225 : 0 : nix->sqs[qid] = NULL;
2226 : :
2227 : 0 : return rc;
2228 : : }
2229 : :
2230 : : static int
2231 : 0 : sqb_aura_dyn_expand(struct roc_nix_sq *sq, uint16_t count)
2232 : : {
2233 : 0 : struct nix *nix = roc_nix_to_nix_priv(sq->roc_nix);
2234 : : uint64_t *sqbs = NULL;
2235 : : uint16_t blk_sz;
2236 : : int i;
2237 : :
2238 : 0 : blk_sz = nix->sqb_size;
2239 : 0 : sqbs = calloc(1, count * sizeof(uint64_t));
2240 [ # # ]: 0 : if (!sqbs)
2241 : : return -ENOMEM;
2242 : :
2243 [ # # ]: 0 : for (i = 0; i < count; i++) {
2244 : 0 : sqbs[i] = (uint64_t)plt_zmalloc(blk_sz, ROC_ALIGN);
2245 [ # # ]: 0 : if (!sqbs[i])
2246 : : break;
2247 : : }
2248 : :
2249 [ # # ]: 0 : if (i != count) {
2250 : 0 : i = i - 1;
2251 [ # # ]: 0 : for (; i >= 0; i--)
2252 : 0 : plt_free((void *)sqbs[i]);
2253 : 0 : free(sqbs);
2254 : 0 : return -ENOMEM;
2255 : : }
2256 : :
2257 : 0 : plt_io_wmb();
2258 : :
2259 : : /* Add new buffers to sqb aura */
2260 [ # # ]: 0 : for (i = 0; i < count; i++)
2261 : 0 : roc_npa_aura_op_free(sq->aura_handle, 0, sqbs[i]);
2262 : 0 : free(sqbs);
2263 : :
2264 : : /* Adjust SQ info */
2265 : 0 : sq->nb_sqb_bufs += count;
2266 : 0 : sq->nb_sqb_bufs_adj += count;
2267 : 0 : sq->aura_sqb_bufs += count;
2268 : 0 : return 0;
2269 : : }
2270 : :
2271 : : static int
2272 : 0 : sqb_aura_dyn_contract(struct roc_nix_sq *sq, uint16_t count)
2273 : : {
2274 : 0 : struct nix *nix = roc_nix_to_nix_priv(sq->roc_nix);
2275 : : struct dev *dev = &nix->dev;
2276 : : struct ndc_sync_op *ndc_req;
2277 : : uint64_t *sqbs = NULL;
2278 : : struct mbox *mbox;
2279 : : uint64_t timeout; /* 10's of usec */
2280 : : uint64_t cycles;
2281 : : int i, rc;
2282 : :
2283 : 0 : mbox = dev->mbox;
2284 : : /* Sync NDC-NIX-TX for LF */
2285 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox_get(mbox));
2286 [ # # ]: 0 : if (ndc_req == NULL) {
2287 : : mbox_put(mbox);
2288 : 0 : return -EFAULT;
2289 : : }
2290 : :
2291 : 0 : ndc_req->nix_lf_tx_sync = 1;
2292 : 0 : rc = mbox_process(mbox);
2293 [ # # ]: 0 : if (rc) {
2294 : : mbox_put(mbox);
2295 : 0 : return rc;
2296 : : }
2297 : : mbox_put(mbox);
2298 : :
2299 : : /* Wait for enough time based on shaper min rate */
2300 : 0 : timeout = (sq->nb_desc * roc_nix_max_pkt_len(sq->roc_nix) * 8 * 1E5);
2301 : : /* Wait for worst case scenario of this SQ being last priority
2302 : : * and so have to wait for all other SQ's drain out by their own.
2303 : : */
2304 : 0 : timeout = timeout * nix->nb_tx_queues;
2305 : 0 : timeout = timeout / nix->tm_rate_min;
2306 [ # # ]: 0 : if (!timeout)
2307 : : timeout = 10000;
2308 : 0 : cycles = (timeout * 10 * plt_tsc_hz()) / (uint64_t)1E6;
2309 : 0 : cycles += plt_tsc_cycles();
2310 : :
2311 : 0 : sqbs = calloc(1, count * sizeof(uint64_t));
2312 [ # # ]: 0 : if (!sqbs)
2313 : : return -ENOMEM;
2314 : :
2315 : : i = 0;
2316 [ # # # # ]: 0 : while (i < count && plt_tsc_cycles() < cycles) {
2317 : 0 : sqbs[i] = roc_npa_aura_op_alloc(sq->aura_handle, 0);
2318 : : if (sqbs[i])
2319 : : i++;
2320 : : else
2321 : 0 : plt_delay_us(1);
2322 : : }
2323 : :
2324 [ # # ]: 0 : if (i != count) {
2325 : 0 : plt_warn("SQ %u busy, unable to recover %u SQB's(%u desc)", sq->qid, count,
2326 : : count * sq->sqes_per_sqb);
2327 : :
2328 : : /* Restore the SQB aura state and return */
2329 : : i--;
2330 : : for (; i >= 0; i--)
2331 : : roc_npa_aura_op_free(sq->aura_handle, 0, sqbs[i]);
2332 : 0 : free(sqbs);
2333 : 0 : return -EAGAIN;
2334 : : }
2335 : :
2336 : : /* Extracted necessary SQB's, on free them */
2337 : : for (i = 0; i < count; i++)
2338 : : plt_free((void *)sqbs[i]);
2339 : 0 : free(sqbs);
2340 : :
2341 : : /* Adjust SQ info */
2342 : 0 : sq->nb_sqb_bufs -= count;
2343 : 0 : sq->nb_sqb_bufs_adj -= count;
2344 : 0 : sq->aura_sqb_bufs -= count;
2345 : 0 : return 0;
2346 : : }
2347 : :
2348 : : int
2349 : 0 : roc_nix_sq_resize(struct roc_nix_sq *sq, uint32_t nb_desc)
2350 : : {
2351 : 0 : struct roc_nix *roc_nix = sq->roc_nix;
2352 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2353 : : uint16_t aura_sqb_bufs, nb_sqb_bufs, sqes_per_sqb;
2354 : : int64_t *regaddr;
2355 : : uint64_t wdata;
2356 : : uint16_t diff;
2357 : : int rc;
2358 : :
2359 [ # # ]: 0 : if (!roc_nix->sq_resize_ena)
2360 : : return -ENOTSUP;
2361 : :
2362 : 0 : sqes_per_sqb = sq->sqes_per_sqb;
2363 : :
2364 : : /* Calculate new nb_sqb_bufs */
2365 : : nb_sqb_bufs = sq_desc_to_sqb(nix, sqes_per_sqb, nb_desc);
2366 [ # # ]: 0 : aura_sqb_bufs = sqb_slack_adjust(nix, nb_sqb_bufs, !!sq->sq_cnt_ptr);
2367 : :
2368 [ # # ]: 0 : if (aura_sqb_bufs == sq->aura_sqb_bufs)
2369 : : return 0;
2370 : :
2371 : : /* Issue atomic op to make sure all inflight LMTST's are complete
2372 : : * assuming no new submissions will take place.
2373 : : */
2374 : : wdata = ((uint64_t)sq->qid) << 32;
2375 : : regaddr = (int64_t *)(nix->base + NIX_LF_SQ_OP_STATUS);
2376 : : roc_atomic64_add_nosync(wdata, regaddr);
2377 : :
2378 : : /* Expand or Contract SQB aura */
2379 [ # # ]: 0 : if (aura_sqb_bufs > sq->aura_sqb_bufs) {
2380 : : /* Increase the limit */
2381 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, aura_sqb_bufs);
2382 : 0 : diff = aura_sqb_bufs - sq->aura_sqb_bufs;
2383 [ # # ]: 0 : roc_npa_aura_op_cnt_set(sq->aura_handle, 1, diff);
2384 : :
2385 : 0 : rc = sqb_aura_dyn_expand(sq, diff);
2386 : : } else {
2387 : 0 : diff = sq->aura_sqb_bufs - aura_sqb_bufs;
2388 : 0 : rc = sqb_aura_dyn_contract(sq, diff);
2389 : :
2390 : : /* Decrease the limit */
2391 [ # # ]: 0 : if (!rc) {
2392 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, aura_sqb_bufs);
2393 [ # # ]: 0 : roc_npa_aura_op_cnt_set(sq->aura_handle, 1, -(int64_t)diff);
2394 : : }
2395 : : }
2396 : :
2397 : 0 : plt_io_wmb();
2398 [ # # ]: 0 : if (!rc) {
2399 : 0 : sq->nb_desc = nb_desc;
2400 [ # # ]: 0 : if (sq->sq_cnt_ptr)
2401 : 0 : plt_atomic_store_explicit((uint64_t __plt_atomic *)sq->sq_cnt_ptr, nb_desc,
2402 : : plt_memory_order_release);
2403 : 0 : *(uint64_t *)sq->fc = roc_npa_aura_op_cnt_get(sq->aura_handle);
2404 : : } else {
2405 : 0 : roc_npa_aura_limit_modify(sq->aura_handle, sq->aura_sqb_bufs);
2406 : : }
2407 : :
2408 : 0 : plt_io_wmb();
2409 : 0 : return rc;
2410 : : }
2411 : :
2412 : : void
2413 : 0 : roc_nix_cq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2414 : : uint32_t *tail)
2415 : : {
2416 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2417 : : uint64_t reg, val;
2418 : : int64_t *addr;
2419 : :
2420 [ # # ]: 0 : if (head == NULL || tail == NULL)
2421 : : return;
2422 : :
2423 : : reg = (((uint64_t)qid) << 32);
2424 : : addr = (int64_t *)(nix->base + NIX_LF_CQ_OP_STATUS);
2425 : : val = roc_atomic64_add_nosync(reg, addr);
2426 : : if (val &
2427 : : (BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) | BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR)))
2428 : : val = 0;
2429 : :
2430 : 0 : *tail = (uint32_t)(val & 0xFFFFF);
2431 : 0 : *head = (uint32_t)((val >> 20) & 0xFFFFF);
2432 : : }
2433 : :
2434 : : void
2435 : 0 : roc_nix_sq_head_tail_get(struct roc_nix *roc_nix, uint16_t qid, uint32_t *head,
2436 : : uint32_t *tail)
2437 : : {
2438 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2439 : 0 : struct roc_nix_sq *sq = nix->sqs[qid];
2440 : : uint16_t sqes_per_sqb, sqb_cnt;
2441 : : uint64_t reg, val;
2442 : : int64_t *addr;
2443 : :
2444 [ # # ]: 0 : if (head == NULL || tail == NULL)
2445 : : return;
2446 : :
2447 : : reg = (((uint64_t)qid) << 32);
2448 : : addr = (int64_t *)(nix->base + NIX_LF_SQ_OP_STATUS);
2449 : : val = roc_atomic64_add_nosync(reg, addr);
2450 : : if (val & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR)) {
2451 : : val = 0;
2452 : : return;
2453 : : }
2454 : :
2455 : : *tail = (uint32_t)((val >> 28) & 0x3F);
2456 : 0 : *head = (uint32_t)((val >> 20) & 0x3F);
2457 : : sqb_cnt = (uint16_t)(val & 0xFFFF);
2458 : :
2459 : 0 : sqes_per_sqb = 1 << sq->sqes_per_sqb_log2;
2460 : :
2461 : : /* Update tail index as per used sqb count */
2462 : 0 : *tail += (sqes_per_sqb * (sqb_cnt - 1));
2463 : : }
2464 : :
2465 : : int
2466 : 0 : roc_nix_q_err_cb_register(struct roc_nix *roc_nix, q_err_get_t sq_err_handle)
2467 : : {
2468 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2469 : : struct dev *dev = &nix->dev;
2470 : :
2471 [ # # ]: 0 : if (sq_err_handle == NULL)
2472 : : return NIX_ERR_PARAM;
2473 : :
2474 : 0 : dev->ops->q_err_cb = (q_err_cb_t)sq_err_handle;
2475 : 0 : return 0;
2476 : : }
2477 : :
2478 : : void
2479 : 0 : roc_nix_q_err_cb_unregister(struct roc_nix *roc_nix)
2480 : : {
2481 : : struct nix *nix = roc_nix_to_nix_priv(roc_nix);
2482 : : struct dev *dev = &nix->dev;
2483 : :
2484 : 0 : dev->ops->q_err_cb = NULL;
2485 : 0 : }
2486 : :
2487 : : int
2488 : 0 : roc_nix_sq_cnt_update(struct roc_nix_sq *sq, bool enable)
2489 : : {
2490 : 0 : struct nix *nix = roc_nix_to_nix_priv(sq->roc_nix);
2491 : 0 : struct mbox *mbox = mbox_get((&nix->dev)->mbox);
2492 : 0 : int64_t __plt_atomic *sq_cntm = (int64_t __plt_atomic *)sq->sq_cnt_ptr;
2493 : : struct nix_cn20k_aq_enq_rsp *rsp;
2494 : : struct nix_cn20k_aq_enq_req *aq;
2495 : : int rc;
2496 : :
2497 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2498 [ # # ]: 0 : if (!aq) {
2499 : : mbox_put(mbox);
2500 : 0 : return -ENOSPC;
2501 : : }
2502 : :
2503 : 0 : aq->qidx = sq->qid;
2504 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2505 : 0 : aq->op = NIX_AQ_INSTOP_READ;
2506 : : rc = mbox_process_msg(mbox, (void *)&rsp);
2507 [ # # ]: 0 : if (rc) {
2508 : : mbox_put(mbox);
2509 : 0 : return rc;
2510 : : }
2511 : :
2512 : : /* Check if sq is already in same state */
2513 [ # # # # : 0 : if ((enable && rsp->sq.update_sq_count) || (!enable && !rsp->sq.update_sq_count)) {
# # # # ]
2514 : : mbox_put(mbox);
2515 : 0 : return 0;
2516 : : }
2517 : :
2518 : : /* Disable sq */
2519 : 0 : aq = mbox_alloc_msg_nix_cn20k_aq_enq(mbox);
2520 [ # # ]: 0 : if (!aq) {
2521 : : mbox_put(mbox);
2522 : 0 : return -ENOSPC;
2523 : : }
2524 : :
2525 : 0 : aq->qidx = sq->qid;
2526 : 0 : aq->ctype = NIX_AQ_CTYPE_SQ;
2527 : 0 : aq->op = NIX_AQ_INSTOP_WRITE;
2528 : 0 : aq->sq_mask.update_sq_count = ~aq->sq_mask.update_sq_count;
2529 : 0 : aq->sq.update_sq_count = enable;
2530 [ # # ]: 0 : if (enable)
2531 : 0 : aq->sq.update_sq_count = sq->update_sq_cnt;
2532 : 0 : rc = mbox_process(mbox);
2533 [ # # ]: 0 : if (rc) {
2534 : : mbox_put(mbox);
2535 : 0 : return rc;
2536 : : }
2537 [ # # ]: 0 : if (enable)
2538 : 0 : plt_atomic_store_explicit(sq_cntm, sq->nb_desc, plt_memory_order_relaxed);
2539 : : else
2540 : 0 : plt_atomic_store_explicit(sq_cntm, 0, plt_memory_order_relaxed);
2541 : :
2542 : : mbox_put(mbox);
2543 : 0 : return 0;
2544 : : }
|