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