test/eventdev: add tests for eth Rx adapter APIs
[dpdk.git] / test / test / test_event_eth_rx_adapter.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 #include <string.h>
33 #include <rte_common.h>
34 #include <rte_mempool.h>
35 #include <rte_mbuf.h>
36 #include <rte_ethdev.h>
37 #include <rte_eventdev.h>
38
39 #include <rte_event_eth_rx_adapter.h>
40
41 #include "test.h"
42
43 #define MAX_NUM_RX_QUEUE        64
44 #define NB_MBUFS                (8192 * num_ports * MAX_NUM_RX_QUEUE)
45 #define MBUF_CACHE_SIZE         512
46 #define MBUF_PRIV_SIZE          0
47 #define TEST_INST_ID            0
48 #define TEST_DEV_ID             0
49 #define TEST_ETHDEV_ID          0
50
51 struct event_eth_rx_adapter_test_params {
52         struct rte_mempool *mp;
53         uint16_t rx_rings, tx_rings;
54         uint32_t caps;
55 };
56
57 static struct event_eth_rx_adapter_test_params default_params;
58
59 static inline int
60 port_init(uint8_t port, struct rte_mempool *mp)
61 {
62         static const struct rte_eth_conf port_conf_default = {
63                 .rxmode = {
64                         .mq_mode = ETH_MQ_RX_RSS,
65                         .max_rx_pkt_len = ETHER_MAX_LEN
66                 },
67                 .rx_adv_conf = {
68                         .rss_conf = {
69                                 .rss_hf = ETH_RSS_IP |
70                                           ETH_RSS_TCP |
71                                           ETH_RSS_UDP,
72                         }
73                 }
74         };
75         const uint16_t rx_ring_size = 512, tx_ring_size = 512;
76         struct rte_eth_conf port_conf = port_conf_default;
77         int retval;
78         uint16_t q;
79         struct rte_eth_dev_info dev_info;
80
81         if (port >= rte_eth_dev_count())
82                 return -1;
83
84         retval = rte_eth_dev_configure(port, 0, 0, &port_conf);
85
86         rte_eth_dev_info_get(port, &dev_info);
87
88         default_params.rx_rings = RTE_MIN(dev_info.max_rx_queues,
89                                         MAX_NUM_RX_QUEUE);
90         default_params.tx_rings = 1;
91
92         /* Configure the Ethernet device. */
93         retval = rte_eth_dev_configure(port, default_params.rx_rings,
94                                 default_params.tx_rings, &port_conf);
95         if (retval != 0)
96                 return retval;
97
98         for (q = 0; q < default_params.rx_rings; q++) {
99                 retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
100                                 rte_eth_dev_socket_id(port), NULL, mp);
101                 if (retval < 0)
102                         return retval;
103         }
104
105         /* Allocate and set up 1 TX queue per Ethernet port. */
106         for (q = 0; q < default_params.tx_rings; q++) {
107                 retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
108                                 rte_eth_dev_socket_id(port), NULL);
109                 if (retval < 0)
110                         return retval;
111         }
112
113         /* Start the Ethernet port. */
114         retval = rte_eth_dev_start(port);
115         if (retval < 0)
116                 return retval;
117
118         /* Display the port MAC address. */
119         struct ether_addr addr;
120         rte_eth_macaddr_get(port, &addr);
121         printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
122                            " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
123                         (unsigned int)port,
124                         addr.addr_bytes[0], addr.addr_bytes[1],
125                         addr.addr_bytes[2], addr.addr_bytes[3],
126                         addr.addr_bytes[4], addr.addr_bytes[5]);
127
128         /* Enable RX in promiscuous mode for the Ethernet device. */
129         rte_eth_promiscuous_enable(port);
130
131         return 0;
132 }
133
134 static int
135 init_ports(int num_ports)
136 {
137         uint8_t portid;
138         int retval;
139
140         default_params.mp = rte_pktmbuf_pool_create("packet_pool",
141                                                 NB_MBUFS,
142                                                 MBUF_CACHE_SIZE,
143                                                 MBUF_PRIV_SIZE,
144                                                 RTE_MBUF_DEFAULT_BUF_SIZE,
145                                                 rte_socket_id());
146         if (!default_params.mp)
147                 return -ENOMEM;
148
149         for (portid = 0; portid < num_ports; portid++) {
150                 retval = port_init(portid, default_params.mp);
151                 if (retval)
152                         return retval;
153         }
154
155         return 0;
156 }
157
158 static int
159 testsuite_setup(void)
160 {
161         int err;
162         uint8_t count;
163         struct rte_event_dev_info dev_info;
164
165         count = rte_event_dev_count();
166         if (!count) {
167                 printf("Failed to find a valid event device,"
168                         " testing with event_skeleton device\n");
169                 rte_vdev_init("event_skeleton", NULL);
170         }
171
172         struct rte_event_dev_config config = {
173                         .nb_event_queues = 1,
174                         .nb_event_ports = 1,
175         };
176
177         err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info);
178         config.nb_event_queue_flows = dev_info.max_event_queue_flows;
179         config.nb_event_port_dequeue_depth =
180                         dev_info.max_event_port_dequeue_depth;
181         config.nb_event_port_enqueue_depth =
182                         dev_info.max_event_port_enqueue_depth;
183         config.nb_events_limit =
184                         dev_info.max_num_events;
185         err = rte_event_dev_configure(TEST_DEV_ID, &config);
186         TEST_ASSERT(err == 0, "Event device initialization failed err %d\n",
187                         err);
188
189         /*
190          * eth devices like octeontx use event device to receive packets
191          * so rte_eth_dev_start invokes rte_event_dev_start internally, so
192          * call init_ports after rte_event_dev_configure
193          */
194         err = init_ports(rte_eth_dev_count());
195         TEST_ASSERT(err == 0, "Port initialization failed err %d\n", err);
196
197         err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID,
198                                                 &default_params.caps);
199         TEST_ASSERT(err == 0, "Failed to get adapter cap err %d\n",
200                         err);
201
202         return err;
203 }
204
205 static void
206 testsuite_teardown(void)
207 {
208         uint32_t i;
209         for (i = 0; i < rte_eth_dev_count(); i++)
210                 rte_eth_dev_stop(i);
211
212         rte_mempool_free(default_params.mp);
213 }
214
215 static int
216 adapter_create(void)
217 {
218         int err;
219         struct rte_event_dev_info dev_info;
220         struct rte_event_port_conf rx_p_conf;
221
222         err = rte_event_dev_info_get(TEST_DEV_ID, &dev_info);
223         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
224
225         rx_p_conf.new_event_threshold = dev_info.max_num_events;
226         rx_p_conf.dequeue_depth = dev_info.max_event_port_dequeue_depth;
227         rx_p_conf.enqueue_depth = dev_info.max_event_port_enqueue_depth;
228         err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID,
229                                         &rx_p_conf);
230         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
231
232         return err;
233 }
234
235 static void
236 adapter_free(void)
237 {
238         rte_event_eth_rx_adapter_free(TEST_INST_ID);
239 }
240
241 static int
242 adapter_create_free(void)
243 {
244         int err;
245
246         struct rte_event_port_conf rx_p_conf = {
247                         .dequeue_depth = 8,
248                         .enqueue_depth = 8,
249                         .new_event_threshold = 1200,
250         };
251
252         err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID,
253                                         NULL);
254         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
255
256         err = rte_event_eth_rx_adapter_create(TEST_INST_ID, TEST_DEV_ID,
257                                         &rx_p_conf);
258         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
259
260         err = rte_event_eth_rx_adapter_create(TEST_INST_ID,
261                                         TEST_DEV_ID, &rx_p_conf);
262         TEST_ASSERT(err == -EEXIST, "Expected -EEXIST %d got %d", -EEXIST, err);
263
264         err = rte_event_eth_rx_adapter_free(TEST_INST_ID);
265         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
266
267         err = rte_event_eth_rx_adapter_free(TEST_INST_ID);
268         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err);
269
270         err = rte_event_eth_rx_adapter_free(1);
271         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL %d got %d", -EINVAL, err);
272
273         return TEST_SUCCESS;
274 }
275
276 static int
277 adapter_queue_add_del(void)
278 {
279         int err;
280         struct rte_event ev;
281         uint32_t cap;
282
283         struct rte_event_eth_rx_adapter_queue_conf queue_config;
284
285         err = rte_event_eth_rx_adapter_caps_get(TEST_DEV_ID, TEST_ETHDEV_ID,
286                                          &cap);
287         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
288
289         ev.queue_id = 0;
290         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
291         ev.priority = 0;
292
293         queue_config.rx_queue_flags = 0;
294         if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
295                 ev.flow_id = 1;
296                 queue_config.rx_queue_flags =
297                         RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
298         }
299         queue_config.ev = ev;
300         queue_config.servicing_weight = 1;
301
302         err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
303                                                 rte_eth_dev_count(),
304                                                 -1, &queue_config);
305         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
306
307         if (cap & RTE_EVENT_ETH_RX_ADAPTER_CAP_MULTI_EVENTQ) {
308                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
309                                                         TEST_ETHDEV_ID, 0,
310                                                         &queue_config);
311                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
312
313                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
314                                                         TEST_ETHDEV_ID, 0);
315                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
316
317                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
318                                                         TEST_ETHDEV_ID,
319                                                         -1,
320                                                         &queue_config);
321                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
322
323                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
324                                                         TEST_ETHDEV_ID,
325                                                         -1);
326                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
327         } else {
328                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
329                                                         TEST_ETHDEV_ID,
330                                                         0,
331                                                         &queue_config);
332                 TEST_ASSERT(err == -EINVAL, "Expected EINVAL got %d", err);
333
334                 err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID,
335                                                         TEST_ETHDEV_ID, -1,
336                                                         &queue_config);
337                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
338
339                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
340                                                         TEST_ETHDEV_ID, 0);
341                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
342
343                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
344                                                         TEST_ETHDEV_ID, -1);
345                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
346
347                 err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID,
348                                                         TEST_ETHDEV_ID, -1);
349                 TEST_ASSERT(err == 0, "Expected 0 got %d", err);
350         }
351
352         err = rte_event_eth_rx_adapter_queue_add(1, TEST_ETHDEV_ID, -1,
353                                                 &queue_config);
354         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
355
356         err = rte_event_eth_rx_adapter_queue_del(1, TEST_ETHDEV_ID, -1);
357         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
358
359         return TEST_SUCCESS;
360 }
361
362 static int
363 adapter_start_stop(void)
364 {
365         int err;
366         struct rte_event ev;
367
368         ev.queue_id = 0;
369         ev.sched_type = RTE_SCHED_TYPE_ATOMIC;
370         ev.priority = 0;
371
372         struct rte_event_eth_rx_adapter_queue_conf queue_config;
373
374         queue_config.rx_queue_flags = 0;
375         if (default_params.caps &
376                 RTE_EVENT_ETH_RX_ADAPTER_CAP_OVERRIDE_FLOW_ID) {
377                 ev.flow_id = 1;
378                 queue_config.rx_queue_flags =
379                         RTE_EVENT_ETH_RX_ADAPTER_QUEUE_FLOW_ID_VALID;
380         }
381
382         queue_config.ev = ev;
383         queue_config.servicing_weight = 1;
384
385         err = rte_event_eth_rx_adapter_queue_add(TEST_INST_ID, TEST_ETHDEV_ID,
386                                         -1, &queue_config);
387         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
388
389         err = rte_event_eth_rx_adapter_start(TEST_INST_ID);
390         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
391
392         err = rte_event_eth_rx_adapter_stop(TEST_INST_ID);
393         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
394
395         err = rte_event_eth_rx_adapter_queue_del(TEST_INST_ID, TEST_ETHDEV_ID,
396                                                 -1);
397         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
398
399         err = rte_event_eth_rx_adapter_start(TEST_INST_ID);
400         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
401
402         err = rte_event_eth_rx_adapter_stop(TEST_INST_ID);
403         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
404
405         err = rte_event_eth_rx_adapter_start(1);
406         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
407
408         err = rte_event_eth_rx_adapter_stop(1);
409         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
410
411         return TEST_SUCCESS;
412 }
413
414 static int
415 adapter_stats(void)
416 {
417         int err;
418         struct rte_event_eth_rx_adapter_stats stats;
419
420         err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, NULL);
421         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
422
423         err = rte_event_eth_rx_adapter_stats_get(TEST_INST_ID, &stats);
424         TEST_ASSERT(err == 0, "Expected 0 got %d", err);
425
426         err = rte_event_eth_rx_adapter_stats_get(1, &stats);
427         TEST_ASSERT(err == -EINVAL, "Expected -EINVAL got %d", err);
428
429         return TEST_SUCCESS;
430 }
431
432 static struct unit_test_suite service_tests  = {
433         .suite_name = "rx event eth adapter test suite",
434         .setup = testsuite_setup,
435         .teardown = testsuite_teardown,
436         .unit_test_cases = {
437                 TEST_CASE_ST(NULL, NULL, adapter_create_free),
438                 TEST_CASE_ST(adapter_create, adapter_free,
439                                         adapter_queue_add_del),
440                 TEST_CASE_ST(adapter_create, adapter_free, adapter_start_stop),
441                 TEST_CASE_ST(adapter_create, adapter_free, adapter_stats),
442                 TEST_CASES_END() /**< NULL terminate unit test array */
443         }
444 };
445
446 static int
447 test_event_eth_rx_adapter_common(void)
448 {
449         return unit_test_suite_runner(&service_tests);
450 }
451
452 REGISTER_TEST_COMMAND(event_eth_rx_adapter_autotest,
453                 test_event_eth_rx_adapter_common);