xref: /dpdk/drivers/net/nfb/nfb_ethdev.c (revision ffc4f45c9d079517b61c1cd0339ce0007cdaace7)
16435f9a0SRastislav Cernay /* SPDX-License-Identifier: BSD-3-Clause
26435f9a0SRastislav Cernay  * Copyright(c) 2019 Cesnet
36435f9a0SRastislav Cernay  * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
46435f9a0SRastislav Cernay  * All rights reserved.
56435f9a0SRastislav Cernay  */
66435f9a0SRastislav Cernay 
76435f9a0SRastislav Cernay #include <nfb/nfb.h>
86435f9a0SRastislav Cernay #include <nfb/ndp.h>
96435f9a0SRastislav Cernay #include <netcope/rxmac.h>
106435f9a0SRastislav Cernay #include <netcope/txmac.h>
116435f9a0SRastislav Cernay 
12df96fd0dSBruce Richardson #include <ethdev_pci.h>
139c7fd48fSRastislav Cernay #include <rte_kvargs.h>
146435f9a0SRastislav Cernay 
156435f9a0SRastislav Cernay #include "nfb_stats.h"
166435f9a0SRastislav Cernay #include "nfb_rx.h"
176435f9a0SRastislav Cernay #include "nfb_tx.h"
186435f9a0SRastislav Cernay #include "nfb_rxmode.h"
196435f9a0SRastislav Cernay #include "nfb.h"
206435f9a0SRastislav Cernay 
216435f9a0SRastislav Cernay /**
226435f9a0SRastislav Cernay  * Default MAC addr
236435f9a0SRastislav Cernay  */
246d13ea8eSOlivier Matz static const struct rte_ether_addr eth_addr = {
256435f9a0SRastislav Cernay 	.addr_bytes = { 0x00, 0x11, 0x17, 0x00, 0x00, 0x00 }
266435f9a0SRastislav Cernay };
276435f9a0SRastislav Cernay 
286435f9a0SRastislav Cernay /**
296435f9a0SRastislav Cernay  * Open all RX DMA queues
306435f9a0SRastislav Cernay  *
316435f9a0SRastislav Cernay  * @param dev
326435f9a0SRastislav Cernay  *   Pointer to nfb device.
336435f9a0SRastislav Cernay  * @param[out] rxmac
346435f9a0SRastislav Cernay  *   Pointer to output array of nc_rxmac
356435f9a0SRastislav Cernay  * @param[out] max_rxmac
366435f9a0SRastislav Cernay  *   Pointer to output max index of rxmac
376435f9a0SRastislav Cernay  */
386435f9a0SRastislav Cernay static void
nfb_nc_rxmac_init(struct nfb_device * nfb,struct nc_rxmac * rxmac[RTE_MAX_NC_RXMAC],uint16_t * max_rxmac)396435f9a0SRastislav Cernay nfb_nc_rxmac_init(struct nfb_device *nfb,
406435f9a0SRastislav Cernay 	struct nc_rxmac *rxmac[RTE_MAX_NC_RXMAC],
416435f9a0SRastislav Cernay 	uint16_t *max_rxmac)
426435f9a0SRastislav Cernay {
436435f9a0SRastislav Cernay 	*max_rxmac = 0;
446435f9a0SRastislav Cernay 	while ((rxmac[*max_rxmac] = nc_rxmac_open_index(nfb, *max_rxmac)))
456435f9a0SRastislav Cernay 		++(*max_rxmac);
466435f9a0SRastislav Cernay }
476435f9a0SRastislav Cernay 
486435f9a0SRastislav Cernay /**
496435f9a0SRastislav Cernay  * Open all TX DMA queues
506435f9a0SRastislav Cernay  *
516435f9a0SRastislav Cernay  * @param dev
526435f9a0SRastislav Cernay  *   Pointer to nfb device.
536435f9a0SRastislav Cernay  * @param[out] txmac
546435f9a0SRastislav Cernay  *   Pointer to output array of nc_txmac
556435f9a0SRastislav Cernay  * @param[out] max_rxmac
566435f9a0SRastislav Cernay  *   Pointer to output max index of txmac
576435f9a0SRastislav Cernay  */
586435f9a0SRastislav Cernay static void
nfb_nc_txmac_init(struct nfb_device * nfb,struct nc_txmac * txmac[RTE_MAX_NC_TXMAC],uint16_t * max_txmac)596435f9a0SRastislav Cernay nfb_nc_txmac_init(struct nfb_device *nfb,
606435f9a0SRastislav Cernay 	struct nc_txmac *txmac[RTE_MAX_NC_TXMAC],
616435f9a0SRastislav Cernay 	uint16_t *max_txmac)
626435f9a0SRastislav Cernay {
636435f9a0SRastislav Cernay 	*max_txmac = 0;
646435f9a0SRastislav Cernay 	while ((txmac[*max_txmac] = nc_txmac_open_index(nfb, *max_txmac)))
656435f9a0SRastislav Cernay 		++(*max_txmac);
666435f9a0SRastislav Cernay }
676435f9a0SRastislav Cernay 
686435f9a0SRastislav Cernay /**
696435f9a0SRastislav Cernay  * Close all RX DMA queues
706435f9a0SRastislav Cernay  *
716435f9a0SRastislav Cernay  * @param rxmac
726435f9a0SRastislav Cernay  *   Pointer to array of nc_rxmac
736435f9a0SRastislav Cernay  * @param max_rxmac
746435f9a0SRastislav Cernay  *   Maximum index of rxmac
756435f9a0SRastislav Cernay  */
766435f9a0SRastislav Cernay static void
nfb_nc_rxmac_deinit(struct nc_rxmac * rxmac[RTE_MAX_NC_RXMAC],uint16_t max_rxmac)776435f9a0SRastislav Cernay nfb_nc_rxmac_deinit(struct nc_rxmac *rxmac[RTE_MAX_NC_RXMAC],
786435f9a0SRastislav Cernay 	uint16_t max_rxmac)
796435f9a0SRastislav Cernay {
808a4c8edbSMartin Spinler 	uint16_t i;
818a4c8edbSMartin Spinler 	for (i = 0; i < max_rxmac; i++) {
828a4c8edbSMartin Spinler 		nc_rxmac_close(rxmac[i]);
838a4c8edbSMartin Spinler 		rxmac[i] = NULL;
846435f9a0SRastislav Cernay 	}
856435f9a0SRastislav Cernay }
866435f9a0SRastislav Cernay 
876435f9a0SRastislav Cernay /**
886435f9a0SRastislav Cernay  * Close all TX DMA queues
896435f9a0SRastislav Cernay  *
906435f9a0SRastislav Cernay  * @param txmac
916435f9a0SRastislav Cernay  *   Pointer to array of nc_txmac
926435f9a0SRastislav Cernay  * @param max_txmac
936435f9a0SRastislav Cernay  *   Maximum index of txmac
946435f9a0SRastislav Cernay  */
956435f9a0SRastislav Cernay static void
nfb_nc_txmac_deinit(struct nc_txmac * txmac[RTE_MAX_NC_TXMAC],uint16_t max_txmac)966435f9a0SRastislav Cernay nfb_nc_txmac_deinit(struct nc_txmac *txmac[RTE_MAX_NC_TXMAC],
976435f9a0SRastislav Cernay 	uint16_t max_txmac)
986435f9a0SRastislav Cernay {
998a4c8edbSMartin Spinler 	uint16_t i;
1008a4c8edbSMartin Spinler 	for (i = 0; i < max_txmac; i++) {
1018a4c8edbSMartin Spinler 		nc_txmac_close(txmac[i]);
1028a4c8edbSMartin Spinler 		txmac[i] = NULL;
1036435f9a0SRastislav Cernay 	}
1046435f9a0SRastislav Cernay }
1056435f9a0SRastislav Cernay 
1066435f9a0SRastislav Cernay /**
1076435f9a0SRastislav Cernay  * DPDK callback to start the device.
1086435f9a0SRastislav Cernay  *
1096435f9a0SRastislav Cernay  * Start device by starting all configured queues.
1106435f9a0SRastislav Cernay  *
1116435f9a0SRastislav Cernay  * @param dev
1126435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
1136435f9a0SRastislav Cernay  *
1146435f9a0SRastislav Cernay  * @return
1156435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
1166435f9a0SRastislav Cernay  */
1176435f9a0SRastislav Cernay static int
nfb_eth_dev_start(struct rte_eth_dev * dev)1186435f9a0SRastislav Cernay nfb_eth_dev_start(struct rte_eth_dev *dev)
1196435f9a0SRastislav Cernay {
1206435f9a0SRastislav Cernay 	int ret;
1216435f9a0SRastislav Cernay 	uint16_t i;
1226435f9a0SRastislav Cernay 	uint16_t nb_rx = dev->data->nb_rx_queues;
1236435f9a0SRastislav Cernay 	uint16_t nb_tx = dev->data->nb_tx_queues;
1246435f9a0SRastislav Cernay 
1256435f9a0SRastislav Cernay 	for (i = 0; i < nb_rx; i++) {
1266435f9a0SRastislav Cernay 		ret = nfb_eth_rx_queue_start(dev, i);
1276435f9a0SRastislav Cernay 		if (ret != 0)
1286435f9a0SRastislav Cernay 			goto err_rx;
1296435f9a0SRastislav Cernay 	}
1306435f9a0SRastislav Cernay 
1316435f9a0SRastislav Cernay 	for (i = 0; i < nb_tx; i++) {
1326435f9a0SRastislav Cernay 		ret = nfb_eth_tx_queue_start(dev, i);
1336435f9a0SRastislav Cernay 		if (ret != 0)
1346435f9a0SRastislav Cernay 			goto err_tx;
1356435f9a0SRastislav Cernay 	}
1366435f9a0SRastislav Cernay 
1376435f9a0SRastislav Cernay 	return 0;
1386435f9a0SRastislav Cernay 
1396435f9a0SRastislav Cernay err_tx:
1406435f9a0SRastislav Cernay 	for (i = 0; i < nb_tx; i++)
1416435f9a0SRastislav Cernay 		nfb_eth_tx_queue_stop(dev, i);
1426435f9a0SRastislav Cernay err_rx:
1436435f9a0SRastislav Cernay 	for (i = 0; i < nb_rx; i++)
1446435f9a0SRastislav Cernay 		nfb_eth_rx_queue_stop(dev, i);
1456435f9a0SRastislav Cernay 	return ret;
1466435f9a0SRastislav Cernay }
1476435f9a0SRastislav Cernay 
1486435f9a0SRastislav Cernay /**
1496435f9a0SRastislav Cernay  * DPDK callback to stop the device.
1506435f9a0SRastislav Cernay  *
1516435f9a0SRastislav Cernay  * Stop device by stopping all configured queues.
1526435f9a0SRastislav Cernay  *
1536435f9a0SRastislav Cernay  * @param dev
1546435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
1556435f9a0SRastislav Cernay  */
15662024eb8SIvan Ilchenko static int
nfb_eth_dev_stop(struct rte_eth_dev * dev)1576435f9a0SRastislav Cernay nfb_eth_dev_stop(struct rte_eth_dev *dev)
1586435f9a0SRastislav Cernay {
1596435f9a0SRastislav Cernay 	uint16_t i;
1606435f9a0SRastislav Cernay 	uint16_t nb_rx = dev->data->nb_rx_queues;
1616435f9a0SRastislav Cernay 	uint16_t nb_tx = dev->data->nb_tx_queues;
1626435f9a0SRastislav Cernay 
163b8f5d2aeSThomas Monjalon 	dev->data->dev_started = 0;
164b8f5d2aeSThomas Monjalon 
1656435f9a0SRastislav Cernay 	for (i = 0; i < nb_tx; i++)
1666435f9a0SRastislav Cernay 		nfb_eth_tx_queue_stop(dev, i);
1676435f9a0SRastislav Cernay 
1686435f9a0SRastislav Cernay 	for (i = 0; i < nb_rx; i++)
1696435f9a0SRastislav Cernay 		nfb_eth_rx_queue_stop(dev, i);
17062024eb8SIvan Ilchenko 
17162024eb8SIvan Ilchenko 	return 0;
1726435f9a0SRastislav Cernay }
1736435f9a0SRastislav Cernay 
1746435f9a0SRastislav Cernay /**
1756435f9a0SRastislav Cernay  * DPDK callback for Ethernet device configuration.
1766435f9a0SRastislav Cernay  *
1776435f9a0SRastislav Cernay  * @param dev
1786435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
1796435f9a0SRastislav Cernay  *
1806435f9a0SRastislav Cernay  * @return
1816435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
1826435f9a0SRastislav Cernay  */
1836435f9a0SRastislav Cernay static int
nfb_eth_dev_configure(struct rte_eth_dev * dev __rte_unused)1846435f9a0SRastislav Cernay nfb_eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
1856435f9a0SRastislav Cernay {
1861b408187SMartin Spinler 	int ret;
1871b408187SMartin Spinler 	struct pmd_internals *internals = dev->data->dev_private;
1881b408187SMartin Spinler 	struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1891b408187SMartin Spinler 
1901b408187SMartin Spinler 	if (dev_conf->rxmode.offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
1911b408187SMartin Spinler 		ret = rte_mbuf_dyn_rx_timestamp_register
1921b408187SMartin Spinler 				(&nfb_timestamp_dynfield_offset,
1931b408187SMartin Spinler 				&nfb_timestamp_rx_dynflag);
1941b408187SMartin Spinler 		if (ret != 0) {
195ad616a80SStephen Hemminger 			NFB_LOG(ERR, "Cannot register Rx timestamp field/flag %d", ret);
1961b408187SMartin Spinler 			nfb_close(internals->nfb);
1971b408187SMartin Spinler 			return -rte_errno;
1981b408187SMartin Spinler 		}
1991b408187SMartin Spinler 	}
2001b408187SMartin Spinler 
2016435f9a0SRastislav Cernay 	return 0;
2026435f9a0SRastislav Cernay }
2036435f9a0SRastislav Cernay 
2043a9f9364SMartin Spinler static uint32_t
nfb_eth_get_max_mac_address_count(struct rte_eth_dev * dev)2053a9f9364SMartin Spinler nfb_eth_get_max_mac_address_count(struct rte_eth_dev *dev)
2063a9f9364SMartin Spinler {
2073a9f9364SMartin Spinler 	uint16_t i;
2083a9f9364SMartin Spinler 	uint32_t c;
2093a9f9364SMartin Spinler 	uint32_t ret = (uint32_t)-1;
2103a9f9364SMartin Spinler 	struct pmd_internals *internals = dev->data->dev_private;
2113a9f9364SMartin Spinler 
2123a9f9364SMartin Spinler 	/*
2133a9f9364SMartin Spinler 	 * Go through all RX MAC components in firmware and find
2143a9f9364SMartin Spinler 	 * the minimal indicated space size for MAC addresses.
2153a9f9364SMartin Spinler 	 */
2163a9f9364SMartin Spinler 	for (i = 0; i < internals->max_rxmac; i++) {
2173a9f9364SMartin Spinler 		c = nc_rxmac_mac_address_count(internals->rxmac[i]);
2183a9f9364SMartin Spinler 		ret = RTE_MIN(c, ret);
2193a9f9364SMartin Spinler 	}
2203a9f9364SMartin Spinler 
2213a9f9364SMartin Spinler 	/* The driver must support at least 1 MAC address, pretend that */
2223a9f9364SMartin Spinler 	if (internals->max_rxmac == 0 || ret == 0)
2233a9f9364SMartin Spinler 		ret = 1;
2243a9f9364SMartin Spinler 
2253a9f9364SMartin Spinler 	return ret;
2263a9f9364SMartin Spinler }
2273a9f9364SMartin Spinler 
2286435f9a0SRastislav Cernay /**
2296435f9a0SRastislav Cernay  * DPDK callback to get information about the device.
2306435f9a0SRastislav Cernay  *
2316435f9a0SRastislav Cernay  * @param dev
2326435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
2336435f9a0SRastislav Cernay  * @param[out] info
2346435f9a0SRastislav Cernay  *   Info structure output buffer.
2356435f9a0SRastislav Cernay  */
236bdad90d1SIvan Ilchenko static int
nfb_eth_dev_info(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)2376435f9a0SRastislav Cernay nfb_eth_dev_info(struct rte_eth_dev *dev,
2386435f9a0SRastislav Cernay 	struct rte_eth_dev_info *dev_info)
2396435f9a0SRastislav Cernay {
2403a9f9364SMartin Spinler 	dev_info->max_mac_addrs = nfb_eth_get_max_mac_address_count(dev);
2413a9f9364SMartin Spinler 
2426435f9a0SRastislav Cernay 	dev_info->max_rx_pktlen = (uint32_t)-1;
2436435f9a0SRastislav Cernay 	dev_info->max_rx_queues = dev->data->nb_rx_queues;
2446435f9a0SRastislav Cernay 	dev_info->max_tx_queues = dev->data->nb_tx_queues;
245295968d1SFerruh Yigit 	dev_info->speed_capa = RTE_ETH_LINK_SPEED_100G;
2461b408187SMartin Spinler 	dev_info->rx_offload_capa =
2471b408187SMartin Spinler 		RTE_ETH_RX_OFFLOAD_TIMESTAMP;
248bdad90d1SIvan Ilchenko 
249bdad90d1SIvan Ilchenko 	return 0;
2506435f9a0SRastislav Cernay }
2516435f9a0SRastislav Cernay 
2526435f9a0SRastislav Cernay /**
2536435f9a0SRastislav Cernay  * DPDK callback to close the device.
2546435f9a0SRastislav Cernay  *
2556435f9a0SRastislav Cernay  * Destroy all queues and objects, free memory.
2566435f9a0SRastislav Cernay  *
2576435f9a0SRastislav Cernay  * @param dev
2586435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
2596435f9a0SRastislav Cernay  */
260b142387bSThomas Monjalon static int
nfb_eth_dev_close(struct rte_eth_dev * dev)2616435f9a0SRastislav Cernay nfb_eth_dev_close(struct rte_eth_dev *dev)
2626435f9a0SRastislav Cernay {
263f1d59d3fSRastislav Cernay 	struct pmd_internals *internals = dev->data->dev_private;
2646435f9a0SRastislav Cernay 	uint16_t i;
2656435f9a0SRastislav Cernay 	uint16_t nb_rx = dev->data->nb_rx_queues;
2666435f9a0SRastislav Cernay 	uint16_t nb_tx = dev->data->nb_tx_queues;
26762024eb8SIvan Ilchenko 	int ret;
2686435f9a0SRastislav Cernay 
26930410493SThomas Monjalon 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
27030410493SThomas Monjalon 		return 0;
27130410493SThomas Monjalon 
27262024eb8SIvan Ilchenko 	ret = nfb_eth_dev_stop(dev);
2736435f9a0SRastislav Cernay 
274f1d59d3fSRastislav Cernay 	nfb_nc_rxmac_deinit(internals->rxmac, internals->max_rxmac);
275f1d59d3fSRastislav Cernay 	nfb_nc_txmac_deinit(internals->txmac, internals->max_txmac);
276f1d59d3fSRastislav Cernay 
2776435f9a0SRastislav Cernay 	for (i = 0; i < nb_rx; i++) {
2787483341aSXueming Li 		nfb_eth_rx_queue_release(dev, i);
2796435f9a0SRastislav Cernay 		dev->data->rx_queues[i] = NULL;
2806435f9a0SRastislav Cernay 	}
2816435f9a0SRastislav Cernay 	dev->data->nb_rx_queues = 0;
2826435f9a0SRastislav Cernay 	for (i = 0; i < nb_tx; i++) {
2837483341aSXueming Li 		nfb_eth_tx_queue_release(dev, i);
2846435f9a0SRastislav Cernay 		dev->data->tx_queues[i] = NULL;
2856435f9a0SRastislav Cernay 	}
2866435f9a0SRastislav Cernay 	dev->data->nb_tx_queues = 0;
287f1d59d3fSRastislav Cernay 
28862024eb8SIvan Ilchenko 	return ret;
2896435f9a0SRastislav Cernay }
2906435f9a0SRastislav Cernay 
2916435f9a0SRastislav Cernay /**
2926435f9a0SRastislav Cernay  * DPDK callback to retrieve physical link information.
2936435f9a0SRastislav Cernay  *
2946435f9a0SRastislav Cernay  * @param dev
2956435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
2966435f9a0SRastislav Cernay  * @param[out] link
2976435f9a0SRastislav Cernay  *   Storage for current link status.
2986435f9a0SRastislav Cernay  *
2996435f9a0SRastislav Cernay  * @return
3006435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
3016435f9a0SRastislav Cernay  */
3026435f9a0SRastislav Cernay static int
nfb_eth_link_update(struct rte_eth_dev * dev,int wait_to_complete __rte_unused)3036435f9a0SRastislav Cernay nfb_eth_link_update(struct rte_eth_dev *dev,
3046435f9a0SRastislav Cernay 	int wait_to_complete __rte_unused)
3056435f9a0SRastislav Cernay {
3066435f9a0SRastislav Cernay 	uint16_t i;
3076435f9a0SRastislav Cernay 	struct nc_rxmac_status status;
3086435f9a0SRastislav Cernay 	struct rte_eth_link link;
3096435f9a0SRastislav Cernay 	memset(&link, 0, sizeof(link));
3106435f9a0SRastislav Cernay 
3116435f9a0SRastislav Cernay 	struct pmd_internals *internals = dev->data->dev_private;
3126435f9a0SRastislav Cernay 
3136435f9a0SRastislav Cernay 	status.speed = MAC_SPEED_UNKNOWN;
3146435f9a0SRastislav Cernay 
315295968d1SFerruh Yigit 	link.link_speed = RTE_ETH_SPEED_NUM_NONE;
316295968d1SFerruh Yigit 	link.link_status = RTE_ETH_LINK_DOWN;
317295968d1SFerruh Yigit 	link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
318295968d1SFerruh Yigit 	link.link_autoneg = RTE_ETH_LINK_SPEED_FIXED;
3196435f9a0SRastislav Cernay 
3206435f9a0SRastislav Cernay 	if (internals->rxmac[0] != NULL) {
3216435f9a0SRastislav Cernay 		nc_rxmac_read_status(internals->rxmac[0], &status);
3226435f9a0SRastislav Cernay 
3236435f9a0SRastislav Cernay 		switch (status.speed) {
3246435f9a0SRastislav Cernay 		case MAC_SPEED_10G:
325295968d1SFerruh Yigit 			link.link_speed = RTE_ETH_SPEED_NUM_10G;
3266435f9a0SRastislav Cernay 			break;
3276435f9a0SRastislav Cernay 		case MAC_SPEED_40G:
328295968d1SFerruh Yigit 			link.link_speed = RTE_ETH_SPEED_NUM_40G;
3296435f9a0SRastislav Cernay 			break;
3306435f9a0SRastislav Cernay 		case MAC_SPEED_100G:
331295968d1SFerruh Yigit 			link.link_speed = RTE_ETH_SPEED_NUM_100G;
3326435f9a0SRastislav Cernay 			break;
3336435f9a0SRastislav Cernay 		default:
334295968d1SFerruh Yigit 			link.link_speed = RTE_ETH_SPEED_NUM_NONE;
3356435f9a0SRastislav Cernay 			break;
3366435f9a0SRastislav Cernay 		}
3376435f9a0SRastislav Cernay 	}
3386435f9a0SRastislav Cernay 
3396435f9a0SRastislav Cernay 	for (i = 0; i < internals->max_rxmac; ++i) {
3406435f9a0SRastislav Cernay 		nc_rxmac_read_status(internals->rxmac[i], &status);
3416435f9a0SRastislav Cernay 
3426435f9a0SRastislav Cernay 		if (status.enabled && status.link_up) {
343295968d1SFerruh Yigit 			link.link_status = RTE_ETH_LINK_UP;
3446435f9a0SRastislav Cernay 			break;
3456435f9a0SRastislav Cernay 		}
3466435f9a0SRastislav Cernay 	}
3476435f9a0SRastislav Cernay 
3486435f9a0SRastislav Cernay 	rte_eth_linkstatus_set(dev, &link);
3496435f9a0SRastislav Cernay 
3506435f9a0SRastislav Cernay 	return 0;
3516435f9a0SRastislav Cernay }
3526435f9a0SRastislav Cernay 
3536435f9a0SRastislav Cernay /**
3546435f9a0SRastislav Cernay  * DPDK callback to bring the link UP.
3556435f9a0SRastislav Cernay  *
3566435f9a0SRastislav Cernay  * @param dev
3576435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
3586435f9a0SRastislav Cernay  *
3596435f9a0SRastislav Cernay  * @return
3606435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
3616435f9a0SRastislav Cernay  */
3626435f9a0SRastislav Cernay static int
nfb_eth_dev_set_link_up(struct rte_eth_dev * dev)3636435f9a0SRastislav Cernay nfb_eth_dev_set_link_up(struct rte_eth_dev *dev)
3646435f9a0SRastislav Cernay {
3656435f9a0SRastislav Cernay 	struct pmd_internals *internals = (struct pmd_internals *)
3666435f9a0SRastislav Cernay 		dev->data->dev_private;
3676435f9a0SRastislav Cernay 
3686435f9a0SRastislav Cernay 	uint16_t i;
3696435f9a0SRastislav Cernay 	for (i = 0; i < internals->max_rxmac; ++i)
3706435f9a0SRastislav Cernay 		nc_rxmac_enable(internals->rxmac[i]);
3716435f9a0SRastislav Cernay 
3726435f9a0SRastislav Cernay 	for (i = 0; i < internals->max_txmac; ++i)
3736435f9a0SRastislav Cernay 		nc_txmac_enable(internals->txmac[i]);
3746435f9a0SRastislav Cernay 
3756435f9a0SRastislav Cernay 	return 0;
3766435f9a0SRastislav Cernay }
3776435f9a0SRastislav Cernay 
3786435f9a0SRastislav Cernay /**
3796435f9a0SRastislav Cernay  * DPDK callback to bring the link DOWN.
3806435f9a0SRastislav Cernay  *
3816435f9a0SRastislav Cernay  * @param dev
3826435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
3836435f9a0SRastislav Cernay  *
3846435f9a0SRastislav Cernay  * @return
3856435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
3866435f9a0SRastislav Cernay  */
3876435f9a0SRastislav Cernay static int
nfb_eth_dev_set_link_down(struct rte_eth_dev * dev)3886435f9a0SRastislav Cernay nfb_eth_dev_set_link_down(struct rte_eth_dev *dev)
3896435f9a0SRastislav Cernay {
3906435f9a0SRastislav Cernay 	struct pmd_internals *internals = (struct pmd_internals *)
3916435f9a0SRastislav Cernay 		dev->data->dev_private;
3926435f9a0SRastislav Cernay 
3936435f9a0SRastislav Cernay 	uint16_t i;
3946435f9a0SRastislav Cernay 	for (i = 0; i < internals->max_rxmac; ++i)
3956435f9a0SRastislav Cernay 		nc_rxmac_disable(internals->rxmac[i]);
3966435f9a0SRastislav Cernay 
3976435f9a0SRastislav Cernay 	for (i = 0; i < internals->max_txmac; ++i)
3986435f9a0SRastislav Cernay 		nc_txmac_disable(internals->txmac[i]);
3996435f9a0SRastislav Cernay 
4006435f9a0SRastislav Cernay 	return 0;
4016435f9a0SRastislav Cernay }
4026435f9a0SRastislav Cernay 
4033a9f9364SMartin Spinler static uint64_t
nfb_eth_mac_addr_conv(struct rte_ether_addr * mac_addr)4043a9f9364SMartin Spinler nfb_eth_mac_addr_conv(struct rte_ether_addr *mac_addr)
4053a9f9364SMartin Spinler {
4063a9f9364SMartin Spinler 	int i;
4073a9f9364SMartin Spinler 	uint64_t res = 0;
4083a9f9364SMartin Spinler 	for (i = 0; i < RTE_ETHER_ADDR_LEN; i++) {
4093a9f9364SMartin Spinler 		res <<= 8;
4103a9f9364SMartin Spinler 		res |= mac_addr->addr_bytes[i] & 0xFF;
4113a9f9364SMartin Spinler 	}
4123a9f9364SMartin Spinler 	return res;
4133a9f9364SMartin Spinler }
4143a9f9364SMartin Spinler 
4156435f9a0SRastislav Cernay /**
4166435f9a0SRastislav Cernay  * DPDK callback to set primary MAC address.
4176435f9a0SRastislav Cernay  *
4186435f9a0SRastislav Cernay  * @param dev
4196435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
4206435f9a0SRastislav Cernay  * @param mac_addr
4216435f9a0SRastislav Cernay  *   MAC address to register.
4226435f9a0SRastislav Cernay  *
4236435f9a0SRastislav Cernay  * @return
4246435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
4256435f9a0SRastislav Cernay  */
4266435f9a0SRastislav Cernay static int
nfb_eth_mac_addr_set(struct rte_eth_dev * dev,struct rte_ether_addr * mac_addr)4276435f9a0SRastislav Cernay nfb_eth_mac_addr_set(struct rte_eth_dev *dev,
4286d13ea8eSOlivier Matz 	struct rte_ether_addr *mac_addr)
4296435f9a0SRastislav Cernay {
4306435f9a0SRastislav Cernay 	unsigned int i;
4313a9f9364SMartin Spinler 	uint64_t mac;
4326435f9a0SRastislav Cernay 	struct rte_eth_dev_data *data = dev->data;
4336435f9a0SRastislav Cernay 	struct pmd_internals *internals = (struct pmd_internals *)
4346435f9a0SRastislav Cernay 		data->dev_private;
4356435f9a0SRastislav Cernay 
4363a9f9364SMartin Spinler 	mac = nfb_eth_mac_addr_conv(mac_addr);
4373a9f9364SMartin Spinler 	/* Until no real multi-port support, configure all RX MACs the same */
4386435f9a0SRastislav Cernay 	for (i = 0; i < internals->max_rxmac; ++i)
4396435f9a0SRastislav Cernay 		nc_rxmac_set_mac(internals->rxmac[i], 0, mac, 1);
4406435f9a0SRastislav Cernay 
4416435f9a0SRastislav Cernay 	return 0;
4426435f9a0SRastislav Cernay }
4436435f9a0SRastislav Cernay 
4443a9f9364SMartin Spinler static int
nfb_eth_mac_addr_add(struct rte_eth_dev * dev,struct rte_ether_addr * mac_addr,uint32_t index,uint32_t pool __rte_unused)4453a9f9364SMartin Spinler nfb_eth_mac_addr_add(struct rte_eth_dev *dev,
4463a9f9364SMartin Spinler 	struct rte_ether_addr *mac_addr, uint32_t index, uint32_t pool __rte_unused)
4473a9f9364SMartin Spinler {
4483a9f9364SMartin Spinler 	unsigned int i;
4493a9f9364SMartin Spinler 	uint64_t mac;
4503a9f9364SMartin Spinler 	struct rte_eth_dev_data *data = dev->data;
4513a9f9364SMartin Spinler 	struct pmd_internals *internals = (struct pmd_internals *)
4523a9f9364SMartin Spinler 		data->dev_private;
4533a9f9364SMartin Spinler 
4543a9f9364SMartin Spinler 	mac = nfb_eth_mac_addr_conv(mac_addr);
4553a9f9364SMartin Spinler 	for (i = 0; i < internals->max_rxmac; ++i)
4563a9f9364SMartin Spinler 		nc_rxmac_set_mac(internals->rxmac[i], index, mac, 1);
4573a9f9364SMartin Spinler 
4583a9f9364SMartin Spinler 	return 0;
4593a9f9364SMartin Spinler }
4603a9f9364SMartin Spinler 
4613a9f9364SMartin Spinler static void
nfb_eth_mac_addr_remove(struct rte_eth_dev * dev,uint32_t index)4623a9f9364SMartin Spinler nfb_eth_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
4633a9f9364SMartin Spinler {
4643a9f9364SMartin Spinler 	unsigned int i;
4653a9f9364SMartin Spinler 	struct rte_eth_dev_data *data = dev->data;
4663a9f9364SMartin Spinler 	struct pmd_internals *internals = (struct pmd_internals *)
4673a9f9364SMartin Spinler 		data->dev_private;
4683a9f9364SMartin Spinler 
4693a9f9364SMartin Spinler 	for (i = 0; i < internals->max_rxmac; ++i)
4703a9f9364SMartin Spinler 		nc_rxmac_set_mac(internals->rxmac[i], index, 0, 0);
4713a9f9364SMartin Spinler }
4723a9f9364SMartin Spinler 
4736435f9a0SRastislav Cernay static const struct eth_dev_ops ops = {
4746435f9a0SRastislav Cernay 	.dev_start = nfb_eth_dev_start,
4756435f9a0SRastislav Cernay 	.dev_stop = nfb_eth_dev_stop,
4766435f9a0SRastislav Cernay 	.dev_set_link_up = nfb_eth_dev_set_link_up,
4776435f9a0SRastislav Cernay 	.dev_set_link_down = nfb_eth_dev_set_link_down,
4786435f9a0SRastislav Cernay 	.dev_close = nfb_eth_dev_close,
4796435f9a0SRastislav Cernay 	.dev_configure = nfb_eth_dev_configure,
4806435f9a0SRastislav Cernay 	.dev_infos_get = nfb_eth_dev_info,
4816435f9a0SRastislav Cernay 	.promiscuous_enable = nfb_eth_promiscuous_enable,
4826435f9a0SRastislav Cernay 	.promiscuous_disable = nfb_eth_promiscuous_disable,
4836435f9a0SRastislav Cernay 	.allmulticast_enable = nfb_eth_allmulticast_enable,
4846435f9a0SRastislav Cernay 	.allmulticast_disable = nfb_eth_allmulticast_disable,
4856435f9a0SRastislav Cernay 	.rx_queue_start = nfb_eth_rx_queue_start,
4866435f9a0SRastislav Cernay 	.rx_queue_stop = nfb_eth_rx_queue_stop,
4876435f9a0SRastislav Cernay 	.tx_queue_start = nfb_eth_tx_queue_start,
4886435f9a0SRastislav Cernay 	.tx_queue_stop = nfb_eth_tx_queue_stop,
4896435f9a0SRastislav Cernay 	.rx_queue_setup = nfb_eth_rx_queue_setup,
4906435f9a0SRastislav Cernay 	.tx_queue_setup = nfb_eth_tx_queue_setup,
4916435f9a0SRastislav Cernay 	.rx_queue_release = nfb_eth_rx_queue_release,
4926435f9a0SRastislav Cernay 	.tx_queue_release = nfb_eth_tx_queue_release,
4936435f9a0SRastislav Cernay 	.link_update = nfb_eth_link_update,
4946435f9a0SRastislav Cernay 	.stats_get = nfb_eth_stats_get,
4956435f9a0SRastislav Cernay 	.stats_reset = nfb_eth_stats_reset,
4966435f9a0SRastislav Cernay 	.mac_addr_set = nfb_eth_mac_addr_set,
4973a9f9364SMartin Spinler 	.mac_addr_add = nfb_eth_mac_addr_add,
4983a9f9364SMartin Spinler 	.mac_addr_remove = nfb_eth_mac_addr_remove,
4996435f9a0SRastislav Cernay };
5006435f9a0SRastislav Cernay 
5016435f9a0SRastislav Cernay /**
5026435f9a0SRastislav Cernay  * DPDK callback to initialize an ethernet device
5036435f9a0SRastislav Cernay  *
5046435f9a0SRastislav Cernay  * @param dev
5056435f9a0SRastislav Cernay  *   Pointer to ethernet device structure
5066435f9a0SRastislav Cernay  *
5076435f9a0SRastislav Cernay  * @return
5086435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
5096435f9a0SRastislav Cernay  */
5106435f9a0SRastislav Cernay static int
nfb_eth_dev_init(struct rte_eth_dev * dev)5116435f9a0SRastislav Cernay nfb_eth_dev_init(struct rte_eth_dev *dev)
5126435f9a0SRastislav Cernay {
5133a9f9364SMartin Spinler 	uint32_t mac_count;
5146435f9a0SRastislav Cernay 	struct rte_eth_dev_data *data = dev->data;
5156435f9a0SRastislav Cernay 	struct pmd_internals *internals = (struct pmd_internals *)
5166435f9a0SRastislav Cernay 		data->dev_private;
5176435f9a0SRastislav Cernay 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
5186435f9a0SRastislav Cernay 	struct rte_pci_addr *pci_addr = &pci_dev->addr;
5196d13ea8eSOlivier Matz 	struct rte_ether_addr eth_addr_init;
520*ffc4f45cSStephen Hemminger 	char nfb_dev[PATH_MAX];
5216435f9a0SRastislav Cernay 
522ad616a80SStephen Hemminger 	NFB_LOG(INFO, "Initializing NFB device (" PCI_PRI_FMT ")",
5236435f9a0SRastislav Cernay 		pci_addr->domain, pci_addr->bus, pci_addr->devid,
5246435f9a0SRastislav Cernay 		pci_addr->function);
5256435f9a0SRastislav Cernay 
526*ffc4f45cSStephen Hemminger 	snprintf(nfb_dev, sizeof(nfb_dev),
5276435f9a0SRastislav Cernay 		"/dev/nfb/by-pci-slot/" PCI_PRI_FMT,
5286435f9a0SRastislav Cernay 		pci_addr->domain, pci_addr->bus, pci_addr->devid,
5296435f9a0SRastislav Cernay 		pci_addr->function);
5306435f9a0SRastislav Cernay 
5316435f9a0SRastislav Cernay 	/*
5326435f9a0SRastislav Cernay 	 * Get number of available DMA RX and TX queues, which is maximum
5336435f9a0SRastislav Cernay 	 * number of queues that can be created and store it in private device
5346435f9a0SRastislav Cernay 	 * data structure.
5356435f9a0SRastislav Cernay 	 */
536*ffc4f45cSStephen Hemminger 	internals->nfb = nfb_open(nfb_dev);
5376435f9a0SRastislav Cernay 	if (internals->nfb == NULL) {
538*ffc4f45cSStephen Hemminger 		NFB_LOG(ERR, "nfb_open(): failed to open %s", nfb_dev);
5396435f9a0SRastislav Cernay 		return -EINVAL;
5406435f9a0SRastislav Cernay 	}
5416435f9a0SRastislav Cernay 	data->nb_rx_queues = ndp_get_rx_queue_available_count(internals->nfb);
5426435f9a0SRastislav Cernay 	data->nb_tx_queues = ndp_get_tx_queue_available_count(internals->nfb);
5436435f9a0SRastislav Cernay 
544ad616a80SStephen Hemminger 	NFB_LOG(INFO, "Available NDP queues RX: %u TX: %u",
5456435f9a0SRastislav Cernay 		data->nb_rx_queues, data->nb_tx_queues);
5466435f9a0SRastislav Cernay 
5476435f9a0SRastislav Cernay 	nfb_nc_rxmac_init(internals->nfb,
5486435f9a0SRastislav Cernay 		internals->rxmac,
5496435f9a0SRastislav Cernay 		&internals->max_rxmac);
5506435f9a0SRastislav Cernay 	nfb_nc_txmac_init(internals->nfb,
5516435f9a0SRastislav Cernay 		internals->txmac,
5526435f9a0SRastislav Cernay 		&internals->max_txmac);
5536435f9a0SRastislav Cernay 
5546435f9a0SRastislav Cernay 	/* Set rx, tx burst functions */
5556435f9a0SRastislav Cernay 	dev->rx_pkt_burst = nfb_eth_ndp_rx;
5566435f9a0SRastislav Cernay 	dev->tx_pkt_burst = nfb_eth_ndp_tx;
5576435f9a0SRastislav Cernay 
5586435f9a0SRastislav Cernay 	/* Set function callbacks for Ethernet API */
5596435f9a0SRastislav Cernay 	dev->dev_ops = &ops;
5606435f9a0SRastislav Cernay 
5616435f9a0SRastislav Cernay 	/* Get link state */
5626435f9a0SRastislav Cernay 	nfb_eth_link_update(dev, 0);
5636435f9a0SRastislav Cernay 
5643a9f9364SMartin Spinler 	/* Allocate space for MAC addresses */
5653a9f9364SMartin Spinler 	mac_count = nfb_eth_get_max_mac_address_count(dev);
5663a9f9364SMartin Spinler 	data->mac_addrs = rte_zmalloc(data->name,
5673a9f9364SMartin Spinler 		sizeof(struct rte_ether_addr) * mac_count, RTE_CACHE_LINE_SIZE);
5686435f9a0SRastislav Cernay 	if (data->mac_addrs == NULL) {
569ad616a80SStephen Hemminger 		NFB_LOG(ERR, "Could not alloc space for MAC address");
5706435f9a0SRastislav Cernay 		nfb_close(internals->nfb);
5716435f9a0SRastislav Cernay 		return -EINVAL;
5726435f9a0SRastislav Cernay 	}
5736435f9a0SRastislav Cernay 
574538da7a1SOlivier Matz 	rte_eth_random_addr(eth_addr_init.addr_bytes);
5756435f9a0SRastislav Cernay 	eth_addr_init.addr_bytes[0] = eth_addr.addr_bytes[0];
5766435f9a0SRastislav Cernay 	eth_addr_init.addr_bytes[1] = eth_addr.addr_bytes[1];
5776435f9a0SRastislav Cernay 	eth_addr_init.addr_bytes[2] = eth_addr.addr_bytes[2];
5786435f9a0SRastislav Cernay 
5796435f9a0SRastislav Cernay 	nfb_eth_mac_addr_set(dev, &eth_addr_init);
5803a9f9364SMartin Spinler 	rte_ether_addr_copy(&eth_addr_init, &dev->data->mac_addrs[0]);
5816435f9a0SRastislav Cernay 
5826435f9a0SRastislav Cernay 	data->promiscuous = nfb_eth_promiscuous_get(dev);
5836435f9a0SRastislav Cernay 	data->all_multicast = nfb_eth_allmulticast_get(dev);
5846435f9a0SRastislav Cernay 
585f30e69b4SFerruh Yigit 	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
586f30e69b4SFerruh Yigit 
587ad616a80SStephen Hemminger 	NFB_LOG(INFO, "NFB device (" PCI_PRI_FMT ") successfully initialized",
5886435f9a0SRastislav Cernay 		pci_addr->domain, pci_addr->bus, pci_addr->devid,
5896435f9a0SRastislav Cernay 		pci_addr->function);
5906435f9a0SRastislav Cernay 
5916435f9a0SRastislav Cernay 	return 0;
5926435f9a0SRastislav Cernay }
5936435f9a0SRastislav Cernay 
5946435f9a0SRastislav Cernay /**
5956435f9a0SRastislav Cernay  * DPDK callback to uninitialize an ethernet device
5966435f9a0SRastislav Cernay  *
5976435f9a0SRastislav Cernay  * @param dev
5986435f9a0SRastislav Cernay  *   Pointer to ethernet device structure
5996435f9a0SRastislav Cernay  *
6006435f9a0SRastislav Cernay  * @return
6016435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
6026435f9a0SRastislav Cernay  */
6036435f9a0SRastislav Cernay static int
nfb_eth_dev_uninit(struct rte_eth_dev * dev)6046435f9a0SRastislav Cernay nfb_eth_dev_uninit(struct rte_eth_dev *dev)
6056435f9a0SRastislav Cernay {
6066435f9a0SRastislav Cernay 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
6076435f9a0SRastislav Cernay 	struct rte_pci_addr *pci_addr = &pci_dev->addr;
6086435f9a0SRastislav Cernay 
609f1d59d3fSRastislav Cernay 	nfb_eth_dev_close(dev);
6106435f9a0SRastislav Cernay 
611ad616a80SStephen Hemminger 	NFB_LOG(INFO, "NFB device (" PCI_PRI_FMT ") successfully uninitialized",
6126435f9a0SRastislav Cernay 		pci_addr->domain, pci_addr->bus, pci_addr->devid,
6136435f9a0SRastislav Cernay 		pci_addr->function);
6146435f9a0SRastislav Cernay 
6156435f9a0SRastislav Cernay 	return 0;
6166435f9a0SRastislav Cernay }
6176435f9a0SRastislav Cernay 
6186435f9a0SRastislav Cernay static const struct rte_pci_id nfb_pci_id_table[] = {
6196435f9a0SRastislav Cernay 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE, PCI_DEVICE_ID_NFB_40G2) },
6206435f9a0SRastislav Cernay 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE, PCI_DEVICE_ID_NFB_100G2) },
6216435f9a0SRastislav Cernay 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_NETCOPE, PCI_DEVICE_ID_NFB_200G2QL) },
622f37c57a1SRastislav Cernay 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_SILICOM, PCI_DEVICE_ID_FB2CGG3) },
623f37c57a1SRastislav Cernay 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_SILICOM, PCI_DEVICE_ID_FB2CGG3D) },
6246435f9a0SRastislav Cernay 	{ .vendor_id = 0, }
6256435f9a0SRastislav Cernay };
6266435f9a0SRastislav Cernay 
6276435f9a0SRastislav Cernay /**
6286435f9a0SRastislav Cernay  * DPDK callback to register a PCI device.
6296435f9a0SRastislav Cernay  *
6306435f9a0SRastislav Cernay  * This function spawns Ethernet devices out of a given PCI device.
6316435f9a0SRastislav Cernay  *
6326435f9a0SRastislav Cernay  * @param[in] pci_drv
6336435f9a0SRastislav Cernay  *   PCI driver structure (nfb_driver).
6346435f9a0SRastislav Cernay  * @param[in] pci_dev
6356435f9a0SRastislav Cernay  *   PCI device information.
6366435f9a0SRastislav Cernay  *
6376435f9a0SRastislav Cernay  * @return
6386435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
6396435f9a0SRastislav Cernay  */
6406435f9a0SRastislav Cernay static int
nfb_eth_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)6416435f9a0SRastislav Cernay nfb_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
6426435f9a0SRastislav Cernay 		struct rte_pci_device *pci_dev)
6436435f9a0SRastislav Cernay {
6446435f9a0SRastislav Cernay 	return rte_eth_dev_pci_generic_probe(pci_dev,
6456435f9a0SRastislav Cernay 		sizeof(struct pmd_internals), nfb_eth_dev_init);
6466435f9a0SRastislav Cernay }
6476435f9a0SRastislav Cernay 
6486435f9a0SRastislav Cernay /**
6496435f9a0SRastislav Cernay  * DPDK callback to remove a PCI device.
6506435f9a0SRastislav Cernay  *
6516435f9a0SRastislav Cernay  * This function removes all Ethernet devices belong to a given PCI device.
6526435f9a0SRastislav Cernay  *
6536435f9a0SRastislav Cernay  * @param[in] pci_dev
6546435f9a0SRastislav Cernay  *   Pointer to the PCI device.
6556435f9a0SRastislav Cernay  *
6566435f9a0SRastislav Cernay  * @return
6576435f9a0SRastislav Cernay  *   0 on success, the function cannot fail.
6586435f9a0SRastislav Cernay  */
6596435f9a0SRastislav Cernay static int
nfb_eth_pci_remove(struct rte_pci_device * pci_dev)6606435f9a0SRastislav Cernay nfb_eth_pci_remove(struct rte_pci_device *pci_dev)
6616435f9a0SRastislav Cernay {
6626435f9a0SRastislav Cernay 	return rte_eth_dev_pci_generic_remove(pci_dev, nfb_eth_dev_uninit);
6636435f9a0SRastislav Cernay }
6646435f9a0SRastislav Cernay 
6656435f9a0SRastislav Cernay static struct rte_pci_driver nfb_eth_driver = {
6666435f9a0SRastislav Cernay 	.id_table = nfb_pci_id_table,
6676435f9a0SRastislav Cernay 	.probe = nfb_eth_pci_probe,
6686435f9a0SRastislav Cernay 	.remove = nfb_eth_pci_remove,
6696435f9a0SRastislav Cernay };
6706435f9a0SRastislav Cernay 
6716435f9a0SRastislav Cernay RTE_PMD_REGISTER_PCI(RTE_NFB_DRIVER_NAME, nfb_eth_driver);
6726435f9a0SRastislav Cernay RTE_PMD_REGISTER_PCI_TABLE(RTE_NFB_DRIVER_NAME, nfb_pci_id_table);
6736435f9a0SRastislav Cernay RTE_PMD_REGISTER_KMOD_DEP(RTE_NFB_DRIVER_NAME, "* nfb");
674ad616a80SStephen Hemminger RTE_LOG_REGISTER_DEFAULT(nfb_logtype, NOTICE);
675