1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
11 #include <ethdev_pci.h>
13 #include "txgbe_logs.h"
14 #include "base/txgbe.h"
15 #include "txgbe_ethdev.h"
16 #include "txgbe_rxtx.h"
18 static int txgbevf_dev_close(struct rte_eth_dev *dev);
19 static void txgbevf_intr_disable(struct rte_eth_dev *dev);
20 static void txgbevf_intr_enable(struct rte_eth_dev *dev);
21 static void txgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
24 * The set of PCI devices this driver supports (for VF)
26 static const struct rte_pci_id pci_id_txgbevf_map[] = {
27 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_RAPTOR_VF) },
28 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_RAPTOR_VF_HV) },
29 { .vendor_id = 0, /* sentinel */ },
32 static const struct eth_dev_ops txgbevf_eth_dev_ops;
35 * Negotiate mailbox API version with the PF.
36 * After reset API version is always set to the basic one (txgbe_mbox_api_10).
37 * Then we try to negotiate starting with the most recent one.
38 * If all negotiation attempts fail, then we will proceed with
39 * the default one (txgbe_mbox_api_10).
42 txgbevf_negotiate_api(struct txgbe_hw *hw)
46 /* start with highest supported, proceed down */
47 static const int sup_ver[] = {
54 for (i = 0; i < ARRAY_SIZE(sup_ver); i++) {
55 if (txgbevf_negotiate_api_version(hw, sup_ver[i]) == 0)
61 generate_random_mac_addr(struct rte_ether_addr *mac_addr)
65 /* Set Organizationally Unique Identifier (OUI) prefix. */
66 mac_addr->addr_bytes[0] = 0x00;
67 mac_addr->addr_bytes[1] = 0x09;
68 mac_addr->addr_bytes[2] = 0xC0;
69 /* Force indication of locally assigned MAC address. */
70 mac_addr->addr_bytes[0] |= RTE_ETHER_LOCAL_ADMIN_ADDR;
71 /* Generate the last 3 bytes of the MAC address with a random number. */
73 memcpy(&mac_addr->addr_bytes[3], &random, 3);
77 * Virtual Function device init
80 eth_txgbevf_dev_init(struct rte_eth_dev *eth_dev)
84 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
85 struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
86 struct rte_ether_addr *perm_addr =
87 (struct rte_ether_addr *)hw->mac.perm_addr;
89 PMD_INIT_FUNC_TRACE();
91 eth_dev->dev_ops = &txgbevf_eth_dev_ops;
93 /* for secondary processes, we don't initialise any further as primary
94 * has already done this work. Only check we don't need a different
97 if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
98 struct txgbe_tx_queue *txq;
99 uint16_t nb_tx_queues = eth_dev->data->nb_tx_queues;
100 /* TX queue function in primary, set by last queue initialized
101 * Tx queue may not initialized by primary process
103 if (eth_dev->data->tx_queues) {
104 txq = eth_dev->data->tx_queues[nb_tx_queues - 1];
105 txgbe_set_tx_function(eth_dev, txq);
107 /* Use default TX function if we get here */
109 "No TX queues configured yet. Using default TX function.");
112 txgbe_set_rx_function(eth_dev);
117 rte_eth_copy_pci_info(eth_dev, pci_dev);
119 hw->device_id = pci_dev->id.device_id;
120 hw->vendor_id = pci_dev->id.vendor_id;
121 hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
122 hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
123 hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
125 /* Initialize the shared code (base driver) */
126 err = txgbe_init_shared_code(hw);
129 "Shared code init failed for txgbevf: %d", err);
133 /* init_mailbox_params */
134 hw->mbx.init_params(hw);
136 /* Disable the interrupts for VF */
137 txgbevf_intr_disable(eth_dev);
139 hw->mac.num_rar_entries = 128; /* The MAX of the underlying PF */
140 err = hw->mac.reset_hw(hw);
143 * The VF reset operation returns the TXGBE_ERR_INVALID_MAC_ADDR when
144 * the underlying PF driver has not assigned a MAC address to the VF.
145 * In this case, assign a random MAC address.
147 if (err != 0 && err != TXGBE_ERR_INVALID_MAC_ADDR) {
148 PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", err);
150 * This error code will be propagated to the app by
151 * rte_eth_dev_reset, so use a public error code rather than
152 * the internal-only TXGBE_ERR_RESET_FAILED
157 /* negotiate mailbox API version to use with the PF. */
158 txgbevf_negotiate_api(hw);
160 /* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */
161 txgbevf_get_queues(hw, &tcs, &tc);
163 /* Allocate memory for storing MAC addresses */
164 eth_dev->data->mac_addrs = rte_zmalloc("txgbevf", RTE_ETHER_ADDR_LEN *
165 hw->mac.num_rar_entries, 0);
166 if (eth_dev->data->mac_addrs == NULL) {
168 "Failed to allocate %u bytes needed to store "
170 RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
174 /* Generate a random MAC address, if none was assigned by PF. */
175 if (rte_is_zero_ether_addr(perm_addr)) {
176 generate_random_mac_addr(perm_addr);
177 err = txgbe_set_rar_vf(hw, 1, perm_addr->addr_bytes, 0, 1);
179 rte_free(eth_dev->data->mac_addrs);
180 eth_dev->data->mac_addrs = NULL;
183 PMD_INIT_LOG(INFO, "\tVF MAC address not assigned by Host PF");
184 PMD_INIT_LOG(INFO, "\tAssign randomly generated MAC address "
185 "%02x:%02x:%02x:%02x:%02x:%02x",
186 perm_addr->addr_bytes[0],
187 perm_addr->addr_bytes[1],
188 perm_addr->addr_bytes[2],
189 perm_addr->addr_bytes[3],
190 perm_addr->addr_bytes[4],
191 perm_addr->addr_bytes[5]);
194 /* Copy the permanent MAC address */
195 rte_ether_addr_copy(perm_addr, ð_dev->data->mac_addrs[0]);
197 /* reset the hardware with the new settings */
198 err = hw->mac.start_hw(hw);
200 PMD_INIT_LOG(ERR, "VF Initialization Failure: %d", err);
204 txgbevf_intr_enable(eth_dev);
206 PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x mac.type=%s",
207 eth_dev->data->port_id, pci_dev->id.vendor_id,
208 pci_dev->id.device_id, "txgbe_mac_raptor_vf");
213 /* Virtual Function device uninit */
215 eth_txgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
217 PMD_INIT_FUNC_TRACE();
219 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
222 txgbevf_dev_close(eth_dev);
227 static int eth_txgbevf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
228 struct rte_pci_device *pci_dev)
230 return rte_eth_dev_pci_generic_probe(pci_dev,
231 sizeof(struct txgbe_adapter), eth_txgbevf_dev_init);
234 static int eth_txgbevf_pci_remove(struct rte_pci_device *pci_dev)
236 return rte_eth_dev_pci_generic_remove(pci_dev, eth_txgbevf_dev_uninit);
240 * virtual function driver struct
242 static struct rte_pci_driver rte_txgbevf_pmd = {
243 .id_table = pci_id_txgbevf_map,
244 .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
245 .probe = eth_txgbevf_pci_probe,
246 .remove = eth_txgbevf_pci_remove,
250 * Virtual Function operations
253 txgbevf_intr_disable(struct rte_eth_dev *dev)
255 struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
256 struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
258 PMD_INIT_FUNC_TRACE();
260 /* Clear interrupt mask to stop from interrupts being generated */
261 wr32(hw, TXGBE_VFIMS, TXGBE_VFIMS_MASK);
265 /* Clear mask value. */
266 intr->mask_misc = TXGBE_VFIMS_MASK;
270 txgbevf_intr_enable(struct rte_eth_dev *dev)
272 struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
273 struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
275 PMD_INIT_FUNC_TRACE();
277 /* VF enable interrupt autoclean */
278 wr32(hw, TXGBE_VFIMC, TXGBE_VFIMC_MASK);
286 txgbevf_dev_close(struct rte_eth_dev *dev)
288 struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
289 PMD_INIT_FUNC_TRACE();
290 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
293 hw->mac.reset_hw(hw);
295 txgbe_dev_free_queues(dev);
298 * Remove the VF MAC address ro ensure
299 * that the VF traffic goes to the PF
300 * after stop, close and detach of the VF
302 txgbevf_remove_mac_addr(dev, 0);
304 /* Disable the interrupts for VF */
305 txgbevf_intr_disable(dev);
307 rte_free(dev->data->mac_addrs);
308 dev->data->mac_addrs = NULL;
314 txgbevf_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
315 __rte_unused uint32_t index,
316 __rte_unused uint32_t pool)
318 struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
322 * On a VF, adding again the same MAC addr is not an idempotent
323 * operation. Trap this case to avoid exhausting the [very limited]
324 * set of PF resources used to store VF MAC addresses.
326 if (memcmp(hw->mac.perm_addr, mac_addr,
327 sizeof(struct rte_ether_addr)) == 0)
329 err = txgbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);
331 PMD_DRV_LOG(ERR, "Unable to add MAC address "
332 "%02x:%02x:%02x:%02x:%02x:%02x - err=%d",
333 mac_addr->addr_bytes[0],
334 mac_addr->addr_bytes[1],
335 mac_addr->addr_bytes[2],
336 mac_addr->addr_bytes[3],
337 mac_addr->addr_bytes[4],
338 mac_addr->addr_bytes[5],
344 txgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
346 struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
347 struct rte_ether_addr *perm_addr =
348 (struct rte_ether_addr *)hw->mac.perm_addr;
349 struct rte_ether_addr *mac_addr;
354 * The TXGBE_VF_SET_MACVLAN command of the txgbe-pf driver does
355 * not support the deletion of a given MAC address.
356 * Instead, it imposes to delete all MAC addresses, then to add again
357 * all MAC addresses with the exception of the one to be deleted.
359 (void)txgbevf_set_uc_addr_vf(hw, 0, NULL);
362 * Add again all MAC addresses, with the exception of the deleted one
363 * and of the permanent MAC address.
365 for (i = 0, mac_addr = dev->data->mac_addrs;
366 i < hw->mac.num_rar_entries; i++, mac_addr++) {
367 /* Skip the deleted MAC address */
370 /* Skip NULL MAC addresses */
371 if (rte_is_zero_ether_addr(mac_addr))
373 /* Skip the permanent MAC address */
374 if (memcmp(perm_addr, mac_addr,
375 sizeof(struct rte_ether_addr)) == 0)
377 err = txgbevf_set_uc_addr_vf(hw, 2, mac_addr->addr_bytes);
380 "Adding again MAC address "
381 "%02x:%02x:%02x:%02x:%02x:%02x failed "
383 mac_addr->addr_bytes[0],
384 mac_addr->addr_bytes[1],
385 mac_addr->addr_bytes[2],
386 mac_addr->addr_bytes[3],
387 mac_addr->addr_bytes[4],
388 mac_addr->addr_bytes[5],
394 txgbevf_set_default_mac_addr(struct rte_eth_dev *dev,
395 struct rte_ether_addr *addr)
397 struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
399 hw->mac.set_rar(hw, 0, (void *)addr, 0, 0);
405 * dev_ops for virtual function, bare necessities for basic vf
406 * operation have been implemented
408 static const struct eth_dev_ops txgbevf_eth_dev_ops = {
409 .mac_addr_add = txgbevf_add_mac_addr,
410 .mac_addr_remove = txgbevf_remove_mac_addr,
411 .mac_addr_set = txgbevf_set_default_mac_addr,
414 RTE_PMD_REGISTER_PCI(net_txgbe_vf, rte_txgbevf_pmd);
415 RTE_PMD_REGISTER_PCI_TABLE(net_txgbe_vf, pci_id_txgbevf_map);
416 RTE_PMD_REGISTER_KMOD_DEP(net_txgbe_vf, "* igb_uio | vfio-pci");