Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <rte_pmd_cnxk.h>
6 : :
7 : : #include <cnxk_ethdev.h>
8 : : #include <cnxk_mempool.h>
9 : :
10 : : #define CNXK_NIX_INL_META_POOL_NAME "NIX_INL_META_POOL"
11 : : #define CN10K_HW_POOL_OPS_NAME "cn10k_hwpool_ops"
12 : :
13 : : #define CNXK_NIX_INL_SELFTEST "selftest"
14 : : #define CNXK_NIX_INL_IPSEC_IN_MIN_SPI "ipsec_in_min_spi"
15 : : #define CNXK_NIX_INL_IPSEC_IN_MAX_SPI "ipsec_in_max_spi"
16 : : #define CNXK_INL_CPT_CHANNEL "inl_cpt_channel"
17 : : #define CNXK_NIX_INL_NB_META_BUFS "nb_meta_bufs"
18 : : #define CNXK_NIX_INL_META_BUF_SZ "meta_buf_sz"
19 : : #define CNXK_NIX_SOFT_EXP_POLL_FREQ "soft_exp_poll_freq"
20 : : #define CNXK_MAX_IPSEC_RULES "max_ipsec_rules"
21 : : #define CNXK_NIX_INL_RX_INJ_ENABLE "rx_inj_ena"
22 : : #define CNXK_NIX_CUSTOM_INB_SA "custom_inb_sa"
23 : :
24 : : /* Default soft expiry poll freq in usec */
25 : : #define CNXK_NIX_SOFT_EXP_POLL_FREQ_DFLT 100
26 : :
27 : : struct inl_cpt_channel {
28 : : bool is_multi_channel;
29 : : uint16_t channel;
30 : : uint16_t mask;
31 : : };
32 : :
33 : : #define CNXK_NIX_INL_DEV_NAME RTE_STR(cnxk_nix_inl_dev_)
34 : : #define CNXK_NIX_INL_DEV_NAME_LEN \
35 : : (sizeof(CNXK_NIX_INL_DEV_NAME) + PCI_PRI_STR_SIZE)
36 : :
37 : : struct cnxk_ethdev_pmd_ops cnxk_pmd_ops;
38 : :
39 : : static inline int
40 : : bitmap_ctzll(uint64_t slab)
41 : : {
42 : 0 : if (slab == 0)
43 : : return 0;
44 : :
45 : 0 : return rte_ctz64(slab);
46 : : }
47 : :
48 : : int
49 : 0 : cnxk_nix_inl_meta_pool_cb(uint64_t *aura_handle, uintptr_t *mpool, uint32_t buf_sz,
50 : : uint32_t nb_bufs, bool destroy, const char *mempool_name)
51 : : {
52 : : const char *mp_name = NULL;
53 : : struct rte_pktmbuf_pool_private mbp_priv;
54 : : struct rte_mempool *mp;
55 : : uint16_t first_skip;
56 : : int rc;
57 : :
58 : : /* Null Mempool name indicates to allocate Zero aura. */
59 [ # # ]: 0 : if (!mempool_name)
60 : : mp_name = CNXK_NIX_INL_META_POOL_NAME;
61 : : else
62 : : mp_name = mempool_name;
63 : :
64 : : /* Destroy the mempool if requested */
65 [ # # ]: 0 : if (destroy) {
66 : 0 : mp = rte_mempool_lookup(mp_name);
67 [ # # ]: 0 : if (!mp)
68 : : return -ENOENT;
69 : :
70 [ # # ]: 0 : if (mp->pool_id != *aura_handle) {
71 : 0 : plt_err("Meta pool aura mismatch");
72 : 0 : return -EINVAL;
73 : : }
74 : :
75 : 0 : rte_mempool_free(mp);
76 : :
77 : 0 : *aura_handle = 0;
78 : 0 : *mpool = 0;
79 : 0 : return 0;
80 : : }
81 : :
82 : : /* Need to make it similar to rte_pktmbuf_pool() for sake of OOP
83 : : * support.
84 : : */
85 : 0 : mp = rte_mempool_create_empty(mp_name, nb_bufs, buf_sz, 0,
86 : : sizeof(struct rte_pktmbuf_pool_private),
87 : : SOCKET_ID_ANY, 0);
88 [ # # ]: 0 : if (!mp) {
89 : 0 : plt_err("Failed to create inline meta pool");
90 : 0 : return -EIO;
91 : : }
92 : :
93 [ # # ]: 0 : rc = rte_mempool_set_ops_byname(mp, rte_mbuf_platform_mempool_ops(),
94 : : mempool_name ?
95 : : NULL : PLT_PTR_CAST(CNXK_MEMPOOL_F_ZERO_AURA));
96 [ # # ]: 0 : if (rc) {
97 : 0 : plt_err("Failed to setup mempool ops for meta, rc=%d", rc);
98 : 0 : goto free_mp;
99 : : }
100 : :
101 : : /* Init mempool private area */
102 : : first_skip = sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM;
103 : : memset(&mbp_priv, 0, sizeof(mbp_priv));
104 : 0 : mbp_priv.mbuf_data_room_size = (buf_sz - first_skip +
105 : : RTE_PKTMBUF_HEADROOM);
106 : 0 : rte_pktmbuf_pool_init(mp, &mbp_priv);
107 : :
108 : : /* Populate buffer */
109 : 0 : rc = rte_mempool_populate_default(mp);
110 [ # # ]: 0 : if (rc < 0) {
111 : 0 : plt_err("Failed to create inline meta pool, rc=%d", rc);
112 : 0 : goto free_mp;
113 : : }
114 : :
115 : 0 : rte_mempool_obj_iter(mp, rte_pktmbuf_init, NULL);
116 : 0 : *aura_handle = mp->pool_id;
117 : 0 : *mpool = (uintptr_t)mp;
118 : 0 : return 0;
119 : 0 : free_mp:
120 : 0 : rte_mempool_free(mp);
121 : 0 : return rc;
122 : : }
123 : :
124 : : /* Create Aura and link with Global mempool for 1:N Pool:Aura case */
125 : : int
126 : 0 : cnxk_nix_inl_custom_meta_pool_cb(uintptr_t pmpool, uintptr_t *mpool, const char *mempool_name,
127 : : uint64_t *aura_handle, uint32_t buf_sz, uint32_t nb_bufs,
128 : : bool destroy)
129 : : {
130 : : struct rte_mempool *hp;
131 : : int rc;
132 : :
133 : : /* Destroy the mempool if requested */
134 [ # # ]: 0 : if (destroy) {
135 : 0 : hp = rte_mempool_lookup(mempool_name);
136 [ # # ]: 0 : if (!hp)
137 : : return -ENOENT;
138 : :
139 [ # # ]: 0 : if (hp->pool_id != *aura_handle) {
140 : 0 : plt_err("Meta pool aura mismatch");
141 : 0 : return -EINVAL;
142 : : }
143 : :
144 : 0 : plt_free(hp->pool_config);
145 : 0 : rte_mempool_free(hp);
146 : :
147 : 0 : *aura_handle = 0;
148 : 0 : *mpool = 0;
149 : 0 : return 0;
150 : : }
151 : :
152 : : /* Need to make it similar to rte_pktmbuf_pool() for sake of OOP
153 : : * support.
154 : : */
155 : 0 : hp = rte_mempool_create_empty(mempool_name, nb_bufs, buf_sz, 0,
156 : : sizeof(struct rte_pktmbuf_pool_private),
157 : : SOCKET_ID_ANY, 0);
158 [ # # ]: 0 : if (!hp) {
159 : 0 : plt_err("Failed to create inline meta pool");
160 : 0 : return -EIO;
161 : : }
162 : :
163 : 0 : rc = rte_mempool_set_ops_byname(hp, CN10K_HW_POOL_OPS_NAME, (void *)pmpool);
164 : :
165 [ # # ]: 0 : if (rc) {
166 : 0 : plt_err("Failed to setup ops, rc=%d", rc);
167 : 0 : goto free_hp;
168 : : }
169 : :
170 : : /* Populate buffer */
171 : 0 : rc = rte_mempool_populate_default(hp);
172 [ # # ]: 0 : if (rc < 0) {
173 : 0 : plt_err("Failed to populate pool, rc=%d", rc);
174 : 0 : goto free_hp;
175 : : }
176 : :
177 : 0 : *aura_handle = hp->pool_id;
178 : 0 : *mpool = (uintptr_t)hp;
179 : 0 : return 0;
180 : 0 : free_hp:
181 : 0 : rte_mempool_free(hp);
182 : 0 : return rc;
183 : : }
184 : :
185 : : static int
186 : 0 : parse_max_ipsec_rules(const char *key, const char *value, void *extra_args)
187 : : {
188 : : RTE_SET_USED(key);
189 : : uint32_t val;
190 : :
191 : 0 : val = atoi(value);
192 : :
193 [ # # ]: 0 : if (val < 1 || val > 4095)
194 : : return -EINVAL;
195 : :
196 : 0 : *(uint32_t *)extra_args = val;
197 : :
198 : 0 : return 0;
199 : : }
200 : :
201 : : static int
202 : 0 : parse_val_u8(const char *key, const char *value, void *extra_args)
203 : : {
204 : : RTE_SET_USED(key);
205 : : uint32_t val;
206 : :
207 : 0 : val = atoi(value);
208 : :
209 : 0 : *(uint8_t *)extra_args = !!(val == 1);
210 : :
211 : 0 : return 0;
212 : : }
213 : :
214 : : int
215 : 0 : cnxk_eth_outb_sa_idx_get(struct cnxk_eth_dev *dev, uint32_t *idx_p,
216 : : uint32_t spi)
217 : : {
218 : : uint32_t pos, idx;
219 : : uint64_t slab;
220 : : int rc;
221 : :
222 [ # # ]: 0 : if (!dev->outb.sa_bmap)
223 : : return -ENOTSUP;
224 : :
225 : 0 : pos = 0;
226 [ # # ]: 0 : slab = 0;
227 : : /* Scan from the beginning */
228 : : plt_bitmap_scan_init(dev->outb.sa_bmap);
229 : :
230 [ # # ]: 0 : if (dev->nix.custom_sa_action) {
231 [ # # ]: 0 : if (spi > dev->outb.max_sa)
232 : : return -ENOTSUP;
233 : : idx = spi;
234 : : } else {
235 : : /* Scan bitmap to get the free sa index */
236 : 0 : rc = plt_bitmap_scan(dev->outb.sa_bmap, &pos, &slab);
237 : : /* Empty bitmap */
238 [ # # ]: 0 : if (rc == 0) {
239 : 0 : plt_err("Outbound SA' exhausted, use 'ipsec_out_max_sa' "
240 : : "devargs to increase");
241 : 0 : return -ERANGE;
242 : : }
243 : :
244 : : /* Get free SA index */
245 [ # # ]: 0 : idx = pos + bitmap_ctzll(slab);
246 : : }
247 : 0 : plt_bitmap_clear(dev->outb.sa_bmap, idx);
248 : 0 : *idx_p = idx;
249 : 0 : return 0;
250 : : }
251 : :
252 : : int
253 : 0 : cnxk_eth_outb_sa_idx_put(struct cnxk_eth_dev *dev, uint32_t idx)
254 : : {
255 [ # # ]: 0 : if (idx >= dev->outb.max_sa)
256 : : return -EINVAL;
257 : :
258 : : /* Check if it is already free */
259 [ # # ]: 0 : if (plt_bitmap_get(dev->outb.sa_bmap, idx))
260 : : return -EINVAL;
261 : :
262 : : /* Mark index as free */
263 : 0 : plt_bitmap_set(dev->outb.sa_bmap, idx);
264 : 0 : return 0;
265 : : }
266 : :
267 : : struct cnxk_eth_sec_sess *
268 : 0 : cnxk_eth_sec_sess_get_by_spi(struct cnxk_eth_dev *dev, uint32_t spi, bool inb)
269 : : {
270 : : struct cnxk_eth_sec_sess_list *list;
271 : : struct cnxk_eth_sec_sess *eth_sec;
272 : :
273 [ # # ]: 0 : list = inb ? &dev->inb.list : &dev->outb.list;
274 [ # # ]: 0 : TAILQ_FOREACH(eth_sec, list, entry) {
275 [ # # ]: 0 : if (eth_sec->spi == spi)
276 : 0 : return eth_sec;
277 : : }
278 : :
279 : : return NULL;
280 : : }
281 : :
282 : : struct cnxk_eth_sec_sess *
283 : 0 : cnxk_eth_sec_sess_get_by_sess(struct cnxk_eth_dev *dev,
284 : : struct rte_security_session *sess)
285 : : {
286 : : struct cnxk_eth_sec_sess *eth_sec = NULL;
287 : :
288 : : /* Search in inbound list */
289 [ # # ]: 0 : TAILQ_FOREACH(eth_sec, &dev->inb.list, entry) {
290 [ # # ]: 0 : if (eth_sec->sess == sess)
291 : 0 : return eth_sec;
292 : : }
293 : :
294 : : /* Search in outbound list */
295 [ # # ]: 0 : TAILQ_FOREACH(eth_sec, &dev->outb.list, entry) {
296 [ # # ]: 0 : if (eth_sec->sess == sess)
297 : 0 : return eth_sec;
298 : : }
299 : :
300 : : return NULL;
301 : : }
302 : :
303 : : uint16_t
304 : 0 : rte_pmd_cnxk_inl_dev_submit(struct rte_pmd_cnxk_inl_dev_q *qptr, void *inst, uint16_t nb_inst)
305 : : {
306 : 0 : return cnxk_pmd_ops.inl_dev_submit((struct roc_nix_inl_dev_q *)qptr, inst, nb_inst);
307 : : }
308 : :
309 : : struct rte_pmd_cnxk_inl_dev_q *
310 : 0 : rte_pmd_cnxk_inl_dev_qptr_get(void)
311 : : {
312 : 0 : return roc_nix_inl_dev_qptr_get(0);
313 : : }
314 : :
315 : : int
316 : 0 : rte_pmd_cnxk_cpt_q_stats_get(uint16_t portid, enum rte_pmd_cnxk_cpt_q_stats_type type,
317 : : struct rte_pmd_cnxk_cpt_q_stats *stats, uint16_t idx)
318 : : {
319 : 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[portid];
320 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
321 : :
322 : 0 : return roc_nix_inl_cpt_lf_stats_get(&dev->nix, (enum roc_nix_cpt_lf_stats_type)type,
323 : : (struct roc_nix_cpt_lf_stats *)stats, idx);
324 : : }
325 : :
326 : : union rte_pmd_cnxk_ipsec_hw_sa *
327 : 0 : rte_pmd_cnxk_hw_session_base_get(uint16_t portid, bool inb)
328 : : {
329 [ # # ]: 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[portid];
330 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
331 : : uintptr_t sa_base;
332 : :
333 [ # # ]: 0 : if (inb)
334 : 0 : sa_base = roc_nix_inl_inb_sa_base_get(&dev->nix, dev->inb.inl_dev);
335 : : else
336 : 0 : sa_base = roc_nix_inl_outb_sa_base_get(&dev->nix);
337 : :
338 : 0 : return (union rte_pmd_cnxk_ipsec_hw_sa *)sa_base;
339 : : }
340 : :
341 : : int
342 : 0 : rte_pmd_cnxk_sa_flush(uint16_t portid, union rte_pmd_cnxk_ipsec_hw_sa *sess, bool inb)
343 : : {
344 : 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[portid];
345 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
346 : :
347 : 0 : return roc_nix_inl_sa_sync(&dev->nix, sess, inb, ROC_NIX_INL_SA_OP_FLUSH);
348 : : }
349 : :
350 : : int
351 : 0 : rte_pmd_cnxk_hw_sa_read(uint16_t portid, void *sess, union rte_pmd_cnxk_ipsec_hw_sa *data,
352 : : uint32_t len, bool inb)
353 : : {
354 : 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[portid];
355 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
356 : : struct cnxk_eth_sec_sess *eth_sec;
357 : : void *sa;
358 : : int rc;
359 : :
360 : 0 : eth_sec = cnxk_eth_sec_sess_get_by_sess(dev, sess);
361 [ # # ]: 0 : if (eth_sec)
362 : 0 : sa = eth_sec->sa;
363 : : else
364 : : sa = sess;
365 : :
366 : 0 : rc = roc_nix_inl_sa_sync(&dev->nix, sa, inb, ROC_NIX_INL_SA_OP_FLUSH);
367 [ # # ]: 0 : if (rc)
368 : : return -EINVAL;
369 : :
370 : 0 : memcpy(data, sa, len);
371 : :
372 : 0 : return 0;
373 : : }
374 : :
375 : : int
376 : 0 : rte_pmd_cnxk_hw_sa_write(uint16_t portid, void *sess, union rte_pmd_cnxk_ipsec_hw_sa *data,
377 : : uint32_t len, bool inb)
378 : : {
379 : 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[portid];
380 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
381 : : struct cnxk_eth_sec_sess *eth_sec;
382 : : struct roc_nix_inl_dev_q *q;
383 : : void *sa;
384 : :
385 : 0 : eth_sec = cnxk_eth_sec_sess_get_by_sess(dev, sess);
386 [ # # ]: 0 : if (eth_sec)
387 : 0 : sa = eth_sec->sa;
388 : : else
389 : : sa = sess;
390 : :
391 : 0 : q = dev->inb.inl_dev_q;
392 [ # # # # ]: 0 : if (q && cnxk_nix_inl_fc_check(q->fc_addr, &q->fc_addr_sw, q->nb_desc, 1))
393 : : return -EAGAIN;
394 : :
395 : 0 : return roc_nix_inl_ctx_write(&dev->nix, data, sa, inb, len);
396 : : }
397 : :
398 : : union rte_pmd_cnxk_cpt_res_s *
399 : 0 : rte_pmd_cnxk_inl_ipsec_res(struct rte_mbuf *mbuf)
400 : : {
401 : : const union nix_rx_parse_u *rx;
402 : : uint16_t desc_size;
403 : : uintptr_t wqe;
404 : :
405 [ # # # # ]: 0 : if (!mbuf || !(mbuf->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD))
406 : : return NULL;
407 : :
408 : 0 : wqe = (uintptr_t)(mbuf + 1);
409 : 0 : rx = (const union nix_rx_parse_u *)(wqe + 8);
410 : 0 : desc_size = (rx->desc_sizem1 + 1) * 16;
411 : :
412 : : /* rte_pmd_cnxk_cpt_res_s sits after SG list at 16B aligned address */
413 : 0 : return (void *)(wqe + 64 + desc_size);
414 : : }
415 : :
416 : : void
417 : 0 : rte_pmd_cnxk_hw_inline_inb_cfg_set(uint16_t portid, struct rte_pmd_cnxk_ipsec_inb_cfg *cfg)
418 : : {
419 : 0 : struct rte_eth_dev *eth_dev = &rte_eth_devices[portid];
420 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
421 : :
422 : 0 : dev->nix.inb_cfg_param1 = cfg->param1;
423 : 0 : dev->nix.inb_cfg_param2 = cfg->param2;
424 : 0 : }
425 : :
426 : : static unsigned int
427 : 0 : cnxk_eth_sec_session_get_size(void *device __rte_unused)
428 : : {
429 : 0 : return RTE_MAX(sizeof(struct cnxk_macsec_sess), sizeof(struct cnxk_eth_sec_sess));
430 : : }
431 : :
432 : : struct rte_security_ops cnxk_eth_sec_ops = {
433 : : .session_get_size = cnxk_eth_sec_session_get_size
434 : : };
435 : :
436 : : static int
437 : 0 : parse_val_u32(const char *key, const char *value, void *extra_args)
438 : : {
439 : : RTE_SET_USED(key);
440 : : uint32_t val;
441 : :
442 : 0 : errno = 0;
443 : 0 : val = strtoul(value, NULL, 0);
444 [ # # ]: 0 : if (errno)
445 : : val = 0;
446 : :
447 : 0 : *(uint32_t *)extra_args = val;
448 : :
449 : 0 : return 0;
450 : : }
451 : :
452 : : static int
453 : 0 : parse_selftest(const char *key, const char *value, void *extra_args)
454 : : {
455 : : RTE_SET_USED(key);
456 : : uint32_t val;
457 : :
458 : 0 : val = atoi(value);
459 : :
460 : 0 : *(uint8_t *)extra_args = !!(val == 1);
461 : 0 : return 0;
462 : : }
463 : :
464 : : static int
465 : 0 : parse_inl_cpt_channel(const char *key, const char *value, void *extra_args)
466 : : {
467 : : RTE_SET_USED(key);
468 : : uint16_t chan = 0, mask = 0;
469 : 0 : char *next = 0;
470 : :
471 : : /* next will point to the separator '/' */
472 : 0 : chan = strtol(value, &next, 16);
473 : 0 : mask = strtol(++next, 0, 16);
474 : :
475 [ # # ]: 0 : if (chan > GENMASK(12, 0) || mask > GENMASK(12, 0))
476 : : return -EINVAL;
477 : :
478 : 0 : ((struct inl_cpt_channel *)extra_args)->channel = chan;
479 : 0 : ((struct inl_cpt_channel *)extra_args)->mask = mask;
480 : 0 : ((struct inl_cpt_channel *)extra_args)->is_multi_channel = true;
481 : :
482 : 0 : return 0;
483 : : }
484 : :
485 : : static int
486 : 0 : nix_inl_parse_devargs(struct rte_devargs *devargs,
487 : : struct roc_nix_inl_dev *inl_dev)
488 : : {
489 : 0 : uint32_t soft_exp_poll_freq = CNXK_NIX_SOFT_EXP_POLL_FREQ_DFLT;
490 : 0 : uint32_t ipsec_in_max_spi = BIT(8) - 1;
491 : 0 : uint32_t ipsec_in_min_spi = 0;
492 : : struct inl_cpt_channel cpt_channel;
493 : 0 : uint32_t max_ipsec_rules = 0;
494 : : struct rte_kvargs *kvlist;
495 : 0 : uint8_t custom_inb_sa = 0;
496 : 0 : uint32_t nb_meta_bufs = 0;
497 : 0 : uint32_t meta_buf_sz = 0;
498 : 0 : uint8_t rx_inj_ena = 0;
499 [ # # ]: 0 : uint8_t selftest = 0;
500 : :
501 : : memset(&cpt_channel, 0, sizeof(cpt_channel));
502 : :
503 [ # # ]: 0 : if (devargs == NULL)
504 : 0 : goto null_devargs;
505 : :
506 : 0 : kvlist = rte_kvargs_parse(devargs->args, NULL);
507 [ # # ]: 0 : if (kvlist == NULL)
508 : 0 : goto exit;
509 : :
510 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_SELFTEST, &parse_selftest,
511 : : &selftest);
512 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_IPSEC_IN_MIN_SPI,
513 : : &parse_val_u32, &ipsec_in_min_spi);
514 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_IPSEC_IN_MAX_SPI,
515 : : &parse_val_u32, &ipsec_in_max_spi);
516 : 0 : rte_kvargs_process(kvlist, CNXK_INL_CPT_CHANNEL, &parse_inl_cpt_channel,
517 : : &cpt_channel);
518 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_NB_META_BUFS, &parse_val_u32,
519 : : &nb_meta_bufs);
520 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_META_BUF_SZ, &parse_val_u32,
521 : : &meta_buf_sz);
522 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_SOFT_EXP_POLL_FREQ,
523 : : &parse_val_u32, &soft_exp_poll_freq);
524 : 0 : rte_kvargs_process(kvlist, CNXK_MAX_IPSEC_RULES, &parse_max_ipsec_rules, &max_ipsec_rules);
525 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_INL_RX_INJ_ENABLE, &parse_val_u8, &rx_inj_ena);
526 : 0 : rte_kvargs_process(kvlist, CNXK_NIX_CUSTOM_INB_SA, &parse_val_u8, &custom_inb_sa);
527 : 0 : rte_kvargs_free(kvlist);
528 : :
529 : 0 : null_devargs:
530 : 0 : inl_dev->ipsec_in_min_spi = ipsec_in_min_spi;
531 : 0 : inl_dev->ipsec_in_max_spi = ipsec_in_max_spi;
532 : 0 : inl_dev->selftest = selftest;
533 : 0 : inl_dev->channel = cpt_channel.channel;
534 : 0 : inl_dev->chan_mask = cpt_channel.mask;
535 : 0 : inl_dev->is_multi_channel = cpt_channel.is_multi_channel;
536 : 0 : inl_dev->nb_meta_bufs = nb_meta_bufs;
537 : 0 : inl_dev->meta_buf_sz = meta_buf_sz;
538 : 0 : inl_dev->soft_exp_poll_freq = soft_exp_poll_freq;
539 [ # # ]: 0 : inl_dev->max_ipsec_rules = max_ipsec_rules;
540 [ # # ]: 0 : if (roc_feature_nix_has_rx_inject())
541 : 0 : inl_dev->rx_inj_ena = rx_inj_ena;
542 : 0 : inl_dev->custom_inb_sa = custom_inb_sa;
543 : 0 : return 0;
544 : : exit:
545 : 0 : return -EINVAL;
546 : : }
547 : :
548 : : static inline char *
549 : 0 : nix_inl_dev_to_name(struct rte_pci_device *pci_dev, char *name)
550 : : {
551 : 0 : snprintf(name, CNXK_NIX_INL_DEV_NAME_LEN,
552 : : CNXK_NIX_INL_DEV_NAME PCI_PRI_FMT, pci_dev->addr.domain,
553 : 0 : pci_dev->addr.bus, pci_dev->addr.devid,
554 : 0 : pci_dev->addr.function);
555 : :
556 : 0 : return name;
557 : : }
558 : :
559 : : static int
560 : 0 : cnxk_nix_inl_dev_remove(struct rte_pci_device *pci_dev)
561 : : {
562 : : char name[CNXK_NIX_INL_DEV_NAME_LEN];
563 : : const struct rte_memzone *mz;
564 : : struct roc_nix_inl_dev *dev;
565 : : int rc;
566 : :
567 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
568 : : return 0;
569 : :
570 : 0 : mz = rte_memzone_lookup(nix_inl_dev_to_name(pci_dev, name));
571 [ # # ]: 0 : if (!mz)
572 : : return 0;
573 : :
574 : 0 : dev = mz->addr;
575 : :
576 : : /* Cleanup inline dev */
577 : 0 : rc = roc_nix_inl_dev_fini(dev);
578 [ # # ]: 0 : if (rc) {
579 : 0 : plt_err("Failed to cleanup inl dev, rc=%d(%s)", rc,
580 : : roc_error_msg_get(rc));
581 : 0 : return rc;
582 : : }
583 : :
584 : 0 : rte_memzone_free(mz);
585 : 0 : return 0;
586 : : }
587 : :
588 : : static int
589 : 0 : cnxk_nix_inl_dev_probe(struct rte_pci_driver *pci_drv,
590 : : struct rte_pci_device *pci_dev)
591 : : {
592 : : char name[CNXK_NIX_INL_DEV_NAME_LEN];
593 : : struct roc_nix_inl_dev *inl_dev;
594 : : const struct rte_memzone *mz;
595 : : uint16_t wqe_skip;
596 : : int rc = -ENOMEM;
597 : :
598 : : RTE_SET_USED(pci_drv);
599 : :
600 : 0 : rc = roc_plt_init();
601 [ # # ]: 0 : if (rc) {
602 : 0 : plt_err("Failed to initialize platform model, rc=%d", rc);
603 : 0 : return rc;
604 : : }
605 : :
606 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
607 : : return 0;
608 : :
609 : 0 : mz = rte_memzone_reserve_aligned(nix_inl_dev_to_name(pci_dev, name),
610 : : sizeof(*inl_dev), SOCKET_ID_ANY, 0,
611 : : RTE_CACHE_LINE_SIZE);
612 [ # # ]: 0 : if (mz == NULL)
613 : : return rc;
614 : :
615 : 0 : inl_dev = mz->addr;
616 : 0 : inl_dev->pci_dev = pci_dev;
617 : :
618 : : /* Parse devargs string */
619 : 0 : rc = nix_inl_parse_devargs(pci_dev->device.devargs, inl_dev);
620 [ # # ]: 0 : if (rc) {
621 : 0 : plt_err("Failed to parse devargs rc=%d", rc);
622 : 0 : goto free_mem;
623 : : }
624 : :
625 : 0 : inl_dev->attach_cptlf = true;
626 : : /* WQE skip is one for DPDK */
627 : : wqe_skip = RTE_ALIGN_CEIL(sizeof(struct rte_mbuf), ROC_CACHE_LINE_SZ);
628 : : wqe_skip = wqe_skip / ROC_CACHE_LINE_SZ;
629 : 0 : inl_dev->wqe_skip = wqe_skip;
630 : 0 : rc = roc_nix_inl_dev_init(inl_dev);
631 [ # # ]: 0 : if (rc) {
632 : 0 : plt_err("Failed to init nix inl device, rc=%d(%s)", rc,
633 : : roc_error_msg_get(rc));
634 : 0 : goto free_mem;
635 : : }
636 : :
637 : : return 0;
638 : 0 : free_mem:
639 : 0 : rte_memzone_free(mz);
640 : 0 : return rc;
641 : : }
642 : :
643 : : static const struct rte_pci_id cnxk_nix_inl_pci_map[] = {
644 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_RVU_NIX_INL_PF)},
645 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_RVU_NIX_INL_VF)},
646 : : {
647 : : .vendor_id = 0,
648 : : },
649 : : };
650 : :
651 : : static struct rte_pci_driver cnxk_nix_inl_pci = {
652 : : .id_table = cnxk_nix_inl_pci_map,
653 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA,
654 : : .probe = cnxk_nix_inl_dev_probe,
655 : : .remove = cnxk_nix_inl_dev_remove,
656 : : };
657 : :
658 : 252 : RTE_PMD_REGISTER_PCI(cnxk_nix_inl, cnxk_nix_inl_pci);
659 : : RTE_PMD_REGISTER_PCI_TABLE(cnxk_nix_inl, cnxk_nix_inl_pci_map);
660 : : RTE_PMD_REGISTER_KMOD_DEP(cnxk_nix_inl, "vfio-pci");
661 : :
662 : : RTE_PMD_REGISTER_PARAM_STRING(cnxk_nix_inl,
663 : : CNXK_NIX_INL_SELFTEST "=1"
664 : : CNXK_NIX_INL_IPSEC_IN_MIN_SPI "=<1-U32_MAX>"
665 : : CNXK_NIX_INL_IPSEC_IN_MAX_SPI "=<1-U32_MAX>"
666 : : CNXK_INL_CPT_CHANNEL "=<1-4095>/<1-4095>"
667 : : CNXK_NIX_INL_NB_META_BUFS "=<1-U32_MAX>"
668 : : CNXK_NIX_INL_META_BUF_SZ "=<1-U32_MAX>"
669 : : CNXK_NIX_SOFT_EXP_POLL_FREQ "=<0-U32_MAX>"
670 : : CNXK_MAX_IPSEC_RULES "=<1-4095>"
671 : : CNXK_NIX_INL_RX_INJ_ENABLE "=1"
672 : : CNXK_NIX_CUSTOM_INB_SA "=1");
|