Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : : #include <cnxk_ethdev.h>
5 : :
6 : : #include <eal_export.h>
7 : : #include <rte_eventdev.h>
8 : : #include <rte_pmd_cnxk.h>
9 : :
10 : : cnxk_ethdev_rx_offload_cb_t cnxk_ethdev_rx_offload_cb;
11 : :
12 : : #define CNXK_NIX_CQ_INL_CLAMP_MAX (64UL * 1024UL)
13 : :
14 : : #define NIX_TM_DFLT_RR_WT 71
15 : :
16 : : RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_cnxk_model_str_get, 23.11)
17 : : const char *
18 : 0 : rte_pmd_cnxk_model_str_get(void)
19 : : {
20 : 0 : return roc_model->name;
21 : : }
22 : :
23 : : static inline uint64_t
24 : : nix_get_rx_offload_capa(struct cnxk_eth_dev *dev)
25 : : {
26 : : uint64_t capa = CNXK_NIX_RX_OFFLOAD_CAPA;
27 : :
28 [ # # ]: 0 : if (roc_nix_is_vf_or_sdp(&dev->nix) ||
29 [ # # ]: 0 : dev->npc.switch_header_type == ROC_PRIV_FLAGS_HIGIG)
30 : : capa &= ~RTE_ETH_RX_OFFLOAD_TIMESTAMP;
31 : :
32 : : return capa;
33 : : }
34 : :
35 : : static inline uint64_t
36 : : nix_get_tx_offload_capa(struct cnxk_eth_dev *dev)
37 : : {
38 : : RTE_SET_USED(dev);
39 : : return CNXK_NIX_TX_OFFLOAD_CAPA;
40 : : }
41 : :
42 : : static inline uint32_t
43 : 0 : nix_get_speed_capa(struct cnxk_eth_dev *dev)
44 : : {
45 : : uint32_t speed_capa;
46 : :
47 : : /* Auto negotiation disabled */
48 : : speed_capa = RTE_ETH_LINK_SPEED_FIXED;
49 [ # # # # ]: 0 : if (!roc_nix_is_vf_or_sdp(&dev->nix) && !roc_nix_is_lbk(&dev->nix)) {
50 : : speed_capa |= RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_10G |
51 : : RTE_ETH_LINK_SPEED_25G | RTE_ETH_LINK_SPEED_40G |
52 : : RTE_ETH_LINK_SPEED_50G | RTE_ETH_LINK_SPEED_100G;
53 : : }
54 : :
55 : 0 : return speed_capa;
56 : : }
57 : :
58 : : static uint32_t
59 [ # # ]: 0 : nix_inl_cq_sz_clamp_up(struct roc_nix *nix, struct rte_mempool *mp,
60 : : uint32_t nb_desc)
61 : : {
62 : : struct roc_nix_rq *inl_rq;
63 : : uint64_t limit;
64 : :
65 : : /* For CN10KB and above, LBP needs minimum CQ size */
66 [ # # ]: 0 : if (!roc_errata_cpt_hang_on_x2p_bp())
67 : 0 : return RTE_MAX(nb_desc, (uint32_t)4096);
68 : :
69 : : /* CQ should be able to hold all buffers in first pass RQ's aura
70 : : * this RQ's aura.
71 : : */
72 : 0 : inl_rq = roc_nix_inl_dev_rq(nix);
73 : : if (!inl_rq) {
74 : : /* This itself is going to be inline RQ's aura */
75 : : limit = roc_npa_aura_op_limit_get(mp->pool_id);
76 : : } else {
77 : : limit = roc_npa_aura_op_limit_get(inl_rq->aura_handle);
78 : : /* Also add this RQ's aura if it is different */
79 : : if (inl_rq->aura_handle != mp->pool_id)
80 : : limit += roc_npa_aura_op_limit_get(mp->pool_id);
81 : : }
82 : 0 : nb_desc = PLT_MAX(limit + 1, nb_desc);
83 [ # # ]: 0 : if (nb_desc > CNXK_NIX_CQ_INL_CLAMP_MAX) {
84 : 0 : plt_warn("Could not setup CQ size to accommodate"
85 : : " all buffers in related auras (%" PRIu64 ")",
86 : : limit);
87 : : nb_desc = CNXK_NIX_CQ_INL_CLAMP_MAX;
88 : : }
89 : : return nb_desc;
90 : : }
91 : :
92 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ethdev_rx_offload_cb_register)
93 : : void
94 : 0 : cnxk_ethdev_rx_offload_cb_register(cnxk_ethdev_rx_offload_cb_t cb)
95 : : {
96 : 0 : cnxk_ethdev_rx_offload_cb = cb;
97 : 0 : }
98 : :
99 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_nix_inb_mode_set)
100 : : int
101 : 0 : cnxk_nix_inb_mode_set(struct cnxk_eth_dev *dev, bool use_inl_dev)
102 : : {
103 : 0 : struct roc_nix *nix = &dev->nix;
104 : :
105 : 0 : plt_nix_dbg("Security sessions(%u) still active, inl=%u!!!",
106 : : dev->inb.nb_sess, !!dev->inb.inl_dev);
107 : :
108 : : /* Change the mode */
109 : 0 : dev->inb.inl_dev = use_inl_dev;
110 : :
111 : : /* Update RoC for NPC rule insertion */
112 : 0 : roc_nix_inb_mode_set(nix, use_inl_dev);
113 : :
114 : : /* Setup lookup mem */
115 : 0 : return cnxk_nix_lookup_mem_sa_base_set(dev);
116 : : }
117 : :
118 : : static int
119 : 0 : nix_security_setup(struct cnxk_eth_dev *dev)
120 : : {
121 : 0 : struct roc_nix *nix = &dev->nix;
122 : : int i, rc = 0;
123 : :
124 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
125 : : /* Setup minimum SA table when inline device is used */
126 [ # # ]: 0 : nix->ipsec_in_min_spi = dev->inb.no_inl_dev ? dev->inb.min_spi : 0;
127 [ # # ]: 0 : nix->ipsec_in_max_spi = dev->inb.no_inl_dev ? dev->inb.max_spi : 1;
128 : :
129 : : /* Enable custom meta aura when multi-chan is used */
130 [ # # # # ]: 0 : if (nix->local_meta_aura_ena && roc_nix_inl_dev_is_multi_channel() &&
131 [ # # ]: 0 : !dev->inb.custom_meta_aura_dis)
132 : 0 : nix->custom_meta_aura_ena = true;
133 : :
134 : : /* Setup Inline Inbound */
135 : 0 : rc = roc_nix_inl_inb_init(nix);
136 [ # # ]: 0 : if (rc) {
137 : 0 : plt_err("Failed to initialize nix inline inb, rc=%d",
138 : : rc);
139 : 0 : return rc;
140 : : }
141 : :
142 : : /* By default pick using inline device for poll mode.
143 : : * Will be overridden when event mode rq's are setup.
144 : : */
145 : 0 : cnxk_nix_inb_mode_set(dev, !dev->inb.no_inl_dev);
146 : :
147 : : /* Allocate memory to be used as dptr for CPT ucode
148 : : * WRITE_SA op.
149 : : */
150 : 0 : dev->inb.sa_dptr =
151 : 0 : plt_zmalloc(ROC_NIX_INL_OT_IPSEC_INB_HW_SZ, 0);
152 [ # # ]: 0 : if (!dev->inb.sa_dptr) {
153 : 0 : plt_err("Couldn't allocate memory for SA dptr");
154 : : rc = -ENOMEM;
155 : 0 : goto cleanup;
156 : : }
157 : 0 : dev->inb.inl_dev_q = roc_nix_inl_dev_qptr_get(0);
158 : : }
159 : :
160 [ # # ]: 0 : if (dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY ||
161 [ # # ]: 0 : dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
162 : : struct plt_bitmap *bmap;
163 : : size_t bmap_sz;
164 : : void *mem;
165 : :
166 : : /* Setup enough descriptors for all tx queues */
167 : 0 : nix->outb_nb_desc = dev->outb.nb_desc;
168 : 0 : nix->outb_nb_crypto_qs = dev->outb.nb_crypto_qs;
169 : :
170 : : /* Setup Inline Outbound */
171 : 0 : rc = roc_nix_inl_outb_init(nix);
172 [ # # ]: 0 : if (rc) {
173 : 0 : plt_err("Failed to initialize nix inline outb, rc=%d",
174 : : rc);
175 : 0 : goto sa_dptr_free;
176 : : }
177 : :
178 : 0 : dev->outb.lf_base = roc_nix_inl_outb_lf_base_get(nix);
179 : :
180 : : /* Skip the rest if DEV_TX_OFFLOAD_SECURITY is not enabled */
181 [ # # ]: 0 : if (!(dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY))
182 : : return 0;
183 : :
184 : : /* Allocate memory to be used as dptr for CPT ucode
185 : : * WRITE_SA op.
186 : : */
187 : 0 : dev->outb.sa_dptr =
188 : 0 : plt_zmalloc(ROC_NIX_INL_OT_IPSEC_OUTB_HW_SZ, 0);
189 [ # # ]: 0 : if (!dev->outb.sa_dptr) {
190 : 0 : plt_err("Couldn't allocate memory for SA dptr");
191 : : rc = -ENOMEM;
192 : 0 : goto sa_dptr_free;
193 : : }
194 : :
195 : : rc = -ENOMEM;
196 : : /* Allocate a bitmap to alloc and free sa indexes */
197 : 0 : bmap_sz = plt_bitmap_get_memory_footprint(dev->outb.max_sa);
198 : 0 : mem = plt_zmalloc(bmap_sz, PLT_CACHE_LINE_SIZE);
199 [ # # ]: 0 : if (mem == NULL) {
200 : 0 : plt_err("Outbound SA bmap alloc failed");
201 : :
202 : 0 : rc |= roc_nix_inl_outb_fini(nix);
203 : 0 : goto sa_dptr_free;
204 : : }
205 : :
206 : : rc = -EIO;
207 : 0 : bmap = plt_bitmap_init(dev->outb.max_sa, mem, bmap_sz);
208 [ # # ]: 0 : if (!bmap) {
209 : 0 : plt_err("Outbound SA bmap init failed");
210 : :
211 : 0 : rc |= roc_nix_inl_outb_fini(nix);
212 : 0 : plt_free(mem);
213 : 0 : goto sa_dptr_free;
214 : : }
215 : :
216 [ # # ]: 0 : for (i = 0; i < dev->outb.max_sa; i++)
217 : 0 : plt_bitmap_set(bmap, i);
218 : :
219 : 0 : dev->outb.sa_base = roc_nix_inl_outb_sa_base_get(nix);
220 : 0 : dev->outb.sa_bmap_mem = mem;
221 : 0 : dev->outb.sa_bmap = bmap;
222 : :
223 : 0 : dev->outb.fc_sw_mem = plt_zmalloc(dev->outb.nb_crypto_qs *
224 : : RTE_CACHE_LINE_SIZE,
225 : : RTE_CACHE_LINE_SIZE);
226 [ # # ]: 0 : if (!dev->outb.fc_sw_mem) {
227 : 0 : plt_err("Outbound fc sw mem alloc failed");
228 : 0 : goto sa_bmap_free;
229 : : }
230 : :
231 : 0 : dev->outb.cpt_eng_caps = roc_nix_inl_eng_caps_get(nix);
232 : : }
233 : : return 0;
234 : :
235 : : sa_bmap_free:
236 : 0 : plt_free(dev->outb.sa_bmap_mem);
237 : 0 : sa_dptr_free:
238 [ # # ]: 0 : if (dev->inb.sa_dptr)
239 : 0 : plt_free(dev->inb.sa_dptr);
240 [ # # ]: 0 : if (dev->outb.sa_dptr)
241 : 0 : plt_free(dev->outb.sa_dptr);
242 : 0 : cleanup:
243 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY)
244 : 0 : rc |= roc_nix_inl_inb_fini(nix);
245 : : return rc;
246 : : }
247 : :
248 : : static int
249 : 0 : nix_meter_fini(struct cnxk_eth_dev *dev)
250 : : {
251 : : struct cnxk_meter_node *next_mtr = NULL;
252 : 0 : struct roc_nix_bpf_objs profs = {0};
253 : : struct cnxk_meter_node *mtr = NULL;
254 : : struct cnxk_mtr *fms = &dev->mtr;
255 : 0 : struct roc_nix *nix = &dev->nix;
256 : : struct roc_nix_rq *rq;
257 : : uint32_t i;
258 : : int rc = 0;
259 : :
260 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(mtr, fms, next, next_mtr) {
261 [ # # ]: 0 : for (i = 0; i < mtr->rq_num; i++) {
262 : 0 : rq = &dev->rqs[mtr->rq_id[i]];
263 : 0 : rc |= roc_nix_bpf_ena_dis(nix, mtr->bpf_id, rq, false);
264 : : }
265 : :
266 : 0 : profs.level = mtr->level;
267 : 0 : profs.count = 1;
268 : 0 : profs.ids[0] = mtr->bpf_id;
269 : 0 : rc = roc_nix_bpf_free(nix, &profs, 1);
270 : :
271 [ # # ]: 0 : if (rc)
272 : 0 : return rc;
273 : :
274 [ # # ]: 0 : TAILQ_REMOVE(fms, mtr, next);
275 : 0 : plt_free(mtr);
276 : : }
277 : : return 0;
278 : : }
279 : :
280 : : static int
281 : 0 : nix_security_release(struct cnxk_eth_dev *dev)
282 : : {
283 : 0 : struct rte_eth_dev *eth_dev = dev->eth_dev;
284 : : struct cnxk_eth_sec_sess *eth_sec, *tvar;
285 : 0 : struct roc_nix *nix = &dev->nix;
286 : : int rc, ret = 0;
287 : :
288 : : /* Cleanup Inline inbound */
289 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
290 : : /* Destroy inbound sessions */
291 : : tvar = NULL;
292 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(eth_sec, &dev->inb.list, entry, tvar)
293 : 0 : cnxk_eth_sec_ops.session_destroy(eth_dev,
294 : : eth_sec->sess);
295 : :
296 : : /* Clear lookup mem */
297 : 0 : cnxk_nix_lookup_mem_sa_base_clear(dev);
298 : :
299 : 0 : rc = roc_nix_inl_inb_fini(nix);
300 [ # # ]: 0 : if (rc)
301 : 0 : plt_err("Failed to cleanup nix inline inb, rc=%d", rc);
302 : : ret |= rc;
303 : :
304 : 0 : cnxk_nix_lookup_mem_metapool_clear(dev);
305 : :
306 [ # # ]: 0 : if (dev->inb.sa_dptr) {
307 : 0 : plt_free(dev->inb.sa_dptr);
308 : 0 : dev->inb.sa_dptr = NULL;
309 : : }
310 : : }
311 : :
312 : : /* Cleanup Inline outbound */
313 [ # # ]: 0 : if (dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY ||
314 [ # # ]: 0 : dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
315 : : /* Destroy outbound sessions */
316 : : tvar = NULL;
317 [ # # ]: 0 : RTE_TAILQ_FOREACH_SAFE(eth_sec, &dev->outb.list, entry, tvar)
318 : 0 : cnxk_eth_sec_ops.session_destroy(eth_dev,
319 : : eth_sec->sess);
320 : :
321 : 0 : rc = roc_nix_inl_outb_fini(nix);
322 [ # # ]: 0 : if (rc)
323 : 0 : plt_err("Failed to cleanup nix inline outb, rc=%d", rc);
324 : 0 : ret |= rc;
325 : :
326 : : plt_bitmap_free(dev->outb.sa_bmap);
327 : 0 : plt_free(dev->outb.sa_bmap_mem);
328 : 0 : dev->outb.sa_bmap = NULL;
329 : 0 : dev->outb.sa_bmap_mem = NULL;
330 [ # # ]: 0 : if (dev->outb.sa_dptr) {
331 : 0 : plt_free(dev->outb.sa_dptr);
332 : 0 : dev->outb.sa_dptr = NULL;
333 : : }
334 : :
335 : 0 : plt_free(dev->outb.fc_sw_mem);
336 : 0 : dev->outb.fc_sw_mem = NULL;
337 : : }
338 : :
339 : 0 : dev->inb.inl_dev = false;
340 : 0 : roc_nix_inb_mode_set(nix, false);
341 : 0 : dev->nb_rxq_sso = 0;
342 : 0 : dev->inb.nb_sess = 0;
343 : 0 : dev->outb.nb_sess = 0;
344 : 0 : return ret;
345 : : }
346 : :
347 : : static void
348 : 0 : nix_enable_mseg_on_jumbo(struct cnxk_eth_rxq_sp *rxq)
349 : : {
350 : : struct rte_pktmbuf_pool_private *mbp_priv;
351 : : struct rte_eth_dev *eth_dev;
352 : : struct cnxk_eth_dev *dev;
353 : : uint32_t buffsz;
354 : :
355 : 0 : dev = rxq->dev;
356 : 0 : eth_dev = dev->eth_dev;
357 : :
358 : : /* Get rx buffer size */
359 [ # # ]: 0 : mbp_priv = rte_mempool_get_priv(rxq->qconf.mp);
360 : 0 : buffsz = mbp_priv->mbuf_data_room_size - RTE_PKTMBUF_HEADROOM;
361 : :
362 [ # # ]: 0 : if (eth_dev->data->mtu + (uint32_t)CNXK_NIX_L2_OVERHEAD > buffsz) {
363 : 0 : dev->rx_offloads |= RTE_ETH_RX_OFFLOAD_SCATTER;
364 : 0 : dev->tx_offloads |= RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
365 : : }
366 : 0 : }
367 : :
368 : : int
369 : 0 : nix_recalc_mtu(struct rte_eth_dev *eth_dev)
370 : : {
371 : 0 : struct rte_eth_dev_data *data = eth_dev->data;
372 : : struct cnxk_eth_rxq_sp *rxq;
373 : : int rc;
374 : :
375 : 0 : rxq = ((struct cnxk_eth_rxq_sp *)data->rx_queues[0]) - 1;
376 : : /* Setup scatter mode if needed by jumbo */
377 : 0 : nix_enable_mseg_on_jumbo(rxq);
378 : :
379 : 0 : rc = cnxk_nix_mtu_set(eth_dev, data->mtu);
380 [ # # ]: 0 : if (rc)
381 : 0 : plt_err("Failed to set default MTU size, rc=%d", rc);
382 : :
383 : 0 : return rc;
384 : : }
385 : :
386 : : static int
387 : 0 : nix_init_flow_ctrl_config(struct rte_eth_dev *eth_dev)
388 : : {
389 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
390 : : enum roc_nix_fc_mode fc_mode = ROC_NIX_FC_FULL;
391 : : struct cnxk_fc_cfg *fc = &dev->fc_cfg;
392 : : int rc;
393 : :
394 [ # # # # ]: 0 : if (roc_nix_is_vf_or_sdp(&dev->nix) && !roc_nix_is_lbk(&dev->nix))
395 : : return 0;
396 : :
397 : : /* To avoid Link credit deadlock on Ax, disable Tx FC if it's enabled */
398 [ # # ]: 0 : if (roc_model_is_cn96_ax() &&
399 [ # # ]: 0 : dev->npc.switch_header_type != ROC_PRIV_FLAGS_HIGIG)
400 : : fc_mode = ROC_NIX_FC_TX;
401 : :
402 : : /* By default enable flow control */
403 : 0 : rc = roc_nix_fc_mode_set(&dev->nix, fc_mode);
404 [ # # ]: 0 : if (rc)
405 : : return rc;
406 : :
407 [ # # ]: 0 : fc->mode = (fc_mode == ROC_NIX_FC_FULL) ? RTE_ETH_FC_FULL : RTE_ETH_FC_TX_PAUSE;
408 : 0 : fc->rx_pause = (fc->mode == RTE_ETH_FC_FULL) || (fc->mode == RTE_ETH_FC_RX_PAUSE);
409 : 0 : fc->tx_pause = (fc->mode == RTE_ETH_FC_FULL) || (fc->mode == RTE_ETH_FC_TX_PAUSE);
410 : 0 : return rc;
411 : : }
412 : :
413 : : static int
414 : 0 : nix_update_flow_ctrl_config(struct rte_eth_dev *eth_dev)
415 : : {
416 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
417 : : struct cnxk_fc_cfg *fc = &dev->fc_cfg;
418 : 0 : struct rte_eth_fc_conf fc_cfg = {0};
419 : :
420 [ # # # # ]: 0 : if (roc_nix_is_sdp(&dev->nix) || roc_nix_is_esw(&dev->nix))
421 : 0 : return 0;
422 : :
423 : : /* Don't do anything if PFC is enabled */
424 [ # # ]: 0 : if (dev->pfc_cfg.rx_pause_en || dev->pfc_cfg.tx_pause_en)
425 : : return 0;
426 : :
427 [ # # ]: 0 : fc_cfg.mode = fc->mode;
428 : :
429 : : /* To avoid Link credit deadlock on Ax, disable Tx FC if it's enabled */
430 [ # # ]: 0 : if (roc_model_is_cn96_ax() &&
431 [ # # ]: 0 : dev->npc.switch_header_type != ROC_PRIV_FLAGS_HIGIG &&
432 [ # # ]: 0 : (fc_cfg.mode == RTE_ETH_FC_FULL || fc_cfg.mode == RTE_ETH_FC_RX_PAUSE)) {
433 : 0 : fc_cfg.mode =
434 : 0 : (fc_cfg.mode == RTE_ETH_FC_FULL ||
435 : : fc_cfg.mode == RTE_ETH_FC_TX_PAUSE) ?
436 [ # # ]: 0 : RTE_ETH_FC_TX_PAUSE : RTE_ETH_FC_NONE;
437 : : }
438 : :
439 : 0 : return cnxk_nix_flow_ctrl_set(eth_dev, &fc_cfg);
440 : : }
441 : :
442 : : uint64_t
443 : 0 : cnxk_nix_rxq_mbuf_setup(struct cnxk_eth_dev *dev)
444 : : {
445 : 0 : uint16_t port_id = dev->eth_dev->data->port_id;
446 : : struct rte_mbuf mb_def;
447 : : uint64_t *tmp;
448 : :
449 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_off) % 8 != 0);
450 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, refcnt) -
451 : : offsetof(struct rte_mbuf, data_off) !=
452 : : 2);
453 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, nb_segs) -
454 : : offsetof(struct rte_mbuf, data_off) !=
455 : : 4);
456 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, port) -
457 : : offsetof(struct rte_mbuf, data_off) !=
458 : : 6);
459 : 0 : mb_def.nb_segs = 1;
460 : 0 : mb_def.data_off = RTE_PKTMBUF_HEADROOM +
461 : 0 : (dev->ptp_en * CNXK_NIX_TIMESYNC_RX_OFFSET);
462 : 0 : mb_def.port = port_id;
463 : : rte_mbuf_refcnt_set(&mb_def, 1);
464 : :
465 : : /* Prevent compiler reordering: rearm_data covers previous fields */
466 : 0 : rte_compiler_barrier();
467 : : tmp = (uint64_t *)&mb_def.rearm_data;
468 : :
469 : 0 : return *tmp;
470 : : }
471 : :
472 : : static inline uint8_t
473 : : nix_sq_max_sqe_sz(struct cnxk_eth_dev *dev)
474 : : {
475 : : /*
476 : : * Maximum three segments can be supported with W8, Choose
477 : : * NIX_MAXSQESZ_W16 for multi segment offload.
478 : : */
479 : 0 : if (dev->tx_offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
480 : : return NIX_MAXSQESZ_W16;
481 : : else
482 : 0 : return NIX_MAXSQESZ_W8;
483 : : }
484 : :
485 : : int
486 [ # # ]: 0 : cnxk_nix_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t qid,
487 : : uint16_t nb_desc, uint16_t fp_tx_q_sz,
488 : : const struct rte_eth_txconf *tx_conf)
489 : : {
490 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
491 : 0 : const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
492 : : struct roc_nix *nix = &dev->nix;
493 : : struct cnxk_eth_txq_sp *txq_sp;
494 : : struct roc_nix_cq *cq;
495 : : struct roc_nix_sq *sq;
496 : : size_t txq_sz;
497 : : int rc;
498 : :
499 : : /* Free memory prior to re-allocation if needed. */
500 [ # # ]: 0 : if (eth_dev->data->tx_queues[qid] != NULL) {
501 : 0 : plt_nix_dbg("Freeing memory prior to re-allocation %d", qid);
502 : 0 : dev_ops->tx_queue_release(eth_dev, qid);
503 : 0 : eth_dev->data->tx_queues[qid] = NULL;
504 : : }
505 : :
506 : : /* When Tx Security offload is enabled, increase tx desc count by
507 : : * max possible outbound desc count.
508 : : */
509 [ # # ]: 0 : if (dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY)
510 : 0 : nb_desc += dev->outb.nb_desc;
511 : :
512 : : /* Setup ROC SQ */
513 : 0 : sq = &dev->sqs[qid];
514 : 0 : sq->qid = qid;
515 [ # # ]: 0 : sq->nb_desc = nb_desc;
516 : 0 : sq->max_sqe_sz = nix_sq_max_sqe_sz(dev);
517 [ # # ]: 0 : if (sq->nb_desc >= CNXK_NIX_DEF_SQ_COUNT)
518 : 0 : sq->fc_hyst_bits = 0x1;
519 : :
520 [ # # ]: 0 : if (nix->tx_compl_ena) {
521 : 0 : sq->cqid = sq->qid + dev->nb_rxq;
522 : 0 : sq->cq_ena = 1;
523 : 0 : cq = &dev->cqs[sq->cqid];
524 : 0 : cq->qid = sq->cqid;
525 : 0 : cq->nb_desc = nb_desc;
526 : 0 : rc = roc_nix_cq_init(&dev->nix, cq);
527 [ # # ]: 0 : if (rc) {
528 : 0 : plt_err("Failed to init cq=%d, rc=%d", cq->qid, rc);
529 : 0 : return rc;
530 : : }
531 : : }
532 : :
533 : 0 : rc = roc_nix_sq_init(&dev->nix, sq);
534 [ # # ]: 0 : if (rc) {
535 : 0 : plt_err("Failed to init sq=%d, rc=%d", qid, rc);
536 : 0 : return rc;
537 : : }
538 : :
539 : : rc = -ENOMEM;
540 : 0 : txq_sz = sizeof(struct cnxk_eth_txq_sp) + fp_tx_q_sz;
541 : 0 : txq_sp = plt_zmalloc(txq_sz, PLT_CACHE_LINE_SIZE);
542 [ # # ]: 0 : if (!txq_sp) {
543 : 0 : plt_err("Failed to alloc tx queue mem");
544 : 0 : rc |= roc_nix_sq_fini(sq);
545 : 0 : return rc;
546 : : }
547 : :
548 : 0 : txq_sp->dev = dev;
549 : 0 : txq_sp->qid = qid;
550 : 0 : txq_sp->qconf.conf.tx = *tx_conf;
551 : : /* Queue config should reflect global offloads */
552 : 0 : txq_sp->qconf.conf.tx.offloads = dev->tx_offloads;
553 : 0 : txq_sp->qconf.nb_desc = nb_desc;
554 : :
555 : 0 : plt_nix_dbg("sq=%d fc=%p offload=0x%" PRIx64 " lmt_addr=%p"
556 : : " nb_sqb_bufs=%d sqes_per_sqb_log2=%d",
557 : : qid, sq->fc, dev->tx_offloads, sq->lmt_addr,
558 : : sq->nb_sqb_bufs, sq->sqes_per_sqb_log2);
559 : :
560 : : /* Store start of fast path area */
561 : 0 : eth_dev->data->tx_queues[qid] = txq_sp + 1;
562 : 0 : eth_dev->data->tx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED;
563 : 0 : return 0;
564 : : }
565 : :
566 : : void
567 : 0 : cnxk_nix_tx_queue_release(struct rte_eth_dev *eth_dev, uint16_t qid)
568 : : {
569 : 0 : void *txq = eth_dev->data->tx_queues[qid];
570 : : struct cnxk_eth_txq_sp *txq_sp;
571 : : struct cnxk_eth_dev *dev;
572 : : struct roc_nix_sq *sq;
573 : : int rc;
574 : :
575 [ # # ]: 0 : if (!txq)
576 : : return;
577 : :
578 : : txq_sp = cnxk_eth_txq_to_sp(txq);
579 : :
580 : 0 : dev = txq_sp->dev;
581 : :
582 : 0 : plt_nix_dbg("Releasing txq %u", qid);
583 : :
584 : : /* Cleanup ROC SQ */
585 : 0 : sq = &dev->sqs[qid];
586 : 0 : rc = roc_nix_sq_fini(sq);
587 [ # # ]: 0 : if (rc)
588 : 0 : plt_err("Failed to cleanup sq, rc=%d", rc);
589 : :
590 : : /* Finally free */
591 : 0 : plt_free(txq_sp);
592 : : }
593 : :
594 : : static int
595 : 0 : cnxk_nix_process_rx_conf(const struct rte_eth_rxconf *rx_conf,
596 : : struct rte_mempool **lpb_pool,
597 : : struct rte_mempool **spb_pool)
598 : : {
599 : : struct rte_mempool *pool0;
600 : : struct rte_mempool *pool1;
601 : 0 : struct rte_mempool **mp = rx_conf->rx_mempools;
602 : : const char *platform_ops;
603 : : struct rte_mempool_ops *ops;
604 : :
605 [ # # ]: 0 : if (*lpb_pool ||
606 [ # # ]: 0 : rx_conf->rx_nmempool != CNXK_NIX_NUM_POOLS_MAX) {
607 : 0 : plt_err("invalid arguments");
608 : 0 : return -EINVAL;
609 : : }
610 : :
611 [ # # # # : 0 : if (mp == NULL || mp[0] == NULL || mp[1] == NULL) {
# # ]
612 : 0 : plt_err("invalid memory pools");
613 : 0 : return -EINVAL;
614 : : }
615 : :
616 : : pool0 = mp[0];
617 : : pool1 = mp[1];
618 : :
619 [ # # ]: 0 : if (pool0->elt_size > pool1->elt_size) {
620 : 0 : *lpb_pool = pool0;
621 : 0 : *spb_pool = pool1;
622 : :
623 : : } else {
624 : 0 : *lpb_pool = pool1;
625 : 0 : *spb_pool = pool0;
626 : : }
627 : :
628 [ # # ]: 0 : if ((*spb_pool)->pool_id == 0) {
629 : 0 : plt_err("Invalid pool_id");
630 : 0 : return -EINVAL;
631 : : }
632 : :
633 : 0 : platform_ops = rte_mbuf_platform_mempool_ops();
634 [ # # ]: 0 : ops = rte_mempool_get_ops((*spb_pool)->ops_index);
635 [ # # ]: 0 : if (strncmp(ops->name, platform_ops, RTE_MEMPOOL_OPS_NAMESIZE)) {
636 : 0 : plt_err("mempool ops should be of cnxk_npa type");
637 : 0 : return -EINVAL;
638 : : }
639 : :
640 : 0 : plt_info("spb_pool:%s lpb_pool:%s lpb_len:%u spb_len:%u", (*spb_pool)->name,
641 : : (*lpb_pool)->name, (*lpb_pool)->elt_size, (*spb_pool)->elt_size);
642 : :
643 : 0 : return 0;
644 : : }
645 : :
646 : : int
647 [ # # ]: 0 : cnxk_nix_rx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t qid,
648 : : uint32_t nb_desc, uint16_t fp_rx_q_sz,
649 : : const struct rte_eth_rxconf *rx_conf,
650 : : struct rte_mempool *mp)
651 : : {
652 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
653 : 0 : struct roc_nix *nix = &dev->nix;
654 : : struct cnxk_eth_rxq_sp *rxq_sp;
655 : : struct rte_mempool_ops *ops;
656 : : const char *platform_ops;
657 : : struct roc_nix_rq *rq;
658 : : struct roc_nix_cq *cq;
659 : : uint16_t first_skip;
660 : : uint16_t wqe_skip;
661 : : int rc = -EINVAL;
662 : : size_t rxq_sz;
663 : 0 : struct rte_mempool *lpb_pool = mp;
664 : 0 : struct rte_mempool *spb_pool = NULL;
665 : :
666 : : /* Sanity checks */
667 [ # # ]: 0 : if (rx_conf->rx_deferred_start == 1) {
668 : 0 : plt_err("Deferred Rx start is not supported");
669 : 0 : goto fail;
670 : : }
671 : :
672 [ # # ]: 0 : if (rx_conf->rx_nmempool > 0) {
673 : 0 : rc = cnxk_nix_process_rx_conf(rx_conf, &lpb_pool, &spb_pool);
674 [ # # ]: 0 : if (rc)
675 : 0 : goto fail;
676 : : }
677 : :
678 : 0 : platform_ops = rte_mbuf_platform_mempool_ops();
679 : : /* This driver needs cnxk_npa mempool ops to work */
680 [ # # ]: 0 : ops = rte_mempool_get_ops(lpb_pool->ops_index);
681 [ # # ]: 0 : if (strncmp(ops->name, platform_ops, RTE_MEMPOOL_OPS_NAMESIZE)) {
682 : 0 : plt_err("mempool ops should be of cnxk_npa type");
683 : 0 : goto fail;
684 : : }
685 : :
686 [ # # ]: 0 : if (lpb_pool->pool_id == 0) {
687 : 0 : plt_err("Invalid pool_id");
688 : 0 : goto fail;
689 : : }
690 : :
691 : : /* Free memory prior to re-allocation if needed */
692 [ # # ]: 0 : if (eth_dev->data->rx_queues[qid] != NULL) {
693 : 0 : const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
694 : :
695 : 0 : plt_nix_dbg("Freeing memory prior to re-allocation %d", qid);
696 : 0 : dev_ops->rx_queue_release(eth_dev, qid);
697 : 0 : eth_dev->data->rx_queues[qid] = NULL;
698 : : }
699 : :
700 : : /* Its a no-op when inline device is not used */
701 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY ||
702 [ # # ]: 0 : dev->tx_offloads & RTE_ETH_TX_OFFLOAD_SECURITY)
703 : 0 : roc_nix_inl_dev_xaq_realloc(lpb_pool->pool_id);
704 : :
705 : : /* Increase CQ size to Aura size to avoid CQ overflow and
706 : : * then CPT buffer leak.
707 : : */
708 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY)
709 : 0 : nb_desc = nix_inl_cq_sz_clamp_up(nix, lpb_pool, nb_desc);
710 : :
711 : : /* Setup ROC CQ */
712 : 0 : cq = &dev->cqs[qid];
713 : 0 : cq->qid = qid;
714 : 0 : cq->nb_desc = nb_desc;
715 : 0 : rc = roc_nix_cq_init(&dev->nix, cq);
716 [ # # ]: 0 : if (rc) {
717 : 0 : plt_err("Failed to init roc cq for rq=%d, rc=%d", qid, rc);
718 : 0 : goto fail;
719 : : }
720 : :
721 : : /* Setup ROC RQ */
722 : 0 : rq = &dev->rqs[qid];
723 : 0 : rq->qid = qid;
724 : 0 : rq->cqid = cq->qid;
725 : 0 : rq->aura_handle = lpb_pool->pool_id;
726 : 0 : rq->flow_tag_width = 32;
727 [ # # ]: 0 : rq->sso_ena = false;
728 : :
729 : : /* Calculate first mbuf skip */
730 : : first_skip = (sizeof(struct rte_mbuf));
731 : : first_skip += RTE_PKTMBUF_HEADROOM;
732 : 0 : first_skip += rte_pktmbuf_priv_size(lpb_pool);
733 : 0 : rq->first_skip = first_skip;
734 : 0 : rq->later_skip = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(lpb_pool);
735 [ # # ]: 0 : rq->lpb_size = lpb_pool->elt_size;
736 [ # # ]: 0 : if (roc_errata_nix_no_meta_aura())
737 : 0 : rq->lpb_drop_ena = !(dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY);
738 : :
739 : : /* Enable Inline IPSec on RQ, will not be used for Poll mode */
740 [ # # # # ]: 0 : if (roc_nix_inl_inb_is_enabled(nix) && !dev->inb.inl_dev) {
741 : 0 : rq->ipsech_ena = true;
742 : : /* WQE skip is needed when poll mode is enabled in CN10KA_B0 and above
743 : : * for Inline IPsec traffic to CQ without inline device.
744 : : */
745 : : wqe_skip = RTE_ALIGN_CEIL(sizeof(struct rte_mbuf), ROC_CACHE_LINE_SZ);
746 : : wqe_skip = wqe_skip / ROC_CACHE_LINE_SZ;
747 : 0 : rq->wqe_skip = wqe_skip;
748 : : }
749 : :
750 [ # # ]: 0 : if (spb_pool) {
751 : 0 : rq->spb_ena = 1;
752 : 0 : rq->spb_aura_handle = spb_pool->pool_id;
753 : 0 : rq->spb_size = spb_pool->elt_size;
754 : : }
755 : :
756 : 0 : rc = roc_nix_rq_init(&dev->nix, rq, !!eth_dev->data->dev_started);
757 [ # # ]: 0 : if (rc) {
758 : 0 : plt_err("Failed to init roc rq for rq=%d, rc=%d", qid, rc);
759 : 0 : goto cq_fini;
760 : : }
761 : :
762 : : /* Allocate and setup fast path rx queue */
763 : : rc = -ENOMEM;
764 : 0 : rxq_sz = sizeof(struct cnxk_eth_rxq_sp) + fp_rx_q_sz;
765 : 0 : rxq_sp = plt_zmalloc(rxq_sz, PLT_CACHE_LINE_SIZE);
766 [ # # ]: 0 : if (!rxq_sp) {
767 : 0 : plt_err("Failed to alloc rx queue for rq=%d", qid);
768 : 0 : goto rq_fini;
769 : : }
770 : :
771 : : /* Setup slow path fields */
772 : 0 : rxq_sp->dev = dev;
773 : 0 : rxq_sp->qid = qid;
774 : 0 : rxq_sp->qconf.conf.rx = *rx_conf;
775 : : /* Queue config should reflect global offloads */
776 : 0 : rxq_sp->qconf.conf.rx.offloads = dev->rx_offloads;
777 : 0 : rxq_sp->qconf.nb_desc = nb_desc;
778 : 0 : rxq_sp->qconf.mp = lpb_pool;
779 : 0 : rxq_sp->tc = 0;
780 : 0 : rxq_sp->tx_pause = (dev->fc_cfg.mode == RTE_ETH_FC_FULL ||
781 : : dev->fc_cfg.mode == RTE_ETH_FC_TX_PAUSE);
782 : :
783 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
784 : : /* Pass a tagmask used to handle error packets in inline device.
785 : : * Ethdev rq's tag_mask field will be overwritten later
786 : : * when sso is setup.
787 : : */
788 : 0 : rq->tag_mask =
789 : : 0x0FF00000 | ((uint32_t)RTE_EVENT_TYPE_ETHDEV << 28);
790 : :
791 : : /* Setup rq reference for inline dev if present */
792 : 0 : rc = roc_nix_inl_dev_rq_get(rq, !!eth_dev->data->dev_started);
793 [ # # ]: 0 : if (rc)
794 : 0 : goto free_mem;
795 : : }
796 : :
797 : 0 : plt_nix_dbg("rq=%d pool=%s nb_desc=%d->%d", qid, lpb_pool->name, nb_desc,
798 : : cq->nb_desc);
799 : :
800 : : /* Store start of fast path area */
801 : 0 : eth_dev->data->rx_queues[qid] = rxq_sp + 1;
802 : 0 : eth_dev->data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED;
803 : :
804 : : /* Calculating delta and freq mult between PTP HI clock and tsc.
805 : : * These are needed in deriving raw clock value from tsc counter.
806 : : * read_clock eth op returns raw clock value.
807 : : */
808 [ # # # # ]: 0 : if ((dev->rx_offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) || dev->ptp_en) {
809 : 0 : rc = cnxk_nix_tsc_convert(dev);
810 [ # # ]: 0 : if (rc) {
811 : 0 : plt_err("Failed to calculate delta and freq mult");
812 : 0 : goto rq_fini;
813 : : }
814 : : }
815 : :
816 : : return 0;
817 : : free_mem:
818 : 0 : plt_free(rxq_sp);
819 : 0 : rq_fini:
820 : 0 : rc |= roc_nix_rq_fini(rq);
821 : 0 : cq_fini:
822 : 0 : rc |= roc_nix_cq_fini(cq);
823 : : fail:
824 : : return rc;
825 : : }
826 : :
827 : : static void
828 : 0 : cnxk_nix_rx_queue_release(struct rte_eth_dev *eth_dev, uint16_t qid)
829 : : {
830 : 0 : void *rxq = eth_dev->data->rx_queues[qid];
831 : : struct cnxk_eth_rxq_sp *rxq_sp;
832 : : struct cnxk_eth_dev *dev;
833 : : struct roc_nix_rq *rq;
834 : : struct roc_nix_cq *cq;
835 : : int rc;
836 : :
837 [ # # ]: 0 : if (!rxq)
838 : : return;
839 : :
840 : : rxq_sp = cnxk_eth_rxq_to_sp(rxq);
841 : 0 : dev = rxq_sp->dev;
842 : 0 : rq = &dev->rqs[qid];
843 : :
844 : 0 : plt_nix_dbg("Releasing rxq %u", qid);
845 : :
846 : : /* Release rq reference for inline dev if present */
847 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY)
848 : 0 : roc_nix_inl_dev_rq_put(rq);
849 : :
850 : : /* Cleanup ROC RQ */
851 : 0 : rc = roc_nix_rq_fini(rq);
852 [ # # ]: 0 : if (rc)
853 : 0 : plt_err("Failed to cleanup rq, rc=%d", rc);
854 : :
855 : : /* Cleanup ROC CQ */
856 : 0 : cq = &dev->cqs[qid];
857 : 0 : rc = roc_nix_cq_fini(cq);
858 [ # # ]: 0 : if (rc)
859 : 0 : plt_err("Failed to cleanup cq, rc=%d", rc);
860 : :
861 : : /* Finally free fast path area */
862 : 0 : plt_free(rxq_sp);
863 : : }
864 : :
865 : : uint32_t
866 : 0 : cnxk_rss_ethdev_to_nix(struct cnxk_eth_dev *dev, uint64_t ethdev_rss,
867 : : uint8_t rss_level)
868 : : {
869 : 0 : uint32_t flow_key_type[RSS_MAX_LEVELS][6] = {
870 : : {FLOW_KEY_TYPE_IPV4, FLOW_KEY_TYPE_IPV6, FLOW_KEY_TYPE_TCP,
871 : : FLOW_KEY_TYPE_UDP, FLOW_KEY_TYPE_SCTP, FLOW_KEY_TYPE_ETH_DMAC},
872 : : {FLOW_KEY_TYPE_INNR_IPV4, FLOW_KEY_TYPE_INNR_IPV6,
873 : : FLOW_KEY_TYPE_INNR_TCP, FLOW_KEY_TYPE_INNR_UDP,
874 : : FLOW_KEY_TYPE_INNR_SCTP, FLOW_KEY_TYPE_INNR_ETH_DMAC},
875 : : {FLOW_KEY_TYPE_IPV4 | FLOW_KEY_TYPE_INNR_IPV4,
876 : : FLOW_KEY_TYPE_IPV6 | FLOW_KEY_TYPE_INNR_IPV6,
877 : : FLOW_KEY_TYPE_TCP | FLOW_KEY_TYPE_INNR_TCP,
878 : : FLOW_KEY_TYPE_UDP | FLOW_KEY_TYPE_INNR_UDP,
879 : : FLOW_KEY_TYPE_SCTP | FLOW_KEY_TYPE_INNR_SCTP,
880 : : FLOW_KEY_TYPE_ETH_DMAC | FLOW_KEY_TYPE_INNR_ETH_DMAC}
881 : : };
882 : : uint32_t flowkey_cfg = 0;
883 : :
884 : 0 : dev->ethdev_rss_hf = ethdev_rss;
885 : :
886 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_L2_PAYLOAD &&
887 [ # # ]: 0 : dev->npc.switch_header_type == ROC_PRIV_FLAGS_LEN_90B) {
888 : : flowkey_cfg |= FLOW_KEY_TYPE_CH_LEN_90B;
889 : : }
890 : :
891 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_C_VLAN)
892 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_VLAN;
893 : :
894 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_L3_SRC_ONLY)
895 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_L3_SRC;
896 : :
897 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_L3_DST_ONLY)
898 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_L3_DST;
899 : :
900 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_L4_SRC_ONLY)
901 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_L4_SRC;
902 : :
903 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_L4_DST_ONLY)
904 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_L4_DST;
905 : :
906 [ # # ]: 0 : if (ethdev_rss & RSS_IPV4_ENABLE)
907 : 0 : flowkey_cfg |= flow_key_type[rss_level][RSS_IPV4_INDEX];
908 : :
909 [ # # ]: 0 : if (ethdev_rss & RSS_IPV6_ENABLE)
910 : 0 : flowkey_cfg |= flow_key_type[rss_level][RSS_IPV6_INDEX];
911 : :
912 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_TCP)
913 : 0 : flowkey_cfg |= flow_key_type[rss_level][RSS_TCP_INDEX];
914 : :
915 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_UDP)
916 : 0 : flowkey_cfg |= flow_key_type[rss_level][RSS_UDP_INDEX];
917 : :
918 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_SCTP)
919 : 0 : flowkey_cfg |= flow_key_type[rss_level][RSS_SCTP_INDEX];
920 : :
921 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_L2_PAYLOAD)
922 : 0 : flowkey_cfg |= flow_key_type[rss_level][RSS_DMAC_INDEX];
923 : :
924 [ # # ]: 0 : if (ethdev_rss & RSS_IPV6_EX_ENABLE)
925 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_IPV6_EXT;
926 : :
927 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_PORT)
928 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_PORT;
929 : :
930 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_NVGRE)
931 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_NVGRE;
932 : :
933 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_VXLAN)
934 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_VXLAN;
935 : :
936 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_GENEVE)
937 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_GENEVE;
938 : :
939 [ # # ]: 0 : if (ethdev_rss & RTE_ETH_RSS_GTPU)
940 : 0 : flowkey_cfg |= FLOW_KEY_TYPE_GTPU;
941 : :
942 : 0 : return flowkey_cfg;
943 : : }
944 : :
945 : : static int
946 : 0 : nix_rxchan_cfg_disable(struct cnxk_eth_dev *dev)
947 : : {
948 : 0 : struct roc_nix *nix = &dev->nix;
949 : : struct roc_nix_fc_cfg fc_cfg;
950 : : int rc;
951 : :
952 [ # # ]: 0 : if (!roc_nix_is_lbk(nix))
953 : : return 0;
954 : :
955 : : memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
956 : : fc_cfg.type = ROC_NIX_FC_RXCHAN_CFG;
957 : : fc_cfg.rxchan_cfg.enable = false;
958 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
959 [ # # ]: 0 : if (rc) {
960 : 0 : plt_err("Failed to setup flow control, rc=%d(%s)", rc, roc_error_msg_get(rc));
961 : 0 : return rc;
962 : : }
963 : : return 0;
964 : : }
965 : :
966 : : static void
967 : 0 : nix_free_queue_mem(struct cnxk_eth_dev *dev)
968 : : {
969 : 0 : plt_free(dev->rqs);
970 : 0 : plt_free(dev->cqs);
971 : 0 : plt_free(dev->sqs);
972 : 0 : dev->rqs = NULL;
973 : 0 : dev->cqs = NULL;
974 : 0 : dev->sqs = NULL;
975 : 0 : }
976 : :
977 : : static int
978 : 0 : nix_ingress_policer_setup(struct cnxk_eth_dev *dev)
979 : : {
980 : 0 : struct rte_eth_dev *eth_dev = dev->eth_dev;
981 : : int rc = 0;
982 : :
983 : 0 : TAILQ_INIT(&dev->mtr_profiles);
984 : 0 : TAILQ_INIT(&dev->mtr_policy);
985 : 0 : TAILQ_INIT(&dev->mtr);
986 : :
987 [ # # ]: 0 : if (eth_dev->dev_ops->mtr_ops_get == NULL)
988 : : return rc;
989 : :
990 : 0 : return nix_mtr_capabilities_init(eth_dev);
991 : : }
992 : :
993 : : static int
994 : 0 : nix_rss_default_setup(struct cnxk_eth_dev *dev)
995 : : {
996 : 0 : struct rte_eth_dev *eth_dev = dev->eth_dev;
997 : : uint8_t rss_hash_level;
998 : : uint32_t flowkey_cfg;
999 : : uint64_t rss_hf;
1000 : :
1001 : 0 : rss_hf = eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
1002 : 0 : rss_hash_level = RTE_ETH_RSS_LEVEL(rss_hf);
1003 [ # # ]: 0 : if (rss_hash_level)
1004 : 0 : rss_hash_level -= 1;
1005 : :
1006 : 0 : flowkey_cfg = cnxk_rss_ethdev_to_nix(dev, rss_hf, rss_hash_level);
1007 : 0 : return roc_nix_rss_default_setup(&dev->nix, flowkey_cfg);
1008 : : }
1009 : :
1010 : : static int
1011 [ # # ]: 0 : nix_store_queue_cfg_and_then_release(struct rte_eth_dev *eth_dev)
1012 : : {
1013 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1014 : 0 : const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
1015 : : struct cnxk_eth_qconf *tx_qconf = NULL;
1016 : : struct cnxk_eth_qconf *rx_qconf = NULL;
1017 : : struct cnxk_eth_rxq_sp *rxq_sp;
1018 : : struct cnxk_eth_txq_sp *txq_sp;
1019 : : int i, nb_rxq, nb_txq;
1020 : : void **txq, **rxq;
1021 : :
1022 : 0 : nb_rxq = RTE_MIN(dev->nb_rxq, eth_dev->data->nb_rx_queues);
1023 : 0 : nb_txq = RTE_MIN(dev->nb_txq, eth_dev->data->nb_tx_queues);
1024 : :
1025 : 0 : tx_qconf = malloc(nb_txq * sizeof(*tx_qconf));
1026 [ # # ]: 0 : if (tx_qconf == NULL) {
1027 : 0 : plt_err("Failed to allocate memory for tx_qconf");
1028 : 0 : goto fail;
1029 : : }
1030 : :
1031 : 0 : rx_qconf = malloc(nb_rxq * sizeof(*rx_qconf));
1032 [ # # ]: 0 : if (rx_qconf == NULL) {
1033 : 0 : plt_err("Failed to allocate memory for rx_qconf");
1034 : 0 : goto fail;
1035 : : }
1036 : :
1037 : 0 : txq = eth_dev->data->tx_queues;
1038 [ # # ]: 0 : for (i = 0; i < nb_txq; i++) {
1039 [ # # ]: 0 : if (txq[i] == NULL) {
1040 : 0 : tx_qconf[i].valid = false;
1041 : 0 : plt_info("txq[%d] is already released", i);
1042 : 0 : continue;
1043 : : }
1044 : : txq_sp = cnxk_eth_txq_to_sp(txq[i]);
1045 : 0 : memcpy(&tx_qconf[i], &txq_sp->qconf, sizeof(*tx_qconf));
1046 : 0 : tx_qconf[i].valid = true;
1047 : 0 : dev_ops->tx_queue_release(eth_dev, i);
1048 : 0 : eth_dev->data->tx_queues[i] = NULL;
1049 : : }
1050 : :
1051 : 0 : rxq = eth_dev->data->rx_queues;
1052 [ # # ]: 0 : for (i = 0; i < nb_rxq; i++) {
1053 [ # # ]: 0 : if (rxq[i] == NULL) {
1054 : 0 : rx_qconf[i].valid = false;
1055 : 0 : plt_info("rxq[%d] is already released", i);
1056 : 0 : continue;
1057 : : }
1058 : : rxq_sp = cnxk_eth_rxq_to_sp(rxq[i]);
1059 : 0 : memcpy(&rx_qconf[i], &rxq_sp->qconf, sizeof(*rx_qconf));
1060 : 0 : rx_qconf[i].valid = true;
1061 : 0 : dev_ops->rx_queue_release(eth_dev, i);
1062 : 0 : eth_dev->data->rx_queues[i] = NULL;
1063 : : }
1064 : :
1065 : 0 : dev->tx_qconf = tx_qconf;
1066 : 0 : dev->rx_qconf = rx_qconf;
1067 : 0 : return 0;
1068 : :
1069 : 0 : fail:
1070 : 0 : free(tx_qconf);
1071 : : free(rx_qconf);
1072 : 0 : return -ENOMEM;
1073 : : }
1074 : :
1075 : : static int
1076 : 0 : nix_restore_queue_cfg(struct rte_eth_dev *eth_dev)
1077 : : {
1078 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1079 : 0 : const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
1080 : 0 : struct cnxk_eth_qconf *tx_qconf = dev->tx_qconf;
1081 : 0 : struct cnxk_eth_qconf *rx_qconf = dev->rx_qconf;
1082 : : int rc, i, nb_rxq, nb_txq;
1083 : :
1084 : 0 : nb_rxq = RTE_MIN(dev->nb_rxq, eth_dev->data->nb_rx_queues);
1085 : 0 : nb_txq = RTE_MIN(dev->nb_txq, eth_dev->data->nb_tx_queues);
1086 : :
1087 : : rc = -ENOMEM;
1088 : : /* Setup tx & rx queues with previous configuration so
1089 : : * that the queues can be functional in cases like ports
1090 : : * are started without re configuring queues.
1091 : : *
1092 : : * Usual re config sequence is like below:
1093 : : * port_configure() {
1094 : : * if(reconfigure) {
1095 : : * queue_release()
1096 : : * queue_setup()
1097 : : * }
1098 : : * queue_configure() {
1099 : : * queue_release()
1100 : : * queue_setup()
1101 : : * }
1102 : : * }
1103 : : * port_start()
1104 : : *
1105 : : * In some application's control path, queue_configure() would
1106 : : * NOT be invoked for TXQs/RXQs in port_configure().
1107 : : * In such cases, queues can be functional after start as the
1108 : : * queues are already setup in port_configure().
1109 : : */
1110 [ # # ]: 0 : for (i = 0; i < nb_txq; i++) {
1111 [ # # ]: 0 : if (!tx_qconf[i].valid)
1112 : 0 : continue;
1113 : 0 : rc = dev_ops->tx_queue_setup(eth_dev, i, tx_qconf[i].nb_desc, 0,
1114 : 0 : &tx_qconf[i].conf.tx);
1115 [ # # ]: 0 : if (rc) {
1116 : 0 : plt_err("Failed to setup tx queue rc=%d", rc);
1117 [ # # ]: 0 : for (i -= 1; i >= 0; i--)
1118 : 0 : dev_ops->tx_queue_release(eth_dev, i);
1119 : 0 : goto fail;
1120 : : }
1121 : : }
1122 : :
1123 : 0 : free(tx_qconf);
1124 : : tx_qconf = NULL;
1125 : :
1126 [ # # ]: 0 : for (i = 0; i < nb_rxq; i++) {
1127 [ # # ]: 0 : if (!rx_qconf[i].valid)
1128 : 0 : continue;
1129 : 0 : rc = dev_ops->rx_queue_setup(eth_dev, i, rx_qconf[i].nb_desc, 0,
1130 : 0 : &rx_qconf[i].conf.rx,
1131 : : rx_qconf[i].mp);
1132 [ # # ]: 0 : if (rc) {
1133 : 0 : plt_err("Failed to setup rx queue rc=%d", rc);
1134 [ # # ]: 0 : for (i -= 1; i >= 0; i--)
1135 : 0 : dev_ops->rx_queue_release(eth_dev, i);
1136 : 0 : goto tx_queue_release;
1137 : : }
1138 : : }
1139 : :
1140 : 0 : free(rx_qconf);
1141 : : rx_qconf = NULL;
1142 : :
1143 : 0 : return 0;
1144 : :
1145 : : tx_queue_release:
1146 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
1147 : 0 : dev_ops->tx_queue_release(eth_dev, i);
1148 : 0 : fail:
1149 : 0 : free(tx_qconf);
1150 : 0 : free(rx_qconf);
1151 : :
1152 : 0 : return rc;
1153 : : }
1154 : :
1155 : : static void
1156 : : nix_set_nop_rxtx_function(struct rte_eth_dev *eth_dev)
1157 : : {
1158 : : /* These dummy functions are required for supporting
1159 : : * some applications which reconfigure queues without
1160 : : * stopping tx burst and rx burst threads.
1161 : : * When the queues context is saved, txq/rxqs are released
1162 : : * which caused app crash since rx/tx burst is still
1163 : : * on different lcores
1164 : : */
1165 : 0 : eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
1166 : 0 : eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
1167 : : rte_mb();
1168 : : }
1169 : :
1170 : : static int
1171 : 0 : nix_lso_tun_fmt_update(struct cnxk_eth_dev *dev)
1172 : : {
1173 : : uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX];
1174 : : uint8_t tun[ROC_NIX_LSO_TUN_MAX];
1175 : 0 : struct roc_nix *nix = &dev->nix;
1176 : : int rc;
1177 : :
1178 : 0 : rc = roc_nix_lso_fmt_get(nix, udp_tun, tun);
1179 [ # # ]: 0 : if (rc)
1180 : : return rc;
1181 : :
1182 : 0 : dev->lso_tun_fmt = ((uint64_t)tun[ROC_NIX_LSO_TUN_V4V4] |
1183 : 0 : (uint64_t)tun[ROC_NIX_LSO_TUN_V4V6] << 8 |
1184 : 0 : (uint64_t)tun[ROC_NIX_LSO_TUN_V6V4] << 16 |
1185 : 0 : (uint64_t)tun[ROC_NIX_LSO_TUN_V6V6] << 24);
1186 : :
1187 : 0 : dev->lso_tun_fmt |= ((uint64_t)udp_tun[ROC_NIX_LSO_TUN_V4V4] << 32 |
1188 : 0 : (uint64_t)udp_tun[ROC_NIX_LSO_TUN_V4V6] << 40 |
1189 : 0 : (uint64_t)udp_tun[ROC_NIX_LSO_TUN_V6V4] << 48 |
1190 : 0 : (uint64_t)udp_tun[ROC_NIX_LSO_TUN_V6V6] << 56);
1191 : 0 : return 0;
1192 : : }
1193 : :
1194 : : static int
1195 : 0 : nix_lso_fmt_setup(struct cnxk_eth_dev *dev)
1196 : : {
1197 : 0 : struct roc_nix *nix = &dev->nix;
1198 : : int rc;
1199 : :
1200 : : /* Nothing much to do if offload is not enabled */
1201 [ # # ]: 0 : if (!(dev->tx_offloads &
1202 : : (RTE_ETH_TX_OFFLOAD_TCP_TSO | RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
1203 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO | RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO)))
1204 : : return 0;
1205 : :
1206 : : /* Setup LSO formats in AF. Its a no-op if other ethdev has
1207 : : * already set it up
1208 : : */
1209 : 0 : rc = roc_nix_lso_fmt_setup(nix);
1210 [ # # ]: 0 : if (rc)
1211 : : return rc;
1212 : :
1213 : 0 : return nix_lso_tun_fmt_update(dev);
1214 : : }
1215 : :
1216 : : int
1217 : 0 : cnxk_nix_configure(struct rte_eth_dev *eth_dev)
1218 : : {
1219 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1220 : : struct rte_eth_dev_data *data = eth_dev->data;
1221 : : struct rte_eth_conf *conf = &data->dev_conf;
1222 : : struct rte_eth_rxmode *rxmode = &conf->rxmode;
1223 : : struct rte_eth_txmode *txmode = &conf->txmode;
1224 : : char ea_fmt[RTE_ETHER_ADDR_FMT_SIZE];
1225 : 0 : struct roc_nix_fc_cfg fc_cfg = {0};
1226 : 0 : struct roc_nix *nix = &dev->nix;
1227 : : uint16_t nb_rxq, nb_txq, nb_cq;
1228 : : struct rte_ether_addr *ea;
1229 : : uint64_t rx_cfg;
1230 : : void *qs;
1231 : : int rc;
1232 : :
1233 : : rc = -EINVAL;
1234 : :
1235 : : /* Sanity checks */
1236 [ # # ]: 0 : if (rte_eal_has_hugepages() == 0) {
1237 : 0 : plt_err("Huge page is not configured");
1238 : 0 : goto fail_configure;
1239 : : }
1240 : :
1241 [ # # ]: 0 : if (conf->dcb_capability_en == 1) {
1242 : 0 : plt_err("dcb enable is not supported");
1243 : 0 : goto fail_configure;
1244 : : }
1245 : :
1246 [ # # ]: 0 : if (rxmode->mq_mode != RTE_ETH_MQ_RX_NONE &&
1247 : : rxmode->mq_mode != RTE_ETH_MQ_RX_RSS) {
1248 : 0 : plt_err("Unsupported mq rx mode %d", rxmode->mq_mode);
1249 : 0 : goto fail_configure;
1250 : : }
1251 : :
1252 [ # # ]: 0 : if (txmode->mq_mode != RTE_ETH_MQ_TX_NONE) {
1253 : 0 : plt_err("Unsupported mq tx mode %d", txmode->mq_mode);
1254 : 0 : goto fail_configure;
1255 : : }
1256 : :
1257 : : /* Free the resources allocated from the previous configure */
1258 [ # # ]: 0 : if (dev->configured == 1) {
1259 : : /* Unregister queue irq's */
1260 : 0 : roc_nix_unregister_queue_irqs(nix);
1261 : :
1262 : : /* Unregister CQ irqs if present */
1263 [ # # ]: 0 : if (eth_dev->data->dev_conf.intr_conf.rxq)
1264 : 0 : roc_nix_unregister_cq_irqs(nix);
1265 : :
1266 : : /* Set no-op functions */
1267 : : nix_set_nop_rxtx_function(eth_dev);
1268 : : /* Store queue config for later */
1269 : 0 : rc = nix_store_queue_cfg_and_then_release(eth_dev);
1270 [ # # ]: 0 : if (rc)
1271 : 0 : goto fail_configure;
1272 : :
1273 : : /* Disable and free rte_meter entries */
1274 : 0 : rc = nix_meter_fini(dev);
1275 [ # # ]: 0 : if (rc)
1276 : 0 : goto fail_configure;
1277 : :
1278 : : /* Cleanup security support */
1279 : 0 : rc = nix_security_release(dev);
1280 [ # # ]: 0 : if (rc)
1281 : 0 : goto fail_configure;
1282 : :
1283 : 0 : roc_nix_tm_fini(nix);
1284 : 0 : nix_rxchan_cfg_disable(dev);
1285 : 0 : roc_nix_lf_free(nix);
1286 : : }
1287 : :
1288 : 0 : dev->rx_offloads = rxmode->offloads;
1289 : 0 : dev->tx_offloads = txmode->offloads;
1290 : :
1291 [ # # ]: 0 : if (nix->custom_inb_sa)
1292 : 0 : dev->rx_offloads |= RTE_ETH_RX_OFFLOAD_SECURITY;
1293 : :
1294 : : /* Prepare rx cfg */
1295 : : rx_cfg = ROC_NIX_LF_RX_CFG_DIS_APAD;
1296 [ # # ]: 0 : if (dev->rx_offloads &
1297 : : (RTE_ETH_RX_OFFLOAD_TCP_CKSUM | RTE_ETH_RX_OFFLOAD_UDP_CKSUM)) {
1298 : : rx_cfg |= ROC_NIX_LF_RX_CFG_CSUM_OL4;
1299 : : rx_cfg |= ROC_NIX_LF_RX_CFG_CSUM_IL4;
1300 : : }
1301 [ # # ]: 0 : rx_cfg |= (ROC_NIX_LF_RX_CFG_DROP_RE | ROC_NIX_LF_RX_CFG_L2_LEN_ERR |
1302 : : ROC_NIX_LF_RX_CFG_LEN_IL4 | ROC_NIX_LF_RX_CFG_LEN_IL3 |
1303 : : ROC_NIX_LF_RX_CFG_LEN_OL4 | ROC_NIX_LF_RX_CFG_LEN_OL3);
1304 : :
1305 : : rx_cfg &= (ROC_NIX_LF_RX_CFG_RX_ERROR_MASK);
1306 : :
1307 [ # # ]: 0 : if (roc_feature_nix_has_drop_re_mask())
1308 : 0 : rx_cfg |= (ROC_NIX_RE_CRC8_PCH | ROC_NIX_RE_MACSEC);
1309 : :
1310 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
1311 : 0 : rx_cfg |= ROC_NIX_LF_RX_CFG_IP6_UDP_OPT;
1312 : : /* Disable drop re if rx offload security is enabled and
1313 : : * platform does not support it.
1314 : : */
1315 [ # # ]: 0 : if (dev->ipsecd_drop_re_dis)
1316 : 0 : rx_cfg &= ~(ROC_NIX_LF_RX_CFG_DROP_RE);
1317 : : }
1318 : :
1319 : 0 : nb_rxq = RTE_MAX(data->nb_rx_queues, 1);
1320 : 0 : nb_txq = RTE_MAX(data->nb_tx_queues, 1);
1321 : :
1322 [ # # ]: 0 : if (roc_nix_is_lbk(nix))
1323 : 0 : nix->enable_loop = eth_dev->data->dev_conf.lpbk_mode;
1324 : :
1325 : 0 : nix->tx_compl_ena = dev->tx_compl_ena;
1326 : :
1327 : : /* Alloc a nix lf */
1328 : 0 : rc = roc_nix_lf_alloc(nix, nb_rxq, nb_txq, rx_cfg);
1329 [ # # ]: 0 : if (rc) {
1330 : 0 : plt_err("Failed to init nix_lf rc=%d", rc);
1331 : 0 : goto fail_configure;
1332 : : }
1333 : :
1334 [ # # ]: 0 : if (!roc_nix_is_vf_or_sdp(nix)) {
1335 : : /* Sync same MAC address to CGX/RPM table */
1336 : 0 : rc = roc_nix_mac_addr_set(nix, dev->mac_addr);
1337 [ # # ]: 0 : if (rc) {
1338 : 0 : plt_err("Failed to set mac addr, rc=%d", rc);
1339 : 0 : goto fail_configure;
1340 : : }
1341 : : }
1342 : :
1343 : : /* Check if ptp is enable in PF owning this VF*/
1344 [ # # # # ]: 0 : if (!roc_nix_is_pf(nix) && (!roc_nix_is_sdp(nix)))
1345 : 0 : dev->ptp_en = roc_nix_ptp_is_enable(nix);
1346 : :
1347 : 0 : dev->npc.channel = roc_nix_get_base_chan(nix);
1348 : :
1349 : 0 : nb_rxq = data->nb_rx_queues;
1350 : 0 : nb_txq = data->nb_tx_queues;
1351 : : nb_cq = nb_rxq;
1352 [ # # ]: 0 : if (nix->tx_compl_ena)
1353 : 0 : nb_cq += nb_txq;
1354 : : rc = -ENOMEM;
1355 [ # # ]: 0 : if (nb_rxq) {
1356 : : /* Allocate memory for roc rq's and cq's */
1357 : 0 : qs = plt_zmalloc(sizeof(struct roc_nix_rq) * nb_rxq, 0);
1358 [ # # ]: 0 : if (!qs) {
1359 : 0 : plt_err("Failed to alloc rqs");
1360 : 0 : goto free_nix_lf;
1361 : : }
1362 : 0 : dev->rqs = qs;
1363 : : }
1364 : :
1365 [ # # ]: 0 : if (nb_txq) {
1366 : : /* Allocate memory for roc sq's */
1367 : 0 : qs = plt_zmalloc(sizeof(struct roc_nix_sq) * nb_txq, 0);
1368 [ # # ]: 0 : if (!qs) {
1369 : 0 : plt_err("Failed to alloc sqs");
1370 : 0 : goto free_nix_lf;
1371 : : }
1372 : 0 : dev->sqs = qs;
1373 : : }
1374 : :
1375 [ # # ]: 0 : if (nb_cq) {
1376 : 0 : qs = plt_zmalloc(sizeof(struct roc_nix_cq) * nb_cq, 0);
1377 [ # # ]: 0 : if (!qs) {
1378 : 0 : plt_err("Failed to alloc cqs");
1379 : 0 : goto free_nix_lf;
1380 : : }
1381 : 0 : dev->cqs = qs;
1382 : : }
1383 : :
1384 : : /* Re-enable NIX LF error interrupts */
1385 : 0 : roc_nix_err_intr_ena_dis(nix, true);
1386 : 0 : roc_nix_ras_intr_ena_dis(nix, true);
1387 : :
1388 [ # # ]: 0 : if (nix->rx_ptp_ena &&
1389 [ # # ]: 0 : dev->npc.switch_header_type == ROC_PRIV_FLAGS_HIGIG) {
1390 : 0 : plt_err("Both PTP and switch header enabled");
1391 : 0 : goto free_nix_lf;
1392 : : }
1393 : :
1394 : 0 : rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
1395 : 0 : dev->npc.pre_l2_size_offset,
1396 : 0 : dev->npc.pre_l2_size_offset_mask,
1397 : 0 : dev->npc.pre_l2_size_shift_dir);
1398 [ # # ]: 0 : if (rc) {
1399 : 0 : plt_err("Failed to enable switch type nix_lf rc=%d", rc);
1400 : 0 : goto free_nix_lf;
1401 : : }
1402 : :
1403 : : /* Setup LSO if needed */
1404 : 0 : rc = nix_lso_fmt_setup(dev);
1405 [ # # ]: 0 : if (rc) {
1406 : 0 : plt_err("Failed to setup nix lso format fields, rc=%d", rc);
1407 : 0 : goto free_nix_lf;
1408 : : }
1409 : :
1410 : : /* Configure RSS */
1411 : 0 : rc = nix_rss_default_setup(dev);
1412 [ # # ]: 0 : if (rc) {
1413 : 0 : plt_err("Failed to configure rss rc=%d", rc);
1414 : 0 : goto free_nix_lf;
1415 : : }
1416 : :
1417 : : /* Overwrite default RSS setup if requested by user */
1418 : 0 : rc = cnxk_nix_rss_hash_update(eth_dev, &conf->rx_adv_conf.rss_conf);
1419 [ # # ]: 0 : if (rc) {
1420 : 0 : plt_err("Failed to configure rss rc=%d", rc);
1421 : 0 : goto free_nix_lf;
1422 : : }
1423 : :
1424 : : /* Init the default TM scheduler hierarchy */
1425 : 0 : rc = roc_nix_tm_init(nix);
1426 [ # # ]: 0 : if (rc) {
1427 : 0 : plt_err("Failed to init traffic manager, rc=%d", rc);
1428 : 0 : goto free_nix_lf;
1429 : : }
1430 : :
1431 : 0 : rc = nix_ingress_policer_setup(dev);
1432 [ # # ]: 0 : if (rc) {
1433 : 0 : plt_err("Failed to setup ingress policer rc=%d", rc);
1434 : 0 : goto free_nix_lf;
1435 : : }
1436 : :
1437 : 0 : rc = roc_nix_tm_hierarchy_enable(nix, ROC_NIX_TM_DEFAULT, false);
1438 [ # # ]: 0 : if (rc) {
1439 : 0 : plt_err("Failed to enable default tm hierarchy, rc=%d", rc);
1440 : 0 : goto tm_fini;
1441 : : }
1442 : :
1443 : : /* Register queue IRQs */
1444 : 0 : rc = roc_nix_register_queue_irqs(nix);
1445 [ # # ]: 0 : if (rc) {
1446 : 0 : plt_err("Failed to register queue interrupts rc=%d", rc);
1447 : 0 : goto tm_fini;
1448 : : }
1449 : :
1450 : : /* Register cq IRQs */
1451 [ # # ]: 0 : if (eth_dev->data->dev_conf.intr_conf.rxq) {
1452 [ # # ]: 0 : if (eth_dev->data->nb_rx_queues > dev->nix.cints) {
1453 : 0 : plt_err("Rx interrupt cannot be enabled, rxq > %d",
1454 : : dev->nix.cints);
1455 : 0 : goto q_irq_fini;
1456 : : }
1457 : : /* Rx interrupt feature cannot work with vector mode because,
1458 : : * vector mode does not process packets unless min 4 pkts are
1459 : : * received, while cq interrupts are generated even for 1 pkt
1460 : : * in the CQ.
1461 : : */
1462 : 0 : dev->scalar_ena = true;
1463 : :
1464 : 0 : rc = roc_nix_register_cq_irqs(nix);
1465 [ # # ]: 0 : if (rc) {
1466 : 0 : plt_err("Failed to register CQ interrupts rc=%d", rc);
1467 : 0 : goto q_irq_fini;
1468 : : }
1469 : : }
1470 : :
1471 [ # # ]: 0 : if (roc_nix_is_lbk(nix))
1472 : 0 : goto skip_lbk_setup;
1473 : :
1474 : : /* Configure loop back mode */
1475 : 0 : rc = roc_nix_mac_loopback_enable(nix,
1476 : 0 : eth_dev->data->dev_conf.lpbk_mode);
1477 [ # # ]: 0 : if (rc) {
1478 : 0 : plt_err("Failed to configure cgx loop back mode rc=%d", rc);
1479 : 0 : goto cq_fini;
1480 : : }
1481 : :
1482 : 0 : skip_lbk_setup:
1483 : : /* Setup Inline security support */
1484 : 0 : rc = nix_security_setup(dev);
1485 [ # # ]: 0 : if (rc)
1486 : 0 : goto cq_fini;
1487 : :
1488 : : /* Init flow control configuration */
1489 [ # # ]: 0 : if (!roc_nix_is_esw(nix)) {
1490 : 0 : fc_cfg.type = ROC_NIX_FC_RXCHAN_CFG;
1491 : 0 : fc_cfg.rxchan_cfg.enable = true;
1492 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
1493 [ # # ]: 0 : if (rc) {
1494 : 0 : plt_err("Failed to initialize flow control rc=%d", rc);
1495 : 0 : goto cq_fini;
1496 : : }
1497 : : }
1498 : :
1499 : : /* Update flow control configuration to PMD */
1500 : 0 : rc = nix_init_flow_ctrl_config(eth_dev);
1501 [ # # ]: 0 : if (rc) {
1502 : 0 : plt_err("Failed to initialize flow control rc=%d", rc);
1503 : 0 : goto cq_fini;
1504 : : }
1505 : :
1506 : : /*
1507 : : * Restore queue config when reconfigure followed by
1508 : : * reconfigure and no queue configure invoked from application case.
1509 : : */
1510 [ # # ]: 0 : if (dev->configured == 1) {
1511 : 0 : rc = nix_restore_queue_cfg(eth_dev);
1512 [ # # ]: 0 : if (rc)
1513 : 0 : goto sec_release;
1514 : : }
1515 : :
1516 : : /* Update the mac address */
1517 : 0 : ea = eth_dev->data->mac_addrs;
1518 [ # # ]: 0 : memcpy(ea, dev->mac_addr, RTE_ETHER_ADDR_LEN);
1519 [ # # ]: 0 : if (rte_is_zero_ether_addr(ea))
1520 : 0 : rte_eth_random_addr((uint8_t *)ea);
1521 : :
1522 : 0 : rte_ether_format_addr(ea_fmt, RTE_ETHER_ADDR_FMT_SIZE, ea);
1523 : :
1524 : 0 : plt_nix_dbg("Configured port%d mac=%s nb_rxq=%d nb_txq=%d"
1525 : : " rx_offloads=0x%" PRIx64 " tx_offloads=0x%" PRIx64 "",
1526 : : eth_dev->data->port_id, ea_fmt, nb_rxq, nb_txq,
1527 : : dev->rx_offloads, dev->tx_offloads);
1528 : :
1529 : : /* All good */
1530 : 0 : dev->configured = 1;
1531 : 0 : dev->nb_rxq = data->nb_rx_queues;
1532 : 0 : dev->nb_txq = data->nb_tx_queues;
1533 : 0 : return 0;
1534 : :
1535 : : sec_release:
1536 : 0 : rc |= nix_security_release(dev);
1537 : 0 : cq_fini:
1538 : 0 : roc_nix_unregister_cq_irqs(nix);
1539 : 0 : q_irq_fini:
1540 : 0 : roc_nix_unregister_queue_irqs(nix);
1541 : 0 : tm_fini:
1542 : 0 : roc_nix_tm_fini(nix);
1543 : 0 : free_nix_lf:
1544 : 0 : nix_free_queue_mem(dev);
1545 : 0 : rc |= nix_rxchan_cfg_disable(dev);
1546 : 0 : rc |= roc_nix_lf_free(nix);
1547 : 0 : fail_configure:
1548 : 0 : dev->configured = 0;
1549 : 0 : return rc;
1550 : : }
1551 : :
1552 : : int
1553 [ # # ]: 0 : cnxk_nix_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qid)
1554 : : {
1555 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1556 : : struct rte_eth_dev_data *data = eth_dev->data;
1557 : 0 : struct roc_nix_sq *sq = &dev->sqs[qid];
1558 : : int rc = -EINVAL;
1559 : :
1560 [ # # ]: 0 : if (data->tx_queue_state[qid] == RTE_ETH_QUEUE_STATE_STARTED)
1561 : : return 0;
1562 : :
1563 : 0 : rc = roc_nix_sq_ena_dis(sq, true);
1564 [ # # ]: 0 : if (rc) {
1565 : 0 : plt_err("Failed to enable sq aura fc, txq=%u, rc=%d", qid, rc);
1566 : 0 : goto done;
1567 : : }
1568 : :
1569 : 0 : data->tx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STARTED;
1570 : : done:
1571 : : return rc;
1572 : : }
1573 : :
1574 : : int
1575 [ # # ]: 0 : cnxk_nix_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qid)
1576 : : {
1577 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1578 : : struct rte_eth_dev_data *data = eth_dev->data;
1579 : 0 : struct roc_nix_sq *sq = &dev->sqs[qid];
1580 : : int rc;
1581 : :
1582 [ # # ]: 0 : if (data->tx_queue_state[qid] == RTE_ETH_QUEUE_STATE_STOPPED)
1583 : : return 0;
1584 : :
1585 : 0 : rc = roc_nix_sq_ena_dis(sq, false);
1586 [ # # ]: 0 : if (rc) {
1587 : 0 : plt_err("Failed to disable sqb aura fc, txq=%u, rc=%d", qid,
1588 : : rc);
1589 : 0 : goto done;
1590 : : }
1591 : :
1592 : 0 : data->tx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED;
1593 : : done:
1594 : : return rc;
1595 : : }
1596 : :
1597 : : static int
1598 [ # # ]: 0 : cnxk_nix_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qid)
1599 : : {
1600 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1601 : : struct rte_eth_dev_data *data = eth_dev->data;
1602 : 0 : struct roc_nix_rq *rq = &dev->rqs[qid];
1603 : : int rc;
1604 : :
1605 [ # # ]: 0 : if (data->rx_queue_state[qid] == RTE_ETH_QUEUE_STATE_STARTED)
1606 : : return 0;
1607 : :
1608 : 0 : rc = roc_nix_rq_ena_dis(rq, true);
1609 [ # # ]: 0 : if (rc) {
1610 : 0 : plt_err("Failed to enable rxq=%u, rc=%d", qid, rc);
1611 : 0 : goto done;
1612 : : }
1613 : :
1614 : 0 : data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STARTED;
1615 : : done:
1616 : : return rc;
1617 : : }
1618 : :
1619 : : static int
1620 [ # # ]: 0 : cnxk_nix_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qid)
1621 : : {
1622 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1623 : : struct rte_eth_dev_data *data = eth_dev->data;
1624 : 0 : struct roc_nix_rq *rq = &dev->rqs[qid];
1625 : : int rc;
1626 : :
1627 [ # # ]: 0 : if (data->rx_queue_state[qid] == RTE_ETH_QUEUE_STATE_STOPPED)
1628 : : return 0;
1629 : :
1630 : 0 : rc = roc_nix_rq_ena_dis(rq, false);
1631 [ # # ]: 0 : if (rc) {
1632 : 0 : plt_err("Failed to disable rxq=%u, rc=%d", qid, rc);
1633 : 0 : goto done;
1634 : : }
1635 : :
1636 : 0 : data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED;
1637 : : done:
1638 : : return rc;
1639 : : }
1640 : :
1641 : : static int
1642 [ # # ]: 0 : cnxk_nix_dev_stop(struct rte_eth_dev *eth_dev)
1643 : : {
1644 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1645 [ # # ]: 0 : const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
1646 : : struct rte_mbuf *rx_pkts[32];
1647 : : struct rte_eth_link link;
1648 : : int count, i, j, rc;
1649 : : void *rxq;
1650 : :
1651 : : /* In case of Inline IPSec, will need to avoid disabling the MCAM rules and NPC Rx
1652 : : * in this routine to continue processing of second pass inflight packets if any.
1653 : : * Drop of second pass packets will leak first pass buffers on some platforms
1654 : : * due to hardware limitations.
1655 : : */
1656 [ # # ]: 0 : if (roc_feature_nix_has_second_pass_drop() ||
1657 [ # # ]: 0 : !(dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY)) {
1658 : : /* Disable all the NPC entries */
1659 : 0 : rc = roc_npc_mcam_enable_all_entries(&dev->npc, 0);
1660 [ # # ]: 0 : if (rc)
1661 : : return rc;
1662 : :
1663 : : /* Disable Rx via NPC */
1664 : 0 : roc_nix_npc_rx_ena_dis(&dev->nix, false);
1665 : : }
1666 : :
1667 : : /* Stop link change events */
1668 [ # # ]: 0 : if (!roc_nix_is_vf_or_sdp(&dev->nix))
1669 : 0 : roc_nix_mac_link_event_start_stop(&dev->nix, false);
1670 : :
1671 : 0 : roc_nix_inl_outb_soft_exp_poll_switch(&dev->nix, false);
1672 : :
1673 : : /* Stop inline device RQ first */
1674 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY)
1675 : 0 : roc_nix_inl_rq_ena_dis(&dev->nix, false);
1676 : :
1677 : : /* Stop rx queues and free up pkts pending */
1678 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
1679 : 0 : rc = dev_ops->rx_queue_stop(eth_dev, i);
1680 [ # # ]: 0 : if (rc)
1681 : 0 : continue;
1682 : :
1683 : 0 : rxq = eth_dev->data->rx_queues[i];
1684 : 0 : count = dev->rx_pkt_burst_no_offload(rxq, rx_pkts, 32);
1685 [ # # ]: 0 : while (count) {
1686 [ # # ]: 0 : for (j = 0; j < count; j++)
1687 : 0 : rte_pktmbuf_free(rx_pkts[j]);
1688 : 0 : count = dev->rx_pkt_burst_no_offload(rxq, rx_pkts, 32);
1689 : : }
1690 : : }
1691 : :
1692 : : /* Stop tx queues */
1693 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++)
1694 : 0 : dev_ops->tx_queue_stop(eth_dev, i);
1695 : :
1696 : : /* Bring down link status internally */
1697 : : memset(&link, 0, sizeof(link));
1698 : 0 : rte_eth_linkstatus_set(eth_dev, &link);
1699 : :
1700 : 0 : return 0;
1701 : : }
1702 : :
1703 : : int
1704 [ # # ]: 0 : cnxk_nix_dev_start(struct rte_eth_dev *eth_dev)
1705 : : {
1706 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1707 : : int rc, i;
1708 : :
1709 [ # # # # ]: 0 : if (eth_dev->data->nb_rx_queues != 0 && !dev->ptp_en) {
1710 : 0 : rc = nix_recalc_mtu(eth_dev);
1711 [ # # ]: 0 : if (rc)
1712 : : return rc;
1713 : : }
1714 : :
1715 : : /* Start rx queues */
1716 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
1717 : 0 : rc = cnxk_nix_rx_queue_start(eth_dev, i);
1718 [ # # ]: 0 : if (rc)
1719 : 0 : return rc;
1720 : : }
1721 : :
1722 [ # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
1723 : 0 : rc = roc_nix_inl_rq_ena_dis(&dev->nix, true);
1724 [ # # ]: 0 : if (rc) {
1725 : 0 : plt_err("Failed to enable Inline device RQ, rc=%d", rc);
1726 : 0 : return rc;
1727 : : }
1728 : : }
1729 : :
1730 : : /* Start tx queues */
1731 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
1732 : 0 : rc = cnxk_nix_tx_queue_start(eth_dev, i);
1733 [ # # ]: 0 : if (rc)
1734 : 0 : return rc;
1735 : : }
1736 : :
1737 : : /* Update Flow control configuration */
1738 : 0 : rc = nix_update_flow_ctrl_config(eth_dev);
1739 [ # # ]: 0 : if (rc) {
1740 : 0 : plt_err("Failed to enable flow control. error code(%d)", rc);
1741 : 0 : return rc;
1742 : : }
1743 : :
1744 : : /* Enable Rx in NPC */
1745 : 0 : rc = roc_nix_npc_rx_ena_dis(&dev->nix, true);
1746 [ # # ]: 0 : if (rc) {
1747 : 0 : plt_err("Failed to enable NPC rx %d", rc);
1748 : 0 : return rc;
1749 : : }
1750 : :
1751 : 0 : rc = roc_npc_mcam_enable_all_entries(&dev->npc, 1);
1752 [ # # ]: 0 : if (rc) {
1753 : 0 : plt_err("Failed to enable NPC entries %d", rc);
1754 : 0 : return rc;
1755 : : }
1756 : :
1757 : 0 : cnxk_nix_toggle_flag_link_cfg(dev, true);
1758 : :
1759 : : /* Start link change events */
1760 [ # # ]: 0 : if (!roc_nix_is_vf_or_sdp(&dev->nix)) {
1761 : 0 : rc = roc_nix_mac_link_event_start_stop(&dev->nix, true);
1762 [ # # ]: 0 : if (rc) {
1763 : 0 : plt_err("Failed to start cgx link event %d", rc);
1764 : 0 : goto rx_disable;
1765 : : }
1766 : : }
1767 : :
1768 : : /* Enable PTP if it is requested by the user or already
1769 : : * enabled on PF owning this VF
1770 : : */
1771 [ # # ]: 0 : memset(&dev->tstamp, 0, sizeof(struct cnxk_timesync_info));
1772 [ # # # # ]: 0 : if ((dev->rx_offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) || dev->ptp_en)
1773 : 0 : cnxk_eth_dev_ops.timesync_enable(eth_dev);
1774 : : else
1775 : 0 : cnxk_eth_dev_ops.timesync_disable(eth_dev);
1776 : :
1777 [ # # # # ]: 0 : if (dev->rx_offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP || dev->ptp_en) {
1778 : 0 : rc = rte_mbuf_dyn_rx_timestamp_register
1779 : : (&dev->tstamp.tstamp_dynfield_offset,
1780 : : &dev->tstamp.rx_tstamp_dynflag);
1781 [ # # ]: 0 : if (rc != 0) {
1782 : 0 : plt_err("Failed to register Rx timestamp field/flag");
1783 : 0 : goto rx_disable;
1784 : : }
1785 : : }
1786 : :
1787 : 0 : cnxk_nix_toggle_flag_link_cfg(dev, false);
1788 : :
1789 : 0 : roc_nix_inl_outb_soft_exp_poll_switch(&dev->nix, true);
1790 : :
1791 : 0 : return 0;
1792 : :
1793 : 0 : rx_disable:
1794 : 0 : roc_nix_npc_rx_ena_dis(&dev->nix, false);
1795 : 0 : cnxk_nix_toggle_flag_link_cfg(dev, false);
1796 : 0 : return rc;
1797 : : }
1798 : :
1799 : : static int cnxk_nix_dev_reset(struct rte_eth_dev *eth_dev);
1800 : : static int cnxk_nix_dev_close(struct rte_eth_dev *eth_dev);
1801 : :
1802 : : /* CNXK platform independent eth dev ops */
1803 : : struct eth_dev_ops cnxk_eth_dev_ops = {
1804 : : .mtu_set = cnxk_nix_mtu_set,
1805 : : .mac_addr_add = cnxk_nix_mac_addr_add,
1806 : : .mac_addr_remove = cnxk_nix_mac_addr_del,
1807 : : .mac_addr_set = cnxk_nix_mac_addr_set,
1808 : : .dev_infos_get = cnxk_nix_info_get,
1809 : : .link_update = cnxk_nix_link_update,
1810 : : .tx_queue_release = cnxk_nix_tx_queue_release,
1811 : : .rx_queue_release = cnxk_nix_rx_queue_release,
1812 : : .dev_stop = cnxk_nix_dev_stop,
1813 : : .dev_close = cnxk_nix_dev_close,
1814 : : .dev_reset = cnxk_nix_dev_reset,
1815 : : .tx_queue_start = cnxk_nix_tx_queue_start,
1816 : : .rx_queue_start = cnxk_nix_rx_queue_start,
1817 : : .rx_queue_stop = cnxk_nix_rx_queue_stop,
1818 : : .dev_supported_ptypes_get = cnxk_nix_supported_ptypes_get,
1819 : : .promiscuous_enable = cnxk_nix_promisc_enable,
1820 : : .promiscuous_disable = cnxk_nix_promisc_disable,
1821 : : .allmulticast_enable = cnxk_nix_allmulticast_enable,
1822 : : .allmulticast_disable = cnxk_nix_allmulticast_disable,
1823 : : .rx_burst_mode_get = cnxk_nix_rx_burst_mode_get,
1824 : : .tx_burst_mode_get = cnxk_nix_tx_burst_mode_get,
1825 : : .flow_ctrl_get = cnxk_nix_flow_ctrl_get,
1826 : : .flow_ctrl_set = cnxk_nix_flow_ctrl_set,
1827 : : .priority_flow_ctrl_queue_config =
1828 : : cnxk_nix_priority_flow_ctrl_queue_config,
1829 : : .priority_flow_ctrl_queue_info_get =
1830 : : cnxk_nix_priority_flow_ctrl_queue_info_get,
1831 : : .dev_set_link_up = cnxk_nix_set_link_up,
1832 : : .dev_set_link_down = cnxk_nix_set_link_down,
1833 : : .get_module_info = cnxk_nix_get_module_info,
1834 : : .get_module_eeprom = cnxk_nix_get_module_eeprom,
1835 : : .rx_queue_intr_enable = cnxk_nix_rx_queue_intr_enable,
1836 : : .rx_queue_intr_disable = cnxk_nix_rx_queue_intr_disable,
1837 : : .pool_ops_supported = cnxk_nix_pool_ops_supported,
1838 : : .queue_stats_mapping_set = cnxk_nix_queue_stats_mapping,
1839 : : .stats_get = cnxk_nix_stats_get,
1840 : : .stats_reset = cnxk_nix_stats_reset,
1841 : : .xstats_get = cnxk_nix_xstats_get,
1842 : : .xstats_get_names = cnxk_nix_xstats_get_names,
1843 : : .xstats_reset = cnxk_nix_xstats_reset,
1844 : : .xstats_get_by_id = cnxk_nix_xstats_get_by_id,
1845 : : .xstats_get_names_by_id = cnxk_nix_xstats_get_names_by_id,
1846 : : .fw_version_get = cnxk_nix_fw_version_get,
1847 : : .rxq_info_get = cnxk_nix_rxq_info_get,
1848 : : .txq_info_get = cnxk_nix_txq_info_get,
1849 : : .tx_done_cleanup = cnxk_nix_tx_done_cleanup,
1850 : : .flow_ops_get = cnxk_nix_flow_ops_get,
1851 : : .get_reg = cnxk_nix_dev_get_reg,
1852 : : .timesync_read_rx_timestamp = cnxk_nix_timesync_read_rx_timestamp,
1853 : : .timesync_read_tx_timestamp = cnxk_nix_timesync_read_tx_timestamp,
1854 : : .timesync_read_time = cnxk_nix_timesync_read_time,
1855 : : .timesync_write_time = cnxk_nix_timesync_write_time,
1856 : : .timesync_adjust_time = cnxk_nix_timesync_adjust_time,
1857 : : .read_clock = cnxk_nix_read_clock,
1858 : : .reta_update = cnxk_nix_reta_update,
1859 : : .reta_query = cnxk_nix_reta_query,
1860 : : .rss_hash_update = cnxk_nix_rss_hash_update,
1861 : : .rss_hash_conf_get = cnxk_nix_rss_hash_conf_get,
1862 : : .set_mc_addr_list = cnxk_nix_mc_addr_list_configure,
1863 : : .set_queue_rate_limit = cnxk_nix_tm_set_queue_rate_limit,
1864 : : .tm_ops_get = cnxk_nix_tm_ops_get,
1865 : : .mtr_ops_get = cnxk_nix_mtr_ops_get,
1866 : : .eth_dev_priv_dump = cnxk_nix_eth_dev_priv_dump,
1867 : : .cman_info_get = cnxk_nix_cman_info_get,
1868 : : .cman_config_init = cnxk_nix_cman_config_init,
1869 : : .cman_config_set = cnxk_nix_cman_config_set,
1870 : : .cman_config_get = cnxk_nix_cman_config_get,
1871 : : .eth_tx_descriptor_dump = cnxk_nix_tx_descriptor_dump,
1872 : : };
1873 : :
1874 : : void
1875 : 0 : cnxk_eth_dev_q_err_cb(struct roc_nix *nix, void *data)
1876 : : {
1877 : : struct cnxk_eth_dev *dev = (struct cnxk_eth_dev *)nix;
1878 : 0 : struct rte_eth_dev *eth_dev = dev->eth_dev;
1879 : :
1880 : : /* Set the flag and execute application callbacks */
1881 : 0 : rte_eth_dev_callback_process(eth_dev, RTE_ETH_EVENT_INTR_RESET, data);
1882 : 0 : }
1883 : :
1884 : : static int
1885 : 0 : cnxk_eth_dev_init(struct rte_eth_dev *eth_dev)
1886 : : {
1887 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
1888 : : struct rte_security_ctx *sec_ctx;
1889 : 0 : struct roc_nix *nix = &dev->nix;
1890 : : struct rte_pci_device *pci_dev;
1891 : : int rc, max_entries;
1892 : :
1893 : 0 : eth_dev->dev_ops = &cnxk_eth_dev_ops;
1894 : 0 : eth_dev->rx_queue_count = cnxk_nix_rx_queue_count;
1895 : 0 : eth_dev->rx_descriptor_status = cnxk_nix_rx_descriptor_status;
1896 : 0 : eth_dev->tx_descriptor_status = cnxk_nix_tx_descriptor_status;
1897 : :
1898 : : /* Alloc security context */
1899 : 0 : sec_ctx = plt_zmalloc(sizeof(struct rte_security_ctx), 0);
1900 [ # # ]: 0 : if (!sec_ctx)
1901 : : return -ENOMEM;
1902 : 0 : sec_ctx->device = eth_dev;
1903 : 0 : sec_ctx->ops = &cnxk_eth_sec_ops;
1904 : 0 : sec_ctx->flags = RTE_SEC_CTX_F_FAST_SET_MDATA;
1905 : 0 : eth_dev->security_ctx = sec_ctx;
1906 : :
1907 : : /* For secondary processes, the primary has done all the work */
1908 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1909 : : return 0;
1910 : :
1911 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
1912 : 0 : rte_eth_copy_pci_info(eth_dev, pci_dev);
1913 : :
1914 : : /* Parse devargs string */
1915 : 0 : rc = cnxk_ethdev_parse_devargs(eth_dev->device->devargs, dev);
1916 [ # # ]: 0 : if (rc) {
1917 : 0 : plt_err("Failed to parse devargs rc=%d", rc);
1918 : 0 : goto error;
1919 : : }
1920 : :
1921 : : /* Initialize base roc nix */
1922 : 0 : nix->pci_dev = pci_dev;
1923 : 0 : nix->hw_vlan_ins = true;
1924 : 0 : nix->port_id = eth_dev->data->port_id;
1925 : : /* For better performance set default VF root schedule weight */
1926 [ # # ]: 0 : nix->root_sched_weight = NIX_TM_DFLT_RR_WT;
1927 : :
1928 : : /* Skip meta aura for cn20k */
1929 [ # # # # ]: 0 : if (roc_feature_nix_has_own_meta_aura() && !roc_feature_nix_has_second_pass_drop())
1930 : 0 : nix->local_meta_aura_ena = true;
1931 : :
1932 : 0 : rc = roc_nix_dev_init(nix);
1933 [ # # ]: 0 : if (rc) {
1934 : 0 : plt_err("Failed to initialize roc nix rc=%d", rc);
1935 : 0 : goto error;
1936 : : }
1937 : :
1938 : : /* Register up msg callbacks */
1939 : 0 : roc_nix_mac_link_cb_register(nix, cnxk_eth_dev_link_status_cb);
1940 : :
1941 : : /* Register up msg callbacks */
1942 : 0 : roc_nix_mac_link_info_get_cb_register(nix,
1943 : : cnxk_eth_dev_link_status_get_cb);
1944 : :
1945 : : /* Register up msg callbacks */
1946 : 0 : roc_nix_q_err_cb_register(nix, cnxk_eth_dev_q_err_cb);
1947 : :
1948 : : /* Register callback for inline meta pool create */
1949 : 0 : roc_nix_inl_meta_pool_cb_register(cnxk_nix_inl_meta_pool_cb);
1950 : :
1951 : : /* Register callback for inline meta pool create 1:N pool:aura */
1952 : 0 : roc_nix_inl_custom_meta_pool_cb_register(cnxk_nix_inl_custom_meta_pool_cb);
1953 : :
1954 : 0 : dev->eth_dev = eth_dev;
1955 : 0 : dev->configured = 0;
1956 : 0 : dev->ptype_disable = 0;
1957 : 0 : dev->proto = RTE_MTR_COLOR_IN_PROTO_OUTER_VLAN;
1958 : :
1959 : 0 : TAILQ_INIT(&dev->inb.list);
1960 : 0 : TAILQ_INIT(&dev->outb.list);
1961 : : rte_spinlock_init(&dev->inb.lock);
1962 : : rte_spinlock_init(&dev->outb.lock);
1963 : :
1964 : : /* For vfs, returned max_entries will be 0. but to keep default mac
1965 : : * address, one entry must be allocated. so setting up to 1.
1966 : : */
1967 [ # # ]: 0 : if (roc_nix_is_vf_or_sdp(nix))
1968 : : max_entries = 1;
1969 : : else
1970 : 0 : max_entries = roc_nix_mac_max_entries_get(nix);
1971 : :
1972 [ # # ]: 0 : if (max_entries <= 0) {
1973 : 0 : plt_err("Failed to get max entries for mac addr");
1974 : : rc = -ENOTSUP;
1975 : 0 : goto dev_fini;
1976 : : }
1977 : :
1978 : 0 : eth_dev->data->mac_addrs =
1979 : 0 : rte_zmalloc("mac_addr", max_entries * RTE_ETHER_ADDR_LEN, 0);
1980 [ # # ]: 0 : if (eth_dev->data->mac_addrs == NULL) {
1981 : 0 : plt_err("Failed to allocate memory for mac addr");
1982 : : rc = -ENOMEM;
1983 : 0 : goto dev_fini;
1984 : : }
1985 : :
1986 : 0 : dev->dmac_idx_map = rte_zmalloc("dmac_idx_map", max_entries * sizeof(int), 0);
1987 [ # # ]: 0 : if (dev->dmac_idx_map == NULL) {
1988 : 0 : plt_err("Failed to allocate memory for dmac idx map");
1989 : : rc = -ENOMEM;
1990 : 0 : goto free_mac_addrs;
1991 : : }
1992 : :
1993 : 0 : dev->max_mac_entries = max_entries;
1994 : 0 : dev->dmac_filter_count = 1;
1995 : :
1996 : : /* Get mac address */
1997 : 0 : rc = roc_nix_npc_mac_addr_get(nix, dev->mac_addr);
1998 [ # # ]: 0 : if (rc) {
1999 : 0 : plt_err("Failed to get mac addr, rc=%d", rc);
2000 : 0 : goto free_mac_addrs;
2001 : : }
2002 : :
2003 : : /* Update the mac address */
2004 : 0 : memcpy(eth_dev->data->mac_addrs, dev->mac_addr, RTE_ETHER_ADDR_LEN);
2005 : :
2006 : : /* Union of all capabilities supported by CNXK.
2007 : : * Platform specific capabilities will be
2008 : : * updated later.
2009 : : */
2010 : 0 : dev->rx_offload_capa = nix_get_rx_offload_capa(dev);
2011 : 0 : dev->tx_offload_capa = nix_get_tx_offload_capa(dev);
2012 : 0 : dev->speed_capa = nix_get_speed_capa(dev);
2013 : :
2014 : : /* Initialize roc npc */
2015 : 0 : dev->npc.roc_nix = nix;
2016 : 0 : rc = roc_npc_init(&dev->npc);
2017 [ # # ]: 0 : if (rc)
2018 : 0 : goto free_mac_addrs;
2019 : :
2020 [ # # # # ]: 0 : if (roc_feature_nix_has_macsec() && roc_mcs_is_supported()) {
2021 : 0 : rc = cnxk_mcs_dev_init(dev, 0);
2022 [ # # ]: 0 : if (rc) {
2023 : 0 : plt_err("Failed to init MCS");
2024 : 0 : goto free_mac_addrs;
2025 : : }
2026 : 0 : dev->rx_offload_capa |= RTE_ETH_RX_OFFLOAD_MACSEC_STRIP;
2027 : 0 : dev->tx_offload_capa |= RTE_ETH_TX_OFFLOAD_MACSEC_INSERT;
2028 : :
2029 : 0 : TAILQ_INIT(&dev->mcs_list);
2030 : : }
2031 : :
2032 : : /* Reserve a switch domain for eswitch device */
2033 [ # # ]: 0 : if (pci_dev->id.device_id == PCI_DEVID_CNXK_RVU_ESWITCH_VF) {
2034 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
2035 : 0 : rc = rte_eth_switch_domain_alloc(&dev->switch_domain_id);
2036 [ # # ]: 0 : if (rc) {
2037 : 0 : plt_err("Failed to alloc switch domain: %d", rc);
2038 : 0 : goto free_mac_addrs;
2039 : : }
2040 : : }
2041 : :
2042 : 0 : plt_nix_dbg("Port=%d pf=%d vf=%d ver=%s hwcap=0x%" PRIx64 " rxoffload_capa=0x%" PRIx64
2043 : : " txoffload_capa=0x%" PRIx64,
2044 : : eth_dev->data->port_id, roc_nix_get_pf(nix), roc_nix_get_vf(nix),
2045 : : CNXK_ETH_DEV_PMD_VERSION, dev->hwcap, dev->rx_offload_capa,
2046 : : dev->tx_offload_capa);
2047 : 0 : return 0;
2048 : :
2049 : 0 : free_mac_addrs:
2050 : 0 : rte_free(eth_dev->data->mac_addrs);
2051 : 0 : rte_free(dev->dmac_idx_map);
2052 : 0 : dev_fini:
2053 : 0 : roc_nix_dev_fini(nix);
2054 : 0 : error:
2055 : 0 : plt_err("Failed to init nix eth_dev rc=%d", rc);
2056 : 0 : return rc;
2057 : : }
2058 : :
2059 : : static int
2060 : 0 : cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool reset)
2061 : : {
2062 : : struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
2063 : 0 : const struct eth_dev_ops *dev_ops = eth_dev->dev_ops;
2064 : : struct cnxk_pfc_cfg *pfc_cfg = &dev->pfc_cfg;
2065 : : struct cnxk_fc_cfg *fc_cfg = &dev->fc_cfg;
2066 : : struct rte_eth_pfc_queue_conf pfc_conf;
2067 : 0 : struct roc_nix *nix = &dev->nix;
2068 : : struct rte_eth_fc_conf fc_conf;
2069 : : int rc, i;
2070 : :
2071 : 0 : plt_free(eth_dev->security_ctx);
2072 : 0 : eth_dev->security_ctx = NULL;
2073 : :
2074 : : /* Nothing to be done for secondary processes */
2075 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2076 : : return 0;
2077 : :
2078 : : /* Disable switch hdr pkind */
2079 : 0 : roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
2080 : :
2081 : : /* Clear the flag since we are closing down */
2082 : 0 : dev->configured = 0;
2083 : :
2084 : : /* Disable all the NPC entries */
2085 : 0 : rc = roc_npc_mcam_enable_all_entries(&dev->npc, 0);
2086 [ # # ]: 0 : if (rc)
2087 : : return rc;
2088 : :
2089 : 0 : roc_nix_npc_rx_ena_dis(nix, false);
2090 : :
2091 : : /* Restore 802.3 Flow control configuration */
2092 : : memset(&pfc_conf, 0, sizeof(struct rte_eth_pfc_queue_conf));
2093 : : memset(&fc_conf, 0, sizeof(struct rte_eth_fc_conf));
2094 [ # # ]: 0 : if (fc_cfg->rx_pause || fc_cfg->tx_pause) {
2095 : : fc_conf.mode = RTE_ETH_FC_NONE;
2096 : 0 : rc = cnxk_nix_flow_ctrl_set(eth_dev, &fc_conf);
2097 [ # # ]: 0 : if (rc < 0)
2098 : 0 : plt_err("Failed to reset control flow. error code(%d)",
2099 : : rc);
2100 : : }
2101 [ # # # # ]: 0 : if (pfc_cfg->rx_pause_en || pfc_cfg->tx_pause_en) {
2102 [ # # ]: 0 : for (i = 0; i < RTE_MAX(eth_dev->data->nb_rx_queues,
2103 : : eth_dev->data->nb_tx_queues);
2104 : 0 : i++) {
2105 : 0 : pfc_conf.mode = RTE_ETH_FC_NONE;
2106 : 0 : pfc_conf.rx_pause.tc = ROC_NIX_PFC_CLASS_INVALID;
2107 : 0 : pfc_conf.rx_pause.tx_qid = i;
2108 : 0 : pfc_conf.tx_pause.tc = ROC_NIX_PFC_CLASS_INVALID;
2109 : 0 : pfc_conf.tx_pause.rx_qid = i;
2110 : 0 : rc = cnxk_nix_priority_flow_ctrl_queue_config(eth_dev,
2111 : : &pfc_conf);
2112 [ # # ]: 0 : if (rc && rc != -ENOTSUP)
2113 : 0 : plt_err("Failed to reset PFC. error code(%d)", rc);
2114 : : }
2115 : : }
2116 : :
2117 : : /* Free switch domain ID reserved for eswitch device */
2118 [ # # # # ]: 0 : if ((eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) &&
2119 : 0 : rte_eth_switch_domain_free(dev->switch_domain_id))
2120 : 0 : plt_err("Failed to free switch domain");
2121 : :
2122 : : /* Disable and free rte_meter entries */
2123 : 0 : nix_meter_fini(dev);
2124 : :
2125 : : /* Disable and free rte_flow entries */
2126 : 0 : roc_npc_fini(&dev->npc);
2127 : :
2128 : : /* Disable link status events */
2129 : 0 : roc_nix_mac_link_event_start_stop(nix, false);
2130 : :
2131 : : /* Unregister the link update op, this is required to stop VFs from
2132 : : * receiving link status updates on exit path.
2133 : : */
2134 : 0 : roc_nix_mac_link_cb_unregister(nix);
2135 : :
2136 : : /* Free up SQs */
2137 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
2138 : 0 : dev_ops->tx_queue_release(eth_dev, i);
2139 : 0 : eth_dev->data->tx_queues[i] = NULL;
2140 : : }
2141 : 0 : eth_dev->data->nb_tx_queues = 0;
2142 : :
2143 : : /* Free up RQ's and CQ's */
2144 [ # # ]: 0 : for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
2145 : 0 : dev_ops->rx_queue_release(eth_dev, i);
2146 : 0 : eth_dev->data->rx_queues[i] = NULL;
2147 : : }
2148 [ # # ]: 0 : eth_dev->data->nb_rx_queues = 0;
2149 : :
2150 [ # # # # ]: 0 : if (roc_feature_nix_has_macsec() && roc_mcs_is_supported())
2151 : 0 : cnxk_mcs_dev_fini(dev);
2152 : :
2153 : : /* Free security resources */
2154 : 0 : nix_security_release(dev);
2155 : :
2156 : : /* Free tm resources */
2157 : 0 : roc_nix_tm_fini(nix);
2158 : :
2159 : : /* Unregister queue irqs */
2160 : 0 : roc_nix_unregister_queue_irqs(nix);
2161 : :
2162 : : /* Unregister cq irqs */
2163 [ # # ]: 0 : if (eth_dev->data->dev_conf.intr_conf.rxq)
2164 : 0 : roc_nix_unregister_cq_irqs(nix);
2165 : :
2166 : : /* Free ROC RQ's, SQ's and CQ's memory */
2167 : 0 : nix_free_queue_mem(dev);
2168 : :
2169 : : /* free nix bpid */
2170 : 0 : rc = nix_rxchan_cfg_disable(dev);
2171 [ # # ]: 0 : if (rc)
2172 : 0 : plt_err("Failed to free nix bpid, rc=%d", rc);
2173 : :
2174 : : /* Free nix lf resources */
2175 : 0 : rc = roc_nix_lf_free(nix);
2176 [ # # ]: 0 : if (rc)
2177 : 0 : plt_err("Failed to free nix lf, rc=%d", rc);
2178 : :
2179 : 0 : rte_free(dev->dmac_idx_map);
2180 : 0 : dev->dmac_idx_map = NULL;
2181 : :
2182 : 0 : rte_free(eth_dev->data->mac_addrs);
2183 : 0 : eth_dev->data->mac_addrs = NULL;
2184 : :
2185 : 0 : rc = roc_nix_dev_fini(nix);
2186 : : /* Can be freed later by PMD if NPA LF is in use */
2187 [ # # ]: 0 : if (rc == -EAGAIN) {
2188 [ # # ]: 0 : if (!reset)
2189 : 0 : eth_dev->data->dev_private = NULL;
2190 : 0 : return 0;
2191 [ # # ]: 0 : } else if (rc) {
2192 : 0 : plt_err("Failed in nix dev fini, rc=%d", rc);
2193 : : }
2194 : :
2195 : : return rc;
2196 : : }
2197 : :
2198 : : static int
2199 : 0 : cnxk_nix_dev_close(struct rte_eth_dev *eth_dev)
2200 : : {
2201 : 0 : cnxk_eth_dev_uninit(eth_dev, false);
2202 : 0 : return 0;
2203 : : }
2204 : :
2205 : : static int
2206 : 0 : cnxk_nix_dev_reset(struct rte_eth_dev *eth_dev)
2207 : : {
2208 : : int rc;
2209 : :
2210 : 0 : rc = cnxk_eth_dev_uninit(eth_dev, true);
2211 [ # # ]: 0 : if (rc)
2212 : : return rc;
2213 : :
2214 : 0 : return cnxk_eth_dev_init(eth_dev);
2215 : : }
2216 : :
2217 : : int
2218 : 0 : cnxk_nix_remove(struct rte_pci_device *pci_dev)
2219 : : {
2220 : : struct rte_eth_dev *eth_dev;
2221 : : struct roc_nix *nix;
2222 : : int rc = -EINVAL;
2223 : :
2224 : 0 : eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
2225 [ # # ]: 0 : if (eth_dev) {
2226 : : /* Cleanup eth dev */
2227 : 0 : rc = cnxk_eth_dev_uninit(eth_dev, false);
2228 [ # # ]: 0 : if (rc)
2229 : : return rc;
2230 : :
2231 : 0 : rte_eth_dev_release_port(eth_dev);
2232 : : }
2233 : :
2234 : : /* Nothing to be done for secondary processes */
2235 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2236 : : return 0;
2237 : :
2238 : : /* Check if this device is hosting common resource */
2239 : 0 : nix = roc_idev_npa_nix_get();
2240 [ # # # # ]: 0 : if (!nix || nix->pci_dev != pci_dev)
2241 : : return 0;
2242 : :
2243 : : /* Try nix fini now */
2244 : 0 : rc = roc_nix_dev_fini(nix);
2245 [ # # ]: 0 : if (rc == -EAGAIN) {
2246 : 0 : plt_info("%s: common resource in use by other devices",
2247 : : pci_dev->name);
2248 : 0 : goto exit;
2249 [ # # ]: 0 : } else if (rc) {
2250 : 0 : plt_err("Failed in nix dev fini, rc=%d", rc);
2251 : 0 : goto exit;
2252 : : }
2253 : :
2254 : : /* Free device pointer as rte_ethdev does not have it anymore */
2255 : 0 : rte_free(nix);
2256 : : exit:
2257 : : return rc;
2258 : : }
2259 : :
2260 : : int
2261 : 0 : cnxk_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
2262 : : {
2263 : : int rc;
2264 : :
2265 : : RTE_SET_USED(pci_drv);
2266 : :
2267 : 0 : rc = rte_eth_dev_pci_generic_probe(pci_dev, sizeof(struct cnxk_eth_dev),
2268 : : cnxk_eth_dev_init);
2269 : :
2270 : : /* On error on secondary, recheck if port exists in primary or
2271 : : * in mid of detach state.
2272 : : */
2273 [ # # # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY && rc)
2274 [ # # ]: 0 : if (!rte_eth_dev_allocated(pci_dev->device.name))
2275 : 0 : return 0;
2276 : : return rc;
2277 : : }
|