streaming.c (71047B)
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 test to check TDM table and programming. Each port loops traffic 8 * back to itself using port bridging and higig lookup for HG ports. Test test 9 * calculates expected rates based on port config and oversub ratio and checks 10 * against it. 11 * Configuration parameters passed from CLI: 12 * PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all 13 * ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes 14 * FloodCnt: Number of packets in each swill. Setting this to 0 will let the 15 * test calculate the number of packets that can be sent to achieve 16 * a lossless swirl at full rate. Set to 0 by default. 17 * RateCalcInt: Interval in seconds over which rate is to be calculated 18 * TolLr: Rate tolerance percentage for linerate ports (1% by default). 19 * TolOv: Rate tolerance percentage for oversubscribed ports (3% by default). 20 * ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default). 21 * MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set 22 * to 0 for random. 23 */ 24 25 #include <appl/diag/system.h> 26 #include <shared/alloc.h> 27 #include <shared/bsl.h> 28 29 #include <soc/cm.h> 30 #include <soc/dma.h> 31 #include <soc/drv.h> 32 #include <soc/dcb.h> 33 #include <soc/cmicm.h> 34 #include <soc/cmic.h> 35 36 #include <sal/types.h> 37 #include <appl/diag/parse.h> 38 #include <bcm/port.h> 39 #include <bcm/vlan.h> 40 #include <bcm/stat.h> 41 42 #include "testlist.h" 43 #include "gen_pkt.h" 44 45 #if defined(BCM_TRIDENT3_SUPPORT) 46 47 #define TD3_CELL_SIZE 256 48 #define TD3_NUM_HPIPE_PER_PIPE 2 49 #define TD3_NUM_PIPE 2 50 #define TD3_NUM_PORTS_PER_HPIPE 32 51 #define NUM_BITS_PER_BYTE 8 52 #define TD3_FIRST_CELL_SIZE 192 53 #define TD3_PKT_SIZE_WC_ETHER 64 54 #define TD3_PKT_OH_ETHER 20 55 56 #define TD3_FREQ_1700MHZ 1700 57 #define TD3_FREQ_1625MHZ 1625 58 #define TD3_FREQ_1525MHZ 1525 59 #define TD3_FREQ_1425MHZ 1425 60 #define TD3_FREQ_1325MHZ 1325 61 #define TD3_FREQ_1275MHZ 1275 62 #define TD3_FREQ_1012MHZ 1012 63 #define TD3_FREQ_850MHZ 850 64 #define TD3_BW_1700MHZ 1142000 65 #define TD3_BW_1625MHZ 1092000 66 #define TD3_BW_1525MHZ 1024000 67 #define TD3_BW_1425MHZ 957000 68 #define TD3_BW_1325MHZ 890000 69 #define TD3_BW_1275MHZ 856000 70 #define TD3_BW_1012MHZ 680000 71 #define TD3_BW_850MHZ 571000 72 73 #define TD3_FREQ_1525MHZ_CAL_LEN 409 74 #define TD3_FREQ_1425MHZ_CAL_LEN 383 75 #define TD3_FREQ_1325MHZ_CAL_LEN 356 76 #define TD3_FREQ_1012MHZ_CAL_LEN 272 77 #define TD3_FREQ_850MHZ_CAL_LEN 228 78 #define TD3_ANCL_CELLS 12 79 80 #endif 81 82 #define MAC_DA {0x12,0x34,0x56,0x78,0x9a,0xbc} 83 #define MAC_SA {0xfe,0xdc,0xba,0x98,0x76,0x54} 84 #define TPID 0x8100 85 #define VLAN 0x0a00 86 #define MIN_PKT_SIZE 64 87 #define MTU 9216 88 #define MTU_CELL_CNT 45 89 #define SPEED_FACTOR_DEFAULT 1 90 #define PKT_SIZE_PARAM_DEFAULT 0 91 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0 92 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10 93 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 1 94 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 3 95 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 1 96 #define NUM_LPORT_TAB_ENTRIES 256 97 #define NUM_PORT_TAB_ENTRIES 136 98 #define MISC_BW 10000 99 #define NUM_SUBP_OBM 4 100 #define MAX_NUM_CELLS_PARAM_DEFAULT 4 101 102 #ifdef BCM_TOMAHAWK3_SUPPORT 103 #define TARGET_CELL_COUNT 300 104 #else 105 #define TARGET_CELL_COUNT 80 106 #endif 107 108 #define TX_CHAN 0 109 #define RX_CHAN 1 110 111 #define HG2_WC_PKT_SIZE 64 112 #define ENET_WC_PKT_SIZE 145 113 #define ENET_IPG 12 114 #define ENET_PREAMBLE 8 115 #define HG2_IPG 8 116 #define HG2_HDR 12 117 118 #define CELL_SIZE 208 119 #define FIRST_CELL_ENET 144 120 #define FIRST_CELL_HG2 148 121 #define RXDMA_TIMEOUT 10000 122 123 #define NUM_BYTES_MAC_ADDR 6 124 #define NUM_BYTES_CRC 4 125 126 #define TH_FREQ_850 850 127 #define TH_FREQ_765 765 128 #define TH_FREQ_672 672 129 #define TH_FREQ_645 645 130 #define TH_FREQ_545 545 131 #define TH_BW_850 561000 132 #define TH_BW_765 504000 133 #define TH_BW_672 442000 134 #define TH_BW_645 423000 135 #define TH_BW_545 358000 136 137 #define TD2P_FREQ_793 793 138 #define TD2P_FREQ_635 635 139 #define TD2P_FREQ_529 529 140 #define TD2P_FREQ_421 421 141 #define TD2P_BW_793 500000 142 #define TD2P_BW_635 380000 143 #define TD2P_BW_529 340000 144 #define TD2P_BW_421 260000 145 146 #define TH2_FREQ_1700 1700 147 #define TH2_FREQ_1625 1625 148 #define TH2_FREQ_1525 1525 149 #define TH2_FREQ_1425 1425 150 #define TH2_FREQ_1325 1325 151 #define TH2_FREQ_1275 1275 152 #define TH2_FREQ_1225 1225 153 #define TH2_FREQ_1125 1125 154 #define TH2_FREQ_1050 1050 155 #define TH2_FREQ_950 950 156 #define TH2_FREQ_850 850 157 158 #define CMICM_MMU_BKP_OFF_THRESHOLD 0x20 159 #define CMICX_MMU_BKP_OFF_THRESHOLD 0xFF 160 161 #define DMA_CHAN_PER_CMC(unit) (SOC_VCHAN_NUM(unit) / SOC_CMCS_NUM(unit)) 162 163 #if defined(BCM_ESW_SUPPORT) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) 164 165 typedef struct streaming_s { 166 167 uint32 num_fp_ports; 168 int *port_speed; 169 int *port_list; 170 uint32 *port_oversub; 171 uint32 num_pipes; 172 uint32 total_chip_bw; 173 uint32 oversub_mode; 174 uint32 bw_per_pipe; 175 uint32 *ovs_ratio_x1000; 176 uint64 *rate; 177 uint64 *exp_rate; 178 uint64 *tpkt_start; 179 uint64 *tpkt_end; 180 uint64 *tbyt_start; 181 uint64 *tbyt_end; 182 uint32 **rand_pkt_sizes; 183 uint32 pkt_size_param; 184 uint32 flood_pkt_cnt_param; 185 uint32 rate_calc_interval_param; 186 uint32 rate_tolerance_lr_param; 187 uint32 rate_tolerance_ov_param; 188 uint32 check_packet_integrity_param; 189 uint32 max_num_cells_param; 190 uint32 speed_factor_param; 191 uint32 bad_input; 192 int test_fail; 193 uint32 pkt_seed; 194 } streaming_t; 195 196 static streaming_t *streaming_parray[SOC_MAX_NUM_DEVICES]; 197 198 /* 199 * Function: 200 * streaming_parse_test_params 201 * Purpose: 202 * Parse CLI parameters, create test structure and flag bad inputs. 203 * Parameters: 204 * unit - StrataSwitch Unit #. 205 * a - Pointer to arguments 206 * 207 * Returns: 208 * Nothing 209 * Notes: 210 * streaming_p->bad_input set from here - tells test to crash out in case 211 * CLI input combination is invalid. 212 */ 213 214 static void 215 streaming_parse_test_params(int unit, args_t *a) 216 { 217 parse_table_t parse_table; 218 streaming_t *streaming_p = streaming_parray[unit]; 219 220 const char tr501_test_usage[] = 221 #ifdef COMPILER_STRING_CONST_LIMIT 222 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 223 #else 224 "Streaming test to check TDM table and programming. Each port loops traffic\n" 225 "back to itself using port bridging and higig lookup for HG ports. Test test\n" 226 "calculates expected rates based on port config and oversub ratio and checks\n" 227 "against it.\n" 228 "Configuration parameters passed from CLI:\n" 229 "PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all\n" 230 " ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes\n" 231 "FloodCnt: Number of packets in each swill. Setting this to 0 will let the\n" 232 " test calculate the number of packets that can be sent to achieve\n" 233 " a lossless swirl at full rate. Set to 0 by default.\n" 234 "RateCalcInt: Interval in seconds over which rate is to be calculated\n" 235 "TolLr: Rate tolerance percentage for linerate ports (1 percentage by default).\n" 236 "TolOv: Rate tolerance percentage for oversubscribed ports (3 percentage by default).\n" 237 "ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default).\n" 238 "MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set\n" 239 " to 0 for random.\n"; 240 #endif 241 242 streaming_p->bad_input = 0; 243 streaming_p->oversub_mode = 0; 244 streaming_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT; 245 streaming_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT; 246 streaming_p->rate_calc_interval_param = RATE_CALC_INTERVAL_PARAM_DEFAULT; 247 streaming_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT; 248 streaming_p->rate_tolerance_ov_param = RATE_TOLERANCE_OV_PARAM_DEFAULT; 249 streaming_p->check_packet_integrity_param 250 = CHECK_PACKET_INTEGRITY_PARAM_DEFAULT; 251 streaming_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT; 252 streaming_p->speed_factor_param = SPEED_FACTOR_DEFAULT; 253 254 /*Parse CLI opts */ 255 256 parse_table_init(unit, &parse_table); 257 parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0, 258 &(streaming_p->pkt_size_param), NULL); 259 parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0, 260 &(streaming_p->flood_pkt_cnt_param), NULL); 261 parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0, 262 &(streaming_p->rate_calc_interval_param), NULL); 263 parse_table_add(&parse_table, "TolLr", PQ_INT|PQ_DFL, 0, 264 &(streaming_p->rate_tolerance_lr_param), NULL); 265 parse_table_add(&parse_table, "TolOv", PQ_INT|PQ_DFL, 0, 266 &(streaming_p->rate_tolerance_ov_param), NULL); 267 parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0, 268 &(streaming_p->check_packet_integrity_param), NULL); 269 parse_table_add(&parse_table, "MaxNumCells", PQ_INT|PQ_DFL, 0, 270 &(streaming_p->max_num_cells_param), NULL); 271 parse_table_add(&parse_table, "SpeedFactor", PQ_INT|PQ_DFL, 0, 272 &(streaming_p->speed_factor_param), NULL); 273 274 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 275 test_msg("%s", tr501_test_usage); 276 test_error(unit, 277 "%s: Invalid option: %s\n", 278 ARG_CMD(a), 279 ARG_CUR(a) ? ARG_CUR(a) : "*"); 280 streaming_p->bad_input = 1; 281 parse_arg_eq_done(&parse_table); 282 } else { 283 cli_out("\n ------------- PRINTING TEST PARAMS ------------------"); 284 cli_out("\npkt_size_param = %0d", streaming_p->pkt_size_param); 285 cli_out("\nrate_calc_interval_param = %0d", 286 streaming_p->rate_calc_interval_param); 287 cli_out("\nflood_pkt_cnt_param = %0d", streaming_p->flood_pkt_cnt_param); 288 cli_out("\nrate_tolerance_lr_param = %0d", 289 streaming_p->rate_tolerance_lr_param); 290 cli_out("\nrate_tolerance_ov_param = %0d", 291 streaming_p->rate_tolerance_ov_param); 292 cli_out("\ncheck_packet_integrity_param = %0d", 293 streaming_p->check_packet_integrity_param); 294 cli_out("\nmax_num_cells_param = %0d", streaming_p->max_num_cells_param); 295 cli_out("\nspeed_factor_param = %0d",streaming_p->speed_factor_param); 296 cli_out("\n -----------------------------------------------------"); 297 } 298 299 if (streaming_p->max_num_cells_param == 0) { 300 /* coverity[dont_call : FALSE] */ 301 streaming_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1; 302 } 303 304 if (streaming_p->pkt_size_param == 0) { 305 cli_out 306 ("\nUsing worst case packet sizes - 145B for Ethernet " 307 "and 76B (64B + 12B hg-hdr) for HG2"); 308 } else if (streaming_p->pkt_size_param == 1) { 309 cli_out("\nUsing random packet sizes"); 310 } else if (streaming_p->pkt_size_param < MIN_PKT_SIZE) { 311 test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n", 312 MIN_PKT_SIZE); 313 streaming_p->bad_input = 1; 314 } else if (streaming_p->pkt_size_param > MTU) { 315 test_error(unit,"\n*ERROR: Packet size cannot be higher than %0dB (Device MTU)\n", 316 MTU); 317 streaming_p->bad_input = 1; 318 } 319 320 if (streaming_p->flood_pkt_cnt_param == 0) { 321 cli_out("\nFloodCnt=0, test will automatically calculate number of" 322 " packets to flood each port"); 323 } 324 } 325 326 /* 327 * Function: 328 * streaming_soc_set_up_mac_lpbk 329 * Purpose: 330 * Enable MAC loopback on all ports 331 * Parameters: 332 * unit: StrataSwitch Unit #. 333 * 334 * Returns: 335 * Nothing 336 */ 337 338 339 static void 340 streaming_soc_set_up_mac_lpbk(int unit) 341 { 342 int p; 343 344 cli_out("\nSetting up MAC loopbacks"); 345 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 346 (void) bcm_port_loopback_set(unit, p, BCM_PORT_LOOPBACK_MAC); 347 } 348 } 349 350 /* 351 * Function: 352 * streaming_turn_off_cmic_mmu_bkp 353 * Purpose: 354 * Turn off CMIC to MMU backpressure 355 * Parameters: 356 * unit: StrataSwitch Unit #. 357 * 358 * Returns: 359 * Nothing 360 */ 361 362 static void 363 streaming_turn_off_cmic_mmu_bkp(int unit) 364 { 365 int cmc, ch; 366 int vchan; 367 uint32 threshold = CMICM_MMU_BKP_OFF_THRESHOLD; 368 369 if (soc_feature(unit, soc_feature_cmicm) 370 || soc_feature(unit, soc_feature_cmicd_v2) 371 || soc_feature(unit, soc_feature_cmicd_v3)) { 372 threshold = CMICM_MMU_BKP_OFF_THRESHOLD; 373 } else if (soc_feature(unit, soc_feature_cmicx)) { 374 threshold = CMICX_MMU_BKP_OFF_THRESHOLD; 375 } 376 377 for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) { 378 for (ch = 0; ch < DMA_CHAN_PER_CMC(unit); ch++) { 379 vchan = cmc * DMA_CHAN_PER_CMC(unit) + ch; 380 soc_dma_chan_rxbuf_threshold_cfg(unit, vchan, threshold); 381 } 382 } 383 384 if (soc_feature(unit, soc_feature_cmicx)) { 385 for (cmc = 0; cmc < SOC_CMCS_NUM(unit); cmc++) { 386 soc_dma_cmc_rxbuf_threshold_cfg(unit, cmc, threshold); 387 } 388 } 389 } 390 static void 391 streaming_soc_turn_off_idb_fc(int unit, soc_reg_t *idb_fcc_regs, int a_size) 392 { 393 int obm_subp; 394 int idx; 395 uint64 idb_fc; 396 soc_field_t idb_flow_control_config_fields[] = 397 { PORT_FC_ENf, LOSSLESS1_FC_ENf, LOSSLESS0_FC_ENf, 398 LOSSLESS1_PRIORITY_PROFILEf, LOSSLESS0_PRIORITY_PROFILEf 399 }; 400 uint32 idb_flow_control_config_values[] = { 0x0, 0x0, 0x0, 0xff, 0xff }; 401 402 cli_out("\nTurning off flow control at IDB/MMU"); 403 404 COMPILER_64_SET(idb_fc, 0x0, 0x0); 405 406 if (SOC_REG_IS_VALID(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r)) { 407 soc_reg_fields32_modify(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 408 REG_PORT_ANY, 5, idb_flow_control_config_fields, 409 idb_flow_control_config_values); 410 (void) soc_reg_get(unit, IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 0, 0, &idb_fc); 411 } 412 413 for (obm_subp = 0; obm_subp < NUM_SUBP_OBM; obm_subp++) { 414 for(idx = 0; idx < a_size; idx++) { 415 if(SOC_REG_IS_VALID(unit, idb_fcc_regs[idx])) { 416 (void) soc_reg_set(unit, idb_fcc_regs[idx], 0, obm_subp, idb_fc); 417 } 418 } 419 } 420 } 421 /* 422 * Function: 423 * streaming_turn_off_fc 424 * Purpose: 425 * Turn off flow control at the MAC, IDB and MMU. 426 * Parameters: 427 * unit: StrataSwitch Unit #. 428 * 429 * Returns: 430 * Nothing 431 */ 432 433 static void 434 streaming_soc_turn_off_fc(int unit) 435 { 436 int p; 437 int idx; 438 int a_size = 0; 439 soc_reg_t idb_fcc_regs[] = { 440 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 441 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r, 442 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r, 443 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r, 444 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r, 445 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r, 446 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r, 447 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r, 448 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r, 449 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r, 450 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r, 451 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r, 452 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r, 453 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r, 454 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r, 455 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r, 456 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r, 457 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r, 458 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r, 459 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r, 460 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r, 461 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r, 462 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r, 463 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r, 464 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE1r, 465 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE1r, 466 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE1r, 467 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE1r, 468 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE1r, 469 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE1r, 470 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE1r, 471 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE1r, 472 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r, 473 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r, 474 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r, 475 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r, 476 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE2r, 477 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE2r, 478 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE2r, 479 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE2r, 480 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE2r, 481 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE2r, 482 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE2r, 483 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE2r, 484 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE2r, 485 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE2r, 486 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE2r, 487 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE2r, 488 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r, 489 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r, 490 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r, 491 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r, 492 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE3r, 493 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE3r, 494 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE3r, 495 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE3r, 496 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE3r, 497 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE3r, 498 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE3r, 499 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE3r, 500 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE3r, 501 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE3r, 502 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE3r, 503 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE3r 504 }; 505 #ifdef BCM_TRIDENT3_SUPPORT 506 soc_reg_t idb_fcc_regs_td3[] = { 507 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r, 508 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r, 509 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r, 510 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r, 511 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE0r, 512 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE0r, 513 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE0r, 514 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE0r, 515 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE0r, 516 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE0r, 517 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE0r, 518 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE0r, 519 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE0r, 520 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE0r, 521 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE0r, 522 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE0r, 523 IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r, 524 IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r, 525 IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r, 526 IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r, 527 IDB_OBM4_FLOW_CONTROL_CONFIG_PIPE1r, 528 IDB_OBM5_FLOW_CONTROL_CONFIG_PIPE1r, 529 IDB_OBM6_FLOW_CONTROL_CONFIG_PIPE1r, 530 IDB_OBM7_FLOW_CONTROL_CONFIG_PIPE1r, 531 IDB_OBM8_FLOW_CONTROL_CONFIG_PIPE1r, 532 IDB_OBM9_FLOW_CONTROL_CONFIG_PIPE1r, 533 IDB_OBM10_FLOW_CONTROL_CONFIG_PIPE1r, 534 IDB_OBM11_FLOW_CONTROL_CONFIG_PIPE1r, 535 IDB_OBM12_FLOW_CONTROL_CONFIG_PIPE1r, 536 IDB_OBM13_FLOW_CONTROL_CONFIG_PIPE1r, 537 IDB_OBM14_FLOW_CONTROL_CONFIG_PIPE1r, 538 IDB_OBM15_FLOW_CONTROL_CONFIG_PIPE1r 539 }; 540 #endif 541 soc_reg_t pgw_fcc_regs[] = { 542 PGW_OBM_PORT0_FC_CONFIGr, 543 PGW_OBM_PORT1_FC_CONFIGr, 544 PGW_OBM_PORT2_FC_CONFIGr, 545 PGW_OBM_PORT3_FC_CONFIGr, 546 PGW_OBM_PORT4_FC_CONFIGr, 547 PGW_OBM_PORT5_FC_CONFIGr, 548 PGW_OBM_PORT6_FC_CONFIGr, 549 PGW_OBM_PORT7_FC_CONFIGr, 550 PGW_OBM_PORT8_FC_CONFIGr, 551 PGW_OBM_PORT9_FC_CONFIGr, 552 PGW_OBM_PORT10_FC_CONFIGr, 553 PGW_OBM_PORT11_FC_CONFIGr, 554 PGW_OBM_PORT12_FC_CONFIGr, 555 PGW_OBM_PORT13_FC_CONFIGr, 556 PGW_OBM_PORT14_FC_CONFIGr, 557 PGW_OBM_PORT15_FC_CONFIGr 558 }; 559 560 561 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 562 bcm_port_pause_set(unit, p, FALSE, FALSE); 563 soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, p, 564 PORT_PAUSE_ENABLEf, 0x0); 565 } 566 soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, 0, 567 PORT_PAUSE_ENABLEf, 0x0); 568 569 #ifdef BCM_TRIDENT3_SUPPORT 570 if(SOC_IS_TRIDENT3X(unit)) 571 { 572 a_size = sizeof(idb_fcc_regs_td3) / sizeof(soc_reg_t); 573 streaming_soc_turn_off_idb_fc(unit, idb_fcc_regs_td3, a_size); 574 } 575 #endif 576 if(SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2PLUS(unit)) 577 { 578 a_size = sizeof(idb_fcc_regs) / sizeof(soc_reg_t); 579 streaming_soc_turn_off_idb_fc(unit, idb_fcc_regs, a_size); 580 for (idx = 0; idx < (sizeof(pgw_fcc_regs) / sizeof(soc_reg_t)); idx++) { 581 if (SOC_REG_IS_VALID(unit, pgw_fcc_regs[idx])) { 582 soc_reg_field32_modify(unit, pgw_fcc_regs[idx], REG_PORT_ANY, 583 PORT_FC_ENABLEf, 0x0); 584 } 585 } 586 } 587 } 588 589 /* 590 * Function: 591 * stream_get_reg_tpkt_tbyt 592 * Purpose: 593 * Get register of TPKTr and TBYTr 594 * Parameters: 595 * unit: StrataSwitch Unit #. 596 * reg_tpkt: ptr to register TPKTr 597 * reg_tbyt: ptr to register TBYTr 598 * 599 * Returns: 600 * BCM_E_XXX 601 */ 602 static bcm_error_t 603 stream_get_reg_tpkt_tbyt(int unit, int port, soc_reg_t* reg_tpkt, 604 soc_reg_t* reg_tbyt) 605 { 606 bcm_error_t rv = BCM_E_NONE; 607 608 if (soc_feature(unit, soc_feature_cxl_mib)) { 609 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, 610 SOC_INFO(unit).port_l2p_mapping[port]), SOC_BLK_CLPORT)) { 611 (*reg_tpkt) = CLMIB_TPKTr; 612 (*reg_tbyt) = CLMIB_TBYTr; 613 } else if (IS_QSGMII_PORT(unit, port)) { 614 (*reg_tpkt) = GTPKTr; 615 (*reg_tbyt) = GTBYTr; 616 } else { 617 (*reg_tpkt) = XLMIB_TPKTr; 618 (*reg_tbyt) = XLMIB_TBYTr; 619 } 620 } else { 621 (*reg_tpkt) = TPKTr; 622 (*reg_tbyt) = TBYTr; 623 } 624 625 return rv; 626 } 627 /* 628 * Function: 629 * get_pipe 630 * Purpose: 631 * Get pipe number for a given device port. 632 * Parameters: 633 * unit: StrataSwitch Unit #. 634 * port: Device port # 635 * 636 * Returns: 637 * Pipe number. 638 */ 639 640 static int 641 get_pipe(int unit, int port) 642 { 643 int pipe; 644 soc_info_t *si = &SOC_INFO(unit); 645 646 for (pipe = 0; pipe < si->num_pipe; pipe++) { 647 if (SOC_PBMP_MEMBER(si->pipe_pbm[pipe], port)) { 648 break; 649 } 650 } 651 return pipe; 652 } 653 654 /* 655 * Function: 656 * num_cells 657 * Purpose: 658 * Get the cell count for a given packet size. 659 * Parameters: 660 * unit: StrataSwitch Unit #. 661 * port: Device port # 662 * 663 * Returns: 664 * Cell count 665 */ 666 667 static uint32 668 num_cells(int unit, uint32 pkt_size, int port) 669 { 670 uint32 i; 671 uint32 num_cells = 1; 672 673 674 if (IS_HG_PORT(unit, port)) { 675 i = FIRST_CELL_HG2; 676 } 677 else { 678 i = FIRST_CELL_ENET; 679 #ifdef BCM_TRIDENT3_SUPPORT 680 if(SOC_IS_TRIDENT3X(unit)) { 681 i = TD3_FIRST_CELL_SIZE; 682 } 683 #endif 684 685 } 686 while (i < pkt_size) { 687 num_cells++; 688 #ifdef BCM_TRIDENT3_SUPPORT 689 if(SOC_IS_TRIDENT3X(unit)) 690 i += TD3_CELL_SIZE; 691 #endif 692 if (SOC_IS_TOMAHAWK3(unit)) { 693 i += 254; 694 } else if(SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2PLUS(unit)) 695 i += CELL_SIZE; 696 } 697 return num_cells; 698 } 699 /* 700 * Function: 701 * lossless_flood_cnt 702 * Purpose: 703 * Calculates number of packets that need to be sent to a port for a 704 * lossless swirl 705 * Parameters: 706 * unit - StrataSwitch Unit #. 707 * pkt_size : Packet size in bytes 708 * port: Test port no 709 * Returns: 710 * Number of packets needed for lossless flooding 711 */ 712 713 static uint32 714 lossless_flood_cnt(int unit, uint32 pkt_size, int port) 715 { 716 uint32 flood_cnt = 0; 717 uint32 total_cells = 0; 718 719 streaming_t *streaming_p = streaming_parray[unit]; 720 721 if (pkt_size == 1) { 722 while (total_cells < TARGET_CELL_COUNT) { 723 total_cells += num_cells(unit, 724 streaming_p->rand_pkt_sizes[port][flood_cnt], 725 streaming_p->port_list[port]); 726 flood_cnt++; 727 } 728 } else { 729 flood_cnt = TARGET_CELL_COUNT / (num_cells(unit, pkt_size, 730 streaming_p->port_list[port])); 731 } 732 733 if (flood_cnt < 3) { 734 flood_cnt = 3; 735 } 736 return(flood_cnt); 737 } 738 739 /* 740 * Function: 741 * safe_pkt_size 742 * Purpose: 743 * Calculate safe packet size based on oversub ratio. The assumption is that 744 * a front panel port will behave essentially as a line rate port and show no 745 * bandwidth degradation for packet sizes above the safe packet size. 746 * This is based on input from device microarchitects. Broadcom internal 747 * users of this test can contact microarchitecture for more info. 748 * Parameters: 749 * unit: StrataSwitch Unit #. 750 * ovs_ratio_x1000: Oversub ratio x1000 751 * 752 * Returns: 753 * Safe packet size. 754 */ 755 756 static uint32 757 safe_pkt_size(int unit, int ovs_ratio_x1000) 758 { 759 uint32 safe_size = 64; 760 761 if (ovs_ratio_x1000 <= 1507) { 762 safe_size = 763 145 + 764 ((((229000 - 144000) / (1507 - 1000)) * (ovs_ratio_x1000 - 765 1000)) / 1000); 766 } else if ((ovs_ratio_x1000 > 1507) && (ovs_ratio_x1000 <= 1760)) { 767 safe_size = 768 353 + 769 ((((416000 - 353000) / (1760 - 1508)) * (ovs_ratio_x1000 - 770 1508)) / 1000); 771 } else if ((ovs_ratio_x1000 > 1760) && (ovs_ratio_x1000 <= 1912)) { 772 safe_size = 773 562 + 774 ((((611000 - 562000) / (1912 - 1760)) * (ovs_ratio_x1000 - 775 1760)) / 1000); 776 } else { 777 safe_size = 770; 778 } 779 780 return safe_size; 781 782 } 783 784 /* 785 * Function: 786 * calc_oversub_ratio 787 * Purpose: 788 * Calculate oversub ratio for each pipe based on port config 789 * Parameters: 790 * unit: StrataSwitch Unit #. 791 * 792 * Returns: 793 * Nothing 794 */ 795 796 797 static void 798 calc_oversub_ratio(int unit) 799 { 800 int i; 801 int pipe; 802 int pipe_bandwidth = 0; 803 int lr_bandwidth = 0; 804 int ov_bandwidth = 0; 805 uint16 dev_id; 806 uint8 rev_id; 807 soc_info_t *si = &SOC_INFO(unit); 808 streaming_t *streaming_p = streaming_parray[unit]; 809 int cal_universal; 810 811 streaming_p->ovs_ratio_x1000 = 812 (uint32 *) sal_alloc(si->num_pipe * sizeof(uint32), "ovs_ratio"); 813 814 cli_out("\nCalculating oversub ratios"); 815 cli_out("\nOperating Freq = %0d", si->frequency); 816 817 soc_cm_get_id(unit, &dev_id, &rev_id); 818 cal_universal = si->fabric_port_enable ? 1 : 0; 819 820 if (dev_id == BCM56970_DEVICE_ID) { 821 switch (si->frequency) { 822 case TH2_FREQ_1700: 823 pipe_bandwidth = cal_universal ? 1050 : 1095; 824 break; 825 case TH2_FREQ_1625: 826 pipe_bandwidth = cal_universal ? 1002 : 1047; 827 break; 828 case TH2_FREQ_1525: 829 pipe_bandwidth = cal_universal ? 940 : 980; 830 break; 831 case TH2_FREQ_1425: 832 pipe_bandwidth = cal_universal ? 877 : 915; 833 break; 834 case TH2_FREQ_1325: 835 pipe_bandwidth = cal_universal ? 812 : 847; 836 break; 837 case TH2_FREQ_1275: 838 pipe_bandwidth = cal_universal ? 782 : 815; 839 break; 840 case TH2_FREQ_1225: 841 pipe_bandwidth = cal_universal ? 750 : 782; 842 break; 843 case TH2_FREQ_1125: 844 pipe_bandwidth = cal_universal ? 687 : 717; 845 break; 846 case TH2_FREQ_1050: 847 pipe_bandwidth = cal_universal ? 640 : 667; 848 break; 849 case TH2_FREQ_950: 850 pipe_bandwidth = cal_universal ? 575 : 600; 851 break; 852 case TH2_FREQ_850: 853 pipe_bandwidth = cal_universal ? 512 : 535; 854 break; 855 default: 856 pipe_bandwidth = cal_universal ? 1050 : 1095; 857 } 858 859 pipe_bandwidth = pipe_bandwidth * 1000; 860 } 861 else if (dev_id == BCM56960_DEVICE_ID) { 862 switch (si->frequency) { 863 case TH_FREQ_850: 864 pipe_bandwidth = TH_BW_850; 865 break; 866 case TH_FREQ_765: 867 pipe_bandwidth = TH_BW_765; 868 break; 869 case TH_FREQ_672: 870 pipe_bandwidth = TH_BW_672; 871 break; 872 case TH_FREQ_645: 873 pipe_bandwidth = TH_BW_645; 874 break; 875 case TH_FREQ_545: 876 pipe_bandwidth = TH_BW_545; 877 break; 878 default: 879 pipe_bandwidth = TH_BW_850; 880 } 881 } 882 else if (dev_id == BCM56860_DEVICE_ID || dev_id == BCM56850_DEVICE_ID) { 883 switch (si->frequency) { 884 case TD2P_FREQ_793: 885 pipe_bandwidth = TD2P_BW_793; 886 break; 887 case TD2P_FREQ_635: 888 pipe_bandwidth = TD2P_BW_635; 889 break; 890 case TD2P_FREQ_529: 891 pipe_bandwidth = TD2P_BW_529; 892 break; 893 case TD2P_FREQ_421: 894 pipe_bandwidth = TD2P_BW_421; 895 break; 896 default: 897 pipe_bandwidth = TD2P_BW_793; 898 } 899 } 900 #ifdef BCM_TRIDENT3_SUPPORT 901 else if (dev_id == BCM56870_DEVICE_ID) 902 { 903 switch (si->frequency) { 904 case TD3_FREQ_1700MHZ: 905 pipe_bandwidth = TD3_BW_1700MHZ; 906 break; 907 case TD3_FREQ_1625MHZ: 908 pipe_bandwidth = TD3_BW_1625MHZ; 909 break; 910 case TD3_FREQ_1525MHZ: 911 pipe_bandwidth = TD3_BW_1525MHZ; 912 break; 913 case TD3_FREQ_1425MHZ: 914 pipe_bandwidth = TD3_BW_1425MHZ; 915 break; 916 case TD3_FREQ_1325MHZ: 917 pipe_bandwidth = TD3_BW_1325MHZ; 918 break; 919 case TD3_FREQ_1275MHZ: 920 pipe_bandwidth = TD3_BW_1275MHZ; 921 break; 922 case TD3_FREQ_1012MHZ: 923 pipe_bandwidth = TD3_BW_1012MHZ; 924 break; 925 case TD3_FREQ_850MHZ: 926 pipe_bandwidth = TD3_BW_850MHZ; 927 break; 928 929 } 930 } 931 #endif 932 else { 933 pipe_bandwidth = TD2P_BW_793; 934 } 935 936 pipe_bandwidth = pipe_bandwidth - MISC_BW; 937 938 cli_out("\nPer pipe BW = %0d", pipe_bandwidth); 939 940 for (pipe = 0; pipe < si->num_pipe; pipe++) { 941 lr_bandwidth = 0; 942 ov_bandwidth = 0; 943 for (i = 0; i < streaming_p->num_fp_ports; i++) { 944 if (SOC_PBMP_MEMBER(si->pipe_pbm[pipe], streaming_p->port_list[i])) { 945 if (streaming_p->port_oversub[i] == 1) { 946 ov_bandwidth += streaming_p->port_speed[i]; 947 } else { 948 lr_bandwidth += streaming_p->port_speed[i]; 949 } 950 } 951 } 952 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 953 if(ov_bandwidth != 0) 954 streaming_p->oversub_mode = 1; 955 #endif 956 streaming_p->ovs_ratio_x1000[pipe] = 957 (ov_bandwidth) / ((pipe_bandwidth - lr_bandwidth) / 1000); 958 959 if (streaming_p->pkt_size_param > 960 safe_pkt_size(unit, streaming_p->ovs_ratio_x1000[pipe])) { 961 streaming_p->ovs_ratio_x1000[pipe] = 1000; 962 } 963 964 if (streaming_p->ovs_ratio_x1000[pipe] < 1000) { 965 streaming_p->ovs_ratio_x1000[pipe] = 1000; 966 } 967 968 cli_out 969 ("\nFor pipe %0d, LR BW = %0d, OV BW = %0d, ovs_ratio(x1000) = %0d", 970 pipe, lr_bandwidth, ov_bandwidth, 971 streaming_p->ovs_ratio_x1000[pipe]); 972 } 973 } 974 #if defined(BCM_TRIDENT3_SUPPORT) 975 static int 976 get_cal_length(int core_clk) 977 { 978 int calc_len; 979 switch (core_clk) { 980 case TD3_FREQ_1525MHZ: 981 calc_len = TD3_FREQ_1525MHZ_CAL_LEN; 982 break; 983 case TD3_FREQ_1425MHZ: 984 calc_len = TD3_FREQ_1425MHZ_CAL_LEN; 985 break; 986 case TD3_FREQ_1325MHZ: 987 calc_len = TD3_FREQ_1325MHZ_CAL_LEN; 988 break; 989 case TD3_FREQ_1012MHZ: 990 calc_len = TD3_FREQ_1012MHZ_CAL_LEN; 991 break; 992 case TD3_FREQ_850MHZ: 993 calc_len = TD3_FREQ_850MHZ_CAL_LEN; 994 break; 995 default: 996 calc_len = TD3_FREQ_1525MHZ_CAL_LEN; 997 break; 998 } 999 return calc_len; 1000 } 1001 1002 static int 1003 get_packet_size(int unit, int port) 1004 { 1005 int pkt_size, flood_cnt, i; 1006 streaming_t *streaming_p = streaming_parray[unit]; 1007 if (streaming_p->pkt_size_param == 0) { 1008 if (IS_HG_PORT(unit, streaming_p->port_list[port])) { 1009 pkt_size = HG2_WC_PKT_SIZE; 1010 } else { 1011 pkt_size = ENET_WC_PKT_SIZE; 1012 } 1013 } else { 1014 pkt_size = streaming_p->pkt_size_param; 1015 } 1016 1017 /* random packets */ 1018 if (pkt_size == 1) { 1019 if (streaming_p->flood_pkt_cnt_param == 0) { 1020 flood_cnt = lossless_flood_cnt(unit, pkt_size, port); 1021 } else { 1022 flood_cnt = streaming_p->flood_pkt_cnt_param; 1023 } 1024 for(i = 0; i< flood_cnt; i++) { 1025 pkt_size += streaming_p->rand_pkt_sizes[port][i]; 1026 } 1027 pkt_size = pkt_size / flood_cnt; 1028 } 1029 return pkt_size; 1030 } 1031 #endif 1032 /* 1033 * Function: 1034 * set_exp_rates 1035 * Purpose: 1036 * Set expected rates array (streaming_p->exp_rate). This is based on port 1037 * speed and oversub ratio (for oversubscribed ports). 1038 * Parameters: 1039 * unit: StrataSwitch Unit #. 1040 * 1041 * Returns: 1042 * Nothing 1043 */ 1044 1045 1046 static void 1047 set_exp_rates(int unit) 1048 { 1049 int i; 1050 char exp_rate_str[32]; 1051 uint64 ovs_ratio_x1000_64; 1052 streaming_t *streaming_p = streaming_parray[unit]; 1053 #ifdef BCM_TRIDENT3_SUPPORT 1054 int lgc_port, phy_port, pipe_id, hpipe_id; 1055 int pkt_size, cell_num; 1056 uint32 packet_rate, cell_rate; 1057 int core_clk, dpp_clk, calc_len, dpp_clk_ratio_x10, 1058 pkt_slot_ratio_x100, cell_slot_ratio_x100; 1059 soc_info_t *si = &SOC_INFO(unit); 1060 int hpipe_bw[TD3_NUM_PIPE][TD3_NUM_HPIPE_PER_PIPE] = { 1061 {0, 0}, 1062 {0, 0} 1063 }; 1064 #endif 1065 cli_out("\nSetting expected rates"); 1066 streaming_p->exp_rate = 1067 (uint64 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint64), 1068 "exp_rate"); 1069 #ifdef BCM_TRIDENT3_SUPPORT 1070 if(SOC_IS_TRIDENT3X(unit)) { 1071 1072 if(streaming_p->oversub_mode) { 1073 1074 core_clk = si->frequency; 1075 calc_len = get_cal_length(core_clk); 1076 dpp_clk_ratio_x10 = (core_clk > TD3_FREQ_1012MHZ)? 15:10; 1077 dpp_clk = core_clk * 10 / dpp_clk_ratio_x10 / TD3_NUM_HPIPE_PER_PIPE; 1078 pkt_slot_ratio_x100 = (calc_len - dpp_clk_ratio_x10 * TD3_ANCL_CELLS / 10) * 100/ calc_len; 1079 cell_slot_ratio_x100 = (calc_len - TD3_ANCL_CELLS) * 100 / calc_len; 1080 for(i = 0; i < streaming_p->num_fp_ports; i++) { 1081 1082 lgc_port = streaming_p->port_list[i]; 1083 phy_port = si->port_l2p_mapping[lgc_port]; 1084 pipe_id = si->port_pipe[lgc_port]; 1085 hpipe_id = (phy_port/TD3_NUM_PORTS_PER_HPIPE) % TD3_NUM_HPIPE_PER_PIPE; 1086 hpipe_bw[pipe_id][hpipe_id] += streaming_p->port_speed[i] / 1000; /* unit Gbits/s */ 1087 1088 } 1089 for(i = 0; i < streaming_p->num_fp_ports; i++) { 1090 if (streaming_p->port_oversub[i] == 1 && streaming_p->port_speed[i] != 0) { 1091 1092 lgc_port = streaming_p->port_list[i]; 1093 phy_port = si->port_l2p_mapping[lgc_port]; 1094 pipe_id = si->port_pipe[lgc_port]; 1095 hpipe_id = (phy_port / TD3_NUM_PORTS_PER_HPIPE) % TD3_NUM_HPIPE_PER_PIPE; 1096 pkt_size = get_packet_size(unit, i) + TD3_PKT_OH_ETHER; 1097 cell_num = num_cells(unit, pkt_size, i); 1098 1099 packet_rate = dpp_clk * pkt_slot_ratio_x100 * pkt_size / hpipe_bw[pipe_id][hpipe_id] 1100 * (streaming_p->port_speed[i] / 1000) / 100 * NUM_BITS_PER_BYTE; 1101 1102 packet_rate = packet_rate > streaming_p->port_speed[i] ? streaming_p->port_speed[i]: packet_rate; 1103 1104 cell_rate = (core_clk / TD3_NUM_HPIPE_PER_PIPE) * cell_slot_ratio_x100 1105 * pkt_size / 100 / cell_num / hpipe_bw[pipe_id][hpipe_id] 1106 * (streaming_p->port_speed[i] / 1000) * NUM_BITS_PER_BYTE; 1107 cell_rate = cell_rate > streaming_p->port_speed[i] ? streaming_p->port_speed[i]: cell_rate; 1108 1109 COMPILER_64_SET(streaming_p->exp_rate[i], 0, 1110 packet_rate > cell_rate? cell_rate : packet_rate); 1111 COMPILER_64_UMUL_32(streaming_p->exp_rate[i], 1000000); 1112 } 1113 } 1114 1115 } else { 1116 for(i = 0; i < streaming_p->num_fp_ports; i++) { 1117 COMPILER_64_SET(streaming_p->exp_rate[i], 0, 1118 streaming_p->port_speed[i]); 1119 COMPILER_64_UMUL_32(streaming_p->exp_rate[i], 1000000); 1120 } 1121 } 1122 1123 } 1124 #endif 1125 if(SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT2PLUS(unit)) { 1126 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1127 if (streaming_p->port_oversub[i] == 1) { 1128 COMPILER_64_SET(streaming_p->exp_rate[i], 0, 1129 streaming_p->port_speed[i]); 1130 COMPILER_64_UMUL_32(streaming_p->exp_rate[i], 1000000); 1131 COMPILER_64_SET(ovs_ratio_x1000_64, 0, 1132 streaming_p->ovs_ratio_x1000[get_pipe(unit, 1133 streaming_p-> 1134 port_list[i])]); 1135 COMPILER_64_UMUL_32(streaming_p->exp_rate[i], 1000); 1136 COMPILER_64_UDIV_64(streaming_p->exp_rate[i], ovs_ratio_x1000_64); 1137 } else { 1138 COMPILER_64_SET(streaming_p->exp_rate[i], 0, 1139 streaming_p->port_speed[i]); 1140 COMPILER_64_UMUL_32(streaming_p->exp_rate[i], 1000000); 1141 } 1142 } 1143 } 1144 1145 LOG_INFO(BSL_LS_APPL_TESTS, 1146 (BSL_META_U(unit, "\nPRINTING EXPECTED RATES"))); 1147 LOG_INFO(BSL_LS_APPL_TESTS, 1148 (BSL_META_U(unit, "\n======================="))); 1149 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1150 format_uint64_decimal(exp_rate_str, streaming_p->exp_rate[i], 0); 1151 LOG_INFO(BSL_LS_APPL_TESTS, 1152 (BSL_META_U(unit, "\nFor port %0d, exp_rate[%0d] = %s"), i, 1153 i, exp_rate_str)); 1154 } 1155 LOG_INFO(BSL_LS_APPL_TESTS, 1156 (BSL_META_U(unit, "\n======================="))); 1157 } 1158 1159 /* 1160 * Function: 1161 * set_port_property_arrays 1162 * Purpose: 1163 * Set port_list, port_speed and port_oversub arrays. Also call set_exp_rates 1164 * Parameters: 1165 * unit: StrataSwitch Unit #. 1166 * 1167 * Returns: 1168 * Safe packet size. 1169 */ 1170 1171 static void 1172 set_port_property_arrays(int unit) 1173 { 1174 int p; 1175 int i, j; 1176 uint32 pkt_size; 1177 soc_info_t *si = &SOC_INFO(unit); 1178 streaming_t *streaming_p = streaming_parray[unit]; 1179 1180 streaming_p->num_fp_ports = 0; 1181 1182 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1183 streaming_p->num_fp_ports++; 1184 } 1185 1186 streaming_p->port_list = 1187 (int *)sal_alloc(streaming_p->num_fp_ports * sizeof(uint32), 1188 "port_list"); 1189 streaming_p->port_speed = 1190 (int *)sal_alloc(streaming_p->num_fp_ports * sizeof(uint32), 1191 "port_speed_array"); 1192 streaming_p->port_oversub = 1193 (uint32 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint32), 1194 "port_oversub_array"); 1195 streaming_p->rand_pkt_sizes = 1196 (uint32 **) sal_alloc(streaming_p->num_fp_ports * sizeof(uint32 *), 1197 "rand_pkt_sizes_array*"); 1198 1199 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1200 streaming_p->rand_pkt_sizes[i] = 1201 (uint32 *) sal_alloc(TARGET_CELL_COUNT * sizeof(uint32), 1202 "rand_pkt_sizes_array"); 1203 } 1204 1205 i = 0; 1206 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1207 streaming_p->port_list[i] = p; 1208 i++; 1209 } 1210 1211 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1212 streaming_p->port_speed[i] = 1213 si->port_speed_max[streaming_p->port_list[i]]; 1214 1215 switch(streaming_p->port_speed[i]) { 1216 case 11000: 1217 streaming_p->port_speed[i] = 10600; 1218 break; 1219 case 27000: 1220 streaming_p->port_speed[i] = 26500; 1221 break; 1222 case 42000: 1223 streaming_p->port_speed[i] = 42400; 1224 break; 1225 } 1226 } 1227 1228 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1229 if (SOC_PBMP_MEMBER(si->oversub_pbm, streaming_p->port_list[i]) 1230 && 1231 (!(SOC_PBMP_MEMBER(si->management_pbm, streaming_p->port_list[i])))) 1232 { 1233 streaming_p->port_oversub[i] = 1; 1234 } else { 1235 streaming_p->port_oversub[i] = 0; 1236 } 1237 } 1238 1239 calc_oversub_ratio(unit); 1240 1241 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\nPRINTING PORT SPEED"))); 1242 LOG_INFO(BSL_LS_APPL_TESTS, 1243 (BSL_META_U(unit, "\n==============================="))); 1244 1245 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1246 LOG_INFO(BSL_LS_APPL_TESTS, 1247 (BSL_META_U(unit, "\nFor port %0d, port_speed[%0d] = %0d"), i, 1248 i, streaming_p->port_speed[i])); 1249 } 1250 1251 LOG_INFO(BSL_LS_APPL_TESTS, 1252 (BSL_META_U(unit, "\n===============================\n"))); 1253 1254 LOG_INFO(BSL_LS_APPL_TESTS, 1255 (BSL_META_U(unit, "\nPRINTING PORT OVERSUB ARRAY"))); 1256 LOG_INFO(BSL_LS_APPL_TESTS, 1257 (BSL_META_U(unit, "\n==============================="))); 1258 1259 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1260 LOG_INFO(BSL_LS_APPL_TESTS, 1261 (BSL_META_U(unit, "\nFor port %0d, port_oversub[%0d] = %0d"), 1262 i, i, streaming_p->port_oversub[i])); 1263 } 1264 LOG_INFO(BSL_LS_APPL_TESTS, 1265 (BSL_META_U(unit, "\n===============================\n"))); 1266 1267 1268 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1269 for (j = 0; j < TARGET_CELL_COUNT; j++) { 1270 do { 1271 /* coverity[dont_call : FALSE] */ 1272 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + MIN_PKT_SIZE; 1273 } while (num_cells(unit, pkt_size, streaming_p->port_list[i]) > 1274 streaming_p->max_num_cells_param); 1275 streaming_p->rand_pkt_sizes[i][j] = pkt_size; 1276 } 1277 } 1278 1279 set_exp_rates(unit); 1280 } 1281 1282 /* 1283 * Function: 1284 * set_up_streams 1285 * Purpose: 1286 * VLAN programming for streaming. Each port is put on an unique VLAN. 1287 * Parameters: 1288 * unit: StrataSwitch Unit #. 1289 * ovs_ratio_x1000: Oversub ratio x1000 1290 * 1291 * Returns: 1292 * Safe packet size. 1293 */ 1294 1295 static void 1296 set_up_streams(int unit) 1297 { 1298 int i; 1299 pbmp_t pbm, ubm; 1300 uint32 vlan = VLAN; 1301 streaming_t *streaming_p = streaming_parray[unit]; 1302 1303 1304 BCM_PBMP_CLEAR(ubm); 1305 1306 bcm_vlan_destroy_all(unit); 1307 1308 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1309 BCM_PBMP_CLEAR(pbm); 1310 bcm_vlan_create(unit, (bcm_vlan_t) (vlan)); 1311 BCM_PBMP_PORT_ADD(pbm, streaming_p->port_list[i]); 1312 bcm_vlan_port_add(unit, (bcm_vlan_t) (vlan), pbm, ubm); 1313 vlan++; 1314 } 1315 } 1316 1317 1318 1319 /* 1320 * Function: 1321 * streaming_gen_random_l2_pkt 1322 * Purpose: 1323 * Generate random L2 packet with seq ID 1324 * Parameters: 1325 * unit - StrataSwitch Unit #. 1326 * 1327 * Returns: 1328 * Nothing 1329 */ 1330 1331 void 1332 streaming_gen_random_l2_pkt(uint8 *pkt_ptr, uint32 pkt_size, 1333 uint8 mac_da[NUM_BYTES_MAC_ADDR], 1334 uint8 mac_sa[NUM_BYTES_MAC_ADDR], uint16 tpid, 1335 uint16 vlan_id, uint32 seq_id) 1336 { 1337 uint32 crc; 1338 tgp_gen_random_l2_pkt(pkt_ptr, pkt_size, mac_da, mac_sa, tpid, vlan_id); 1339 pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 6] = (seq_id >> 24) & 0xff; 1340 pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 7] = (seq_id >> 16) & 0xff; 1341 pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 8] = (seq_id >> 8) & 0xff; 1342 pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 9] = (seq_id) & 0xff; 1343 pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 10] = (pkt_size >> 8) & 0xff; 1344 pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 11] = (pkt_size) & 0xff; 1345 1346 tgp_populate_crc_table(); 1347 crc = tgp_generate_calculate_crc(pkt_ptr, pkt_size); 1348 1349 pkt_ptr[pkt_size - NUM_BYTES_CRC + 3] = (crc >> 24) & 0xff; 1350 pkt_ptr[pkt_size - NUM_BYTES_CRC + 2] = (crc >> 16) & 0xff; 1351 pkt_ptr[pkt_size - NUM_BYTES_CRC + 1] = (crc >> 8) & 0xff; 1352 pkt_ptr[pkt_size - NUM_BYTES_CRC] = (crc) & 0xff; 1353 } 1354 1355 1356 /* 1357 * Function: 1358 * send_pkts 1359 * Purpose: 1360 * Send packets to flood VLANs and create a swirl on each port. 1361 * Parameters: 1362 * unit - StrataSwitch Unit #. 1363 * 1364 * Returns: 1365 * Nothing 1366 */ 1367 1368 static void 1369 send_pkts(int unit) 1370 { 1371 uint8 mac_da[] = MAC_DA; 1372 uint8 mac_sa[] = MAC_SA; 1373 uint8 *packet_store_ptr; 1374 uint32 pkt_size; 1375 int i, j; 1376 pbmp_t lp_pbm, empty_pbm0, empty_pbm1; 1377 dv_t *dv_tx; 1378 int channel_done; 1379 int flags = 0; 1380 uint32 pkt_count = 0; 1381 uint32 flood_cnt; 1382 uint32 use_random_packet_sizes = 0; 1383 streaming_t *streaming_p = streaming_parray[unit]; 1384 1385 soc_dma_init(unit); 1386 1387 dv_tx = soc_dma_dv_alloc(unit, DV_TX, 3); 1388 1389 SOC_PBMP_CLEAR(lp_pbm); 1390 SOC_PBMP_PORT_ADD(lp_pbm, 1); 1391 SOC_PBMP_CLEAR(empty_pbm0); 1392 SOC_PBMP_CLEAR(empty_pbm1); 1393 1394 cli_out("\nSending packets ..."); 1395 1396 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1397 if (streaming_p->pkt_size_param == 0) { 1398 if (IS_HG_PORT(unit, streaming_p->port_list[i])) { 1399 pkt_size = HG2_WC_PKT_SIZE; 1400 } else { 1401 pkt_size = ENET_WC_PKT_SIZE; 1402 } 1403 } else { 1404 pkt_size = streaming_p->pkt_size_param; 1405 } 1406 1407 if (streaming_p->flood_pkt_cnt_param == 0) { 1408 flood_cnt = lossless_flood_cnt(unit, pkt_size, i); 1409 } else { 1410 flood_cnt = streaming_p->flood_pkt_cnt_param; 1411 } 1412 1413 if (pkt_size == 1) { 1414 use_random_packet_sizes = 1; 1415 } 1416 1417 cli_out("\nflood_cnt for test port %0d = %0d", i, flood_cnt); 1418 1419 for (j = 0; j < flood_cnt; j++) { 1420 if (use_random_packet_sizes == 1) { 1421 pkt_size = streaming_p->rand_pkt_sizes[i][j]; 1422 } 1423 packet_store_ptr = 1424 sal_dma_alloc(pkt_size * sizeof(uint8), "packet"); 1425 1426 pkt_count++; 1427 channel_done = 0; 1428 soc_dma_abort_dv(unit, dv_tx); 1429 sal_srand(streaming_p->pkt_seed + i + j); 1430 streaming_gen_random_l2_pkt(packet_store_ptr, pkt_size, mac_da, 1431 mac_sa, TPID, (VLAN + i), j); 1432 soc_dma_dv_reset(DV_TX, dv_tx); 1433 soc_dma_desc_add(dv_tx, (sal_vaddr_t) (packet_store_ptr), pkt_size, 1434 lp_pbm, empty_pbm0, empty_pbm1, flags, NULL); 1435 soc_dma_desc_end_packet(dv_tx); 1436 (void) soc_dma_chan_config(unit, TX_CHAN, DV_TX, SOC_DMA_F_POLL); 1437 soc_dma_start(unit, TX_CHAN, dv_tx); 1438 1439 while (channel_done == 0) { 1440 soc_dma_chan_poll_done(unit, TX_CHAN, 1441 SOC_DMA_POLL_CHAIN_DONE, 1442 &channel_done); 1443 } 1444 sal_dma_free(packet_store_ptr); 1445 } 1446 cli_out("\n%0d Packets sent", pkt_count); 1447 } 1448 soc_dma_dv_free(unit, dv_tx); 1449 } 1450 1451 /* 1452 * Function: 1453 * get_rates 1454 * Purpose: 1455 * Read packet counters in the MAC to measure rate over a given interval. 1456 * Parameters: 1457 * unit - StrataSwitch Unit #. 1458 * rate_calc_int: Interval in seconds over which rate is measured 1459 * 1460 * Returns: 1461 * Nothing 1462 */ 1463 1464 static void 1465 get_rates(int unit, uint32 rate_calc_int) 1466 { 1467 int p; 1468 int i; 1469 uint32 ipg, preamble; 1470 uint64 rdata, tpkt, tbyt; 1471 uint64 tpkt_delta; 1472 uint64 tbyt_delta; 1473 uint64 rate_calc_int_64; 1474 soc_reg_t reg_tpkt = TPKTr, reg_tbyt = TBYTr; 1475 1476 streaming_t *streaming_p = streaming_parray[unit]; 1477 1478 COMPILER_64_SET(rate_calc_int_64, 0, rate_calc_int); 1479 1480 cli_out("\nCalculating Rates:"); 1481 1482 streaming_p->tpkt_start = 1483 (uint64 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint64), 1484 "tpkt_start"); 1485 streaming_p->tpkt_end = 1486 (uint64 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint64), 1487 "tpkt_end"); 1488 streaming_p->tbyt_start = 1489 (uint64 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint64), 1490 "tbyt_start"); 1491 streaming_p->tbyt_end = 1492 (uint64 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint64), 1493 "tbyt_end"); 1494 streaming_p->rate = 1495 (uint64 *) sal_alloc(streaming_p->num_fp_ports * sizeof(uint64), 1496 "rate"); 1497 1498 cli_out("\nWait 2s for traffic to stabilize"); 1499 sal_usleep(2000000); 1500 1501 cli_out("\nMeasuring Rate over a period of %0ds", rate_calc_int); 1502 1503 bcm_stat_sync(unit); 1504 1505 i = 0; 1506 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1507 1508 if (SOC_IS_TOMAHAWK3(unit)) { 1509 bcm_stat_get(unit, p, snmpDot1dTpPortOutFrames, &tpkt); 1510 COMPILER_64_SET(streaming_p->tpkt_start[i], COMPILER_64_HI(tpkt), 1511 COMPILER_64_LO(tpkt)); 1512 i++; 1513 } else { 1514 if (stream_get_reg_tpkt_tbyt(unit, p, ®_tpkt, ®_tbyt) != 1515 BCM_E_FAIL) { 1516 /* coverity[check_return : FALSE] */ 1517 soc_reg_get(unit, reg_tpkt, p, 0, &rdata); 1518 COMPILER_64_SET(streaming_p->tpkt_start[i], COMPILER_64_HI(rdata), 1519 COMPILER_64_LO(rdata)); 1520 i++; 1521 } 1522 } 1523 } 1524 1525 i = 0; 1526 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1527 if (SOC_IS_TOMAHAWK3(unit)) { 1528 bcm_stat_get(unit, p, snmpIfOutOctets, &tbyt); 1529 COMPILER_64_SET(streaming_p->tbyt_start[i], COMPILER_64_HI(tbyt), 1530 COMPILER_64_LO(tbyt)); 1531 i++; 1532 } else { 1533 if (stream_get_reg_tpkt_tbyt(unit, p, ®_tpkt, ®_tbyt) != 1534 BCM_E_FAIL) { 1535 /* coverity[check_return : FALSE] */ 1536 soc_reg_get(unit, reg_tbyt, p, 0, &rdata); 1537 COMPILER_64_SET(streaming_p->tbyt_start[i], COMPILER_64_HI(rdata), 1538 COMPILER_64_LO(rdata)); 1539 i++; 1540 } 1541 } 1542 } 1543 1544 sal_usleep(rate_calc_int * 1000000); 1545 1546 i = 0; 1547 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1548 if (SOC_IS_TOMAHAWK3(unit)) { 1549 bcm_stat_get(unit, p, snmpIfOutOctets, &tbyt); 1550 COMPILER_64_SET(streaming_p->tbyt_end[i], COMPILER_64_HI(tbyt), 1551 COMPILER_64_LO(tbyt)); 1552 i++; 1553 } else { 1554 if (stream_get_reg_tpkt_tbyt(unit, p, ®_tpkt, ®_tbyt) != 1555 BCM_E_FAIL) { 1556 /* coverity[check_return : FALSE] */ 1557 soc_reg_get(unit, reg_tbyt, p, 0, &rdata); 1558 COMPILER_64_SET(streaming_p->tbyt_end[i], COMPILER_64_HI(rdata), 1559 COMPILER_64_LO(rdata)); 1560 i++; 1561 } 1562 } 1563 } 1564 1565 i = 0; 1566 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1567 if (SOC_IS_TOMAHAWK3(unit)) { 1568 bcm_stat_get(unit, p, snmpDot1dTpPortOutFrames, &tpkt); 1569 COMPILER_64_SET(streaming_p->tpkt_end[i], COMPILER_64_HI(tpkt), 1570 COMPILER_64_LO(tpkt)); 1571 i++; 1572 } else { 1573 if (stream_get_reg_tpkt_tbyt(unit, p, ®_tpkt, ®_tbyt) != 1574 BCM_E_FAIL) { 1575 /* coverity[check_return : FALSE] */ 1576 soc_reg_get(unit, reg_tpkt, p, 0, &rdata); 1577 COMPILER_64_SET(streaming_p->tpkt_end[i], COMPILER_64_HI(rdata), 1578 COMPILER_64_LO(rdata)); 1579 i++; 1580 } 1581 } 1582 } 1583 1584 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1585 if (IS_HG_PORT(unit, streaming_p->port_list[i])) { 1586 ipg = HG2_IPG; 1587 preamble = 0; 1588 } else { 1589 ipg = ENET_IPG; 1590 preamble = ENET_PREAMBLE; 1591 } 1592 COMPILER_64_DELTA(tbyt_delta, streaming_p->tbyt_start[i], 1593 streaming_p->tbyt_end[i]); 1594 COMPILER_64_DELTA(tpkt_delta, streaming_p->tpkt_start[i], 1595 streaming_p->tpkt_end[i]); 1596 COMPILER_64_UMUL_32(tpkt_delta, (ipg + preamble)); 1597 COMPILER_64_ADD_64(tbyt_delta, tpkt_delta); 1598 COMPILER_64_UMUL_32(tbyt_delta, 8); 1599 COMPILER_64_SET(streaming_p->rate[i], COMPILER_64_HI(tbyt_delta), 1600 COMPILER_64_LO(tbyt_delta)); 1601 COMPILER_64_UDIV_64(streaming_p->rate[i], rate_calc_int_64); 1602 } 1603 } 1604 1605 /* 1606 * Function: 1607 * check_rates 1608 * Purpose: 1609 * Check rates against expected rates. 1610 * Parameters: 1611 * unit - StrataSwitch Unit #. 1612 * 1613 * Returns: 1614 * SOC_E_XXXX 1615 */ 1616 1617 static void 1618 check_rates(int unit) 1619 { 1620 uint64 min_rate; 1621 uint64 max_rate; 1622 uint32 tolerance; 1623 uint64 margin_of_error; 1624 uint64 port_line_rate; 1625 uint64 hundred_64; 1626 int i; 1627 int fail = 0; 1628 char avg_rate_str[32], min_rate_str[32], max_rate_str[32]; 1629 streaming_t *streaming_p = streaming_parray[unit]; 1630 1631 COMPILER_64_SET(hundred_64, 0, 100); 1632 1633 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1634 if (!(COMPILER_64_IS_ZERO(streaming_p->exp_rate[i]))) { 1635 if (streaming_p->port_oversub[i] == 1) { 1636 tolerance = streaming_p->rate_tolerance_ov_param; 1637 } else { 1638 tolerance = streaming_p->rate_tolerance_lr_param; 1639 } 1640 1641 COMPILER_64_SET(margin_of_error, 1642 COMPILER_64_HI(streaming_p->exp_rate[i]), 1643 COMPILER_64_LO(streaming_p->exp_rate[i])); 1644 COMPILER_64_UMUL_32(margin_of_error, tolerance); 1645 COMPILER_64_UDIV_64(margin_of_error, hundred_64); 1646 1647 COMPILER_64_DELTA(min_rate, margin_of_error, 1648 streaming_p->exp_rate[i]); 1649 1650 COMPILER_64_SET(port_line_rate, 0, streaming_p->port_speed[i]); 1651 COMPILER_64_UMUL_32(port_line_rate, 1000000); 1652 COMPILER_64_ZERO(max_rate); 1653 COMPILER_64_SET(margin_of_error, 1654 COMPILER_64_HI(port_line_rate), 1655 COMPILER_64_LO(port_line_rate)); 1656 COMPILER_64_UMUL_32(margin_of_error, tolerance); 1657 COMPILER_64_UDIV_64(margin_of_error, hundred_64); 1658 COMPILER_64_SET(max_rate, COMPILER_64_HI(port_line_rate), 1659 COMPILER_64_LO(port_line_rate)); 1660 COMPILER_64_ADD_64(max_rate, margin_of_error); 1661 1662 cli_out("\n"); 1663 COMPILER_64_UMUL_32(streaming_p->rate[i], streaming_p->speed_factor_param); 1664 if ((COMPILER_64_LT(streaming_p->rate[i], min_rate)) 1665 || (COMPILER_64_GT(streaming_p->rate[i], max_rate))) { 1666 cli_out("*ERROR: "); 1667 fail = 1; 1668 } 1669 format_uint64_decimal(avg_rate_str, streaming_p->rate[i], ','); 1670 format_uint64_decimal(min_rate_str, min_rate, ','); 1671 format_uint64_decimal(max_rate_str, max_rate, ','); 1672 cli_out 1673 ("Test Port = %0d, Device Port = %0d, Rate = %s, " 1674 "min_rate = %s, max_rate = %s", 1675 i, streaming_p->port_list[i], 1676 avg_rate_str, min_rate_str, max_rate_str); 1677 } 1678 } 1679 if (fail == 1) { 1680 test_error(unit, 1681 "\n*************** RATE CHECKS FAILED ***************\n"); 1682 streaming_p->test_fail = 1; 1683 } else { 1684 cli_out("\n****************** RATE CHECKS PASSED ******************\n"); 1685 } 1686 } 1687 1688 /* 1689 * Function: 1690 * set_up_ports 1691 * Purpose: 1692 * Enable port bridging and HiGig lookup for HG2 ports 1693 * Parameters: 1694 * unit - StrataSwitch Unit #. 1695 * 1696 * Returns: 1697 * Nothing 1698 */ 1699 1700 static void 1701 set_up_ports(int unit) 1702 { 1703 int i; 1704 lport_tab_entry_t lport_tab_entry; 1705 port_tab_entry_t port_tab_entry; 1706 streaming_t *streaming_p = streaming_parray[unit]; 1707 soc_field_t ihg_lookup_fields[] = 1708 { HYBRID_MODE_ENABLEf, USE_MH_PKT_PRIf, USE_MH_VIDf, HG_LOOKUP_ENABLEf, 1709 REMOVE_MH_SRC_PORTf 1710 }; 1711 uint32 ihg_lookup_values[] = { 0x0, 0x1, 0x1, 0x1, 0x0 }; 1712 1713 if (!SOC_IS_TOMAHAWK3(unit)) { 1714 cli_out("\nEnabling HG_LOOKUP on HG ports"); 1715 1716 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1717 if (IS_HG_PORT(unit, streaming_p->port_list[i])) { 1718 soc_reg_fields32_modify(unit, IHG_LOOKUPr, 1719 streaming_p->port_list[i], 5, 1720 ihg_lookup_fields, ihg_lookup_values); 1721 } 1722 } 1723 } 1724 1725 cli_out("\nEnabling Port bridging"); 1726 1727 for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) { 1728 (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i, 1729 lport_tab_entry.entry_data); 1730 if (soc_mem_field_valid(unit, LPORT_TABm, ALLOW_SRC_MODf)) { 1731 soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data, 1732 ALLOW_SRC_MODf, 0x1); 1733 } 1734 soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data, 1735 PORT_BRIDGEf, 0x1); 1736 soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i, 1737 lport_tab_entry.entry_data); 1738 } 1739 1740 for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) { 1741 (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i, port_tab_entry.entry_data); 1742 soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data, 1743 PORT_BRIDGEf, 0x1); 1744 soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i, 1745 port_tab_entry.entry_data); 1746 } 1747 } 1748 1749 /* 1750 * Function: 1751 * check_mib_counters 1752 * Purpose: 1753 * Checks Error counters in MAC 1754 * Parameters: 1755 * unit - StrataSwitch Unit #. 1756 * 1757 * Returns: 1758 * Nothing 1759 */ 1760 1761 static void 1762 check_mib_counters(int unit) 1763 { 1764 uint32 i, j, column; 1765 uint64 rdata; 1766 int rv; 1767 int pblk; 1768 streaming_t *streaming_p = streaming_parray[unit]; 1769 soc_reg_t error_counters[][4] = { 1770 {RFLRr, XLMIB_RFLRr, CLMIB_RFLRr, GRFLRr}, 1771 {RFCSr, XLMIB_RFCSr, CLMIB_RFCSr, GRFCSr}, 1772 {RJBRr, XLMIB_RJBRr, CLMIB_RJBRr, GRJBRr}, 1773 {RMTUEr, XLMIB_RMTUEr, CLMIB_RMTUEr, GRMTUEr}, 1774 {RTRFUr, XLMIB_RTRFUr, CLMIB_RTRFUr, INVALIDr}, 1775 {RERPKTr, XLMIB_RERPKTr, CLMIB_RERPKTr, GRCDEr}, 1776 {RRPKTr, XLMIB_RRPKTr, CLMIB_RRPKTr, GRRPKTr}, 1777 {RUNDr, XLMIB_RUNDr, CLMIB_RUNDr, GRUNDr}, 1778 {RFRGr, XLMIB_RFRGr, CLMIB_RFRGr, GRFRGr}, 1779 {RRBYTr, XLMIB_RRBYTr, CLMIB_RRBYTr, GRRBYTr}, 1780 {TJBRr, XLMIB_TJBRr, CLMIB_TJBRr, GTJBRr}, 1781 {TFCSr, XLMIB_TFCSr, CLMIB_TFCSr, GTFCSr}, 1782 {TERRr, XLMIB_TERRr, CLMIB_TERRr, GTXCLr}, 1783 {TFRGr, XLMIB_TFRGr, CLMIB_TFRGr, GTFRGr}, 1784 {TRPKTr, XLMIB_TRPKTr, CLMIB_TRPKTr, INVALIDr}, 1785 {TUFLr, XLMIB_TUFLr, CLMIB_TUFLr, INVALIDr}, 1786 {TPCEr, TPCE_64r, TPCE_64r, TPCE_64r}, 1787 {RDISCr, RDISC_64r, RDISC_64r, RDISC_64r}, 1788 {RIPHE4r, RIPHE4_64r, RIPHE4_64r, RIPHE4_64r}, 1789 {RIPHE6r, RIPHE6_64r, RIPHE6_64r, RIPHE6_64r}, 1790 {RIPD4r, RIPD4_64r, RIPD4_64r, RIPD4_64r}, 1791 {RIPD6r, RIPD6_64r, RIPD6_64r, RIPD6_64r}, 1792 {RPORTDr, RPORTD_64r, RPORTD_64r, RPORTD_64r} 1793 }; 1794 1795 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1796 column = 0; 1797 1798 if (soc_feature(unit, soc_feature_cxl_mib)) { 1799 pblk = SOC_PORT_BLOCK(unit, 1800 SOC_INFO(unit).port_l2p_mapping[streaming_p->port_list[i]]); 1801 if (SOC_BLOCK_IS_CMP(unit, pblk, SOC_BLK_CLPORT)) { 1802 column = 2; 1803 } else if (IS_QSGMII_PORT(unit, streaming_p->port_list[i])) { 1804 column = 3; 1805 } else if (SOC_BLOCK_IS_CMP(unit, pblk, SOC_BLK_XLPORT)) { 1806 column = 1; 1807 } 1808 } 1809 for (j = 0; j < (sizeof(error_counters) / sizeof(error_counters[0])); j++) { 1810 if (SOC_REG_IS_VALID(unit, error_counters[j][column])) { 1811 rv = soc_reg_get(unit, error_counters[j][column], 1812 streaming_p->port_list[i], 0, &rdata); 1813 1814 if (SOC_FAILURE(rv)) { 1815 test_error(unit, "\nError reading MIB counter %s", 1816 SOC_REG_NAME(unit, error_counters[j][column])); 1817 streaming_p->test_fail = 1; 1818 } else if (!(COMPILER_64_IS_ZERO(rdata))) { 1819 test_error (unit, "\n*ERROR: Error counter %s has a non zero value " 1820 "for device port %0d", 1821 SOC_REG_NAME(unit, error_counters[j][column]), 1822 streaming_p->port_list[i]); 1823 streaming_p->test_fail = 1; 1824 } 1825 } 1826 } 1827 } 1828 } 1829 1830 /* 1831 * Function: 1832 * invalidate_vlan 1833 * Purpose: 1834 * Invalidates VLAN in VLAN table 1835 * Parameters: 1836 * unit - StrataSwitch Unit #. 1837 * test_port - Test port number 1838 * 1839 * Returns: 1840 * Nothing 1841 */ 1842 1843 static void 1844 invalidate_vlan(int unit, uint32 vlan) 1845 { 1846 vlan_tab_entry_t vlan_tab_entry; 1847 1848 (void) soc_mem_read(unit, VLAN_TABm, COPYNO_ALL, vlan, vlan_tab_entry.entry_data); 1849 soc_mem_field32_set(unit, VLAN_TABm, vlan_tab_entry.entry_data, 1850 VALIDf, 0x0); 1851 soc_mem_write(unit, VLAN_TABm, COPYNO_ALL, vlan, vlan_tab_entry.entry_data); 1852 } 1853 1854 /* 1855 * Function: 1856 * check_packet_integrity 1857 * Purpose: 1858 * Redirect all packets back to CPU and check packet integrity 1859 * Parameters: 1860 * unit - StrataSwitch Unit #. 1861 * 1862 * Returns: 1863 * Nothing 1864 */ 1865 1866 static void 1867 check_packet_integrity(int unit) 1868 { 1869 uint8 mac_da[] = MAC_DA; 1870 uint8 mac_sa[] = MAC_SA; 1871 uint8 *ref_pkt_ptr; 1872 uint8 *rx_pkt_ptr; 1873 uint32 pkt_size; 1874 int i, j, k; 1875 pbmp_t lp_pbm, empty_pbm0, empty_pbm1; 1876 dv_t *dv_rx; 1877 int channel_done; 1878 int flags = 0; 1879 uint32 pkt_count = 0; 1880 uint32 pkt_count_port = 0; 1881 uint32 flood_cnt; 1882 int timeout = RXDMA_TIMEOUT; 1883 uint32 match = 1; 1884 uint32 zero_crc = 1; 1885 uint32 seq_id; 1886 streaming_t *streaming_p = streaming_parray[unit]; 1887 uint32 header_size = 0; 1888 1889 dv_rx = soc_dma_dv_alloc(unit, DV_RX, 3); 1890 1891 SOC_PBMP_CLEAR(lp_pbm); 1892 SOC_PBMP_PORT_ADD(lp_pbm, 1); 1893 SOC_PBMP_CLEAR(empty_pbm0); 1894 SOC_PBMP_CLEAR(empty_pbm1); 1895 1896 cli_out("\nRouting all packets back to CPU to check pkt integrity ..."); 1897 1898 soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 1, 0xffffffff); 1899 soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 2, 0xffffffff); 1900 1901 soc_dma_header_size_get(unit, &header_size); 1902 1903 soc_reg_field32_modify(unit, CPU_CONTROL_0r, 0, UVLAN_TOCPUf, 0x1); 1904 1905 for (i = 0; i < streaming_p->num_fp_ports; i++) { 1906 if (streaming_p->pkt_size_param == 0) { 1907 if (IS_HG_PORT(unit, streaming_p->port_list[i])) { 1908 pkt_size = HG2_WC_PKT_SIZE; 1909 } else { 1910 pkt_size = ENET_WC_PKT_SIZE; 1911 } 1912 } else { 1913 pkt_size = streaming_p->pkt_size_param; 1914 } 1915 1916 if (streaming_p->flood_pkt_cnt_param == 0) { 1917 flood_cnt = lossless_flood_cnt(unit, pkt_size, i); 1918 } else { 1919 flood_cnt = streaming_p->flood_pkt_cnt_param; 1920 } 1921 for (j = 0; j < flood_cnt; j++) { 1922 ref_pkt_ptr = 1923 sal_dma_alloc(MTU * sizeof(uint8), "ref_packet"); 1924 rx_pkt_ptr = 1925 sal_dma_alloc(MTU * sizeof(uint8) + header_size, "rx_pkt"); 1926 1927 for (k = 0; k < MTU + header_size; k++) { 1928 rx_pkt_ptr[k] = 0x00; 1929 } 1930 1931 channel_done = 0; 1932 soc_dma_abort_dv(unit, dv_rx); 1933 1934 soc_dma_dv_reset(DV_RX, dv_rx); 1935 soc_dma_desc_add(dv_rx, (sal_vaddr_t) (rx_pkt_ptr), MTU, 1936 lp_pbm, empty_pbm0, empty_pbm1, flags, NULL); 1937 soc_dma_desc_end_packet(dv_rx); 1938 (void) soc_dma_chan_config(unit, RX_CHAN, DV_RX, SOC_DMA_F_POLL); 1939 1940 soc_dma_start(unit, RX_CHAN, dv_rx); 1941 invalidate_vlan(unit, (VLAN + i)); 1942 1943 while (channel_done == 0 && timeout > 0) { 1944 soc_dma_chan_poll_done(unit, RX_CHAN, 1945 SOC_DMA_POLL_CHAIN_DONE, 1946 &channel_done); 1947 timeout--; 1948 } 1949 1950 if (timeout > 0) { 1951 pkt_count++; 1952 pkt_count_port++; 1953 seq_id = 0x00000000; 1954 pkt_size = 0x00000000; 1955 1956 seq_id |= (rx_pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 6 + header_size] << 24); 1957 seq_id |= (rx_pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 7 + header_size] << 16); 1958 seq_id |= (rx_pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 8 + header_size] << 8); 1959 seq_id |= (rx_pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 9 + header_size]); 1960 pkt_size |= (rx_pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 10 + header_size] << 8); 1961 pkt_size |= (rx_pkt_ptr[(2 * NUM_BYTES_MAC_ADDR) + 11 + header_size]); 1962 1963 sal_srand(streaming_p->pkt_seed + i + seq_id); 1964 streaming_gen_random_l2_pkt(ref_pkt_ptr, pkt_size, mac_da, 1965 mac_sa, TPID, (VLAN + i), seq_id); 1966 1967 for (k = 0; k < (pkt_size - NUM_BYTES_CRC); k++) { 1968 if (rx_pkt_ptr[k + header_size] != ref_pkt_ptr[k]) { 1969 match = 0; 1970 test_error(unit, "\n*ERROR: Test port %0d, " 1971 "Device Port %0d has packet corruption" 1972 " on received pkt %0d", 1973 i, streaming_p->port_list[i], j); 1974 streaming_p->test_fail = 1; 1975 while(k < (pkt_size - NUM_BYTES_CRC)) 1976 { 1977 cli_out("\n Expected byte: %d -- Received byte: %d",ref_pkt_ptr[k], rx_pkt_ptr[k + header_size]); 1978 k++; 1979 } 1980 break; 1981 } 1982 } 1983 1984 for(k = 0; k < NUM_BYTES_CRC; k++) { 1985 if (rx_pkt_ptr[header_size + pkt_size - NUM_BYTES_CRC + k] != 0) { 1986 zero_crc = 0; 1987 } 1988 } 1989 1990 if (zero_crc == 1) { 1991 match = 0; 1992 test_error(unit, "\n*ERROR: Test port %0d, " 1993 "Device Port %0d has packet corruption" 1994 "(zero CRC) on received pkt %0d", 1995 i, streaming_p->port_list[i], j); 1996 streaming_p->test_fail = 1; 1997 } 1998 1999 zero_crc = 1; 2000 } else 2001 { 2002 cli_out("\n first packet was not sent back to CPU"); 2003 timeout = RXDMA_TIMEOUT; 2004 sal_dma_free(rx_pkt_ptr); 2005 sal_dma_free(ref_pkt_ptr); 2006 break; 2007 } 2008 2009 timeout = RXDMA_TIMEOUT; 2010 sal_dma_free(rx_pkt_ptr); 2011 sal_dma_free(ref_pkt_ptr); 2012 } 2013 cli_out("\n%0d Packets received", pkt_count); 2014 2015 if (pkt_count_port < flood_cnt) { 2016 match = 0; 2017 test_error(unit, "\n*ERROR: Test port %0d, Device Port %0d" 2018 " expected %0d pkts, received %0d packets", 2019 i, streaming_p->port_list[i], flood_cnt, 2020 pkt_count_port); 2021 streaming_p->test_fail = 1; 2022 } 2023 pkt_count_port = 0; 2024 } 2025 2026 soc_dma_dv_free(unit, dv_rx); 2027 2028 if (match == 1) { 2029 cli_out("\n***** PACKET INTEGRITY CHECKS PASSED *****\n"); 2030 } 2031 else { 2032 test_error(unit, "\n***** PACKET INTEGRITY CHECKS FAILED *****\n"); 2033 } 2034 } 2035 2036 /* 2037 * Function: 2038 * streaming_test_init 2039 * Purpose: 2040 * Test init function. Parse CLI params and do necessary init. 2041 * Parameters: 2042 * unit - StrataSwitch Unit #. 2043 * 2044 * Returns: 2045 * Nothing 2046 */ 2047 2048 2049 int 2050 streaming_test_init(int unit, args_t *a, void **pa) 2051 { 2052 streaming_t *streaming_p; 2053 2054 streaming_p = streaming_parray[unit]; 2055 2056 streaming_p = sal_alloc(sizeof(streaming_t), "streaming_test"); 2057 sal_memset(streaming_p, 0, sizeof(streaming_t)); 2058 streaming_parray[unit] = streaming_p; 2059 cli_out("\nCalling streaming_test_init"); 2060 streaming_parse_test_params(unit, a); 2061 2062 streaming_p->test_fail = 0; 2063 2064 if (streaming_p->bad_input == 1) { 2065 goto done; 2066 } 2067 2068 streaming_soc_set_up_mac_lpbk(unit); 2069 streaming_turn_off_cmic_mmu_bkp(unit); 2070 streaming_soc_turn_off_fc(unit); 2071 /* coverity[dont_call : FALSE] */ 2072 streaming_p->pkt_seed = sal_rand(); 2073 2074 done: 2075 return 0; 2076 } 2077 2078 /* 2079 * Function: 2080 * streaming_test 2081 * Purpose: 2082 * Set up ports/streams and send packets. 2083 * Parameters: 2084 * unit - StrataSwitch Unit #. 2085 * 2086 * Returns: 2087 * Nothing 2088 */ 2089 2090 2091 int 2092 streaming_test(int unit, args_t *a, void *pa) 2093 { 2094 streaming_t *streaming_p; 2095 2096 streaming_p = streaming_parray[unit]; 2097 2098 if (streaming_p->bad_input == 1) { 2099 goto done; 2100 } 2101 2102 cli_out("\nCalling streaming_test"); 2103 set_port_property_arrays(unit); 2104 set_up_ports(unit); 2105 set_up_streams(unit); 2106 send_pkts(unit); 2107 2108 done: 2109 return 0; 2110 } 2111 2112 /* 2113 * Function: 2114 * streaming_test_cleanup 2115 * Purpose: 2116 * Do test end checks and free all allocated memory. 2117 * Parameters: 2118 * unit - StrataSwitch Unit #. 2119 * 2120 * Returns: 2121 * Nothing 2122 */ 2123 2124 int 2125 streaming_test_cleanup(int unit, void *pa) 2126 { 2127 streaming_t *streaming_p; 2128 int rv; 2129 2130 streaming_p = streaming_parray[unit]; 2131 2132 if (streaming_p->bad_input == 1) { 2133 goto done; 2134 } 2135 cli_out("\nCalling streaming_test_cleanup"); 2136 2137 get_rates(unit, streaming_p->rate_calc_interval_param); 2138 check_mib_counters(unit); 2139 check_rates(unit); 2140 2141 if (streaming_p->check_packet_integrity_param != 0) { 2142 check_packet_integrity(unit); 2143 } 2144 2145 sal_free(streaming_p->port_speed); 2146 sal_free(streaming_p->port_oversub); 2147 sal_free(streaming_p->ovs_ratio_x1000); 2148 sal_free(streaming_p->rate); 2149 sal_free(streaming_p->exp_rate); 2150 sal_free(streaming_p->tpkt_start); 2151 sal_free(streaming_p->tpkt_end); 2152 2153 done: 2154 if (streaming_p->bad_input == 1) { 2155 streaming_p->test_fail = 1; 2156 } 2157 2158 if (streaming_p->test_fail == 1) { 2159 rv = BCM_E_FAIL; 2160 } 2161 else { 2162 rv = BCM_E_NONE; 2163 } 2164 2165 sal_free(streaming_p); 2166 2167 cli_out("\n"); 2168 2169 return rv; 2170 } 2171 #endif /* BCM_ESW_SUPPORT */