xref: /dpdk/drivers/net/sfc/sfc_ethdev.c (revision a8e64c6b455f4dd0b39f256e02f73401ce3cd09c)
163d588ffSAndrew Rybchenko /*-
263d588ffSAndrew Rybchenko  * Copyright (c) 2016 Solarflare Communications Inc.
363d588ffSAndrew Rybchenko  * All rights reserved.
463d588ffSAndrew Rybchenko  *
563d588ffSAndrew Rybchenko  * This software was jointly developed between OKTET Labs (under contract
663d588ffSAndrew Rybchenko  * for Solarflare) and Solarflare Communications, Inc.
763d588ffSAndrew Rybchenko  *
863d588ffSAndrew Rybchenko  * Redistribution and use in source and binary forms, with or without
963d588ffSAndrew Rybchenko  * modification, are permitted provided that the following conditions are met:
1063d588ffSAndrew Rybchenko  *
1163d588ffSAndrew Rybchenko  * 1. Redistributions of source code must retain the above copyright notice,
1263d588ffSAndrew Rybchenko  *    this list of conditions and the following disclaimer.
1363d588ffSAndrew Rybchenko  * 2. Redistributions in binary form must reproduce the above copyright notice,
1463d588ffSAndrew Rybchenko  *    this list of conditions and the following disclaimer in the documentation
1563d588ffSAndrew Rybchenko  *    and/or other materials provided with the distribution.
1663d588ffSAndrew Rybchenko  *
1763d588ffSAndrew Rybchenko  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1863d588ffSAndrew Rybchenko  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1963d588ffSAndrew Rybchenko  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2063d588ffSAndrew Rybchenko  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2163d588ffSAndrew Rybchenko  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2263d588ffSAndrew Rybchenko  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2363d588ffSAndrew Rybchenko  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2463d588ffSAndrew Rybchenko  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2563d588ffSAndrew Rybchenko  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2663d588ffSAndrew Rybchenko  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
2763d588ffSAndrew Rybchenko  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2863d588ffSAndrew Rybchenko  */
2963d588ffSAndrew Rybchenko 
3063d588ffSAndrew Rybchenko #include <rte_dev.h>
3163d588ffSAndrew Rybchenko #include <rte_ethdev.h>
3263d588ffSAndrew Rybchenko #include <rte_pci.h>
3363d588ffSAndrew Rybchenko 
34ba641f20SAndrew Rybchenko #include "efx.h"
35ba641f20SAndrew Rybchenko 
3663d588ffSAndrew Rybchenko #include "sfc.h"
3763d588ffSAndrew Rybchenko #include "sfc_debug.h"
3863d588ffSAndrew Rybchenko #include "sfc_log.h"
3963d588ffSAndrew Rybchenko #include "sfc_kvargs.h"
40886f8d8aSArtem Andreev #include "sfc_ev.h"
4163d588ffSAndrew Rybchenko 
4263d588ffSAndrew Rybchenko 
4363d588ffSAndrew Rybchenko static void
4463d588ffSAndrew Rybchenko sfc_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
4563d588ffSAndrew Rybchenko {
4663d588ffSAndrew Rybchenko 	struct sfc_adapter *sa = dev->data->dev_private;
4763d588ffSAndrew Rybchenko 
4863d588ffSAndrew Rybchenko 	sfc_log_init(sa, "entry");
4963d588ffSAndrew Rybchenko 
5063d588ffSAndrew Rybchenko 	dev_info->pci_dev = RTE_DEV_TO_PCI(dev->device);
5103ed2119SAndrew Rybchenko 	dev_info->max_rx_pktlen = EFX_MAC_PDU_MAX;
52*a8e64c6bSAndrew Rybchenko 
53*a8e64c6bSAndrew Rybchenko 	/* By default packets are dropped if no descriptors are available */
54*a8e64c6bSAndrew Rybchenko 	dev_info->default_rxconf.rx_drop_en = 1;
55*a8e64c6bSAndrew Rybchenko 
56*a8e64c6bSAndrew Rybchenko 	dev_info->rx_desc_lim.nb_max = EFX_RXQ_MAXNDESCS;
57*a8e64c6bSAndrew Rybchenko 	dev_info->rx_desc_lim.nb_min = EFX_RXQ_MINNDESCS;
58*a8e64c6bSAndrew Rybchenko 	/* The RXQ hardware requires that the descriptor count is a power
59*a8e64c6bSAndrew Rybchenko 	 * of 2, but rx_desc_lim cannot properly describe that constraint.
60*a8e64c6bSAndrew Rybchenko 	 */
61*a8e64c6bSAndrew Rybchenko 	dev_info->rx_desc_lim.nb_align = EFX_RXQ_MINNDESCS;
6263d588ffSAndrew Rybchenko }
6363d588ffSAndrew Rybchenko 
64aaa3f5f0SAndrew Rybchenko static int
65aaa3f5f0SAndrew Rybchenko sfc_dev_configure(struct rte_eth_dev *dev)
66aaa3f5f0SAndrew Rybchenko {
67aaa3f5f0SAndrew Rybchenko 	struct rte_eth_dev_data *dev_data = dev->data;
68aaa3f5f0SAndrew Rybchenko 	struct sfc_adapter *sa = dev_data->dev_private;
69aaa3f5f0SAndrew Rybchenko 	int rc;
70aaa3f5f0SAndrew Rybchenko 
71aaa3f5f0SAndrew Rybchenko 	sfc_log_init(sa, "entry n_rxq=%u n_txq=%u",
72aaa3f5f0SAndrew Rybchenko 		     dev_data->nb_rx_queues, dev_data->nb_tx_queues);
73aaa3f5f0SAndrew Rybchenko 
74aaa3f5f0SAndrew Rybchenko 	sfc_adapter_lock(sa);
75aaa3f5f0SAndrew Rybchenko 	switch (sa->state) {
76aaa3f5f0SAndrew Rybchenko 	case SFC_ADAPTER_CONFIGURED:
77aaa3f5f0SAndrew Rybchenko 		sfc_close(sa);
78aaa3f5f0SAndrew Rybchenko 		SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
79aaa3f5f0SAndrew Rybchenko 		/* FALLTHROUGH */
80aaa3f5f0SAndrew Rybchenko 	case SFC_ADAPTER_INITIALIZED:
81aaa3f5f0SAndrew Rybchenko 		rc = sfc_configure(sa);
82aaa3f5f0SAndrew Rybchenko 		break;
83aaa3f5f0SAndrew Rybchenko 	default:
84aaa3f5f0SAndrew Rybchenko 		sfc_err(sa, "unexpected adapter state %u to configure",
85aaa3f5f0SAndrew Rybchenko 			sa->state);
86aaa3f5f0SAndrew Rybchenko 		rc = EINVAL;
87aaa3f5f0SAndrew Rybchenko 		break;
88aaa3f5f0SAndrew Rybchenko 	}
89aaa3f5f0SAndrew Rybchenko 	sfc_adapter_unlock(sa);
90aaa3f5f0SAndrew Rybchenko 
91aaa3f5f0SAndrew Rybchenko 	sfc_log_init(sa, "done %d", rc);
92aaa3f5f0SAndrew Rybchenko 	SFC_ASSERT(rc >= 0);
93aaa3f5f0SAndrew Rybchenko 	return -rc;
94aaa3f5f0SAndrew Rybchenko }
95aaa3f5f0SAndrew Rybchenko 
9693fcf09bSAndrew Rybchenko static int
9793fcf09bSAndrew Rybchenko sfc_dev_start(struct rte_eth_dev *dev)
9893fcf09bSAndrew Rybchenko {
9993fcf09bSAndrew Rybchenko 	struct sfc_adapter *sa = dev->data->dev_private;
10093fcf09bSAndrew Rybchenko 	int rc;
10193fcf09bSAndrew Rybchenko 
10293fcf09bSAndrew Rybchenko 	sfc_log_init(sa, "entry");
10393fcf09bSAndrew Rybchenko 
10493fcf09bSAndrew Rybchenko 	sfc_adapter_lock(sa);
10593fcf09bSAndrew Rybchenko 	rc = sfc_start(sa);
10693fcf09bSAndrew Rybchenko 	sfc_adapter_unlock(sa);
10793fcf09bSAndrew Rybchenko 
10893fcf09bSAndrew Rybchenko 	sfc_log_init(sa, "done %d", rc);
10993fcf09bSAndrew Rybchenko 	SFC_ASSERT(rc >= 0);
11093fcf09bSAndrew Rybchenko 	return -rc;
11193fcf09bSAndrew Rybchenko }
11293fcf09bSAndrew Rybchenko 
113886f8d8aSArtem Andreev static int
114886f8d8aSArtem Andreev sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
115886f8d8aSArtem Andreev {
116886f8d8aSArtem Andreev 	struct sfc_adapter *sa = dev->data->dev_private;
117886f8d8aSArtem Andreev 	struct rte_eth_link *dev_link = &dev->data->dev_link;
118886f8d8aSArtem Andreev 	struct rte_eth_link old_link;
119886f8d8aSArtem Andreev 	struct rte_eth_link current_link;
120886f8d8aSArtem Andreev 
121886f8d8aSArtem Andreev 	sfc_log_init(sa, "entry");
122886f8d8aSArtem Andreev 
123886f8d8aSArtem Andreev 	if (sa->state != SFC_ADAPTER_STARTED)
124886f8d8aSArtem Andreev 		return 0;
125886f8d8aSArtem Andreev 
126886f8d8aSArtem Andreev retry:
127886f8d8aSArtem Andreev 	EFX_STATIC_ASSERT(sizeof(*dev_link) == sizeof(rte_atomic64_t));
128886f8d8aSArtem Andreev 	*(int64_t *)&old_link = rte_atomic64_read((rte_atomic64_t *)dev_link);
129886f8d8aSArtem Andreev 
130886f8d8aSArtem Andreev 	if (wait_to_complete) {
131886f8d8aSArtem Andreev 		efx_link_mode_t link_mode;
132886f8d8aSArtem Andreev 
133886f8d8aSArtem Andreev 		efx_port_poll(sa->nic, &link_mode);
134886f8d8aSArtem Andreev 		sfc_port_link_mode_to_info(link_mode, &current_link);
135886f8d8aSArtem Andreev 
136886f8d8aSArtem Andreev 		if (!rte_atomic64_cmpset((volatile uint64_t *)dev_link,
137886f8d8aSArtem Andreev 					 *(uint64_t *)&old_link,
138886f8d8aSArtem Andreev 					 *(uint64_t *)&current_link))
139886f8d8aSArtem Andreev 			goto retry;
140886f8d8aSArtem Andreev 	} else {
141886f8d8aSArtem Andreev 		sfc_ev_mgmt_qpoll(sa);
142886f8d8aSArtem Andreev 		*(int64_t *)&current_link =
143886f8d8aSArtem Andreev 			rte_atomic64_read((rte_atomic64_t *)dev_link);
144886f8d8aSArtem Andreev 	}
145886f8d8aSArtem Andreev 
146886f8d8aSArtem Andreev 	if (old_link.link_status != current_link.link_status)
147886f8d8aSArtem Andreev 		sfc_info(sa, "Link status is %s",
148886f8d8aSArtem Andreev 			 current_link.link_status ? "UP" : "DOWN");
149886f8d8aSArtem Andreev 
150886f8d8aSArtem Andreev 	return old_link.link_status == current_link.link_status ? 0 : -1;
151886f8d8aSArtem Andreev }
152886f8d8aSArtem Andreev 
15393fcf09bSAndrew Rybchenko static void
15493fcf09bSAndrew Rybchenko sfc_dev_stop(struct rte_eth_dev *dev)
15593fcf09bSAndrew Rybchenko {
15693fcf09bSAndrew Rybchenko 	struct sfc_adapter *sa = dev->data->dev_private;
15793fcf09bSAndrew Rybchenko 
15893fcf09bSAndrew Rybchenko 	sfc_log_init(sa, "entry");
15993fcf09bSAndrew Rybchenko 
16093fcf09bSAndrew Rybchenko 	sfc_adapter_lock(sa);
16193fcf09bSAndrew Rybchenko 	sfc_stop(sa);
16293fcf09bSAndrew Rybchenko 	sfc_adapter_unlock(sa);
16393fcf09bSAndrew Rybchenko 
16493fcf09bSAndrew Rybchenko 	sfc_log_init(sa, "done");
16593fcf09bSAndrew Rybchenko }
16693fcf09bSAndrew Rybchenko 
167aaa3f5f0SAndrew Rybchenko static void
168aaa3f5f0SAndrew Rybchenko sfc_dev_close(struct rte_eth_dev *dev)
169aaa3f5f0SAndrew Rybchenko {
170aaa3f5f0SAndrew Rybchenko 	struct sfc_adapter *sa = dev->data->dev_private;
171aaa3f5f0SAndrew Rybchenko 
172aaa3f5f0SAndrew Rybchenko 	sfc_log_init(sa, "entry");
173aaa3f5f0SAndrew Rybchenko 
174aaa3f5f0SAndrew Rybchenko 	sfc_adapter_lock(sa);
175aaa3f5f0SAndrew Rybchenko 	switch (sa->state) {
17693fcf09bSAndrew Rybchenko 	case SFC_ADAPTER_STARTED:
17793fcf09bSAndrew Rybchenko 		sfc_stop(sa);
17893fcf09bSAndrew Rybchenko 		SFC_ASSERT(sa->state == SFC_ADAPTER_CONFIGURED);
17993fcf09bSAndrew Rybchenko 		/* FALLTHROUGH */
180aaa3f5f0SAndrew Rybchenko 	case SFC_ADAPTER_CONFIGURED:
181aaa3f5f0SAndrew Rybchenko 		sfc_close(sa);
182aaa3f5f0SAndrew Rybchenko 		SFC_ASSERT(sa->state == SFC_ADAPTER_INITIALIZED);
183aaa3f5f0SAndrew Rybchenko 		/* FALLTHROUGH */
184aaa3f5f0SAndrew Rybchenko 	case SFC_ADAPTER_INITIALIZED:
185aaa3f5f0SAndrew Rybchenko 		break;
186aaa3f5f0SAndrew Rybchenko 	default:
187aaa3f5f0SAndrew Rybchenko 		sfc_err(sa, "unexpected adapter state %u on close", sa->state);
188aaa3f5f0SAndrew Rybchenko 		break;
189aaa3f5f0SAndrew Rybchenko 	}
190aaa3f5f0SAndrew Rybchenko 	sfc_adapter_unlock(sa);
191aaa3f5f0SAndrew Rybchenko 
192aaa3f5f0SAndrew Rybchenko 	sfc_log_init(sa, "done");
193aaa3f5f0SAndrew Rybchenko }
194aaa3f5f0SAndrew Rybchenko 
19563d588ffSAndrew Rybchenko static const struct eth_dev_ops sfc_eth_dev_ops = {
196aaa3f5f0SAndrew Rybchenko 	.dev_configure			= sfc_dev_configure,
19793fcf09bSAndrew Rybchenko 	.dev_start			= sfc_dev_start,
19893fcf09bSAndrew Rybchenko 	.dev_stop			= sfc_dev_stop,
199aaa3f5f0SAndrew Rybchenko 	.dev_close			= sfc_dev_close,
200886f8d8aSArtem Andreev 	.link_update			= sfc_dev_link_update,
20163d588ffSAndrew Rybchenko 	.dev_infos_get			= sfc_dev_infos_get,
20263d588ffSAndrew Rybchenko };
20363d588ffSAndrew Rybchenko 
20463d588ffSAndrew Rybchenko static int
20563d588ffSAndrew Rybchenko sfc_eth_dev_init(struct rte_eth_dev *dev)
20663d588ffSAndrew Rybchenko {
20763d588ffSAndrew Rybchenko 	struct sfc_adapter *sa = dev->data->dev_private;
20863d588ffSAndrew Rybchenko 	struct rte_pci_device *pci_dev = SFC_DEV_TO_PCI(dev);
20963d588ffSAndrew Rybchenko 	int rc;
210ba641f20SAndrew Rybchenko 	const efx_nic_cfg_t *encp;
211ba641f20SAndrew Rybchenko 	const struct ether_addr *from;
21263d588ffSAndrew Rybchenko 
21363d588ffSAndrew Rybchenko 	/* Required for logging */
21463d588ffSAndrew Rybchenko 	sa->eth_dev = dev;
21563d588ffSAndrew Rybchenko 
21663d588ffSAndrew Rybchenko 	/* Copy PCI device info to the dev->data */
21763d588ffSAndrew Rybchenko 	rte_eth_copy_pci_info(dev, pci_dev);
21863d588ffSAndrew Rybchenko 
21963d588ffSAndrew Rybchenko 	rc = sfc_kvargs_parse(sa);
22063d588ffSAndrew Rybchenko 	if (rc != 0)
22163d588ffSAndrew Rybchenko 		goto fail_kvargs_parse;
22263d588ffSAndrew Rybchenko 
22363d588ffSAndrew Rybchenko 	rc = sfc_kvargs_process(sa, SFC_KVARG_DEBUG_INIT,
22463d588ffSAndrew Rybchenko 				sfc_kvarg_bool_handler, &sa->debug_init);
22563d588ffSAndrew Rybchenko 	if (rc != 0)
22663d588ffSAndrew Rybchenko 		goto fail_kvarg_debug_init;
22763d588ffSAndrew Rybchenko 
22863d588ffSAndrew Rybchenko 	sfc_log_init(sa, "entry");
22963d588ffSAndrew Rybchenko 
230ba641f20SAndrew Rybchenko 	dev->data->mac_addrs = rte_zmalloc("sfc", ETHER_ADDR_LEN, 0);
231ba641f20SAndrew Rybchenko 	if (dev->data->mac_addrs == NULL) {
232ba641f20SAndrew Rybchenko 		rc = ENOMEM;
233ba641f20SAndrew Rybchenko 		goto fail_mac_addrs;
234ba641f20SAndrew Rybchenko 	}
235ba641f20SAndrew Rybchenko 
236ba641f20SAndrew Rybchenko 	sfc_adapter_lock_init(sa);
237ba641f20SAndrew Rybchenko 	sfc_adapter_lock(sa);
238ba641f20SAndrew Rybchenko 
239ba641f20SAndrew Rybchenko 	sfc_log_init(sa, "attaching");
240ba641f20SAndrew Rybchenko 	rc = sfc_attach(sa);
241ba641f20SAndrew Rybchenko 	if (rc != 0)
242ba641f20SAndrew Rybchenko 		goto fail_attach;
243ba641f20SAndrew Rybchenko 
244ba641f20SAndrew Rybchenko 	encp = efx_nic_cfg_get(sa->nic);
245ba641f20SAndrew Rybchenko 
246ba641f20SAndrew Rybchenko 	/*
247ba641f20SAndrew Rybchenko 	 * The arguments are really reverse order in comparison to
248ba641f20SAndrew Rybchenko 	 * Linux kernel. Copy from NIC config to Ethernet device data.
249ba641f20SAndrew Rybchenko 	 */
250ba641f20SAndrew Rybchenko 	from = (const struct ether_addr *)(encp->enc_mac_addr);
251ba641f20SAndrew Rybchenko 	ether_addr_copy(from, &dev->data->mac_addrs[0]);
252ba641f20SAndrew Rybchenko 
25363d588ffSAndrew Rybchenko 	dev->dev_ops = &sfc_eth_dev_ops;
25463d588ffSAndrew Rybchenko 
255ba641f20SAndrew Rybchenko 	sfc_adapter_unlock(sa);
256ba641f20SAndrew Rybchenko 
25763d588ffSAndrew Rybchenko 	sfc_log_init(sa, "done");
25863d588ffSAndrew Rybchenko 	return 0;
25963d588ffSAndrew Rybchenko 
260ba641f20SAndrew Rybchenko fail_attach:
261ba641f20SAndrew Rybchenko 	sfc_adapter_unlock(sa);
262ba641f20SAndrew Rybchenko 	sfc_adapter_lock_fini(sa);
263ba641f20SAndrew Rybchenko 	rte_free(dev->data->mac_addrs);
264ba641f20SAndrew Rybchenko 	dev->data->mac_addrs = NULL;
265ba641f20SAndrew Rybchenko 
266ba641f20SAndrew Rybchenko fail_mac_addrs:
26763d588ffSAndrew Rybchenko fail_kvarg_debug_init:
26863d588ffSAndrew Rybchenko 	sfc_kvargs_cleanup(sa);
26963d588ffSAndrew Rybchenko 
27063d588ffSAndrew Rybchenko fail_kvargs_parse:
27163d588ffSAndrew Rybchenko 	sfc_log_init(sa, "failed %d", rc);
27263d588ffSAndrew Rybchenko 	SFC_ASSERT(rc > 0);
27363d588ffSAndrew Rybchenko 	return -rc;
27463d588ffSAndrew Rybchenko }
27563d588ffSAndrew Rybchenko 
27663d588ffSAndrew Rybchenko static int
27763d588ffSAndrew Rybchenko sfc_eth_dev_uninit(struct rte_eth_dev *dev)
27863d588ffSAndrew Rybchenko {
27963d588ffSAndrew Rybchenko 	struct sfc_adapter *sa = dev->data->dev_private;
28063d588ffSAndrew Rybchenko 
28163d588ffSAndrew Rybchenko 	sfc_log_init(sa, "entry");
28263d588ffSAndrew Rybchenko 
283ba641f20SAndrew Rybchenko 	sfc_adapter_lock(sa);
284ba641f20SAndrew Rybchenko 
285ba641f20SAndrew Rybchenko 	sfc_detach(sa);
286ba641f20SAndrew Rybchenko 
287ba641f20SAndrew Rybchenko 	rte_free(dev->data->mac_addrs);
288ba641f20SAndrew Rybchenko 	dev->data->mac_addrs = NULL;
289ba641f20SAndrew Rybchenko 
29063d588ffSAndrew Rybchenko 	dev->dev_ops = NULL;
29163d588ffSAndrew Rybchenko 
29263d588ffSAndrew Rybchenko 	sfc_kvargs_cleanup(sa);
29363d588ffSAndrew Rybchenko 
294ba641f20SAndrew Rybchenko 	sfc_adapter_unlock(sa);
295ba641f20SAndrew Rybchenko 	sfc_adapter_lock_fini(sa);
296ba641f20SAndrew Rybchenko 
29763d588ffSAndrew Rybchenko 	sfc_log_init(sa, "done");
29863d588ffSAndrew Rybchenko 
29963d588ffSAndrew Rybchenko 	/* Required for logging, so cleanup last */
30063d588ffSAndrew Rybchenko 	sa->eth_dev = NULL;
30163d588ffSAndrew Rybchenko 	return 0;
30263d588ffSAndrew Rybchenko }
30363d588ffSAndrew Rybchenko 
30463d588ffSAndrew Rybchenko static const struct rte_pci_id pci_id_sfc_efx_map[] = {
305ba641f20SAndrew Rybchenko 	{ RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_FARMINGDALE) },
306ba641f20SAndrew Rybchenko 	{ RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_GREENPORT) },
307ba641f20SAndrew Rybchenko 	{ RTE_PCI_DEVICE(EFX_PCI_VENID_SFC, EFX_PCI_DEVID_MEDFORD) },
30863d588ffSAndrew Rybchenko 	{ .vendor_id = 0 /* sentinel */ }
30963d588ffSAndrew Rybchenko };
31063d588ffSAndrew Rybchenko 
31163d588ffSAndrew Rybchenko static struct eth_driver sfc_efx_pmd = {
31263d588ffSAndrew Rybchenko 	.pci_drv = {
31363d588ffSAndrew Rybchenko 		.id_table = pci_id_sfc_efx_map,
314ba641f20SAndrew Rybchenko 		.drv_flags =
315ba641f20SAndrew Rybchenko 			RTE_PCI_DRV_NEED_MAPPING,
31663d588ffSAndrew Rybchenko 		.probe = rte_eth_dev_pci_probe,
31763d588ffSAndrew Rybchenko 		.remove = rte_eth_dev_pci_remove,
31863d588ffSAndrew Rybchenko 	},
31963d588ffSAndrew Rybchenko 	.eth_dev_init = sfc_eth_dev_init,
32063d588ffSAndrew Rybchenko 	.eth_dev_uninit = sfc_eth_dev_uninit,
32163d588ffSAndrew Rybchenko 	.dev_private_size = sizeof(struct sfc_adapter),
32263d588ffSAndrew Rybchenko };
32363d588ffSAndrew Rybchenko 
32463d588ffSAndrew Rybchenko RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd.pci_drv);
32563d588ffSAndrew Rybchenko RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
32663d588ffSAndrew Rybchenko RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
32763d588ffSAndrew Rybchenko 	SFC_KVARG_DEBUG_INIT "=" SFC_KVARG_VALUES_BOOL);
328