decdbd4fd81ac29921f66d0a557e1865d59e1be1
[dpdk.git] / drivers / net / ngbe / ngbe_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3  * Copyright(c) 2010-2017 Intel Corporation
4  */
5
6 #include <errno.h>
7 #include <rte_common.h>
8 #include <ethdev_pci.h>
9
10 #include <rte_alarm.h>
11
12 #include "ngbe_logs.h"
13 #include "ngbe.h"
14 #include "ngbe_ethdev.h"
15
16 static int ngbe_dev_close(struct rte_eth_dev *dev);
17
18 static void ngbe_dev_interrupt_handler(void *param);
19 static void ngbe_dev_interrupt_delayed_handler(void *param);
20
21 /*
22  * The set of PCI devices this driver supports
23  */
24 static const struct rte_pci_id pci_id_ngbe_map[] = {
25         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2) },
26         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A2S) },
27         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4) },
28         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A4S) },
29         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2) },
30         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL2S) },
31         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4) },
32         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL4S) },
33         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860NCSI) },
34         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1) },
35         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860A1L) },
36         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, NGBE_DEV_ID_EM_WX1860AL_W) },
37         { .vendor_id = 0, /* sentinel */ },
38 };
39
40 static const struct eth_dev_ops ngbe_eth_dev_ops;
41
42 static inline void
43 ngbe_enable_intr(struct rte_eth_dev *dev)
44 {
45         struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
46         struct ngbe_hw *hw = ngbe_dev_hw(dev);
47
48         wr32(hw, NGBE_IENMISC, intr->mask_misc);
49         wr32(hw, NGBE_IMC(0), intr->mask & BIT_MASK32);
50         ngbe_flush(hw);
51 }
52
53 static void
54 ngbe_disable_intr(struct ngbe_hw *hw)
55 {
56         PMD_INIT_FUNC_TRACE();
57
58         wr32(hw, NGBE_IMS(0), NGBE_IMS_MASK);
59         ngbe_flush(hw);
60 }
61
62 /*
63  * Ensure that all locks are released before first NVM or PHY access
64  */
65 static void
66 ngbe_swfw_lock_reset(struct ngbe_hw *hw)
67 {
68         uint16_t mask;
69
70         /*
71          * These ones are more tricky since they are common to all ports; but
72          * swfw_sync retries last long enough (1s) to be almost sure that if
73          * lock can not be taken it is due to an improper lock of the
74          * semaphore.
75          */
76         mask = NGBE_MNGSEM_SWPHY |
77                NGBE_MNGSEM_SWMBX |
78                NGBE_MNGSEM_SWFLASH;
79         if (hw->mac.acquire_swfw_sync(hw, mask) < 0)
80                 PMD_DRV_LOG(DEBUG, "SWFW common locks released");
81
82         hw->mac.release_swfw_sync(hw, mask);
83 }
84
85 static int
86 eth_ngbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
87 {
88         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
89         struct ngbe_hw *hw = ngbe_dev_hw(eth_dev);
90         struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
91         const struct rte_memzone *mz;
92         uint32_t ctrl_ext;
93         int err;
94
95         PMD_INIT_FUNC_TRACE();
96
97         eth_dev->dev_ops = &ngbe_eth_dev_ops;
98
99         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
100                 return 0;
101
102         rte_eth_copy_pci_info(eth_dev, pci_dev);
103
104         /* Vendor and Device ID need to be set before init of shared code */
105         hw->device_id = pci_dev->id.device_id;
106         hw->vendor_id = pci_dev->id.vendor_id;
107         hw->sub_system_id = pci_dev->id.subsystem_device_id;
108         ngbe_map_device_id(hw);
109         hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
110
111         /* Reserve memory for interrupt status block */
112         mz = rte_eth_dma_zone_reserve(eth_dev, "ngbe_driver", -1,
113                 NGBE_ISB_SIZE, NGBE_ALIGN, SOCKET_ID_ANY);
114         if (mz == NULL)
115                 return -ENOMEM;
116
117         hw->isb_dma = TMZ_PADDR(mz);
118         hw->isb_mem = TMZ_VADDR(mz);
119
120         /* Initialize the shared code (base driver) */
121         err = ngbe_init_shared_code(hw);
122         if (err != 0) {
123                 PMD_INIT_LOG(ERR, "Shared code init failed: %d", err);
124                 return -EIO;
125         }
126
127         /* Unlock any pending hardware semaphore */
128         ngbe_swfw_lock_reset(hw);
129
130         err = hw->rom.init_params(hw);
131         if (err != 0) {
132                 PMD_INIT_LOG(ERR, "The EEPROM init failed: %d", err);
133                 return -EIO;
134         }
135
136         /* Make sure we have a good EEPROM before we read from it */
137         err = hw->rom.validate_checksum(hw, NULL);
138         if (err != 0) {
139                 PMD_INIT_LOG(ERR, "The EEPROM checksum is not valid: %d", err);
140                 return -EIO;
141         }
142
143         err = hw->mac.init_hw(hw);
144         if (err != 0) {
145                 PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err);
146                 return -EIO;
147         }
148
149         /* disable interrupt */
150         ngbe_disable_intr(hw);
151
152         /* Allocate memory for storing MAC addresses */
153         eth_dev->data->mac_addrs = rte_zmalloc("ngbe", RTE_ETHER_ADDR_LEN *
154                                                hw->mac.num_rar_entries, 0);
155         if (eth_dev->data->mac_addrs == NULL) {
156                 PMD_INIT_LOG(ERR,
157                              "Failed to allocate %u bytes needed to store MAC addresses",
158                              RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
159                 return -ENOMEM;
160         }
161
162         /* Copy the permanent MAC address */
163         rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
164                         &eth_dev->data->mac_addrs[0]);
165
166         /* Allocate memory for storing hash filter MAC addresses */
167         eth_dev->data->hash_mac_addrs = rte_zmalloc("ngbe",
168                         RTE_ETHER_ADDR_LEN * NGBE_VMDQ_NUM_UC_MAC, 0);
169         if (eth_dev->data->hash_mac_addrs == NULL) {
170                 PMD_INIT_LOG(ERR,
171                              "Failed to allocate %d bytes needed to store MAC addresses",
172                              RTE_ETHER_ADDR_LEN * NGBE_VMDQ_NUM_UC_MAC);
173                 rte_free(eth_dev->data->mac_addrs);
174                 eth_dev->data->mac_addrs = NULL;
175                 return -ENOMEM;
176         }
177
178         ctrl_ext = rd32(hw, NGBE_PORTCTL);
179         /* let hardware know driver is loaded */
180         ctrl_ext |= NGBE_PORTCTL_DRVLOAD;
181         /* Set PF Reset Done bit so PF/VF Mail Ops can work */
182         ctrl_ext |= NGBE_PORTCTL_RSTDONE;
183         wr32(hw, NGBE_PORTCTL, ctrl_ext);
184         ngbe_flush(hw);
185
186         rte_intr_callback_register(intr_handle,
187                                    ngbe_dev_interrupt_handler, eth_dev);
188
189         /* enable uio/vfio intr/eventfd mapping */
190         rte_intr_enable(intr_handle);
191
192         /* enable support intr */
193         ngbe_enable_intr(eth_dev);
194
195         return 0;
196 }
197
198 static int
199 eth_ngbe_dev_uninit(struct rte_eth_dev *eth_dev)
200 {
201         PMD_INIT_FUNC_TRACE();
202
203         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
204                 return 0;
205
206         ngbe_dev_close(eth_dev);
207
208         return -EINVAL;
209 }
210
211 static int
212 eth_ngbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
213                 struct rte_pci_device *pci_dev)
214 {
215         return rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
216                         sizeof(struct ngbe_adapter),
217                         eth_dev_pci_specific_init, pci_dev,
218                         eth_ngbe_dev_init, NULL);
219 }
220
221 static int eth_ngbe_pci_remove(struct rte_pci_device *pci_dev)
222 {
223         struct rte_eth_dev *ethdev;
224
225         ethdev = rte_eth_dev_allocated(pci_dev->device.name);
226         if (ethdev == NULL)
227                 return 0;
228
229         return rte_eth_dev_destroy(ethdev, eth_ngbe_dev_uninit);
230 }
231
232 static struct rte_pci_driver rte_ngbe_pmd = {
233         .id_table = pci_id_ngbe_map,
234         .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
235                      RTE_PCI_DRV_INTR_LSC,
236         .probe = eth_ngbe_pci_probe,
237         .remove = eth_ngbe_pci_remove,
238 };
239
240 static int
241 ngbe_dev_configure(struct rte_eth_dev *dev)
242 {
243         struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
244
245         PMD_INIT_FUNC_TRACE();
246
247         /* set flag to update link status after init */
248         intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE;
249
250         return 0;
251 }
252
253 /*
254  * Reset and stop device.
255  */
256 static int
257 ngbe_dev_close(struct rte_eth_dev *dev)
258 {
259         PMD_INIT_FUNC_TRACE();
260
261         RTE_SET_USED(dev);
262
263         return -EINVAL;
264 }
265
266 static int
267 ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
268 {
269         RTE_SET_USED(dev);
270
271         dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_100M |
272                                 ETH_LINK_SPEED_10M;
273
274         return 0;
275 }
276
277 /* return 0 means link status changed, -1 means not changed */
278 int
279 ngbe_dev_link_update_share(struct rte_eth_dev *dev,
280                             int wait_to_complete)
281 {
282         struct ngbe_hw *hw = ngbe_dev_hw(dev);
283         struct rte_eth_link link;
284         u32 link_speed = NGBE_LINK_SPEED_UNKNOWN;
285         u32 lan_speed = 0;
286         struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
287         bool link_up;
288         int err;
289         int wait = 1;
290
291         memset(&link, 0, sizeof(link));
292         link.link_status = ETH_LINK_DOWN;
293         link.link_speed = ETH_SPEED_NUM_NONE;
294         link.link_duplex = ETH_LINK_HALF_DUPLEX;
295         link.link_autoneg = !(dev->data->dev_conf.link_speeds &
296                         ~ETH_LINK_SPEED_AUTONEG);
297
298         hw->mac.get_link_status = true;
299
300         if (intr->flags & NGBE_FLAG_NEED_LINK_CONFIG)
301                 return rte_eth_linkstatus_set(dev, &link);
302
303         /* check if it needs to wait to complete, if lsc interrupt is enabled */
304         if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)
305                 wait = 0;
306
307         err = hw->mac.check_link(hw, &link_speed, &link_up, wait);
308         if (err != 0) {
309                 link.link_speed = ETH_SPEED_NUM_NONE;
310                 link.link_duplex = ETH_LINK_FULL_DUPLEX;
311                 return rte_eth_linkstatus_set(dev, &link);
312         }
313
314         if (!link_up)
315                 return rte_eth_linkstatus_set(dev, &link);
316
317         intr->flags &= ~NGBE_FLAG_NEED_LINK_CONFIG;
318         link.link_status = ETH_LINK_UP;
319         link.link_duplex = ETH_LINK_FULL_DUPLEX;
320
321         switch (link_speed) {
322         default:
323         case NGBE_LINK_SPEED_UNKNOWN:
324                 link.link_speed = ETH_SPEED_NUM_NONE;
325                 break;
326
327         case NGBE_LINK_SPEED_10M_FULL:
328                 link.link_speed = ETH_SPEED_NUM_10M;
329                 lan_speed = 0;
330                 break;
331
332         case NGBE_LINK_SPEED_100M_FULL:
333                 link.link_speed = ETH_SPEED_NUM_100M;
334                 lan_speed = 1;
335                 break;
336
337         case NGBE_LINK_SPEED_1GB_FULL:
338                 link.link_speed = ETH_SPEED_NUM_1G;
339                 lan_speed = 2;
340                 break;
341         }
342
343         if (hw->is_pf) {
344                 wr32m(hw, NGBE_LAN_SPEED, NGBE_LAN_SPEED_MASK, lan_speed);
345                 if (link_speed & (NGBE_LINK_SPEED_1GB_FULL |
346                                 NGBE_LINK_SPEED_100M_FULL |
347                                 NGBE_LINK_SPEED_10M_FULL)) {
348                         wr32m(hw, NGBE_MACTXCFG, NGBE_MACTXCFG_SPEED_MASK,
349                                 NGBE_MACTXCFG_SPEED_1G | NGBE_MACTXCFG_TE);
350                 }
351         }
352
353         return rte_eth_linkstatus_set(dev, &link);
354 }
355
356 static int
357 ngbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
358 {
359         return ngbe_dev_link_update_share(dev, wait_to_complete);
360 }
361
362 /*
363  * It reads ICR and sets flag for the link_update.
364  *
365  * @param dev
366  *  Pointer to struct rte_eth_dev.
367  *
368  * @return
369  *  - On success, zero.
370  *  - On failure, a negative value.
371  */
372 static int
373 ngbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
374 {
375         uint32_t eicr;
376         struct ngbe_hw *hw = ngbe_dev_hw(dev);
377         struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
378
379         /* clear all cause mask */
380         ngbe_disable_intr(hw);
381
382         /* read-on-clear nic registers here */
383         eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC];
384         PMD_DRV_LOG(DEBUG, "eicr %x", eicr);
385
386         intr->flags = 0;
387
388         /* set flag for async link update */
389         if (eicr & NGBE_ICRMISC_PHY)
390                 intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE;
391
392         if (eicr & NGBE_ICRMISC_VFMBX)
393                 intr->flags |= NGBE_FLAG_MAILBOX;
394
395         if (eicr & NGBE_ICRMISC_LNKSEC)
396                 intr->flags |= NGBE_FLAG_MACSEC;
397
398         if (eicr & NGBE_ICRMISC_GPIO)
399                 intr->flags |= NGBE_FLAG_NEED_LINK_UPDATE;
400
401         return 0;
402 }
403
404 /**
405  * It gets and then prints the link status.
406  *
407  * @param dev
408  *  Pointer to struct rte_eth_dev.
409  *
410  * @return
411  *  - On success, zero.
412  *  - On failure, a negative value.
413  */
414 static void
415 ngbe_dev_link_status_print(struct rte_eth_dev *dev)
416 {
417         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
418         struct rte_eth_link link;
419
420         rte_eth_linkstatus_get(dev, &link);
421
422         if (link.link_status == ETH_LINK_UP) {
423                 PMD_INIT_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
424                                         (int)(dev->data->port_id),
425                                         (unsigned int)link.link_speed,
426                         link.link_duplex == ETH_LINK_FULL_DUPLEX ?
427                                         "full-duplex" : "half-duplex");
428         } else {
429                 PMD_INIT_LOG(INFO, " Port %d: Link Down",
430                                 (int)(dev->data->port_id));
431         }
432         PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
433                                 pci_dev->addr.domain,
434                                 pci_dev->addr.bus,
435                                 pci_dev->addr.devid,
436                                 pci_dev->addr.function);
437 }
438
439 /*
440  * It executes link_update after knowing an interrupt occurred.
441  *
442  * @param dev
443  *  Pointer to struct rte_eth_dev.
444  *
445  * @return
446  *  - On success, zero.
447  *  - On failure, a negative value.
448  */
449 static int
450 ngbe_dev_interrupt_action(struct rte_eth_dev *dev)
451 {
452         struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
453         int64_t timeout;
454
455         PMD_DRV_LOG(DEBUG, "intr action type %d", intr->flags);
456
457         if (intr->flags & NGBE_FLAG_NEED_LINK_UPDATE) {
458                 struct rte_eth_link link;
459
460                 /*get the link status before link update, for predicting later*/
461                 rte_eth_linkstatus_get(dev, &link);
462
463                 ngbe_dev_link_update(dev, 0);
464
465                 /* likely to up */
466                 if (link.link_status != ETH_LINK_UP)
467                         /* handle it 1 sec later, wait it being stable */
468                         timeout = NGBE_LINK_UP_CHECK_TIMEOUT;
469                 /* likely to down */
470                 else
471                         /* handle it 4 sec later, wait it being stable */
472                         timeout = NGBE_LINK_DOWN_CHECK_TIMEOUT;
473
474                 ngbe_dev_link_status_print(dev);
475                 if (rte_eal_alarm_set(timeout * 1000,
476                                       ngbe_dev_interrupt_delayed_handler,
477                                       (void *)dev) < 0) {
478                         PMD_DRV_LOG(ERR, "Error setting alarm");
479                 } else {
480                         /* remember original mask */
481                         intr->mask_misc_orig = intr->mask_misc;
482                         /* only disable lsc interrupt */
483                         intr->mask_misc &= ~NGBE_ICRMISC_PHY;
484
485                         intr->mask_orig = intr->mask;
486                         /* only disable all misc interrupts */
487                         intr->mask &= ~(1ULL << NGBE_MISC_VEC_ID);
488                 }
489         }
490
491         PMD_DRV_LOG(DEBUG, "enable intr immediately");
492         ngbe_enable_intr(dev);
493
494         return 0;
495 }
496
497 /**
498  * Interrupt handler which shall be registered for alarm callback for delayed
499  * handling specific interrupt to wait for the stable nic state. As the
500  * NIC interrupt state is not stable for ngbe after link is just down,
501  * it needs to wait 4 seconds to get the stable status.
502  *
503  * @param param
504  *  The address of parameter (struct rte_eth_dev *) registered before.
505  */
506 static void
507 ngbe_dev_interrupt_delayed_handler(void *param)
508 {
509         struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
510         struct ngbe_interrupt *intr = ngbe_dev_intr(dev);
511         struct ngbe_hw *hw = ngbe_dev_hw(dev);
512         uint32_t eicr;
513
514         ngbe_disable_intr(hw);
515
516         eicr = ((u32 *)hw->isb_mem)[NGBE_ISB_MISC];
517
518         if (intr->flags & NGBE_FLAG_NEED_LINK_UPDATE) {
519                 ngbe_dev_link_update(dev, 0);
520                 intr->flags &= ~NGBE_FLAG_NEED_LINK_UPDATE;
521                 ngbe_dev_link_status_print(dev);
522                 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
523                                               NULL);
524         }
525
526         if (intr->flags & NGBE_FLAG_MACSEC) {
527                 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_MACSEC,
528                                               NULL);
529                 intr->flags &= ~NGBE_FLAG_MACSEC;
530         }
531
532         /* restore original mask */
533         intr->mask_misc = intr->mask_misc_orig;
534         intr->mask_misc_orig = 0;
535         intr->mask = intr->mask_orig;
536         intr->mask_orig = 0;
537
538         PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
539         ngbe_enable_intr(dev);
540 }
541
542 /**
543  * Interrupt handler triggered by NIC  for handling
544  * specific interrupt.
545  *
546  * @param param
547  *  The address of parameter (struct rte_eth_dev *) registered before.
548  */
549 static void
550 ngbe_dev_interrupt_handler(void *param)
551 {
552         struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
553
554         ngbe_dev_interrupt_get_status(dev);
555         ngbe_dev_interrupt_action(dev);
556 }
557
558 static const struct eth_dev_ops ngbe_eth_dev_ops = {
559         .dev_configure              = ngbe_dev_configure,
560         .dev_infos_get              = ngbe_dev_info_get,
561         .link_update                = ngbe_dev_link_update,
562 };
563
564 RTE_PMD_REGISTER_PCI(net_ngbe, rte_ngbe_pmd);
565 RTE_PMD_REGISTER_PCI_TABLE(net_ngbe, pci_id_ngbe_map);
566 RTE_PMD_REGISTER_KMOD_DEP(net_ngbe, "* igb_uio | uio_pci_generic | vfio-pci");
567
568 RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_init, init, NOTICE);
569 RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_driver, driver, NOTICE);
570
571 #ifdef RTE_ETHDEV_DEBUG_RX
572         RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_rx, rx, DEBUG);
573 #endif
574 #ifdef RTE_ETHDEV_DEBUG_TX
575         RTE_LOG_REGISTER_SUFFIX(ngbe_logtype_tx, tx, DEBUG);
576 #endif