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