Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <cnxk_ethdev.h>
6 : : #include <cnxk_mempool.h>
7 : :
8 : : #define CNXK_NIX_INL_META_POOL_NAME "NIX_INL_META_POOL"
9 : : #define CN10K_HW_POOL_OPS_NAME "cn10k_hwpool_ops"
10 : :
11 : : #define CNXK_NIX_INL_SELFTEST "selftest"
12 : : #define CNXK_NIX_INL_IPSEC_IN_MIN_SPI "ipsec_in_min_spi"
13 : : #define CNXK_NIX_INL_IPSEC_IN_MAX_SPI "ipsec_in_max_spi"
14 : : #define CNXK_INL_CPT_CHANNEL "inl_cpt_channel"
15 : : #define CNXK_NIX_INL_NB_META_BUFS "nb_meta_bufs"
16 : : #define CNXK_NIX_INL_META_BUF_SZ "meta_buf_sz"
17 : : #define CNXK_NIX_SOFT_EXP_POLL_FREQ "soft_exp_poll_freq"
18 : : #define CNXK_MAX_IPSEC_RULES "max_ipsec_rules"
19 : :
20 : : /* Default soft expiry poll freq in usec */
21 : : #define CNXK_NIX_SOFT_EXP_POLL_FREQ_DFLT 100
22 : :
23 : : struct inl_cpt_channel {
24 : : bool is_multi_channel;
25 : : uint16_t channel;
26 : : uint16_t mask;
27 : : };
28 : :
29 : : #define CNXK_NIX_INL_DEV_NAME RTE_STR(cnxk_nix_inl_dev_)
30 : : #define CNXK_NIX_INL_DEV_NAME_LEN \
31 : : (sizeof(CNXK_NIX_INL_DEV_NAME) + PCI_PRI_STR_SIZE)
32 : :
33 : : static inline int
34 : : bitmap_ctzll(uint64_t slab)
35 : : {
36 : 0 : if (slab == 0)
37 : : return 0;
38 : :
39 : 0 : return rte_ctz64(slab);
40 : : }
41 : :
42 : : int
43 : 0 : cnxk_nix_inl_meta_pool_cb(uint64_t *aura_handle, uintptr_t *mpool, uint32_t buf_sz,
44 : : uint32_t nb_bufs, bool destroy, const char *mempool_name)
45 : : {
46 : : const char *mp_name = NULL;
47 : : struct rte_pktmbuf_pool_private mbp_priv;
48 : : struct rte_mempool *mp;
49 : : uint16_t first_skip;
50 : : int rc;
51 : :
52 : : /* Null Mempool name indicates to allocate Zero aura. */
53 [ # # ]: 0 : if (!mempool_name)
54 : : mp_name = CNXK_NIX_INL_META_POOL_NAME;
55 : : else
56 : : mp_name = mempool_name;
57 : :
58 : : /* Destroy the mempool if requested */
59 [ # # ]: 0 : if (destroy) {
60 : 0 : mp = rte_mempool_lookup(mp_name);
61 [ # # ]: 0 : if (!mp)
62 : : return -ENOENT;
63 : :
64 [ # # ]: 0 : if (mp->pool_id != *aura_handle) {
65 : 0 : plt_err("Meta pool aura mismatch");
66 : 0 : return -EINVAL;
67 : : }
68 : :
69 : 0 : rte_mempool_free(mp);
70 : :
71 : 0 : *aura_handle = 0;
72 : 0 : *mpool = 0;
73 : 0 : return 0;
74 : : }
75 : :
76 : : /* Need to make it similar to rte_pktmbuf_pool() for sake of OOP
77 : : * support.
78 : : */
79 : 0 : mp = rte_mempool_create_empty(mp_name, nb_bufs, buf_sz, 0,
80 : : sizeof(struct rte_pktmbuf_pool_private),
81 : : SOCKET_ID_ANY, 0);
82 [ # # ]: 0 : if (!mp) {
83 : 0 : plt_err("Failed to create inline meta pool");
84 : 0 : return -EIO;
85 : : }
86 : :
87 [ # # ]: 0 : rc = rte_mempool_set_ops_byname(mp, rte_mbuf_platform_mempool_ops(),
88 : : mempool_name ?
89 : : NULL : PLT_PTR_CAST(CNXK_MEMPOOL_F_ZERO_AURA));
90 [ # # ]: 0 : if (rc) {
91 : 0 : plt_err("Failed to setup mempool ops for meta, rc=%d", rc);
92 : 0 : goto free_mp;
93 : : }
94 : :
95 : : /* Init mempool private area */
96 : : first_skip = sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM;
97 : : memset(&mbp_priv, 0, sizeof(mbp_priv));
98 : 0 : mbp_priv.mbuf_data_room_size = (buf_sz - first_skip +
99 : : RTE_PKTMBUF_HEADROOM);
100 : 0 : rte_pktmbuf_pool_init(mp, &mbp_priv);
101 : :
102 : : /* Populate buffer */
103 : 0 : rc = rte_mempool_populate_default(mp);
104 [ # # ]: 0 : if (rc < 0) {
105 : 0 : plt_err("Failed to create inline meta pool, rc=%d", rc);
106 : 0 : goto free_mp;
107 : : }
108 : :
109 : 0 : rte_mempool_obj_iter(mp, rte_pktmbuf_init, NULL);
110 : 0 : *aura_handle = mp->pool_id;
111 : 0 : *mpool = (uintptr_t)mp;
112 : 0 : return 0;
113 : 0 : free_mp:
114 : 0 : rte_mempool_free(mp);
115 : 0 : return rc;
116 : : }
117 : :
118 : : /* Create Aura and link with Global mempool for 1:N Pool:Aura case */
119 : : int
120 : 0 : cnxk_nix_inl_custom_meta_pool_cb(uintptr_t pmpool, uintptr_t *mpool, const char *mempool_name,
121 : : uint64_t *aura_handle, uint32_t buf_sz, uint32_t nb_bufs,
122 : : bool destroy)
123 : : {
124 : : struct rte_mempool *hp;
125 : : int rc;
126 : :
127 : : /* Destroy the mempool if requested */
128 [ # # ]: 0 : if (destroy) {
129 : 0 : hp = rte_mempool_lookup(mempool_name);
130 [ # # ]: 0 : if (!hp)
131 : : return -ENOENT;
132 : :
133 [ # # ]: 0 : if (hp->pool_id != *aura_handle) {
134 : 0 : plt_err("Meta pool aura mismatch");
135 : 0 : return -EINVAL;
136 : : }
137 : :
138 : 0 : rte_mempool_free(hp);
139 : 0 : plt_free(hp->pool_config);
140 : :
141 : 0 : *aura_handle = 0;
142 : 0 : *mpool = 0;
143 : 0 : return 0;
144 : : }
145 : :
146 : : /* Need to make it similar to rte_pktmbuf_pool() for sake of OOP
147 : : * support.
148 : : */
149 : 0 : hp = rte_mempool_create_empty(mempool_name, nb_bufs, buf_sz, 0,
150 : : sizeof(struct rte_pktmbuf_pool_private),
151 : : SOCKET_ID_ANY, 0);
152 [ # # ]: 0 : if (!hp) {
153 : 0 : plt_err("Failed to create inline meta pool");
154 : 0 : return -EIO;
155 : : }
156 : :
157 : 0 : rc = rte_mempool_set_ops_byname(hp, CN10K_HW_POOL_OPS_NAME, (void *)pmpool);
158 : :
159 [ # # ]: 0 : if (rc) {
160 : 0 : plt_err("Failed to setup ops, rc=%d", rc);
161 : 0 : goto free_hp;
162 : : }
163 : :
164 : : /* Populate buffer */
165 : 0 : rc = rte_mempool_populate_default(hp);
166 [ # # ]: 0 : if (rc < 0) {
167 : 0 : plt_err("Failed to populate pool, rc=%d", rc);
168 : 0 : goto free_hp;
169 : : }
170 : :
171 : 0 : *aura_handle = hp->pool_id;
172 : 0 : *mpool = (uintptr_t)hp;
173 : 0 : return 0;
174 : 0 : free_hp:
175 : 0 : rte_mempool_free(hp);
176 : 0 : return rc;
177 : : }
178 : :
179 : : static int
180 : 0 : parse_max_ipsec_rules(const char *key, const char *value, void *extra_args)
181 : : {
182 : : RTE_SET_USED(key);
183 : : uint32_t val;
184 : :
185 : 0 : val = atoi(value);
186 : :
187 [ # # ]: 0 : if (val < 1 || val > 4095)
188 : : return -EINVAL;
189 : :
190 : 0 : *(uint32_t *)extra_args = val;
191 : :
192 : 0 : return 0;
193 : : }
194 : :
195 : : int
196 : 0 : cnxk_eth_outb_sa_idx_get(struct cnxk_eth_dev *dev, uint32_t *idx_p,
197 : : uint32_t spi)
198 : : {
199 : : uint32_t pos, idx;
200 : : uint64_t slab;
201 : : int rc;
202 : :
203 [ # # ]: 0 : if (!dev->outb.sa_bmap)
204 : : return -ENOTSUP;
205 : :
206 : 0 : pos = 0;
207 [ # # ]: 0 : slab = 0;
208 : : /* Scan from the beginning */
209 : : plt_bitmap_scan_init(dev->outb.sa_bmap);
210 : :
211 [ # # ]: 0 : if (dev->nix.custom_sa_action) {
212 [ # # ]: 0 : if (spi > dev->outb.max_sa)
213 : : return -ENOTSUP;
214 : : idx = spi;
215 : : } else {
216 : : /* Scan bitmap to get the free sa index */
217 : 0 : rc = plt_bitmap_scan(dev->outb.sa_bmap, &pos, &slab);
218 : : /* Empty bitmap */
219 [ # # ]: 0 : if (rc == 0) {
220 : 0 : plt_err("Outbound SA' exhausted, use 'ipsec_out_max_sa' "
221 : : "devargs to increase");
222 : 0 : return -ERANGE;
223 : : }
224 : :
225 : : /* Get free SA index */
226 [ # # ]: 0 : idx = pos + bitmap_ctzll(slab);
227 : : }
228 : 0 : plt_bitmap_clear(dev->outb.sa_bmap, idx);
229 : 0 : *idx_p = idx;
230 : 0 : return 0;
231 : : }
232 : :
233 : : int
234 : 0 : cnxk_eth_outb_sa_idx_put(struct cnxk_eth_dev *dev, uint32_t idx)
235 : : {
236 [ # # ]: 0 : if (idx >= dev->outb.max_sa)
237 : : return -EINVAL;
238 : :
239 : : /* Check if it is already free */
240 [ # # ]: 0 : if (plt_bitmap_get(dev->outb.sa_bmap, idx))
241 : : return -EINVAL;
242 : :
243 : : /* Mark index as free */
244 : 0 : plt_bitmap_set(dev->outb.sa_bmap, idx);
245 : 0 : return 0;
246 : : }
247 : :
248 : : struct cnxk_eth_sec_sess *
249 : 0 : cnxk_eth_sec_sess_get_by_spi(struct cnxk_eth_dev *dev, uint32_t spi, bool inb)
250 : : {
251 : : struct cnxk_eth_sec_sess_list *list;
252 : : struct cnxk_eth_sec_sess *eth_sec;
253 : :
254 [ # # ]: 0 : list = inb ? &dev->inb.list : &dev->outb.list;
255 [ # # ]: 0 : TAILQ_FOREACH(eth_sec, list, entry) {
256 [ # # ]: 0 : if (eth_sec->spi == spi)
257 : 0 : return eth_sec;
258 : : }
259 : :
260 : : return NULL;
261 : : }
262 : :
263 : : struct cnxk_eth_sec_sess *
264 : 0 : cnxk_eth_sec_sess_get_by_sess(struct cnxk_eth_dev *dev,
265 : : struct rte_security_session *sess)
266 : : {
267 : : struct cnxk_eth_sec_sess *eth_sec = NULL;
268 : :
269 : : /* Search in inbound list */
270 [ # # ]: 0 : TAILQ_FOREACH(eth_sec, &dev->inb.list, entry) {
271 [ # # ]: 0 : if (eth_sec->sess == sess)
272 : 0 : return eth_sec;
273 : : }
274 : :
275 : : /* Search in outbound list */
276 [ # # ]: 0 : TAILQ_FOREACH(eth_sec, &dev->outb.list, entry) {
277 [ # # ]: 0 : if (eth_sec->sess == sess)
278 : 0 : return eth_sec;
279 : : }
280 : :
281 : : return NULL;
282 : : }
283 : :
284 : : static unsigned int
285 : 0 : cnxk_eth_sec_session_get_size(void *device __rte_unused)
286 : : {
287 : 0 : return RTE_MAX(sizeof(struct cnxk_macsec_sess), sizeof(struct cnxk_eth_sec_sess));
288 : : }
289 : :
290 : : struct rte_security_ops cnxk_eth_sec_ops = {
291 : : .session_get_size = cnxk_eth_sec_session_get_size
292 : : };
293 : :
294 : : static int
295 : 0 : parse_val_u32(const char *key, const char *value, void *extra_args)
296 : : {
297 : : RTE_SET_USED(key);
298 : : uint32_t val;
299 : :
300 : 0 : errno = 0;
301 : 0 : val = strtoul(value, NULL, 0);
302 [ # # ]: 0 : if (errno)
303 : : val = 0;
304 : :
305 : 0 : *(uint32_t *)extra_args = val;
306 : :
307 : 0 : return 0;
308 : : }
309 : :
310 : : static int
311 : 0 : parse_selftest(const char *key, const char *value, void *extra_args)
312 : : {
313 : : RTE_SET_USED(key);
314 : : uint32_t val;
315 : :
316 : 0 : val = atoi(value);
317 : :
318 : 0 : *(uint8_t *)extra_args = !!(val == 1);
319 : 0 : return 0;
320 : : }
321 : :
322 : : static int
323 : 0 : parse_inl_cpt_channel(const char *key, const char *value, void *extra_args)
324 : : {
325 : : RTE_SET_USED(key);
326 : : uint16_t chan = 0, mask = 0;
327 : 0 : char *next = 0;
328 : :
329 : : /* next will point to the separator '/' */
330 : 0 : chan = strtol(value, &next, 16);
331 : 0 : mask = strtol(++next, 0, 16);
332 : :
333 [ # # ]: 0 : if (chan > GENMASK(12, 0) || mask > GENMASK(12, 0))
334 : : return -EINVAL;
335 : :
336 : 0 : ((struct inl_cpt_channel *)extra_args)->channel = chan;
337 : 0 : ((struct inl_cpt_channel *)extra_args)->mask = mask;
338 : 0 : ((struct inl_cpt_channel *)extra_args)->is_multi_channel = true;
339 : :
340 : 0 : return 0;
341 : : }
342 : :
343 : : static int
344 : 0 : nix_inl_parse_devargs(struct rte_devargs *devargs,
345 : : struct roc_nix_inl_dev *inl_dev)
346 : : {
347 : 0 : uint32_t soft_exp_poll_freq = CNXK_NIX_SOFT_EXP_POLL_FREQ_DFLT;
348 : 0 : uint32_t ipsec_in_max_spi = BIT(8) - 1;
349 : 0 : uint32_t ipsec_in_min_spi = 0;
350 : : struct inl_cpt_channel cpt_channel;
351 : 0 : uint32_t max_ipsec_rules = 0;
352 : : struct rte_kvargs *kvlist;
353 : 0 : uint32_t nb_meta_bufs = 0;
354 : 0 : uint32_t meta_buf_sz = 0;
355 [ # # ]: 0 : uint8_t selftest = 0;
356 : :
357 : : memset(&cpt_channel, 0, sizeof(cpt_channel));
358 : :
359 [ # # ]: 0 : if (devargs == NULL)
360 : 0 : goto null_devargs;
361 : :
362 : 0 : kvlist = rte_kvargs_parse(devargs->args, NULL);
363 [ # # ]: 0 : if (kvlist == NULL)
364 : 0 : goto exit;
365 : :
366 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_SELFTEST, &parse_selftest,
367 : : &selftest);
368 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_IPSEC_IN_MIN_SPI,
369 : : &parse_val_u32, &ipsec_in_min_spi);
370 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_IPSEC_IN_MAX_SPI,
371 : : &parse_val_u32, &ipsec_in_max_spi);
372 : 0 : rte_kvargs_process(kvlist, CNXK_INL_CPT_CHANNEL, &parse_inl_cpt_channel,
373 : : &cpt_channel);
374 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_NB_META_BUFS, &parse_val_u32,
375 : : &nb_meta_bufs);
376 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_META_BUF_SZ, &parse_val_u32,
377 : : &meta_buf_sz);
378 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_SOFT_EXP_POLL_FREQ,
379 : : &parse_val_u32, &soft_exp_poll_freq);
380 : 0 : rte_kvargs_process(kvlist, CNXK_MAX_IPSEC_RULES, &parse_max_ipsec_rules, &max_ipsec_rules);
381 : 0 : rte_kvargs_free(kvlist);
382 : :
383 : 0 : null_devargs:
384 : 0 : inl_dev->ipsec_in_min_spi = ipsec_in_min_spi;
385 : 0 : inl_dev->ipsec_in_max_spi = ipsec_in_max_spi;
386 : 0 : inl_dev->selftest = selftest;
387 : 0 : inl_dev->channel = cpt_channel.channel;
388 : 0 : inl_dev->chan_mask = cpt_channel.mask;
389 : 0 : inl_dev->is_multi_channel = cpt_channel.is_multi_channel;
390 : 0 : inl_dev->nb_meta_bufs = nb_meta_bufs;
391 : 0 : inl_dev->meta_buf_sz = meta_buf_sz;
392 : 0 : inl_dev->soft_exp_poll_freq = soft_exp_poll_freq;
393 : 0 : inl_dev->max_ipsec_rules = max_ipsec_rules;
394 : 0 : return 0;
395 : : exit:
396 : 0 : return -EINVAL;
397 : : }
398 : :
399 : : static inline char *
400 : 0 : nix_inl_dev_to_name(struct rte_pci_device *pci_dev, char *name)
401 : : {
402 : 0 : snprintf(name, CNXK_NIX_INL_DEV_NAME_LEN,
403 : : CNXK_NIX_INL_DEV_NAME PCI_PRI_FMT, pci_dev->addr.domain,
404 : 0 : pci_dev->addr.bus, pci_dev->addr.devid,
405 : 0 : pci_dev->addr.function);
406 : :
407 : 0 : return name;
408 : : }
409 : :
410 : : static int
411 : 0 : cnxk_nix_inl_dev_remove(struct rte_pci_device *pci_dev)
412 : : {
413 : : char name[CNXK_NIX_INL_DEV_NAME_LEN];
414 : : const struct rte_memzone *mz;
415 : : struct roc_nix_inl_dev *dev;
416 : : int rc;
417 : :
418 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
419 : : return 0;
420 : :
421 : 0 : mz = rte_memzone_lookup(nix_inl_dev_to_name(pci_dev, name));
422 [ # # ]: 0 : if (!mz)
423 : : return 0;
424 : :
425 : 0 : dev = mz->addr;
426 : :
427 : : /* Cleanup inline dev */
428 : 0 : rc = roc_nix_inl_dev_fini(dev);
429 [ # # ]: 0 : if (rc) {
430 : 0 : plt_err("Failed to cleanup inl dev, rc=%d(%s)", rc,
431 : : roc_error_msg_get(rc));
432 : 0 : return rc;
433 : : }
434 : :
435 : 0 : rte_memzone_free(mz);
436 : 0 : return 0;
437 : : }
438 : :
439 : : static int
440 : 0 : cnxk_nix_inl_dev_probe(struct rte_pci_driver *pci_drv,
441 : : struct rte_pci_device *pci_dev)
442 : : {
443 : : char name[CNXK_NIX_INL_DEV_NAME_LEN];
444 : : struct roc_nix_inl_dev *inl_dev;
445 : : const struct rte_memzone *mz;
446 : : uint16_t wqe_skip;
447 : : int rc = -ENOMEM;
448 : :
449 : : RTE_SET_USED(pci_drv);
450 : :
451 : 0 : rc = roc_plt_init();
452 [ # # ]: 0 : if (rc) {
453 : 0 : plt_err("Failed to initialize platform model, rc=%d", rc);
454 : 0 : return rc;
455 : : }
456 : :
457 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
458 : : return 0;
459 : :
460 : 0 : mz = rte_memzone_reserve_aligned(nix_inl_dev_to_name(pci_dev, name),
461 : : sizeof(*inl_dev), SOCKET_ID_ANY, 0,
462 : : RTE_CACHE_LINE_SIZE);
463 [ # # ]: 0 : if (mz == NULL)
464 : : return rc;
465 : :
466 : 0 : inl_dev = mz->addr;
467 : 0 : inl_dev->pci_dev = pci_dev;
468 : :
469 : : /* Parse devargs string */
470 : 0 : rc = nix_inl_parse_devargs(pci_dev->device.devargs, inl_dev);
471 [ # # ]: 0 : if (rc) {
472 : 0 : plt_err("Failed to parse devargs rc=%d", rc);
473 : 0 : goto free_mem;
474 : : }
475 : :
476 : 0 : inl_dev->attach_cptlf = true;
477 : : /* WQE skip is one for DPDK */
478 : : wqe_skip = RTE_ALIGN_CEIL(sizeof(struct rte_mbuf), ROC_CACHE_LINE_SZ);
479 : : wqe_skip = wqe_skip / ROC_CACHE_LINE_SZ;
480 : 0 : inl_dev->wqe_skip = wqe_skip;
481 : 0 : rc = roc_nix_inl_dev_init(inl_dev);
482 [ # # ]: 0 : if (rc) {
483 : 0 : plt_err("Failed to init nix inl device, rc=%d(%s)", rc,
484 : : roc_error_msg_get(rc));
485 : 0 : goto free_mem;
486 : : }
487 : :
488 : : return 0;
489 : 0 : free_mem:
490 : 0 : rte_memzone_free(mz);
491 : 0 : return rc;
492 : : }
493 : :
494 : : static const struct rte_pci_id cnxk_nix_inl_pci_map[] = {
495 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_RVU_NIX_INL_PF)},
496 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_RVU_NIX_INL_VF)},
497 : : {
498 : : .vendor_id = 0,
499 : : },
500 : : };
501 : :
502 : : static struct rte_pci_driver cnxk_nix_inl_pci = {
503 : : .id_table = cnxk_nix_inl_pci_map,
504 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
505 : : .probe = cnxk_nix_inl_dev_probe,
506 : : .remove = cnxk_nix_inl_dev_remove,
507 : : };
508 : :
509 : 235 : RTE_PMD_REGISTER_PCI(cnxk_nix_inl, cnxk_nix_inl_pci);
510 : : RTE_PMD_REGISTER_PCI_TABLE(cnxk_nix_inl, cnxk_nix_inl_pci_map);
511 : : RTE_PMD_REGISTER_KMOD_DEP(cnxk_nix_inl, "vfio-pci");
512 : :
513 : : RTE_PMD_REGISTER_PARAM_STRING(cnxk_nix_inl,
514 : : CNXK_NIX_INL_SELFTEST "=1"
515 : : CNXK_NIX_INL_IPSEC_IN_MIN_SPI "=<1-U32_MAX>"
516 : : CNXK_NIX_INL_IPSEC_IN_MAX_SPI "=<1-U32_MAX>"
517 : : CNXK_INL_CPT_CHANNEL "=<1-4095>/<1-4095>"
518 : : CNXK_NIX_INL_NB_META_BUFS "=<1-U32_MAX>"
519 : : CNXK_NIX_INL_META_BUF_SZ "=<1-U32_MAX>"
520 : : CNXK_NIX_SOFT_EXP_POLL_FREQ "=<0-U32_MAX>"
521 : : CNXK_MAX_IPSEC_RULES "=<1-4095>");
|