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 229 memset(&null_conf, 0, sizeof(struct rte_eth_conf)); 230 231 if ((rte_eth_dev_configure(rxtx_portd, 1, 1, &null_conf) < 0) 232 || (rte_eth_dev_configure(rxtx_porte, 1, 1, 233 &null_conf) < 0)) { 234 printf("Configure failed for port\n"); 235 return TEST_FAILED; 236 } 237 238 if ((rte_eth_tx_queue_setup(rxtx_portd, 0, RING_SIZE, 239 SOCKET0, NULL) < 0) 240 || (rte_eth_tx_queue_setup(rxtx_porte, 0, RING_SIZE, 241 SOCKET0, NULL) < 0)) { 242 printf("TX queue setup failed\n"); 243 return TEST_FAILED; 244 } 245 246 if ((rte_eth_rx_queue_setup(rxtx_portd, 0, RING_SIZE, 247 SOCKET0, NULL, mp) < 0) 248 || (rte_eth_rx_queue_setup(rxtx_porte, 0, RING_SIZE, 249 SOCKET0, NULL, mp) < 0)) { 250 printf("RX queue setup failed\n"); 251 return TEST_FAILED; 252 } 253 254 if ((rte_eth_dev_start(rxtx_portd) < 0) 255 || (rte_eth_dev_start(rxtx_porte) < 0)) { 256 printf("Error starting port\n"); 257 return TEST_FAILED; 258 } 259 260 rte_eth_stats_reset(rxtx_portd); 261 /* check stats of port, should all be zero */ 262 rte_eth_stats_get(rxtx_portd, &stats); 263 if (stats.ipackets != 0 || stats.opackets != 0 || 264 stats.ibytes != 0 || stats.obytes != 0 || 265 stats.ierrors != 0 || stats.oerrors != 0) { 266 printf("Error: port %d stats are not zero\n", rxtx_portd); 267 return TEST_FAILED; 268 } 269 270 rte_eth_stats_reset(rxtx_porte); 271 /* check stats of port, should all be zero */ 272 rte_eth_stats_get(rxtx_porte, &stats2); 273 if (stats2.ipackets != 0 || stats2.opackets != 0 || 274 stats2.ibytes != 0 || stats2.obytes != 0 || 275 stats2.ierrors != 0 || stats2.oerrors != 0) { 276 printf("Error: port %d stats are not zero\n", rxtx_porte); 277 return TEST_FAILED; 278 } 279 280 /* 281 * send and receive 1 packet (rxtx_portd -> rxtx_porte) 282 * and check for stats update 283 */ 284 printf("Testing send and receive 1 packet (rxtx_portd -> rxtx_porte)\n"); 285 if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 286 printf("Error sending packet to port %d\n", rxtx_portd); 287 return TEST_FAILED; 288 } 289 290 if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 291 printf("Error receiving packet from port %d\n", rxtx_porte); 292 return TEST_FAILED; 293 } 294 295 rte_eth_stats_get(rxtx_portd, &stats); 296 rte_eth_stats_get(rxtx_porte, &stats2); 297 if (stats.ipackets != 0 || stats.opackets != 1 || 298 stats.ibytes != 0 || stats.obytes != 0 || 299 stats.ierrors != 0 || stats.oerrors != 0) { 300 printf("Error: port %d stats are not as expected\n", 301 rxtx_portd); 302 return TEST_FAILED; 303 } 304 305 if (stats2.ipackets != 1 || stats2.opackets != 0 || 306 stats2.ibytes != 0 || stats2.obytes != 0 || 307 stats2.ierrors != 0 || stats2.oerrors != 0) { 308 printf("Error: port %d stats are not as expected\n", 309 rxtx_porte); 310 return TEST_FAILED; 311 } 312 313 /* 314 * send and receive 1 packet (rxtx_porte -> rxtx_portd) 315 * and check for stats update 316 */ 317 printf("Testing send and receive 1 packet " 318 "(rxtx_porte -> rxtx_portd)\n"); 319 if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 320 printf("Error sending packet to port %d\n", rxtx_porte); 321 return TEST_FAILED; 322 } 323 324 if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 325 printf("Error receiving packet from port %d\n", rxtx_portd); 326 return TEST_FAILED; 327 } 328 329 rte_eth_stats_get(rxtx_portd, &stats); 330 rte_eth_stats_get(rxtx_porte, &stats2); 331 if (stats.ipackets != 1 || stats.opackets != 1 || 332 stats.ibytes != 0 || stats.obytes != 0 || 333 stats.ierrors != 0 || stats.oerrors != 0) { 334 printf("Error: port %d stats are not as expected\n", 335 rxtx_portd); 336 return TEST_FAILED; 337 } 338 339 if (stats2.ipackets != 1 || stats2.opackets != 1 || 340 stats2.ibytes != 0 || stats2.obytes != 0 || 341 stats2.ierrors != 0 || stats2.oerrors != 0) { 342 printf("Error: port %d stats are not as expected\n", 343 rxtx_porte); 344 return TEST_FAILED; 345 } 346 347 /* 348 * send and receive 1 packet (rxtx_portd -> rxtx_portd) 349 * and check for stats update 350 */ 351 printf("Testing send and receive 1 packet " 352 "(rxtx_portd -> rxtx_portd)\n"); 353 if (rte_eth_tx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 354 printf("Error sending packet to port %d\n", rxtx_portd); 355 return TEST_FAILED; 356 } 357 358 if (rte_eth_rx_burst(rxtx_portd, 0, &pbuf, 1) != 1) { 359 printf("Error receiving packet from port %d\n", rxtx_porte); 360 return TEST_FAILED; 361 } 362 363 rte_eth_stats_get(rxtx_portd, &stats); 364 rte_eth_stats_get(rxtx_porte, &stats2); 365 if (stats.ipackets != 2 || stats.opackets != 2 || 366 stats.ibytes != 0 || stats.obytes != 0 || 367 stats.ierrors != 0 || stats.oerrors != 0) { 368 printf("Error: port %d stats are not as expected\n", 369 rxtx_portd); 370 return TEST_FAILED; 371 } 372 373 if (stats2.ipackets != 1 || stats2.opackets != 1 || 374 stats2.ibytes != 0 || stats2.obytes != 0 || 375 stats2.ierrors != 0 || stats2.oerrors != 0) { 376 printf("Error: port %d stats are not as expected\n", 377 rxtx_porte); 378 return TEST_FAILED; 379 } 380 381 /* 382 * send and receive 1 packet (rxtx_porte -> rxtx_porte) 383 * and check for stats update 384 */ 385 printf("Testing send and receive 1 packet " 386 "(rxtx_porte -> rxtx_porte)\n"); 387 if (rte_eth_tx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 388 printf("Error sending packet to port %d\n", rxtx_porte); 389 return TEST_FAILED; 390 } 391 392 if (rte_eth_rx_burst(rxtx_porte, 0, &pbuf, 1) != 1) { 393 printf("Error receiving packet from port %d\n", rxtx_porte); 394 return TEST_FAILED; 395 } 396 397 rte_eth_stats_get(rxtx_portd, &stats); 398 rte_eth_stats_get(rxtx_porte, &stats2); 399 if (stats.ipackets != 2 || stats.opackets != 2 || 400 stats.ibytes != 0 || stats.obytes != 0 || 401 stats.ierrors != 0 || stats.oerrors != 0) { 402 printf("Error: port %d stats are not as expected\n", 403 rxtx_portd); 404 return TEST_FAILED; 405 } 406 407 if (stats2.ipackets != 2 || stats2.opackets != 2 || 408 stats2.ibytes != 0 || stats2.obytes != 0 || 409 stats2.ierrors != 0 || stats2.oerrors != 0) { 410 printf("Error: port %d stats are not as expected\n", 411 rxtx_porte); 412 return TEST_FAILED; 413 } 414 415 rte_eth_dev_stop(rxtx_portd); 416 rte_eth_dev_stop(rxtx_porte); 417 418 return TEST_SUCCESS; 419 } 420 421 static void 422 test_cleanup_resources(void) 423 { 424 int itr; 425 for (itr = 0; itr < NUM_RINGS; itr++) 426 rte_ring_free(rxtx[itr]); 427 428 rte_eth_dev_stop(tx_porta); 429 rte_eth_dev_stop(rx_portb); 430 rte_eth_dev_stop(rxtx_portc); 431 432 rte_mempool_free(mp); 433 rte_vdev_uninit("net_ring_net_ringa"); 434 rte_vdev_uninit("net_ring_net_ringb"); 435 rte_vdev_uninit("net_ring_net_ringc"); 436 rte_vdev_uninit("net_ring_net_ringd"); 437 rte_vdev_uninit("net_ring_net_ringe"); 438 } 439 440 static int 441 test_pmd_ringcreate_setup(void) 442 { 443 uint8_t nb_ports; 444 445 nb_ports = rte_eth_dev_count_avail(); 446 printf("nb_ports=%d\n", (int)nb_ports); 447 448 /* create the rings and eth_rings in the test code. 449 * This does not test the rte_pmd_ring_devinit function. 450 * 451 * Test with the command line option --vdev=net_ring0 to test rte_pmd_ring_devinit. 452 */ 453 rxtx[0] = rte_ring_create("R0", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 454 if (rxtx[0] == NULL) { 455 printf("rte_ring_create R0 failed"); 456 return -1; 457 } 458 459 rxtx[1] = rte_ring_create("R1", RING_SIZE, SOCKET0, RING_F_SP_ENQ|RING_F_SC_DEQ); 460 if (rxtx[1] == NULL) { 461 printf("rte_ring_create R1 failed"); 462 return -1; 463 } 464 465 tx_porta = rte_eth_from_rings("net_ringa", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 466 rx_portb = rte_eth_from_rings("net_ringb", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 467 rxtx_portc = rte_eth_from_rings("net_ringc", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 468 rxtx_portd = rte_eth_from_rings("net_ringd", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 469 rxtx_porte = rte_eth_from_rings("net_ringe", rxtx, NUM_RINGS, rxtx, NUM_RINGS, SOCKET0); 470 471 printf("tx_porta=%d rx_portb=%d rxtx_portc=%d rxtx_portd=%d rxtx_porte=%d\n", 472 tx_porta, rx_portb, rxtx_portc, rxtx_portd, rxtx_porte); 473 474 if ((tx_porta == -1) || (rx_portb == -1) || (rxtx_portc == -1) 475 || (rxtx_portd == -1) || (rxtx_porte == -1)) { 476 printf("rte_eth_from rings failed\n"); 477 return -1; 478 } 479 480 mp = rte_pktmbuf_pool_create("mbuf_pool", NB_MBUF, 32, 481 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); 482 if (mp == NULL) 483 return -1; 484 485 if ((tx_porta >= RTE_MAX_ETHPORTS) || (rx_portb >= RTE_MAX_ETHPORTS) 486 || (rxtx_portc >= RTE_MAX_ETHPORTS) 487 || (rxtx_portd >= RTE_MAX_ETHPORTS) 488 || (rxtx_porte >= RTE_MAX_ETHPORTS)) { 489 printf(" port exceed max eth ports\n"); 490 return -1; 491 } 492 return 0; 493 } 494 495 static int 496 test_command_line_ring_port(void) 497 { 498 int port, cmdl_port0 = -1; 499 int ret; 500 501 /* find a port created with the --vdev=net_ring0 command line option */ 502 RTE_ETH_FOREACH_DEV(port) { 503 struct rte_eth_dev_info dev_info; 504 505 ret = rte_eth_dev_info_get(port, &dev_info); 506 TEST_ASSERT((ret == 0), 507 "Error during getting device (port %d) info: %s\n", 508 port, strerror(-ret)); 509 510 if (!strcmp(dev_info.driver_name, "Rings PMD")) { 511 printf("found a command line ring port=%d\n", port); 512 cmdl_port0 = port; 513 break; 514 } 515 } 516 if (cmdl_port0 != -1) { 517 TEST_ASSERT((test_ethdev_configure_port(cmdl_port0) < 0), 518 "test ethdev configure port cmdl_port0 is failed"); 519 TEST_ASSERT((test_send_basic_packets_port(cmdl_port0) < 0), 520 "test send basic packets port cmdl_port0 is failed"); 521 TEST_ASSERT((test_stats_reset(cmdl_port0) < 0), 522 "test stats reset cmdl_port0 is failed"); 523 TEST_ASSERT((test_get_stats(cmdl_port0) < 0), 524 "test get stats cmdl_port0 is failed"); 525 rte_eth_dev_stop(cmdl_port0); 526 } 527 return TEST_SUCCESS; 528 } 529 530 static int 531 test_ethdev_configure_ports(void) 532 { 533 TEST_ASSERT((test_ethdev_configure_port(tx_porta) == 0), 534 "test ethdev configure ports tx_porta is failed"); 535 TEST_ASSERT((test_ethdev_configure_port(rx_portb) == 0), 536 "test ethdev configure ports rx_portb is failed"); 537 TEST_ASSERT((test_ethdev_configure_port(rxtx_portc) == 0), 538 "test ethdev configure ports rxtx_portc is failed"); 539 540 return TEST_SUCCESS; 541 } 542 543 static int 544 test_get_stats_for_port(void) 545 { 546 TEST_ASSERT(test_get_stats(rxtx_portc) == 0, "test get stats failed"); 547 return TEST_SUCCESS; 548 } 549 550 static int 551 test_stats_reset_for_port(void) 552 { 553 TEST_ASSERT(test_stats_reset(rxtx_portc) == 0, "test stats reset failed"); 554 return TEST_SUCCESS; 555 } 556 557 static struct 558 unit_test_suite test_pmd_ring_suite = { 559 .setup = test_pmd_ringcreate_setup, 560 .teardown = test_cleanup_resources, 561 .suite_name = "Test Pmd Ring Unit Test Suite", 562 .unit_test_cases = { 563 TEST_CASE(test_ethdev_configure_ports), 564 TEST_CASE(test_send_basic_packets), 565 TEST_CASE(test_get_stats_for_port), 566 TEST_CASE(test_stats_reset_for_port), 567 TEST_CASE(test_pmd_ring_pair_create_attach), 568 TEST_CASE(test_command_line_ring_port), 569 TEST_CASES_END() 570 } 571 }; 572 573 static int 574 test_pmd_ring(void) 575 { 576 return unit_test_suite_runner(&test_pmd_ring_suite); 577 } 578 579 REGISTER_TEST_COMMAND(ring_pmd_autotest, test_pmd_ring); 580