1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2015 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 static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte; 42 43 #define SOCKET0 0 44 #define RING_SIZE 256 45 #define NUM_RINGS 2 46 #define NB_MBUF 512 47 48 49 static int 50 test_ethdev_configure_port(int port) 51 { 52 struct rte_eth_conf null_conf; 53 struct rte_eth_link link; 54 55 memset(&null_conf, 0, sizeof(struct rte_eth_conf)); 56 57 if (rte_eth_dev_configure(port, 1, 2, &null_conf) < 0) { 58 printf("Configure failed for port %d\n", port); 59 return -1; 60 } 61 62 /* Test queue release */ 63 if (rte_eth_dev_configure(port, 1, 1, &null_conf) < 0) { 64 printf("Configure failed for port %d\n", port); 65 return -1; 66 } 67 68 if (rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL) < 0) { 69 printf("TX queue setup failed port %d\n", port); 70 return -1; 71 } 72 73 if (rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, 74 NULL, mp) < 0) { 75 printf("RX queue setup failed port %d\n", port); 76 return -1; 77 } 78 79 if (rte_eth_dev_start(port) < 0) { 80 printf("Error starting port %d\n", port); 81 return -1; 82 } 83 84 rte_eth_link_get(port, &link); 85 86 return 0; 87 } 88 89 static int 90 test_send_basic_packets(void) 91 { 92 struct rte_mbuf bufs[RING_SIZE]; 93 struct rte_mbuf *pbufs[RING_SIZE]; 94 int i; 95 96 printf("Testing send and receive RING_SIZE/2 packets (tx_porta -> rx_portb)\n"); 97 98 for (i = 0; i < RING_SIZE/2; i++) 99 pbufs[i] = &bufs[i]; 100 101 if (rte_eth_tx_burst(tx_porta, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { 102 printf("Failed to transmit packet burst port %d\n", tx_porta); 103 return -1; 104 } 105 106 if (rte_eth_rx_burst(rx_portb, 0, pbufs, RING_SIZE) != RING_SIZE/2) { 107 printf("Failed to receive packet burst on port %d\n", rx_portb); 108 return -1; 109 } 110 111 for (i = 0; i < RING_SIZE/2; i++) 112 if (pbufs[i] != &bufs[i]) { 113 printf("Error: received data does not match that transmitted\n"); 114 return -1; 115 } 116 117 return 0; 118 } 119 120 static int 121 test_send_basic_packets_port(int port) 122 { 123 struct rte_mbuf bufs[RING_SIZE]; 124 struct rte_mbuf *pbufs[RING_SIZE]; 125 int i; 126 127 printf("Testing send and receive RING_SIZE/2 packets (cmdl_port0 -> cmdl_port0)\n"); 128 129 for (i = 0; i < RING_SIZE/2; i++) 130 pbufs[i] = &bufs[i]; 131 132 if (rte_eth_tx_burst(port, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { 133 printf("Failed to transmit packet burst port %d\n", port); 134 return -1; 135 } 136 137 if (rte_eth_rx_burst(port, 0, pbufs, RING_SIZE) != RING_SIZE/2) { 138 printf("Failed to receive packet burst on port %d\n", port); 139 return -1; 140 } 141 142 for (i = 0; i < RING_SIZE/2; i++) 143 if (pbufs[i] != &bufs[i]) { 144 printf("Error: received data does not match that transmitted\n"); 145 return -1; 146 } 147 148 return 0; 149 } 150 151 152 static int 153 test_get_stats(int port) 154 { 155 struct rte_eth_stats stats; 156 struct rte_mbuf buf, *pbuf = &buf; 157 158 printf("Testing ring PMD stats_get port %d\n", port); 159 160 /* check stats of RXTX port, should all be zero */ 161 162 rte_eth_stats_get(port, &stats); 163 if (stats.ipackets != 0 || stats.opackets != 0 || 164 stats.ibytes != 0 || stats.obytes != 0 || 165 stats.ierrors != 0 || stats.oerrors != 0) { 166 printf("Error: port %d stats are not zero\n", port); 167 return -1; 168 } 169 170 /* send and receive 1 packet and check for stats update */ 171 if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { 172 printf("Error sending packet to port %d\n", port); 173 return -1; 174 } 175 176 if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { 177 printf("Error receiving packet from port %d\n", port); 178 return -1; 179 } 180 181 rte_eth_stats_get(port, &stats); 182 if (stats.ipackets != 1 || stats.opackets != 1 || 183 stats.ibytes != 0 || stats.obytes != 0 || 184 stats.ierrors != 0 || stats.oerrors != 0) { 185 printf("Error: port %d stats are not as expected\n", port); 186 return -1; 187 } 188 return 0; 189 } 190 191 static int 192 test_stats_reset(int port) 193 { 194 struct rte_eth_stats stats; 195 struct rte_mbuf buf, *pbuf = &buf; 196 197 printf("Testing ring PMD stats_reset port %d\n", port); 198 199 rte_eth_stats_reset(port); 200 201 /* check stats of RXTX port, should all be zero */ 202 rte_eth_stats_get(port, &stats); 203 if (stats.ipackets != 0 || stats.opackets != 0 || 204 stats.ibytes != 0 || stats.obytes != 0 || 205 stats.ierrors != 0 || stats.oerrors != 0) { 206 printf("Error: port %d stats are not zero\n", port); 207 return -1; 208 } 209 210 /* send and receive 1 packet and check for stats update */ 211 if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { 212 printf("Error sending packet to port %d\n", port); 213 return -1; 214 } 215 216 if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { 217 printf("Error receiving packet from port %d\n", port); 218 return -1; 219 } 220 221 rte_eth_stats_get(port, &stats); 222 if (stats.ipackets != 1 || stats.opackets != 1 || 223 stats.ibytes != 0 || stats.obytes != 0 || 224 stats.ierrors != 0 || stats.oerrors != 0) { 225 printf("Error: port %d stats are not as expected\n", port); 226 return -1; 227 } 228 229 rte_eth_stats_reset(port); 230 231 /* check stats of RXTX port, should all be zero */ 232 rte_eth_stats_get(port, &stats); 233 if (stats.ipackets != 0 || stats.opackets != 0 || 234 stats.ibytes != 0 || stats.obytes != 0 || 235 stats.ierrors != 0 || stats.oerrors != 0) { 236 printf("Error: port %d stats are not zero\n", port); 237 return -1; 238 } 239 240 return 0; 241 } 242 243 static int 244 test_pmd_ring_pair_create_attach(int portd, int porte) 245 { 246 struct rte_eth_stats stats, stats2; 247 struct rte_mbuf buf, *pbuf = &buf; 248 struct rte_eth_conf null_conf; 249 250 if ((rte_eth_dev_configure(portd, 1, 1, &null_conf) < 0) 251 || (rte_eth_dev_configure(porte, 1, 1, &null_conf) < 0)) { 252 printf("Configure failed for port\n"); 253 return -1; 254 } 255 256 if ((rte_eth_tx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL) < 0) 257 || (rte_eth_tx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL) < 0)) { 258 printf("TX queue setup failed\n"); 259 return -1; 260 } 261 262 if ((rte_eth_rx_queue_setup(portd, 0, RING_SIZE, SOCKET0, NULL, mp) < 0) 263 || (rte_eth_rx_queue_setup(porte, 0, RING_SIZE, SOCKET0, NULL, mp) < 0)) { 264 printf("RX queue setup failed\n"); 265 return -1; 266 } 267 268 if ((rte_eth_dev_start(portd) < 0) 269 || (rte_eth_dev_start(porte) < 0)) { 270 printf("Error starting port\n"); 271 return -1; 272 } 273 274 rte_eth_stats_reset(portd); 275 /* check stats of port, should all be zero */ 276 rte_eth_stats_get(portd, &stats); 277 if (stats.ipackets != 0 || stats.opackets != 0 || 278 stats.ibytes != 0 || stats.obytes != 0 || 279 stats.ierrors != 0 || stats.oerrors != 0) { 280 printf("Error: port %d stats are not zero\n", portd); 281 return -1; 282 } 283 284 rte_eth_stats_reset(porte); 285 /* check stats of port, should all be zero */ 286 rte_eth_stats_get(porte, &stats2); 287 if (stats2.ipackets != 0 || stats2.opackets != 0 || 288 stats2.ibytes != 0 || stats2.obytes != 0 || 289 stats2.ierrors != 0 || stats2.oerrors != 0) { 290 printf("Error: port %d stats are not zero\n", porte); 291 return -1; 292 } 293 294 /* 295 * send and receive 1 packet (portd -> porte) 296 * and check for stats update 297 */ 298 printf("Testing send and receive 1 packet (portd -> porte)\n"); 299 if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) { 300 printf("Error sending packet to port %d\n", portd); 301 return -1; 302 } 303 304 if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) { 305 printf("Error receiving packet from port %d\n", porte); 306 return -1; 307 } 308 309 rte_eth_stats_get(portd, &stats); 310 rte_eth_stats_get(porte, &stats2); 311 if (stats.ipackets != 0 || stats.opackets != 1 || 312 stats.ibytes != 0 || stats.obytes != 0 || 313 stats.ierrors != 0 || stats.oerrors != 0) { 314 printf("Error: port %d stats are not as expected\n", portd); 315 return -1; 316 } 317 318 if (stats2.ipackets != 1 || stats2.opackets != 0 || 319 stats2.ibytes != 0 || stats2.obytes != 0 || 320 stats2.ierrors != 0 || stats2.oerrors != 0) { 321 printf("Error: port %d stats are not as expected\n", porte); 322 return -1; 323 } 324 325 /* 326 * send and receive 1 packet (porte -> portd) 327 * and check for stats update 328 */ 329 printf("Testing send and receive 1 packet (porte -> portd)\n"); 330 if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) { 331 printf("Error sending packet to port %d\n", porte); 332 return -1; 333 } 334 335 if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) { 336 printf("Error receiving packet from port %d\n", portd); 337 return -1; 338 } 339 340 rte_eth_stats_get(portd, &stats); 341 rte_eth_stats_get(porte, &stats2); 342 if (stats.ipackets != 1 || stats.opackets != 1 || 343 stats.ibytes != 0 || stats.obytes != 0 || 344 stats.ierrors != 0 || stats.oerrors != 0) { 345 printf("Error: port %d stats are not as expected\n", portd); 346 return -1; 347 } 348 349 if (stats2.ipackets != 1 || stats2.opackets != 1 || 350 stats2.ibytes != 0 || stats2.obytes != 0 || 351 stats2.ierrors != 0 || stats2.oerrors != 0) { 352 printf("Error: port %d stats are not as expected\n", porte); 353 return -1; 354 } 355 356 /* 357 * send and receive 1 packet (portd -> portd) 358 * and check for stats update 359 */ 360 printf("Testing send and receive 1 packet (portd -> portd)\n"); 361 if (rte_eth_tx_burst(portd, 0, &pbuf, 1) != 1) { 362 printf("Error sending packet to port %d\n", portd); 363 return -1; 364 } 365 366 if (rte_eth_rx_burst(portd, 0, &pbuf, 1) != 1) { 367 printf("Error receiving packet from port %d\n", porte); 368 return -1; 369 } 370 371 rte_eth_stats_get(portd, &stats); 372 rte_eth_stats_get(porte, &stats2); 373 if (stats.ipackets != 2 || stats.opackets != 2 || 374 stats.ibytes != 0 || stats.obytes != 0 || 375 stats.ierrors != 0 || stats.oerrors != 0) { 376 printf("Error: port %d stats are not as expected\n", portd); 377 return -1; 378 } 379 380 if (stats2.ipackets != 1 || stats2.opackets != 1 || 381 stats2.ibytes != 0 || stats2.obytes != 0 || 382 stats2.ierrors != 0 || stats2.oerrors != 0) { 383 printf("Error: port %d stats are not as expected\n", porte); 384 return -1; 385 } 386 387 /* 388 * send and receive 1 packet (porte -> porte) 389 * and check for stats update 390 */ 391 printf("Testing send and receive 1 packet (porte -> porte)\n"); 392 if (rte_eth_tx_burst(porte, 0, &pbuf, 1) != 1) { 393 printf("Error sending packet to port %d\n", porte); 394 return -1; 395 } 396 397 if (rte_eth_rx_burst(porte, 0, &pbuf, 1) != 1) { 398 printf("Error receiving packet from port %d\n", porte); 399 return -1; 400 } 401 402 rte_eth_stats_get(portd, &stats); 403 rte_eth_stats_get(porte, &stats2); 404 if (stats.ipackets != 2 || stats.opackets != 2 || 405 stats.ibytes != 0 || stats.obytes != 0 || 406 stats.ierrors != 0 || stats.oerrors != 0) { 407 printf("Error: port %d stats are not as expected\n", portd); 408 return -1; 409 } 410 411 if (stats2.ipackets != 2 || stats2.opackets != 2 || 412 stats2.ibytes != 0 || stats2.obytes != 0 || 413 stats2.ierrors != 0 || stats2.oerrors != 0) { 414 printf("Error: port %d stats are not as expected\n", porte); 415 return -1; 416 } 417 418 rte_eth_dev_stop(portd); 419 rte_eth_dev_stop(porte); 420 421 return 0; 422 } 423 424 static int 425 test_pmd_ring(void) 426 { 427 struct rte_ring *rxtx[NUM_RINGS]; 428 int port, cmdl_port0 = -1; 429 uint8_t nb_ports; 430 431 nb_ports = rte_eth_dev_count(); 432 printf("nb_ports=%d\n", (int)nb_ports); 433 434 /* create the rings and eth_rings in the test code. 435 * This does not test the rte_pmd_ring_devinit function. 436 * 437 * Test with the command line option --vdev=eth_ring0 to test rte_pmd_ring_devinit. 438 */ 439 rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 440 if (rxtx[0] == NULL) { 441 printf("rte_ring_create R0 failed"); 442 return -1; 443 } 444 445 rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 446 if (rxtx[1] == NULL) { 447 printf("rte_ring_create R1 failed"); 448 return -1; 449 } 450 451 tx_porta = rte_eth_from_rings("eth_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 452 rx_portb = rte_eth_from_rings("eth_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 453 rxtx_portc = rte_eth_from_rings("eth_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 454 rxtx_portd = rte_eth_from_rings("eth_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 455 rxtx_porte = rte_eth_from_rings("eth_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 456 457 printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n", 458 tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte); 459 460 if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1) 461 || (rxtx_portd == -1) || (rxtx_porte == -1)) { 462 printf("rte_eth_from rings failed\n"); 463 return -1; 464 } 465 466 mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, 467 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 468 if (mp == NULL) 469 return -1; 470 471 if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS) 472 || (rxtx_portc >= RTE_MAX_ETHPORTS) 473 || (rxtx_portd >= RTE_MAX_ETHPORTS) 474 || (rxtx_porte >= RTE_MAX_ETHPORTS)) { 475 printf(" port exceed max eth ports\n"); 476 return -1; 477 } 478 479 if (test_ethdev_configure_port(tx_porta) < 0) 480 return -1; 481 482 if (test_ethdev_configure_port(rx_portb) < 0) 483 return -1; 484 485 if (test_ethdev_configure_port(rxtx_portc) < 0) 486 return -1; 487 488 if (test_send_basic_packets() < 0) 489 return -1; 490 491 if (test_get_stats(rxtx_portc) < 0) 492 return -1; 493 494 if (test_stats_reset(rxtx_portc) < 0) 495 return -1; 496 497 rte_eth_dev_stop(tx_porta); 498 rte_eth_dev_stop(rx_portb); 499 rte_eth_dev_stop(rxtx_portc); 500 501 if (test_pmd_ring_pair_create_attach(rxtx_portd, rxtx_porte) < 0) 502 return -1; 503 504 /* find a port created with the --vdev=eth_ring0 command line option */ 505 for (port = 0; port < nb_ports; port++) { 506 struct rte_eth_dev_info dev_info; 507 508 rte_eth_dev_info_get(port, &dev_info); 509 if (!strcmp(dev_info.driver_name, "Rings PMD")) { 510 printf("found a command line ring port=%d\n", port); 511 cmdl_port0 = port; 512 break; 513 } 514 } 515 if (cmdl_port0 != -1) { 516 if (test_ethdev_configure_port(cmdl_port0) < 0) 517 return -1; 518 if (test_send_basic_packets_port(cmdl_port0) < 0) 519 return -1; 520 if (test_stats_reset(cmdl_port0) < 0) 521 return -1; 522 if (test_get_stats(cmdl_port0) < 0) 523 return -1; 524 rte_eth_dev_stop(cmdl_port0); 525 } 526 return 0; 527 } 528 529 static struct test_command ring_pmd_cmd = { 530 .command = "ring_pmd_autotest", 531 .callback = test_pmd_ring, 532 }; 533 REGISTER_TEST_COMMAND(ring_pmd_cmd); 534