1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2015 Intel Corporation 3 */ 4 #include "test.h" 5 #include <string.h> 6 7 #include <stdio.h> 8 9 #include <rte_eth_ring.h> 10 #include <rte_ethdev.h> 11 #include <rte_bus_vdev.h> 12 13 #define SOCKET0 0 14 #define RING_SIZE 256 15 #define NUM_RINGS 2 16 #define NB_MBUF 512 17 18 static struct rte_mempool *mp; 19 struct rte_ring *rxtx[NUM_RINGS]; 20 static int tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte; 21 22 static int 23 test_ethdev_configure_port(int port) 24 { 25 struct rte_eth_conf null_conf; 26 struct rte_eth_link link; 27 int ret; 28 29 memset(&null_conf, 0, sizeof(struct rte_eth_conf)); 30 31 if (rte_eth_dev_configure(port, 1, 2, &null_conf) < 0) { 32 printf("Configure failed for port %d\n", port); 33 return -1; 34 } 35 36 /* Test queue release */ 37 if (rte_eth_dev_configure(port, 1, 1, &null_conf) < 0) { 38 printf("Configure failed for port %d\n", port); 39 return -1; 40 } 41 42 if (rte_eth_tx_queue_setup(port, 0, RING_SIZE, SOCKET0, NULL) < 0) { 43 printf("TX queue setup failed port %d\n", port); 44 return -1; 45 } 46 47 if (rte_eth_rx_queue_setup(port, 0, RING_SIZE, SOCKET0, 48 NULL, mp) < 0) { 49 printf("RX queue setup failed port %d\n", port); 50 return -1; 51 } 52 53 if (rte_eth_dev_start(port) < 0) { 54 printf("Error starting port %d\n", port); 55 return -1; 56 } 57 58 ret = rte_eth_link_get(port, &link); 59 if (ret < 0) { 60 printf("Link get failed for port %u: %s", 61 port, rte_strerror(-ret)); 62 return -1; 63 } 64 65 return 0; 66 } 67 68 static int 69 test_send_basic_packets(void) 70 { 71 struct rte_mbuf bufs[RING_SIZE]; 72 struct rte_mbuf *pbufs[RING_SIZE]; 73 int i; 74 75 printf("Testing send and receive RING_SIZE/2 packets (tx_porta -> rx_portb)\n"); 76 77 for (i = 0; i < RING_SIZE/2; i++) 78 pbufs[i] = &bufs[i]; 79 80 if (rte_eth_tx_burst(tx_porta, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { 81 printf("Failed to transmit packet burst port %d\n", tx_porta); 82 return TEST_FAILED; 83 } 84 85 if (rte_eth_rx_burst(rx_portb, 0, pbufs, RING_SIZE) != RING_SIZE/2) { 86 printf("Failed to receive packet burst on port %d\n", rx_portb); 87 return TEST_FAILED; 88 } 89 90 for (i = 0; i < RING_SIZE/2; i++) 91 if (pbufs[i] != &bufs[i]) { 92 printf("Error: received data does not match that transmitted\n"); 93 return TEST_FAILED; 94 } 95 96 return TEST_SUCCESS; 97 } 98 99 static int 100 test_send_basic_packets_port(int port) 101 { 102 struct rte_mbuf bufs[RING_SIZE]; 103 struct rte_mbuf *pbufs[RING_SIZE]; 104 int i; 105 106 printf("Testing send and receive RING_SIZE/2 packets (cmdl_port0 -> cmdl_port0)\n"); 107 108 for (i = 0; i < RING_SIZE/2; i++) 109 pbufs[i] = &bufs[i]; 110 111 if (rte_eth_tx_burst(port, 0, pbufs, RING_SIZE/2) < RING_SIZE/2) { 112 printf("Failed to transmit packet burst port %d\n", port); 113 return -1; 114 } 115 116 if (rte_eth_rx_burst(port, 0, pbufs, RING_SIZE) != RING_SIZE/2) { 117 printf("Failed to receive packet burst on port %d\n", port); 118 return -1; 119 } 120 121 for (i = 0; i < RING_SIZE/2; i++) 122 if (pbufs[i] != &bufs[i]) { 123 printf("Error: received data does not match that transmitted\n"); 124 return -1; 125 } 126 127 return 0; 128 } 129 130 131 static int 132 test_get_stats(int port) 133 { 134 struct rte_eth_stats stats; 135 struct rte_mbuf buf, *pbuf = &buf; 136 137 printf("Testing ring PMD stats_get port %d\n", port); 138 139 /* check stats of RXTX port, should all be zero */ 140 141 rte_eth_stats_get(port, &stats); 142 if (stats.ipackets != 0 || stats.opackets != 0 || 143 stats.ibytes != 0 || stats.obytes != 0 || 144 stats.ierrors != 0 || stats.oerrors != 0) { 145 printf("Error: port %d stats are not zero\n", port); 146 return -1; 147 } 148 149 /* send and receive 1 packet and check for stats update */ 150 if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { 151 printf("Error sending packet to port %d\n", port); 152 return -1; 153 } 154 155 if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { 156 printf("Error receiving packet from port %d\n", port); 157 return -1; 158 } 159 160 rte_eth_stats_get(port, &stats); 161 if (stats.ipackets != 1 || stats.opackets != 1 || 162 stats.ibytes != 0 || stats.obytes != 0 || 163 stats.ierrors != 0 || stats.oerrors != 0) { 164 printf("Error: port %d stats are not as expected\n", port); 165 return -1; 166 } 167 return 0; 168 } 169 170 static int 171 test_stats_reset(int port) 172 { 173 struct rte_eth_stats stats; 174 struct rte_mbuf buf, *pbuf = &buf; 175 176 printf("Testing ring PMD stats_reset port %d\n", port); 177 178 rte_eth_stats_reset(port); 179 180 /* check stats of RXTX port, should all be zero */ 181 rte_eth_stats_get(port, &stats); 182 if (stats.ipackets != 0 || stats.opackets != 0 || 183 stats.ibytes != 0 || stats.obytes != 0 || 184 stats.ierrors != 0 || stats.oerrors != 0) { 185 printf("Error: port %d stats are not zero\n", port); 186 return -1; 187 } 188 189 /* send and receive 1 packet and check for stats update */ 190 if (rte_eth_tx_burst(port, 0, &pbuf, 1) != 1) { 191 printf("Error sending packet to port %d\n", port); 192 return -1; 193 } 194 195 if (rte_eth_rx_burst(port, 0, &pbuf, 1) != 1) { 196 printf("Error receiving packet from port %d\n", port); 197 return -1; 198 } 199 200 rte_eth_stats_get(port, &stats); 201 if (stats.ipackets != 1 || stats.opackets != 1 || 202 stats.ibytes != 0 || stats.obytes != 0 || 203 stats.ierrors != 0 || stats.oerrors != 0) { 204 printf("Error: port %d stats are not as expected\n", port); 205 return -1; 206 } 207 208 rte_eth_stats_reset(port); 209 210 /* check stats of RXTX port, should all be zero */ 211 rte_eth_stats_get(port, &stats); 212 if (stats.ipackets != 0 || stats.opackets != 0 || 213 stats.ibytes != 0 || stats.obytes != 0 || 214 stats.ierrors != 0 || stats.oerrors != 0) { 215 printf("Error: port %d stats are not zero\n", port); 216 return -1; 217 } 218 219 return 0; 220 } 221 222 static int 223 test_pmd_ring_pair_create_attach(void) 224 { 225 struct rte_eth_stats stats, stats2; 226 struct rte_mbuf buf, *pbuf = &buf; 227 struct rte_eth_conf null_conf; 228 int ret; 229 230 memset(&null_conf, 0, sizeof(struct rte_eth_conf)); 231 232 if ((rte_eth_dev_configure(rxtx_portd, 1, 1, &null_conf) < 0) 233 || (rte_eth_dev_configure(rxtx_porte, 1, 1, 234 &null_conf) < 0)) { 235 printf("Configure failed for port\n"); 236 return TEST_FAILED; 237 } 238 239 if ((rte_eth_tx_queue_setup(rxtx_portd, 0, RING_SIZE, 240 SOCKET0, NULL) < 0) 241 || (rte_eth_tx_queue_setup(rxtx_porte, 0, RING_SIZE, 242 SOCKET0, NULL) < 0)) { 243 printf("TX queue setup failed\n"); 244 return TEST_FAILED; 245 } 246 247 if ((rte_eth_rx_queue_setup(rxtx_portd, 0, RING_SIZE, 248 SOCKET0, NULL, mp) < 0) 249 || (rte_eth_rx_queue_setup(rxtx_porte, 0, RING_SIZE, 250 SOCKET0, NULL, mp) < 0)) { 251 printf("RX queue setup failed\n"); 252 return TEST_FAILED; 253 } 254 255 if ((rte_eth_dev_start(rxtx_portd) < 0) 256 || (rte_eth_dev_start(rxtx_porte) < 0)) { 257 printf("Error starting port\n"); 258 return TEST_FAILED; 259 } 260 261 rte_eth_stats_reset(rxtx_portd); 262 /* check stats of port, should all be zero */ 263 rte_eth_stats_get(rxtx_portd, &stats); 264 if (stats.ipackets != 0 || stats.opackets != 0 || 265 stats.ibytes != 0 || stats.obytes != 0 || 266 stats.ierrors != 0 || stats.oerrors != 0) { 267 printf("Error: port %d stats are not zero\n", rxtx_portd); 268 return TEST_FAILED; 269 } 270 271 rte_eth_stats_reset(rxtx_porte); 272 /* check stats of port, should all be zero */ 273 rte_eth_stats_get(rxtx_porte, &stats2); 274 if (stats2.ipackets != 0 || stats2.opackets != 0 || 275 stats2.ibytes != 0 || stats2.obytes != 0 || 276 stats2.ierrors != 0 || stats2.oerrors != 0) { 277 printf("Error: port %d stats are not zero\n", rxtx_porte); 278 return TEST_FAILED; 279 } 280 281 /* 282 * send and receive 1 packet (rxtx_portd -> rxtx_porte) 283 * and check for stats update 284 */ 285 printf("Testing send and receive 1 packet (rxtx_portd -> rxtx_porte)\n"); 286 if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 287 printf("Error sending packet to port %d\n", rxtx_portd); 288 return TEST_FAILED; 289 } 290 291 if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 292 printf("Error receiving packet from port %d\n", rxtx_porte); 293 return TEST_FAILED; 294 } 295 296 rte_eth_stats_get(rxtx_portd, &stats); 297 rte_eth_stats_get(rxtx_porte, &stats2); 298 if (stats.ipackets != 0 || stats.opackets != 1 || 299 stats.ibytes != 0 || stats.obytes != 0 || 300 stats.ierrors != 0 || stats.oerrors != 0) { 301 printf("Error: port %d stats are not as expected\n", 302 rxtx_portd); 303 return TEST_FAILED; 304 } 305 306 if (stats2.ipackets != 1 || stats2.opackets != 0 || 307 stats2.ibytes != 0 || stats2.obytes != 0 || 308 stats2.ierrors != 0 || stats2.oerrors != 0) { 309 printf("Error: port %d stats are not as expected\n", 310 rxtx_porte); 311 return TEST_FAILED; 312 } 313 314 /* 315 * send and receive 1 packet (rxtx_porte -> rxtx_portd) 316 * and check for stats update 317 */ 318 printf("Testing send and receive 1 packet " 319 "(rxtx_porte -> rxtx_portd)\n"); 320 if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 321 printf("Error sending packet to port %d\n", rxtx_porte); 322 return TEST_FAILED; 323 } 324 325 if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 326 printf("Error receiving packet from port %d\n", rxtx_portd); 327 return TEST_FAILED; 328 } 329 330 rte_eth_stats_get(rxtx_portd, &stats); 331 rte_eth_stats_get(rxtx_porte, &stats2); 332 if (stats.ipackets != 1 || stats.opackets != 1 || 333 stats.ibytes != 0 || stats.obytes != 0 || 334 stats.ierrors != 0 || stats.oerrors != 0) { 335 printf("Error: port %d stats are not as expected\n", 336 rxtx_portd); 337 return TEST_FAILED; 338 } 339 340 if (stats2.ipackets != 1 || stats2.opackets != 1 || 341 stats2.ibytes != 0 || stats2.obytes != 0 || 342 stats2.ierrors != 0 || stats2.oerrors != 0) { 343 printf("Error: port %d stats are not as expected\n", 344 rxtx_porte); 345 return TEST_FAILED; 346 } 347 348 /* 349 * send and receive 1 packet (rxtx_portd -> rxtx_portd) 350 * and check for stats update 351 */ 352 printf("Testing send and receive 1 packet " 353 "(rxtx_portd -> rxtx_portd)\n"); 354 if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 355 printf("Error sending packet to port %d\n", rxtx_portd); 356 return TEST_FAILED; 357 } 358 359 if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 360 printf("Error receiving packet from port %d\n", rxtx_porte); 361 return TEST_FAILED; 362 } 363 364 rte_eth_stats_get(rxtx_portd, &stats); 365 rte_eth_stats_get(rxtx_porte, &stats2); 366 if (stats.ipackets != 2 || stats.opackets != 2 || 367 stats.ibytes != 0 || stats.obytes != 0 || 368 stats.ierrors != 0 || stats.oerrors != 0) { 369 printf("Error: port %d stats are not as expected\n", 370 rxtx_portd); 371 return TEST_FAILED; 372 } 373 374 if (stats2.ipackets != 1 || stats2.opackets != 1 || 375 stats2.ibytes != 0 || stats2.obytes != 0 || 376 stats2.ierrors != 0 || stats2.oerrors != 0) { 377 printf("Error: port %d stats are not as expected\n", 378 rxtx_porte); 379 return TEST_FAILED; 380 } 381 382 /* 383 * send and receive 1 packet (rxtx_porte -> rxtx_porte) 384 * and check for stats update 385 */ 386 printf("Testing send and receive 1 packet " 387 "(rxtx_porte -> rxtx_porte)\n"); 388 if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 389 printf("Error sending packet to port %d\n", rxtx_porte); 390 return TEST_FAILED; 391 } 392 393 if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 394 printf("Error receiving packet from port %d\n", rxtx_porte); 395 return TEST_FAILED; 396 } 397 398 rte_eth_stats_get(rxtx_portd, &stats); 399 rte_eth_stats_get(rxtx_porte, &stats2); 400 if (stats.ipackets != 2 || stats.opackets != 2 || 401 stats.ibytes != 0 || stats.obytes != 0 || 402 stats.ierrors != 0 || stats.oerrors != 0) { 403 printf("Error: port %d stats are not as expected\n", 404 rxtx_portd); 405 return TEST_FAILED; 406 } 407 408 if (stats2.ipackets != 2 || stats2.opackets != 2 || 409 stats2.ibytes != 0 || stats2.obytes != 0 || 410 stats2.ierrors != 0 || stats2.oerrors != 0) { 411 printf("Error: port %d stats are not as expected\n", 412 rxtx_porte); 413 return TEST_FAILED; 414 } 415 416 ret = rte_eth_dev_stop(rxtx_portd); 417 if (ret != 0) 418 printf("Error: failed to stop port %u: %s\n", 419 rxtx_portd, rte_strerror(-ret)); 420 ret = rte_eth_dev_stop(rxtx_porte); 421 if (ret != 0) 422 printf("Error: failed to stop port %u: %s\n", 423 rxtx_porte, rte_strerror(-ret)); 424 425 return TEST_SUCCESS; 426 } 427 428 static void 429 test_cleanup_resources(void) 430 { 431 int itr, ret; 432 for (itr = 0; itr < NUM_RINGS; itr++) 433 rte_ring_free(rxtx[itr]); 434 435 ret = rte_eth_dev_stop(tx_porta); 436 if (ret != 0) 437 printf("Error: failed to stop port %u: %s\n", 438 tx_porta, rte_strerror(-ret)); 439 ret = rte_eth_dev_stop(rx_portb); 440 if (ret != 0) 441 printf("Error: failed to stop port %u: %s\n", 442 rx_portb, rte_strerror(-ret)); 443 ret = rte_eth_dev_stop(rxtx_portc); 444 if (ret != 0) 445 printf("Error: failed to stop port %u: %s\n", 446 rxtx_portc, rte_strerror(-ret)); 447 448 rte_mempool_free(mp); 449 rte_vdev_uninit("net_ring_net_ringa"); 450 rte_vdev_uninit("net_ring_net_ringb"); 451 rte_vdev_uninit("net_ring_net_ringc"); 452 rte_vdev_uninit("net_ring_net_ringd"); 453 rte_vdev_uninit("net_ring_net_ringe"); 454 } 455 456 static int 457 test_pmd_ringcreate_setup(void) 458 { 459 uint8_t nb_ports; 460 461 nb_ports = rte_eth_dev_count_avail(); 462 printf("nb_ports=%d\n", (int)nb_ports); 463 464 /* create the rings and eth_rings in the test code. 465 * This does not test the rte_pmd_ring_devinit function. 466 * 467 * Test with the command line option --vdev=net_ring0 to test rte_pmd_ring_devinit. 468 */ 469 rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 470 if (rxtx[0] == NULL) { 471 printf("rte_ring_create R0 failed"); 472 return -1; 473 } 474 475 rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 476 if (rxtx[1] == NULL) { 477 printf("rte_ring_create R1 failed"); 478 return -1; 479 } 480 481 tx_porta = rte_eth_from_rings("net_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 482 rx_portb = rte_eth_from_rings("net_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 483 rxtx_portc = rte_eth_from_rings("net_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 484 rxtx_portd = rte_eth_from_rings("net_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 485 rxtx_porte = rte_eth_from_rings("net_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 486 487 printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n", 488 tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte); 489 490 if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1) 491 || (rxtx_portd == -1) || (rxtx_porte == -1)) { 492 printf("rte_eth_from rings failed\n"); 493 return -1; 494 } 495 496 mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, 497 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 498 if (mp == NULL) 499 return -1; 500 501 if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS) 502 || (rxtx_portc >= RTE_MAX_ETHPORTS) 503 || (rxtx_portd >= RTE_MAX_ETHPORTS) 504 || (rxtx_porte >= RTE_MAX_ETHPORTS)) { 505 printf(" port exceed max eth ports\n"); 506 return -1; 507 } 508 return 0; 509 } 510 511 static int 512 test_command_line_ring_port(void) 513 { 514 int port, cmdl_port0 = -1; 515 int ret; 516 517 /* find a port created with the --vdev=net_ring0 command line option */ 518 RTE_ETH_FOREACH_DEV(port) { 519 struct rte_eth_dev_info dev_info; 520 521 ret = rte_eth_dev_info_get(port, &dev_info); 522 TEST_ASSERT((ret == 0), 523 "Error during getting device (port %d) info: %s\n", 524 port, strerror(-ret)); 525 526 if (!strcmp(dev_info.driver_name, "Rings PMD")) { 527 printf("found a command line ring port=%d\n", port); 528 cmdl_port0 = port; 529 break; 530 } 531 } 532 if (cmdl_port0 != -1) { 533 TEST_ASSERT((test_ethdev_configure_port(cmdl_port0) < 0), 534 "test ethdev configure port cmdl_port0 is failed"); 535 TEST_ASSERT((test_send_basic_packets_port(cmdl_port0) < 0), 536 "test send basic packets port cmdl_port0 is failed"); 537 TEST_ASSERT((test_stats_reset(cmdl_port0) < 0), 538 "test stats reset cmdl_port0 is failed"); 539 TEST_ASSERT((test_get_stats(cmdl_port0) < 0), 540 "test get stats cmdl_port0 is failed"); 541 TEST_ASSERT((rte_eth_dev_stop(cmdl_port0) == 0), 542 "test stop cmdl_port0 is failed"); 543 } 544 return TEST_SUCCESS; 545 } 546 547 static int 548 test_ethdev_configure_ports(void) 549 { 550 TEST_ASSERT((test_ethdev_configure_port(tx_porta) == 0), 551 "test ethdev configure ports tx_porta is failed"); 552 TEST_ASSERT((test_ethdev_configure_port(rx_portb) == 0), 553 "test ethdev configure ports rx_portb is failed"); 554 TEST_ASSERT((test_ethdev_configure_port(rxtx_portc) == 0), 555 "test ethdev configure ports rxtx_portc is failed"); 556 557 return TEST_SUCCESS; 558 } 559 560 static int 561 test_get_stats_for_port(void) 562 { 563 TEST_ASSERT(test_get_stats(rxtx_portc) == 0, "test get stats failed"); 564 return TEST_SUCCESS; 565 } 566 567 static int 568 test_stats_reset_for_port(void) 569 { 570 TEST_ASSERT(test_stats_reset(rxtx_portc) == 0, "test stats reset failed"); 571 return TEST_SUCCESS; 572 } 573 574 static struct 575 unit_test_suite test_pmd_ring_suite = { 576 .setup = test_pmd_ringcreate_setup, 577 .teardown = test_cleanup_resources, 578 .suite_name = "Test Pmd Ring Unit Test Suite", 579 .unit_test_cases = { 580 TEST_CASE(test_ethdev_configure_ports), 581 TEST_CASE(test_send_basic_packets), 582 TEST_CASE(test_get_stats_for_port), 583 TEST_CASE(test_stats_reset_for_port), 584 TEST_CASE(test_pmd_ring_pair_create_attach), 585 TEST_CASE(test_command_line_ring_port), 586 TEST_CASES_END() 587 } 588 }; 589 590 static int 591 test_pmd_ring(void) 592 { 593 return unit_test_suite_runner(&test_pmd_ring_suite); 594 } 595 596 REGISTER_FAST_TEST(ring_pmd_autotest, true, true, test_pmd_ring); 597