pktspeed.c (21625B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: pktspeed.c 8 * Purpose: Run a TX or RX reload test to check DMA speed 9 * 10 * Test Parameters: 11 * PORT - TX port 12 * RXPORT - RX port 13 * PKTsize - What size packets to use 14 * ALLOCsize - What allocation size to use for packets 15 * ChainLen - How many DMA'd packets to set up in loop 16 * Seconds - How many seconds to run 17 * 18 * Test reports speed once per second. 19 * 20 * Notes: Code originally from appl/diag/txrx.c 21 * Moved here to address PR SDK/422 22 */ 23 24 #include <sal/core/time.h> 25 #include <sal/types.h> 26 #include <sal/appl/io.h> 27 #include <shared/bsl.h> 28 #include <soc/types.h> 29 #include <soc/cm.h> 30 #include <soc/dma.h> 31 #include <soc/dcb.h> 32 #include <soc/drv.h> 33 34 #include <bcm/tx.h> 35 #include <bcm/pkt.h> 36 #include <bcm/rx.h> 37 #include <bcm/port.h> 38 #include <bcm/cosq.h> 39 #include <bcm/error.h> 40 41 #ifdef BCM_CMICM_SUPPORT 42 #include <soc/cmicm.h> 43 #endif 44 45 #include "testlist.h" 46 47 #if defined (BCM_PETRA_SUPPORT) 48 #include <soc/dpp/drv.h> 49 #else 50 #define SOC_DPP_PP_ENABLE(unit) (0) 51 #endif 52 53 #if defined (BCM_ESW_SUPPORT) || defined (BCM_PETRA_SUPPORT) 54 55 #define TEST_FAIL -1 56 #define TEST_OK 0 57 58 typedef struct pktspeed_param_s { 59 int unit, /* Which unit to test on */ 60 tx_port, /* packet TX port (TX/RX test) */ 61 rx_port, /* packet RX port (RX test) */ 62 tx_packet_count, /* tx packet count (RX test) */ 63 pkt_size, /* Size of actual pkt */ 64 alloc_size, /* Allocation size of packet */ 65 chain_len, /* Number of pkts to set up per cycle */ 66 seconds, /* Number of seconds to run */ 67 poll; /* T=poll F=interrupt */ 68 int p_l_start; /* first pkt length for iteration*/ 69 int p_l_end; /* last pkt length for iteration */ 70 int p_l_inc; /* pkt length increment between iterations */ 71 volatile COMPILER_DOUBLE count; /* Packet count */ 72 } pktspeed_param_t; 73 74 static volatile int desc_intr_count = 0; 75 static volatile int chain_intr_count = 0; 76 77 static pktspeed_param_t *pktspeed_param[SOC_MAX_NUM_DEVICES]; 78 79 /* 80 * Function: 81 * pktspeed_print_param 82 * 83 * Purpose: 84 * Print parameter structure 85 * 86 * Parameters: 87 * psp - parameter structure 88 * 89 * Returns: 90 * Allocated structure or NULL if alloc failed. 91 */ 92 93 STATIC void 94 pktspeed_print_param(pktspeed_param_t *psp) 95 { 96 if (psp != NULL) { 97 cli_out("port=%d ", psp->tx_port); 98 cli_out("rx=%d ", psp->rx_port); 99 cli_out("pkt=%d ", psp->pkt_size); 100 cli_out("alloc=%d ", psp->alloc_size); 101 cli_out("cl=%d ", psp->chain_len); 102 cli_out("sec=%d ", psp->seconds); 103 cli_out("\n"); 104 } else { 105 cli_out("psp(null)\n"); 106 } 107 } 108 109 /* 110 * Function: 111 * pktspeed_print_report 112 * 113 * Purpose: 114 * Print speed report 115 * 116 * Parameters: 117 * psp - parameter structure 118 * t_diff - time difference (usec) 119 * 120 * Returns: 121 * void 122 */ 123 124 STATIC void 125 pktspeed_print_report(pktspeed_param_t *psp, COMPILER_DOUBLE count, int t_diff) 126 { 127 COMPILER_DOUBLE bytes_per_second, pkts_per_second; 128 COMPILER_DOUBLE t_diff_dbl, pkt_size_dbl; 129 130 if (psp != NULL) { 131 COMPILER_32_TO_DOUBLE(t_diff_dbl, t_diff); 132 COMPILER_32_TO_DOUBLE(pkt_size_dbl, psp->pkt_size); 133 pkts_per_second = count/t_diff_dbl; 134 bytes_per_second = (count * pkt_size_dbl)/t_diff_dbl; 135 cli_out(" %15" COMPILER_DOUBLE_FORMAT 136 " %15" COMPILER_DOUBLE_FORMAT 137 " %15" COMPILER_DOUBLE_FORMAT "\n", 138 count, pkts_per_second, bytes_per_second); 139 } else { 140 cli_out("psp(null)\n"); 141 } 142 } 143 144 /* 145 * Function: 146 * pktspeed_done_desc 147 * 148 * Purpose: 149 * dv_done_desc callout increments packet count in interrupt context 150 * 151 * Parameters: 152 * u - unit 153 * dv - dv struct 154 * dcb - dcp struct 155 * 156 * Returns: 157 * void 158 */ 159 160 STATIC void 161 pktspeed_done_desc(int u, struct dv_s *dv, dcb_t *dcb) 162 { 163 pktspeed_param_t *psp = (pktspeed_param_t *)dv->dv_public1.ptr; 164 165 psp->count += psp->chain_len; 166 167 desc_intr_count += 1; 168 } 169 170 STATIC void 171 pktspeed_done_chain(int unit, dv_t *dv_chain) 172 { 173 chain_intr_count += 1; 174 } 175 176 /* 177 * Function: 178 * pktspeed_run_test 179 * 180 * Purpose: 181 * Run actual pktspeed test 182 * 183 * Parameters: 184 * tx_test - TRUE for TX test, FALSE for RX test 185 * psp - test parameters 186 * 187 * Returns: 188 * TEST_OK 189 * TEST_FAIL 190 * 191 * Notes: 192 * Could possibly use a pause scheme at the end of the while loop. 193 */ 194 195 STATIC int 196 pktspeed_run_test(int tx_test, pktspeed_param_t *psp) 197 { 198 pbmp_t tx_pbm; 199 static pbmp_t empty_pbm; /* Initialized to 0 automatically */ 200 char *pkt_data = NULL; 201 dv_t *dv = NULL; 202 sal_usecs_t start_time, cur_time; 203 COMPILER_DOUBLE count; 204 int t_diff, last_rpt; 205 int tot_dcb; 206 int i; 207 int rv = TEST_OK; 208 int rv2 = TEST_OK; 209 dcb_t *d; 210 int channel; 211 bcm_pkt_t *pkt = NULL; 212 bcm_vlan_t tx_vlan = 0x123; 213 bcm_pbmp_t pbmp; 214 bcm_pbmp_t ubmp; 215 bcm_gport_t sch_gport; 216 bcm_gport_t egq_gport; 217 static sal_mac_addr_t mac_dest = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 218 static sal_mac_addr_t mac_src = {0x02, 0x11, 0x22, 0x33, 0x44, 0x66}; 219 220 if (psp == NULL) { 221 cli_out("pktspeed test: NULL param struct\n"); 222 return(TEST_FAIL); 223 } 224 225 COMPILER_32_TO_DOUBLE(count, 0); 226 227 BCM_PBMP_CLEAR(pbmp); 228 BCM_PBMP_CLEAR(ubmp); 229 230 if (tx_test) { 231 232 rv = bcm_port_enable_set(psp->unit, psp->tx_port, TRUE); 233 if (rv != TEST_OK ) { 234 goto done; 235 } 236 SOC_PBMP_PORT_SET(tx_pbm, psp->tx_port); 237 channel = 0; 238 if (soc_dma_chan_config(psp->unit, channel, DV_TX, SOC_DMA_F_DEFAULT) < 0) { 239 cli_out("pktspeed test: Could not configure u %d, chan %d\n", 240 psp->unit, 241 channel); 242 rv = TEST_FAIL; 243 goto done; 244 } 245 } else { /* Set ports to loopback and send a broadcast packet */ 246 rv = bcm_port_loopback_set(psp->unit, psp->tx_port, BCM_PORT_LOOPBACK_MAC); 247 if (rv != TEST_OK ) { 248 goto done; 249 } 250 rv = bcm_port_loopback_set(psp->unit, psp->rx_port, BCM_PORT_LOOPBACK_MAC); 251 if (rv != TEST_OK ) { 252 goto done; 253 } 254 rv = bcm_port_enable_set(psp->unit, psp->tx_port, TRUE); 255 if (rv != TEST_OK ) { 256 goto done; 257 } 258 rv = bcm_port_enable_set(psp->unit, psp->rx_port, TRUE); 259 if (rv != TEST_OK ) { 260 goto done; 261 } 262 if ((bcm_pkt_alloc(psp->unit, 263 psp->pkt_size, 264 BCM_TX_CRC_REGEN, &pkt)) != 265 BCM_E_NONE) { 266 cli_out("Could not allocate packet to tx\n"); 267 return TEST_FAIL; 268 } 269 /* Set up broadcast packet */ 270 if (!SOC_IS_ARAD(psp->unit) || !SOC_DPP_PP_ENABLE(psp->unit)) { 271 BCM_PKT_HDR_DMAC_SET(pkt, mac_dest); 272 BCM_PKT_HDR_SMAC_SET(pkt, mac_src); 273 BCM_PKT_HDR_TPID_SET(pkt, ENET_DEFAULT_TPID); 274 BCM_PKT_HDR_VTAG_CONTROL_SET(pkt, VLAN_CTRL(0, 0, 1)); 275 } else { 276 /* Add the rx_port, rx_port and cpu port to the broadcast vlan domain */ 277 rv = bcm_vlan_create(psp->unit, tx_vlan); 278 if (rv != TEST_OK ) { 279 goto done; 280 } 281 BCM_PBMP_PORT_ADD(pbmp, psp->tx_port); 282 BCM_PBMP_PORT_ADD(pbmp, psp->rx_port); 283 BCM_PBMP_PORT_ADD(pbmp, 0); 284 rv = bcm_vlan_port_add(psp->unit, tx_vlan, pbmp, ubmp); 285 if (rv != TEST_OK ) { 286 goto done; 287 } 288 /* Add the PTCH header */ 289 (pkt)->_pkt_data.data[0] = 0xD0; 290 (pkt)->_pkt_data.data[1] = psp->tx_port; 291 /* Add the Ethernet packet */ 292 sal_memcpy((pkt)->_pkt_data.data + 2, mac_dest, 6); 293 sal_memcpy((pkt)->_pkt_data.data + 8, mac_src, 6); 294 _BCM_HTONS_CVT_SET(pkt, ENET_DEFAULT_TPID, 14); 295 _BCM_HTONS_CVT_SET(pkt, VLAN_CTRL(0, 0, tx_vlan), 16); 296 /* Configure the CPU sch and egq scheduler as the rate of 1G bps */ 297 BCM_COSQ_GPORT_E2E_PORT_SET(sch_gport, 0); 298 rv = bcm_cosq_gport_bandwidth_set(psp->unit, sch_gport, 0, 0, 10000000, 0); 299 if (rv != TEST_OK ) { 300 goto done; 301 } 302 BCM_GPORT_LOCAL_SET(egq_gport, 0); 303 rv = bcm_cosq_gport_bandwidth_set(psp->unit, egq_gport, 0, 0, 10000000, 0); 304 if (rv != TEST_OK ) { 305 goto done; 306 } 307 } 308 SOC_PBMP_PORT_SET(pkt->tx_pbmp, psp->tx_port); 309 pkt->opcode = BCM_HG_OPCODE_BC; 310 311 channel = 1; 312 if (DV_RX != soc_dma_chan_dvt_get(psp->unit, channel)) { 313 if (soc_dma_chan_config(psp->unit, channel, DV_RX, 0) < 0) { 314 cli_out("pktspeed test: Could not configure u %d, chan %d\n", 315 psp->unit, 316 channel); 317 rv = TEST_FAIL; 318 goto done; 319 } 320 } 321 bcm_rx_queue_channel_set(psp->unit, -1, 1); 322 323 { 324 int i; 325 for (i=0; i< psp->tx_packet_count; i++) { 326 /* Send broadcast packet */ 327 if (bcm_tx(psp->unit, pkt, NULL) != BCM_E_NONE) { 328 cli_out("Failed to transmit packet\n"); 329 return TEST_FAIL; 330 } 331 } 332 } 333 334 } 335 336 tot_dcb = psp->chain_len + 1; /* Need one for reload */ 337 338 /* Round packet size up to 8 byte boundary */ 339 psp->alloc_size = (psp->alloc_size + 7) & 0xffffff8; 340 341 if ((pkt_data = soc_cm_salloc(psp->unit, psp->alloc_size * psp->chain_len, 342 "reload_data")) == NULL) { 343 cli_out("Could not allocate packet data\n"); 344 rv = TEST_FAIL; 345 goto done; 346 } 347 348 if ((dv = soc_dma_dv_alloc(psp->unit, tx_test ? DV_TX : DV_RX, 349 tot_dcb)) == NULL) { 350 cli_out("Could not allocate DV\n"); 351 rv = TEST_FAIL; 352 goto done; 353 } 354 355 /* DCBs MUST start off 0 */ 356 sal_memset(dv->dv_dcb, 0, SOC_DCB_SIZE(psp->unit) * tot_dcb); 357 358 for (i = 0; i < psp->chain_len; i++) { 359 if (soc_dma_desc_add(dv, (sal_vaddr_t)&pkt_data[i * psp->alloc_size], 360 psp->alloc_size, tx_pbm, empty_pbm, 361 empty_pbm, 0, NULL) < 0) { 362 cli_out("Could not setup packet %d\n", i); 363 rv = TEST_FAIL; 364 goto done; 365 } 366 soc_dma_desc_end_packet(dv); 367 } 368 369 /* Set reload bit of last descriptor to point to first */ 370 if (soc_dma_rld_desc_add(dv, (sal_vaddr_t)dv->dv_dcb) < 0) { 371 cli_out("Could not setup reload dcb\n"); 372 rv = TEST_FAIL; 373 goto done; 374 } 375 376 d = SOC_DCB_IDX2PTR(psp->unit, dv->dv_dcb, dv->dv_vcnt - 1); 377 SOC_DCB_CHAIN_SET(psp->unit, d, 1); 378 379 /* Disable DMA interrupts - prevent soc_start_dma() from choking */ 380 #ifdef BCM_CMICM_SUPPORT 381 if(soc_feature(psp->unit, soc_feature_cmicm)) { 382 (void)soc_cmicm_intr0_disable(psp->unit, 383 IRQ_CMCx_DESC_DONE(channel) | IRQ_CMCx_CHAIN_DONE(channel)); 384 } else 385 #endif 386 { 387 soc_intr_disable(psp->unit, 388 IRQ_DESC_DONE(channel) | IRQ_CHAIN_DONE(channel)); 389 } 390 if (!psp->poll) { 391 /* Setup callout if interrupt */ 392 dv->dv_done_desc = pktspeed_done_desc; 393 dv->dv_done_chain = pktspeed_done_chain; 394 dv->dv_public1.ptr = (void *)psp; 395 dv->dv_flags |= DV_F_NOTIFY_DSC | DV_F_NOTIFY_CHN; 396 } 397 398 cur_time = start_time = sal_time_usecs(); 399 t_diff = 0; 400 last_rpt = 0; 401 count = psp->count = 0; 402 403 /* Start DMA */ 404 if (soc_dma_start(psp->unit, channel, dv) < 0) { 405 cli_out("pktspeed test: Could not start dv, u %d, chan %d\n", 406 psp->unit, channel); 407 rv = TEST_FAIL; 408 goto done; 409 } 410 411 cli_out("Starting %s reload test:\n", 412 tx_test ? "TX" : "RX"); 413 pktspeed_print_param(psp); 414 cli_out(" %15s %15s %15s\n", 415 "Total Pkts", "Pkts/Second", "Bytes/Second"); 416 while (t_diff <= psp->seconds) { 417 if (psp->poll) { 418 /* Monitor done bit in last real dcb */ 419 soc_cm_sinval(psp->unit, d, SOC_DCB_SIZE(psp->unit)); 420 if (SOC_DCB_DONE_GET(psp->unit, d)) { 421 psp->count += psp->chain_len; 422 count = psp->count; 423 SOC_DCB_DONE_SET(psp->unit, d, 0); 424 soc_cm_sflush(psp->unit, d, SOC_DCB_SIZE(psp->unit)); 425 } 426 } else { 427 sal_sleep(1); 428 count = psp->count; 429 } 430 /* Report every second */ 431 if (t_diff >= last_rpt + 1) { 432 last_rpt = t_diff; 433 pktspeed_print_report(psp, count, t_diff); 434 } 435 cur_time = sal_time_usecs(); 436 t_diff = SAL_USECS_SUB(cur_time, start_time)/1000000; 437 } 438 439 done: 440 if (SOC_IS_ARAD(psp->unit) && !tx_test) { 441 bcm_vlan_port_remove(psp->unit, tx_vlan, pbmp); 442 bcm_vlan_destroy(psp->unit, tx_vlan); 443 } 444 rv2 = bcm_port_loopback_set(psp->unit, psp->tx_port, BCM_PORT_LOOPBACK_NONE); 445 if (rv2 != TEST_OK ) { 446 cli_out("Re tx port loopback failed\n"); 447 } 448 if (!tx_test) { 449 rv2= bcm_port_loopback_set(psp->unit, psp->rx_port, 450 BCM_PORT_LOOPBACK_NONE); 451 if (rv2 != TEST_OK ) { 452 cli_out("Disable rx port loopback failed\n"); 453 } 454 } 455 456 if (dv) { 457 soc_dma_abort_dv(psp->unit, dv); 458 soc_dma_dv_free(psp->unit, dv); 459 } 460 if (pkt_data) { 461 soc_cm_sfree(psp->unit, pkt_data); 462 } 463 if (pkt) { 464 bcm_pkt_free(psp->unit, pkt); 465 } 466 467 468 469 return rv; 470 } 471 472 /* 473 * Function: 474 * pktspeed_alloc 475 * 476 * Purpose: 477 * Allocate and initialize test parameter structure 478 * 479 * Parameters: 480 * unit - Unit these parameters are for 481 * 482 * Returns: 483 * Allocated structure or NULL if alloc failed. 484 */ 485 486 STATIC pktspeed_param_t * 487 pktspeed_alloc(int unit) 488 { 489 bcm_port_t port = 0; 490 pktspeed_param_t *psp = 491 (pktspeed_param_t *)sal_alloc(sizeof(pktspeed_param_t), 492 "Pktspeed test config"); 493 494 if (psp != NULL) { 495 psp->unit = unit; 496 if(SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) { 497 psp->tx_port = 30; 498 } else if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) { 499 psp->tx_port = 2; 500 } else if (SOC_IS_KATANA(unit) || SOC_IS_GREYHOUND(unit)) { 501 BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port) { 502 break; 503 } 504 psp->tx_port = port; 505 } else if (SOC_IS_ARAD(unit)) { 506 psp->tx_port = 13; 507 } else { 508 psp->tx_port = 1; 509 } 510 psp->rx_port = -1; /* Select automatically */ 511 if (!SOC_IS_ARAD(psp->unit)) { 512 psp->tx_packet_count = 100; 513 } else { 514 psp->tx_packet_count = 1; 515 } 516 psp->pkt_size = 68; 517 psp->alloc_size = 68; 518 psp->chain_len = 1000; 519 psp->seconds = 10; 520 psp->poll = TRUE; 521 COMPILER_32_TO_DOUBLE(psp->count, 0); 522 psp->p_l_start = 0; /* 0 means no iteration */ 523 psp->p_l_end = 0; 524 psp->p_l_inc = 64; 525 } 526 return psp; 527 } 528 529 /* 530 * Function: 531 * pktspeed_free 532 * 533 * Purpose: 534 * Free test parameter structure 535 * 536 * Parameters: 537 * psp - parameter structure pointer 538 * 539 * Returns: 540 * TEST_OK 541 * TEST_FAIL 542 */ 543 544 STATIC int pktspeed_free(pktspeed_param_t *psp) 545 { 546 int rv = TEST_FAIL; 547 548 if (!psp) { 549 return rv; 550 } 551 sal_free(psp); 552 553 return TEST_OK; 554 } 555 556 /* 557 * Function: 558 * pktspeed_test_init 559 * 560 * Purpose: 561 * Parse test arguments and save parameter structure locally 562 * 563 * Parameters: 564 * unit - unit to test 565 * args - test arguments 566 * pa - test cookie (not used) 567 * 568 * Returns: 569 * TEST_OK 570 * TEST_FAIL 571 */ 572 573 int 574 pktspeed_test_init(int unit, args_t *args, void **pa) 575 { 576 parse_table_t pt; 577 pktspeed_param_t *psp = pktspeed_alloc(unit); 578 579 if (psp == NULL) { 580 cli_out("%s: out of memory\n", ARG_CMD(args)); 581 return(TEST_FAIL); 582 } 583 584 parse_table_init(unit, &pt); 585 586 parse_table_add(&pt, "PORT", PQ_DFL|PQ_PORT, 0, 587 &psp->tx_port, NULL); 588 parse_table_add(&pt, "RXport", PQ_DFL|PQ_PORT, 0, 589 &psp->rx_port, NULL); 590 parse_table_add(&pt, "TxPktCount", PQ_DFL|PQ_INT, 0, 591 &psp->tx_packet_count, NULL); 592 parse_table_add(&pt, "PKTsize", PQ_DFL|PQ_INT, 0, 593 &psp->pkt_size, NULL); 594 parse_table_add(&pt, "ALLOCsize", PQ_DFL|PQ_INT, 0, 595 &psp->alloc_size, NULL); 596 parse_table_add(&pt, "ChainLen", PQ_DFL|PQ_INT, 0, 597 &psp->chain_len, NULL); 598 parse_table_add(&pt, "SEConds", PQ_DFL|PQ_INT, 0, 599 &psp->seconds, NULL); 600 parse_table_add(&pt, "LengthStart", PQ_DFL|PQ_INT, 0, 601 &psp->p_l_start, NULL); 602 parse_table_add(&pt, "LengthEnd", PQ_DFL|PQ_INT, 0, 603 &psp->p_l_end, NULL); 604 parse_table_add(&pt, "LengthInc", PQ_DFL|PQ_INT, 0, 605 &psp->p_l_inc, NULL); 606 607 /* Parse remaining arguments */ 608 if (0 > parse_arg_eq(args, &pt)) { 609 test_error(unit, 610 "%s: Invalid option: %s\n", 611 ARG_CMD(args), 612 ARG_CUR(args) ? ARG_CUR(args) : "*"); 613 parse_arg_eq_done(&pt); 614 goto fail; 615 } 616 parse_arg_eq_done(&pt); 617 618 if (psp->pkt_size > psp->alloc_size) { 619 test_error(unit, 620 "%s: Error: packet size > alloc size\n", 621 ARG_CMD(args)); 622 parse_arg_eq_done(&pt); 623 goto fail; 624 } 625 parse_arg_eq_done(&pt); 626 627 if (psp->rx_port < 0) { /* Find an unused port */ 628 int p; 629 630 /* Find first available port != tx_port */ 631 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 632 if (p != psp->tx_port) { 633 psp->rx_port = p; 634 break; 635 } 636 } 637 638 /* Check to see if one was found */ 639 if (psp->rx_port < 0) { 640 test_error(unit, 641 "%s: Could not find an available RX port.\n", 642 ARG_CMD(args)); 643 goto fail; 644 } 645 646 } else { /* RX port specified */ 647 648 /* Make sure selected RX port is valid */ 649 if (!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), psp->rx_port)) { 650 test_error(unit, 651 "%s: Invalid RX port %d.\n", 652 ARG_CMD(args), psp->rx_port); 653 goto fail; 654 } 655 } 656 657 /* Make sure TX port is valid, too */ 658 if (!BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), psp->tx_port)) { 659 test_error(unit, 660 "%s: Invalid TX port %d.\n", 661 ARG_CMD(args), psp->tx_port); 662 goto fail; 663 } 664 665 pktspeed_param[unit] = psp; 666 667 668 return TEST_OK; 669 fail: 670 if (psp) { 671 sal_free(psp); 672 } 673 return(TEST_FAIL); 674 } 675 676 /* 677 * Function: 678 * pktspeed_test_tx 679 * 680 * Purpose: 681 * Runs TX test 682 * 683 * Parameters: 684 * unit - unit to test 685 * a - test arguments (ignored) 686 * pa - test cookie (ignored) 687 * 688 * Returns: 689 * TEST_OK 690 * TEST_FAIL 691 */ 692 693 int 694 pktspeed_test_tx(int unit, args_t *a, void *pa) 695 { 696 pktspeed_param_t *psp = pktspeed_param[unit]; 697 int rv = TEST_OK; 698 int len; 699 700 if (psp->p_l_start == 0) { /* single length only */ 701 psp->p_l_start = psp->p_l_end = psp->alloc_size; 702 } 703 704 for (len = psp->p_l_start; len <= psp->p_l_end; len += psp->p_l_inc) { 705 psp->alloc_size = len; /* alloc size placed in DCB determines amount 706 of data tx; pkt_size is not used in tx test */ 707 rv = pktspeed_run_test(TRUE, psp); 708 if (rv != TEST_OK) { 709 break; 710 } 711 } 712 713 return rv; 714 } 715 716 /* 717 * Function: 718 * pktspeed_test_rx 719 * 720 * Purpose: 721 * Runs RX test 722 * 723 * Parameters: 724 * unit - unit to test 725 * a - test arguments (ignored) 726 * pa - test cookie (ignored) 727 * 728 * Returns: 729 * TEST_OK 730 * TEST_FAIL 731 */ 732 733 int 734 pktspeed_test_rx(int unit, args_t *a, void *pa) 735 { 736 pktspeed_param_t *psp = pktspeed_param[unit]; 737 int rv = TEST_OK; 738 int len; 739 740 if (psp->p_l_start == 0) { /* single length only */ 741 psp->p_l_start = psp->p_l_end = psp->pkt_size; 742 } 743 744 for (len = psp->p_l_start; len <= psp->p_l_end; len += psp->p_l_inc) { 745 psp->pkt_size = len; 746 rv = pktspeed_run_test(FALSE, psp); 747 if (rv != TEST_OK) { 748 break; 749 } 750 } 751 752 return rv; 753 } 754 755 /* 756 * Function: 757 * pktspeed_test_done 758 * 759 * Purpose: 760 * Cleans up after tx or rx test completes 761 * 762 * Parameters: 763 * unit - unit to test 764 * pa - test cookie (ignored) 765 * 766 * Returns: 767 * TEST_OK 768 * TEST_FAIL 769 */ 770 771 int 772 pktspeed_test_done(int unit, void *pa) 773 { 774 return pktspeed_free(pktspeed_param[unit]); 775 } 776 777 #endif /* BCM_ESW_SUPPORT */