xref: /dpdk/drivers/net/ngbe/ngbe_ethdev_vf.c (revision 7744e90805b525162441f02c3bccfc1f73b1b07c)
1950820f1SZaiyu Wang /* SPDX-License-Identifier: BSD-3-Clause
2950820f1SZaiyu Wang  * Copyright(c) 2018-2025 Beijing WangXun Technology Co., Ltd.
3950820f1SZaiyu Wang  * Copyright(c) 2010-2017 Intel Corporation
4950820f1SZaiyu Wang  */
5950820f1SZaiyu Wang 
6950820f1SZaiyu Wang #include <sys/queue.h>
7950820f1SZaiyu Wang #include <stdio.h>
8950820f1SZaiyu Wang #include <errno.h>
9950820f1SZaiyu Wang #include <stdint.h>
10950820f1SZaiyu Wang #include <string.h>
11950820f1SZaiyu Wang #include <ethdev_pci.h>
12950820f1SZaiyu Wang 
13950820f1SZaiyu Wang #include "ngbe_logs.h"
14950820f1SZaiyu Wang #include "base/ngbe.h"
15950820f1SZaiyu Wang #include "ngbe_ethdev.h"
16950820f1SZaiyu Wang #include "ngbe_rxtx.h"
17950820f1SZaiyu Wang #include "ngbe_regs_group.h"
18950820f1SZaiyu Wang 
19950820f1SZaiyu Wang #define NGBEVF_PMD_NAME "rte_ngbevf_pmd" /* PMD name */
20950820f1SZaiyu Wang static int ngbevf_dev_close(struct rte_eth_dev *dev);
21*7744e908SZaiyu Wang static int ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev);
22*7744e908SZaiyu Wang static int ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev);
23950820f1SZaiyu Wang 
24950820f1SZaiyu Wang /*
25950820f1SZaiyu Wang  * The set of PCI devices this driver supports (for VF)
26950820f1SZaiyu Wang  */
27950820f1SZaiyu Wang static const struct rte_pci_id pci_id_ngbevf_map[] = {
28950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W_VF) },
29950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2_VF) },
30950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2S_VF) },
31950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4_VF) },
32950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4S_VF) },
33950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2_VF) },
34950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S_VF) },
35950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4_VF) },
36950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S_VF) },
37950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860NCSI_VF) },
38950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1_VF) },
39950820f1SZaiyu Wang 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1L_VF) },
40950820f1SZaiyu Wang 	{ .vendor_id = 0, /* sentinel */ },
41950820f1SZaiyu Wang };
42950820f1SZaiyu Wang 
4366070ca4SZaiyu Wang static const struct rte_eth_desc_lim rx_desc_lim = {
4466070ca4SZaiyu Wang 	.nb_max = NGBE_RING_DESC_MAX,
4566070ca4SZaiyu Wang 	.nb_min = NGBE_RING_DESC_MIN,
4666070ca4SZaiyu Wang 	.nb_align = NGBE_RXD_ALIGN,
4766070ca4SZaiyu Wang };
4866070ca4SZaiyu Wang 
4966070ca4SZaiyu Wang static const struct rte_eth_desc_lim tx_desc_lim = {
5066070ca4SZaiyu Wang 	.nb_max = NGBE_RING_DESC_MAX,
5166070ca4SZaiyu Wang 	.nb_min = NGBE_RING_DESC_MIN,
5266070ca4SZaiyu Wang 	.nb_align = NGBE_TXD_ALIGN,
5366070ca4SZaiyu Wang 	.nb_seg_max = NGBE_TX_MAX_SEG,
5466070ca4SZaiyu Wang 	.nb_mtu_seg_max = NGBE_TX_MAX_SEG,
5566070ca4SZaiyu Wang };
5666070ca4SZaiyu Wang 
57950820f1SZaiyu Wang static const struct eth_dev_ops ngbevf_eth_dev_ops;
58950820f1SZaiyu Wang 
59950820f1SZaiyu Wang /*
6066070ca4SZaiyu Wang  * Negotiate mailbox API version with the PF.
6166070ca4SZaiyu Wang  * After reset API version is always set to the basic one (ngbe_mbox_api_10).
6266070ca4SZaiyu Wang  * Then we try to negotiate starting with the most recent one.
6366070ca4SZaiyu Wang  * If all negotiation attempts fail, then we will proceed with
6466070ca4SZaiyu Wang  * the default one (ngbe_mbox_api_10).
6566070ca4SZaiyu Wang  */
6666070ca4SZaiyu Wang static void
6766070ca4SZaiyu Wang ngbevf_negotiate_api(struct ngbe_hw *hw)
6866070ca4SZaiyu Wang {
6966070ca4SZaiyu Wang 	int32_t i;
7066070ca4SZaiyu Wang 
7166070ca4SZaiyu Wang 	/* start with highest supported, proceed down */
7266070ca4SZaiyu Wang 	static const int sup_ver[] = {
7366070ca4SZaiyu Wang 		ngbe_mbox_api_13,
7466070ca4SZaiyu Wang 		ngbe_mbox_api_12,
7566070ca4SZaiyu Wang 		ngbe_mbox_api_11,
7666070ca4SZaiyu Wang 		ngbe_mbox_api_10,
7766070ca4SZaiyu Wang 	};
7866070ca4SZaiyu Wang 
7966070ca4SZaiyu Wang 	for (i = 0; i < ARRAY_SIZE(sup_ver); i++) {
8066070ca4SZaiyu Wang 		if (ngbevf_negotiate_api_version(hw, sup_ver[i]) == 0)
8166070ca4SZaiyu Wang 			break;
8266070ca4SZaiyu Wang 	}
8366070ca4SZaiyu Wang }
8466070ca4SZaiyu Wang 
8566070ca4SZaiyu Wang /*
86950820f1SZaiyu Wang  * Virtual Function device init
87950820f1SZaiyu Wang  */
88950820f1SZaiyu Wang static int
89950820f1SZaiyu Wang eth_ngbevf_dev_init(struct rte_eth_dev *eth_dev)
90950820f1SZaiyu Wang {
91950820f1SZaiyu Wang 	int err;
9266070ca4SZaiyu Wang 	uint32_t tc, tcs;
93950820f1SZaiyu Wang 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
94950820f1SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
95950820f1SZaiyu Wang 
96950820f1SZaiyu Wang 	PMD_INIT_FUNC_TRACE();
97950820f1SZaiyu Wang 
98950820f1SZaiyu Wang 	eth_dev->dev_ops = &ngbevf_eth_dev_ops;
99950820f1SZaiyu Wang 
100950820f1SZaiyu Wang 	rte_eth_copy_pci_info(eth_dev, pci_dev);
101950820f1SZaiyu Wang 
102950820f1SZaiyu Wang 	hw->device_id = pci_dev->id.device_id;
103950820f1SZaiyu Wang 	hw->vendor_id = pci_dev->id.vendor_id;
104950820f1SZaiyu Wang 	hw->sub_system_id = pci_dev->id.subsystem_device_id;
105950820f1SZaiyu Wang 	ngbe_map_device_id(hw);
106950820f1SZaiyu Wang 	hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
107950820f1SZaiyu Wang 
108950820f1SZaiyu Wang 	/* Initialize the shared code (base driver) */
109950820f1SZaiyu Wang 	err = ngbe_init_shared_code(hw);
110950820f1SZaiyu Wang 	if (err != 0) {
111950820f1SZaiyu Wang 		PMD_INIT_LOG(ERR,
112950820f1SZaiyu Wang 			"Shared code init failed for ngbevf: %d", err);
113950820f1SZaiyu Wang 		return -EIO;
114950820f1SZaiyu Wang 	}
115950820f1SZaiyu Wang 
11666070ca4SZaiyu Wang 	/* init_mailbox_params */
11766070ca4SZaiyu Wang 	hw->mbx.init_params(hw);
11866070ca4SZaiyu Wang 
119950820f1SZaiyu Wang 	hw->mac.num_rar_entries = 32; /* The MAX of the underlying PF */
12066070ca4SZaiyu Wang 	err = hw->mac.reset_hw(hw);
12166070ca4SZaiyu Wang 
12266070ca4SZaiyu Wang 	/*
12366070ca4SZaiyu Wang 	 * The VF reset operation returns the NGBE_ERR_INVALID_MAC_ADDR when
12466070ca4SZaiyu Wang 	 * the underlying PF driver has not assigned a MAC address to the VF.
12566070ca4SZaiyu Wang 	 * In this case, assign a random MAC address.
12666070ca4SZaiyu Wang 	 */
12766070ca4SZaiyu Wang 	if (err != 0 && err != NGBE_ERR_INVALID_MAC_ADDR) {
12866070ca4SZaiyu Wang 		PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", err);
12966070ca4SZaiyu Wang 		/*
13066070ca4SZaiyu Wang 		 * This error code will be propagated to the app by
13166070ca4SZaiyu Wang 		 * rte_eth_dev_reset, so use a public error code rather than
13266070ca4SZaiyu Wang 		 * the internal-only NGBE_ERR_RESET_FAILED
13366070ca4SZaiyu Wang 		 */
13466070ca4SZaiyu Wang 		return -EAGAIN;
13566070ca4SZaiyu Wang 	}
13666070ca4SZaiyu Wang 
13766070ca4SZaiyu Wang 	/* negotiate mailbox API version to use with the PF. */
13866070ca4SZaiyu Wang 	ngbevf_negotiate_api(hw);
13966070ca4SZaiyu Wang 
14066070ca4SZaiyu Wang 	/* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */
14166070ca4SZaiyu Wang 	ngbevf_get_queues(hw, &tcs, &tc);
142950820f1SZaiyu Wang 
143950820f1SZaiyu Wang 	/* Allocate memory for storing MAC addresses */
144950820f1SZaiyu Wang 	eth_dev->data->mac_addrs = rte_zmalloc("ngbevf", RTE_ETHER_ADDR_LEN *
145950820f1SZaiyu Wang 					       hw->mac.num_rar_entries, 0);
146950820f1SZaiyu Wang 	if (eth_dev->data->mac_addrs == NULL) {
147950820f1SZaiyu Wang 		PMD_INIT_LOG(ERR,
148950820f1SZaiyu Wang 			     "Failed to allocate %u bytes needed to store MAC addresses",
149950820f1SZaiyu Wang 			     RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
150950820f1SZaiyu Wang 		return -ENOMEM;
151950820f1SZaiyu Wang 	}
152950820f1SZaiyu Wang 
15366070ca4SZaiyu Wang 	/* reset the hardware with the new settings */
15466070ca4SZaiyu Wang 	err = hw->mac.start_hw(hw);
15566070ca4SZaiyu Wang 	if (err) {
15666070ca4SZaiyu Wang 		PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", err);
15766070ca4SZaiyu Wang 		return -EIO;
15866070ca4SZaiyu Wang 	}
15966070ca4SZaiyu Wang 
160*7744e908SZaiyu Wang 	/* enter promiscuous mode */
161*7744e908SZaiyu Wang 	ngbevf_dev_promiscuous_enable(eth_dev);
162*7744e908SZaiyu Wang 
163950820f1SZaiyu Wang 	PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s",
164950820f1SZaiyu Wang 		     eth_dev->data->port_id, pci_dev->id.vendor_id,
165950820f1SZaiyu Wang 		     pci_dev->id.device_id, "ngbe_mac_sp_vf");
166950820f1SZaiyu Wang 
167950820f1SZaiyu Wang 	return 0;
168950820f1SZaiyu Wang }
169950820f1SZaiyu Wang 
170950820f1SZaiyu Wang /* Virtual Function device uninit */
171950820f1SZaiyu Wang static int
172950820f1SZaiyu Wang eth_ngbevf_dev_uninit(struct rte_eth_dev *eth_dev)
173950820f1SZaiyu Wang {
174950820f1SZaiyu Wang 	PMD_INIT_FUNC_TRACE();
175950820f1SZaiyu Wang 
176950820f1SZaiyu Wang 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
177950820f1SZaiyu Wang 		return 0;
178950820f1SZaiyu Wang 
179950820f1SZaiyu Wang 	ngbevf_dev_close(eth_dev);
180950820f1SZaiyu Wang 
181950820f1SZaiyu Wang 	return 0;
182950820f1SZaiyu Wang }
183950820f1SZaiyu Wang 
184950820f1SZaiyu Wang static int eth_ngbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
185950820f1SZaiyu Wang 	struct rte_pci_device *pci_dev)
186950820f1SZaiyu Wang {
187950820f1SZaiyu Wang 	return rte_eth_dev_pci_generic_probe(pci_dev,
188950820f1SZaiyu Wang 		sizeof(struct ngbe_adapter), eth_ngbevf_dev_init);
189950820f1SZaiyu Wang }
190950820f1SZaiyu Wang 
191950820f1SZaiyu Wang static int eth_ngbevf_pci_remove(struct rte_pci_device *pci_dev)
192950820f1SZaiyu Wang {
193950820f1SZaiyu Wang 	return rte_eth_dev_pci_generic_remove(pci_dev, eth_ngbevf_dev_uninit);
194950820f1SZaiyu Wang }
195950820f1SZaiyu Wang 
196950820f1SZaiyu Wang /*
197950820f1SZaiyu Wang  * virtual function driver struct
198950820f1SZaiyu Wang  */
199950820f1SZaiyu Wang static struct rte_pci_driver rte_ngbevf_pmd = {
200950820f1SZaiyu Wang 	.id_table = pci_id_ngbevf_map,
201950820f1SZaiyu Wang 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
202950820f1SZaiyu Wang 	.probe = eth_ngbevf_pci_probe,
203950820f1SZaiyu Wang 	.remove = eth_ngbevf_pci_remove,
204950820f1SZaiyu Wang };
205950820f1SZaiyu Wang 
206950820f1SZaiyu Wang static int
207950820f1SZaiyu Wang ngbevf_dev_info_get(struct rte_eth_dev *dev,
208950820f1SZaiyu Wang 		     struct rte_eth_dev_info *dev_info)
209950820f1SZaiyu Wang {
21066070ca4SZaiyu Wang 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
211950820f1SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
212950820f1SZaiyu Wang 
213950820f1SZaiyu Wang 	dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
214950820f1SZaiyu Wang 	dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
21566070ca4SZaiyu Wang 	dev_info->min_rx_bufsize = 1024;
21666070ca4SZaiyu Wang 	dev_info->max_rx_pktlen = NGBE_FRAME_SIZE_MAX;
21766070ca4SZaiyu Wang 	dev_info->max_mac_addrs = hw->mac.num_rar_entries;
21866070ca4SZaiyu Wang 	dev_info->max_hash_mac_addrs = NGBE_VMDQ_NUM_UC_MAC;
21966070ca4SZaiyu Wang 	dev_info->max_vfs = pci_dev->max_vfs;
22066070ca4SZaiyu Wang 	dev_info->max_vmdq_pools = RTE_ETH_64_POOLS;
22166070ca4SZaiyu Wang 	dev_info->rx_queue_offload_capa = ngbe_get_rx_queue_offloads(dev);
22266070ca4SZaiyu Wang 	dev_info->rx_offload_capa = (ngbe_get_rx_port_offloads(dev) |
22366070ca4SZaiyu Wang 				     dev_info->rx_queue_offload_capa);
22466070ca4SZaiyu Wang 	dev_info->tx_queue_offload_capa = 0;
22566070ca4SZaiyu Wang 	dev_info->tx_offload_capa = ngbe_get_tx_port_offloads(dev);
22666070ca4SZaiyu Wang 	dev_info->hash_key_size = NGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
22766070ca4SZaiyu Wang 	dev_info->reta_size = RTE_ETH_RSS_RETA_SIZE_128;
22866070ca4SZaiyu Wang 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
22966070ca4SZaiyu Wang 		.rx_thresh = {
23066070ca4SZaiyu Wang 			.pthresh = NGBE_DEFAULT_RX_PTHRESH,
23166070ca4SZaiyu Wang 			.hthresh = NGBE_DEFAULT_RX_HTHRESH,
23266070ca4SZaiyu Wang 			.wthresh = NGBE_DEFAULT_RX_WTHRESH,
23366070ca4SZaiyu Wang 		},
23466070ca4SZaiyu Wang 		.rx_free_thresh = NGBE_DEFAULT_RX_FREE_THRESH,
23566070ca4SZaiyu Wang 		.rx_drop_en = 0,
23666070ca4SZaiyu Wang 		.offloads = 0,
23766070ca4SZaiyu Wang 	};
23866070ca4SZaiyu Wang 
23966070ca4SZaiyu Wang 	dev_info->default_txconf = (struct rte_eth_txconf) {
24066070ca4SZaiyu Wang 		.tx_thresh = {
24166070ca4SZaiyu Wang 			.pthresh = NGBE_DEFAULT_TX_PTHRESH,
24266070ca4SZaiyu Wang 			.hthresh = NGBE_DEFAULT_TX_HTHRESH,
24366070ca4SZaiyu Wang 			.wthresh = NGBE_DEFAULT_TX_WTHRESH,
24466070ca4SZaiyu Wang 		},
24566070ca4SZaiyu Wang 		.tx_free_thresh = NGBE_DEFAULT_TX_FREE_THRESH,
24666070ca4SZaiyu Wang 		.offloads = 0,
24766070ca4SZaiyu Wang 	};
24866070ca4SZaiyu Wang 
24966070ca4SZaiyu Wang 	dev_info->rx_desc_lim = rx_desc_lim;
25066070ca4SZaiyu Wang 	dev_info->tx_desc_lim = tx_desc_lim;
251950820f1SZaiyu Wang 
252950820f1SZaiyu Wang 	return 0;
253950820f1SZaiyu Wang }
254950820f1SZaiyu Wang 
255950820f1SZaiyu Wang static int
256950820f1SZaiyu Wang ngbevf_dev_close(struct rte_eth_dev *dev)
257950820f1SZaiyu Wang {
25866070ca4SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
25966070ca4SZaiyu Wang 
260950820f1SZaiyu Wang 	PMD_INIT_FUNC_TRACE();
261950820f1SZaiyu Wang 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
262950820f1SZaiyu Wang 		return 0;
263950820f1SZaiyu Wang 
26466070ca4SZaiyu Wang 	hw->mac.reset_hw(hw);
26566070ca4SZaiyu Wang 
266950820f1SZaiyu Wang 	rte_free(dev->data->mac_addrs);
267950820f1SZaiyu Wang 	dev->data->mac_addrs = NULL;
268950820f1SZaiyu Wang 
269950820f1SZaiyu Wang 	return 0;
270950820f1SZaiyu Wang }
271950820f1SZaiyu Wang 
272*7744e908SZaiyu Wang static int
273*7744e908SZaiyu Wang ngbevf_dev_promiscuous_enable(struct rte_eth_dev *dev)
274*7744e908SZaiyu Wang {
275*7744e908SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
276*7744e908SZaiyu Wang 	int ret;
277*7744e908SZaiyu Wang 
278*7744e908SZaiyu Wang 	switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_PROMISC)) {
279*7744e908SZaiyu Wang 	case 0:
280*7744e908SZaiyu Wang 		ret = 0;
281*7744e908SZaiyu Wang 		break;
282*7744e908SZaiyu Wang 	case NGBE_ERR_FEATURE_NOT_SUPPORTED:
283*7744e908SZaiyu Wang 		ret = -ENOTSUP;
284*7744e908SZaiyu Wang 		break;
285*7744e908SZaiyu Wang 	default:
286*7744e908SZaiyu Wang 		ret = -EAGAIN;
287*7744e908SZaiyu Wang 		break;
288*7744e908SZaiyu Wang 	}
289*7744e908SZaiyu Wang 
290*7744e908SZaiyu Wang 	return ret;
291*7744e908SZaiyu Wang }
292*7744e908SZaiyu Wang 
293*7744e908SZaiyu Wang static int
294*7744e908SZaiyu Wang ngbevf_dev_promiscuous_disable(struct rte_eth_dev *dev)
295*7744e908SZaiyu Wang {
296*7744e908SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
297*7744e908SZaiyu Wang 	int ret;
298*7744e908SZaiyu Wang 
299*7744e908SZaiyu Wang 	switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_NONE)) {
300*7744e908SZaiyu Wang 	case 0:
301*7744e908SZaiyu Wang 		ret = 0;
302*7744e908SZaiyu Wang 		break;
303*7744e908SZaiyu Wang 	case NGBE_ERR_FEATURE_NOT_SUPPORTED:
304*7744e908SZaiyu Wang 		ret = -ENOTSUP;
305*7744e908SZaiyu Wang 		break;
306*7744e908SZaiyu Wang 	default:
307*7744e908SZaiyu Wang 		ret = -EAGAIN;
308*7744e908SZaiyu Wang 		break;
309*7744e908SZaiyu Wang 	}
310*7744e908SZaiyu Wang 
311*7744e908SZaiyu Wang 	return ret;
312*7744e908SZaiyu Wang }
313*7744e908SZaiyu Wang 
314*7744e908SZaiyu Wang static int
315*7744e908SZaiyu Wang ngbevf_dev_allmulticast_enable(struct rte_eth_dev *dev)
316*7744e908SZaiyu Wang {
317*7744e908SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
318*7744e908SZaiyu Wang 	int ret;
319*7744e908SZaiyu Wang 
320*7744e908SZaiyu Wang 	if (dev->data->promiscuous == 1)
321*7744e908SZaiyu Wang 		return 0;
322*7744e908SZaiyu Wang 
323*7744e908SZaiyu Wang 	switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_ALLMULTI)) {
324*7744e908SZaiyu Wang 	case 0:
325*7744e908SZaiyu Wang 		ret = 0;
326*7744e908SZaiyu Wang 		break;
327*7744e908SZaiyu Wang 	case NGBE_ERR_FEATURE_NOT_SUPPORTED:
328*7744e908SZaiyu Wang 		ret = -ENOTSUP;
329*7744e908SZaiyu Wang 		break;
330*7744e908SZaiyu Wang 	default:
331*7744e908SZaiyu Wang 		ret = -EAGAIN;
332*7744e908SZaiyu Wang 		break;
333*7744e908SZaiyu Wang 	}
334*7744e908SZaiyu Wang 
335*7744e908SZaiyu Wang 	return ret;
336*7744e908SZaiyu Wang }
337*7744e908SZaiyu Wang 
338*7744e908SZaiyu Wang static int
339*7744e908SZaiyu Wang ngbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
340*7744e908SZaiyu Wang {
341*7744e908SZaiyu Wang 	struct ngbe_hw *hw = ngbe_dev_hw(dev);
342*7744e908SZaiyu Wang 	int ret;
343*7744e908SZaiyu Wang 
344*7744e908SZaiyu Wang 	switch (hw->mac.update_xcast_mode(hw, NGBEVF_XCAST_MODE_MULTI)) {
345*7744e908SZaiyu Wang 	case 0:
346*7744e908SZaiyu Wang 		ret = 0;
347*7744e908SZaiyu Wang 		break;
348*7744e908SZaiyu Wang 	case NGBE_ERR_FEATURE_NOT_SUPPORTED:
349*7744e908SZaiyu Wang 		ret = -ENOTSUP;
350*7744e908SZaiyu Wang 		break;
351*7744e908SZaiyu Wang 	default:
352*7744e908SZaiyu Wang 		ret = -EAGAIN;
353*7744e908SZaiyu Wang 		break;
354*7744e908SZaiyu Wang 	}
355*7744e908SZaiyu Wang 
356*7744e908SZaiyu Wang 	return ret;
357*7744e908SZaiyu Wang }
358*7744e908SZaiyu Wang 
359950820f1SZaiyu Wang /*
360950820f1SZaiyu Wang  * dev_ops for virtual function, bare necessities for basic vf
361950820f1SZaiyu Wang  * operation have been implemented
362950820f1SZaiyu Wang  */
363950820f1SZaiyu Wang static const struct eth_dev_ops ngbevf_eth_dev_ops = {
364*7744e908SZaiyu Wang 	.promiscuous_enable   = ngbevf_dev_promiscuous_enable,
365*7744e908SZaiyu Wang 	.promiscuous_disable  = ngbevf_dev_promiscuous_disable,
366*7744e908SZaiyu Wang 	.allmulticast_enable  = ngbevf_dev_allmulticast_enable,
367*7744e908SZaiyu Wang 	.allmulticast_disable = ngbevf_dev_allmulticast_disable,
368950820f1SZaiyu Wang 	.dev_infos_get        = ngbevf_dev_info_get,
369950820f1SZaiyu Wang };
370950820f1SZaiyu Wang 
371950820f1SZaiyu Wang RTE_PMD_REGISTER_PCI(net_ngbe_vf, rte_ngbevf_pmd);
372950820f1SZaiyu Wang RTE_PMD_REGISTER_PCI_TABLE(net_ngbe_vf, pci_id_ngbevf_map);
373950820f1SZaiyu Wang RTE_PMD_REGISTER_KMOD_DEP(net_ngbe_vf, "* igb_uio | vfio-pci");
374