3a8904729b9c720d966c559c153c67c8145ab980
[dpdk.git] / drivers / net / null / rte_eth_null.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) IGEL Co.,Ltd.
3  *  All rights reserved.
4  */
5
6 #include <rte_mbuf.h>
7 #include <rte_ethdev_driver.h>
8 #include <rte_ethdev_vdev.h>
9 #include <rte_malloc.h>
10 #include <rte_memcpy.h>
11 #include <rte_bus_vdev.h>
12 #include <rte_kvargs.h>
13 #include <rte_spinlock.h>
14
15 #define ETH_NULL_PACKET_SIZE_ARG        "size"
16 #define ETH_NULL_PACKET_COPY_ARG        "copy"
17
18 static unsigned default_packet_size = 64;
19 static unsigned default_packet_copy;
20
21 static const char *valid_arguments[] = {
22         ETH_NULL_PACKET_SIZE_ARG,
23         ETH_NULL_PACKET_COPY_ARG,
24         NULL
25 };
26
27 struct pmd_internals;
28
29 struct null_queue {
30         struct pmd_internals *internals;
31
32         struct rte_mempool *mb_pool;
33         struct rte_mbuf *dummy_packet;
34
35         rte_atomic64_t rx_pkts;
36         rte_atomic64_t tx_pkts;
37 };
38
39 struct pmd_internals {
40         unsigned packet_size;
41         unsigned packet_copy;
42         uint16_t port_id;
43
44         struct null_queue rx_null_queues[RTE_MAX_QUEUES_PER_PORT];
45         struct null_queue tx_null_queues[RTE_MAX_QUEUES_PER_PORT];
46
47         struct rte_ether_addr eth_addr;
48         /** Bit mask of RSS offloads, the bit offset also means flow type */
49         uint64_t flow_type_rss_offloads;
50
51         rte_spinlock_t rss_lock;
52
53         uint16_t reta_size;
54         struct rte_eth_rss_reta_entry64 reta_conf[ETH_RSS_RETA_SIZE_128 /
55                         RTE_RETA_GROUP_SIZE];
56
57         uint8_t rss_key[40];                /**< 40-byte hash key. */
58 };
59 static struct rte_eth_link pmd_link = {
60         .link_speed = ETH_SPEED_NUM_10G,
61         .link_duplex = ETH_LINK_FULL_DUPLEX,
62         .link_status = ETH_LINK_DOWN,
63         .link_autoneg = ETH_LINK_FIXED,
64 };
65
66 static int eth_null_logtype;
67
68 #define PMD_LOG(level, fmt, args...) \
69         rte_log(RTE_LOG_ ## level, eth_null_logtype, \
70                 "%s(): " fmt "\n", __func__, ##args)
71
72 static uint16_t
73 eth_null_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
74 {
75         int i;
76         struct null_queue *h = q;
77         unsigned packet_size;
78
79         if ((q == NULL) || (bufs == NULL))
80                 return 0;
81
82         packet_size = h->internals->packet_size;
83         if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) != 0)
84                 return 0;
85
86         for (i = 0; i < nb_bufs; i++) {
87                 bufs[i]->data_len = (uint16_t)packet_size;
88                 bufs[i]->pkt_len = packet_size;
89                 bufs[i]->port = h->internals->port_id;
90         }
91
92         rte_atomic64_add(&(h->rx_pkts), i);
93
94         return i;
95 }
96
97 static uint16_t
98 eth_null_copy_rx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
99 {
100         int i;
101         struct null_queue *h = q;
102         unsigned packet_size;
103
104         if ((q == NULL) || (bufs == NULL))
105                 return 0;
106
107         packet_size = h->internals->packet_size;
108         if (rte_pktmbuf_alloc_bulk(h->mb_pool, bufs, nb_bufs) != 0)
109                 return 0;
110
111         for (i = 0; i < nb_bufs; i++) {
112                 rte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), h->dummy_packet,
113                                         packet_size);
114                 bufs[i]->data_len = (uint16_t)packet_size;
115                 bufs[i]->pkt_len = packet_size;
116                 bufs[i]->port = h->internals->port_id;
117         }
118
119         rte_atomic64_add(&(h->rx_pkts), i);
120
121         return i;
122 }
123
124 static uint16_t
125 eth_null_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
126 {
127         int i;
128         struct null_queue *h = q;
129
130         if ((q == NULL) || (bufs == NULL))
131                 return 0;
132
133         for (i = 0; i < nb_bufs; i++)
134                 rte_pktmbuf_free(bufs[i]);
135
136         rte_atomic64_add(&(h->tx_pkts), i);
137
138         return i;
139 }
140
141 static uint16_t
142 eth_null_copy_tx(void *q, struct rte_mbuf **bufs, uint16_t nb_bufs)
143 {
144         int i;
145         struct null_queue *h = q;
146         unsigned packet_size;
147
148         if ((q == NULL) || (bufs == NULL))
149                 return 0;
150
151         packet_size = h->internals->packet_size;
152         for (i = 0; i < nb_bufs; i++) {
153                 rte_memcpy(h->dummy_packet, rte_pktmbuf_mtod(bufs[i], void *),
154                                         packet_size);
155                 rte_pktmbuf_free(bufs[i]);
156         }
157
158         rte_atomic64_add(&(h->tx_pkts), i);
159
160         return i;
161 }
162
163 static int
164 eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
165 {
166         return 0;
167 }
168
169 static int
170 eth_dev_start(struct rte_eth_dev *dev)
171 {
172         if (dev == NULL)
173                 return -EINVAL;
174
175         dev->data->dev_link.link_status = ETH_LINK_UP;
176         return 0;
177 }
178
179 static void
180 eth_dev_stop(struct rte_eth_dev *dev)
181 {
182         if (dev == NULL)
183                 return;
184
185         dev->data->dev_link.link_status = ETH_LINK_DOWN;
186 }
187
188 static int
189 eth_rx_queue_setup(struct rte_eth_dev *dev, uint16_t rx_queue_id,
190                 uint16_t nb_rx_desc __rte_unused,
191                 unsigned int socket_id __rte_unused,
192                 const struct rte_eth_rxconf *rx_conf __rte_unused,
193                 struct rte_mempool *mb_pool)
194 {
195         struct rte_mbuf *dummy_packet;
196         struct pmd_internals *internals;
197         unsigned packet_size;
198
199         if ((dev == NULL) || (mb_pool == NULL))
200                 return -EINVAL;
201
202         internals = dev->data->dev_private;
203
204         if (rx_queue_id >= dev->data->nb_rx_queues)
205                 return -ENODEV;
206
207         packet_size = internals->packet_size;
208
209         internals->rx_null_queues[rx_queue_id].mb_pool = mb_pool;
210         dev->data->rx_queues[rx_queue_id] =
211                 &internals->rx_null_queues[rx_queue_id];
212         dummy_packet = rte_zmalloc_socket(NULL,
213                         packet_size, 0, dev->data->numa_node);
214         if (dummy_packet == NULL)
215                 return -ENOMEM;
216
217         internals->rx_null_queues[rx_queue_id].internals = internals;
218         internals->rx_null_queues[rx_queue_id].dummy_packet = dummy_packet;
219
220         return 0;
221 }
222
223 static int
224 eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
225                 uint16_t nb_tx_desc __rte_unused,
226                 unsigned int socket_id __rte_unused,
227                 const struct rte_eth_txconf *tx_conf __rte_unused)
228 {
229         struct rte_mbuf *dummy_packet;
230         struct pmd_internals *internals;
231         unsigned packet_size;
232
233         if (dev == NULL)
234                 return -EINVAL;
235
236         internals = dev->data->dev_private;
237
238         if (tx_queue_id >= dev->data->nb_tx_queues)
239                 return -ENODEV;
240
241         packet_size = internals->packet_size;
242
243         dev->data->tx_queues[tx_queue_id] =
244                 &internals->tx_null_queues[tx_queue_id];
245         dummy_packet = rte_zmalloc_socket(NULL,
246                         packet_size, 0, dev->data->numa_node);
247         if (dummy_packet == NULL)
248                 return -ENOMEM;
249
250         internals->tx_null_queues[tx_queue_id].internals = internals;
251         internals->tx_null_queues[tx_queue_id].dummy_packet = dummy_packet;
252
253         return 0;
254 }
255
256 static int
257 eth_mtu_set(struct rte_eth_dev *dev __rte_unused, uint16_t mtu __rte_unused)
258 {
259         return 0;
260 }
261
262 static int
263 eth_dev_info(struct rte_eth_dev *dev,
264                 struct rte_eth_dev_info *dev_info)
265 {
266         struct pmd_internals *internals;
267
268         if ((dev == NULL) || (dev_info == NULL))
269                 return -EINVAL;
270
271         internals = dev->data->dev_private;
272         dev_info->max_mac_addrs = 1;
273         dev_info->max_rx_pktlen = (uint32_t)-1;
274         dev_info->max_rx_queues = RTE_DIM(internals->rx_null_queues);
275         dev_info->max_tx_queues = RTE_DIM(internals->tx_null_queues);
276         dev_info->min_rx_bufsize = 0;
277         dev_info->reta_size = internals->reta_size;
278         dev_info->flow_type_rss_offloads = internals->flow_type_rss_offloads;
279
280         return 0;
281 }
282
283 static int
284 eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *igb_stats)
285 {
286         unsigned i, num_stats;
287         unsigned long rx_total = 0, tx_total = 0;
288         const struct pmd_internals *internal;
289
290         if ((dev == NULL) || (igb_stats == NULL))
291                 return -EINVAL;
292
293         internal = dev->data->dev_private;
294         num_stats = RTE_MIN((unsigned)RTE_ETHDEV_QUEUE_STAT_CNTRS,
295                         RTE_MIN(dev->data->nb_rx_queues,
296                                 RTE_DIM(internal->rx_null_queues)));
297         for (i = 0; i < num_stats; i++) {
298                 igb_stats->q_ipackets[i] =
299                         internal->rx_null_queues[i].rx_pkts.cnt;
300                 rx_total += igb_stats->q_ipackets[i];
301         }
302
303         num_stats = RTE_MIN((unsigned)RTE_ETHDEV_QUEUE_STAT_CNTRS,
304                         RTE_MIN(dev->data->nb_tx_queues,
305                                 RTE_DIM(internal->tx_null_queues)));
306         for (i = 0; i < num_stats; i++) {
307                 igb_stats->q_opackets[i] =
308                         internal->tx_null_queues[i].tx_pkts.cnt;
309                 tx_total += igb_stats->q_opackets[i];
310         }
311
312         igb_stats->ipackets = rx_total;
313         igb_stats->opackets = tx_total;
314
315         return 0;
316 }
317
318 static int
319 eth_stats_reset(struct rte_eth_dev *dev)
320 {
321         unsigned i;
322         struct pmd_internals *internal;
323
324         if (dev == NULL)
325                 return -EINVAL;
326
327         internal = dev->data->dev_private;
328         for (i = 0; i < RTE_DIM(internal->rx_null_queues); i++)
329                 internal->rx_null_queues[i].rx_pkts.cnt = 0;
330         for (i = 0; i < RTE_DIM(internal->tx_null_queues); i++)
331                 internal->tx_null_queues[i].tx_pkts.cnt = 0;
332
333         return 0;
334 }
335
336 static void
337 eth_queue_release(void *q)
338 {
339         struct null_queue *nq;
340
341         if (q == NULL)
342                 return;
343
344         nq = q;
345         rte_free(nq->dummy_packet);
346 }
347
348 static int
349 eth_link_update(struct rte_eth_dev *dev __rte_unused,
350                 int wait_to_complete __rte_unused) { return 0; }
351
352 static int
353 eth_rss_reta_update(struct rte_eth_dev *dev,
354                 struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
355 {
356         int i, j;
357         struct pmd_internals *internal = dev->data->dev_private;
358
359         if (reta_size != internal->reta_size)
360                 return -EINVAL;
361
362         rte_spinlock_lock(&internal->rss_lock);
363
364         /* Copy RETA table */
365         for (i = 0; i < (internal->reta_size / RTE_RETA_GROUP_SIZE); i++) {
366                 internal->reta_conf[i].mask = reta_conf[i].mask;
367                 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
368                         if ((reta_conf[i].mask >> j) & 0x01)
369                                 internal->reta_conf[i].reta[j] = reta_conf[i].reta[j];
370         }
371
372         rte_spinlock_unlock(&internal->rss_lock);
373
374         return 0;
375 }
376
377 static int
378 eth_rss_reta_query(struct rte_eth_dev *dev,
379                 struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size)
380 {
381         int i, j;
382         struct pmd_internals *internal = dev->data->dev_private;
383
384         if (reta_size != internal->reta_size)
385                 return -EINVAL;
386
387         rte_spinlock_lock(&internal->rss_lock);
388
389         /* Copy RETA table */
390         for (i = 0; i < (internal->reta_size / RTE_RETA_GROUP_SIZE); i++) {
391                 for (j = 0; j < RTE_RETA_GROUP_SIZE; j++)
392                         if ((reta_conf[i].mask >> j) & 0x01)
393                                 reta_conf[i].reta[j] = internal->reta_conf[i].reta[j];
394         }
395
396         rte_spinlock_unlock(&internal->rss_lock);
397
398         return 0;
399 }
400
401 static int
402 eth_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf)
403 {
404         struct pmd_internals *internal = dev->data->dev_private;
405
406         rte_spinlock_lock(&internal->rss_lock);
407
408         if ((rss_conf->rss_hf & internal->flow_type_rss_offloads) != 0)
409                 dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf =
410                                 rss_conf->rss_hf & internal->flow_type_rss_offloads;
411
412         if (rss_conf->rss_key)
413                 rte_memcpy(internal->rss_key, rss_conf->rss_key, 40);
414
415         rte_spinlock_unlock(&internal->rss_lock);
416
417         return 0;
418 }
419
420 static int
421 eth_rss_hash_conf_get(struct rte_eth_dev *dev,
422                 struct rte_eth_rss_conf *rss_conf)
423 {
424         struct pmd_internals *internal = dev->data->dev_private;
425
426         rte_spinlock_lock(&internal->rss_lock);
427
428         rss_conf->rss_hf = dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf;
429         if (rss_conf->rss_key)
430                 rte_memcpy(rss_conf->rss_key, internal->rss_key, 40);
431
432         rte_spinlock_unlock(&internal->rss_lock);
433
434         return 0;
435 }
436
437 static int
438 eth_mac_address_set(__rte_unused struct rte_eth_dev *dev,
439                     __rte_unused struct rte_ether_addr *addr)
440 {
441         return 0;
442 }
443
444 static const struct eth_dev_ops ops = {
445         .dev_start = eth_dev_start,
446         .dev_stop = eth_dev_stop,
447         .dev_configure = eth_dev_configure,
448         .dev_infos_get = eth_dev_info,
449         .rx_queue_setup = eth_rx_queue_setup,
450         .tx_queue_setup = eth_tx_queue_setup,
451         .rx_queue_release = eth_queue_release,
452         .tx_queue_release = eth_queue_release,
453         .mtu_set = eth_mtu_set,
454         .link_update = eth_link_update,
455         .mac_addr_set = eth_mac_address_set,
456         .stats_get = eth_stats_get,
457         .stats_reset = eth_stats_reset,
458         .reta_update = eth_rss_reta_update,
459         .reta_query = eth_rss_reta_query,
460         .rss_hash_update = eth_rss_hash_update,
461         .rss_hash_conf_get = eth_rss_hash_conf_get
462 };
463
464 static int
465 eth_dev_null_create(struct rte_vdev_device *dev,
466                 unsigned packet_size,
467                 unsigned packet_copy)
468 {
469         const unsigned nb_rx_queues = 1;
470         const unsigned nb_tx_queues = 1;
471         struct rte_eth_dev_data *data;
472         struct pmd_internals *internals = NULL;
473         struct rte_eth_dev *eth_dev = NULL;
474
475         static const uint8_t default_rss_key[40] = {
476                 0x6D, 0x5A, 0x56, 0xDA, 0x25, 0x5B, 0x0E, 0xC2, 0x41, 0x67, 0x25, 0x3D,
477                 0x43, 0xA3, 0x8F, 0xB0, 0xD0, 0xCA, 0x2B, 0xCB, 0xAE, 0x7B, 0x30, 0xB4,
478                 0x77, 0xCB, 0x2D, 0xA3, 0x80, 0x30, 0xF2, 0x0C, 0x6A, 0x42, 0xB7, 0x3B,
479                 0xBE, 0xAC, 0x01, 0xFA
480         };
481
482         if (dev->device.numa_node == SOCKET_ID_ANY)
483                 dev->device.numa_node = rte_socket_id();
484
485         PMD_LOG(INFO, "Creating null ethdev on numa socket %u",
486                 dev->device.numa_node);
487
488         eth_dev = rte_eth_vdev_allocate(dev, sizeof(*internals));
489         if (!eth_dev)
490                 return -ENOMEM;
491
492         /* now put it all together
493          * - store queue data in internals,
494          * - store numa_node info in ethdev data
495          * - point eth_dev_data to internals
496          * - and point eth_dev structure to new eth_dev_data structure
497          */
498         /* NOTE: we'll replace the data element, of originally allocated eth_dev
499          * so the nulls are local per-process */
500
501         internals = eth_dev->data->dev_private;
502         internals->packet_size = packet_size;
503         internals->packet_copy = packet_copy;
504         internals->port_id = eth_dev->data->port_id;
505         rte_eth_random_addr(internals->eth_addr.addr_bytes);
506
507         internals->flow_type_rss_offloads =  ETH_RSS_PROTO_MASK;
508         internals->reta_size = RTE_DIM(internals->reta_conf) * RTE_RETA_GROUP_SIZE;
509
510         rte_memcpy(internals->rss_key, default_rss_key, 40);
511
512         data = eth_dev->data;
513         data->nb_rx_queues = (uint16_t)nb_rx_queues;
514         data->nb_tx_queues = (uint16_t)nb_tx_queues;
515         data->dev_link = pmd_link;
516         data->mac_addrs = &internals->eth_addr;
517
518         eth_dev->dev_ops = &ops;
519
520         /* finally assign rx and tx ops */
521         if (packet_copy) {
522                 eth_dev->rx_pkt_burst = eth_null_copy_rx;
523                 eth_dev->tx_pkt_burst = eth_null_copy_tx;
524         } else {
525                 eth_dev->rx_pkt_burst = eth_null_rx;
526                 eth_dev->tx_pkt_burst = eth_null_tx;
527         }
528
529         rte_eth_dev_probing_finish(eth_dev);
530         return 0;
531 }
532
533 static inline int
534 get_packet_size_arg(const char *key __rte_unused,
535                 const char *value, void *extra_args)
536 {
537         const char *a = value;
538         unsigned *packet_size = extra_args;
539
540         if ((value == NULL) || (extra_args == NULL))
541                 return -EINVAL;
542
543         *packet_size = (unsigned)strtoul(a, NULL, 0);
544         if (*packet_size == UINT_MAX)
545                 return -1;
546
547         return 0;
548 }
549
550 static inline int
551 get_packet_copy_arg(const char *key __rte_unused,
552                 const char *value, void *extra_args)
553 {
554         const char *a = value;
555         unsigned *packet_copy = extra_args;
556
557         if ((value == NULL) || (extra_args == NULL))
558                 return -EINVAL;
559
560         *packet_copy = (unsigned)strtoul(a, NULL, 0);
561         if (*packet_copy == UINT_MAX)
562                 return -1;
563
564         return 0;
565 }
566
567 static int
568 rte_pmd_null_probe(struct rte_vdev_device *dev)
569 {
570         const char *name, *params;
571         unsigned packet_size = default_packet_size;
572         unsigned packet_copy = default_packet_copy;
573         struct rte_kvargs *kvlist = NULL;
574         struct rte_eth_dev *eth_dev;
575         int ret;
576
577         if (!dev)
578                 return -EINVAL;
579
580         name = rte_vdev_device_name(dev);
581         params = rte_vdev_device_args(dev);
582         PMD_LOG(INFO, "Initializing pmd_null for %s", name);
583
584         if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
585                 eth_dev = rte_eth_dev_attach_secondary(name);
586                 if (!eth_dev) {
587                         PMD_LOG(ERR, "Failed to probe %s", name);
588                         return -1;
589                 }
590                 /* TODO: request info from primary to set up Rx and Tx */
591                 eth_dev->dev_ops = &ops;
592                 eth_dev->device = &dev->device;
593                 if (packet_copy) {
594                         eth_dev->rx_pkt_burst = eth_null_copy_rx;
595                         eth_dev->tx_pkt_burst = eth_null_copy_tx;
596                 } else {
597                         eth_dev->rx_pkt_burst = eth_null_rx;
598                         eth_dev->tx_pkt_burst = eth_null_tx;
599                 }
600                 rte_eth_dev_probing_finish(eth_dev);
601                 return 0;
602         }
603
604         if (params != NULL) {
605                 kvlist = rte_kvargs_parse(params, valid_arguments);
606                 if (kvlist == NULL)
607                         return -1;
608
609                 if (rte_kvargs_count(kvlist, ETH_NULL_PACKET_SIZE_ARG) == 1) {
610
611                         ret = rte_kvargs_process(kvlist,
612                                         ETH_NULL_PACKET_SIZE_ARG,
613                                         &get_packet_size_arg, &packet_size);
614                         if (ret < 0)
615                                 goto free_kvlist;
616                 }
617
618                 if (rte_kvargs_count(kvlist, ETH_NULL_PACKET_COPY_ARG) == 1) {
619
620                         ret = rte_kvargs_process(kvlist,
621                                         ETH_NULL_PACKET_COPY_ARG,
622                                         &get_packet_copy_arg, &packet_copy);
623                         if (ret < 0)
624                                 goto free_kvlist;
625                 }
626         }
627
628         PMD_LOG(INFO, "Configure pmd_null: packet size is %d, "
629                         "packet copy is %s", packet_size,
630                         packet_copy ? "enabled" : "disabled");
631
632         ret = eth_dev_null_create(dev, packet_size, packet_copy);
633
634 free_kvlist:
635         if (kvlist)
636                 rte_kvargs_free(kvlist);
637         return ret;
638 }
639
640 static int
641 rte_pmd_null_remove(struct rte_vdev_device *dev)
642 {
643         struct rte_eth_dev *eth_dev = NULL;
644
645         if (!dev)
646                 return -EINVAL;
647
648         PMD_LOG(INFO, "Closing null ethdev on numa socket %u",
649                         rte_socket_id());
650
651         /* find the ethdev entry */
652         eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev));
653         if (eth_dev == NULL)
654                 return -1;
655
656         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
657                 /* mac_addrs must not be freed alone because part of dev_private */
658                 eth_dev->data->mac_addrs = NULL;
659
660         rte_eth_dev_release_port(eth_dev);
661
662         return 0;
663 }
664
665 static struct rte_vdev_driver pmd_null_drv = {
666         .probe = rte_pmd_null_probe,
667         .remove = rte_pmd_null_remove,
668 };
669
670 RTE_PMD_REGISTER_VDEV(net_null, pmd_null_drv);
671 RTE_PMD_REGISTER_ALIAS(net_null, eth_null);
672 RTE_PMD_REGISTER_PARAM_STRING(net_null,
673         "size=<int> "
674         "copy=<int>");
675
676 RTE_INIT(eth_null_init_log)
677 {
678         eth_null_logtype = rte_log_register("pmd.net.null");
679         if (eth_null_logtype >= 0)
680                 rte_log_set_level(eth_null_logtype, RTE_LOG_NOTICE);
681 }