streaming_l2uc.c (35655B)
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 * L2UC Streaming test to check basic L2 packet switching. The test pairs up 8 * same speed ports and creates L2UC traffic swills. Test also 9 * calculates expected rates based on port config and oversub ratio, measures 10 * actual rate over a period of time and conducts rate checks. Finally all 11 * packets in each swill will be redirected to the CPU and checked for integrity. 12 * 13 * Configuration parameters passed from CLI: 14 * PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all 15 * ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes 16 * FloodCnt: Number of packets in each swill. Setting this to 0 will let the 17 * test calculate the number of packets that can be sent to achieve 18 * a lossless swirl at full rate. Set to 0 by default. 19 * RateCalcInt: Interval in seconds over which rate is to be calculated 20 * TolLr: Rate tolerance percentage for linerate ports (1% by default). 21 * TolOv: Rate tolerance percentage for oversubscribed ports (3% by default). 22 * ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default). 23 * MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set 24 * to 0 for random. 25 */ 26 27 #include <appl/diag/system.h> 28 #include <shared/alloc.h> 29 #include <shared/bsl.h> 30 31 #include <soc/cm.h> 32 #include <soc/dma.h> 33 #include <soc/drv.h> 34 #include <soc/dcb.h> 35 #include <soc/cmicm.h> 36 #include <soc/cmic.h> 37 38 #include <sal/types.h> 39 #include <appl/diag/parse.h> 40 #include <bcm/port.h> 41 #include <bcm/vlan.h> 42 43 #include "testlist.h" 44 #include "gen_pkt.h" 45 #include "streaming_lib.h" 46 47 #define MAC_DA {0x12,0x34,0x56,0x78,0x9a,0xbc} 48 #define MAC_SA {0xfe,0xdc,0xba,0x98,0x76,0x54} 49 #define VLAN 0x0a00 50 51 #define XLATE_VLAN0 0x0100 52 #define XLATE_VLAN1 0x0400 53 54 #define MAX_FP_PORTS 130 55 #define MAX_NUM_CELLS_PARAM_DEFAULT 4 56 57 #define HG2_MY_MODID 100 58 #define MODPORT_MAP_OFFSET 256 59 60 #define NULL_DEST 999 61 62 #define PKT_SIZE_PARAM_DEFAULT 0 63 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0 64 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10 65 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 1 66 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 3 67 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 1 68 #define SPEEDUP_FACTOR_PARAM_DEFAULT 1 69 #define NUM_LPORT_TAB_ENTRIES 256 70 #define NUM_PORT_TAB_ENTRIES 136 71 72 #if defined(BCM_ESW_SUPPORT) && \ 73 (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) 74 75 typedef struct l2uc_s { 76 uint32 num_fp_ports; 77 uint32 num_streams; 78 int *port_speed; 79 int *port_list; 80 int *dest_port; 81 uint32 *stream; 82 int *hg_stream; 83 uint32 *modid; 84 uint32 *port_oversub; 85 uint32 num_pipes; 86 uint32 total_chip_bw; 87 uint32 bw_per_pipe; 88 uint32 *ovs_ratio_x1000; 89 uint64 *rate; 90 uint64 *exp_rate; 91 uint64 *tpkt_start; 92 uint64 *tpkt_end; 93 uint64 *tbyt_start; 94 uint64 *tbyt_end; 95 uint32 **rand_pkt_sizes; 96 uint32 pkt_size_param; 97 uint32 flood_pkt_cnt_param; 98 uint32 rate_calc_interval_param; 99 uint32 rate_tolerance_lr_param; 100 uint32 rate_tolerance_ov_param; 101 uint32 check_packet_integrity_param; 102 uint32 max_num_cells_param; 103 uint32 scaling_factor_param; 104 uint32 bad_input; 105 int test_fail; 106 uint32 pkt_seed; 107 } l2uc_t; 108 109 static l2uc_t *l2uc_parray[SOC_MAX_NUM_DEVICES]; 110 111 112 /* 113 * Function: 114 * l2uc_lossless_flood_cnt 115 * Purpose: 116 * Calculates number of packets that need to be sent to a port for a 117 * lossless swirl 118 * Parameters: 119 * unit - StrataSwitch Unit #. 120 * pkt_size : Packet size in bytes 121 * port: Test port no 122 * Returns: 123 * Number of packets needed for lossless flooding 124 */ 125 static uint32 126 l2uc_lossless_flood_cnt(int unit, int port_idx, int hg_en) 127 { 128 uint32 port, num_fp_ports, pkt_size, flood_cnt; 129 uint32 *rand_pkt_size; 130 int param_flood_cnt, param_pkt_size; 131 l2uc_t *l2uc_p = l2uc_parray[unit]; 132 133 port = l2uc_p->port_list[port_idx]; 134 num_fp_ports = l2uc_p->num_fp_ports; 135 rand_pkt_size = l2uc_p->rand_pkt_sizes[port_idx]; 136 param_flood_cnt = l2uc_p->flood_pkt_cnt_param; 137 param_pkt_size = l2uc_p->pkt_size_param; 138 139 if (param_flood_cnt == 0) { 140 if (param_pkt_size == 0) { 141 pkt_size = stream_get_wc_pkt_size(unit, hg_en); 142 } else { 143 pkt_size = param_pkt_size; 144 } 145 flood_cnt = stream_get_ll_flood_cnt(unit, port, pkt_size, 146 rand_pkt_size); 147 if (num_fp_ports > 0) { 148 flood_cnt = (flood_cnt * MAX_FP_PORTS) / num_fp_ports; 149 if (flood_cnt % 2 == 1) { 150 flood_cnt++; 151 } 152 } 153 } else { 154 flood_cnt = param_flood_cnt; 155 } 156 157 return(flood_cnt); 158 } 159 160 /* 161 * Function: 162 * l2uc_chk_port_rate 163 * Purpose: 164 * Check actual port rates against expected port rates. 165 * Parameters: 166 * unit - StrataSwitch Unit #. 167 * 168 * Returns: 169 * SOC_E_XXXX 170 */ 171 static bcm_error_t 172 l2uc_chk_port_rate(int unit) 173 { 174 int i, port; 175 bcm_error_t rv = BCM_E_NONE; 176 stream_rate_t *rate_calc; 177 l2uc_t *l2uc_p = l2uc_parray[unit]; 178 179 rate_calc = (stream_rate_t *) 180 sal_alloc(sizeof(stream_rate_t), "rate_calc"); 181 if (rate_calc == NULL) { 182 test_error(unit, "Failed to allocate memory for rate_calc\n"); 183 return BCM_E_FAIL; 184 } 185 sal_memset(rate_calc, 0, sizeof(stream_rate_t)); 186 187 rate_calc->mode = 0; /* check act_rate against config_rate */ 188 rate_calc->pkt_size = l2uc_p->pkt_size_param; 189 rate_calc->interval_len = l2uc_p->rate_calc_interval_param; 190 rate_calc->tolerance_lr = l2uc_p->rate_tolerance_lr_param; 191 rate_calc->tolerance_os = l2uc_p->rate_tolerance_ov_param; 192 rate_calc->scaling_factor = l2uc_p->scaling_factor_param; 193 194 SOC_PBMP_CLEAR(rate_calc->pbmp); 195 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 196 port = l2uc_p->port_list[i]; 197 if (port < SOC_MAX_NUM_PORTS) { 198 SOC_PBMP_PORT_ADD(rate_calc->pbmp, port); 199 /* src_port */ 200 rate_calc->src_port[port] = port; 201 } 202 } 203 204 rv = stream_chk_port_rate(unit, PBMP_PORT_ALL(unit), rate_calc); 205 206 sal_free(rate_calc); 207 return rv; 208 } 209 210 /* 211 * Function: 212 * l2uc_chk_pkt_integrity 213 * Purpose: 214 * Redirect all packets back to CPU and check packet integrity 215 * Parameters: 216 * unit - StrataSwitch Unit #. 217 * 218 * Returns: 219 * SOC_E_XXXX 220 */ 221 static bcm_error_t 222 l2uc_chk_pkt_integrity(int unit) 223 { 224 int i, port, port_idx, vlan_id; 225 int param_pkt_seed; 226 uint32 flood_cnt; 227 uint8 mac_da[] = MAC_DA; 228 uint8 mac_sa[] = MAC_SA; 229 stream_integrity_t *pkt_intg; 230 bcm_error_t rv = BCM_E_NONE; 231 l2uc_t *l2uc_p = l2uc_parray[unit]; 232 233 param_pkt_seed = l2uc_p->pkt_seed; 234 235 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt_intg"); 236 if (pkt_intg == NULL) { 237 test_error(unit, "Failed to allocate memory for pkt_intg\n"); 238 return BCM_E_FAIL; 239 } 240 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 241 242 pkt_intg->type = PKT_TYPE_L2; 243 SOC_PBMP_CLEAR(pkt_intg->rx_pbmp); 244 for (i = 0; i < l2uc_p->num_streams; i++) { 245 port_idx = l2uc_p->dest_port[l2uc_p->stream[i]]; 246 port = l2uc_p->port_list[port_idx]; 247 if (port < SOC_MAX_NUM_PORTS) { 248 /* rx_pbmp */ 249 SOC_PBMP_PORT_ADD(pkt_intg->rx_pbmp, port); 250 /* rx_vlan */ 251 if (l2uc_p->hg_stream[i] == 1) { 252 vlan_id = VLAN + i; 253 } else { 254 vlan_id = XLATE_VLAN0 + i; 255 } 256 pkt_intg->rx_vlan[port] = vlan_id; 257 /* tx_vlan */ 258 if (l2uc_p->hg_stream[i] == 1) { 259 vlan_id = VLAN + i; 260 } else { 261 vlan_id = XLATE_VLAN1 + i; 262 } 263 pkt_intg->tx_vlan[port] = vlan_id; 264 /* port_flood_cnt */ 265 flood_cnt = l2uc_lossless_flood_cnt(unit, port_idx, 266 l2uc_p->hg_stream[i]); 267 pkt_intg->port_flood_cnt[port] = flood_cnt * 2; 268 /* port_pkt_seed */ 269 pkt_intg->port_pkt_seed[port] = param_pkt_seed + i; 270 /* mac_da, mac_sa */ 271 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR); 272 sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR); 273 } 274 } 275 276 if (stream_chk_pkt_integrity(unit, pkt_intg) != BCM_E_NONE) { 277 rv = BCM_E_FAIL; 278 } 279 280 sal_free(pkt_intg); 281 return rv; 282 } 283 284 /* 285 * Function: 286 * l2uc_parse_test_params 287 * Purpose: 288 * Parse CLI parameters, create test structure and flag bad inputs. 289 * Parameters: 290 * unit - StrataSwitch Unit #. 291 * a - Pointer to arguments 292 * 293 * Returns: 294 * Nothing 295 * Notes: 296 * l2uc_p->bad_input set from here - tells test to crash out in case 297 * CLI input combination is invalid. 298 */ 299 static void 300 l2uc_parse_test_params(int unit, args_t *a) 301 { 302 parse_table_t parse_table; 303 l2uc_t *l2uc_p = l2uc_parray[unit]; 304 305 const char tr510_test_usage[] = 306 #ifdef COMPILER_STRING_CONST_LIMIT 307 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 308 #else 309 "\nL2UC Streaming test to check basic L2 packet switching. The test pairs up\n" 310 "same speed ports and creates L2UC traffic swills. Test also\n" 311 "calculates expected rates based on port config and oversub ratio, measures\n" 312 "actual rate over a period of time and conducts rate checks. Finally all\n" 313 "packets in each swill will be redirected to the CPU and checked for integrity.\n" 314 "\n" 315 "Configuration parameters passed from CLI:\n" 316 "PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all\n" 317 " ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes\n" 318 "FloodCnt: Number of packets in each swill. Setting this to 0 will let the\n" 319 " test calculate the number of packets that can be sent to achieve\n" 320 " a lossless swirl at full rate. Set to 0 by default.\n" 321 "RateCalcInt: Interval in seconds over which rate is to be calculated\n" 322 "TolLr: Rate tolerance percentage for linerate ports (1 percentage by default).\n" 323 "TolOv: Rate tolerance percentage for oversubscribed ports (3 percentage by default).\n" 324 "ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default).\n" 325 "MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set\n" 326 " to 0 for random.\n"; 327 #endif 328 329 l2uc_p->bad_input = 0; 330 331 l2uc_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT; 332 l2uc_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT; 333 l2uc_p->rate_calc_interval_param = RATE_CALC_INTERVAL_PARAM_DEFAULT; 334 l2uc_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT; 335 l2uc_p->rate_tolerance_ov_param = RATE_TOLERANCE_OV_PARAM_DEFAULT; 336 l2uc_p->check_packet_integrity_param 337 = CHECK_PACKET_INTEGRITY_PARAM_DEFAULT; 338 l2uc_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT; 339 l2uc_p->scaling_factor_param = SPEEDUP_FACTOR_PARAM_DEFAULT; 340 341 /*Parse CLI opts */ 342 343 parse_table_init(unit, &parse_table); 344 parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0, 345 &(l2uc_p->pkt_size_param), NULL); 346 parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0, 347 &(l2uc_p->flood_pkt_cnt_param), NULL); 348 parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0, 349 &(l2uc_p->rate_calc_interval_param), NULL); 350 parse_table_add(&parse_table, "TolLr", PQ_INT|PQ_DFL, 0, 351 &(l2uc_p->rate_tolerance_lr_param), NULL); 352 parse_table_add(&parse_table, "TolOv", PQ_INT|PQ_DFL, 0, 353 &(l2uc_p->rate_tolerance_ov_param), NULL); 354 parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0, 355 &(l2uc_p->check_packet_integrity_param), NULL); 356 parse_table_add(&parse_table, "MaxNumCells", PQ_INT|PQ_DFL, 0, 357 &(l2uc_p->max_num_cells_param), NULL); 358 parse_table_add(&parse_table, "ScalingFactor", PQ_INT|PQ_DFL, 0, 359 &(l2uc_p->scaling_factor_param), NULL); 360 361 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 362 test_msg("%s", tr510_test_usage); 363 test_error(unit, 364 "%s: Invalid option: %s\n", 365 ARG_CMD(a), 366 ARG_CUR(a) ? ARG_CUR(a) : "*"); 367 l2uc_p->bad_input = 1; 368 parse_arg_eq_done(&parse_table); 369 } else { 370 cli_out("\n"); 371 cli_out("------------- PRINTING TEST PARAMS ------------------\n"); 372 cli_out("PktSize = %0d\n", l2uc_p->pkt_size_param); 373 cli_out("RateCalcInt = %0d\n", l2uc_p->rate_calc_interval_param); 374 cli_out("FloodCnt = %0d\n", l2uc_p->flood_pkt_cnt_param); 375 cli_out("TolLr = %0d\n", l2uc_p->rate_tolerance_lr_param); 376 cli_out("TolOv = %0d\n", l2uc_p->rate_tolerance_ov_param); 377 cli_out("ChkPktInteg = %0d\n", l2uc_p->check_packet_integrity_param); 378 cli_out("MaxNumCells = %0d\n", l2uc_p->max_num_cells_param); 379 cli_out("ScalingFactor= %0d\n", l2uc_p->scaling_factor_param); 380 cli_out("-----------------------------------------------------\n"); 381 } 382 383 if (l2uc_p->max_num_cells_param == 0) { 384 /* coverity[dont_call : FALSE] */ 385 l2uc_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1; 386 } 387 388 if (l2uc_p->pkt_size_param == 0) { 389 cli_out 390 ("\nUsing worst case packet sizes - 145B for Ethernet " 391 "and 76B (64B + 12B hg-hdr) for HG2"); 392 } else if (l2uc_p->pkt_size_param == 1) { 393 cli_out("\nUsing random packet sizes"); 394 } else if (l2uc_p->pkt_size_param < MIN_PKT_SIZE) { 395 test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n", 396 MIN_PKT_SIZE); 397 l2uc_p->bad_input = 1; 398 } else if (l2uc_p->pkt_size_param > MTU) { 399 test_error(unit,"\n*ERROR: Packet size cannot be higher than %0dB (Device MTU)\n", 400 MTU); 401 l2uc_p->bad_input = 1; 402 } 403 404 if (l2uc_p->flood_pkt_cnt_param == 0) { 405 cli_out("\nFloodCnt=0, test will automatically calculate number of" 406 " packets to flood each port"); 407 } 408 } 409 410 411 /* 412 * Function: 413 * l2uc_set_port_property 414 * Purpose: 415 * Set port_list, port_speed and port_oversub arrays. Also call set_exp_rates 416 * Parameters: 417 * unit: StrataSwitch Unit #. 418 * 419 * Returns: 420 * Safe packet size. 421 */ 422 static void 423 l2uc_set_port_property(int unit) 424 { 425 int p, i, j, paired_port; 426 uint32 pkt_size, can_be_paired = 0; 427 soc_info_t *si = &SOC_INFO(unit); 428 l2uc_t *l2uc_p = l2uc_parray[unit]; 429 430 l2uc_p->num_fp_ports = 0; 431 l2uc_p->num_streams = 0; 432 433 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 434 l2uc_p->num_fp_ports++; 435 } 436 437 l2uc_p->port_list = 438 (int *)sal_alloc(l2uc_p->num_fp_ports * sizeof(int), 439 "port_list"); 440 l2uc_p->port_speed = 441 (int *)sal_alloc(l2uc_p->num_fp_ports * sizeof(int), 442 "port_speed_array"); 443 l2uc_p->dest_port = 444 (int *)sal_alloc(l2uc_p->num_fp_ports * sizeof(int), 445 "dest_port_array"); 446 l2uc_p->stream = 447 (uint32 *)sal_alloc(l2uc_p->num_fp_ports * sizeof(uint32), 448 "stream"); 449 l2uc_p->modid = 450 (uint32 *)sal_alloc(l2uc_p->num_fp_ports * sizeof(int), 451 "modid_array"); 452 l2uc_p->hg_stream = 453 (int *)sal_alloc(l2uc_p->num_fp_ports * sizeof(int), 454 "hg_stream_array"); 455 l2uc_p->port_oversub = 456 (uint32 *) sal_alloc(l2uc_p->num_fp_ports * sizeof(uint32), 457 "port_oversub_array"); 458 l2uc_p->rand_pkt_sizes = 459 (uint32 **) sal_alloc(l2uc_p->num_fp_ports * sizeof(uint32 *), 460 "rand_pkt_sizes_array*"); 461 462 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 463 l2uc_p->rand_pkt_sizes[i] = 464 (uint32 *) sal_alloc(TARGET_CELL_COUNT * sizeof(uint32), 465 "rand_pkt_sizes_array"); 466 } 467 468 i = 0; 469 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 470 l2uc_p->port_list[i] = p; 471 i++; 472 } 473 474 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 475 l2uc_p->port_speed[i] = 476 si->port_speed_max[l2uc_p->port_list[i]]; 477 478 switch(l2uc_p->port_speed[i]) { 479 case 11000: l2uc_p->port_speed[i] = 10600; break; 480 case 27000: l2uc_p->port_speed[i] = 26500; break; 481 case 42000: l2uc_p->port_speed[i] = 42400; break; 482 default: break; 483 } 484 } 485 486 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 487 if (SOC_PBMP_MEMBER(si->oversub_pbm, l2uc_p->port_list[i]) && 488 (!(SOC_PBMP_MEMBER(si->management_pbm, l2uc_p->port_list[i])))) { 489 l2uc_p->port_oversub[i] = 1; 490 } else { 491 l2uc_p->port_oversub[i] = 0; 492 } 493 } 494 495 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 496 l2uc_p->dest_port[i] = NULL_DEST; 497 l2uc_p->hg_stream[i] = 0; 498 } 499 500 /* a trick to accelerate port grouping, if same speed eth and hg */ 501 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 502 if (IS_HG_PORT(unit, l2uc_p->port_list[i])) { 503 l2uc_p->port_speed[i] |= 0x1; 504 } 505 } 506 507 /* set src and dst ports for each stream */ 508 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 509 can_be_paired = 0; 510 if(l2uc_p->dest_port[i] == NULL_DEST) { 511 for (j = 0;j < l2uc_p->num_fp_ports; j++) { 512 if((l2uc_p->dest_port[j] == NULL_DEST) 513 && (l2uc_p->port_speed[i] 514 == l2uc_p->port_speed[j]) 515 && (i!=j)) { 516 can_be_paired = 1; 517 } 518 } 519 520 if(can_be_paired) { 521 do { 522 paired_port = sal_rand() % l2uc_p->num_fp_ports; 523 }while((l2uc_p->port_speed[i] != 524 l2uc_p->port_speed[paired_port]) 525 || (l2uc_p->dest_port[paired_port] != NULL_DEST) 526 || (i == paired_port)); 527 528 l2uc_p->dest_port[i] = paired_port; 529 l2uc_p->dest_port[paired_port] = i; 530 l2uc_p->stream[l2uc_p->num_streams] = i; 531 if (IS_HG_PORT(unit, l2uc_p->port_list[i])) { 532 l2uc_p->hg_stream[l2uc_p->num_streams] = 1; 533 l2uc_p->modid[i] = l2uc_p->num_streams; 534 l2uc_p->modid[paired_port] = l2uc_p->num_streams; 535 } 536 l2uc_p->num_streams++; 537 } 538 } 539 } 540 541 /* restore hg speed */ 542 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 543 if (IS_HG_PORT(unit, l2uc_p->port_list[i])) { 544 l2uc_p->port_speed[i] &= ~0x1; 545 } 546 } 547 548 /* random packet size */ 549 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 550 for (j = 0; j < TARGET_CELL_COUNT; j++) { 551 do { 552 /* coverity[dont_call : FALSE] */ 553 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + MIN_PKT_SIZE; 554 } while (stream_get_pkt_cell_cnt(unit, pkt_size, l2uc_p->port_list[i]) > 555 l2uc_p->max_num_cells_param); 556 l2uc_p->rand_pkt_sizes[i][j] = pkt_size; 557 } 558 } 559 560 { 561 /* print */ 562 LOG_INFO(BSL_LS_APPL_TESTS, 563 (BSL_META_U(unit, "\n==== STREAM INFO (VERBOSE) =====\n"))); 564 LOG_INFO(BSL_LS_APPL_TESTS, 565 (BSL_META_U(unit, "\n%8s%8s%8s%8s%8s%8s\n"), 566 "idx", "port", "dst", "speed", "ovsb", "HiGig")); 567 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 568 LOG_INFO(BSL_LS_APPL_TESTS, 569 (BSL_META_U(unit, "%8d%8d%8d%7dG"), 570 i, 571 l2uc_p->port_list[i], 572 l2uc_p->port_list[l2uc_p->dest_port[i]], 573 l2uc_p->port_speed[i]/1000)); 574 if (SOC_PBMP_MEMBER(si->oversub_pbm, l2uc_p->port_list[i])) { 575 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "OS")); 576 } else { 577 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "--")); 578 } 579 if (IS_HG_PORT(unit, l2uc_p->port_list[i])) { 580 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "HG")); 581 } else { 582 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%8s"), "--")); 583 } 584 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 585 } 586 } 587 } 588 589 /* 590 * Function: 591 * l2uc_set_up_ports 592 * Purpose: 593 * Programs port table to set unique modid for each HG2 port. Also 594 * programs ING_VLAN_TAG_ACTION_PROFILEm to remove the inner tag for 595 * double tagged packets. 596 * Parameters: 597 * unit - StrataSwitch Unit #. 598 * 599 * Returns: 600 * Nothing 601 */ 602 static void 603 l2uc_set_up_ports(int unit) 604 { 605 int p; 606 port_tab_entry_t port_tab_entry; 607 ing_vlan_tag_action_profile_entry_t ing_vlan_tag_action_profile_entry; 608 609 if (SOC_MEM_IS_VALID(unit, PORT_TABm)) { 610 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 611 if (IS_HG_PORT(unit, p)) { 612 (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, 613 p, port_tab_entry.entry_data); 614 soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data, 615 MY_MODIDf, (HG2_MY_MODID + p)); 616 (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, p, 617 port_tab_entry.entry_data); 618 } 619 } 620 } else { 621 cli_out("\n*ERROR, invalid mem %s\n", SOC_MEM_NAME(unit, PORT_TABm)); 622 } 623 624 if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILEm)) { 625 (void) soc_mem_read(unit, ING_VLAN_TAG_ACTION_PROFILEm, COPYNO_ALL, 626 0, ing_vlan_tag_action_profile_entry.entry_data); 627 soc_mem_field32_set(unit, ING_VLAN_TAG_ACTION_PROFILEm, 628 ing_vlan_tag_action_profile_entry.entry_data, 629 DT_ITAG_ACTIONf, 0x3); 630 (void) soc_mem_write(unit, ING_VLAN_TAG_ACTION_PROFILEm, COPYNO_ALL, 631 0, ing_vlan_tag_action_profile_entry.entry_data); 632 } else { 633 cli_out("\n*ERROR, invalid mem %s\n", 634 SOC_MEM_NAME(unit, ING_VLAN_TAG_ACTION_PROFILEm)); 635 } 636 } 637 638 /* 639 * Function: 640 * set_modport_map_index_upper 641 * Purpose: 642 * Set MODPORT_MAP_SEL.MODPORT_MAP_INDEX_UPPER to a given value 643 * Parameters: 644 * unit: StrataSwitch Unit #. 645 * port : Device Port no 646 * index : Value for MODPORT_MAP_INDEX_UPPER 647 * 648 * Returns: 649 * Nothing. 650 */ 651 static void 652 set_modport_map_index_upper(int unit, int port, uint32 index) 653 { 654 if (SOC_REG_IS_VALID(unit, MODPORT_MAP_SELr)) { 655 soc_reg_field32_modify(unit, MODPORT_MAP_SELr, port, 656 MODPORT_MAP_INDEX_UPPERf, index); 657 } else { 658 cli_out("\n*ERROR, invalid reg %s\n", 659 SOC_REG_NAME(unit, MODPORT_MAP_SELr)); 660 } 661 } 662 663 /* 664 * Function: 665 * set_modport_map_sw 666 * Purpose: 667 * Program MODPORT_MAP_SW to set destination port for a given HG2 port 668 * Parameters: 669 * unit: StrataSwitch Unit #. 670 * modid : Modid for HG2 port 671 * index_upper: MODPORT_MAP_SEL.MODPORT_MAP_INDEX_UPPER 672 * dest0: Dest device port 673 * 674 * Returns: 675 * Nothing. 676 */ 677 static void 678 set_modport_map_sw(int unit, uint32 modid, uint32 index_upper, uint32 dest0) 679 { 680 modport_map_sw_entry_t modport_map_sw_entry; 681 uint32 index; 682 683 if (SOC_MEM_IS_VALID(unit, MODPORT_MAP_SWm)) { 684 index = (index_upper * MODPORT_MAP_OFFSET) + modid; 685 686 (void) soc_mem_read(unit, MODPORT_MAP_SWm, COPYNO_ALL, index, 687 modport_map_sw_entry.entry_data); 688 soc_mem_field32_set(unit, MODPORT_MAP_SWm, 689 modport_map_sw_entry.entry_data, DEST0f, dest0); 690 soc_mem_field32_set(unit, MODPORT_MAP_SWm, 691 modport_map_sw_entry.entry_data, ENABLE0f, 0x1); 692 (void) soc_mem_write(unit, MODPORT_MAP_SWm, COPYNO_ALL, index, 693 modport_map_sw_entry.entry_data); 694 } else { 695 cli_out("\n*ERROR, invalid mem %s\n", 696 SOC_MEM_NAME(unit, MODPORT_MAP_SWm)); 697 } 698 } 699 700 /* 701 * Function: 702 * l2uc_set_up_streams 703 * Purpose: 704 * Program switch to set up L2UC streams between port pairs. For Ethernet 705 * ports this involves setting up VLAN translations and L2 entries to get 706 * a packet flow of CPU -> P0 (Vlan0, Xlate_Vlan0) -> P1(Xlate_vlan1) -> P0 ... 707 * For HG2 ports the modport map table is programmed such that packets 708 * coming from P0 are directed to P1 and packets coming from P1 are directed 709 * to P0. Packets coming from the CPU are broadcast to both P0 and P1. The 710 * HG2 flow is CPU ->P0,P1 and P0->P1->P0 and P1->P0->P1. 711 * 712 * Parameters: 713 * unit: StrataSwitch Unit #. 714 * 715 * 716 * Returns: 717 * Nothing 718 */ 719 static void 720 l2uc_set_up_streams(int unit) 721 { 722 int i; 723 pbmp_t pbm, ubm; 724 uint32 vlan = VLAN; 725 uint32 xlate_vlan0 = XLATE_VLAN0; 726 uint32 xlate_vlan1 = XLATE_VLAN1; 727 uint32 *port_accounted_for; 728 l2uc_t *l2uc_p = l2uc_parray[unit]; 729 bcm_l2_addr_t l2_addr; 730 bcm_mac_t mac_da = MAC_DA; 731 732 port_accounted_for = (uint32*)sal_alloc(l2uc_p->num_fp_ports 733 * sizeof(uint32), "port_accounted_for"); 734 735 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 736 port_accounted_for[i] = 0; 737 } 738 739 BCM_PBMP_CLEAR(ubm); 740 bcm_vlan_destroy_all(unit); 741 bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE); 742 743 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 744 if (l2uc_p->dest_port[i] != NULL_DEST 745 && port_accounted_for[i] == 0 746 && port_accounted_for[l2uc_p->dest_port[i]] == 0) { 747 if (IS_HG_PORT(unit, l2uc_p->port_list[i])) { 748 BCM_PBMP_CLEAR(pbm); 749 bcm_vlan_create(unit, (bcm_vlan_t) (vlan)); 750 BCM_PBMP_PORT_ADD(pbm, l2uc_p->port_list[i]); 751 BCM_PBMP_PORT_ADD(pbm, l2uc_p->port_list[l2uc_p-> 752 dest_port[i]]); 753 bcm_vlan_port_add(unit, (bcm_vlan_t) (vlan), pbm, ubm); 754 port_accounted_for[i] = 1; 755 port_accounted_for[l2uc_p->dest_port[i]] = 1; 756 757 set_modport_map_index_upper(unit, l2uc_p->port_list[i], 0x1); 758 set_modport_map_sw(unit, l2uc_p->modid[i], 759 0x0, l2uc_p->port_list[i]); 760 set_modport_map_index_upper(unit, l2uc_p->port_list[l2uc_p-> 761 dest_port[i]], 0x0); 762 set_modport_map_sw(unit, l2uc_p->modid[l2uc_p->dest_port[i]], 763 0x1, l2uc_p->port_list[l2uc_p->dest_port[i]]); 764 765 bcm_l2_addr_t_init(&l2_addr, mac_da, (bcm_vlan_t)(vlan)); 766 l2_addr.port = 1; 767 l2_addr.modid = l2uc_p->modid[i]; 768 l2_addr.flags = 0; 769 bcm_l2_addr_add(unit, &l2_addr); 770 } else { 771 bcm_vlan_create(unit, (bcm_vlan_t) (vlan)); 772 bcm_vlan_create(unit, (bcm_vlan_t) (xlate_vlan0)); 773 bcm_vlan_create(unit, (bcm_vlan_t) (xlate_vlan1)); 774 BCM_PBMP_CLEAR(pbm); 775 BCM_PBMP_PORT_ADD(pbm, l2uc_p->port_list[i]); 776 BCM_PBMP_PORT_ADD(pbm, l2uc_p->port_list[l2uc_p-> 777 dest_port[i]]); 778 bcm_vlan_port_add(unit, (bcm_vlan_t) (vlan), pbm, ubm); 779 BCM_PBMP_CLEAR(pbm); 780 BCM_PBMP_PORT_ADD(pbm, l2uc_p->port_list[l2uc_p-> 781 dest_port[i]]); 782 bcm_vlan_port_add(unit, (bcm_vlan_t) (xlate_vlan0), pbm, ubm); 783 BCM_PBMP_CLEAR(pbm); 784 BCM_PBMP_PORT_ADD(pbm, l2uc_p->port_list[i]); 785 bcm_vlan_port_add(unit, (bcm_vlan_t) (xlate_vlan1), pbm, ubm); 786 787 bcm_vlan_translate_add(unit, l2uc_p->port_list[i], 788 (bcm_vlan_t)(vlan), 789 (bcm_vlan_t)(xlate_vlan0), 0); 790 bcm_vlan_translate_add(unit, l2uc_p->port_list[i], 791 (bcm_vlan_t)(xlate_vlan1), 792 (bcm_vlan_t)(xlate_vlan0), 0); 793 bcm_vlan_translate_add(unit, l2uc_p->port_list[l2uc_p-> 794 dest_port[i]], 795 (bcm_vlan_t)(vlan), 796 (bcm_vlan_t)(xlate_vlan1), 0); 797 bcm_vlan_translate_add(unit, l2uc_p->port_list[l2uc_p-> 798 dest_port[i]], 799 (bcm_vlan_t)(xlate_vlan0), 800 (bcm_vlan_t)(xlate_vlan1), 0); 801 bcm_l2_addr_t_init(&l2_addr, mac_da, (bcm_vlan_t)(xlate_vlan0)); 802 l2_addr.port = l2uc_p->port_list[l2uc_p->dest_port[i]]; 803 l2_addr.flags = 0; 804 bcm_l2_addr_add(unit, &l2_addr); 805 806 bcm_l2_addr_t_init(&l2_addr, mac_da, (bcm_vlan_t)(xlate_vlan1)); 807 l2_addr.port = l2uc_p->port_list[i]; 808 l2_addr.flags = 0; 809 bcm_l2_addr_add(unit, &l2_addr); 810 811 port_accounted_for[i] = 1; 812 port_accounted_for[l2uc_p->dest_port[i]] = 1; 813 } 814 815 xlate_vlan0++; 816 xlate_vlan1++; 817 vlan++; 818 } 819 } 820 } 821 822 /* 823 * Function: 824 * l2uc_send_pkts 825 * Purpose: 826 * Send packets to flood create swills on each port pair. 827 * Parameters: 828 * unit - StrataSwitch Unit #. 829 * 830 * Returns: 831 * Nothing 832 */ 833 static void 834 l2uc_send_pkts(int unit) 835 { 836 uint8 mac_da[] = MAC_DA; 837 uint8 mac_sa[] = MAC_SA; 838 int i, port; 839 int hg_en; 840 uint32 flood_cnt, pkt_size, num_pkts_tx, pkt_count = 0; 841 uint32 use_random_packet_sizes = 0; 842 l2uc_t *l2uc_p = l2uc_parray[unit]; 843 stream_pkt_t *tx_pkt; 844 845 tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt"); 846 sal_memset(tx_pkt, 0, sizeof(stream_pkt_t)); 847 848 if (l2uc_p->pkt_size_param == 1) { 849 use_random_packet_sizes = 1; 850 } 851 852 cli_out("\n==================================================\n"); 853 cli_out("\nSending packets ...\n\n"); 854 for (i = 0; i < l2uc_p->num_streams; i++) { 855 hg_en = l2uc_p->hg_stream[i] == 1 ? 1: 0; 856 if (l2uc_p->pkt_size_param == 0) { 857 pkt_size = stream_get_wc_pkt_size(unit, hg_en); 858 } else { 859 pkt_size = l2uc_p->pkt_size_param; 860 } 861 862 port = l2uc_p->dest_port[l2uc_p->stream[i]]; 863 flood_cnt = l2uc_lossless_flood_cnt(unit, port, l2uc_p->hg_stream[i]); 864 if (l2uc_p->hg_stream[i] == 1) { 865 num_pkts_tx = 2 * flood_cnt; 866 } else { 867 num_pkts_tx = flood_cnt; 868 } 869 870 tx_pkt->port = port; 871 tx_pkt->num_pkt = num_pkts_tx; 872 tx_pkt->pkt_seed = l2uc_p->pkt_seed + i; 873 tx_pkt->pkt_size = pkt_size; 874 tx_pkt->rand_pkt_size_en = use_random_packet_sizes; 875 tx_pkt->rand_pkt_size = NULL; 876 tx_pkt->tx_vlan = VLAN + i; 877 sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR); 878 sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR); 879 if (tx_pkt->rand_pkt_size_en) { 880 tx_pkt->rand_pkt_size = l2uc_p->rand_pkt_sizes[port]; 881 } 882 stream_tx_pkt(unit, tx_pkt); 883 884 /* print */ 885 cli_out("Stream %0d, pkt_flood_count = %0d\n", i, tx_pkt->cnt_pkt); 886 pkt_count += tx_pkt->cnt_pkt; 887 } 888 889 cli_out("\nTotal packets sent: %d\n\n", pkt_count); 890 sal_free(tx_pkt); 891 } 892 893 /* 894 * Function: 895 * l2uc_test_init 896 * Purpose: 897 * Test init function. Parse CLI params and do necessary init. 898 * Parameters: 899 * unit - StrataSwitch Unit #. 900 * 901 * Returns: 902 * Nothing 903 */ 904 int 905 l2uc_test_init(int unit, args_t *a, void **pa) 906 { 907 l2uc_t *l2uc_p; 908 909 l2uc_p = l2uc_parray[unit]; 910 l2uc_p = sal_alloc(sizeof(l2uc_t), "l2uc_test"); 911 sal_memset(l2uc_p, 0, sizeof(l2uc_t)); 912 l2uc_parray[unit] = l2uc_p; 913 cli_out("\nCalling l2uc_test_init"); 914 l2uc_parse_test_params(unit, a); 915 916 l2uc_p->test_fail = 0; 917 if (l2uc_p->bad_input == 1) { 918 goto done; 919 } 920 921 /* set mac loopback on all ports */ 922 stream_set_mac_lpbk(unit, PBMP_PORT_ALL(unit)); 923 /* turn off cmic to mmu backpressure */ 924 stream_turn_off_cmic_mmu_bkp(unit); 925 /* turn off flow control */ 926 stream_turn_off_fc(unit, PBMP_PORT_ALL(unit)); 927 /* coverity[dont_call : FALSE] */ 928 l2uc_p->pkt_seed = sal_rand(); 929 930 done: 931 return 0; 932 } 933 934 /* 935 * Function: 936 * l2uc_test 937 * Purpose: 938 * Set up ports/streams and send packets. 939 * Parameters: 940 * unit - StrataSwitch Unit #. 941 * 942 * Returns: 943 * Nothing 944 */ 945 int 946 l2uc_test(int unit, args_t *a, void *pa) 947 { 948 l2uc_t *l2uc_p = l2uc_parray[unit]; 949 950 if (l2uc_p->bad_input == 1) { 951 goto done; 952 } 953 954 cli_out("\nCalling l2uc_test"); 955 l2uc_set_port_property(unit); 956 l2uc_set_up_ports(unit); 957 l2uc_set_up_streams(unit); 958 l2uc_send_pkts(unit); 959 960 /* check counter */ 961 if (stream_chk_mib_counters(unit, PBMP_PORT_ALL(unit), 0) != BCM_E_NONE) { 962 l2uc_p->test_fail = 1; 963 } 964 /* check rate */ 965 if (l2uc_chk_port_rate(unit) != BCM_E_NONE) { 966 l2uc_p->test_fail = 1; 967 } 968 /* check integrity */ 969 if (l2uc_p->check_packet_integrity_param != 0) { 970 if (l2uc_chk_pkt_integrity(unit) != BCM_E_NONE) { 971 l2uc_p->test_fail = 1; 972 } 973 } 974 975 done: 976 return 0; 977 } 978 979 /* 980 * Function: 981 * l2uc_test_cleanup 982 * Purpose: 983 * Do test end checks and free all allocated memory. 984 * Parameters: 985 * unit - StrataSwitch Unit #. 986 * 987 * Returns: 988 * Nothing 989 */ 990 int 991 l2uc_test_cleanup(int unit, void *pa) 992 { 993 l2uc_t *l2uc_p = l2uc_parray[unit]; 994 int i, rv; 995 996 if (l2uc_p->bad_input == 1) { 997 goto done; 998 } 999 LOG_INFO(BSL_LS_APPL_TESTS, 1000 (BSL_META_U(unit, "\nCalling l2uc_test_cleanup\n"))); 1001 1002 sal_free(l2uc_p->port_speed); 1003 sal_free(l2uc_p->port_list); 1004 sal_free(l2uc_p->dest_port); 1005 sal_free(l2uc_p->stream); 1006 sal_free(l2uc_p->hg_stream); 1007 sal_free(l2uc_p->modid); 1008 sal_free(l2uc_p->port_oversub); 1009 sal_free(l2uc_p->ovs_ratio_x1000); 1010 sal_free(l2uc_p->rate); 1011 sal_free(l2uc_p->exp_rate); 1012 sal_free(l2uc_p->tpkt_start); 1013 sal_free(l2uc_p->tpkt_end); 1014 sal_free(l2uc_p->tbyt_start); 1015 sal_free(l2uc_p->tbyt_end); 1016 1017 for (i = 0; i < l2uc_p->num_fp_ports; i++) { 1018 sal_free(l2uc_p->rand_pkt_sizes[i]); 1019 } 1020 sal_free(l2uc_p->rand_pkt_sizes); 1021 1022 done: 1023 if (l2uc_p->bad_input == 1) { 1024 l2uc_p->test_fail = 1; 1025 } 1026 1027 if (l2uc_p->test_fail == 1) { 1028 rv = BCM_E_FAIL; 1029 } else { 1030 rv = BCM_E_NONE; 1031 } 1032 1033 cli_out("\n=================================================="); 1034 cli_out("\n=================================================="); 1035 if (l2uc_p->test_fail == 1) { 1036 cli_out("\n[L2UC test failed]\n\n"); 1037 } else { 1038 cli_out("\n[L2UC test passed]\n\n"); 1039 } 1040 1041 sal_free(l2uc_p); 1042 1043 return rv; 1044 } 1045 #endif /* BCM_ESW_SUPPORT */