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