net/pfe: add device start/stop
[dpdk.git] / drivers / net / pfe / pfe_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2019 NXP
3  */
4
5 #include <rte_kvargs.h>
6 #include <rte_ethdev_vdev.h>
7 #include <rte_bus_vdev.h>
8 #include <dpaa_of.h>
9
10 #include "pfe_logs.h"
11 #include "pfe_mod.h"
12
13 #define PFE_MAX_MACS 1 /*we can support upto 4 MACs per IF*/
14 #define PFE_VDEV_GEM_ID_ARG     "intf"
15
16 struct pfe_vdev_init_params {
17         int8_t  gem_id;
18 };
19 static struct pfe *g_pfe;
20
21 /* TODO: make pfe_svr a runtime option.
22  * Driver should be able to get the SVR
23  * information from HW.
24  */
25 unsigned int pfe_svr = SVR_LS1012A_REV1;
26 static void *cbus_emac_base[3];
27 static void *cbus_gpi_base[3];
28
29 int pfe_logtype_pmd;
30
31 /* pfe_gemac_init
32  */
33 static int
34 pfe_gemac_init(struct pfe_eth_priv_s *priv)
35 {
36         struct gemac_cfg cfg;
37
38         cfg.speed = SPEED_1000M;
39         cfg.duplex = DUPLEX_FULL;
40
41         gemac_set_config(priv->EMAC_baseaddr, &cfg);
42         gemac_allow_broadcast(priv->EMAC_baseaddr);
43         gemac_enable_1536_rx(priv->EMAC_baseaddr);
44         gemac_enable_stacked_vlan(priv->EMAC_baseaddr);
45         gemac_enable_pause_rx(priv->EMAC_baseaddr);
46         gemac_set_bus_width(priv->EMAC_baseaddr, 64);
47         gemac_enable_rx_checksum_offload(priv->EMAC_baseaddr);
48
49         return 0;
50 }
51
52 static void
53 pfe_soc_version_get(void)
54 {
55         FILE *svr_file = NULL;
56         unsigned int svr_ver = 0;
57
58         PMD_INIT_FUNC_TRACE();
59
60         svr_file = fopen(PFE_SOC_ID_FILE, "r");
61         if (!svr_file) {
62                 PFE_PMD_ERR("Unable to open SoC device");
63                 return; /* Not supported on this infra */
64         }
65
66         if (fscanf(svr_file, "svr:%x", &svr_ver) > 0)
67                 pfe_svr = svr_ver;
68         else
69                 PFE_PMD_ERR("Unable to read SoC device");
70
71         fclose(svr_file);
72 }
73
74 static int pfe_eth_start(struct pfe_eth_priv_s *priv)
75 {
76         gpi_enable(priv->GPI_baseaddr);
77         gemac_enable(priv->EMAC_baseaddr);
78
79         return 0;
80 }
81
82 static void
83 pfe_eth_flush_txQ(struct pfe_eth_priv_s *priv, int tx_q_num, int
84                   __rte_unused from_tx, __rte_unused int n_desc)
85 {
86         struct rte_mbuf *mbuf;
87         unsigned int flags;
88
89         /* Clean HIF and client queue */
90         while ((mbuf = hif_lib_tx_get_next_complete(&priv->client,
91                                                    tx_q_num, &flags,
92                                                    HIF_TX_DESC_NT))) {
93                 if (mbuf) {
94                         mbuf->next = NULL;
95                         mbuf->nb_segs = 1;
96                         rte_pktmbuf_free(mbuf);
97                 }
98         }
99 }
100
101
102 static void
103 pfe_eth_flush_tx(struct pfe_eth_priv_s *priv)
104 {
105         unsigned int ii;
106
107         for (ii = 0; ii < emac_txq_cnt; ii++)
108                 pfe_eth_flush_txQ(priv, ii, 0, 0);
109 }
110
111 static int
112 pfe_eth_event_handler(void *data, int event, __rte_unused int qno)
113 {
114         struct pfe_eth_priv_s *priv = data;
115
116         switch (event) {
117         case EVENT_TXDONE_IND:
118                 pfe_eth_flush_tx(priv);
119                 hif_lib_event_handler_start(&priv->client, EVENT_TXDONE_IND, 0);
120                 break;
121         case EVENT_HIGH_RX_WM:
122         default:
123                 break;
124         }
125
126         return 0;
127 }
128
129 static int
130 pfe_eth_open(struct rte_eth_dev *dev)
131 {
132         struct pfe_eth_priv_s *priv = dev->data->dev_private;
133         struct hif_client_s *client;
134         struct hif_shm *hif_shm;
135         int rc;
136
137         /* Register client driver with HIF */
138         client = &priv->client;
139
140         if (client->pfe) {
141                 hif_shm = client->pfe->hif.shm;
142                 /* TODO please remove the below code of if block, once we add
143                  * the proper cleanup in eth_close
144                  */
145                 if (!test_bit(PFE_CL_GEM0 + priv->id,
146                               &hif_shm->g_client_status[0])) {
147                         /* Register client driver with HIF */
148                         memset(client, 0, sizeof(*client));
149                         client->id = PFE_CL_GEM0 + priv->id;
150                         client->tx_qn = emac_txq_cnt;
151                         client->rx_qn = EMAC_RXQ_CNT;
152                         client->priv = priv;
153                         client->pfe = priv->pfe;
154                         client->port_id = dev->data->port_id;
155                         client->event_handler = pfe_eth_event_handler;
156
157                         client->tx_qsize = EMAC_TXQ_DEPTH;
158                         client->rx_qsize = EMAC_RXQ_DEPTH;
159
160                         rc = hif_lib_client_register(client);
161                         if (rc) {
162                                 PFE_PMD_ERR("hif_lib_client_register(%d)"
163                                             " failed", client->id);
164                                 goto err0;
165                         }
166                 }
167         } else {
168                 /* Register client driver with HIF */
169                 memset(client, 0, sizeof(*client));
170                 client->id = PFE_CL_GEM0 + priv->id;
171                 client->tx_qn = emac_txq_cnt;
172                 client->rx_qn = EMAC_RXQ_CNT;
173                 client->priv = priv;
174                 client->pfe = priv->pfe;
175                 client->port_id = dev->data->port_id;
176                 client->event_handler = pfe_eth_event_handler;
177
178                 client->tx_qsize = EMAC_TXQ_DEPTH;
179                 client->rx_qsize = EMAC_RXQ_DEPTH;
180
181                 rc = hif_lib_client_register(client);
182                 if (rc) {
183                         PFE_PMD_ERR("hif_lib_client_register(%d) failed",
184                                     client->id);
185                         goto err0;
186                 }
187         }
188         rc = pfe_eth_start(priv);
189
190 err0:
191         return rc;
192 }
193
194 static int
195 pfe_eth_open_cdev(struct pfe_eth_priv_s *priv)
196 {
197         int pfe_cdev_fd;
198
199         if (priv == NULL)
200                 return -1;
201
202         pfe_cdev_fd = open(PFE_CDEV_PATH, O_RDONLY);
203         if (pfe_cdev_fd < 0) {
204                 PFE_PMD_WARN("Unable to open PFE device file (%s).\n",
205                              PFE_CDEV_PATH);
206                 PFE_PMD_WARN("Link status update will not be available.\n");
207                 priv->link_fd = PFE_CDEV_INVALID_FD;
208                 return -1;
209         }
210
211         priv->link_fd = pfe_cdev_fd;
212
213         return 0;
214 }
215
216 static void
217 pfe_eth_close_cdev(struct pfe_eth_priv_s *priv)
218 {
219         if (priv == NULL)
220                 return;
221
222         if (priv->link_fd != PFE_CDEV_INVALID_FD) {
223                 close(priv->link_fd);
224                 priv->link_fd = PFE_CDEV_INVALID_FD;
225         }
226 }
227
228 static void
229 pfe_eth_stop(struct rte_eth_dev *dev/*, int wake*/)
230 {
231         struct pfe_eth_priv_s *priv = dev->data->dev_private;
232
233         gemac_disable(priv->EMAC_baseaddr);
234         gpi_disable(priv->GPI_baseaddr);
235 }
236
237 static void
238 pfe_eth_exit(struct rte_eth_dev *dev, struct pfe *pfe)
239 {
240         PMD_INIT_FUNC_TRACE();
241
242         pfe_eth_stop(dev);
243         /* Close the device file for link status */
244         pfe_eth_close_cdev(dev->data->dev_private);
245
246         rte_free(dev->data->mac_addrs);
247         rte_eth_dev_release_port(dev);
248         pfe->nb_devs--;
249 }
250
251 static void
252 pfe_eth_close(struct rte_eth_dev *dev)
253 {
254         if (!dev)
255                 return;
256
257         if (!g_pfe)
258                 return;
259
260         pfe_eth_exit(dev, g_pfe);
261
262         if (g_pfe->nb_devs == 0) {
263                 pfe_hif_exit(g_pfe);
264                 pfe_hif_lib_exit(g_pfe);
265                 rte_free(g_pfe);
266                 g_pfe = NULL;
267         }
268 }
269
270 static int
271 pfe_eth_configure(struct rte_eth_dev *dev __rte_unused)
272 {
273         return 0;
274 }
275
276 static int
277 pfe_eth_info(struct rte_eth_dev *dev,
278                 struct rte_eth_dev_info *dev_info)
279 {
280         struct pfe_eth_priv_s *internals = dev->data->dev_private;
281
282         dev_info->if_index = internals->id;
283         dev_info->max_mac_addrs = PFE_MAX_MACS;
284         dev_info->max_rx_queues = dev->data->nb_rx_queues;
285         dev_info->max_tx_queues = dev->data->nb_tx_queues;
286         dev_info->min_rx_bufsize = HIF_RX_PKT_MIN_SIZE;
287         if (pfe_svr == SVR_LS1012A_REV1)
288                 dev_info->max_rx_pktlen = MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD;
289         else
290                 dev_info->max_rx_pktlen = JUMBO_FRAME_SIZE;
291
292         return 0;
293 }
294
295 static const struct eth_dev_ops ops = {
296         .dev_start = pfe_eth_open,
297         .dev_stop = pfe_eth_stop,
298         .dev_close = pfe_eth_close,
299         .dev_configure = pfe_eth_configure,
300         .dev_infos_get = pfe_eth_info,
301 };
302
303 static int
304 pfe_eth_init(struct rte_vdev_device *vdev, struct pfe *pfe, int id)
305 {
306         struct rte_eth_dev *eth_dev = NULL;
307         struct pfe_eth_priv_s *priv = NULL;
308         struct ls1012a_eth_platform_data *einfo;
309         struct ls1012a_pfe_platform_data *pfe_info;
310         int err;
311
312         eth_dev = rte_eth_vdev_allocate(vdev, sizeof(*priv));
313         if (eth_dev == NULL)
314                 return -ENOMEM;
315
316         /* Extract pltform data */
317         pfe_info = (struct ls1012a_pfe_platform_data *)&pfe->platform_data;
318         if (!pfe_info) {
319                 PFE_PMD_ERR("pfe missing additional platform data");
320                 err = -ENODEV;
321                 goto err0;
322         }
323
324         einfo = (struct ls1012a_eth_platform_data *)pfe_info->ls1012a_eth_pdata;
325
326         /* einfo never be NULL, but no harm in having this check */
327         if (!einfo) {
328                 PFE_PMD_ERR("pfe missing additional gemacs platform data");
329                 err = -ENODEV;
330                 goto err0;
331         }
332
333         priv = eth_dev->data->dev_private;
334         priv->ndev = eth_dev;
335         priv->id = einfo[id].gem_id;
336         priv->pfe = pfe;
337
338         pfe->eth.eth_priv[id] = priv;
339
340         /* Set the info in the priv to the current info */
341         priv->einfo = &einfo[id];
342         priv->EMAC_baseaddr = cbus_emac_base[id];
343         priv->PHY_baseaddr = cbus_emac_base[id];
344         priv->GPI_baseaddr = cbus_gpi_base[id];
345
346 #define HIF_GEMAC_TMUQ_BASE     6
347         priv->low_tmu_q = HIF_GEMAC_TMUQ_BASE + (id * 2);
348         priv->high_tmu_q = priv->low_tmu_q + 1;
349
350         rte_spinlock_init(&priv->lock);
351
352         /* Copy the station address into the dev structure, */
353         eth_dev->data->mac_addrs = rte_zmalloc("mac_addr",
354                         ETHER_ADDR_LEN * PFE_MAX_MACS, 0);
355         if (eth_dev->data->mac_addrs == NULL) {
356                 PFE_PMD_ERR("Failed to allocate mem %d to store MAC addresses",
357                         ETHER_ADDR_LEN * PFE_MAX_MACS);
358                 err = -ENOMEM;
359                 goto err0;
360         }
361
362         eth_dev->data->mtu = 1500;
363         eth_dev->dev_ops = &ops;
364         pfe_eth_stop(eth_dev);
365         pfe_gemac_init(priv);
366
367         eth_dev->data->nb_rx_queues = 1;
368         eth_dev->data->nb_tx_queues = 1;
369
370         /* For link status, open the PFE CDEV; Error from this function
371          * is silently ignored; In case of error, the link status will not
372          * be available.
373          */
374         pfe_eth_open_cdev(priv);
375         rte_eth_dev_probing_finish(eth_dev);
376
377         return 0;
378 err0:
379         rte_eth_dev_release_port(eth_dev);
380         return err;
381 }
382
383 static int
384 pfe_get_gemac_if_proprties(struct pfe *pfe,
385                 __rte_unused const struct device_node *parent,
386                 unsigned int port, unsigned int if_cnt,
387                 struct ls1012a_pfe_platform_data *pdata)
388 {
389         const struct device_node *gem = NULL;
390         size_t size;
391         unsigned int ii = 0, phy_id = 0;
392         const u32 *addr;
393         const void *mac_addr;
394
395         for (ii = 0; ii < if_cnt; ii++) {
396                 gem = of_get_next_child(parent, gem);
397                 if (!gem)
398                         goto err;
399                 addr = of_get_property(gem, "reg", &size);
400                 if (addr && (rte_be_to_cpu_32((unsigned int)*addr) == port))
401                         break;
402         }
403
404         if (ii >= if_cnt) {
405                 PFE_PMD_ERR("Failed to find interface = %d", if_cnt);
406                 goto err;
407         }
408
409         pdata->ls1012a_eth_pdata[port].gem_id = port;
410
411         mac_addr = of_get_mac_address(gem);
412
413         if (mac_addr) {
414                 memcpy(pdata->ls1012a_eth_pdata[port].mac_addr, mac_addr,
415                        ETH_ALEN);
416         }
417
418         addr = of_get_property(gem, "fsl,mdio-mux-val", &size);
419         if (!addr) {
420                 PFE_PMD_ERR("Invalid mdio-mux-val....");
421         } else {
422                 phy_id = rte_be_to_cpu_32((unsigned int)*addr);
423                 pdata->ls1012a_eth_pdata[port].mdio_muxval = phy_id;
424         }
425         if (pdata->ls1012a_eth_pdata[port].phy_id < 32)
426                 pfe->mdio_muxval[pdata->ls1012a_eth_pdata[port].phy_id] =
427                          pdata->ls1012a_eth_pdata[port].mdio_muxval;
428
429         return 0;
430
431 err:
432         return -1;
433 }
434
435 /* Parse integer from integer argument */
436 static int
437 parse_integer_arg(const char *key __rte_unused,
438                 const char *value, void *extra_args)
439 {
440         int i;
441         char *end;
442         errno = 0;
443
444         i = strtol(value, &end, 10);
445         if (*end != 0 || errno != 0 || i < 0 || i > 1) {
446                 PFE_PMD_ERR("Supported Port IDS are 0 and 1");
447                 return -EINVAL;
448         }
449
450         *((uint32_t *)extra_args) = i;
451
452         return 0;
453 }
454
455 static int
456 pfe_parse_vdev_init_params(struct pfe_vdev_init_params *params,
457                            struct rte_vdev_device *dev)
458 {
459         struct rte_kvargs *kvlist = NULL;
460         int ret = 0;
461
462         static const char * const pfe_vdev_valid_params[] = {
463                 PFE_VDEV_GEM_ID_ARG,
464                 NULL
465         };
466
467         const char *input_args = rte_vdev_device_args(dev);
468
469         if (!input_args)
470                 return -1;
471
472         kvlist = rte_kvargs_parse(input_args, pfe_vdev_valid_params);
473         if (kvlist == NULL)
474                 return -1;
475
476         ret = rte_kvargs_process(kvlist,
477                                 PFE_VDEV_GEM_ID_ARG,
478                                 &parse_integer_arg,
479                                 &params->gem_id);
480         rte_kvargs_free(kvlist);
481         return ret;
482 }
483
484 static int
485 pmd_pfe_probe(struct rte_vdev_device *vdev)
486 {
487         const u32 *prop;
488         const struct device_node *np;
489         const char *name;
490         const uint32_t *addr;
491         uint64_t cbus_addr, ddr_size, cbus_size;
492         int rc = -1, fd = -1, gem_id;
493         unsigned int ii, interface_count = 0;
494         size_t size = 0;
495         struct pfe_vdev_init_params init_params = {
496                 .gem_id = -1
497         };
498
499         name = rte_vdev_device_name(vdev);
500         rc = pfe_parse_vdev_init_params(&init_params, vdev);
501         if (rc < 0)
502                 return -EINVAL;
503
504         RTE_LOG(INFO, PMD, "Initializing pmd_pfe for %s Given gem-id %d\n",
505                 name, init_params.gem_id);
506
507         if (g_pfe) {
508                 if (g_pfe->nb_devs >= g_pfe->max_intf) {
509                         PFE_PMD_ERR("PFE %d dev already created Max is %d",
510                                 g_pfe->nb_devs, g_pfe->max_intf);
511                         return -EINVAL;
512                 }
513                 goto eth_init;
514         }
515
516         g_pfe = rte_zmalloc(NULL, sizeof(*g_pfe), RTE_CACHE_LINE_SIZE);
517         if (g_pfe == NULL)
518                 return  -EINVAL;
519
520         /* Load the device-tree driver */
521         rc = of_init();
522         if (rc) {
523                 PFE_PMD_ERR("of_init failed with ret: %d", rc);
524                 goto err;
525         }
526
527         np = of_find_compatible_node(NULL, NULL, "fsl,pfe");
528         if (!np) {
529                 PFE_PMD_ERR("Invalid device node");
530                 rc = -EINVAL;
531                 goto err;
532         }
533
534         addr = of_get_address(np, 0, &cbus_size, NULL);
535         if (!addr) {
536                 PFE_PMD_ERR("of_get_address cannot return qman address\n");
537                 goto err;
538         }
539         cbus_addr = of_translate_address(np, addr);
540         if (!cbus_addr) {
541                 PFE_PMD_ERR("of_translate_address failed\n");
542                 goto err;
543         }
544
545         addr = of_get_address(np, 1, &ddr_size, NULL);
546         if (!addr) {
547                 PFE_PMD_ERR("of_get_address cannot return qman address\n");
548                 goto err;
549         }
550
551         g_pfe->ddr_phys_baseaddr = of_translate_address(np, addr);
552         if (!g_pfe->ddr_phys_baseaddr) {
553                 PFE_PMD_ERR("of_translate_address failed\n");
554                 goto err;
555         }
556
557         g_pfe->ddr_baseaddr = pfe_mem_ptov(g_pfe->ddr_phys_baseaddr);
558         g_pfe->ddr_size = ddr_size;
559         g_pfe->cbus_size = cbus_size;
560
561         fd = open("/dev/mem", O_RDWR);
562         g_pfe->cbus_baseaddr = mmap(NULL, cbus_size, PROT_READ | PROT_WRITE,
563                                         MAP_SHARED, fd, cbus_addr);
564         close(fd);
565         if (g_pfe->cbus_baseaddr == MAP_FAILED) {
566                 PFE_PMD_ERR("Can not map cbus base");
567                 rc = -EINVAL;
568                 goto err;
569         }
570
571         /* Read interface count */
572         prop = of_get_property(np, "fsl,pfe-num-interfaces", &size);
573         if (!prop) {
574                 PFE_PMD_ERR("Failed to read number of interfaces");
575                 rc = -ENXIO;
576                 goto err_prop;
577         }
578
579         interface_count = rte_be_to_cpu_32((unsigned int)*prop);
580         if (interface_count <= 0) {
581                 PFE_PMD_ERR("No ethernet interface count : %d",
582                                 interface_count);
583                 rc = -ENXIO;
584                 goto err_prop;
585         }
586         PFE_PMD_INFO("num interfaces = %d ", interface_count);
587
588         g_pfe->max_intf  = interface_count;
589         g_pfe->platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
590
591         for (ii = 0; ii < interface_count; ii++) {
592                 pfe_get_gemac_if_proprties(g_pfe, np, ii, interface_count,
593                                            &g_pfe->platform_data);
594         }
595
596         pfe_lib_init(g_pfe->cbus_baseaddr, g_pfe->ddr_baseaddr,
597                      g_pfe->ddr_phys_baseaddr, g_pfe->ddr_size);
598
599         PFE_PMD_INFO("CLASS version: %x", readl(CLASS_VERSION));
600         PFE_PMD_INFO("TMU version: %x", readl(TMU_VERSION));
601
602         PFE_PMD_INFO("BMU1 version: %x", readl(BMU1_BASE_ADDR + BMU_VERSION));
603         PFE_PMD_INFO("BMU2 version: %x", readl(BMU2_BASE_ADDR + BMU_VERSION));
604
605         PFE_PMD_INFO("EGPI1 version: %x", readl(EGPI1_BASE_ADDR + GPI_VERSION));
606         PFE_PMD_INFO("EGPI2 version: %x", readl(EGPI2_BASE_ADDR + GPI_VERSION));
607         PFE_PMD_INFO("HGPI version: %x", readl(HGPI_BASE_ADDR + GPI_VERSION));
608
609         PFE_PMD_INFO("HIF version: %x", readl(HIF_VERSION));
610         PFE_PMD_INFO("HIF NOPCY version: %x", readl(HIF_NOCPY_VERSION));
611
612         cbus_emac_base[0] = EMAC1_BASE_ADDR;
613         cbus_emac_base[1] = EMAC2_BASE_ADDR;
614
615         cbus_gpi_base[0] = EGPI1_BASE_ADDR;
616         cbus_gpi_base[1] = EGPI2_BASE_ADDR;
617
618         rc = pfe_hif_lib_init(g_pfe);
619         if (rc < 0)
620                 goto err_hif_lib;
621
622         rc = pfe_hif_init(g_pfe);
623         if (rc < 0)
624                 goto err_hif;
625         pfe_soc_version_get();
626 eth_init:
627         if (init_params.gem_id < 0)
628                 gem_id = g_pfe->nb_devs;
629         else
630                 gem_id = init_params.gem_id;
631
632         RTE_LOG(INFO, PMD, "Init pmd_pfe for %s gem-id %d(given =%d)\n",
633                 name, gem_id, init_params.gem_id);
634
635         rc = pfe_eth_init(vdev, g_pfe, gem_id);
636         if (rc < 0)
637                 goto err_eth;
638         else
639                 g_pfe->nb_devs++;
640
641         return 0;
642
643 err_eth:
644         pfe_hif_exit(g_pfe);
645
646 err_hif:
647         pfe_hif_lib_exit(g_pfe);
648
649 err_hif_lib:
650 err_prop:
651         munmap(g_pfe->cbus_baseaddr, cbus_size);
652 err:
653         rte_free(g_pfe);
654         return rc;
655 }
656
657 static int
658 pmd_pfe_remove(struct rte_vdev_device *vdev)
659 {
660         const char *name;
661         struct rte_eth_dev *eth_dev = NULL;
662
663         name = rte_vdev_device_name(vdev);
664         if (name == NULL)
665                 return -EINVAL;
666
667         PFE_PMD_INFO("Closing eventdev sw device %s", name);
668
669         if (!g_pfe)
670                 return 0;
671
672         eth_dev = rte_eth_dev_allocated(name);
673         if (eth_dev == NULL)
674                 return -ENODEV;
675
676         pfe_eth_exit(eth_dev, g_pfe);
677         munmap(g_pfe->cbus_baseaddr, g_pfe->cbus_size);
678
679         if (g_pfe->nb_devs == 0) {
680                 pfe_hif_exit(g_pfe);
681                 pfe_hif_lib_exit(g_pfe);
682                 rte_free(g_pfe);
683                 g_pfe = NULL;
684         }
685         return 0;
686 }
687
688 static
689 struct rte_vdev_driver pmd_pfe_drv = {
690         .probe = pmd_pfe_probe,
691         .remove = pmd_pfe_remove,
692 };
693
694 RTE_PMD_REGISTER_VDEV(PFE_NAME_PMD, pmd_pfe_drv);
695 RTE_PMD_REGISTER_PARAM_STRING(PFE_NAME_PMD, PFE_VDEV_GEM_ID_ARG "=<int> ");
696
697 RTE_INIT(pfe_pmd_init_log)
698 {
699         pfe_logtype_pmd = rte_log_register("pmd.net.pfe");
700         if (pfe_logtype_pmd >= 0)
701                 rte_log_set_level(pfe_logtype_pmd, RTE_LOG_NOTICE);
702 }