1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Cesnet
3 * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
9 #include <netcope/rxmac.h>
10 #include <netcope/txmac.h>
12 #include <rte_ethdev_pci.h>
14 #include "nfb_stats.h"
17 #include "nfb_rxmode.h"
23 static const struct ether_addr eth_addr
= {
24 .addr_bytes
= { 0x00, 0x11, 0x17, 0x00, 0x00, 0x00 }
28 * Open all RX DMA queues
31 * Pointer to nfb device.
33 * Pointer to output array of nc_rxmac
34 * @param[out] max_rxmac
35 * Pointer to output max index of rxmac
38 nfb_nc_rxmac_init(struct nfb_device
*nfb
,
39 struct nc_rxmac
*rxmac
[RTE_MAX_NC_RXMAC
],
43 while ((rxmac
[*max_rxmac
] = nc_rxmac_open_index(nfb
, *max_rxmac
)))
48 * Open all TX DMA queues
51 * Pointer to nfb device.
53 * Pointer to output array of nc_txmac
54 * @param[out] max_rxmac
55 * Pointer to output max index of txmac
58 nfb_nc_txmac_init(struct nfb_device
*nfb
,
59 struct nc_txmac
*txmac
[RTE_MAX_NC_TXMAC
],
63 while ((txmac
[*max_txmac
] = nc_txmac_open_index(nfb
, *max_txmac
)))
68 * Close all RX DMA queues
71 * Pointer to array of nc_rxmac
73 * Maximum index of rxmac
76 nfb_nc_rxmac_deinit(struct nc_rxmac
*rxmac
[RTE_MAX_NC_RXMAC
],
79 for (; max_rxmac
> 0; --max_rxmac
) {
80 nc_rxmac_close(rxmac
[max_rxmac
]);
81 rxmac
[max_rxmac
] = NULL
;
86 * Close all TX DMA queues
89 * Pointer to array of nc_txmac
91 * Maximum index of txmac
94 nfb_nc_txmac_deinit(struct nc_txmac
*txmac
[RTE_MAX_NC_TXMAC
],
97 for (; max_txmac
> 0; --max_txmac
) {
98 nc_txmac_close(txmac
[max_txmac
]);
99 txmac
[max_txmac
] = NULL
;
104 * DPDK callback to start the device.
106 * Start device by starting all configured queues.
109 * Pointer to Ethernet device structure.
112 * 0 on success, a negative errno value otherwise.
115 nfb_eth_dev_start(struct rte_eth_dev
*dev
)
119 uint16_t nb_rx
= dev
->data
->nb_rx_queues
;
120 uint16_t nb_tx
= dev
->data
->nb_tx_queues
;
122 for (i
= 0; i
< nb_rx
; i
++) {
123 ret
= nfb_eth_rx_queue_start(dev
, i
);
128 for (i
= 0; i
< nb_tx
; i
++) {
129 ret
= nfb_eth_tx_queue_start(dev
, i
);
137 for (i
= 0; i
< nb_tx
; i
++)
138 nfb_eth_tx_queue_stop(dev
, i
);
140 for (i
= 0; i
< nb_rx
; i
++)
141 nfb_eth_rx_queue_stop(dev
, i
);
146 * DPDK callback to stop the device.
148 * Stop device by stopping all configured queues.
151 * Pointer to Ethernet device structure.
154 nfb_eth_dev_stop(struct rte_eth_dev
*dev
)
157 uint16_t nb_rx
= dev
->data
->nb_rx_queues
;
158 uint16_t nb_tx
= dev
->data
->nb_tx_queues
;
160 for (i
= 0; i
< nb_tx
; i
++)
161 nfb_eth_tx_queue_stop(dev
, i
);
163 for (i
= 0; i
< nb_rx
; i
++)
164 nfb_eth_rx_queue_stop(dev
, i
);
168 * DPDK callback for Ethernet device configuration.
171 * Pointer to Ethernet device structure.
174 * 0 on success, a negative errno value otherwise.
177 nfb_eth_dev_configure(struct rte_eth_dev
*dev __rte_unused
)
183 * DPDK callback to get information about the device.
186 * Pointer to Ethernet device structure.
188 * Info structure output buffer.
191 nfb_eth_dev_info(struct rte_eth_dev
*dev
,
192 struct rte_eth_dev_info
*dev_info
)
194 dev_info
->max_mac_addrs
= 1;
195 dev_info
->max_rx_pktlen
= (uint32_t)-1;
196 dev_info
->max_rx_queues
= dev
->data
->nb_rx_queues
;
197 dev_info
->max_tx_queues
= dev
->data
->nb_tx_queues
;
198 dev_info
->speed_capa
= ETH_LINK_SPEED_100G
;
202 * DPDK callback to close the device.
204 * Destroy all queues and objects, free memory.
207 * Pointer to Ethernet device structure.
210 nfb_eth_dev_close(struct rte_eth_dev
*dev
)
213 uint16_t nb_rx
= dev
->data
->nb_rx_queues
;
214 uint16_t nb_tx
= dev
->data
->nb_tx_queues
;
216 nfb_eth_dev_stop(dev
);
218 for (i
= 0; i
< nb_rx
; i
++) {
219 nfb_eth_rx_queue_release(dev
->data
->rx_queues
[i
]);
220 dev
->data
->rx_queues
[i
] = NULL
;
222 dev
->data
->nb_rx_queues
= 0;
223 for (i
= 0; i
< nb_tx
; i
++) {
224 nfb_eth_tx_queue_release(dev
->data
->tx_queues
[i
]);
225 dev
->data
->tx_queues
[i
] = NULL
;
227 dev
->data
->nb_tx_queues
= 0;
231 * DPDK callback to retrieve physical link information.
234 * Pointer to Ethernet device structure.
236 * Storage for current link status.
239 * 0 on success, a negative errno value otherwise.
242 nfb_eth_link_update(struct rte_eth_dev
*dev
,
243 int wait_to_complete __rte_unused
)
246 struct nc_rxmac_status status
;
247 struct rte_eth_link link
;
248 memset(&link
, 0, sizeof(link
));
250 struct pmd_internals
*internals
= dev
->data
->dev_private
;
252 status
.speed
= MAC_SPEED_UNKNOWN
;
254 link
.link_speed
= ETH_SPEED_NUM_NONE
;
255 link
.link_status
= ETH_LINK_DOWN
;
256 link
.link_duplex
= ETH_LINK_FULL_DUPLEX
;
257 link
.link_autoneg
= ETH_LINK_SPEED_FIXED
;
259 if (internals
->rxmac
[0] != NULL
) {
260 nc_rxmac_read_status(internals
->rxmac
[0], &status
);
262 switch (status
.speed
) {
264 link
.link_speed
= ETH_SPEED_NUM_10G
;
267 link
.link_speed
= ETH_SPEED_NUM_40G
;
270 link
.link_speed
= ETH_SPEED_NUM_100G
;
273 link
.link_speed
= ETH_SPEED_NUM_NONE
;
278 for (i
= 0; i
< internals
->max_rxmac
; ++i
) {
279 nc_rxmac_read_status(internals
->rxmac
[i
], &status
);
281 if (status
.enabled
&& status
.link_up
) {
282 link
.link_status
= ETH_LINK_UP
;
287 rte_eth_linkstatus_set(dev
, &link
);
293 * DPDK callback to bring the link UP.
296 * Pointer to Ethernet device structure.
299 * 0 on success, a negative errno value otherwise.
302 nfb_eth_dev_set_link_up(struct rte_eth_dev
*dev
)
304 struct pmd_internals
*internals
= (struct pmd_internals
*)
305 dev
->data
->dev_private
;
308 for (i
= 0; i
< internals
->max_rxmac
; ++i
)
309 nc_rxmac_enable(internals
->rxmac
[i
]);
311 for (i
= 0; i
< internals
->max_txmac
; ++i
)
312 nc_txmac_enable(internals
->txmac
[i
]);
318 * DPDK callback to bring the link DOWN.
321 * Pointer to Ethernet device structure.
324 * 0 on success, a negative errno value otherwise.
327 nfb_eth_dev_set_link_down(struct rte_eth_dev
*dev
)
329 struct pmd_internals
*internals
= (struct pmd_internals
*)
330 dev
->data
->dev_private
;
333 for (i
= 0; i
< internals
->max_rxmac
; ++i
)
334 nc_rxmac_disable(internals
->rxmac
[i
]);
336 for (i
= 0; i
< internals
->max_txmac
; ++i
)
337 nc_txmac_disable(internals
->txmac
[i
]);
343 * DPDK callback to set primary MAC address.
346 * Pointer to Ethernet device structure.
348 * MAC address to register.
351 * 0 on success, a negative errno value otherwise.
354 nfb_eth_mac_addr_set(struct rte_eth_dev
*dev
,
355 struct ether_addr
*mac_addr
)
359 struct rte_eth_dev_data
*data
= dev
->data
;
360 struct pmd_internals
*internals
= (struct pmd_internals
*)
363 if (!is_valid_assigned_ether_addr(mac_addr
))
366 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
368 mac
|= mac_addr
->addr_bytes
[i
] & 0xFF;
371 for (i
= 0; i
< internals
->max_rxmac
; ++i
)
372 nc_rxmac_set_mac(internals
->rxmac
[i
], 0, mac
, 1);
374 ether_addr_copy(mac_addr
, data
->mac_addrs
);
378 static const struct eth_dev_ops ops
= {
379 .dev_start
= nfb_eth_dev_start
,
380 .dev_stop
= nfb_eth_dev_stop
,
381 .dev_set_link_up
= nfb_eth_dev_set_link_up
,
382 .dev_set_link_down
= nfb_eth_dev_set_link_down
,
383 .dev_close
= nfb_eth_dev_close
,
384 .dev_configure
= nfb_eth_dev_configure
,
385 .dev_infos_get
= nfb_eth_dev_info
,
386 .promiscuous_enable
= nfb_eth_promiscuous_enable
,
387 .promiscuous_disable
= nfb_eth_promiscuous_disable
,
388 .allmulticast_enable
= nfb_eth_allmulticast_enable
,
389 .allmulticast_disable
= nfb_eth_allmulticast_disable
,
390 .rx_queue_start
= nfb_eth_rx_queue_start
,
391 .rx_queue_stop
= nfb_eth_rx_queue_stop
,
392 .tx_queue_start
= nfb_eth_tx_queue_start
,
393 .tx_queue_stop
= nfb_eth_tx_queue_stop
,
394 .rx_queue_setup
= nfb_eth_rx_queue_setup
,
395 .tx_queue_setup
= nfb_eth_tx_queue_setup
,
396 .rx_queue_release
= nfb_eth_rx_queue_release
,
397 .tx_queue_release
= nfb_eth_tx_queue_release
,
398 .link_update
= nfb_eth_link_update
,
399 .stats_get
= nfb_eth_stats_get
,
400 .stats_reset
= nfb_eth_stats_reset
,
401 .mac_addr_set
= nfb_eth_mac_addr_set
,
405 * DPDK callback to initialize an ethernet device
408 * Pointer to ethernet device structure
411 * 0 on success, a negative errno value otherwise.
414 nfb_eth_dev_init(struct rte_eth_dev
*dev
)
416 struct rte_eth_dev_data
*data
= dev
->data
;
417 struct pmd_internals
*internals
= (struct pmd_internals
*)
419 struct rte_pci_device
*pci_dev
= RTE_ETH_DEV_TO_PCI(dev
);
420 struct rte_pci_addr
*pci_addr
= &pci_dev
->addr
;
421 struct ether_addr eth_addr_init
;
423 RTE_LOG(INFO
, PMD
, "Initializing NFB device (" PCI_PRI_FMT
")\n",
424 pci_addr
->domain
, pci_addr
->bus
, pci_addr
->devid
,
427 snprintf(internals
->nfb_dev
, PATH_MAX
,
428 "/dev/nfb/by-pci-slot/" PCI_PRI_FMT
,
429 pci_addr
->domain
, pci_addr
->bus
, pci_addr
->devid
,
433 * Get number of available DMA RX and TX queues, which is maximum
434 * number of queues that can be created and store it in private device
437 internals
->nfb
= nfb_open(internals
->nfb_dev
);
438 if (internals
->nfb
== NULL
) {
439 RTE_LOG(ERR
, PMD
, "nfb_open(): failed to open %s",
443 data
->nb_rx_queues
= ndp_get_rx_queue_available_count(internals
->nfb
);
444 data
->nb_tx_queues
= ndp_get_tx_queue_available_count(internals
->nfb
);
446 RTE_LOG(INFO
, PMD
, "Available NDP queues RX: %u TX: %u\n",
447 data
->nb_rx_queues
, data
->nb_tx_queues
);
449 nfb_nc_rxmac_init(internals
->nfb
,
451 &internals
->max_rxmac
);
452 nfb_nc_txmac_init(internals
->nfb
,
454 &internals
->max_txmac
);
456 /* Set rx, tx burst functions */
457 dev
->rx_pkt_burst
= nfb_eth_ndp_rx
;
458 dev
->tx_pkt_burst
= nfb_eth_ndp_tx
;
460 /* Set function callbacks for Ethernet API */
464 nfb_eth_link_update(dev
, 0);
466 /* Allocate space for one mac address */
467 data
->mac_addrs
= rte_zmalloc(data
->name
, sizeof(struct ether_addr
),
468 RTE_CACHE_LINE_SIZE
);
469 if (data
->mac_addrs
== NULL
) {
470 RTE_LOG(ERR
, PMD
, "Could not alloc space for MAC address!\n");
471 nfb_close(internals
->nfb
);
475 eth_random_addr(eth_addr_init
.addr_bytes
);
476 eth_addr_init
.addr_bytes
[0] = eth_addr
.addr_bytes
[0];
477 eth_addr_init
.addr_bytes
[1] = eth_addr
.addr_bytes
[1];
478 eth_addr_init
.addr_bytes
[2] = eth_addr
.addr_bytes
[2];
480 nfb_eth_mac_addr_set(dev
, ð_addr_init
);
482 data
->promiscuous
= nfb_eth_promiscuous_get(dev
);
483 data
->all_multicast
= nfb_eth_allmulticast_get(dev
);
484 internals
->rx_filter_original
= data
->promiscuous
;
486 RTE_LOG(INFO
, PMD
, "NFB device ("
487 PCI_PRI_FMT
") successfully initialized\n",
488 pci_addr
->domain
, pci_addr
->bus
, pci_addr
->devid
,
495 * DPDK callback to uninitialize an ethernet device
498 * Pointer to ethernet device structure
501 * 0 on success, a negative errno value otherwise.
504 nfb_eth_dev_uninit(struct rte_eth_dev
*dev
)
506 struct rte_eth_dev_data
*data
= dev
->data
;
507 struct pmd_internals
*internals
= (struct pmd_internals
*)
510 struct rte_pci_device
*pci_dev
= RTE_ETH_DEV_TO_PCI(dev
);
511 struct rte_pci_addr
*pci_addr
= &pci_dev
->addr
;
513 dev
->data
->mac_addrs
= NULL
;
515 nfb_nc_rxmac_deinit(internals
->rxmac
, internals
->max_rxmac
);
516 nfb_nc_txmac_deinit(internals
->txmac
, internals
->max_txmac
);
518 RTE_LOG(INFO
, PMD
, "NFB device ("
519 PCI_PRI_FMT
") successfully uninitialized\n",
520 pci_addr
->domain
, pci_addr
->bus
, pci_addr
->devid
,
526 static const struct rte_pci_id nfb_pci_id_table
[] = {
527 { RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE
, PCI_DEVICE_ID_NFB_40G2
) },
528 { RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE
, PCI_DEVICE_ID_NFB_100G2
) },
529 { RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE
, PCI_DEVICE_ID_NFB_200G2QL
) },
534 * DPDK callback to register a PCI device.
536 * This function spawns Ethernet devices out of a given PCI device.
539 * PCI driver structure (nfb_driver).
541 * PCI device information.
544 * 0 on success, a negative errno value otherwise.
547 nfb_eth_pci_probe(struct rte_pci_driver
*pci_drv __rte_unused
,
548 struct rte_pci_device
*pci_dev
)
550 return rte_eth_dev_pci_generic_probe(pci_dev
,
551 sizeof(struct pmd_internals
), nfb_eth_dev_init
);
555 * DPDK callback to remove a PCI device.
557 * This function removes all Ethernet devices belong to a given PCI device.
560 * Pointer to the PCI device.
563 * 0 on success, the function cannot fail.
566 nfb_eth_pci_remove(struct rte_pci_device
*pci_dev
)
568 return rte_eth_dev_pci_generic_remove(pci_dev
, nfb_eth_dev_uninit
);
571 static struct rte_pci_driver nfb_eth_driver
= {
572 .id_table
= nfb_pci_id_table
,
573 .probe
= nfb_eth_pci_probe
,
574 .remove
= nfb_eth_pci_remove
,
577 RTE_PMD_REGISTER_PCI(RTE_NFB_DRIVER_NAME
, nfb_eth_driver
);
578 RTE_PMD_REGISTER_PCI_TABLE(RTE_NFB_DRIVER_NAME
, nfb_pci_id_table
);
579 RTE_PMD_REGISTER_KMOD_DEP(RTE_NFB_DRIVER_NAME
, "* nfb");