xref: /dpdk/app/test/test_pmd_ring.c (revision fc1f2750a3ec6da919e3c86e59d56f34ec97154b)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 #include "test.h"
34 
35 #include <stdio.h>
36 
37 #include <rte_eth_ring.h>
38 #include <rte_ethdev.h>
39 
40 static struct rte_mempool *mp;
41 
42 #define TX_PORT 0
43 #define RX_PORT 1
44 #define RXTX_PORT 2
45 #define RXTX_PORT2 3
46 #define RXTX_PORT3 4
47 #define SOCKET0 0
48 
49 #define RING_SIZE 256
50 
51 #define MBUF_SIZE (2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
52 #define NB_MBUF   512
53 
54 static int
55 test_ethdev_configure(void)
56 {
57 	struct rte_eth_conf null_conf;
58 	struct rte_eth_link link;
59 
60 	memset(&null_conf, 0, sizeof(struct rte_eth_conf));
61 
62 	if ((TX_PORT >= RTE_MAX_ETHPORTS) || (RX_PORT >= RTE_MAX_ETHPORTS)\
63 		|| (RXTX_PORT >= RTE_MAX_ETHPORTS)) {
64 		printf(" TX/RX port exceed max eth ports\n");
65 		return -1;
66 	}
67 	if (rte_eth_dev_configure(TX_PORT, 1, 2, &null_conf) < 0) {
68 		printf("Configure failed for TX port\n");
69 		return -1;
70 	}
71 
72 	/* Test queue release */
73 	if (rte_eth_dev_configure(TX_PORT, 1, 1, &null_conf) < 0) {
74 		printf("Configure failed for TX port\n");
75 		return -1;
76 	}
77 	if (rte_eth_dev_configure(RX_PORT, 1, 1, &null_conf) < 0) {
78 		printf("Configure failed for RX port\n");
79 		return -1;
80 	}
81 	if (rte_eth_dev_configure(RXTX_PORT, 1, 1, &null_conf) < 0) {
82 		printf("Configure failed for RXTX port\n");
83 		return -1;
84 	}
85 
86 	if (rte_eth_tx_queue_setup(TX_PORT, 0, RING_SIZE, SOCKET0, NULL) < 0) {
87 		printf("TX queue setup failed\n");
88 		return -1;
89 	}
90 	if (rte_eth_rx_queue_setup(RX_PORT, 0, RING_SIZE, SOCKET0,
91 			NULL, mp) < 0) {
92 		printf("RX queue setup failed\n");
93 		return -1;
94 	}
95 	if (rte_eth_tx_queue_setup(RXTX_PORT, 0, RING_SIZE, SOCKET0, NULL) < 0) {
96 		printf("TX queue setup failed\n");
97 		return -1;
98 	}
99 	if (rte_eth_rx_queue_setup(RXTX_PORT, 0, RING_SIZE, SOCKET0,
100 			NULL, mp) < 0) {
101 		printf("RX queue setup failed\n");
102 		return -1;
103 	}
104 
105 	if (rte_eth_dev_start(TX_PORT) < 0) {
106 		printf("Error starting TX port\n");
107 		return -1;
108 	}
109 	if (rte_eth_dev_start(RX_PORT) < 0) {
110 		printf("Error starting RX port\n");
111 		return -1;
112 	}
113 	if (rte_eth_dev_start(RXTX_PORT) < 0) {
114 		printf("Error starting RX port\n");
115 		return -1;
116 	}
117 
118 	rte_eth_link_get(TX_PORT, &link);
119 	rte_eth_link_get(RX_PORT, &link);
120 	rte_eth_link_get(RXTX_PORT, &link);
121 
122 	return 0;
123 }
124 
125 static int
126 test_send_basic_packets(void)
127 {
128 	struct rte_mbuf  bufs[RING_SIZE];
129 	struct rte_mbuf *pbufs[RING_SIZE];
130 	int i;
131 
132 	printf("Testing ring pmd RX/TX\n");
133 
134 	for (i = 0; i < RING_SIZE/2; i++)
135 		pbufs[i] = &bufs[i];
136 
137 	if (rte_eth_tx_burst(TX_PORT, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) {
138 		printf("Failed to transmit packet burst\n");
139 		return -1;
140 	}
141 
142 	if (rte_eth_rx_burst(RX_PORT, 0, pbufs, RING_SIZE) != RING_SIZE/2) {
143 		printf("Failed to receive packet burst\n");
144 		return -1;
145 	}
146 
147 	for (i = 0; i < RING_SIZE/2; i++)
148 		if (pbufs[i] != &bufs[i]) {
149 			printf("Error: received data does not match that transmitted\n");
150 			return -1;
151 		}
152 
153 	return 0;
154 }
155 
156 static int
157 test_get_stats(void)
158 {
159 	struct rte_eth_stats stats;
160 	struct rte_mbuf buf, *pbuf = &buf;
161 
162 	printf("Testing ring PMD stats\n");
163 
164 	/* check stats of RXTX port, should all be zero */
165 	rte_eth_stats_get(RXTX_PORT, &stats);
166 	if (stats.ipackets != 0 || stats.opackets != 0 ||
167 			stats.ibytes != 0 || stats.obytes != 0 ||
168 			stats.ierrors != 0 || stats.oerrors != 0) {
169 		printf("Error: RXTX port stats are not zero\n");
170 		return -1;
171 	}
172 
173 	/* send and receive 1 packet and check for stats update */
174 	if (rte_eth_tx_burst(RXTX_PORT, 0, &pbuf, 1) != 1) {
175 		printf("Error sending packet to RXTX port\n");
176 		return -1;
177 	}
178 	if (rte_eth_rx_burst(RXTX_PORT, 0, &pbuf, 1) != 1) {
179 		printf("Error receiving packet from RXTX port\n");
180 		return -1;
181 	}
182 
183 	rte_eth_stats_get(RXTX_PORT, &stats);
184 	if (stats.ipackets != 1 || stats.opackets != 1 ||
185 			stats.ibytes != 0 || stats.obytes != 0 ||
186 			stats.ierrors != 0 || stats.oerrors != 0) {
187 		printf("Error: RXTX port stats are not as expected\n");
188 		return -1;
189 	}
190 	return 0;
191 }
192 
193 static int
194 test_stats_reset(void)
195 {
196 	struct rte_eth_stats stats;
197 	struct rte_mbuf buf, *pbuf = &buf;
198 
199 	printf("Testing ring PMD stats reset\n");
200 
201 	rte_eth_stats_reset(RXTX_PORT);
202 
203 	/* check stats of RXTX port, should all be zero */
204 	rte_eth_stats_get(RXTX_PORT, &stats);
205 	if (stats.ipackets != 0 || stats.opackets != 0 ||
206 			stats.ibytes != 0 || stats.obytes != 0 ||
207 			stats.ierrors != 0 || stats.oerrors != 0) {
208 		printf("Error: RXTX port stats are not zero\n");
209 		return -1;
210 	}
211 
212 	/* send and receive 1 packet and check for stats update */
213 	if (rte_eth_tx_burst(RXTX_PORT, 0, &pbuf, 1) != 1) {
214 		printf("Error sending packet to RXTX port\n");
215 		return -1;
216 	}
217 
218 	if (rte_eth_rx_burst(RXTX_PORT, 0, &pbuf, 1) != 1) {
219 		printf("Error receiving packet from RXTX port\n");
220 		return -1;
221 	}
222 
223 	rte_eth_stats_get(RXTX_PORT, &stats);
224 	if (stats.ipackets != 1 || stats.opackets != 1 ||
225 			stats.ibytes != 0 || stats.obytes != 0 ||
226 			stats.ierrors != 0 || stats.oerrors != 0) {
227 		printf("Error: RXTX port stats are not as expected\n");
228 		return -1;
229 	}
230 
231 	rte_eth_stats_reset(RXTX_PORT);
232 
233 	/* check stats of RXTX port, should all be zero */
234 	rte_eth_stats_get(RXTX_PORT, &stats);
235 	if (stats.ipackets != 0 || stats.opackets != 0 ||
236 			stats.ibytes != 0 || stats.obytes != 0 ||
237 			stats.ierrors != 0 || stats.oerrors != 0) {
238 		printf("Error: RXTX port stats are not zero\n");
239 		return -1;
240 	}
241 
242 	return 0;
243 }
244 
245 static int
246 test_pmd_ring_pair_create_attach(void)
247 {
248 	struct rte_eth_stats stats, stats2;
249 	struct rte_mbuf buf, *pbuf = &buf;
250 	struct rte_eth_conf null_conf;
251 
252 	if ((RXTX_PORT2 >= RTE_MAX_ETHPORTS) || (RXTX_PORT3 >= RTE_MAX_ETHPORTS)) {
253 		printf(" TX/RX port exceed max eth ports\n");
254 		return -1;
255 	}
256 	if ((rte_eth_dev_configure(RXTX_PORT2, 1, 1, &null_conf) < 0)
257 		|| (rte_eth_dev_configure(RXTX_PORT3, 1, 1, &null_conf) < 0)) {
258 		printf("Configure failed for RXTX port\n");
259 		return -1;
260 	}
261 
262 	if ((rte_eth_tx_queue_setup(RXTX_PORT2, 0, RING_SIZE, SOCKET0, NULL) < 0)
263 		|| (rte_eth_tx_queue_setup(RXTX_PORT3, 0, RING_SIZE, SOCKET0, NULL) < 0)) {
264 		printf("TX queue setup failed\n");
265 		return -1;
266 	}
267 
268 	if ((rte_eth_rx_queue_setup(RXTX_PORT2, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)
269 		|| (rte_eth_rx_queue_setup(RXTX_PORT3, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)) {
270 		printf("RX queue setup failed\n");
271 		return -1;
272 	}
273 
274 	if ((rte_eth_dev_start(RXTX_PORT2) < 0)
275 		|| (rte_eth_dev_start(RXTX_PORT3) < 0)) {
276 		printf("Error starting RXTX port\n");
277 		return -1;
278 	}
279 
280 	/*
281 	 * send and receive 1 packet (RXTX_PORT2 -> RXTX_PORT3)
282 	 * and check for stats update
283 	 */
284 	if (rte_eth_tx_burst(RXTX_PORT2, 0, &pbuf, 1) != 1) {
285 		printf("Error sending packet to RXTX port\n");
286 		return -1;
287 	}
288 
289 	if (rte_eth_rx_burst(RXTX_PORT3, 0, &pbuf, 1) != 1) {
290 		printf("Error receiving packet from RXTX port\n");
291 		return -1;
292 	}
293 
294 	rte_eth_stats_get(RXTX_PORT2, &stats);
295 	rte_eth_stats_get(RXTX_PORT3, &stats2);
296 	if (stats.ipackets != 0 || stats.opackets != 1 ||
297 			stats.ibytes != 0 || stats.obytes != 0 ||
298 			stats.ierrors != 0 || stats.oerrors != 0) {
299 		printf("Error: RXTX port stats are not as expected\n");
300 		return -1;
301 	}
302 
303 	if (stats2.ipackets != 1 || stats2.opackets != 0 ||
304 			stats2.ibytes != 0 || stats2.obytes != 0 ||
305 			stats2.ierrors != 0 || stats2.oerrors != 0) {
306 		printf("Error: RXTX port stats are not as expected\n");
307 		return -1;
308 	}
309 
310 	/*
311 	 * send and receive 1 packet (RXTX_PORT3 -> RXTX_PORT2)
312 	 * and check for stats update
313 	 */
314 	if (rte_eth_tx_burst(RXTX_PORT3, 0, &pbuf, 1) != 1) {
315 		printf("Error sending packet to RXTX port\n");
316 		return -1;
317 	}
318 
319 	if (rte_eth_rx_burst(RXTX_PORT2, 0, &pbuf, 1) != 1) {
320 		printf("Error receiving packet from RXTX port\n");
321 		return -1;
322 	}
323 
324 	rte_eth_stats_get(RXTX_PORT2, &stats);
325 	rte_eth_stats_get(RXTX_PORT3, &stats2);
326 	if (stats.ipackets != 1 || stats.opackets != 1 ||
327 			stats.ibytes != 0 || stats.obytes != 0 ||
328 			stats.ierrors != 0 || stats.oerrors != 0) {
329 		printf("Error: RXTX port stats are not as expected\n");
330 		return -1;
331 	}
332 
333 	if (stats2.ipackets != 1 || stats2.opackets != 1 ||
334 			stats2.ibytes != 0 || stats2.obytes != 0 ||
335 			stats2.ierrors != 0 || stats2.oerrors != 0) {
336 		printf("Error: RXTX port stats are not as expected\n");
337 		return -1;
338 	}
339 
340 	/*
341 	 * send and receive 1 packet (RXTX_PORT2 -> RXTX_PORT2)
342 	 * and check for stats update
343 	 */
344 	if (rte_eth_tx_burst(RXTX_PORT2, 0, &pbuf, 1) != 1) {
345 		printf("Error sending packet to RXTX port\n");
346 		return -1;
347 	}
348 
349 	if (rte_eth_rx_burst(RXTX_PORT2, 0, &pbuf, 1) != 1) {
350 		printf("Error receiving packet from RXTX port\n");
351 		return -1;
352 	}
353 
354 	rte_eth_stats_get(RXTX_PORT2, &stats);
355 	rte_eth_stats_get(RXTX_PORT3, &stats2);
356 	if (stats.ipackets != 2 || stats.opackets != 2 ||
357 			stats.ibytes != 0 || stats.obytes != 0 ||
358 			stats.ierrors != 0 || stats.oerrors != 0) {
359 		printf("Error: RXTX port stats are not as expected\n");
360 		return -1;
361 	}
362 
363 	if (stats2.ipackets != 1 || stats2.opackets != 1 ||
364 			stats2.ibytes != 0 || stats2.obytes != 0 ||
365 			stats2.ierrors != 0 || stats2.oerrors != 0) {
366 		printf("Error: RXTX port stats are not as expected\n");
367 		return -1;
368 	}
369 
370 	/*
371 	 * send and receive 1 packet (RXTX_PORT3 -> RXTX_PORT3)
372 	 * and check for stats update
373 	 */
374 	if (rte_eth_tx_burst(RXTX_PORT3, 0, &pbuf, 1) != 1) {
375 		printf("Error sending packet to RXTX port\n");
376 		return -1;
377 	}
378 
379 	if (rte_eth_rx_burst(RXTX_PORT3, 0, &pbuf, 1) != 1) {
380 		printf("Error receiving packet from RXTX port\n");
381 		return -1;
382 	}
383 
384 	rte_eth_stats_get(RXTX_PORT2, &stats);
385 	rte_eth_stats_get(RXTX_PORT3, &stats2);
386 	if (stats.ipackets != 2 || stats.opackets != 2 ||
387 			stats.ibytes != 0 || stats.obytes != 0 ||
388 			stats.ierrors != 0 || stats.oerrors != 0) {
389 		printf("Error: RXTX port stats are not as expected\n");
390 		return -1;
391 	}
392 
393 	if (stats2.ipackets != 2 || stats2.opackets != 2 ||
394 			stats2.ibytes != 0 || stats2.obytes != 0 ||
395 			stats2.ierrors != 0 || stats2.oerrors != 0) {
396 		printf("Error: RXTX port stats are not as expected\n");
397 		return -1;
398 	}
399 
400 	rte_eth_dev_stop(RXTX_PORT2);
401 	rte_eth_dev_stop(RXTX_PORT3);
402 
403 	return 0;
404 }
405 
406 static int
407 test_pmd_ring(void)
408 {
409 	mp = rte_mempool_create("mbuf_pool", NB_MBUF,
410 			MBUF_SIZE, 32,
411 			sizeof(struct rte_pktmbuf_pool_private),
412 			rte_pktmbuf_pool_init, NULL,
413 			rte_pktmbuf_init, NULL,
414 			rte_socket_id(), 0);
415 	if (mp == NULL)
416 		return -1;
417 
418 	if ((TX_PORT >= RTE_MAX_ETHPORTS) || (RX_PORT >= RTE_MAX_ETHPORTS)\
419 		|| (RXTX_PORT >= RTE_MAX_ETHPORTS)) {
420 		printf(" TX/RX port exceed max eth ports\n");
421 		return -1;
422 	}
423 
424 	if (test_ethdev_configure() < 0)
425 		return -1;
426 
427 	if (test_send_basic_packets() < 0)
428 		return -1;
429 
430 	if (test_get_stats() < 0)
431 		return -1;
432 
433 	if (test_stats_reset() < 0)
434 		return -1;
435 
436 	rte_eth_dev_stop(RX_PORT);
437 	rte_eth_dev_stop(TX_PORT);
438 	rte_eth_dev_stop(RXTX_PORT);
439 
440 	if (test_pmd_ring_pair_create_attach() < 0)
441 		return -1;
442 
443 	return 0;
444 }
445 
446 static struct test_command ring_pmd_cmd = {
447 	.command = "ring_pmd_autotest",
448 	.callback = test_pmd_ring,
449 };
450 REGISTER_TEST_COMMAND(ring_pmd_cmd);
451