Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include <rte_thash.h>
6 : :
7 : : #include <cnxk_eswitch.h>
8 : : #include <cnxk_rep.h>
9 : :
10 : : #define CNXK_NIX_DEF_SQ_COUNT 512
11 : :
12 : : int
13 : 0 : cnxk_eswitch_representor_id(struct cnxk_eswitch_dev *eswitch_dev, uint16_t hw_func,
14 : : uint16_t *rep_id)
15 : : {
16 : : struct cnxk_esw_repr_hw_info *repr_info;
17 : : int rc = 0;
18 : :
19 : 0 : repr_info = cnxk_eswitch_representor_hw_info(eswitch_dev, hw_func);
20 [ # # ]: 0 : if (!repr_info) {
21 : 0 : plt_warn("Failed to get representor group for %x", hw_func);
22 : : rc = -ENOENT;
23 : 0 : goto fail;
24 : : }
25 : :
26 : 0 : *rep_id = repr_info->rep_id;
27 : :
28 : 0 : return 0;
29 : : fail:
30 : 0 : return rc;
31 : : }
32 : :
33 : : struct cnxk_esw_repr_hw_info *
34 : 0 : cnxk_eswitch_representor_hw_info(struct cnxk_eswitch_dev *eswitch_dev, uint16_t hw_func)
35 : : {
36 : : struct cnxk_eswitch_devargs *esw_da;
37 : : int i, j;
38 : :
39 [ # # ]: 0 : if (!eswitch_dev)
40 : : return NULL;
41 : :
42 : : /* Traversing the initialized represented list */
43 [ # # ]: 0 : for (i = 0; i < eswitch_dev->nb_esw_da; i++) {
44 : : esw_da = &eswitch_dev->esw_da[i];
45 [ # # ]: 0 : for (j = 0; j < esw_da->nb_repr_ports; j++) {
46 [ # # ]: 0 : if (esw_da->repr_hw_info[j].hw_func == hw_func)
47 : 0 : return &esw_da->repr_hw_info[j];
48 : : }
49 : : }
50 : : return NULL;
51 : : }
52 : :
53 : : static int
54 : 0 : eswitch_hw_rsrc_cleanup(struct cnxk_eswitch_dev *eswitch_dev, struct rte_pci_device *pci_dev)
55 : : {
56 : : struct roc_nix *nix;
57 : : int rc = 0;
58 : :
59 : 0 : nix = &eswitch_dev->nix;
60 : :
61 : 0 : roc_nix_unregister_queue_irqs(nix);
62 : 0 : roc_nix_tm_fini(nix);
63 : 0 : rc = roc_nix_lf_free(nix);
64 [ # # ]: 0 : if (rc) {
65 : 0 : plt_err("Failed to cleanup sq, rc %d", rc);
66 : 0 : goto exit;
67 : : }
68 : :
69 : : /* Check if this device is hosting common resource */
70 : 0 : nix = roc_idev_npa_nix_get();
71 [ # # # # ]: 0 : if (!nix || nix->pci_dev != pci_dev) {
72 : : rc = 0;
73 : 0 : goto exit;
74 : : }
75 : :
76 : : /* Try nix fini now */
77 : 0 : rc = roc_nix_dev_fini(nix);
78 [ # # ]: 0 : if (rc == -EAGAIN) {
79 : 0 : plt_info("Common resource in use by other devices %s", pci_dev->name);
80 : 0 : goto exit;
81 [ # # ]: 0 : } else if (rc) {
82 : 0 : plt_err("Failed in nix dev fini, rc=%d", rc);
83 : 0 : goto exit;
84 : : }
85 : :
86 : 0 : rte_free(eswitch_dev->txq);
87 : 0 : rte_free(eswitch_dev->rxq);
88 : 0 : rte_free(eswitch_dev->cxq);
89 : :
90 : 0 : exit:
91 : 0 : return rc;
92 : : }
93 : :
94 : : static int
95 : 0 : cnxk_eswitch_dev_remove(struct rte_pci_device *pci_dev)
96 : : {
97 : : struct cnxk_eswitch_dev *eswitch_dev;
98 : : int rc = 0;
99 : :
100 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
101 : : return 0;
102 : :
103 : : eswitch_dev = cnxk_eswitch_pmd_priv();
104 [ # # ]: 0 : if (!eswitch_dev) {
105 : : rc = -EINVAL;
106 : 0 : goto exit;
107 : : }
108 : :
109 : : /* Remove representor devices associated with PF */
110 [ # # ]: 0 : if (eswitch_dev->repr_cnt.nb_repr_created) {
111 : : /* Exiting the rep msg ctrl thread */
112 [ # # ]: 0 : if (eswitch_dev->start_ctrl_msg_thrd) {
113 : : uint32_t sunlen;
114 : 0 : struct sockaddr_un sun = {0};
115 : : int sock_fd = 0;
116 : :
117 : 0 : eswitch_dev->start_ctrl_msg_thrd = false;
118 [ # # ]: 0 : if (!eswitch_dev->client_connected) {
119 : 0 : plt_esw_dbg("Establishing connection for teardown");
120 : 0 : sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
121 [ # # ]: 0 : if (sock_fd == -1) {
122 : 0 : plt_err("Failed to open socket. err %d", -errno);
123 : 0 : return -errno;
124 : : }
125 : 0 : sun.sun_family = AF_UNIX;
126 : : sunlen = sizeof(struct sockaddr_un);
127 : : strncpy(sun.sun_path, CNXK_ESWITCH_CTRL_MSG_SOCK_PATH,
128 : : sizeof(sun.sun_path) - 1);
129 : :
130 [ # # ]: 0 : if (connect(sock_fd, (struct sockaddr *)&sun, sunlen) < 0) {
131 : 0 : plt_err("Failed to connect socket: %s, err %d",
132 : : CNXK_ESWITCH_CTRL_MSG_SOCK_PATH, errno);
133 : 0 : close(sock_fd);
134 : 0 : return -errno;
135 : : }
136 : : }
137 : 0 : rte_thread_join(eswitch_dev->rep_ctrl_msg_thread, NULL);
138 [ # # ]: 0 : if (!eswitch_dev->client_connected)
139 : 0 : close(sock_fd);
140 : : }
141 : :
142 [ # # ]: 0 : if (eswitch_dev->repte_msg_proc.start_thread) {
143 : 0 : eswitch_dev->repte_msg_proc.start_thread = false;
144 : 0 : pthread_cond_signal(&eswitch_dev->repte_msg_proc.repte_msg_cond);
145 : 0 : rte_thread_join(eswitch_dev->repte_msg_proc.repte_msg_thread, NULL);
146 : 0 : pthread_mutex_destroy(&eswitch_dev->repte_msg_proc.mutex);
147 : 0 : pthread_cond_destroy(&eswitch_dev->repte_msg_proc.repte_msg_cond);
148 : : }
149 : :
150 : : /* Remove representor devices associated with PF */
151 : 0 : cnxk_rep_dev_remove(eswitch_dev);
152 : : }
153 : :
154 : : /* Cleanup NPC rxtx flow rules */
155 : 0 : cnxk_eswitch_flow_rules_remove_list(eswitch_dev, &eswitch_dev->esw_flow_list,
156 : 0 : eswitch_dev->npc.pf_func);
157 : :
158 : : /* Cleanup HW resources */
159 : 0 : eswitch_hw_rsrc_cleanup(eswitch_dev, pci_dev);
160 : :
161 : 0 : rte_free(eswitch_dev);
162 : : exit:
163 : : return rc;
164 : : }
165 : :
166 : : int
167 : 0 : cnxk_eswitch_nix_rsrc_start(struct cnxk_eswitch_dev *eswitch_dev)
168 : : {
169 : : int rc;
170 : :
171 : : /* Install eswitch PF mcam rules */
172 : 0 : rc = cnxk_eswitch_pfvf_flow_rules_install(eswitch_dev, false);
173 [ # # ]: 0 : if (rc) {
174 : 0 : plt_err("Failed to install rxtx rules, rc %d", rc);
175 : 0 : goto done;
176 : : }
177 : :
178 : : /* Configure TPID for Eswitch PF LFs */
179 : 0 : rc = roc_eswitch_nix_vlan_tpid_set(&eswitch_dev->nix, ROC_NIX_VLAN_TYPE_OUTER,
180 : : CNXK_ESWITCH_VLAN_TPID, false);
181 [ # # ]: 0 : if (rc) {
182 : 0 : plt_err("Failed to configure tpid, rc %d", rc);
183 : 0 : goto done;
184 : : }
185 : :
186 : : /* Enable Rx in NPC */
187 : 0 : rc = roc_nix_npc_rx_ena_dis(&eswitch_dev->nix, true);
188 [ # # ]: 0 : if (rc) {
189 : 0 : plt_err("Failed to enable NPC rx %d", rc);
190 : 0 : goto done;
191 : : }
192 : :
193 : 0 : rc = roc_npc_mcam_enable_all_entries(&eswitch_dev->npc, 1);
194 [ # # ]: 0 : if (rc) {
195 : 0 : plt_err("Failed to enable NPC entries %d", rc);
196 : 0 : goto done;
197 : : }
198 : :
199 : 0 : done:
200 : 0 : return 0;
201 : : }
202 : :
203 : : int
204 : 0 : cnxk_eswitch_txq_start(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
205 : : {
206 : 0 : struct roc_nix_sq *sq = &eswitch_dev->txq[qid].sqs;
207 : : int rc = -EINVAL;
208 : :
209 [ # # ]: 0 : if (eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STARTED)
210 : : return 0;
211 : :
212 [ # # ]: 0 : if (eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_CONFIGURED) {
213 : 0 : plt_err("Eswitch txq %d not configured yet", qid);
214 : 0 : goto done;
215 : : }
216 : :
217 : 0 : rc = roc_nix_sq_ena_dis(sq, true);
218 [ # # ]: 0 : if (rc) {
219 : 0 : plt_err("Failed to enable sq aura fc, txq=%u, rc=%d", qid, rc);
220 : 0 : goto done;
221 : : }
222 : :
223 : 0 : eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STARTED;
224 : : done:
225 : : return rc;
226 : : }
227 : :
228 : : int
229 : 0 : cnxk_eswitch_txq_stop(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
230 : : {
231 : 0 : struct roc_nix_sq *sq = &eswitch_dev->txq[qid].sqs;
232 : : int rc = -EINVAL;
233 : :
234 [ # # ]: 0 : if (eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STOPPED ||
235 : : eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
236 : : return 0;
237 : :
238 [ # # ]: 0 : if (eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_STARTED) {
239 : 0 : plt_err("Eswitch txq %d not started", qid);
240 : 0 : goto done;
241 : : }
242 : :
243 : 0 : rc = roc_nix_sq_ena_dis(sq, false);
244 [ # # ]: 0 : if (rc) {
245 : 0 : plt_err("Failed to disable sqb aura fc, txq=%u, rc=%d", qid, rc);
246 : 0 : goto done;
247 : : }
248 : :
249 : 0 : eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STOPPED;
250 : : done:
251 : : return rc;
252 : : }
253 : :
254 : : int
255 : 0 : cnxk_eswitch_rxq_start(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
256 : : {
257 : 0 : struct roc_nix_rq *rq = &eswitch_dev->rxq[qid].rqs;
258 : : int rc = -EINVAL;
259 : :
260 [ # # ]: 0 : if (eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STARTED)
261 : : return 0;
262 : :
263 [ # # ]: 0 : if (eswitch_dev->rxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_CONFIGURED) {
264 : 0 : plt_err("Eswitch rxq %d not configured yet", qid);
265 : 0 : goto done;
266 : : }
267 : :
268 : 0 : rc = roc_nix_rq_ena_dis(rq, true);
269 [ # # ]: 0 : if (rc) {
270 : 0 : plt_err("Failed to enable rxq=%u, rc=%d", qid, rc);
271 : 0 : goto done;
272 : : }
273 : :
274 : 0 : eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STARTED;
275 : : done:
276 : : return rc;
277 : : }
278 : :
279 : : int
280 : 0 : cnxk_eswitch_rxq_stop(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
281 : : {
282 : 0 : struct roc_nix_rq *rq = &eswitch_dev->rxq[qid].rqs;
283 : : int rc = -EINVAL;
284 : :
285 [ # # ]: 0 : if (eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_STOPPED ||
286 : : eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
287 : : return 0;
288 : :
289 [ # # ]: 0 : if (eswitch_dev->rxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_STARTED) {
290 : 0 : plt_err("Eswitch rxq %d not started", qid);
291 : 0 : goto done;
292 : : }
293 : :
294 : 0 : rc = roc_nix_rq_ena_dis(rq, false);
295 [ # # ]: 0 : if (rc) {
296 : 0 : plt_err("Failed to disable rxq=%u, rc=%d", qid, rc);
297 : 0 : goto done;
298 : : }
299 : :
300 : 0 : eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_STOPPED;
301 : : done:
302 : : return rc;
303 : : }
304 : :
305 : : int
306 : 0 : cnxk_eswitch_rxq_release(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
307 : : {
308 : : struct roc_nix_rq *rq;
309 : : struct roc_nix_cq *cq;
310 : : int rc;
311 : :
312 [ # # ]: 0 : if (eswitch_dev->rxq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
313 : : return 0;
314 : :
315 : : /* Cleanup ROC SQ */
316 : 0 : rq = &eswitch_dev->rxq[qid].rqs;
317 : 0 : rc = roc_nix_rq_fini(rq);
318 [ # # ]: 0 : if (rc) {
319 : 0 : plt_err("Failed to cleanup sq, rc=%d", rc);
320 : 0 : goto fail;
321 : : }
322 : :
323 : 0 : eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_RELEASED;
324 : :
325 : : /* Cleanup ROC CQ */
326 : 0 : cq = &eswitch_dev->cxq[qid].cqs;
327 : 0 : rc = roc_nix_cq_fini(cq);
328 [ # # ]: 0 : if (rc) {
329 : 0 : plt_err("Failed to cleanup cq, rc=%d", rc);
330 : 0 : goto fail;
331 : : }
332 : :
333 : 0 : eswitch_dev->cxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_RELEASED;
334 : : fail:
335 : : return rc;
336 : : }
337 : :
338 : : int
339 : 0 : cnxk_eswitch_rxq_setup(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid, uint16_t nb_desc,
340 : : const struct rte_eth_rxconf *rx_conf, struct rte_mempool *mp)
341 : : {
342 : 0 : struct roc_nix *nix = &eswitch_dev->nix;
343 : : struct rte_mempool *lpb_pool = mp;
344 : : struct rte_mempool_ops *ops;
345 : : const char *platform_ops;
346 : : struct roc_nix_rq *rq;
347 : : struct roc_nix_cq *cq;
348 : : uint16_t first_skip;
349 : : int rc = -EINVAL;
350 : :
351 [ # # ]: 0 : if (eswitch_dev->rxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_RELEASED ||
352 [ # # ]: 0 : eswitch_dev->cxq[qid].state != CNXK_ESWITCH_QUEUE_STATE_RELEASED) {
353 : 0 : plt_err("Queue %d is in invalid state %d, cannot be setup", qid,
354 : : eswitch_dev->txq[qid].state);
355 : 0 : goto fail;
356 : : }
357 : :
358 : : RTE_SET_USED(rx_conf);
359 : 0 : platform_ops = rte_mbuf_platform_mempool_ops();
360 : : /* This driver needs cnxk_npa mempool ops to work */
361 [ # # ]: 0 : ops = rte_mempool_get_ops(lpb_pool->ops_index);
362 [ # # ]: 0 : if (strncmp(ops->name, platform_ops, RTE_MEMPOOL_OPS_NAMESIZE)) {
363 : 0 : plt_err("mempool ops should be of cnxk_npa type");
364 : 0 : goto fail;
365 : : }
366 : :
367 [ # # ]: 0 : if (lpb_pool->pool_id == 0) {
368 : 0 : plt_err("Invalid pool_id");
369 : 0 : goto fail;
370 : : }
371 : :
372 : : /* Setup ROC CQ */
373 : 0 : cq = &eswitch_dev->cxq[qid].cqs;
374 : : memset(cq, 0, sizeof(struct roc_nix_cq));
375 : 0 : cq->qid = qid;
376 : 0 : cq->nb_desc = nb_desc;
377 : 0 : rc = roc_nix_cq_init(nix, cq);
378 [ # # ]: 0 : if (rc) {
379 : 0 : plt_err("Failed to init roc cq for rq=%d, rc=%d", qid, rc);
380 : 0 : goto fail;
381 : : }
382 : 0 : eswitch_dev->cxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_CONFIGURED;
383 : :
384 : : /* Setup ROC RQ */
385 [ # # ]: 0 : rq = &eswitch_dev->rxq[qid].rqs;
386 : : memset(rq, 0, sizeof(struct roc_nix_rq));
387 : 0 : rq->qid = qid;
388 : 0 : rq->cqid = cq->qid;
389 : 0 : rq->aura_handle = lpb_pool->pool_id;
390 [ # # ]: 0 : rq->flow_tag_width = 32;
391 : : rq->sso_ena = false;
392 : :
393 : : /* Calculate first mbuf skip */
394 : : first_skip = (sizeof(struct rte_mbuf));
395 : : first_skip += RTE_PKTMBUF_HEADROOM;
396 : 0 : first_skip += rte_pktmbuf_priv_size(lpb_pool);
397 : 0 : rq->first_skip = first_skip;
398 : 0 : rq->later_skip = sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(lpb_pool);
399 [ # # ]: 0 : rq->lpb_size = lpb_pool->elt_size;
400 [ # # ]: 0 : if (roc_errata_nix_no_meta_aura())
401 : 0 : rq->lpb_drop_ena = true;
402 : :
403 : 0 : rc = roc_nix_rq_init(nix, rq, true);
404 [ # # ]: 0 : if (rc) {
405 : 0 : plt_err("Failed to init roc rq for rq=%d, rc=%d", qid, rc);
406 : 0 : goto cq_fini;
407 : : }
408 : 0 : eswitch_dev->rxq[qid].state = CNXK_ESWITCH_QUEUE_STATE_CONFIGURED;
409 : :
410 : 0 : return 0;
411 : : cq_fini:
412 : 0 : rc |= roc_nix_cq_fini(cq);
413 : : fail:
414 : : return rc;
415 : : }
416 : :
417 : : int
418 : 0 : cnxk_eswitch_txq_release(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid)
419 : : {
420 : : struct roc_nix_sq *sq;
421 : : int rc = 0;
422 : :
423 [ # # ]: 0 : if (eswitch_dev->txq[qid].state == CNXK_ESWITCH_QUEUE_STATE_RELEASED)
424 : : return 0;
425 : :
426 : : /* Cleanup ROC SQ */
427 : 0 : sq = &eswitch_dev->txq[qid].sqs;
428 : 0 : rc = roc_nix_sq_fini(sq);
429 [ # # ]: 0 : if (rc) {
430 : 0 : plt_err("Failed to cleanup sq, rc=%d", rc);
431 : 0 : goto fail;
432 : : }
433 : :
434 : 0 : eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_RELEASED;
435 : : fail:
436 : : return rc;
437 : : }
438 : :
439 : : int
440 : 0 : cnxk_eswitch_txq_setup(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid, uint16_t nb_desc,
441 : : const struct rte_eth_txconf *tx_conf)
442 : : {
443 : : struct roc_nix_sq *sq;
444 : : int rc = 0;
445 : :
446 [ # # ]: 0 : if (eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_RELEASED) {
447 : 0 : plt_err("Queue %d is in invalid state %d, cannot be setup", qid,
448 : : eswitch_dev->txq[qid].state);
449 : : rc = -EINVAL;
450 : 0 : goto fail;
451 : : }
452 : : RTE_SET_USED(tx_conf);
453 : : /* Setup ROC SQ */
454 [ # # ]: 0 : sq = &eswitch_dev->txq[qid].sqs;
455 : : memset(sq, 0, sizeof(struct roc_nix_sq));
456 : 0 : sq->qid = qid;
457 : 0 : sq->nb_desc = nb_desc;
458 : : sq->max_sqe_sz = NIX_MAXSQESZ_W16;
459 [ # # ]: 0 : if (sq->nb_desc >= CNXK_NIX_DEF_SQ_COUNT)
460 : 0 : sq->fc_hyst_bits = 0x1;
461 : :
462 : 0 : rc = roc_nix_sq_init(&eswitch_dev->nix, sq);
463 [ # # ]: 0 : if (rc)
464 : 0 : plt_err("Failed to init sq=%d, rc=%d", qid, rc);
465 : :
466 : 0 : eswitch_dev->txq[qid].state = CNXK_ESWITCH_QUEUE_STATE_CONFIGURED;
467 : :
468 : 0 : fail:
469 : 0 : return rc;
470 : : }
471 : :
472 : : static int
473 : 0 : nix_lf_setup(struct cnxk_eswitch_dev *eswitch_dev)
474 : : {
475 : : uint16_t nb_rxq, nb_txq, nb_cq;
476 : : struct roc_nix_fc_cfg fc_cfg;
477 : : struct roc_nix *nix;
478 : : uint64_t rx_cfg;
479 : : void *qs;
480 : : int rc;
481 : :
482 : : /* Initialize base roc nix */
483 : 0 : nix = &eswitch_dev->nix;
484 : 0 : nix->pci_dev = eswitch_dev->pci_dev;
485 : 0 : nix->hw_vlan_ins = true;
486 : 0 : nix->reta_sz = ROC_NIX_RSS_RETA_SZ_256;
487 : 0 : rc = roc_nix_dev_init(nix);
488 [ # # ]: 0 : if (rc) {
489 : 0 : plt_err("Failed to init nix eswitch device, rc=%d(%s)", rc, roc_error_msg_get(rc));
490 : 0 : goto fail;
491 : : }
492 : :
493 : : /* Get the representors count */
494 : 0 : rc = roc_nix_max_rep_count(&eswitch_dev->nix);
495 [ # # ]: 0 : if (rc) {
496 : 0 : plt_err("Failed to get rep cnt, rc=%d(%s)", rc, roc_error_msg_get(rc));
497 : 0 : goto free_cqs;
498 : : }
499 : 0 : eswitch_dev->repr_cnt.max_repr = eswitch_dev->nix.rep_cnt;
500 : :
501 : : /* Allocating an NIX LF */
502 : : nb_rxq = CNXK_ESWITCH_MAX_RXQ;
503 : : nb_txq = CNXK_ESWITCH_MAX_TXQ;
504 : : nb_cq = CNXK_ESWITCH_MAX_RXQ;
505 : : rx_cfg = ROC_NIX_LF_RX_CFG_DIS_APAD;
506 : 0 : rc = roc_nix_lf_alloc(nix, nb_rxq, nb_txq, rx_cfg);
507 [ # # ]: 0 : if (rc) {
508 : 0 : plt_err("lf alloc failed = %s(%d)", roc_error_msg_get(rc), rc);
509 : 0 : goto dev_fini;
510 : : }
511 : :
512 : : if (nb_rxq) {
513 : : /* Allocate memory for eswitch rq's and cq's */
514 : 0 : qs = plt_zmalloc(sizeof(struct cnxk_eswitch_rxq) * nb_rxq, 0);
515 [ # # ]: 0 : if (!qs) {
516 : 0 : plt_err("Failed to alloc eswitch rxq");
517 : 0 : goto lf_free;
518 : : }
519 : 0 : eswitch_dev->rxq = qs;
520 : : }
521 : :
522 : : if (nb_txq) {
523 : : /* Allocate memory for roc sq's */
524 : 0 : qs = plt_zmalloc(sizeof(struct cnxk_eswitch_txq) * nb_txq, 0);
525 [ # # ]: 0 : if (!qs) {
526 : 0 : plt_err("Failed to alloc eswitch txq");
527 : 0 : goto free_rqs;
528 : : }
529 : 0 : eswitch_dev->txq = qs;
530 : : }
531 : :
532 : : if (nb_cq) {
533 : 0 : qs = plt_zmalloc(sizeof(struct cnxk_eswitch_cxq) * nb_cq, 0);
534 [ # # ]: 0 : if (!qs) {
535 : 0 : plt_err("Failed to alloc eswitch cxq");
536 : 0 : goto free_sqs;
537 : : }
538 : 0 : eswitch_dev->cxq = qs;
539 : : }
540 : :
541 : 0 : eswitch_dev->nb_rxq = nb_rxq;
542 : 0 : eswitch_dev->nb_txq = nb_txq;
543 : :
544 : : /* Re-enable NIX LF error interrupts */
545 : 0 : roc_nix_err_intr_ena_dis(nix, true);
546 : 0 : roc_nix_ras_intr_ena_dis(nix, true);
547 : :
548 : 0 : rc = roc_nix_lso_fmt_setup(nix);
549 [ # # ]: 0 : if (rc) {
550 : 0 : plt_err("lso setup failed = %s(%d)", roc_error_msg_get(rc), rc);
551 : 0 : goto free_cqs;
552 : : }
553 : :
554 : 0 : rc = roc_nix_switch_hdr_set(nix, 0, 0, 0, 0);
555 [ # # ]: 0 : if (rc) {
556 : 0 : plt_err("switch hdr set failed = %s(%d)", roc_error_msg_get(rc), rc);
557 : 0 : goto free_cqs;
558 : : }
559 : :
560 : 0 : rc = roc_nix_tm_init(nix);
561 [ # # ]: 0 : if (rc) {
562 : 0 : plt_err("tm failed = %s(%d)", roc_error_msg_get(rc), rc);
563 : 0 : goto free_cqs;
564 : : }
565 : :
566 : : /* Register queue IRQs */
567 : 0 : rc = roc_nix_register_queue_irqs(nix);
568 [ # # ]: 0 : if (rc) {
569 : 0 : plt_err("Failed to register queue interrupts rc=%d", rc);
570 : 0 : goto tm_fini;
571 : : }
572 : :
573 : : /* Enable default tree */
574 : 0 : rc = roc_nix_tm_hierarchy_enable(nix, ROC_NIX_TM_DEFAULT, false);
575 [ # # ]: 0 : if (rc) {
576 : 0 : plt_err("tm default hierarchy enable failed = %s(%d)", roc_error_msg_get(rc), rc);
577 : 0 : goto q_irq_fini;
578 : : }
579 : :
580 : : memset(&fc_cfg, 0, sizeof(struct roc_nix_fc_cfg));
581 : : fc_cfg.rxchan_cfg.enable = false;
582 : 0 : rc = roc_nix_fc_config_set(nix, &fc_cfg);
583 [ # # ]: 0 : if (rc) {
584 : 0 : plt_err("Failed to setup flow control, rc=%d(%s)", rc, roc_error_msg_get(rc));
585 : 0 : goto q_irq_fini;
586 : : }
587 : :
588 : 0 : roc_nix_fc_mode_get(nix);
589 : :
590 : 0 : return rc;
591 : 0 : q_irq_fini:
592 : 0 : roc_nix_unregister_queue_irqs(nix);
593 : 0 : tm_fini:
594 : 0 : roc_nix_tm_fini(nix);
595 : 0 : free_cqs:
596 : 0 : rte_free(eswitch_dev->cxq);
597 : 0 : free_sqs:
598 : 0 : rte_free(eswitch_dev->txq);
599 : 0 : free_rqs:
600 : 0 : rte_free(eswitch_dev->rxq);
601 : 0 : lf_free:
602 : 0 : roc_nix_lf_free(nix);
603 : 0 : dev_fini:
604 : 0 : roc_nix_dev_fini(nix);
605 : : fail:
606 : : return rc;
607 : : }
608 : :
609 : : static int
610 : 0 : eswitch_hw_rsrc_setup(struct cnxk_eswitch_dev *eswitch_dev, struct rte_pci_device *pci_dev)
611 : : {
612 : : struct roc_nix *nix;
613 : : int rc;
614 : :
615 : 0 : nix = &eswitch_dev->nix;
616 : 0 : rc = nix_lf_setup(eswitch_dev);
617 [ # # ]: 0 : if (rc) {
618 : 0 : plt_err("Failed to setup hw rsrc, rc=%d(%s)", rc, roc_error_msg_get(rc));
619 : 0 : goto fail;
620 : : }
621 : :
622 : : /* Initialize roc npc */
623 : 0 : eswitch_dev->npc.roc_nix = nix;
624 : 0 : eswitch_dev->npc.flow_max_priority = 3;
625 : 0 : eswitch_dev->npc.flow_prealloc_size = 1;
626 : 0 : rc = roc_npc_init(&eswitch_dev->npc);
627 [ # # ]: 0 : if (rc)
628 : 0 : goto rsrc_cleanup;
629 : :
630 : : /* List for eswitch default flows */
631 : 0 : TAILQ_INIT(&eswitch_dev->esw_flow_list);
632 : :
633 : 0 : return rc;
634 : : rsrc_cleanup:
635 : 0 : eswitch_hw_rsrc_cleanup(eswitch_dev, pci_dev);
636 : : fail:
637 : : return rc;
638 : : }
639 : :
640 : : int
641 : 0 : cnxk_eswitch_representor_info_get(struct cnxk_eswitch_dev *eswitch_dev,
642 : : struct rte_eth_representor_info *info)
643 : : {
644 : : struct cnxk_eswitch_devargs *esw_da;
645 : : int rc = 0, n_entries, i, j = 0, k = 0;
646 : :
647 [ # # ]: 0 : for (i = 0; i < eswitch_dev->nb_esw_da; i++) {
648 [ # # ]: 0 : for (j = 0; j < eswitch_dev->esw_da[i].nb_repr_ports; j++)
649 : 0 : k++;
650 : : }
651 : : n_entries = k;
652 : :
653 [ # # ]: 0 : if (info == NULL)
654 : 0 : goto out;
655 : :
656 : : if ((uint32_t)n_entries > info->nb_ranges_alloc)
657 : : n_entries = info->nb_ranges_alloc;
658 : :
659 : : k = 0;
660 : 0 : info->controller = 0;
661 : 0 : info->pf = 0;
662 [ # # ]: 0 : for (i = 0; i < eswitch_dev->nb_esw_da; i++) {
663 : : esw_da = &eswitch_dev->esw_da[i];
664 : 0 : info->ranges[k].type = esw_da->da.type;
665 [ # # # ]: 0 : switch (esw_da->da.type) {
666 : 0 : case RTE_ETH_REPRESENTOR_PF:
667 : 0 : info->ranges[k].controller = 0;
668 : 0 : info->ranges[k].pf = esw_da->repr_hw_info[0].pfvf;
669 : 0 : info->ranges[k].vf = 0;
670 : 0 : info->ranges[k].id_base = info->ranges[i].pf;
671 : 0 : info->ranges[k].id_end = info->ranges[i].pf;
672 : 0 : snprintf(info->ranges[k].name, sizeof(info->ranges[k].name), "pf%d",
673 : : info->ranges[k].pf);
674 : 0 : k++;
675 : 0 : break;
676 : : case RTE_ETH_REPRESENTOR_VF:
677 [ # # ]: 0 : for (j = 0; j < esw_da->nb_repr_ports; j++) {
678 : 0 : info->ranges[k].controller = 0;
679 : 0 : info->ranges[k].pf = esw_da->da.ports[0];
680 : 0 : info->ranges[k].vf = esw_da->repr_hw_info[j].pfvf;
681 : 0 : info->ranges[k].id_base = esw_da->repr_hw_info[j].port_id;
682 : 0 : info->ranges[k].id_end = esw_da->repr_hw_info[j].port_id;
683 : 0 : snprintf(info->ranges[k].name, sizeof(info->ranges[k].name),
684 : : "pf%dvf%d", info->ranges[k].pf, info->ranges[k].vf);
685 : 0 : k++;
686 : : }
687 : : break;
688 : 0 : default:
689 : 0 : plt_err("Invalid type %d", esw_da->da.type);
690 : : rc = 0;
691 : 0 : goto fail;
692 : : };
693 : : }
694 : 0 : info->nb_ranges = k;
695 : : fail:
696 : : return rc;
697 : : out:
698 : 0 : return n_entries;
699 : : }
700 : :
701 : : static int
702 : 0 : cnxk_eswitch_dev_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
703 : : {
704 : : struct cnxk_eswitch_dev *eswitch_dev;
705 : : const struct rte_memzone *mz = NULL;
706 : : uint16_t num_reps;
707 : : int rc = -ENOMEM;
708 : :
709 : : RTE_SET_USED(pci_drv);
710 : :
711 : : eswitch_dev = cnxk_eswitch_pmd_priv();
712 [ # # ]: 0 : if (!eswitch_dev) {
713 : 0 : rc = roc_plt_init();
714 [ # # ]: 0 : if (rc) {
715 : 0 : plt_err("Failed to initialize platform model, rc=%d", rc);
716 : 0 : return rc;
717 : : }
718 : :
719 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
720 : : return 0;
721 : :
722 : 0 : mz = rte_memzone_reserve_aligned(CNXK_REP_ESWITCH_DEV_MZ, sizeof(*eswitch_dev),
723 : : SOCKET_ID_ANY, 0, RTE_CACHE_LINE_SIZE);
724 [ # # ]: 0 : if (mz == NULL) {
725 : 0 : plt_err("Failed to reserve a memzone");
726 : 0 : goto fail;
727 : : }
728 : :
729 : 0 : eswitch_dev = mz->addr;
730 : 0 : eswitch_dev->pci_dev = pci_dev;
731 : :
732 : 0 : rc = eswitch_hw_rsrc_setup(eswitch_dev, pci_dev);
733 [ # # ]: 0 : if (rc) {
734 : 0 : plt_err("Failed to setup hw rsrc, rc=%d(%s)", rc, roc_error_msg_get(rc));
735 : 0 : goto free_mem;
736 : : }
737 : : }
738 : :
739 [ # # ]: 0 : if (pci_dev->device.devargs) {
740 : 0 : rc = cnxk_eswitch_repr_devargs(pci_dev, eswitch_dev);
741 [ # # ]: 0 : if (rc)
742 : 0 : goto rsrc_cleanup;
743 : : }
744 : :
745 [ # # ]: 0 : if (eswitch_dev->repr_cnt.nb_repr_created > eswitch_dev->repr_cnt.max_repr) {
746 : 0 : plt_err("Representors to be created %d can be greater than max allowed %d",
747 : : eswitch_dev->repr_cnt.nb_repr_created, eswitch_dev->repr_cnt.max_repr);
748 : : rc = -EINVAL;
749 : 0 : goto rsrc_cleanup;
750 : : }
751 : :
752 : : num_reps = eswitch_dev->repr_cnt.nb_repr_created;
753 [ # # ]: 0 : if (!num_reps) {
754 : 0 : plt_err("No representors enabled");
755 : 0 : goto fail;
756 : : }
757 : :
758 : 0 : plt_esw_dbg("Max no of reps %d reps to be created %d Eswtch pfunc %x",
759 : : eswitch_dev->repr_cnt.max_repr, eswitch_dev->repr_cnt.nb_repr_created,
760 : : roc_nix_get_pf_func(&eswitch_dev->nix));
761 : :
762 : : /* Probe representor ports */
763 : 0 : rc = cnxk_rep_dev_probe(pci_dev, eswitch_dev);
764 [ # # ]: 0 : if (rc) {
765 : 0 : plt_err("Failed to probe representor ports");
766 : 0 : goto rsrc_cleanup;
767 : : }
768 : :
769 : : /* Spinlock for synchronization between representors traffic and control
770 : : * messages
771 : : */
772 : : rte_spinlock_init(&eswitch_dev->rep_lock);
773 : :
774 : 0 : return rc;
775 : 0 : rsrc_cleanup:
776 : 0 : eswitch_hw_rsrc_cleanup(eswitch_dev, pci_dev);
777 : 0 : free_mem:
778 : 0 : rte_memzone_free(mz);
779 : : fail:
780 : : return rc;
781 : : }
782 : :
783 : : static const struct rte_pci_id cnxk_eswitch_pci_map[] = {
784 : : {RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CNXK_RVU_ESWITCH_PF)},
785 : : {
786 : : .vendor_id = 0,
787 : : },
788 : : };
789 : :
790 : : static struct rte_pci_driver cnxk_eswitch_pci = {
791 : : .id_table = cnxk_eswitch_pci_map,
792 : : .drv_flags =
793 : : RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_NEED_IOVA_AS_VA | RTE_PCI_DRV_PROBE_AGAIN,
794 : : .probe = cnxk_eswitch_dev_probe,
795 : : .remove = cnxk_eswitch_dev_remove,
796 : : };
797 : :
798 : 252 : RTE_PMD_REGISTER_PCI(cnxk_eswitch, cnxk_eswitch_pci);
799 : : RTE_PMD_REGISTER_PCI_TABLE(cnxk_eswitch, cnxk_eswitch_pci_map);
800 : : RTE_PMD_REGISTER_KMOD_DEP(cnxk_eswitch, "vfio-pci");
|