1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3 * Copyright(c) 2010-2017 Intel Corporation
7 #include <rte_common.h>
8 #include <ethdev_pci.h>
10 #include <rte_alarm.h>
12 #include "ngbe_logs.h"
14 #include "ngbe_ethdev.h"
15 #include "ngbe_rxtx.h"
17 static int ngbe_dev_close(struct rte_eth_dev *dev);
19 static void ngbe_dev_interrupt_handler(void *param);
20 static void ngbe_dev_interrupt_delayed_handler(void *param);
23 * The set of PCI devices this driver supports
25 static const struct rte_pci_id pci_id_ngbe_map[] = {
26 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2) },
27 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2S) },
28 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4) },
29 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4S) },
30 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2) },
31 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S) },
32 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4) },
33 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S) },
34 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860NCSI) },
35 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1) },
36 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1L) },
37 { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W) },
38 { .vendor_id = 0, /* sentinel */ },
41 static const struct rte_eth_desc_lim rx_desc_lim = {
42 .nb_max = NGBE_RING_DESC_MAX,
43 .nb_min = NGBE_RING_DESC_MIN,
44 .nb_align = NGBE_RXD_ALIGN,
47 static const struct rte_eth_desc_lim tx_desc_lim = {
48 .nb_max = NGBE_RING_DESC_MAX,
49 .nb_min = NGBE_RING_DESC_MIN,
50 .nb_align = NGBE_TXD_ALIGN,
51 .nb_seg_max = NGBE_TX_MAX_SEG,
52 .nb_mtu_seg_max = NGBE_TX_MAX_SEG,
55 static const struct eth_dev_ops ngbe_eth_dev_ops;
58 ngbe_enable_intr(struct rte_eth_dev *dev)
60 struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
61 struct ngbe_hw *hw = ngbe_dev_hw(dev);
63 wr32(hw, NGBE_IENMISC, intr->mask_misc);
64 wr32(hw, NGBE_IMC(0), intr->mask & BIT_MASK32);
69 ngbe_disable_intr(struct ngbe_hw *hw)
71 PMD_INIT_FUNC_TRACE();
73 wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK);
78 * Ensure that all locks are released before first NVM or PHY access
81 ngbe_swfw_lock_reset(struct ngbe_hw *hw)
86 * These ones are more tricky since they are common to all ports; but
87 * swfw_sync retries last long enough (1s) to be almost sure that if
88 * lock can not be taken it is due to an improper lock of the
91 mask = NGBE_MNGSEM_SWPHY |
94 if (hw->mac.acquire_swfw_sync(hw, mask) < 0)
95 PMD_DRV_LOG(DEBUG, "SWFW common locks released");
97 hw->mac.release_swfw_sync(hw, mask);
101 eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
103 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
104 struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
105 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
106 const struct rte_memzone *mz;
110 PMD_INIT_FUNC_TRACE();
112 eth_dev->dev_ops = &ngbe_eth_dev_ops;
114 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
117 rte_eth_copy_pci_info(eth_dev, pci_dev);
119 /* Vendor and Device ID need to be set before init of shared code */
120 hw->device_id = pci_dev->id.device_id;
121 hw->vendor_id = pci_dev->id.vendor_id;
122 hw->sub_system_id = pci_dev->id.subsystem_device_id;
123 ngbe_map_device_id(hw);
124 hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
126 /* Reserve memory for interrupt status block */
127 mz = rte_eth_dma_zone_reserve(eth_dev, "ngbe_driver", -1,
128 NGBE_ISB_SIZE, NGBE_ALIGN, SOCKET_ID_ANY);
132 hw->isb_dma = TMZ_PADDR(mz);
133 hw->isb_mem = TMZ_VADDR(mz);
135 /* Initialize the shared code (base driver) */
136 err = ngbe_init_shared_code(hw);
138 PMD_INIT_LOG(ERR, "Shared code init failed: %d", err);
142 /* Unlock any pending hardware semaphore */
143 ngbe_swfw_lock_reset(hw);
145 err = hw->rom.init_params(hw);
147 PMD_INIT_LOG(ERR, "The EEPROM init failed: %d", err);
151 /* Make sure we have a good EEPROM before we read from it */
152 err = hw->rom.validate_checksum(hw, NULL);
154 PMD_INIT_LOG(ERR, "The EEPROM checksum is not valid: %d", err);
158 err = hw->mac.init_hw(hw);
160 PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err);
164 /* disable interrupt */
165 ngbe_disable_intr(hw);
167 /* Allocate memory for storing MAC addresses */
168 eth_dev->data->mac_addrs = rte_zmalloc("ngbe", RTE_ETHER_ADDR_LEN *
169 hw->mac.num_rar_entries, 0);
170 if (eth_dev->data->mac_addrs == NULL) {
172 "Failed to allocate %u bytes needed to store MAC addresses",
173 RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
177 /* Copy the permanent MAC address */
178 rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
179 ð_dev->data->mac_addrs[0]);
181 /* Allocate memory for storing hash filter MAC addresses */
182 eth_dev->data->hash_mac_addrs = rte_zmalloc("ngbe",
183 RTE_ETHER_ADDR_LEN * NGBE_VMDQ_NUM_UC_MAC, 0);
184 if (eth_dev->data->hash_mac_addrs == NULL) {
186 "Failed to allocate %d bytes needed to store MAC addresses",
187 RTE_ETHER_ADDR_LEN * NGBE_VMDQ_NUM_UC_MAC);
188 rte_free(eth_dev->data->mac_addrs);
189 eth_dev->data->mac_addrs = NULL;
193 ctrl_ext = rd32(hw, NGBE_PORTCTL);
194 /* let hardware know driver is loaded */
195 ctrl_ext |= NGBE_PORTCTL_DRVLOAD;
196 /* Set PF Reset Done bit so PF/VF Mail Ops can work */
197 ctrl_ext |= NGBE_PORTCTL_RSTDONE;
198 wr32(hw, NGBE_PORTCTL, ctrl_ext);
201 rte_intr_callback_register(intr_handle,
202 ngbe_dev_interrupt_handler, eth_dev);
204 /* enable uio/vfio intr/eventfd mapping */
205 rte_intr_enable(intr_handle);
207 /* enable support intr */
208 ngbe_enable_intr(eth_dev);
214 eth_ngbe_dev_uninit(struct rte_eth_dev *eth_dev)
216 PMD_INIT_FUNC_TRACE();
218 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
221 ngbe_dev_close(eth_dev);
227 eth_ngbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
228 struct rte_pci_device *pci_dev)
230 return rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
231 sizeof(struct ngbe_adapter),
232 eth_dev_pci_specific_init, pci_dev,
233 eth_ngbe_dev_init, NULL);
236 static int eth_ngbe_pci_remove(struct rte_pci_device *pci_dev)
238 struct rte_eth_dev *ethdev;
240 ethdev = rte_eth_dev_allocated(pci_dev->device.name);
244 return rte_eth_dev_destroy(ethdev, eth_ngbe_dev_uninit);
247 static struct rte_pci_driver rte_ngbe_pmd = {
248 .id_table = pci_id_ngbe_map,
249 .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
250 RTE_PCI_DRV_INTR_LSC,
251 .probe = eth_ngbe_pci_probe,
252 .remove = eth_ngbe_pci_remove,
256 ngbe_dev_configure(struct rte_eth_dev *dev)
258 struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
259 struct ngbe_adapter *adapter = ngbe_dev_adapter(dev);
261 PMD_INIT_FUNC_TRACE();
263 /* set flag to update link status after init */
264 intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE;
267 * Initialize to TRUE. If any of Rx queues doesn't meet the bulk
268 * allocation Rx preconditions we will reset it.
270 adapter->rx_bulk_alloc_allowed = true;
276 * Reset and stop device.
279 ngbe_dev_close(struct rte_eth_dev *dev)
281 PMD_INIT_FUNC_TRACE();
289 ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
291 struct ngbe_hw *hw = ngbe_dev_hw(dev);
293 dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
294 dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
296 dev_info->default_rxconf = (struct rte_eth_rxconf) {
298 .pthresh = NGBE_DEFAULT_RX_PTHRESH,
299 .hthresh = NGBE_DEFAULT_RX_HTHRESH,
300 .wthresh = NGBE_DEFAULT_RX_WTHRESH,
302 .rx_free_thresh = NGBE_DEFAULT_RX_FREE_THRESH,
307 dev_info->default_txconf = (struct rte_eth_txconf) {
309 .pthresh = NGBE_DEFAULT_TX_PTHRESH,
310 .hthresh = NGBE_DEFAULT_TX_HTHRESH,
311 .wthresh = NGBE_DEFAULT_TX_WTHRESH,
313 .tx_free_thresh = NGBE_DEFAULT_TX_FREE_THRESH,
317 dev_info->rx_desc_lim = rx_desc_lim;
318 dev_info->tx_desc_lim = tx_desc_lim;
320 dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_100M |
323 /* Driver-preferred Rx/Tx parameters */
324 dev_info->default_rxportconf.nb_queues = 1;
325 dev_info->default_txportconf.nb_queues = 1;
326 dev_info->default_rxportconf.ring_size = 256;
327 dev_info->default_txportconf.ring_size = 256;
332 /* return 0 means link status changed, -1 means not changed */
334 ngbe_dev_link_update_share(struct rte_eth_dev *dev,
335 int wait_to_complete)
337 struct ngbe_hw *hw = ngbe_dev_hw(dev);
338 struct rte_eth_link link;
339 u32 link_speed = NGBE_LINK_SPEED_UNKNOWN;
341 struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
346 memset(&link, 0, sizeof(link));
347 link.link_status = ETH_LINK_DOWN;
348 link.link_speed = ETH_SPEED_NUM_NONE;
349 link.link_duplex = ETH_LINK_HALF_DUPLEX;
350 link.link_autoneg = !(dev->data->dev_conf.link_speeds &
351 ~ETH_LINK_SPEED_AUTONEG);
353 hw->mac.get_link_status = true;
355 if (intr->flags & NGBE_FLAG_NEED_LINK_CONFIG)
356 return rte_eth_linkstatus_set(dev, &link);
358 /* check if it needs to wait to complete, if lsc interrupt is enabled */
359 if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)
362 err = hw->mac.check_link(hw, &link_speed, &link_up, wait);
364 link.link_speed = ETH_SPEED_NUM_NONE;
365 link.link_duplex = ETH_LINK_FULL_DUPLEX;
366 return rte_eth_linkstatus_set(dev, &link);
370 return rte_eth_linkstatus_set(dev, &link);
372 intr->flags &= ~NGBE_FLAG_NEED_LINK_CONFIG;
373 link.link_status = ETH_LINK_UP;
374 link.link_duplex = ETH_LINK_FULL_DUPLEX;
376 switch (link_speed) {
378 case NGBE_LINK_SPEED_UNKNOWN:
379 link.link_speed = ETH_SPEED_NUM_NONE;
382 case NGBE_LINK_SPEED_10M_FULL:
383 link.link_speed = ETH_SPEED_NUM_10M;
387 case NGBE_LINK_SPEED_100M_FULL:
388 link.link_speed = ETH_SPEED_NUM_100M;
392 case NGBE_LINK_SPEED_1GB_FULL:
393 link.link_speed = ETH_SPEED_NUM_1G;
399 wr32m(hw, NGBE_LAN_SPEED, NGBE_LAN_SPEED_MASK, lan_speed);
400 if (link_speed & (NGBE_LINK_SPEED_1GB_FULL |
401 NGBE_LINK_SPEED_100M_FULL |
402 NGBE_LINK_SPEED_10M_FULL)) {
403 wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_SPEED_MASK,
404 NGBE_MACTXCFG_SPEED_1G | NGBE_MACTXCFG_TE);
408 return rte_eth_linkstatus_set(dev, &link);
412 ngbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
414 return ngbe_dev_link_update_share(dev, wait_to_complete);
418 * It reads ICR and sets flag for the link_update.
421 * Pointer to struct rte_eth_dev.
424 * - On success, zero.
425 * - On failure, a negative value.
428 ngbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
431 struct ngbe_hw *hw = ngbe_dev_hw(dev);
432 struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
434 /* clear all cause mask */
435 ngbe_disable_intr(hw);
437 /* read-on-clear nic registers here */
438 eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC];
439 PMD_DRV_LOG(DEBUG, "eicr %x", eicr);
443 /* set flag for async link update */
444 if (eicr & NGBE_ICRMISC_PHY)
445 intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE;
447 if (eicr & NGBE_ICRMISC_VFMBX)
448 intr->flags |= NGBE_FLAG_MAILBOX;
450 if (eicr & NGBE_ICRMISC_LNKSEC)
451 intr->flags |= NGBE_FLAG_MACSEC;
453 if (eicr & NGBE_ICRMISC_GPIO)
454 intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE;
460 * It gets and then prints the link status.
463 * Pointer to struct rte_eth_dev.
466 * - On success, zero.
467 * - On failure, a negative value.
470 ngbe_dev_link_status_print(struct rte_eth_dev *dev)
472 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
473 struct rte_eth_link link;
475 rte_eth_linkstatus_get(dev, &link);
477 if (link.link_status == ETH_LINK_UP) {
478 PMD_INIT_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
479 (int)(dev->data->port_id),
480 (unsigned int)link.link_speed,
481 link.link_duplex == ETH_LINK_FULL_DUPLEX ?
482 "full-duplex" : "half-duplex");
484 PMD_INIT_LOG(INFO, " Port %d: Link Down",
485 (int)(dev->data->port_id));
487 PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
488 pci_dev->addr.domain,
491 pci_dev->addr.function);
495 * It executes link_update after knowing an interrupt occurred.
498 * Pointer to struct rte_eth_dev.
501 * - On success, zero.
502 * - On failure, a negative value.
505 ngbe_dev_interrupt_action(struct rte_eth_dev *dev)
507 struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
510 PMD_DRV_LOG(DEBUG, "intr action type %d", intr->flags);
512 if (intr->flags & NGBE_FLAG_NEED_LINK_UPDATE) {
513 struct rte_eth_link link;
515 /*get the link status before link update, for predicting later*/
516 rte_eth_linkstatus_get(dev, &link);
518 ngbe_dev_link_update(dev, 0);
521 if (link.link_status != ETH_LINK_UP)
522 /* handle it 1 sec later, wait it being stable */
523 timeout = NGBE_LINK_UP_CHECK_TIMEOUT;
526 /* handle it 4 sec later, wait it being stable */
527 timeout = NGBE_LINK_DOWN_CHECK_TIMEOUT;
529 ngbe_dev_link_status_print(dev);
530 if (rte_eal_alarm_set(timeout * 1000,
531 ngbe_dev_interrupt_delayed_handler,
533 PMD_DRV_LOG(ERR, "Error setting alarm");
535 /* remember original mask */
536 intr->mask_misc_orig = intr->mask_misc;
537 /* only disable lsc interrupt */
538 intr->mask_misc &= ~NGBE_ICRMISC_PHY;
540 intr->mask_orig = intr->mask;
541 /* only disable all misc interrupts */
542 intr->mask &= ~(1ULL << NGBE_MISC_VEC_ID);
546 PMD_DRV_LOG(DEBUG, "enable intr immediately");
547 ngbe_enable_intr(dev);
553 * Interrupt handler which shall be registered for alarm callback for delayed
554 * handling specific interrupt to wait for the stable nic state. As the
555 * NIC interrupt state is not stable for ngbe after link is just down,
556 * it needs to wait 4 seconds to get the stable status.
559 * The address of parameter (struct rte_eth_dev *) registered before.
562 ngbe_dev_interrupt_delayed_handler(void *param)
564 struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
565 struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
566 struct ngbe_hw *hw = ngbe_dev_hw(dev);
569 ngbe_disable_intr(hw);
571 eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC];
573 if (intr->flags & NGBE_FLAG_NEED_LINK_UPDATE) {
574 ngbe_dev_link_update(dev, 0);
575 intr->flags &= ~NGBE_FLAG_NEED_LINK_UPDATE;
576 ngbe_dev_link_status_print(dev);
577 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
581 if (intr->flags & NGBE_FLAG_MACSEC) {
582 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_MACSEC,
584 intr->flags &= ~NGBE_FLAG_MACSEC;
587 /* restore original mask */
588 intr->mask_misc = intr->mask_misc_orig;
589 intr->mask_misc_orig = 0;
590 intr->mask = intr->mask_orig;
593 PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
594 ngbe_enable_intr(dev);
598 * Interrupt handler triggered by NIC for handling
599 * specific interrupt.
602 * The address of parameter (struct rte_eth_dev *) registered before.
605 ngbe_dev_interrupt_handler(void *param)
607 struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
609 ngbe_dev_interrupt_get_status(dev);
610 ngbe_dev_interrupt_action(dev);
613 static const struct eth_dev_ops ngbe_eth_dev_ops = {
614 .dev_configure = ngbe_dev_configure,
615 .dev_infos_get = ngbe_dev_info_get,
616 .link_update = ngbe_dev_link_update,
617 .rx_queue_setup = ngbe_dev_rx_queue_setup,
618 .rx_queue_release = ngbe_dev_rx_queue_release,
619 .tx_queue_setup = ngbe_dev_tx_queue_setup,
620 .tx_queue_release = ngbe_dev_tx_queue_release,
623 RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd);
624 RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map);
625 RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci");
627 RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_init, init, NOTICE);
628 RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_driver, driver, NOTICE);
630 #ifdef RTE_ETHDEV_DEBUG_RX
631 RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_rx, rx, DEBUG);
633 #ifdef RTE_ETHDEV_DEBUG_TX
634 RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_tx, tx, DEBUG);