streaming_lib.c (85311B)
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 * Streaming library for diagnostic (TR) tests. 8 * This library contains functions use by streaming diagnostic tests. 9 */ 10 11 12 #include <appl/diag/system.h> 13 #include <appl/diag/test.h> 14 #include <appl/diag/parse.h> 15 16 #include <shared/alloc.h> 17 #include <shared/bsl.h> 18 19 #include <soc/cmicm.h> 20 #include <soc/mcm/cmicm.h> 21 #include <soc/cmic.h> 22 #include <soc/cm.h> 23 #include <soc/dma.h> 24 #include <soc/drv.h> 25 #include <soc/dcb.h> 26 #include <soc/iproc.h> 27 #include <soc/phyctrl.h> 28 29 #include <sal/types.h> 30 #include <bcm/vlan.h> 31 #include <bcm/port.h> 32 33 #include "gen_pkt.h" 34 #include "streaming_lib.h" 35 36 #if defined(BCM_ESW_SUPPORT) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) 37 38 #define DMA_CHAN_PER_CMC(unit) (SOC_VCHAN_NUM(unit) / SOC_CMCS_NUM(unit)) 39 40 /* 41 * Function: 42 * stream_print_port_config 43 * Purpose: 44 * Print port config 45 * Parameters: 46 * unit - StrataSwitch Unit #. 47 * 48 * Returns: 49 * Nothing 50 */ 51 void 52 stream_print_port_config(int unit, pbmp_t pbmp) 53 { 54 int cnt = 0,port, port_speed; 55 56 LOG_INFO(BSL_LS_APPL_TESTS, 57 (BSL_META_U(unit, "\n=========== PORT CONFIG INFO ============\n"))); 58 LOG_INFO(BSL_LS_APPL_TESTS, 59 (BSL_META_U(unit, "\n%4s %4s %4s %6s %6s\n"), 60 "idx", "port", "spd", "LR/OS", "EH/HG")); 61 PBMP_ITER(pbmp, port) { 62 if (port < SOC_MAX_NUM_PORTS) { 63 bcm_port_speed_get(unit, port, &port_speed); 64 LOG_INFO(BSL_LS_APPL_TESTS, 65 (BSL_META_U(unit, "%4d "), cnt)); 66 LOG_INFO(BSL_LS_APPL_TESTS, 67 (BSL_META_U(unit, "%4d "), port)); 68 LOG_INFO(BSL_LS_APPL_TESTS, 69 (BSL_META_U(unit, "%3dG "), port_speed/1000)); 70 if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) { 71 LOG_INFO(BSL_LS_APPL_TESTS, 72 (BSL_META_U(unit, "%6s "), "OVSB")); 73 } else { 74 LOG_INFO(BSL_LS_APPL_TESTS, 75 (BSL_META_U(unit, "%6s "), "LR")); 76 } 77 if (IS_HG_PORT(unit, port)) { 78 LOG_INFO(BSL_LS_APPL_TESTS, 79 (BSL_META_U(unit, "%6s "), "HG")); 80 } else { 81 LOG_INFO(BSL_LS_APPL_TESTS, 82 (BSL_META_U(unit, "%6s "), "EHTN")); 83 } 84 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 85 cnt++; 86 } 87 } 88 LOG_INFO(BSL_LS_APPL_TESTS,(BSL_META_U(unit, "\n\n"))); 89 } 90 91 /* 92 * Function: 93 * stream_get_port_pipe 94 * Purpose: 95 * Get pipe number for a given device port. 96 * Parameters: 97 * unit: StrataSwitch Unit #. 98 * port: Device port # 99 * 100 * Returns: 101 * Pipe number. 102 */ 103 uint32 104 stream_get_port_pipe(int unit, int port) 105 { 106 uint32 pipe; 107 108 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 109 if (SOC_PBMP_MEMBER(PBMP_PIPE(unit, pipe), port)) { 110 break; 111 } 112 } 113 return pipe; 114 } 115 116 /* 117 * Function: 118 * stream_get_pkt_cell_cnt 119 * Purpose: 120 * Get the cell count for a given packet size. 121 * Parameters: 122 * unit: StrataSwitch Unit # 123 * pkt_size: packet size in bytes 124 * port: Device port # 125 * 126 * Returns: 127 * Cell count 128 */ 129 uint32 130 stream_get_pkt_cell_cnt(int unit, uint32 pkt_size, int port) 131 { 132 uint32 num_cells = 1; 133 uint32 i; 134 135 if (IS_HG_PORT(unit, port)) { 136 i = FIRST_CELL_HG2; 137 } 138 else { 139 i = FIRST_CELL_ENET; 140 } 141 while (i < pkt_size) { 142 num_cells++; 143 i += CELL_SIZE; 144 } 145 return num_cells; 146 } 147 148 /* 149 * Function: 150 * stream_get_safe_pkt_size 151 * Purpose: 152 * Calculate safe packet size based on oversub ratio. The assumption is that 153 * a front panel port will behave essentially as a line rate port and show no 154 * bandwidth degradation for packet sizes above the safe packet size. 155 * This is based on input from device microarchitects. Broadcom internal 156 * users of this test can contact microarchitecture for more info. 157 * Parameters: 158 * unit: StrataSwitch Unit #. 159 * ovs_ratio_x1000: Oversub ratio x1000 160 * 161 * Returns: 162 * Safe packet size. 163 */ 164 uint32 165 stream_get_safe_pkt_size(int unit, int ovs_ratio_x1000) 166 { 167 uint32 safe_size = 64; 168 169 if (ovs_ratio_x1000 <= 1507) { 170 safe_size = 171 145 + 172 ((((229000 - 144000) / (1507 - 1000)) * (ovs_ratio_x1000 - 173 1000)) / 1000); 174 } else if ((ovs_ratio_x1000 > 1507) && (ovs_ratio_x1000 <= 1760)) { 175 safe_size = 176 353 + 177 ((((416000 - 353000) / (1760 - 1508)) * (ovs_ratio_x1000 - 178 1508)) / 1000); 179 } else if ((ovs_ratio_x1000 > 1760) && (ovs_ratio_x1000 <= 1912)) { 180 safe_size = 181 562 + 182 ((((611000 - 562000) / (1912 - 1760)) * (ovs_ratio_x1000 - 183 1760)) / 1000); 184 } else { 185 safe_size = 770; 186 } 187 188 return safe_size; 189 } 190 191 /* 192 * Function: 193 * stream_get_ll_flood_cnt 194 * Purpose: 195 * Calculates number of packets that need to be sent to a port for a 196 * lossless swirl 197 * Parameters: 198 * unit - StrataSwitch Unit #. 199 * pkt_size : Packet size in bytes 200 * port: Device port # 201 * Returns: 202 * Number of packets needed for lossless flooding 203 */ 204 uint32 205 stream_get_ll_flood_cnt(int unit, int port, uint32 pkt_size, 206 uint32 *rand_pkt_size) 207 { 208 uint32 flood_pkt_cnt = 0; 209 uint32 total_cells = 0; 210 211 if (pkt_size == 1 && rand_pkt_size != NULL) { 212 while (total_cells < TARGET_CELL_COUNT && 213 flood_pkt_cnt < TARGET_CELL_COUNT) { 214 total_cells += stream_get_pkt_cell_cnt(unit, 215 rand_pkt_size[flood_pkt_cnt], 216 port); 217 flood_pkt_cnt++; 218 } 219 } else { 220 total_cells = stream_get_pkt_cell_cnt(unit, pkt_size, port); 221 if (total_cells > 0) { 222 flood_pkt_cnt = TARGET_CELL_COUNT / total_cells; 223 } 224 } 225 226 if (flood_pkt_cnt < 3) { 227 flood_pkt_cnt = 3; 228 } 229 if ((flood_pkt_cnt % 2) == 1) { 230 flood_pkt_cnt++; 231 } 232 233 return(flood_pkt_cnt); 234 } 235 236 /* 237 * Function: 238 * stream_get_pipe_bandwidth 239 * Purpose: 240 * Return bandwidth of the given pipe 241 * Parameters: 242 * unit: StrataSwitch Unit #. 243 * flag: reserved for special pipe config, i.e. extra 2nd MGMT port. 244 * 245 * Returns: 246 * Nothing 247 */ 248 uint32 249 stream_get_pipe_bandwidth(int unit, uint32 flag) 250 { 251 int pipe_bandwidth; 252 int freq; 253 uint16 dev_id; 254 uint8 rev_id; 255 int cal_universal; 256 257 soc_cm_get_id(unit, &dev_id, &rev_id); 258 freq = SOC_INFO(unit).frequency; 259 cal_universal = SOC_INFO(unit).fabric_port_enable ? 1 : 0; 260 261 /* TH */ 262 if (dev_id == BCM56960_DEVICE_ID) { 263 switch (freq) { 264 case TH_FREQ_850: pipe_bandwidth = TH_BW_850; break; 265 case TH_FREQ_765: pipe_bandwidth = TH_BW_765; break; 266 case TH_FREQ_672: pipe_bandwidth = TH_BW_672; break; 267 case TH_FREQ_645: pipe_bandwidth = TH_BW_645; break; 268 case TH_FREQ_545: pipe_bandwidth = TH_BW_545; break; 269 default: pipe_bandwidth = TH_BW_850; break; 270 } 271 } 272 /* TD2P */ 273 else if (dev_id == BCM56860_DEVICE_ID || dev_id == BCM56850_DEVICE_ID) { 274 switch (freq) { 275 case TD2P_FREQ_793: pipe_bandwidth = TD2P_BW_793; break; 276 case TD2P_FREQ_635: pipe_bandwidth = TD2P_BW_635; break; 277 case TD2P_FREQ_529: pipe_bandwidth = TD2P_BW_529; break; 278 case TD2P_FREQ_421: pipe_bandwidth = TD2P_BW_421; break; 279 default: pipe_bandwidth = TD2P_BW_793; break; 280 } 281 } 282 /* TH 2 */ 283 else if (dev_id == BCM56970_DEVICE_ID) { 284 switch (freq) { 285 case TH2_FREQ_1700: pipe_bandwidth = cal_universal ? 1050 : 1095; break; 286 case TH2_FREQ_1625: pipe_bandwidth = cal_universal ? 1002 : 1047; break; 287 case TH2_FREQ_1525: pipe_bandwidth = cal_universal ? 940 : 980; break; 288 case TH2_FREQ_1425: pipe_bandwidth = cal_universal ? 877 : 915; break; 289 case TH2_FREQ_1325: pipe_bandwidth = cal_universal ? 812 : 847; break; 290 case TH2_FREQ_1275: pipe_bandwidth = cal_universal ? 782 : 815; break; 291 case TH2_FREQ_1225: pipe_bandwidth = cal_universal ? 750 : 782; break; 292 case TH2_FREQ_1125: pipe_bandwidth = cal_universal ? 687 : 717; break; 293 case TH2_FREQ_1050: pipe_bandwidth = cal_universal ? 640 : 667; break; 294 case TH2_FREQ_950: pipe_bandwidth = cal_universal ? 575 : 600; break; 295 case TH2_FREQ_850: pipe_bandwidth = cal_universal ? 512 : 535; break; 296 default: pipe_bandwidth = cal_universal ? 1050 : 1095; break; 297 } 298 pipe_bandwidth = pipe_bandwidth * 1000; 299 } 300 /* TD3 or TD3 2T or MV2*/ 301 else if (dev_id == BCM56870_DEVICE_ID || dev_id == BCM56873_DEVICE_ID || 302 dev_id == BCM56770_DEVICE_ID || dev_id == BCM56771_DEVICE_ID) { 303 switch (freq) { 304 case TD3_FREQ_1525: pipe_bandwidth = TD3_BW_1525; break; 305 case TD3_FREQ_1425: pipe_bandwidth = TD3_BW_1425; break; 306 case TD3_FREQ_1325: pipe_bandwidth = TD3_BW_1325; break; 307 case TD3_FREQ_1275: pipe_bandwidth = TD3_BW_1275; break; 308 case TD3_FREQ_1012: pipe_bandwidth = TD3_BW_1012; break; 309 case TD3_FREQ_850: pipe_bandwidth = TD3_BW_850; break; 310 default: pipe_bandwidth = TD3_FREQ_850; break; 311 } 312 } 313 /* default */ 314 else { 315 cli_out("\n*WARNING: Unrecognized DEVICE_ID %d\n", dev_id); 316 pipe_bandwidth = TH_BW_850; 317 } 318 319 return pipe_bandwidth; 320 } 321 322 /* 323 * Function: 324 * stream_get_ancl_bandwidth 325 * Purpose: 326 * Return ancillary bandwidth of the given pipe 327 * Parameters: 328 * unit: StrataSwitch Unit #. 329 * flag: reserved for special pipe config, i.e. extra 2nd MGMT port. 330 * 331 * Returns: 332 * Nothing 333 */ 334 uint32 335 stream_get_ancl_bandwidth(int unit, uint32 flag) 336 { 337 int ancl_bandwidth; 338 uint16 dev_id; 339 uint8 rev_id; 340 341 soc_cm_get_id(unit, &dev_id, &rev_id); 342 /* TH */ 343 if (dev_id == BCM56960_DEVICE_ID) { 344 ancl_bandwidth = TH_MISC_BW; 345 } 346 /* TD2P */ 347 else if (dev_id == BCM56860_DEVICE_ID || dev_id == BCM56850_DEVICE_ID) { 348 ancl_bandwidth = TD2P_MISC_BW; 349 } 350 /* TH 2 */ 351 else if (dev_id == BCM56970_DEVICE_ID) { 352 ancl_bandwidth = TH2_MISC_BW; 353 } 354 /* TD3 or TD3 2T or MV2*/ 355 else if (dev_id == BCM56870_DEVICE_ID || dev_id == BCM56873_DEVICE_ID || 356 dev_id == BCM56770_DEVICE_ID || dev_id == BCM56771_DEVICE_ID) { 357 ancl_bandwidth = TD3_MISC_BW; 358 } 359 /* default */ 360 else { 361 cli_out("\n*WARNING: Unrecognized DEVICE_ID %d\n", dev_id); 362 ancl_bandwidth = TH_MISC_BW; 363 } 364 365 return ancl_bandwidth; 366 } 367 368 /* 369 * Function: 370 * stream_get_reg_tpkt_tbyt 371 * Purpose: 372 * Get register of TPKTr and TBYTr 373 * Parameters: 374 * unit: StrataSwitch Unit #. 375 * reg_tpkt: ptr to register TPKTr 376 * reg_tbyt: ptr to register TBYTr 377 * 378 * Returns: 379 * BCM_E_XXX 380 */ 381 bcm_error_t 382 stream_get_reg_tpkt_tbyt(int unit, int port, soc_reg_t* reg_tpkt, soc_reg_t* reg_tbyt) 383 { 384 int phy_port; 385 bcm_error_t rv = BCM_E_NONE; 386 387 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 388 if(phy_port == -1) { 389 cli_out("\nERROR : stream_get_reg_tpkt_tbyt called with invalid " 390 "logical port %0d", port); 391 return BCM_E_INTERNAL; 392 } 393 394 /* TH+ and later (TH+, TH2, TD3) */ 395 if (soc_feature(unit, soc_feature_cxl_mib)) { 396 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, phy_port), 397 SOC_BLK_CLPORT)) { 398 (*reg_tpkt) = CLMIB_TPKTr; 399 (*reg_tbyt) = CLMIB_TBYTr; 400 } else if (IS_QSGMII_PORT(unit, port)) { 401 (*reg_tpkt) = GTPKTr; 402 (*reg_tbyt) = GTBYTr; 403 } else { 404 (*reg_tpkt) = XLMIB_TPKTr; 405 (*reg_tbyt) = XLMIB_TBYTr; 406 } 407 /* TH, TD2P */ 408 } else if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT2PLUS(unit)) { 409 (*reg_tpkt) = TPKTr; 410 (*reg_tbyt) = TBYTr; 411 } 412 /* unrecognized device */ 413 else { 414 rv = BCM_E_FAIL; 415 } 416 417 return rv; 418 } 419 420 /* 421 * Function: 422 * stream_get_wc_pkt_size 423 * Purpose: 424 * Get worst-case packet size for HiGig packet 425 * Parameters: 426 * unit: StrataSwitch Unit #. 427 * hg_en: HiGig enable, 0->false, otherwise->true 428 * 429 * Returns: 430 * worst-case packet size 431 */ 432 uint32 433 stream_get_wc_pkt_size(int unit, int hg_en) 434 { 435 if (SOC_IS_TRIDENT3X(unit)) { 436 return HG2_WC_PKT_SIZE; 437 } 438 439 if (hg_en == 0) { 440 return ENET_WC_PKT_SIZE; 441 } else { 442 return HG2_WC_PKT_SIZE; 443 } 444 } 445 446 /* 447 * Function: 448 * stream_set_vlan 449 * Purpose: 450 * Validates VLAN in VLAN table 451 * Parameters: 452 * unit - StrataSwitch Unit #. 453 * vlan - VLAN ID 454 * enable - 0->disable, otherwise->enable. 455 * 456 * Returns: 457 * Nothing 458 */ 459 void 460 stream_set_vlan(int unit, bcm_vlan_t vlan, int enable) 461 { 462 uint32 value; 463 vlan_tab_entry_t vlan_tab_entry; 464 vlan_2_tab_entry_t vlan_2_tab_entry; 465 466 if (SOC_MEM_IS_VALID(unit, VLAN_TABm)) { 467 value = (enable == 0) ? (0x0) : (0x1); 468 (void) soc_mem_read(unit, VLAN_TABm, COPYNO_ALL, vlan, vlan_tab_entry.entry_data); 469 soc_mem_field32_set(unit, VLAN_TABm, vlan_tab_entry.entry_data, 470 VALIDf, value); 471 (void) soc_mem_write(unit, VLAN_TABm, COPYNO_ALL, vlan, vlan_tab_entry.entry_data); 472 if (SOC_MEM_IS_VALID(unit, VLAN_2_TABm)) { 473 (void) soc_mem_read(unit, VLAN_2_TABm, COPYNO_ALL, vlan, 474 vlan_2_tab_entry.entry_data); 475 soc_mem_field32_set(unit, VLAN_2_TABm, vlan_2_tab_entry.entry_data, 476 VALIDf, value); 477 (void) soc_mem_write(unit, VLAN_2_TABm, COPYNO_ALL, vlan, 478 vlan_2_tab_entry.entry_data); 479 } 480 } else { 481 cli_out("\n*ERROR, invalid mem VLAN_TABm\n"); 482 } 483 } 484 485 /* 486 * Function: 487 * stream_set_vlan_valid 488 * Purpose: 489 * Validates VLAN in VLAN table 490 * Parameters: 491 * unit - StrataSwitch Unit #. 492 * vlan - VLAN ID 493 * 494 * Returns: 495 * Nothing 496 */ 497 void 498 stream_set_vlan_valid(int unit, bcm_vlan_t vlan) 499 { 500 stream_set_vlan(unit, vlan, 1); 501 } 502 503 /* 504 * Function: 505 * stream_set_vlan_invalid 506 * Purpose: 507 * InValidates VLAN in VLAN table 508 * Parameters: 509 * unit - StrataSwitch Unit #. 510 * vlan - VLAN ID 511 * 512 * Returns: 513 * Nothing 514 */ 515 void 516 stream_set_vlan_invalid(int unit, bcm_vlan_t vlan) 517 { 518 stream_set_vlan(unit, vlan, 0); 519 } 520 521 /* 522 * Function: 523 * stream_set_l3mtu 524 * Purpose: 525 * set L3_MTU_VALUES 526 * Parameters: 527 * unit - StrataSwitch Unit #. 528 * vlan - VLAN ID 529 * mtu_value - MTU value 530 * 531 * Returns: 532 * Nothing 533 */ 534 static bcm_error_t 535 stream_set_l3mtu(int unit, bcm_vlan_t vlan, uint32 mtu_value) 536 { 537 bcm_error_t rv = BCM_E_NONE; 538 mtu_values_entry_t l3_mtu_values_entry; 539 540 /*cli_out("Setting MTU to %0d for vlan/oif 0x%0x\n", mtu_value, vlan);*/ 541 SOC_IF_ERROR_RETURN(READ_L3_MTU_VALUESm( 542 unit, MEM_BLOCK_ANY, vlan, &l3_mtu_values_entry)); 543 soc_L3_MTU_VALUESm_field32_set( 544 unit, &l3_mtu_values_entry, MTU_SIZEf, mtu_value); 545 SOC_IF_ERROR_RETURN(WRITE_L3_MTU_VALUESm( 546 unit, MEM_BLOCK_ALL, vlan, &l3_mtu_values_entry)); 547 548 return rv; 549 } 550 551 /* 552 * Function: 553 * stream_set_l3mtu_valid 554 * Purpose: 555 * set L3_MTU_VALUES to a valid value (max value) 556 * Parameters: 557 * unit - StrataSwitch Unit #. 558 * vlan - VLAN ID 559 * 560 * Returns: 561 * Nothing 562 */ 563 void 564 stream_set_l3mtu_valid(int unit, bcm_vlan_t vlan) 565 { 566 (void) stream_set_l3mtu(unit, vlan, MTU); 567 } 568 569 /* 570 * Function: 571 * stream_set_l3mtu_invalid 572 * Purpose: 573 * set L3_MTU_VALUES to an invalid value (min_pkt_size-1) 574 * Parameters: 575 * unit - StrataSwitch Unit #. 576 * vlan - VLAN ID 577 * 578 * Returns: 579 * Nothing 580 */ 581 static void 582 stream_set_l3mtu_invalid(int unit, bcm_vlan_t vlan) 583 { 584 (void) stream_set_l3mtu(unit, vlan, 63); 585 } 586 587 /* 588 * Function: 589 * stream_set_lpbk 590 * Purpose: 591 * Enable and disable MAC/PHY loopback on all ports specified by pbmp. 592 * Parameters: 593 * unit: StrataSwitch Unit #. 594 * pbmp: port bitmap 595 * loopback: loopback mode 596 * 597 * Returns: 598 * SOC_E_XXXX 599 */ 600 STATIC int _last_lpbk = BCM_PORT_LOOPBACK_NONE; 601 bcm_error_t 602 stream_set_lpbk(int unit, pbmp_t pbmp, int loopback) 603 { 604 int port, lp_invalid = 0; 605 606 _last_lpbk = loopback; 607 608 if (loopback == BCM_PORT_LOOPBACK_MAC) { 609 cli_out("\nEnabling MAC loopback"); 610 } else if (loopback == BCM_PORT_LOOPBACK_PHY) { 611 cli_out("\nEnabling PCS local loopback"); 612 } else if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) { 613 cli_out("\nEnabling PMD loopback"); 614 } else if (loopback == BCM_PORT_LOOPBACK_NONE) { 615 cli_out("\nDisabling loopback"); 616 } else { 617 lp_invalid = 1; 618 loopback = BCM_PORT_LOOPBACK_NONE; 619 cli_out("\nInvalid loopback mode"); 620 } 621 622 if (lp_invalid == 0) { 623 PBMP_ITER(pbmp, port) { 624 if (port < SOC_MAX_NUM_PORTS) { 625 if (loopback == BCM_PORT_LOOPBACK_NONE) { 626 if (_last_lpbk == BCM_PORT_LOOPBACK_PHY_REMOTE) { 627 BCM_IF_ERROR_RETURN(stream_set_pmd_lpbk(unit, port, 628 BCM_PORT_PHY_CONTROL_LOOPBACK_PMD, 0)); 629 } else { 630 BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port, 631 loopback)); 632 } 633 } else if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) { 634 BCM_IF_ERROR_RETURN(stream_set_pmd_lpbk(unit, port, 635 BCM_PORT_PHY_CONTROL_LOOPBACK_PMD, 1)); 636 } else { 637 BCM_IF_ERROR_RETURN(bcm_port_loopback_set(unit, port, 638 loopback)); 639 } 640 } 641 } 642 } 643 644 return BCM_E_NONE; 645 } 646 647 /* 648 * Function: 649 * stream_set_pmd_lpbk 650 * Purpose: 651 * Enable PMD local loopback on a port. 652 * Parameters: 653 * unit: StrataSwitch Unit #. 654 * port: Device port number. 655 * type: PHY control type. 656 * value: PHY control value. 657 * 658 * Returns: 659 * SOC_E_XXXX 660 */ 661 bcm_error_t 662 stream_set_pmd_lpbk( int unit, bcm_port_t port, bcm_port_phy_control_t type, uint32 value) 663 { 664 BCM_IF_ERROR_RETURN(bcm_port_phy_control_set(unit, port, type, value)); 665 BCM_IF_ERROR_RETURN(bcm_port_enable_set(unit, port, 1)); 666 return BCM_E_NONE; 667 } 668 669 /* 670 * Function: 671 * stream_set_mac_lpbk 672 * Purpose: 673 * Enable MAC loopback on all ports specified by pbmp. 674 * Parameters: 675 * unit: StrataSwitch Unit #. 676 * pbmp: port bitmap 677 * 678 * Returns: 679 * Nothing 680 */ 681 void 682 stream_set_mac_lpbk(int unit, pbmp_t pbmp) 683 { 684 stream_set_lpbk(unit, pbmp, BCM_PORT_LOOPBACK_MAC); 685 } 686 687 /* 688 * Function: 689 * stream_set_phy_lpbk 690 * Purpose: 691 * Enable PHY loopback on all ports specified by pbmp. 692 * Parameters: 693 * unit: StrataSwitch Unit #. 694 * pbmp: port bitmap 695 * 696 * Returns: 697 * Nothing 698 */ 699 void 700 stream_set_phy_lpbk(int unit, pbmp_t pbmp) 701 { 702 stream_set_lpbk(unit, pbmp, BCM_PORT_LOOPBACK_PHY); 703 } 704 705 /* 706 * Function: 707 * stream_set_no_lpbk 708 * Purpose: 709 * Clear loopback on all ports specified by pbmp. 710 * Parameters: 711 * unit: StrataSwitch Unit #. 712 * pbmp: port bitmap 713 * 714 * Returns: 715 * Nothing 716 */ 717 void 718 stream_set_no_lpbk(int unit, pbmp_t pbmp) 719 { 720 stream_set_lpbk(unit, pbmp, BCM_PORT_LOOPBACK_NONE); 721 } 722 723 /* 724 * Function: 725 * stream_turn_off_cmic_mmu_bkp 726 * Purpose: 727 * Turn off CMIC to MMU backpressure on all channels 728 * Parameters: 729 * unit: StrataSwitch Unit #. 730 * 731 * Returns: 732 * Nothing 733 */ 734 void 735 stream_turn_off_cmic_mmu_bkp(int unit) 736 { 737 int cmc, ch; 738 int vchan; 739 uint32 threshold = CMICM_MMU_BKP_OFF_THRESHOLD; 740 741 if (soc_feature(unit, soc_feature_cmicm) || 742 soc_feature(unit, soc_feature_cmicd_v2) || 743 soc_feature(unit, soc_feature_cmicd_v3)) { 744 threshold = CMICM_MMU_BKP_OFF_THRESHOLD; 745 } else if (soc_feature(unit, soc_feature_cmicx)) { 746 threshold = CMICX_MMU_BKP_OFF_THRESHOLD; 747 } 748 749 for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) { 750 for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) { 751 vchan = cmc * DMA_CHAN_PER_CMC(unit) + ch; 752 soc_dma_chan_rxbuf_threshold_cfg(unit, vchan, threshold); 753 } 754 } 755 756 if (soc_feature(unit, soc_feature_cmicx)) { 757 for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) { 758 soc_dma_cmc_rxbuf_threshold_cfg(unit, cmc, threshold); 759 } 760 } 761 } 762 763 /* 764 * Function: 765 * stream_turn_off_idb_fc 766 * Purpose: 767 * Turn off IDB flow control. 768 * Parameters: 769 * unit: StrataSwitch Unit #. 770 * idb_fcc_regs - ptr to idb flow control registers. 771 * a_size - number of registers in the input ptr. 772 * 773 * Returns: 774 * Nothing 775 */ 776 static void 777 stream_turn_off_idb_fc(int unit, soc_reg_t *idb_fcc_regs, int obm_per_pipe) 778 { 779 int obm_subp; 780 int pipe, obm, idx; 781 uint64 idb_fc; 782 soc_field_t idb_flow_control_config_fields[] = { 783 PORT_FC_ENf, 784 LOSSLESS1_FC_ENf, 785 LOSSLESS0_FC_ENf, 786 LOSSLESS1_PRIORITY_PROFILEf, 787 LOSSLESS0_PRIORITY_PROFILEf 788 }; 789 uint32 idb_flow_control_config_values[] = {0x0, 0x0, 0x0, 0xff, 0xff}; 790 791 cli_out("\nTurning off flow control at IDB/MMU"); 792 793 COMPILER_64_SET(idb_fc, 0x0, 0x0); 794 795 if (SOC_REG_IS_VALID(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r)) { 796 soc_reg_fields32_modify(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 797 REG_PORT_ANY, 5, idb_flow_control_config_fields, 798 idb_flow_control_config_values); 799 (void) soc_reg_get(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 0, 0, 800 &idb_fc); 801 } 802 803 for(pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 804 for(obm = 0; obm < obm_per_pipe; obm++) { 805 idx = (pipe * obm_per_pipe) + obm; 806 if(SOC_REG_IS_VALID(unit, idb_fcc_regs[idx])) { 807 for (obm_subp = 0; obm_subp < NUM_SUBP_OBM; obm_subp++) { 808 (void) soc_reg_set(unit, idb_fcc_regs[idx], 0, obm_subp, idb_fc); 809 } 810 } 811 } 812 } 813 } 814 815 /* 816 * Function: 817 * stream_turn_off_fc 818 * Purpose: 819 * Turn off flow control at the MAC, IDB and MMU. 820 * Parameters: 821 * unit: StrataSwitch Unit #. 822 * pbmp - Device port bitmap 823 * 824 * Returns: 825 * Nothing 826 */ 827 void 828 stream_turn_off_fc(int unit, pbmp_t pbmp) 829 { 830 int port, idx, obm_per_pipe; 831 832 soc_reg_t idb_fcc_regs[] = { 833 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 834 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r, 835 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r, 836 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r, 837 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r, 838 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r, 839 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r, 840 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r, 841 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r, 842 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r, 843 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r, 844 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r, 845 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r, 846 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r, 847 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r, 848 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r, 849 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r, 850 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r, 851 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r, 852 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r, 853 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r, 854 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r, 855 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r, 856 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r, 857 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE1r, 858 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE1r, 859 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE1r, 860 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE1r, 861 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE1r, 862 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE1r, 863 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE1r, 864 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE1r, 865 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r, 866 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r, 867 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r, 868 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r, 869 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE2r, 870 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE2r, 871 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE2r, 872 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE2r, 873 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE2r, 874 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE2r, 875 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE2r, 876 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE2r, 877 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE2r, 878 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE2r, 879 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE2r, 880 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE2r, 881 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r, 882 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r, 883 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r, 884 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r, 885 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE3r, 886 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE3r, 887 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE3r, 888 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE3r, 889 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE3r, 890 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE3r, 891 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE3r, 892 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE3r, 893 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE3r, 894 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE3r, 895 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE3r, 896 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE3r 897 }; 898 899 soc_reg_t pgw_fcc_regs[] = { 900 PGW_OBM_PORT0_FC_CONFIGr, 901 PGW_OBM_PORT1_FC_CONFIGr, 902 PGW_OBM_PORT2_FC_CONFIGr, 903 PGW_OBM_PORT3_FC_CONFIGr, 904 PGW_OBM_PORT4_FC_CONFIGr, 905 PGW_OBM_PORT5_FC_CONFIGr, 906 PGW_OBM_PORT6_FC_CONFIGr, 907 PGW_OBM_PORT7_FC_CONFIGr, 908 PGW_OBM_PORT8_FC_CONFIGr, 909 PGW_OBM_PORT9_FC_CONFIGr, 910 PGW_OBM_PORT10_FC_CONFIGr, 911 PGW_OBM_PORT11_FC_CONFIGr, 912 PGW_OBM_PORT12_FC_CONFIGr, 913 PGW_OBM_PORT13_FC_CONFIGr, 914 PGW_OBM_PORT14_FC_CONFIGr, 915 PGW_OBM_PORT15_FC_CONFIGr 916 }; 917 918 soc_reg_t idb_mv2_fcc_regs[] = { 919 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 920 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r, 921 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r, 922 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r, 923 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r, 924 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r, 925 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r, 926 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r, 927 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r, 928 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r, 929 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r, 930 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r, 931 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r, 932 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r, 933 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r, 934 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r, 935 IDB_OBM16_FLOW_CONTROL_CONFIG_PIPE0r, 936 IDB_OBM17_FLOW_CONTROL_CONFIG_PIPE0r, 937 IDB_OBM18_FLOW_CONTROL_CONFIG_PIPE0r, 938 IDB_OBM19_FLOW_CONTROL_CONFIG_PIPE0r 939 }; 940 941 if (SOC_REG_IS_VALID(unit, THDI_INPUT_PORT_XON_ENABLESr)) { 942 PBMP_ITER(pbmp, port) { 943 if (port < SOC_MAX_NUM_PORTS) { 944 bcm_port_pause_set(unit, port, FALSE, FALSE); 945 soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, 946 port, PORT_PAUSE_ENABLEf, 0x0); 947 } 948 } 949 soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, 950 0, PORT_PAUSE_ENABLEf, 0x0); 951 } 952 953 if(SOC_IS_TOMAHAWK(unit)) { /*TH, TH+*/ 954 obm_per_pipe = 8; 955 } else if (SOC_IS_MAVERICK2(unit)) { 956 obm_per_pipe = 20; 957 } 958 else { /* All other devices are using 16 obm per pipe */ 959 obm_per_pipe = 16; 960 } 961 if (SOC_IS_MAVERICK2(unit)) stream_turn_off_idb_fc(unit, idb_mv2_fcc_regs, obm_per_pipe); 962 else stream_turn_off_idb_fc(unit, idb_fcc_regs, obm_per_pipe); 963 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2PLUS(unit)) { 964 for (idx = 0; idx < (sizeof(pgw_fcc_regs) / sizeof(soc_reg_t)); idx++) { 965 if (SOC_REG_IS_VALID(unit, pgw_fcc_regs[idx])) { 966 soc_reg_field32_modify(unit, pgw_fcc_regs[idx], REG_PORT_ANY, 967 PORT_FC_ENABLEf, 0x0); 968 } 969 } 970 } 971 } 972 973 /* 974 * Function: 975 * stream_gen_random_l2_pkt 976 * Purpose: 977 * Generate random L2 packet with seq ID 978 * Parameters: 979 * pkt_ptr - ptr to packet. 980 * pkt_size - Packet size in bytes 981 * mac_da - Destination MAC Address 982 * mac_sa - Source MAC Address 983 * tpid - TPID 984 * vlan_id - VLAN 985 * seq_id - Sequence ID 986 * 987 * Returns: 988 * Nothing 989 */ 990 void 991 stream_gen_random_l2_pkt(uint8 *pkt_ptr, uint32 pkt_size, uint32 seq_id, 992 uint8 mac_da[NUM_BYTES_MAC_ADDR], 993 uint8 mac_sa[NUM_BYTES_MAC_ADDR], 994 uint16 tpid, uint16 vlan_id) 995 { 996 int i, offset; 997 uint32 crc; 998 999 tgp_gen_random_l2_pkt(pkt_ptr, pkt_size, mac_da, mac_sa, tpid, vlan_id); 1000 1001 /* Replace First 4 Payload Bytes with Sequence ID */ 1002 offset = NUM_BYTES_L2_HDR; 1003 pkt_ptr[offset + 0] = (seq_id >> (3 * 8)) & 0xff; 1004 pkt_ptr[offset + 1] = (seq_id >> (2 * 8)) & 0xff; 1005 pkt_ptr[offset + 2] = (seq_id >> (1 * 8)) & 0xff; 1006 pkt_ptr[offset + 3] = (seq_id >> (0 * 8)) & 0xff; 1007 1008 /* Replace Next 2 Payload Bytes with Packet Size */ 1009 pkt_ptr[offset + 4] = (pkt_size >> 8) & 0xff; 1010 pkt_ptr[offset + 5] = (pkt_size) & 0xff; 1011 1012 /* Recalculate CRC */ 1013 tgp_populate_crc_table(); 1014 crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size); 1015 1016 offset = pkt_size - NUM_BYTES_CRC; 1017 for (i = NUM_BYTES_CRC; i > 0 ; i--) { 1018 pkt_ptr[offset++] = (crc >> ((i - 1) * 8)) & 0xff; 1019 } 1020 } 1021 1022 /* 1023 * Function: 1024 * stream_gen_random_l3_pkt 1025 * Purpose: 1026 * Generate random L3 packet with seq ID 1027 * Parameters: 1028 * 1029 * Returns: 1030 * Nothing 1031 */ 1032 void 1033 stream_gen_random_l3_pkt(uint8 *pkt_ptr, uint8 ipv6_en, 1034 uint32 pkt_size, uint32 seq_id, 1035 uint8 mac_da[NUM_BYTES_MAC_ADDR], 1036 uint8 mac_sa[NUM_BYTES_MAC_ADDR], 1037 uint16 vlan_id, uint32 ip_da, uint32 ip_sa, 1038 uint8 ttl, uint8 tos) 1039 { 1040 int i, offset; 1041 uint32 crc; 1042 1043 tgp_gen_random_ip_pkt(ipv6_en, pkt_ptr, pkt_size, mac_da, mac_sa, 1044 vlan_id, ip_da, ip_sa, ttl, tos); 1045 1046 /* Replace First 4 Payload Bytes with Sequence ID */ 1047 if (ipv6_en == 1) { 1048 offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV6_HDR; 1049 } else { 1050 offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV4_HDR; 1051 } 1052 pkt_ptr[offset + 0] = (seq_id >> (3 * 8)) & 0xff; 1053 pkt_ptr[offset + 1] = (seq_id >> (2 * 8)) & 0xff; 1054 pkt_ptr[offset + 2] = (seq_id >> (1 * 8)) & 0xff; 1055 pkt_ptr[offset + 3] = (seq_id >> (0 * 8)) & 0xff; 1056 1057 /* Replace Next 2 Payload Bytes with Packet Size */ 1058 pkt_ptr[offset + 4] = (pkt_size >> 8) & 0xff; 1059 pkt_ptr[offset + 5] = (pkt_size) & 0xff; 1060 1061 /* Recalculate CRC */ 1062 tgp_populate_crc_table(); 1063 crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size); 1064 1065 offset = pkt_size - NUM_BYTES_CRC; 1066 for (i = NUM_BYTES_CRC; i > 0 ; i--) { 1067 pkt_ptr[offset++] = (crc >> ((i - 1) * 8)) & 0xff; 1068 } 1069 } 1070 1071 /* 1072 * Function: 1073 * stream_gen_random_mpls_l3_pkt 1074 * Purpose: 1075 * Generate random L3 packet with seq ID 1076 * Parameters: 1077 * 1078 * Returns: 1079 * Nothing 1080 */ 1081 void 1082 stream_gen_random_mpls_l3_pkt( 1083 uint8 *pkt_ptr, 1084 stream_pkt_t *tx_pkt, 1085 uint32 pkt_size, 1086 uint32 seq_id, 1087 uint8 tos) 1088 { 1089 int i, offset; 1090 uint32 crc; 1091 int l2_hdr_size, mpls_hdr_size, ip_hdr_size; 1092 1093 tgp_gen_random_mpls_ip_pkt( 1094 pkt_ptr, 1095 pkt_size, 1096 tx_pkt->mac_da, 1097 tx_pkt->mac_sa, 1098 tx_pkt->tx_vlan, 1099 tx_pkt->l3_en, 1100 tx_pkt->l3_mpls_en, 1101 tx_pkt->mpls_labels, 1102 tx_pkt->ipv6_en, 1103 tx_pkt->ipv6_da, 1104 tx_pkt->ipv6_sa, 1105 tx_pkt->ttl, 1106 tos); 1107 1108 l2_hdr_size = NUM_BYTES_L2_HDR; 1109 mpls_hdr_size = (tx_pkt->l3_mpls_en == 1) ? (3 * NUM_BYTES_MPLS_HDR) : 0; 1110 ip_hdr_size = (tx_pkt->l3_en == 1) ? 1111 ((tx_pkt->ipv6_en == 1) ? NUM_BYTES_IPV6_HDR : 1112 NUM_BYTES_IPV4_HDR) : 0; 1113 offset = l2_hdr_size + mpls_hdr_size + ip_hdr_size; 1114 1115 pkt_ptr[offset + 0] = (seq_id >> (3 * 8)) & 0xff; 1116 pkt_ptr[offset + 1] = (seq_id >> (2 * 8)) & 0xff; 1117 pkt_ptr[offset + 2] = (seq_id >> (1 * 8)) & 0xff; 1118 pkt_ptr[offset + 3] = (seq_id >> (0 * 8)) & 0xff; 1119 1120 /* Replace Next 2 Payload Bytes with Packet Size */ 1121 pkt_ptr[offset + 4] = (pkt_size >> 8) & 0xff; 1122 pkt_ptr[offset + 5] = (pkt_size) & 0xff; 1123 1124 pkt_ptr[offset + 6] = (tx_pkt->port) & 0xff; 1125 1126 /* Recalculate CRC */ 1127 tgp_populate_crc_table(); 1128 crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size); 1129 1130 offset = pkt_size - NUM_BYTES_CRC; 1131 for (i = NUM_BYTES_CRC; i > 0 ; i--) { 1132 pkt_ptr[offset++] = (crc >> ((i - 1) * 8)) & 0xff; 1133 } 1134 } 1135 1136 /* 1137 * Function: 1138 * stream_gen_ref_l2_pkt 1139 * Purpose: 1140 * Generate reference L2 packet by retrieving pkt_size and seq_id 1141 * from the given rx packet. 1142 * Parameters: 1143 * unit - StrataSwitch Unit #. 1144 * port - device port number 1145 * pkt_intg - ptr to packet integrity struct, containing all necessary 1146 * parameters needed for integrity check. 1147 * rx_pkt - ptr to rx packet. 1148 * ref_pkt - ptr to reference packet. 1149 * ref_pkt_size - packet size of reference packet 1150 * 1151 * Returns: 1152 * Nothing 1153 */ 1154 static void 1155 stream_gen_ref_l2_pkt(int unit, int port, stream_integrity_t *pkt_intg, 1156 uint8 *rx_pkt, uint8 *ref_pkt, uint32 *ref_pkt_size) 1157 { 1158 uint32 offset, seq_id, pkt_size; 1159 uint32 header_size = 0; 1160 1161 soc_dma_header_size_get(unit, &header_size); 1162 seq_id = 0x00000000; 1163 pkt_size = 0x00000000; 1164 offset = NUM_BYTES_L2_HDR + header_size; 1165 1166 seq_id |= (rx_pkt[offset] << 24); 1167 seq_id |= (rx_pkt[offset + 1] << 16); 1168 seq_id |= (rx_pkt[offset + 2] << 8); 1169 seq_id |= (rx_pkt[offset + 3]); 1170 pkt_size |= (rx_pkt[offset + 4] << 8); 1171 pkt_size |= (rx_pkt[offset + 5]); 1172 1173 sal_srand(pkt_intg->port_pkt_seed[port] + seq_id); 1174 stream_gen_random_l2_pkt(ref_pkt, pkt_size, seq_id, 1175 pkt_intg->mac_da[port], 1176 pkt_intg->mac_sa[port], 1177 TPID, pkt_intg->tx_vlan[port]); 1178 1179 (*ref_pkt_size) = pkt_size; 1180 } 1181 1182 /* 1183 * Function: 1184 * stream_gen_ref_l3_pkt 1185 * Purpose: 1186 * Generate reference L3 packet by retrieving pkt_size and seq_id 1187 * from the given rx packet. 1188 * Parameters: 1189 * unit - StrataSwitch Unit #. 1190 * port - device port number 1191 * pkt_intg - ptr to packet integrity struct, containing all necessary 1192 * parameters needed for integrity check. 1193 * rx_pkt - ptr to rx packet. 1194 * ref_pkt - ptr to reference packet. 1195 * ref_pkt_size - packet size of reference packet 1196 * 1197 * Returns: 1198 * Nothing 1199 */ 1200 static void 1201 stream_gen_ref_l3_pkt(int unit, int port, stream_integrity_t *pkt_intg, 1202 uint8 *rx_pkt, uint8 *ref_pkt, uint32 *ref_pkt_size) 1203 { 1204 uint32 offset, seq_id, pkt_size; 1205 uint8 ttl, tos = 0; 1206 uint32 header_size = 0; 1207 1208 soc_dma_header_size_get(unit, &header_size); 1209 seq_id = 0x00000000; 1210 pkt_size = 0x00000000; 1211 if (pkt_intg->ipv6_en == 1) { 1212 offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV6_HDR; 1213 } else { 1214 offset = NUM_BYTES_L2_HDR + NUM_BYTES_IPV4_HDR; 1215 } 1216 offset += header_size; 1217 1218 seq_id |= (rx_pkt[offset] << 24); 1219 seq_id |= (rx_pkt[offset + 1] << 16); 1220 seq_id |= (rx_pkt[offset + 2] << 8); 1221 seq_id |= (rx_pkt[offset + 3]); 1222 pkt_size |= (rx_pkt[offset + 4] << 8); 1223 pkt_size |= (rx_pkt[offset + 5]); 1224 1225 if (pkt_intg->ipv6_en == 1) { 1226 offset = NUM_BYTES_L2_HDR + 7; /* Byte 25 */ 1227 } else { 1228 offset = NUM_BYTES_L2_HDR + 1; /* Byte 19 */ 1229 tos = rx_pkt[offset + header_size]; 1230 offset = NUM_BYTES_L2_HDR + 8; /* Byte 26 */ 1231 } 1232 offset += header_size; 1233 ttl = rx_pkt[offset]; 1234 1235 sal_srand(pkt_intg->port_pkt_seed[port] + seq_id); 1236 stream_gen_random_l3_pkt(ref_pkt, pkt_intg->ipv6_en, 1237 pkt_size, seq_id, 1238 pkt_intg->mac_da[port], 1239 pkt_intg->mac_sa[port], 1240 pkt_intg->tx_vlan[port], 1241 pkt_intg->ip_da[port], 1242 pkt_intg->ip_sa[port], 1243 ttl, tos); 1244 1245 (*ref_pkt_size) = pkt_size; 1246 } 1247 1248 /* 1249 * Function: 1250 * stream_gen_ref_pkt 1251 * Purpose: 1252 * Generate reference packet by retrieving pkt_size and seq_id 1253 * from the given rx packet. 1254 * Parameters: 1255 * pkt_intg - ptr to packet integrity struct, containing all necessary 1256 * parameters needed for integrity check. 1257 * rx_pkt - ptr to rx packet. 1258 * ref_pkt - ptr to reference packet. 1259 * pkt_size - packet size of reference packet 1260 * 1261 * Returns: 1262 * SOC_E_XXXX 1263 */ 1264 bcm_error_t 1265 stream_gen_ref_pkt(int unit, int port, stream_integrity_t *pkt_intg, 1266 uint8 *rx_pkt, uint8 *ref_pkt, uint32 *pkt_size) 1267 { 1268 bcm_error_t rv = BCM_E_NONE; 1269 1270 if (pkt_intg->type == PKT_TYPE_L2 || 1271 pkt_intg->type == PKT_TYPE_L2_TS) { 1272 stream_gen_ref_l2_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt, pkt_size); 1273 } else if (pkt_intg->type == PKT_TYPE_IPMC || 1274 pkt_intg->type == PKT_TYPE_L3UC) { 1275 stream_gen_ref_l3_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt, pkt_size); 1276 } else { 1277 rv = BCM_E_FAIL; 1278 } 1279 1280 return rv; 1281 } 1282 1283 /* 1284 * Function: 1285 * stream_pktdma_tx 1286 * Purpose: 1287 * Transmit one packet from CPU 1288 * Parameters: 1289 * unit - StrataSwitch Unit #. 1290 * dv - ptr to tx dma descriptor vector 1291 * pkt - ptr to store tx packet 1292 * cnt - number of bytes for tx packet 1293 * 1294 * Returns: 1295 * SOC_E_XXXX 1296 */ 1297 bcm_error_t 1298 stream_pktdma_tx(int unit, dv_t *dv, uint8 *pkt, uint16 cnt) 1299 { 1300 bcm_error_t rv = BCM_E_NONE; 1301 int channel_done = 0; 1302 uint32 timeout = TXDMA_TIMEOUT; 1303 uint32 flags = 0; 1304 pbmp_t lp_pbmp; 1305 pbmp_t empty_pbmp0; 1306 pbmp_t empty_pbmp1; 1307 1308 SOC_PBMP_CLEAR(lp_pbmp); 1309 SOC_PBMP_PORT_ADD(lp_pbmp, 1); 1310 SOC_PBMP_CLEAR(empty_pbmp0); 1311 SOC_PBMP_CLEAR(empty_pbmp1); 1312 1313 soc_dma_abort_dv(unit, dv); 1314 soc_dma_dv_reset(DV_TX, dv); 1315 soc_dma_desc_add(dv, (sal_vaddr_t) (pkt), cnt, 1316 lp_pbmp, empty_pbmp0, empty_pbmp1, flags, NULL); 1317 soc_dma_desc_end_packet(dv); 1318 SOC_IF_ERROR_RETURN( 1319 soc_dma_chan_config(unit, TX_CHAN, DV_TX, SOC_DMA_F_POLL)); 1320 soc_dma_start(unit, TX_CHAN, dv); 1321 1322 while (channel_done == 0 && (timeout--) > 0) { 1323 soc_dma_chan_poll_done(unit, TX_CHAN, SOC_DMA_POLL_CHAIN_DONE, 1324 &channel_done); 1325 } 1326 if (channel_done == 0) { 1327 rv = BCM_E_FAIL; 1328 } 1329 soc_dma_done_desc(unit, TX_CHAN); 1330 1331 return rv; 1332 } 1333 1334 /* 1335 * Function: 1336 * stream_pktdma_rx 1337 * Purpose: 1338 * Receive packet by CPU from given vlan 1339 * Parameters: 1340 * unit - StrataSwitch Unit #. 1341 * rst_vlan - reset vlan 1342 * 0 -> no reset 1343 * 1 -> invalid vlan for L2 packet 1344 * 2 -> invalid vlan for L3 packet 1345 * vlan - vlan ID 1346 * dv - ptr to rx dma descriptor 1347 * pkt - ptr to store rx packet 1348 * cnt - number of bytes of rx packet 1349 * 1350 * Returns: 1351 * SOC_E_XXXX 1352 */ 1353 bcm_error_t 1354 stream_pktdma_rx(int unit, int rst_vlan, bcm_vlan_t vlan, 1355 dv_t *dv, uint8 *pkt, uint16 cnt) 1356 { 1357 bcm_error_t rv = BCM_E_NONE; 1358 int k; 1359 int channel_done = 0; 1360 uint32 timeout = RXDMA_TIMEOUT; 1361 uint32 flags = 0; 1362 pbmp_t lp_pbmp; 1363 pbmp_t empty_pbmp0; 1364 pbmp_t empty_pbmp1; 1365 1366 SOC_PBMP_CLEAR(lp_pbmp); 1367 SOC_PBMP_PORT_ADD(lp_pbmp, 1); 1368 SOC_PBMP_CLEAR(empty_pbmp0); 1369 SOC_PBMP_CLEAR(empty_pbmp1); 1370 1371 cnt = (cnt <= MTU) ? (cnt) : (MTU); 1372 for (k = 0; k < cnt; k++) { 1373 pkt[k] = 0x00; 1374 } 1375 1376 /* set up dma to receive packet */ 1377 channel_done = 0; 1378 soc_dma_abort_dv(unit, dv); 1379 soc_dma_dv_reset(DV_RX, dv); 1380 soc_dma_desc_add(dv, (sal_vaddr_t) (pkt), cnt, 1381 lp_pbmp, empty_pbmp0, empty_pbmp1, flags, NULL); 1382 soc_dma_desc_end_packet(dv); 1383 SOC_IF_ERROR_RETURN( 1384 soc_dma_chan_config(unit, RX_CHAN, DV_RX, SOC_DMA_F_POLL)); 1385 soc_dma_start(unit, RX_CHAN, dv); 1386 1387 /* forward packet to CPU by making packet size invalid */ 1388 if (rst_vlan != 0) { 1389 if (rst_vlan == 1) { 1390 stream_set_vlan_invalid(unit, vlan); 1391 } else if (rst_vlan == 2) { 1392 stream_set_l3mtu_invalid(unit, vlan); 1393 } 1394 } 1395 1396 /* wait until packet received or timeout */ 1397 while (channel_done == 0 && (timeout--) > 0) { 1398 soc_dma_chan_poll_done(unit, RX_CHAN, SOC_DMA_POLL_CHAIN_DONE, 1399 &channel_done); 1400 } 1401 if (channel_done == 0) { 1402 rv = BCM_E_FAIL; 1403 } 1404 1405 /* valid vlan to disable forwarding packet to CPU */ 1406 /* stream_set_vlan_valid(unit, vlan); */ 1407 1408 return rv; 1409 } 1410 1411 /* 1412 * Function: 1413 * stream_tx_pkt 1414 * Purpose: 1415 * Transmit packet from CPU through pkt_dma 1416 * Parameters: 1417 * unit - StrataSwitch Unit #. 1418 * dv - ptr to tx dma descriptor vector 1419 * pkt - ptr to store tx packet 1420 * cnt - number of bytes for tx packet 1421 * 1422 * Returns: 1423 * SOC_E_XXXX 1424 */ 1425 bcm_error_t 1426 stream_tx_pkt(int unit, stream_pkt_t *tx_pkt) 1427 { 1428 bcm_error_t rv = BCM_E_NONE; 1429 uint32 j; 1430 uint32 pkt_size; 1431 uint8 tos; 1432 uint8 *pkt_ptr; 1433 dv_t *dv_tx; 1434 1435 dv_tx = soc_dma_dv_alloc(unit, DV_TX, 3); 1436 soc_dma_init(unit); 1437 1438 tx_pkt->cnt_pkt = 0; 1439 pkt_size = tx_pkt->pkt_size; 1440 for (j = 0; j < tx_pkt->num_pkt; j++) { 1441 if (tx_pkt->rand_pkt_size_en == 1 && tx_pkt->rand_pkt_size != NULL) { 1442 pkt_size = tx_pkt->rand_pkt_size[j]; 1443 } 1444 tos = (j%2) ? 0x55: 0xaa; 1445 pkt_ptr = sal_dma_alloc(pkt_size * sizeof(uint8), "packet"); 1446 sal_srand(tx_pkt->pkt_seed + j); 1447 if (tx_pkt->new_flow_en == 1) { 1448 tos = 0; 1449 stream_gen_random_mpls_l3_pkt(pkt_ptr, 1450 tx_pkt, 1451 pkt_size, 1452 j, 1453 tos); 1454 } else if (tx_pkt->l3_en == 1) { 1455 stream_gen_random_l3_pkt(pkt_ptr, 1456 tx_pkt->ipv6_en, 1457 pkt_size, 1458 j, 1459 tx_pkt->mac_da, 1460 tx_pkt->mac_sa, 1461 (uint16) tx_pkt->tx_vlan, 1462 tx_pkt->ip_da, 1463 tx_pkt->ip_sa, 1464 tx_pkt->ttl, tos); 1465 } else { 1466 stream_gen_random_l2_pkt(pkt_ptr, 1467 pkt_size, 1468 j, 1469 tx_pkt->mac_da, 1470 tx_pkt->mac_sa, 1471 TPID, 1472 (uint16) tx_pkt->tx_vlan); 1473 } 1474 1475 if (stream_pktdma_tx(unit, dv_tx, pkt_ptr, pkt_size) != BCM_E_NONE) { 1476 rv = BCM_E_FAIL; 1477 cli_out("*ERROR: Waiting for tx_pkt done, " 1478 "port %0d, pkt_num %0d\n", 1479 tx_pkt->port, j); 1480 } else { 1481 tx_pkt->cnt_pkt++; 1482 } 1483 sal_dma_free(pkt_ptr); 1484 } 1485 1486 soc_dma_abort_dv(unit, dv_tx); 1487 soc_dma_dv_reset(DV_TX, dv_tx); 1488 soc_dma_dv_free(unit, dv_tx); 1489 1490 return rv; 1491 } 1492 1493 /* 1494 * Function: 1495 * stream_calc_pipe_ovs_ratio 1496 * Purpose: 1497 * Calculate oversub ratio for each pipe based on port config 1498 * Parameters: 1499 * unit: StrataSwitch Unit #. 1500 * pkt_size: packet size in bytes 1501 * num_pipe: number of pipes per device 1502 * pipe_ovs_ratio_x1000: ptr to pipe oversub ratio array 1503 * 1504 * Returns: 1505 * SOC_E_XXXX 1506 */ 1507 static bcm_error_t 1508 stream_calc_pipe_ovs_ratio(int unit, uint32 pkt_size, int num_pipe, 1509 uint32 *pipe_ovs_ratio_x1000) 1510 { 1511 int port, port_speed; 1512 int pipe, pipe_bandwidth = 0; 1513 int lr_bandwidth = 0, ov_bandwidth = 0; 1514 bcm_error_t rv = BCM_E_NONE; 1515 1516 cli_out("\nCalculate pipe oversub ratio\n"); 1517 1518 /* initialize */ 1519 pipe_bandwidth = stream_get_pipe_bandwidth(unit, 0) - 1520 stream_get_ancl_bandwidth(unit, 0); 1521 1522 for (pipe = 0; pipe < num_pipe; pipe++) { 1523 pipe_ovs_ratio_x1000[pipe] = 0; 1524 } 1525 1526 cli_out("Freq = %0d, BW_per_pipe = %0d\n", 1527 SOC_INFO(unit).frequency, pipe_bandwidth); 1528 1529 /* calculate oversub ratio for each pipe */ 1530 for (pipe = 0; pipe < num_pipe; pipe++) { 1531 lr_bandwidth = 0; 1532 ov_bandwidth = 0; 1533 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 1534 if (port < SOC_MAX_NUM_PORTS) { 1535 if (SOC_PBMP_MEMBER(PBMP_PIPE(unit, pipe), port)) { 1536 bcm_port_speed_get(unit, port, &port_speed); 1537 if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) { 1538 ov_bandwidth += port_speed; 1539 } else { 1540 lr_bandwidth += port_speed; 1541 } 1542 } 1543 } 1544 } 1545 1546 if ((pipe_bandwidth - lr_bandwidth) > 0) { 1547 pipe_ovs_ratio_x1000[pipe] = 1548 (ov_bandwidth * 1000) / (pipe_bandwidth - lr_bandwidth); 1549 if (pkt_size > 1550 stream_get_safe_pkt_size(unit, pipe_ovs_ratio_x1000[pipe])) { 1551 pipe_ovs_ratio_x1000[pipe] = 1000; 1552 } 1553 if (pipe_ovs_ratio_x1000[pipe] < 1000) { 1554 pipe_ovs_ratio_x1000[pipe] = 1000; 1555 } 1556 } else { 1557 pipe_ovs_ratio_x1000[pipe] = 0; 1558 } 1559 1560 cli_out("Pipe %0d, LR_BW = %0d, OV_BW = %0d, ovs_ratio_x1000 = %0d\n", 1561 pipe, lr_bandwidth, ov_bandwidth, 1562 pipe_ovs_ratio_x1000[pipe]); 1563 } 1564 1565 return rv; 1566 } 1567 1568 /* 1569 * Function: 1570 * stream_adjust_port_exp_rate_Mbps 1571 * Purpose: 1572 * Guarantee port expected rate is no greater than port max speed. 1573 * Parameters: 1574 * unit: StrataSwitch Unit #. 1575 * port: physical port number. 1576 * exp_rate_Mbps: ptr to port rate in Mbps. 1577 * 1578 * Returns: 1579 * SOC_E_XXXX 1580 */ 1581 static void 1582 stream_adjust_port_exp_rate_Mbps(int unit, int port, uint64 *exp_rate_Mbps) 1583 { 1584 int port_speed, encap; 1585 uint64 max_rate_64; 1586 1587 if (exp_rate_Mbps != NULL) { 1588 if (port < SOC_MAX_NUM_PORTS) { 1589 /* get 64bit speed in Mbps */ 1590 bcm_port_speed_get(unit, port, &port_speed); 1591 encap = (IS_HG_PORT(unit, port) | IS_HG2_ENABLED_PORT(unit, port)) ? 1592 BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE; 1593 if (!SOC_IS_TOMAHAWKX(unit)) { 1594 port_speed = stream_get_exact_speed(port_speed, encap); 1595 } 1596 COMPILER_64_ZERO(max_rate_64); 1597 COMPILER_64_SET(max_rate_64, 0, port_speed); 1598 1599 /* check exp_rate with max_rate*/ 1600 if (COMPILER_64_GT((*exp_rate_Mbps), max_rate_64)) { 1601 COMPILER_64_SET((*exp_rate_Mbps), 1602 COMPILER_64_HI(max_rate_64), 1603 COMPILER_64_LO(max_rate_64)); 1604 } 1605 } 1606 } 1607 } 1608 1609 /* 1610 * Function: 1611 * stream_calc_exp_rate_by_rx 1612 * Purpose: 1613 * Calculate expected rate array for all ports. This is based on port 1614 * speed and pipe oversub ratio (for oversubscribed ports). 1615 * Parameters: 1616 * unit: StrataSwitch Unit #. 1617 * port_rate_exp: ptr to expected rate array 1618 * rate_calc: interface containing all necessary parameters for rate 1619 * calculation 1620 * 1621 * Returns: 1622 * SOC_E_XXXX 1623 */ 1624 bcm_error_t 1625 stream_calc_exp_rate_by_rx(int unit, uint64 *port_rate_exp, 1626 stream_rate_t *rate_calc) 1627 { 1628 int port, port_src, port_speed, encap; 1629 uint32 pkt_size, num_pipe; 1630 uint64 meg; 1631 uint64 ovs_ratio_x1000_64,traffic_load_64; 1632 uint32 *pipe_ovs_ratio; 1633 uint64 *port_rate; 1634 uint32 *param_src_port; 1635 1636 bcm_error_t rv = BCM_E_NONE; 1637 1638 cli_out("\nCalculate expected port rate\n"); 1639 1640 /* initialize */ 1641 pkt_size = rate_calc->pkt_size; 1642 param_src_port = rate_calc->src_port; 1643 num_pipe = NUM_PIPE(unit); 1644 port_rate = port_rate_exp; 1645 pipe_ovs_ratio = (uint32 *) sal_alloc(num_pipe * sizeof(uint32), 1646 "pipe_ovs_ratio"); 1647 if (pipe_ovs_ratio == NULL) { 1648 test_error(unit, "Failed to allocate memory for exp rate check\n"); 1649 return BCM_E_FAIL; 1650 } 1651 sal_memset(pipe_ovs_ratio, 0, num_pipe * sizeof(uint32)); 1652 1653 COMPILER_64_SET(meg, 0, 1000000); 1654 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 1655 COMPILER_64_ZERO(port_rate[port]); 1656 } 1657 1658 /* calculate oversub ratio for each pipe */ 1659 stream_calc_pipe_ovs_ratio(unit, pkt_size, num_pipe, pipe_ovs_ratio); 1660 1661 1662 COMPILER_64_ZERO(traffic_load_64); 1663 /* calculate expected port rate */ 1664 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 1665 if (port < SOC_MAX_NUM_PORTS) { 1666 bcm_port_speed_get(unit, port, &port_speed); 1667 encap = (IS_HG_PORT(unit, port) | IS_HG2_ENABLED_PORT(unit, port)) ? 1668 BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE; 1669 if (!SOC_IS_TOMAHAWKX(unit)) { 1670 port_speed = stream_get_exact_speed(port_speed, encap); 1671 } 1672 1673 if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) { 1674 COMPILER_64_SET(port_rate[port], 0, port_speed); 1675 COMPILER_64_UMUL_32(port_rate[port], 1000000); 1676 COMPILER_64_SET(ovs_ratio_x1000_64, 0, 1677 pipe_ovs_ratio[stream_get_port_pipe(unit, port)]); 1678 COMPILER_64_UMUL_32(port_rate[port], 1000); 1679 COMPILER_64_SET(traffic_load_64, 0, 1000 * 100); 1680 if ( rate_calc->traffic_load != 0) { 1681 COMPILER_64_UDIV_32(traffic_load_64, rate_calc->traffic_load); 1682 } 1683 if (rate_calc->traffic_load != 0 && 1684 (!COMPILER_64_IS_ZERO(traffic_load_64)) && 1685 COMPILER_64_GT(traffic_load_64, ovs_ratio_x1000_64)) { 1686 COMPILER_64_UDIV_64(port_rate[port], traffic_load_64); 1687 } 1688 else { 1689 if (!COMPILER_64_IS_ZERO(ovs_ratio_x1000_64)) { 1690 COMPILER_64_UDIV_64(port_rate[port], ovs_ratio_x1000_64); 1691 } 1692 } 1693 } else { 1694 COMPILER_64_SET(port_rate[port], 0, port_speed); 1695 if (rate_calc->traffic_load != 0 && 1696 !COMPILER_64_IS_ZERO(traffic_load_64)) { 1697 COMPILER_64_UDIV_64(port_rate[port], traffic_load_64); 1698 } 1699 COMPILER_64_UMUL_32(port_rate[port], 1000000); 1700 } 1701 COMPILER_64_UDIV_64(port_rate[port], meg); /* translate to Mbps */ 1702 } 1703 } 1704 1705 /* adjust expected port rate with src port rate */ 1706 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 1707 if (port < SOC_MAX_NUM_PORTS) { 1708 char rate_str[32]; 1709 port_src = param_src_port[port]; 1710 format_uint64_decimal(rate_str, port_rate[port], ','); 1711 LOG_INFO(BSL_LS_APPL_TESTS, 1712 (BSL_META_U(unit, "adjust expected port rate with src port rate dst_port = %8d src_port = %8d src_port rate = %7sM \n"), 1713 port, port_src, rate_str)); 1714 if (port_src < SOC_MAX_NUM_PORTS && 1715 port_src != port && port_src > 0) { 1716 COMPILER_64_SET(port_rate[port], 1717 COMPILER_64_HI(port_rate[port_src]), 1718 COMPILER_64_LO(port_rate[port_src])); 1719 } 1720 } 1721 } 1722 1723 sal_free(pipe_ovs_ratio); 1724 return rv; 1725 } 1726 1727 /* 1728 * Function: 1729 * stream_calc_exp_rate_by_tx 1730 * Purpose: 1731 * Calculate expected rate array for all ports. This is based on port 1732 * speed and pipe oversub ratio (for oversubscribed ports). 1733 * Parameters: 1734 * unit: StrataSwitch Unit #. 1735 * port_rate_exp: ptr to expected rate array 1736 * port_rate_act: ptr to actual rate array 1737 * rate_calc: interface containing all necessary parameters for rate 1738 * calculation 1739 * 1740 * Returns: 1741 * SOC_E_XXXX 1742 */ 1743 static bcm_error_t 1744 stream_calc_exp_rate_by_tx(int unit, pbmp_t pbmp, uint64 *rate_exp, 1745 uint64 *rate_act, stream_rate_t *rate_calc) 1746 { 1747 uint32 port, p, n; 1748 uint32 *src_port_array; 1749 uint32 *num_rep_array; 1750 bcm_error_t rv = BCM_E_NONE; 1751 1752 cli_out("\nCalculate expected port rate\n"); 1753 1754 /* initialize */ 1755 src_port_array = rate_calc->src_port; 1756 num_rep_array = rate_calc->num_rep; 1757 1758 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 1759 COMPILER_64_ZERO(rate_exp[port]); 1760 } 1761 1762 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 1763 if (port < SOC_MAX_NUM_PORTS) { 1764 p = src_port_array[port]; 1765 n = num_rep_array[port]; 1766 COMPILER_64_SET(rate_exp[port], COMPILER_64_HI(rate_act[p]), 1767 COMPILER_64_LO(rate_act[p])); 1768 if (n > 0) { 1769 COMPILER_64_UMUL_32(rate_exp[port], n); 1770 } 1771 /* make sure expected rate is no greater than config rate */ 1772 stream_adjust_port_exp_rate_Mbps(unit, port, &(rate_exp[port])); 1773 } 1774 } 1775 1776 return rv; 1777 } 1778 1779 1780 bcm_error_t 1781 record_rate_information(int unit, uint32 emulation_param, pbmp_t pbmp, uint64 *time, uint64 *pkt_cnt, uint64 *byt_cnt) 1782 { 1783 int port; 1784 uint64 rdata; 1785 soc_reg_t reg_tpkt, reg_tbyt; 1786 1787 PBMP_ITER(pbmp, port) { 1788 if (port < SOC_MAX_NUM_PORTS) { 1789 time[port] = get_cur_time(unit, emulation_param); 1790 if (SOC_IS_TOMAHAWK3(unit)){ 1791 bcm_stat_sync_get(unit, port, snmpIfInUcastPkts, &(pkt_cnt[port])); 1792 bcm_stat_sync_get(unit, port, snmpIfInOctets, &(byt_cnt[port])); 1793 } else { 1794 BCM_IF_ERROR_RETURN(stream_get_reg_tpkt_tbyt(unit, port, 1795 ®_tpkt, ®_tbyt)); 1796 (void) soc_reg_get(unit, reg_tpkt, port, 0, &rdata); 1797 COMPILER_64_SET(pkt_cnt[port], COMPILER_64_HI(rdata), 1798 COMPILER_64_LO(rdata)); 1799 1800 (void) soc_reg_get(unit, reg_tbyt, port, 0, &rdata); 1801 COMPILER_64_SET(byt_cnt[port], COMPILER_64_HI(rdata), 1802 COMPILER_64_LO(rdata)); 1803 } 1804 } 1805 } 1806 return BCM_E_NONE; 1807 } 1808 1809 void 1810 calc_act_port_rate(int unit, pbmp_t pbmp, uint64 *time_start, uint64 *time_end, 1811 uint64 *pkt_start, uint64 *pkt_end, uint64 *byt_start, 1812 uint64 *byt_end, uint64 *port_rate) 1813 { 1814 int port; 1815 uint32 ipg, preamble; 1816 uint64 time_delta, pkt_delta, byt_delta; 1817 1818 PBMP_ITER(pbmp, port) { 1819 if (port < SOC_MAX_NUM_PORTS) { 1820 if (IS_HG_PORT(unit, port)) { 1821 ipg = HG2_IPG; 1822 preamble = 0; 1823 } else { 1824 ipg = ENET_IPG; 1825 preamble = ENET_PREAMBLE; 1826 } 1827 COMPILER_64_DELTA(time_delta, time_start[port], time_end[port]); 1828 1829 COMPILER_64_DELTA(pkt_delta, pkt_start[port], pkt_end[port]); 1830 COMPILER_64_DELTA(byt_delta, byt_start[port], byt_end[port]); 1831 COMPILER_64_UMUL_32(pkt_delta, (ipg + preamble)); 1832 COMPILER_64_ADD_64(byt_delta, pkt_delta); 1833 COMPILER_64_UMUL_32(byt_delta, 8); 1834 COMPILER_64_SET(port_rate[port], COMPILER_64_HI(byt_delta), 1835 COMPILER_64_LO(byt_delta)); 1836 COMPILER_64_UDIV_64(port_rate[port], time_delta); 1837 } 1838 } 1839 } 1840 1841 1842 /* 1843 * Function: 1844 * stream_calc_act_port_rate 1845 * Purpose: 1846 * Calculate actual rate array for all ports. This is based on port 1847 * speed and pipe oversub ratio (for oversubscribed ports). 1848 * Parameters: 1849 * unit: StrataSwitch Unit #. 1850 * scaling_factor: emulator speedup scaling factor, default 1; 1851 * rate_interval: interval length for rate calculation 1852 * port_rate_act : ptr to port actual rate array (x1000) 1853 * 1854 * Returns: 1855 * SOC_E_XXXX 1856 */ 1857 static bcm_error_t 1858 stream_calc_act_port_rate(int unit, uint32 emulation_param, 1859 uint32 rate_interval, uint64 *port_rate_act) 1860 { 1861 int port; 1862 bcm_error_t rv = BCM_E_NONE; 1863 uint32 interval_len; 1864 uint64 *port_rate; 1865 uint64 *time_start, *time_end; 1866 uint64 *tpkt_start, *tpkt_end, 1867 *tbyt_start, *tbyt_end; 1868 1869 cli_out("\nCalculate actual port rate\n"); 1870 1871 /* initialize */ 1872 interval_len = rate_interval; 1873 port_rate = port_rate_act; 1874 1875 time_start = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1876 "time_start"); 1877 time_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1878 "time_end"); 1879 tpkt_start = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1880 "tpkt_start"); 1881 tpkt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1882 "tpkt_end"); 1883 tbyt_start = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1884 "tbyt_start"); 1885 tbyt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1886 "tbyt_end"); 1887 if (time_start == NULL || time_end == NULL || 1888 tpkt_start == NULL || tpkt_end == NULL || 1889 tbyt_start == NULL || tbyt_end == NULL) { 1890 sal_free(time_start); 1891 sal_free(time_end); 1892 sal_free(tpkt_start); 1893 sal_free(tpkt_end); 1894 sal_free(tbyt_start); 1895 sal_free(tbyt_end); 1896 cli_out("*ERROR, Failed to allocate memory in " 1897 "stream_calc_act_port_rate()\n"); 1898 return BCM_E_FAIL; 1899 } 1900 1901 sal_memset(time_start, 0, SOC_MAX_NUM_PORTS * sizeof(uint64)); 1902 sal_memset(time_end, 0, SOC_MAX_NUM_PORTS * sizeof(uint64)); 1903 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 1904 COMPILER_64_ZERO(port_rate[port]); 1905 COMPILER_64_ZERO(tpkt_start[port]); 1906 COMPILER_64_ZERO(tpkt_end[port]); 1907 COMPILER_64_ZERO(tbyt_start[port]); 1908 COMPILER_64_ZERO(tbyt_end[port]); 1909 } 1910 1911 /* wait 2s for traffic to stabilize */ 1912 cli_out("-- Wait 2s for traffic to stabilize\n"); 1913 sal_usleep(2000000); 1914 /* read counters at the beginning of interval */ 1915 record_rate_information(unit, emulation_param, PBMP_PORT_ALL(unit), time_start, 1916 tpkt_start, tbyt_start); 1917 1918 /* wait xs according to interval_len value */ 1919 cli_out("-- Measure Rate over a period of %0ds\n", interval_len); 1920 sal_usleep(interval_len * 1000000); 1921 /* read counters at the end of interval */ 1922 record_rate_information(unit, emulation_param, PBMP_PORT_ALL(unit), time_end, 1923 tpkt_end, tbyt_end); 1924 1925 calc_act_port_rate(unit, PBMP_PORT_ALL(unit), time_start, time_end, 1926 tpkt_start, tpkt_end, tbyt_start, tbyt_end, 1927 port_rate); 1928 1929 sal_free(time_start); 1930 sal_free(time_end); 1931 sal_free(tpkt_start); 1932 sal_free(tpkt_end); 1933 sal_free(tbyt_start); 1934 sal_free(tbyt_end); 1935 return rv; 1936 } 1937 1938 /* 1939 * Function: 1940 * stream_chk_dma_chain_done 1941 * Purpose: 1942 * Check chain done or desc done bit in DMA status register. 1943 * Parameters: 1944 * unit - StrataSwitch Unit #. 1945 * vchan - Virtual channel number 1946 * type - check desc done or chain done 1947 * detected - whether desc done or chain done was detected 1948 * 1949 * Returns: 1950 * SOC_E_XXXX 1951 */ 1952 bcm_error_t 1953 stream_chk_dma_chain_done(int unit, int vchan, soc_dma_poll_type_t type, 1954 int *detected) 1955 { 1956 int rv = SOC_E_NONE; 1957 int cmc = vchan / N_DMA_CHAN; 1958 int chan = vchan % N_DMA_CHAN; 1959 1960 switch (type) { 1961 case SOC_DMA_POLL_DESC_DONE: 1962 *detected = (soc_pci_read(unit, CMIC_CMCx_DMA_STAT_OFFSET(cmc)) 1963 & DS_CMCx_DMA_DESC_DONE(chan)); 1964 break; 1965 case SOC_DMA_POLL_CHAIN_DONE: 1966 *detected = (soc_pci_read(unit, CMIC_CMCx_DMA_STAT_OFFSET(cmc)) 1967 & DS_CMCx_DMA_CHAIN_DONE(chan)); 1968 break; 1969 default: 1970 break; 1971 } 1972 1973 return rv; 1974 } 1975 1976 /* 1977 * Function: 1978 * stream_chk_mib_counters 1979 * Purpose: 1980 * Checks MIB counters in MAC, IP, and EP 1981 * Parameters: 1982 * unit - StrataSwitch Unit #. 1983 * pbmp - Device port bitmap to be checked 1984 * flag - set to 1 to check extra counter registers, default 0. 1985 * 1986 * Returns: 1987 * SOC_E_XXXX 1988 */ 1989 bcm_error_t 1990 stream_chk_mib_counters(int unit, pbmp_t pbmp, int flag) 1991 { 1992 uint32 port, j, column; 1993 uint32 good_reg_num, error_reg_num; 1994 uint64 rdata; 1995 int pblk, phy_port; 1996 bcm_error_t rv = BCM_E_NONE; 1997 soc_reg_t good_counters[][4] = { 1998 {RUCr, RUC_64r, RUC_64r, RUC_64r}, 1999 {RPKTr, XLMIB_RPKTr, CLMIB_RPKTr, GRPKTr}, 2000 {RUCAr, XLMIB_RUCAr, CLMIB_RUCAr, GRUCr}, 2001 {RVLNr, XLMIB_RVLNr, CLMIB_RVLNr, INVALIDr}, 2002 {RBYTr, XLMIB_RBYTr, CLMIB_RBYTr, GRBYTr}, 2003 {RIPC4r, RIPC4_64r, RIPC4_64r, RIPC4_64r}, 2004 {TPKTr, XLMIB_TPKTr, CLMIB_TPKTr, GTPKTr}, 2005 {TUCAr, XLMIB_TUCAr, CLMIB_TUCAr, GTUCr}, 2006 {TVLNr, XLMIB_TVLNr, CLMIB_TVLNr, INVALIDr}, 2007 {TBYTr, XLMIB_TBYTr, CLMIB_TBYTr, GTBYTr} 2008 }; 2009 soc_reg_t error_counters[][4] = { 2010 {RFLRr, XLMIB_RFLRr, CLMIB_RFLRr, GRFLRr}, 2011 {RFCSr, XLMIB_RFCSr, CLMIB_RFCSr, GRFCSr}, 2012 {RJBRr, XLMIB_RJBRr, CLMIB_RJBRr, GRJBRr}, 2013 {RMTUEr, XLMIB_RMTUEr, CLMIB_RMTUEr, GRMTUEr}, 2014 {RTRFUr, XLMIB_RTRFUr, CLMIB_RTRFUr, INVALIDr}, 2015 {RERPKTr, XLMIB_RERPKTr, CLMIB_RERPKTr, GRCDEr}, 2016 {RRPKTr, XLMIB_RRPKTr, CLMIB_RRPKTr, GRRPKTr}, 2017 {RUNDr, XLMIB_RUNDr, CLMIB_RUNDr, GRUNDr}, 2018 {RFRGr, XLMIB_RFRGr, CLMIB_RFRGr, GRFRGr}, 2019 {RRBYTr, XLMIB_RRBYTr, CLMIB_RRBYTr, GRRBYTr}, 2020 {TJBRr, XLMIB_TJBRr, CLMIB_TJBRr, GTJBRr}, 2021 {TFCSr, XLMIB_TFCSr, CLMIB_TFCSr, GTFCSr}, 2022 {TERRr, XLMIB_TERRr, CLMIB_TERRr, GTXCLr}, 2023 {TFRGr, XLMIB_TFRGr, CLMIB_TFRGr, GTFRGr}, 2024 {TRPKTr, XLMIB_TRPKTr, CLMIB_TRPKTr, INVALIDr}, 2025 {TUFLr, XLMIB_TUFLr, CLMIB_TUFLr, INVALIDr}, 2026 {TPCEr, TPCE_64r, TPCE_64r, TPCE_64r}, 2027 {RDISCr, RDISC_64r, RDISC_64r, RDISC_64r}, 2028 {RIPHE4r, RIPHE4_64r, RIPHE4_64r, RIPHE4_64r}, 2029 {RIPHE6r, RIPHE6_64r, RIPHE6_64r, RIPHE6_64r}, 2030 {RIPD4r, RIPD4_64r, RIPD4_64r, RIPD4_64r}, 2031 {RIPD6r, RIPD6_64r, RIPD6_64r, RIPD6_64r}, 2032 {RPORTDr, RPORTD_64r, RPORTD_64r, RPORTD_64r} 2033 }; 2034 2035 good_reg_num = sizeof(good_counters) / sizeof(good_counters[0]); 2036 error_reg_num = sizeof(error_counters) / sizeof(error_counters[0]); 2037 cli_out("\n==================================================\n"); 2038 cli_out("Checking Counter ...\n"); 2039 2040 PBMP_ITER(pbmp, port) { 2041 if (port < SOC_MAX_NUM_PORTS) { 2042 column = 0; 2043 2044 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 2045 if(phy_port == -1) { 2046 cli_out("\nERROR : Invalid logical port %0d used in counter " 2047 "check.", port); 2048 return BCM_E_INTERNAL; 2049 } 2050 2051 if (soc_feature(unit, soc_feature_cxl_mib)) { 2052 pblk = SOC_PORT_BLOCK(unit, phy_port); 2053 if (SOC_BLOCK_IS_CMP(unit, pblk, SOC_BLK_CLPORT)) { 2054 column = 2; 2055 } else if (IS_QSGMII_PORT(unit, port)) { 2056 column = 3; 2057 } else { 2058 column = 1; 2059 } 2060 } 2061 if (flag != 0) { 2062 for (j = 0; j < good_reg_num; j++) { 2063 if (SOC_REG_IS_VALID(unit, good_counters[j][column])) { 2064 SOC_IF_ERROR_RETURN( 2065 soc_reg_get(unit, good_counters[j][column], port, 0, &rdata)); 2066 if (COMPILER_64_IS_ZERO(rdata)) { 2067 cli_out("*ERROR: (a) Counter %s " 2068 "has a zero value for port %0d\n", 2069 SOC_REG_NAME(unit, good_counters[j][column]), port); 2070 rv = BCM_E_FAIL; 2071 } 2072 } 2073 } 2074 } 2075 2076 for (j = 0; j < error_reg_num; j++) { 2077 if (SOC_REG_IS_VALID(unit, error_counters[j][column])) { 2078 SOC_IF_ERROR_RETURN( 2079 soc_reg_get(unit, error_counters[j][column], port, 0, &rdata)); 2080 if (!COMPILER_64_IS_ZERO(rdata)) { 2081 cli_out("*ERROR: (b) Counter %s " 2082 "has a non zero value for port %0d\n", 2083 SOC_REG_NAME(unit, error_counters[j][column]), port); 2084 rv = BCM_E_FAIL; 2085 } 2086 } 2087 } 2088 } 2089 } 2090 2091 if (rv != BCM_E_NONE) { 2092 cli_out("\n********* COUNTER CHECK FAILED *********\n"); 2093 } else { 2094 cli_out("\n********* COUNTER CHECK PASSED *********\n"); 2095 } 2096 return rv; 2097 } 2098 2099 2100 /* 2101 * Function: 2102 * compare_rates 2103 * Purpose: 2104 * Helper funtion to compare actual and expected rates. 2105 * Parameters: 2106 * unit - StrataSwitch Unit #. 2107 * pbmp - Device port bitmap to be checked 2108 * tolerance_lr - Rate tolerance allowed for LR ports 2109 * tolerance_os - Rate tolerance allowed for OVS ports 2110 * port_rate_exp - expected port rate array 2111 * port_rate_act - actual port rate array 2112 * 2113 * Returns: 2114 * SOC_E_XXXX 2115 */ 2116 bcm_error_t 2117 compare_rates(int unit, pbmp_t pbmp, uint32 tolerance_lr, uint32 tolerance_os, 2118 uint64 *port_rate_exp, uint64 *port_rate_act) 2119 { 2120 int cnt = 0, port, port_speed, encap; 2121 uint32 tolerance; 2122 uint64 min_rate, max_rate, hundred_64, margin_of_error; 2123 char exp_rate_str[32], act_rate_str[32], 2124 max_rate_str[32], min_rate_str[32]; 2125 bcm_error_t rv = BCM_E_NONE; 2126 2127 COMPILER_64_SET(hundred_64, 0, 100); 2128 2129 /* check actual rate against expected rate under tolerant range */ 2130 LOG_INFO(BSL_LS_APPL_TESTS, 2131 (BSL_META_U(unit, "\n%4s %8s %8s %8s %8s %8s %8s \n"), 2132 "idx", "Dev_Port", "Speed", "Exp_Rate", 2133 "Min_Rate", "Max_Rate", "Act_Rate")); 2134 2135 PBMP_ITER(pbmp, port) { 2136 if (port < SOC_MAX_NUM_PORTS) { 2137 bcm_port_speed_get(unit, port, &port_speed); 2138 encap = (IS_HG_PORT(unit, port) | IS_HG2_ENABLED_PORT(unit, port)) ? 2139 BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE; 2140 if (!SOC_IS_TOMAHAWKX(unit)) { 2141 port_speed = stream_get_exact_speed(port_speed, encap); 2142 } 2143 2144 /* margin_of_error */ 2145 if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) { 2146 tolerance = tolerance_os; 2147 } else { 2148 tolerance = tolerance_lr; 2149 } 2150 2151 /* adjust speed tolerance */ 2152 if (SOC_IS_TRIDENT3X(unit)) { 2153 /* plus 1% extra tolerance for 10G higig */ 2154 if ((encap == BCM_PORT_ENCAP_HIGIG2) && 2155 (port_speed <= 11000 && port_speed >= 10000)) { 2156 tolerance +=1; 2157 } 2158 } 2159 2160 /* max_rate */ 2161 COMPILER_64_SET(max_rate, 0, port_speed); 2162 COMPILER_64_SET(margin_of_error, 0, port_speed); 2163 COMPILER_64_UMUL_32(margin_of_error, tolerance); 2164 COMPILER_64_UDIV_64(margin_of_error, hundred_64); 2165 COMPILER_64_ADD_64(max_rate, margin_of_error); 2166 2167 /* min_rate */ 2168 COMPILER_64_SET(margin_of_error, 2169 COMPILER_64_HI(port_rate_exp[port]), 2170 COMPILER_64_LO(port_rate_exp[port])); 2171 COMPILER_64_UMUL_32(margin_of_error, tolerance); 2172 COMPILER_64_UDIV_64(margin_of_error, hundred_64); 2173 COMPILER_64_DELTA(min_rate, margin_of_error, port_rate_exp[port]); 2174 2175 /* printout */ 2176 format_uint64_decimal(min_rate_str, min_rate, ','); 2177 format_uint64_decimal(max_rate_str, max_rate, ','); 2178 format_uint64_decimal(exp_rate_str, port_rate_exp[port], ','); 2179 format_uint64_decimal(act_rate_str, port_rate_act[port], ','); 2180 LOG_INFO(BSL_LS_APPL_TESTS, 2181 (BSL_META_U(unit, "%4d %8d %7dG %7sM %7sM %7sM %7sM "), 2182 cnt, port, port_speed/1000, 2183 exp_rate_str, min_rate_str, 2184 max_rate_str, act_rate_str)); 2185 2186 /* check */ 2187 if (COMPILER_64_LT(port_rate_act[port], min_rate)) { 2188 rv = BCM_E_FAIL; 2189 LOG_INFO(BSL_LS_APPL_TESTS, 2190 (BSL_META_U(unit, " %s"), "*FAIL")); 2191 } else if (COMPILER_64_GT(port_rate_act[port], max_rate)) { 2192 LOG_INFO(BSL_LS_APPL_TESTS, 2193 (BSL_META_U(unit, " %s"), "*WARNING")); 2194 } 2195 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 2196 2197 cnt++; 2198 } 2199 } 2200 return rv; 2201 } 2202 2203 /* 2204 * Function: 2205 * stream_chk_port_rate_new 2206 * Purpose: 2207 * Check rates against expected rates. 2208 * Parameters: 2209 * unit - StrataSwitch Unit #. 2210 * pbmp - Device port bitmap to be checked 2211 * rate_calc - ptr to rate struct, containing all necessary 2212 * parameters needed for port rate check. 2213 * 2214 * Returns: 2215 * SOC_E_XXXX 2216 */ 2217 bcm_error_t 2218 stream_chk_port_rate(int unit, pbmp_t pbmp, stream_rate_t *rate_calc) 2219 { 2220 uint32 mode, interval_len, jitter_lr, jitter_os; 2221 uint64 *port_rate_exp, *port_rate_act; 2222 bcm_error_t rv = BCM_E_NONE; 2223 2224 cli_out("\n==================================================\n"); 2225 cli_out("Checking Port Rate ...\n\n"); 2226 /* initialize */ 2227 mode = rate_calc->mode; 2228 interval_len = rate_calc->interval_len; 2229 jitter_lr = rate_calc->tolerance_lr; 2230 jitter_os = rate_calc->tolerance_os; 2231 2232 port_rate_exp = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 2233 "port_rate_exp"); 2234 port_rate_act = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 2235 "port_rate_act"); 2236 if (port_rate_exp == NULL || port_rate_act == NULL) { 2237 sal_free(port_rate_exp); 2238 sal_free(port_rate_act); 2239 test_error(unit, "Failed to allocate memory for rate check\n"); 2240 return BCM_E_FAIL; 2241 } 2242 2243 /* calculate actual rate */ 2244 stream_calc_act_port_rate(unit, rate_calc->emulation_param, interval_len, 2245 port_rate_act); 2246 2247 /* calculate expected rate */ 2248 if (mode == 1) { 2249 /* mode -> 1, calculate expected rate by tx_rate */ 2250 stream_calc_exp_rate_by_tx(unit, pbmp, port_rate_exp, 2251 port_rate_act, rate_calc); 2252 } else { 2253 /* mode -> 0, calculate expected rate by rx config rate */ 2254 stream_calc_exp_rate_by_rx(unit, port_rate_exp, rate_calc); 2255 } 2256 2257 2258 rv = compare_rates(unit, rate_calc->pbmp, jitter_lr, jitter_os, port_rate_exp, port_rate_act); 2259 if (rv != BCM_E_NONE) { 2260 cli_out("\n********** RATE CHECK FAILED ***********\n"); 2261 } else { 2262 cli_out("\n********** RATE CHECK PASSED ***********\n"); 2263 } 2264 2265 sal_free(port_rate_exp); 2266 sal_free(port_rate_act); 2267 return rv; 2268 } 2269 2270 /* 2271 * Function: 2272 * stream_chk_pkt_integrity 2273 * Purpose: 2274 * Redirect all packets back to CPU and check packet integrity 2275 * Parameters: 2276 * unit - StrataSwitch Unit #. 2277 * pkt_intg - ptr to packet integrity struct, containing all necessary 2278 * parameters needed for integrity check. 2279 * 2280 * Returns: 2281 * SOC_E_XXXX 2282 */ 2283 bcm_error_t 2284 stream_chk_pkt_integrity(int unit, stream_integrity_t *pkt_intg) 2285 { 2286 bcm_error_t rv = BCM_E_NONE; 2287 uint8 *rx_pkt, *ref_pkt; 2288 int port, port_speed, j, k, chk_fail = 0, stream_cnt = 0; 2289 int rst_vlan; 2290 dv_t *dv_rx; 2291 uint32 vlan; 2292 uint32 pkt_size; 2293 uint32 port_exp_pkt_cnt, port_act_pkt_cnt, pkt_cnt_sum = 0; 2294 uint32 header_size = 0; 2295 uint32 ts1, ts2, latency, max = 0, min = -1, sum = 0, average; 2296 2297 cli_out("\n==================================================\n"); 2298 cli_out("Checking Packet Integrity ...\n\n"); 2299 /* initialize */ 2300 soc_dma_header_size_get(unit, &header_size); 2301 dv_rx = soc_dma_dv_alloc(unit, DV_RX, 3); 2302 ref_pkt = sal_dma_alloc(MTU * sizeof(uint8), "ref_packet"); 2303 rx_pkt = sal_dma_alloc(MTU * sizeof(uint8) + header_size, "rx_pkt"); 2304 if (dv_rx == NULL || ref_pkt == NULL || rx_pkt == NULL) { 2305 soc_dma_dv_free(unit, dv_rx); 2306 sal_dma_free(ref_pkt); 2307 sal_dma_free(rx_pkt); 2308 test_error(unit, "Failed to allocate memory for integrity check\n"); 2309 return BCM_E_FAIL; 2310 } 2311 2312 /* config all channels as RX */ 2313 soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 1, 0xffffffff); 2314 soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 2, 0xffffffff); 2315 2316 /* config unmatched VLAN packet to be forwarded to CPU */ 2317 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_0r, 0, 2318 UVLAN_TOCPUf, 0x1)); 2319 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_1r, 0, 2320 L3_MTU_FAIL_TOCPUf, 0x1)); 2321 2322 /* check packet integrity for each port */ 2323 LOG_INFO(BSL_LS_APPL_TESTS, 2324 (BSL_META_U(unit, "%4s %4s %4s %8s %8s\n"), 2325 "idx", "port", "spd", "tx_pkt", "rx_pkt")); 2326 PBMP_ITER(pkt_intg->rx_pbmp, port) { 2327 if (port < SOC_MAX_NUM_PORTS) { 2328 /* check integrity of each packet */ 2329 port_exp_pkt_cnt = pkt_intg->port_flood_cnt[port]; 2330 port_act_pkt_cnt = 0; 2331 vlan = pkt_intg->rx_vlan[port]; 2332 for (j = 0; j < port_exp_pkt_cnt; j++) { 2333 rst_vlan = 0; 2334 if (j == 0) { 2335 if (pkt_intg->type == PKT_TYPE_L3UC) { 2336 rst_vlan = 2; /* L3 packet*/ 2337 } else { 2338 rst_vlan = 1; /* L2 packet*/ 2339 } 2340 } 2341 /* receive one packet from CPU though rx_pkt_dma */ 2342 if (stream_pktdma_rx(unit, rst_vlan, vlan, dv_rx, rx_pkt, 2343 MTU + header_size) != BCM_E_NONE) { 2344 /* 2345 cli_out("*ERROR, failed to receive pkt from CPU" 2346 "for integrity check, port %d\n", 2347 port); 2348 chk_fail = 1; */ 2349 break; 2350 } 2351 port_act_pkt_cnt ++; 2352 2353 /* generate reference packet */ 2354 if (stream_gen_ref_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt, 2355 &pkt_size) != BCM_E_NONE) { 2356 cli_out("*ERROR, failed to generate ref_pkt " 2357 "for integrity check, port %d\n", 2358 port); 2359 chk_fail = 1; 2360 break; 2361 } 2362 2363 /* check packet content (payload) */ 2364 for (k = 0; k < (pkt_size - NUM_BYTES_CRC); k++) { 2365 if (rx_pkt[k + header_size] != ref_pkt[k]) { 2366 cli_out("*ERROR: Packet corruption, " 2367 "Stream %d, Port %d, Packet %d\n", 2368 stream_cnt, port, j); 2369 cli_out("-- Expected Packet:"); 2370 tgp_print_pkt(ref_pkt, pkt_size); 2371 cli_out("-- Received Packet:"); 2372 tgp_print_pkt(rx_pkt, pkt_size+header_size); 2373 chk_fail = 1; 2374 break; 2375 } 2376 } 2377 2378 /* latency calculation */ 2379 if (pkt_intg->type == PKT_TYPE_L2_TS) { 2380 ts1 = (rx_pkt[pkt_size+header_size+2] << 24) + (rx_pkt[pkt_size+header_size+3] << 16) + 2381 (rx_pkt[pkt_size+header_size+4] << 8) + rx_pkt[pkt_size+header_size+5]; 2382 ts2 = (rx_pkt[pkt_size+header_size+16] << 24) + (rx_pkt[pkt_size+header_size+17] << 16) + 2383 (rx_pkt[pkt_size+header_size+18] << 8) + rx_pkt[pkt_size+header_size+19]; 2384 latency = ts2 - ts1; 2385 if (latency < min) { 2386 min = latency; 2387 } 2388 if (latency > max) { 2389 max = latency; 2390 } 2391 sum += latency; 2392 LOG_INFO(BSL_LS_APPL_TESTS, 2393 (BSL_META_U(unit, "-- Packet %0d TS2 %0x TS1 %0x Latency %0d\n"), 2394 j, ts2, ts1, latency)); 2395 } 2396 } 2397 2398 /* disable forwarding pkt to cpu for current port */ 2399 if (pkt_intg->type == PKT_TYPE_L3UC) { 2400 stream_set_l3mtu_valid(unit, vlan); 2401 } else { 2402 stream_set_vlan_valid(unit, vlan); 2403 } 2404 2405 /* check packet count */ 2406 bcm_port_speed_get(unit, port, &port_speed); 2407 LOG_INFO(BSL_LS_APPL_TESTS, 2408 (BSL_META_U(unit, "%4d %4d %3dG %8d %8d "), 2409 stream_cnt, port, port_speed/1000, 2410 port_exp_pkt_cnt, port_act_pkt_cnt)); 2411 if (port_act_pkt_cnt == 0) { 2412 chk_fail = 1; 2413 LOG_INFO(BSL_LS_APPL_TESTS, 2414 (BSL_META_U(unit, "*WARNING"))); 2415 } else if (port_act_pkt_cnt < port_exp_pkt_cnt && 2416 !(SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port))) { 2417 chk_fail = 1; 2418 LOG_INFO(BSL_LS_APPL_TESTS, 2419 (BSL_META_U(unit, "*WARNING"))); 2420 } 2421 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 2422 2423 /* print latency */ 2424 if (pkt_intg->type == PKT_TYPE_L2_TS) { 2425 average = _shr_div_exp10(sum, port_act_pkt_cnt, 2); 2426 cli_out("Latency: max %0d ns, min %0d ns, average %0d.%02d ns\n", 2427 max, min, average / 100, average % 100); 2428 } 2429 2430 pkt_cnt_sum += port_act_pkt_cnt; 2431 stream_cnt++; 2432 } 2433 } 2434 2435 cli_out("Total packets received: %d\n", pkt_cnt_sum); 2436 if (chk_fail == 0) { 2437 cli_out("\n**** PACKET INTEGRITY CHECK PASSED *****\n"); 2438 } else { 2439 cli_out("\n**** PACKET INTEGRITY CHECK FAILED *****\n"); 2440 rv = BCM_E_FAIL; 2441 } 2442 2443 soc_dma_abort_dv(unit, dv_rx); 2444 soc_dma_dv_free(unit, dv_rx); 2445 sal_dma_free(rx_pkt); 2446 sal_dma_free(ref_pkt); 2447 2448 return rv; 2449 } 2450 2451 2452 int 2453 stream_get_exact_speed(int speed, int encap) { 2454 if(encap == BCM_PORT_ENCAP_IEEE) return speed; 2455 else { 2456 switch (speed) { 2457 case 120000: speed = 127000; break; 2458 case 100000: speed = 106000; break; 2459 case 50000: speed = 53000; break; 2460 case 40000: speed = 42000; break; 2461 case 25000: speed = 27000; break; 2462 case 20000: speed = 21000; break; 2463 case 10000: speed = 11000; break; 2464 default: break; 2465 } 2466 return speed; 2467 } 2468 } 2469 2470 /* 2471 * Function: 2472 * start_cmic_timesync 2473 * Purpose: 2474 * Enable CMIC timesync module to run NS timestamp 2475 * Parameters: 2476 * unit - StrataSwitch Unit #. 2477 * 2478 * Returns: 2479 * Nothing 2480 */ 2481 void start_cmic_timesync(int unit) 2482 { 2483 uint32 rval; 2484 2485 /* Enable Timestamp Generation */ 2486 READ_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, &rval); 2487 /* 250 Mhz - 4.000 ns */ 2488 soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr, &rval, FRACf, 2489 0x40000000); 2490 WRITE_CMIC_TIMESYNC_TS0_FREQ_CTRL_FRACr(unit, rval); 2491 2492 READ_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, &rval); 2493 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr, &rval, 2494 TIME_CAPTURE_ENABLEf, 1); 2495 WRITE_CMIC_TIMESYNC_TIME_CAPTURE_CONTROLr(unit, rval); 2496 2497 READ_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, &rval); 2498 soc_reg_field_set(unit, CMIC_TIMESYNC_TS0_COUNTER_ENABLEr, &rval, 2499 ENABLEf, 1); 2500 WRITE_CMIC_TIMESYNC_TS0_COUNTER_ENABLEr(unit, rval); 2501 } 2502 2503 uint64 get_ts_count(int unit) 2504 { 2505 uint64 ts, div_64; 2506 uint32 rval, valid, ts_lower, ts_upper; 2507 2508 if (soc_feature(unit, soc_feature_cmicx)) { 2509 /*soc_iproc_getreg(unit, 2510 soc_reg_addr(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, 2511 REG_PORT_ANY, 0), &rval); 2512 cli_out("\n ts capture %0x", rval);*/ 2513 rval = 0; 2514 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &rval, 2515 TIME_CAPTURE_MODEf, 1); 2516 /*soc_iproc_setreg(unit, 2517 soc_reg_addr(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, 2518 REG_PORT_ANY, 0), rval);*/ 2519 soc_pci_write(unit, 0x35024, rval); 2520 2521 rval = soc_pci_read(unit, 0x3502c); 2522 /*soc_iproc_getreg(unit, 2523 soc_reg_addr(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr, 2524 REG_PORT_ANY, 0), &rval); 2525 cli_out("\n ts lower %0x", rval);*/ 2526 ts_lower = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr, 2527 rval, TIMESTAMPf); 2528 rval = soc_pci_read(unit, 0x35030); 2529 /*soc_iproc_getreg(unit, 2530 soc_reg_addr(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, 2531 REG_PORT_ANY, 0), &rval); 2532 cli_out("\n ts upper %0x", rval);*/ 2533 valid = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, 2534 rval, VALIDf); 2535 ts_upper = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, 2536 rval, TIMESTAMPf); 2537 } else { 2538 READ_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, &rval); 2539 soc_reg_field_set(unit, CMIC_TIMESYNC_TIME_CAPTURE_MODEr, &rval, 2540 TIME_CAPTURE_MODEf, 1); 2541 WRITE_CMIC_TIMESYNC_TIME_CAPTURE_MODEr(unit, rval); 2542 READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr(unit, &rval); 2543 ts_lower = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_LOWERr, 2544 rval, TIMESTAMPf); 2545 READ_CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr(unit, &rval); 2546 valid = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, 2547 rval, VALIDf); 2548 ts_upper = soc_reg_field_get(unit, CMIC_TIMESYNC_INPUT_TIME_FIFO_TS_UPPERr, 2549 rval, TIMESTAMPf); 2550 } 2551 2552 COMPILER_64_SET(div_64, 0, 1000); 2553 COMPILER_64_ZERO(ts); 2554 if(valid) { 2555 COMPILER_64_SET(ts, ts_upper, ts_lower); 2556 COMPILER_64_UDIV_64(ts, div_64); 2557 } 2558 return ts; 2559 } 2560 2561 uint64 get_cur_time(int unit, uint32 emulation_param) 2562 { 2563 uint64 time; 2564 2565 if(emulation_param) time = get_ts_count(unit); 2566 else COMPILER_64_SET(time, 0, sal_time_usecs()); 2567 2568 return time; 2569 } 2570 2571 #endif /* BCM_ESW_SUPPORT */