common/cnxk: fix build with custom maximum port config
[dpdk.git] / drivers / common / cnxk / roc_nix_inl.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 uint32_t soft_exp_consumer_cnt;
9
10 PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ ==
11                   1UL << ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ_LOG2);
12 PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ == 512);
13 PLT_STATIC_ASSERT(ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ ==
14                   1UL << ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ_LOG2);
15 PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_INB_SA_SZ ==
16                   1UL << ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
17 PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_INB_SA_SZ == 1024);
18 PLT_STATIC_ASSERT(ROC_NIX_INL_OT_IPSEC_OUTB_SA_SZ ==
19                   1UL << ROC_NIX_INL_OT_IPSEC_OUTB_SA_SZ_LOG2);
20
21 static int
22 nix_inl_inb_sa_tbl_setup(struct roc_nix *roc_nix)
23 {
24         uint32_t ipsec_in_min_spi = roc_nix->ipsec_in_min_spi;
25         uint32_t ipsec_in_max_spi = roc_nix->ipsec_in_max_spi;
26         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
27         struct roc_nix_ipsec_cfg cfg;
28         uint64_t max_sa, i;
29         size_t inb_sa_sz;
30         void *sa;
31         int rc;
32
33         max_sa = plt_align32pow2(ipsec_in_max_spi - ipsec_in_min_spi + 1);
34
35         /* CN9K SA size is different */
36         if (roc_model_is_cn9k())
37                 inb_sa_sz = ROC_NIX_INL_ONF_IPSEC_INB_SA_SZ;
38         else
39                 inb_sa_sz = ROC_NIX_INL_OT_IPSEC_INB_SA_SZ;
40
41         /* Alloc contiguous memory for Inbound SA's */
42         nix->inb_sa_sz = inb_sa_sz;
43         nix->inb_spi_mask = max_sa - 1;
44         nix->inb_sa_base = plt_zmalloc(inb_sa_sz * max_sa,
45                                        ROC_NIX_INL_SA_BASE_ALIGN);
46         if (!nix->inb_sa_base) {
47                 plt_err("Failed to allocate memory for Inbound SA");
48                 return -ENOMEM;
49         }
50         if (roc_model_is_cn10k()) {
51                 for (i = 0; i < max_sa; i++) {
52                         sa = ((uint8_t *)nix->inb_sa_base) + (i * inb_sa_sz);
53                         roc_ot_ipsec_inb_sa_init(sa, true);
54                 }
55         }
56
57         memset(&cfg, 0, sizeof(cfg));
58         cfg.sa_size = inb_sa_sz;
59         cfg.iova = (uintptr_t)nix->inb_sa_base;
60         cfg.max_sa = max_sa;
61         cfg.tt = SSO_TT_ORDERED;
62
63         /* Setup device specific inb SA table */
64         rc = roc_nix_lf_inl_ipsec_cfg(roc_nix, &cfg, true);
65         if (rc) {
66                 plt_err("Failed to setup NIX Inbound SA conf, rc=%d", rc);
67                 goto free_mem;
68         }
69
70         return 0;
71 free_mem:
72         plt_free(nix->inb_sa_base);
73         nix->inb_sa_base = NULL;
74         return rc;
75 }
76
77 static int
78 nix_inl_sa_tbl_release(struct roc_nix *roc_nix)
79 {
80         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
81         int rc;
82
83         rc = roc_nix_lf_inl_ipsec_cfg(roc_nix, NULL, false);
84         if (rc) {
85                 plt_err("Failed to disable Inbound inline ipsec, rc=%d", rc);
86                 return rc;
87         }
88
89         plt_free(nix->inb_sa_base);
90         nix->inb_sa_base = NULL;
91         return 0;
92 }
93
94 struct roc_cpt_lf *
95 roc_nix_inl_outb_lf_base_get(struct roc_nix *roc_nix)
96 {
97         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
98
99         /* NIX Inline config needs to be done */
100         if (!nix->inl_outb_ena || !nix->cpt_lf_base)
101                 return NULL;
102
103         return (struct roc_cpt_lf *)nix->cpt_lf_base;
104 }
105
106 uintptr_t
107 roc_nix_inl_outb_sa_base_get(struct roc_nix *roc_nix)
108 {
109         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
110
111         return (uintptr_t)nix->outb_sa_base;
112 }
113
114 uintptr_t
115 roc_nix_inl_inb_sa_base_get(struct roc_nix *roc_nix, bool inb_inl_dev)
116 {
117         struct idev_cfg *idev = idev_get_cfg();
118         struct nix_inl_dev *inl_dev;
119         struct nix *nix = NULL;
120
121         if (idev == NULL)
122                 return 0;
123
124         if (!inb_inl_dev && roc_nix == NULL)
125                 return -EINVAL;
126
127         if (roc_nix) {
128                 nix = roc_nix_to_nix_priv(roc_nix);
129                 if (!nix->inl_inb_ena)
130                         return 0;
131         }
132
133         if (inb_inl_dev) {
134                 inl_dev = idev->nix_inl_dev;
135                 /* Return inline dev sa base */
136                 if (inl_dev)
137                         return (uintptr_t)inl_dev->inb_sa_base;
138                 return 0;
139         }
140
141         return (uintptr_t)nix->inb_sa_base;
142 }
143
144 uint32_t
145 roc_nix_inl_inb_spi_range(struct roc_nix *roc_nix, bool inb_inl_dev,
146                           uint32_t *min_spi, uint32_t *max_spi)
147 {
148         struct idev_cfg *idev = idev_get_cfg();
149         uint32_t min = 0, max = 0, mask = 0;
150         struct nix_inl_dev *inl_dev;
151         struct nix *nix = NULL;
152
153         if (idev == NULL)
154                 return 0;
155
156         if (!inb_inl_dev && roc_nix == NULL)
157                 return -EINVAL;
158
159         inl_dev = idev->nix_inl_dev;
160         if (inb_inl_dev) {
161                 min = inl_dev->ipsec_in_min_spi;
162                 max = inl_dev->ipsec_in_max_spi;
163                 mask = inl_dev->inb_spi_mask;
164         } else {
165                 nix = roc_nix_to_nix_priv(roc_nix);
166                 if (!nix->inl_inb_ena)
167                         goto exit;
168                 min = roc_nix->ipsec_in_min_spi;
169                 max = roc_nix->ipsec_in_max_spi;
170                 mask = nix->inb_spi_mask;
171         }
172 exit:
173         if (min_spi)
174                 *min_spi = min;
175         if (max_spi)
176                 *max_spi = max;
177         return mask;
178 }
179
180 uint32_t
181 roc_nix_inl_inb_sa_sz(struct roc_nix *roc_nix, bool inl_dev_sa)
182 {
183         struct idev_cfg *idev = idev_get_cfg();
184         struct nix_inl_dev *inl_dev;
185         struct nix *nix;
186
187         if (idev == NULL)
188                 return 0;
189
190         if (!inl_dev_sa && roc_nix == NULL)
191                 return -EINVAL;
192
193         if (roc_nix) {
194                 nix = roc_nix_to_nix_priv(roc_nix);
195                 if (!inl_dev_sa)
196                         return nix->inb_sa_sz;
197         }
198
199         if (inl_dev_sa) {
200                 inl_dev = idev->nix_inl_dev;
201                 if (inl_dev)
202                         return inl_dev->inb_sa_sz;
203         }
204
205         return 0;
206 }
207
208 uintptr_t
209 roc_nix_inl_inb_sa_get(struct roc_nix *roc_nix, bool inb_inl_dev, uint32_t spi)
210 {
211         uint32_t max_spi, min_spi, mask;
212         uintptr_t sa_base;
213         uint64_t sz;
214
215         sa_base = roc_nix_inl_inb_sa_base_get(roc_nix, inb_inl_dev);
216         /* Check if SA base exists */
217         if (!sa_base)
218                 return 0;
219
220         /* Check if SPI is in range */
221         mask = roc_nix_inl_inb_spi_range(roc_nix, inb_inl_dev, &min_spi,
222                                          &max_spi);
223         if (spi > max_spi || spi < min_spi)
224                 plt_warn("Inbound SA SPI %u not in range (%u..%u)", spi,
225                          min_spi, max_spi);
226
227         /* Get SA size */
228         sz = roc_nix_inl_inb_sa_sz(roc_nix, inb_inl_dev);
229         if (!sz)
230                 return 0;
231
232         /* Basic logic of SPI->SA for now */
233         return (sa_base + ((spi & mask) * sz));
234 }
235
236 int
237 roc_nix_reassembly_configure(uint32_t max_wait_time, uint16_t max_frags)
238 {
239         struct idev_cfg *idev = idev_get_cfg();
240         struct roc_cpt *roc_cpt;
241         struct roc_cpt_rxc_time_cfg cfg;
242
243         PLT_SET_USED(max_frags);
244         roc_cpt = idev->cpt;
245         if (!roc_cpt) {
246                 plt_err("Cannot support inline inbound, cryptodev not probed");
247                 return -ENOTSUP;
248         }
249
250         cfg.step = (max_wait_time * 1000 / ROC_NIX_INL_REAS_ACTIVE_LIMIT);
251         cfg.zombie_limit = ROC_NIX_INL_REAS_ZOMBIE_LIMIT;
252         cfg.zombie_thres = ROC_NIX_INL_REAS_ZOMBIE_THRESHOLD;
253         cfg.active_limit = ROC_NIX_INL_REAS_ACTIVE_LIMIT;
254         cfg.active_thres = ROC_NIX_INL_REAS_ACTIVE_THRESHOLD;
255
256         return roc_cpt_rxc_time_cfg(roc_cpt, &cfg);
257 }
258
259 int
260 roc_nix_inl_inb_init(struct roc_nix *roc_nix)
261 {
262         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
263         struct idev_cfg *idev = idev_get_cfg();
264         struct roc_cpt *roc_cpt;
265         uint16_t param1;
266         int rc;
267
268         if (idev == NULL)
269                 return -ENOTSUP;
270
271         /* Unless we have another mechanism to trigger
272          * onetime Inline config in CPTPF, we cannot
273          * support without CPT being probed.
274          */
275         roc_cpt = idev->cpt;
276         if (!roc_cpt) {
277                 plt_err("Cannot support inline inbound, cryptodev not probed");
278                 return -ENOTSUP;
279         }
280
281         if (roc_model_is_cn9k()) {
282                 param1 = ROC_ONF_IPSEC_INB_MAX_L2_SZ;
283         } else {
284                 union roc_ot_ipsec_inb_param1 u;
285
286                 u.u16 = 0;
287                 u.s.esp_trailer_disable = 1;
288                 param1 = u.u16;
289         }
290
291         /* Do onetime Inbound Inline config in CPTPF */
292         rc = roc_cpt_inline_ipsec_inb_cfg(roc_cpt, param1, 0);
293         if (rc && rc != -EEXIST) {
294                 plt_err("Failed to setup inbound lf, rc=%d", rc);
295                 return rc;
296         }
297
298         /* Setup Inbound SA table */
299         rc = nix_inl_inb_sa_tbl_setup(roc_nix);
300         if (rc)
301                 return rc;
302
303         nix->inl_inb_ena = true;
304         return 0;
305 }
306
307 int
308 roc_nix_inl_inb_fini(struct roc_nix *roc_nix)
309 {
310         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
311
312         if (!nix->inl_inb_ena)
313                 return 0;
314
315         nix->inl_inb_ena = false;
316
317         /* Flush Inbound CTX cache entries */
318         roc_nix_cpt_ctx_cache_sync(roc_nix);
319
320         /* Disable Inbound SA */
321         return nix_inl_sa_tbl_release(roc_nix);
322 }
323
324 int
325 roc_nix_inl_outb_init(struct roc_nix *roc_nix)
326 {
327         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
328         struct idev_cfg *idev = idev_get_cfg();
329         struct roc_cpt_lf *lf_base, *lf;
330         struct dev *dev = &nix->dev;
331         struct msix_offset_rsp *rsp;
332         struct nix_inl_dev *inl_dev;
333         size_t sa_sz, ring_sz;
334         uint16_t sso_pffunc;
335         uint8_t eng_grpmask;
336         uint64_t blkaddr, i;
337         uint64_t *ring_base;
338         uint16_t nb_lf;
339         void *sa_base;
340         int j, rc;
341         void *sa;
342
343         if (idev == NULL)
344                 return -ENOTSUP;
345
346         nb_lf = roc_nix->outb_nb_crypto_qs;
347         blkaddr = nix->is_nix1 ? RVU_BLOCK_ADDR_CPT1 : RVU_BLOCK_ADDR_CPT0;
348
349         /* Retrieve inline device if present */
350         inl_dev = idev->nix_inl_dev;
351         sso_pffunc = inl_dev ? inl_dev->dev.pf_func : idev_sso_pffunc_get();
352         /* Use sso_pffunc if explicitly requested */
353         if (roc_nix->ipsec_out_sso_pffunc)
354                 sso_pffunc = idev_sso_pffunc_get();
355
356         if (!sso_pffunc) {
357                 plt_err("Failed to setup inline outb, need either "
358                         "inline device or sso device");
359                 return -ENOTSUP;
360         }
361
362         /* Attach CPT LF for outbound */
363         rc = cpt_lfs_attach(dev, blkaddr, true, nb_lf);
364         if (rc) {
365                 plt_err("Failed to attach CPT LF for inline outb, rc=%d", rc);
366                 return rc;
367         }
368
369         /* Alloc CPT LF */
370         eng_grpmask = (1ULL << ROC_CPT_DFLT_ENG_GRP_SE |
371                        1ULL << ROC_CPT_DFLT_ENG_GRP_SE_IE |
372                        1ULL << ROC_CPT_DFLT_ENG_GRP_AE);
373         rc = cpt_lfs_alloc(dev, eng_grpmask, blkaddr,
374                            !roc_nix->ipsec_out_sso_pffunc);
375         if (rc) {
376                 plt_err("Failed to alloc CPT LF resources, rc=%d", rc);
377                 goto lf_detach;
378         }
379
380         /* Get msix offsets */
381         rc = cpt_get_msix_offset(dev, &rsp);
382         if (rc) {
383                 plt_err("Failed to get CPT LF msix offset, rc=%d", rc);
384                 goto lf_free;
385         }
386
387         mbox_memcpy(nix->cpt_msixoff,
388                     nix->is_nix1 ? rsp->cpt1_lf_msixoff : rsp->cptlf_msixoff,
389                     sizeof(nix->cpt_msixoff));
390
391         /* Alloc required num of cpt lfs */
392         lf_base = plt_zmalloc(nb_lf * sizeof(struct roc_cpt_lf), 0);
393         if (!lf_base) {
394                 plt_err("Failed to alloc cpt lf memory");
395                 rc = -ENOMEM;
396                 goto lf_free;
397         }
398
399         /* Initialize CPT LF's */
400         for (i = 0; i < nb_lf; i++) {
401                 lf = &lf_base[i];
402
403                 lf->lf_id = i;
404                 lf->nb_desc = roc_nix->outb_nb_desc;
405                 lf->dev = &nix->dev;
406                 lf->msixoff = nix->cpt_msixoff[i];
407                 lf->pci_dev = nix->pci_dev;
408
409                 /* Setup CPT LF instruction queue */
410                 rc = cpt_lf_init(lf);
411                 if (rc) {
412                         plt_err("Failed to initialize CPT LF, rc=%d", rc);
413                         goto lf_fini;
414                 }
415
416                 /* Associate this CPT LF with NIX PFFUNC */
417                 rc = cpt_lf_outb_cfg(dev, sso_pffunc, nix->dev.pf_func, i,
418                                      true);
419                 if (rc) {
420                         plt_err("Failed to setup CPT LF->(NIX,SSO) link, rc=%d",
421                                 rc);
422                         goto lf_fini;
423                 }
424
425                 /* Enable IQ */
426                 roc_cpt_iq_enable(lf);
427         }
428
429         if (!roc_nix->ipsec_out_max_sa)
430                 goto skip_sa_alloc;
431
432         /* CN9K SA size is different */
433         if (roc_model_is_cn9k())
434                 sa_sz = ROC_NIX_INL_ONF_IPSEC_OUTB_SA_SZ;
435         else
436                 sa_sz = ROC_NIX_INL_OT_IPSEC_OUTB_SA_SZ;
437         /* Alloc contiguous memory of outbound SA */
438         sa_base = plt_zmalloc(sa_sz * roc_nix->ipsec_out_max_sa,
439                               ROC_NIX_INL_SA_BASE_ALIGN);
440         if (!sa_base) {
441                 plt_err("Outbound SA base alloc failed");
442                 goto lf_fini;
443         }
444         if (roc_model_is_cn10k()) {
445                 for (i = 0; i < roc_nix->ipsec_out_max_sa; i++) {
446                         sa = ((uint8_t *)sa_base) + (i * sa_sz);
447                         roc_ot_ipsec_outb_sa_init(sa);
448                 }
449         }
450         nix->outb_sa_base = sa_base;
451         nix->outb_sa_sz = sa_sz;
452
453 skip_sa_alloc:
454
455         nix->cpt_lf_base = lf_base;
456         nix->nb_cpt_lf = nb_lf;
457         nix->outb_err_sso_pffunc = sso_pffunc;
458         nix->inl_outb_ena = true;
459         nix->outb_se_ring_cnt =
460                 roc_nix->ipsec_out_max_sa / ROC_IPSEC_ERR_RING_MAX_ENTRY + 1;
461         nix->outb_se_ring_base =
462                 roc_nix->port_id * ROC_NIX_SOFT_EXP_PER_PORT_MAX_RINGS;
463
464         if (inl_dev == NULL) {
465                 nix->outb_se_ring_cnt = 0;
466                 return 0;
467         }
468
469         /* Allocate memory to be used as a ring buffer to poll for
470          * soft expiry event from ucode
471          */
472         ring_sz = (ROC_IPSEC_ERR_RING_MAX_ENTRY + 1) * sizeof(uint64_t);
473         ring_base = inl_dev->sa_soft_exp_ring;
474         for (i = 0; i < nix->outb_se_ring_cnt; i++) {
475                 ring_base[nix->outb_se_ring_base + i] =
476                         PLT_U64_CAST(plt_zmalloc(ring_sz, 0));
477                 if (!ring_base[nix->outb_se_ring_base + i]) {
478                         plt_err("Couldn't allocate memory for soft exp ring");
479                         while (i--)
480                                 plt_free(PLT_PTR_CAST(
481                                         ring_base[nix->outb_se_ring_base + i]));
482                         rc = -ENOMEM;
483                         goto lf_fini;
484                 }
485         }
486
487         return 0;
488
489 lf_fini:
490         for (j = i - 1; j >= 0; j--)
491                 cpt_lf_fini(&lf_base[j]);
492         plt_free(lf_base);
493 lf_free:
494         rc |= cpt_lfs_free(dev);
495 lf_detach:
496         rc |= cpt_lfs_detach(dev);
497         return rc;
498 }
499
500 int
501 roc_nix_inl_outb_fini(struct roc_nix *roc_nix)
502 {
503         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
504         struct roc_cpt_lf *lf_base = nix->cpt_lf_base;
505         struct idev_cfg *idev = idev_get_cfg();
506         struct dev *dev = &nix->dev;
507         struct nix_inl_dev *inl_dev;
508         uint64_t *ring_base;
509         int i, rc, ret = 0;
510
511         if (!nix->inl_outb_ena)
512                 return 0;
513
514         nix->inl_outb_ena = false;
515
516         /* Cleanup CPT LF instruction queue */
517         for (i = 0; i < nix->nb_cpt_lf; i++)
518                 cpt_lf_fini(&lf_base[i]);
519
520         /* Free LF resources */
521         rc = cpt_lfs_free(dev);
522         if (rc)
523                 plt_err("Failed to free CPT LF resources, rc=%d", rc);
524         ret |= rc;
525
526         /* Detach LF */
527         rc = cpt_lfs_detach(dev);
528         if (rc)
529                 plt_err("Failed to detach CPT LF, rc=%d", rc);
530
531         /* Free LF memory */
532         plt_free(lf_base);
533         nix->cpt_lf_base = NULL;
534         nix->nb_cpt_lf = 0;
535
536         /* Free outbound SA base */
537         plt_free(nix->outb_sa_base);
538         nix->outb_sa_base = NULL;
539
540         if (idev && idev->nix_inl_dev) {
541                 inl_dev = idev->nix_inl_dev;
542                 ring_base = inl_dev->sa_soft_exp_ring;
543
544                 for (i = 0; i < ROC_NIX_INL_MAX_SOFT_EXP_RNGS; i++) {
545                         if (ring_base[i])
546                                 plt_free(PLT_PTR_CAST(ring_base[i]));
547                 }
548         }
549
550         ret |= rc;
551         return ret;
552 }
553
554 bool
555 roc_nix_inl_dev_is_probed(void)
556 {
557         struct idev_cfg *idev = idev_get_cfg();
558
559         if (idev == NULL)
560                 return 0;
561
562         return !!idev->nix_inl_dev;
563 }
564
565 bool
566 roc_nix_inl_inb_is_enabled(struct roc_nix *roc_nix)
567 {
568         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
569
570         return nix->inl_inb_ena;
571 }
572
573 bool
574 roc_nix_inl_outb_is_enabled(struct roc_nix *roc_nix)
575 {
576         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
577
578         return nix->inl_outb_ena;
579 }
580
581 int
582 roc_nix_inl_dev_rq_get(struct roc_nix_rq *rq)
583 {
584         struct idev_cfg *idev = idev_get_cfg();
585         struct nix_inl_dev *inl_dev;
586         struct roc_nix_rq *inl_rq;
587         struct dev *dev;
588         int rc;
589
590         if (idev == NULL)
591                 return 0;
592
593         inl_dev = idev->nix_inl_dev;
594         /* Nothing to do if no inline device */
595         if (!inl_dev)
596                 return 0;
597
598         /* Just take reference if already inited */
599         if (inl_dev->rq_refs) {
600                 inl_dev->rq_refs++;
601                 rq->inl_dev_ref = true;
602                 return 0;
603         }
604
605         dev = &inl_dev->dev;
606         inl_rq = &inl_dev->rq;
607         memset(inl_rq, 0, sizeof(struct roc_nix_rq));
608
609         /* Take RQ pool attributes from the first ethdev RQ */
610         inl_rq->qid = 0;
611         inl_rq->aura_handle = rq->aura_handle;
612         inl_rq->first_skip = rq->first_skip;
613         inl_rq->later_skip = rq->later_skip;
614         inl_rq->lpb_size = rq->lpb_size;
615         inl_rq->lpb_drop_ena = true;
616         inl_rq->spb_ena = rq->spb_ena;
617         inl_rq->spb_aura_handle = rq->spb_aura_handle;
618         inl_rq->spb_size = rq->spb_size;
619         inl_rq->spb_drop_ena = !!rq->spb_ena;
620
621         if (!roc_model_is_cn9k()) {
622                 uint64_t aura_limit =
623                         roc_npa_aura_op_limit_get(inl_rq->aura_handle);
624                 uint64_t aura_shift = plt_log2_u32(aura_limit);
625                 uint64_t aura_drop, drop_pc;
626
627                 if (aura_shift < 8)
628                         aura_shift = 0;
629                 else
630                         aura_shift = aura_shift - 8;
631
632                 /* Set first pass RQ to drop after part of buffers are in
633                  * use to avoid metabuf alloc failure. This is needed as long
634                  * as we cannot use different aura.
635                  */
636                 drop_pc = inl_dev->lpb_drop_pc;
637                 aura_drop = ((aura_limit * drop_pc) / 100) >> aura_shift;
638                 roc_npa_aura_drop_set(inl_rq->aura_handle, aura_drop, true);
639         }
640
641         if (inl_rq->spb_ena) {
642                 uint64_t aura_limit =
643                         roc_npa_aura_op_limit_get(inl_rq->spb_aura_handle);
644                 uint64_t aura_shift = plt_log2_u32(aura_limit);
645                 uint64_t aura_drop, drop_pc;
646
647                 if (aura_shift < 8)
648                         aura_shift = 0;
649                 else
650                         aura_shift = aura_shift - 8;
651
652                 /* Set first pass RQ to drop after part of buffers are in
653                  * use to avoid metabuf alloc failure. This is needed as long
654                  * as we cannot use different aura.
655                  */
656                 drop_pc = inl_dev->spb_drop_pc;
657                 aura_drop = ((aura_limit * drop_pc) / 100) >> aura_shift;
658                 roc_npa_aura_drop_set(inl_rq->spb_aura_handle, aura_drop, true);
659         }
660
661         /* Enable IPSec */
662         inl_rq->ipsech_ena = true;
663
664         inl_rq->flow_tag_width = 20;
665         /* Special tag mask */
666         inl_rq->tag_mask = rq->tag_mask;
667         inl_rq->tt = SSO_TT_ORDERED;
668         inl_rq->hwgrp = 0;
669         inl_rq->wqe_skip = inl_dev->wqe_skip;
670         inl_rq->sso_ena = true;
671
672         /* Prepare and send RQ init mbox */
673         if (roc_model_is_cn9k())
674                 rc = nix_rq_cn9k_cfg(dev, inl_rq, inl_dev->qints, false, true);
675         else
676                 rc = nix_rq_cfg(dev, inl_rq, inl_dev->qints, false, true);
677         if (rc) {
678                 plt_err("Failed to prepare aq_enq msg, rc=%d", rc);
679                 return rc;
680         }
681
682         rc = mbox_process(dev->mbox);
683         if (rc) {
684                 plt_err("Failed to send aq_enq msg, rc=%d", rc);
685                 return rc;
686         }
687
688         inl_dev->rq_refs++;
689         rq->inl_dev_ref = true;
690         return 0;
691 }
692
693 int
694 roc_nix_inl_dev_rq_put(struct roc_nix_rq *rq)
695 {
696         struct idev_cfg *idev = idev_get_cfg();
697         struct nix_inl_dev *inl_dev;
698         struct roc_nix_rq *inl_rq;
699         struct dev *dev;
700         int rc;
701
702         if (idev == NULL)
703                 return 0;
704
705         if (!rq->inl_dev_ref)
706                 return 0;
707
708         inl_dev = idev->nix_inl_dev;
709         /* Inline device should be there if we have ref */
710         if (!inl_dev) {
711                 plt_err("Failed to find inline device with refs");
712                 return -EFAULT;
713         }
714
715         rq->inl_dev_ref = false;
716         inl_dev->rq_refs--;
717         if (inl_dev->rq_refs)
718                 return 0;
719
720         dev = &inl_dev->dev;
721         inl_rq = &inl_dev->rq;
722         /* There are no more references, disable RQ */
723         rc = nix_rq_ena_dis(dev, inl_rq, false);
724         if (rc)
725                 plt_err("Failed to disable inline device rq, rc=%d", rc);
726
727         roc_npa_aura_drop_set(inl_rq->aura_handle, 0, false);
728         if (inl_rq->spb_ena)
729                 roc_npa_aura_drop_set(inl_rq->spb_aura_handle, 0, false);
730
731         /* Flush NIX LF for CN10K */
732         nix_rq_vwqe_flush(rq, inl_dev->vwqe_interval);
733
734         return rc;
735 }
736
737 uint64_t
738 roc_nix_inl_dev_rq_limit_get(void)
739 {
740         struct idev_cfg *idev = idev_get_cfg();
741         struct nix_inl_dev *inl_dev;
742         struct roc_nix_rq *inl_rq;
743
744         if (!idev || !idev->nix_inl_dev)
745                 return 0;
746
747         inl_dev = idev->nix_inl_dev;
748         if (!inl_dev->rq_refs)
749                 return 0;
750
751         inl_rq = &inl_dev->rq;
752
753         return roc_npa_aura_op_limit_get(inl_rq->aura_handle);
754 }
755
756 void
757 roc_nix_inb_mode_set(struct roc_nix *roc_nix, bool use_inl_dev)
758 {
759         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
760
761         /* Info used by NPC flow rule add */
762         nix->inb_inl_dev = use_inl_dev;
763 }
764
765 int
766 roc_nix_inl_outb_soft_exp_poll_switch(struct roc_nix *roc_nix, bool poll)
767 {
768         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
769         struct idev_cfg *idev = idev_get_cfg();
770         struct nix_inl_dev *inl_dev;
771         uint16_t ring_idx, i;
772
773         if (!idev || !idev->nix_inl_dev)
774                 return 0;
775
776         inl_dev = idev->nix_inl_dev;
777
778         for (i = 0; i < nix->outb_se_ring_cnt; i++) {
779                 ring_idx = nix->outb_se_ring_base + i;
780
781                 if (poll)
782                         plt_bitmap_set(inl_dev->soft_exp_ring_bmap, ring_idx);
783                 else
784                         plt_bitmap_clear(inl_dev->soft_exp_ring_bmap, ring_idx);
785         }
786
787         if (poll)
788                 soft_exp_consumer_cnt++;
789         else
790                 soft_exp_consumer_cnt--;
791
792         return 0;
793 }
794
795 bool
796 roc_nix_inb_is_with_inl_dev(struct roc_nix *roc_nix)
797 {
798         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
799
800         return nix->inb_inl_dev;
801 }
802
803 struct roc_nix_rq *
804 roc_nix_inl_dev_rq(void)
805 {
806         struct idev_cfg *idev = idev_get_cfg();
807         struct nix_inl_dev *inl_dev;
808
809         if (idev != NULL) {
810                 inl_dev = idev->nix_inl_dev;
811                 if (inl_dev != NULL && inl_dev->rq_refs)
812                         return &inl_dev->rq;
813         }
814
815         return NULL;
816 }
817
818 uint16_t __roc_api
819 roc_nix_inl_outb_sso_pffunc_get(struct roc_nix *roc_nix)
820 {
821         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
822
823         return nix->outb_err_sso_pffunc;
824 }
825
826 int
827 roc_nix_inl_cb_register(roc_nix_inl_sso_work_cb_t cb, void *args)
828 {
829         struct idev_cfg *idev = idev_get_cfg();
830         struct nix_inl_dev *inl_dev;
831
832         if (idev == NULL)
833                 return -EIO;
834
835         inl_dev = idev->nix_inl_dev;
836         if (!inl_dev)
837                 return -EIO;
838
839         /* Be silent if registration called with same cb and args */
840         if (inl_dev->work_cb == cb && inl_dev->cb_args == args)
841                 return 0;
842
843         /* Don't allow registration again if registered with different cb */
844         if (inl_dev->work_cb)
845                 return -EBUSY;
846
847         inl_dev->work_cb = cb;
848         inl_dev->cb_args = args;
849         return 0;
850 }
851
852 int
853 roc_nix_inl_cb_unregister(roc_nix_inl_sso_work_cb_t cb, void *args)
854 {
855         struct idev_cfg *idev = idev_get_cfg();
856         struct nix_inl_dev *inl_dev;
857
858         if (idev == NULL)
859                 return -ENOENT;
860
861         inl_dev = idev->nix_inl_dev;
862         if (!inl_dev)
863                 return -ENOENT;
864
865         if (inl_dev->work_cb != cb || inl_dev->cb_args != args)
866                 return -EINVAL;
867
868         inl_dev->work_cb = NULL;
869         inl_dev->cb_args = NULL;
870         return 0;
871 }
872
873 int
874 roc_nix_inl_inb_tag_update(struct roc_nix *roc_nix, uint32_t tag_const,
875                            uint8_t tt)
876 {
877         struct nix *nix = roc_nix_to_nix_priv(roc_nix);
878         struct roc_nix_ipsec_cfg cfg;
879
880         /* Be silent if inline inbound not enabled */
881         if (!nix->inl_inb_ena)
882                 return 0;
883
884         memset(&cfg, 0, sizeof(cfg));
885         cfg.sa_size = nix->inb_sa_sz;
886         cfg.iova = (uintptr_t)nix->inb_sa_base;
887         cfg.max_sa = nix->inb_spi_mask + 1;
888         cfg.tt = tt;
889         cfg.tag_const = tag_const;
890
891         return roc_nix_lf_inl_ipsec_cfg(roc_nix, &cfg, true);
892 }
893
894 int
895 roc_nix_inl_sa_sync(struct roc_nix *roc_nix, void *sa, bool inb,
896                     enum roc_nix_inl_sa_sync_op op)
897 {
898         struct idev_cfg *idev = idev_get_cfg();
899         struct nix_inl_dev *inl_dev = NULL;
900         struct roc_cpt_lf *outb_lf = NULL;
901         union cpt_lf_ctx_reload reload;
902         union cpt_lf_ctx_flush flush;
903         bool get_inl_lf = true;
904         uintptr_t rbase;
905         struct nix *nix;
906
907         /* Nothing much to do on cn9k */
908         if (roc_model_is_cn9k()) {
909                 plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
910                 return 0;
911         }
912
913         if (idev)
914                 inl_dev = idev->nix_inl_dev;
915
916         if (!inl_dev && roc_nix == NULL)
917                 return -EINVAL;
918
919         if (roc_nix) {
920                 nix = roc_nix_to_nix_priv(roc_nix);
921                 outb_lf = nix->cpt_lf_base;
922                 if (inb && !nix->inb_inl_dev)
923                         get_inl_lf = false;
924         }
925
926         if (inb && get_inl_lf) {
927                 outb_lf = NULL;
928                 if (inl_dev && inl_dev->attach_cptlf)
929                         outb_lf = &inl_dev->cpt_lf;
930         }
931
932         if (outb_lf) {
933                 rbase = outb_lf->rbase;
934
935                 flush.u = 0;
936                 reload.u = 0;
937                 switch (op) {
938                 case ROC_NIX_INL_SA_OP_FLUSH_INVAL:
939                         flush.s.inval = 1;
940                         /* fall through */
941                 case ROC_NIX_INL_SA_OP_FLUSH:
942                         flush.s.cptr = ((uintptr_t)sa) >> 7;
943                         plt_write64(flush.u, rbase + CPT_LF_CTX_FLUSH);
944                         break;
945                 case ROC_NIX_INL_SA_OP_RELOAD:
946                         reload.s.cptr = ((uintptr_t)sa) >> 7;
947                         plt_write64(reload.u, rbase + CPT_LF_CTX_RELOAD);
948                         break;
949                 default:
950                         return -EINVAL;
951                 }
952                 return 0;
953         }
954         plt_err("Could not get CPT LF for SA sync");
955         return -ENOTSUP;
956 }
957
958 int
959 roc_nix_inl_ctx_write(struct roc_nix *roc_nix, void *sa_dptr, void *sa_cptr,
960                       bool inb, uint16_t sa_len)
961 {
962         struct idev_cfg *idev = idev_get_cfg();
963         struct nix_inl_dev *inl_dev = NULL;
964         struct roc_cpt_lf *outb_lf = NULL;
965         union cpt_lf_ctx_flush flush;
966         bool get_inl_lf = true;
967         uintptr_t rbase;
968         struct nix *nix;
969         int rc;
970
971         /* Nothing much to do on cn9k */
972         if (roc_model_is_cn9k()) {
973                 plt_atomic_thread_fence(__ATOMIC_ACQ_REL);
974                 return 0;
975         }
976
977         if (idev)
978                 inl_dev = idev->nix_inl_dev;
979
980         if (!inl_dev && roc_nix == NULL)
981                 return -EINVAL;
982
983         if (roc_nix) {
984                 nix = roc_nix_to_nix_priv(roc_nix);
985                 outb_lf = nix->cpt_lf_base;
986
987                 if (inb && !nix->inb_inl_dev)
988                         get_inl_lf = false;
989         }
990
991         if (inb && get_inl_lf) {
992                 outb_lf = NULL;
993                 if (inl_dev && inl_dev->attach_cptlf)
994                         outb_lf = &inl_dev->cpt_lf;
995         }
996
997         if (outb_lf) {
998                 rbase = outb_lf->rbase;
999                 flush.u = 0;
1000
1001                 rc = roc_cpt_ctx_write(outb_lf, sa_dptr, sa_cptr, sa_len);
1002                 if (rc)
1003                         return rc;
1004                 /* Trigger CTX flush to write dirty data back to DRAM */
1005                 flush.s.cptr = ((uintptr_t)sa_cptr) >> 7;
1006                 plt_write64(flush.u, rbase + CPT_LF_CTX_FLUSH);
1007
1008                 return 0;
1009         }
1010         plt_nix_dbg("Could not get CPT LF for CTX write");
1011         return -ENOTSUP;
1012 }
1013
1014 void
1015 roc_nix_inl_dev_lock(void)
1016 {
1017         struct idev_cfg *idev = idev_get_cfg();
1018
1019         if (idev != NULL)
1020                 plt_spinlock_lock(&idev->nix_inl_dev_lock);
1021 }
1022
1023 void
1024 roc_nix_inl_dev_unlock(void)
1025 {
1026         struct idev_cfg *idev = idev_get_cfg();
1027
1028         if (idev != NULL)
1029                 plt_spinlock_unlock(&idev->nix_inl_dev_lock);
1030 }