test/eventdev: add multi-ports test
[dpdk.git] / test / test / test_event_eth_rx_adapter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Intel Corporation
3  */
4 #include <string.h>
5 #include <rte_common.h>
6 #include <rte_mempool.h>
7 #include <rte_mbuf.h>
8 #include <rte_ethdev.h>
9 #include <rte_eventdev.h>
10 #include <rte_bus_vdev.h>
11
12 #include <rte_event_eth_rx_adapter.h>
13
14 #include "test.h"
15
16 #define MAX_NUM_RX_QUEUE        64
17 #define NB_MBUFS                (8192 * num_ports * MAX_NUM_RX_QUEUE)
18 #define MBUF_CACHE_SIZE         512
19 #define MBUF_PRIV_SIZE          0
20 #define TEST_INST_ID            0
21 #define TEST_DEV_ID             0
22 #define TEST_ETHDEV_ID          0
23
24 struct event_eth_rx_adapter_test_params {
25         struct rte_mempool *mp;
26         uint16_t rx_rings, tx_rings;
27         uint32_t caps;
28 };
29
30 static struct event_eth_rx_adapter_test_params default_params;
31
32 static inline int
33 port_init(uint8_t port, struct rte_mempool *mp)
34 {
35         static const struct rte_eth_conf port_conf_default = {
36                 .rxmode = {
37                         .mq_mode = ETH_MQ_RX_RSS,
38                         .max_rx_pkt_len = ETHER_MAX_LEN
39                 },
40                 .rx_adv_conf = {
41                         .rss_conf = {
42                                 .rss_hf = ETH_RSS_IP |
43                                           ETH_RSS_TCP |
44                                           ETH_RSS_UDP,
45                         }
46                 }
47         };
48         const uint16_t rx_ring_size = 512, tx_ring_size = 512;
49         struct rte_eth_conf port_conf = port_conf_default;
50         int retval;
51         uint16_t q;
52         struct rte_eth_dev_info dev_info;
53
54         if (!rte_eth_dev_is_valid_port(port))
55                 return -1;
56
57         retval = rte_eth_dev_configure(port, 0, 0, &port_conf);
58
59         rte_eth_dev_info_get(port, &dev_info);
60
61         default_params.rx_rings = RTE_MIN(dev_info.max_rx_queues,
62                                         MAX_NUM_RX_QUEUE);
63         default_params.tx_rings = 1;
64
65         /* Configure the Ethernet device. */
66         retval = rte_eth_dev_configure(port, default_params.rx_rings,
67                                 default_params.tx_rings, &port_conf);
68         if (retval != 0)
69                 return retval;
70
71         for (q = 0; q < default_params.rx_rings; q++) {
72                 retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
73                                 rte_eth_dev_socket_id(port), NULL, mp);
74                 if (retval < 0)
75                         return retval;
76         }
77
78         /* Allocate and set up 1 TX queue per Ethernet port. */
79         for (q = 0; q < default_params.tx_rings; q++) {
80                 retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
81                                 rte_eth_dev_socket_id(port), NULL);
82                 if (retval < 0)
83                         return retval;
84         }
85
86         /* Start the Ethernet port. */
87         retval = rte_eth_dev_start(port);
88         if (retval < 0)
89                 return retval;
90
91         /* Display the port MAC address. */
92         struct ether_addr addr;
93         rte_eth_macaddr_get(port, &addr);
94         printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
95                            " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
96                         (unsigned int)port,
97                         addr.addr_bytes[0], addr.addr_bytes[1],
98                         addr.addr_bytes[2], addr.addr_bytes[3],
99                         addr.addr_bytes[4], addr.addr_bytes[5]);
100
101         /* Enable RX in promiscuous mode for the Ethernet device. */
102         rte_eth_promiscuous_enable(port);
103
104         return 0;
105 }
106
107 static int
108 init_ports(int num_ports)
109 {
110         uint16_t portid;
111         int retval;
112
113         struct rte_mempool *ptr = rte_mempool_lookup("packet_pool");
114
115         if (ptr == NULL)
116                 default_params.mp = rte_pktmbuf_pool_create("packet_pool",
117                                                 NB_MBUFS,
118                                                 MBUF_CACHE_SIZE,
119                                                 MBUF_PRIV_SIZE,
120                                                 RTE_MBUF_DEFAULT_BUF_SIZE,
121                                                 rte_socket_id());
122         else
123                 default_params.mp = ptr;
124
125         if (!default_params.mp)
126                 return -ENOMEM;
127
128         RTE_ETH_FOREACH_DEV(portid) {
129                 retval = port_init(portid, default_params.mp);
130                 if (retval)
131                         return retval;
132         }
133
134         return 0;
135 }
136
137 static int
138 testsuite_setup(void)
139 {
140         int err;
141         uint8_t count;
142         struct rte_event_dev_info dev_info;
143
144         count = rte_event_dev_count();
145         if (!count) {
146                 printf("Failed to find a valid event device,"
147                         " testing with event_skeleton device\n");
148                 rte_vdev_init("event_skeleton", NULL);
149         }
150
151         struct rte_event_dev_config config = {
152                         .nb_event_queues = 1,
153                         .nb_event_ports = 1,
154         };
155
156         err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info);
157         config.nb_event_queue_flows = dev_info.max_event_queue_flows;
158         config.nb_event_port_dequeue_depth =
159                         dev_info.max_event_port_dequeue_depth;
160         config.nb_event_port_enqueue_depth =
161                         dev_info.max_event_port_enqueue_depth;
162         config.nb_events_limit =
163                         dev_info.max_num_events;
164         err = rte_event_dev_configure(TEST_DEV_ID, &config);
165         TEST_ASSERT(err == 0, "Event device initialization failed err %d\n",
166                         err);
167
168         /*
169          * eth devices like octeontx use event device to receive packets
170          * so rte_eth_dev_start invokes rte_event_dev_start internally, so
171          * call init_ports after rte_event_dev_configure
172          */
173         err = init_ports(rte_eth_dev_count_total());
174         TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err);
175
176         err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID,
177                                                 &default_params.caps);
178         TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n",
179                         err);
180
181         return err;
182 }
183
184 static void
185 testsuite_teardown(void)
186 {
187         uint32_t i;
188         RTE_ETH_FOREACH_DEV(i)
189                 rte_eth_dev_stop(i);
190
191         rte_mempool_free(default_params.mp);
192 }
193
194 static int
195 adapter_create(void)
196 {
197         int err;
198         struct rte_event_dev_info dev_info;
199         struct rte_event_port_conf rx_p_conf;
200
201         err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info);
202         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
203
204         rx_p_conf.new_event_threshold = dev_info.max_num_events;
205         rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
206         rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
207         err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID,
208                                         &rx_p_conf);
209         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
210
211         return err;
212 }
213
214 static void
215 adapter_free(void)
216 {
217         rte_event_eth_rx_adapter_free(TEST_INST_ID);
218 }
219
220 static int
221 adapter_create_free(void)
222 {
223         int err;
224
225         struct rte_event_port_conf rx_p_conf = {
226                         .dequeue_depth = 8,
227                         .enqueue_depth = 8,
228                         .new_event_threshold = 1200,
229         };
230
231         err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID,
232                                         NULL);
233         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
234
235         err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID,
236                                         &rx_p_conf);
237         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
238
239         err = rte_event_eth_rx_adapter_create(TEST_INST_ID,
240                                         TEST_DEV_ID, &rx_p_conf);
241         TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err);
242
243         err = rte_event_eth_rx_adapter_free(TEST_INST_ID);
244         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
245
246         err = rte_event_eth_rx_adapter_free(TEST_INST_ID);
247         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err);
248
249         err = rte_event_eth_rx_adapter_free(1);
250         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err);
251
252         return TEST_SUCCESS;
253 }
254
255 static int
256 adapter_queue_add_del(void)
257 {
258         int err;
259         struct rte_event ev;
260         uint32_t cap;
261
262         struct rte_event_eth_rx_adapter_queue_conf queue_config;
263
264         err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID,
265                                          &cap);
266         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
267
268         ev.queue_id = 0;
269         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
270         ev.priority = 0;
271
272         queue_config.rx_queue_flags = 0;
273         if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
274                 ev.flow_id = 1;
275                 queue_config.rx_queue_flags =
276                         RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
277         }
278         queue_config.ev = ev;
279         queue_config.servicing_weight = 1;
280
281         err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
282                                                 rte_eth_dev_count_total(),
283                                                 -1, &queue_config);
284         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
285
286         if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) {
287                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
288                                                         TEST_ETHDEV_ID, 0,
289                                                         &queue_config);
290                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
291
292                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
293                                                         TEST_ETHDEV_ID, 0);
294                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
295
296                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
297                                                         TEST_ETHDEV_ID,
298                                                         -1,
299                                                         &queue_config);
300                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
301
302                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
303                                                         TEST_ETHDEV_ID,
304                                                         -1);
305                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
306         } else {
307                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
308                                                         TEST_ETHDEV_ID,
309                                                         0,
310                                                         &queue_config);
311                 TEST_ASSERT(err == -EINVAL, "Expected EINVAL got %d", err);
312
313                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
314                                                         TEST_ETHDEV_ID, -1,
315                                                         &queue_config);
316                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
317
318                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
319                                                         TEST_ETHDEV_ID, 0);
320                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
321
322                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
323                                                         TEST_ETHDEV_ID, -1);
324                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
325
326                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
327                                                         TEST_ETHDEV_ID, -1);
328                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
329         }
330
331         err = rte_event_eth_rx_adapter_queue_add(1, TEST_ETHDEV_ID, -1,
332                                                 &queue_config);
333         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
334
335         err = rte_event_eth_rx_adapter_queue_del(1, TEST_ETHDEV_ID, -1);
336         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
337
338         return TEST_SUCCESS;
339 }
340
341 static int
342 adapter_multi_eth_add_del(void)
343 {
344         int err;
345         struct rte_event ev;
346
347         uint16_t port_index, drv_id = 0;
348         char driver_name[50];
349
350         struct rte_event_eth_rx_adapter_queue_conf queue_config;
351
352         ev.queue_id = 0;
353         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
354         ev.priority = 0;
355
356         queue_config.rx_queue_flags = 0;
357         queue_config.ev = ev;
358         queue_config.servicing_weight = 1;
359
360         /* stop eth devices for existing */
361         port_index = 0;
362         for (; port_index < rte_eth_dev_count_total(); port_index += 1)
363                 rte_eth_dev_stop(port_index);
364
365         /* add the max port for rx_adapter */
366         port_index = rte_eth_dev_count_total();
367         for (; port_index < RTE_MAX_ETHPORTS; port_index += 1) {
368                 sprintf(driver_name, "%s%u", "net_null", drv_id);
369                 err = rte_vdev_init(driver_name, NULL);
370                 TEST_ASSERT(err == 0, "Failed driver %s got %d",
371                 driver_name, err);
372                 drv_id += 1;
373         }
374
375         err = init_ports(rte_eth_dev_count_total());
376         TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err);
377
378         /* creating new instance for all newly added eth devices */
379         adapter_create();
380
381         /* eth_rx_adapter_queue_add for n ports */
382         port_index = 0;
383         for (; port_index < rte_eth_dev_count_total(); port_index += 1) {
384                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
385                                 port_index, 0,
386                                 &queue_config);
387                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
388         }
389
390         /* eth_rx_adapter_queue_del n ports */
391         port_index = 0;
392         for (; port_index < rte_eth_dev_count_total(); port_index += 1) {
393                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
394                                 port_index, 0);
395                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
396         }
397
398         adapter_free();
399
400         return TEST_SUCCESS;
401 }
402
403 static int
404 adapter_start_stop(void)
405 {
406         int err;
407         struct rte_event ev;
408
409         ev.queue_id = 0;
410         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
411         ev.priority = 0;
412
413         struct rte_event_eth_rx_adapter_queue_conf queue_config;
414
415         queue_config.rx_queue_flags = 0;
416         if (default_params.caps &
417                 RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
418                 ev.flow_id = 1;
419                 queue_config.rx_queue_flags =
420                         RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
421         }
422
423         queue_config.ev = ev;
424         queue_config.servicing_weight = 1;
425
426         err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID,
427                                         -1, &queue_config);
428         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
429
430         err = rte_event_eth_rx_adapter_start(TEST_INST_ID);
431         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
432
433         err = rte_event_eth_rx_adapter_stop(TEST_INST_ID);
434         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
435
436         err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID,
437                                                 -1);
438         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
439
440         err = rte_event_eth_rx_adapter_start(TEST_INST_ID);
441         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
442
443         err = rte_event_eth_rx_adapter_stop(TEST_INST_ID);
444         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
445
446         err = rte_event_eth_rx_adapter_start(1);
447         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
448
449         err = rte_event_eth_rx_adapter_stop(1);
450         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
451
452         return TEST_SUCCESS;
453 }
454
455 static int
456 adapter_stats(void)
457 {
458         int err;
459         struct rte_event_eth_rx_adapter_stats stats;
460
461         err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, NULL);
462         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
463
464         err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, &stats);
465         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
466
467         err = rte_event_eth_rx_adapter_stats_get(1, &stats);
468         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
469
470         return TEST_SUCCESS;
471 }
472
473 static struct unit_test_suite service_tests  = {
474         .suite_name = "rx event eth adapter test suite",
475         .setup = testsuite_setup,
476         .teardown = testsuite_teardown,
477         .unit_test_cases = {
478                 TEST_CASE_ST(NULL, NULL, adapter_create_free),
479                 TEST_CASE_ST(adapter_create, adapter_free,
480                                         adapter_queue_add_del),
481                 TEST_CASE_ST(NULL, NULL, adapter_multi_eth_add_del),
482                 TEST_CASE_ST(adapter_create, adapter_free, adapter_start_stop),
483                 TEST_CASE_ST(adapter_create, adapter_free, adapter_stats),
484                 TEST_CASES_END() /**< NULL terminate unit test array */
485         }
486 };
487
488 static int
489 test_event_eth_rx_adapter_common(void)
490 {
491         return unit_test_suite_runner(&service_tests);
492 }
493
494 REGISTER_TEST_COMMAND(event_eth_rx_adapter_autotest,
495                 test_event_eth_rx_adapter_common);