streaming_l2mc.c (45344B)
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 * The goal of this test is to check basic multicast and broadcast features of 8 * the chip. 9 * Test Sequence: 10 * 1. Group all active front panel ports into groups of (NumCopy + 1) ports. 11 * Each group constitutes 1 multicast "stream". All ports in a stream should 12 * either be Ethernet or HG2 and have the same line rate, although they may 13 * have different oversub ratios. 14 * 2. Let us assume a stream has n ports P0, P1 ... Pn. The ports should be 15 * arranged such that the P1 is the slowest port, i.e. has the highest 16 * oversub ratio. 17 * 3. Turn off all flow control, set MAC loopback on all ports and set 18 * IGNORE_MY_MODID to 1 on ING_CONFIG_64. 19 * 4. For Ethernet streams: 20 * a. Place all ports in the stream on a single VLAN, say VLAN0. 21 * b. Place ports P0 and P1 on a second VLAN, say VLAN1. 22 * c. Create a 3rd VLAN, say VLAN3 with no ports on it. 23 * d. Add the following VLAN translations: 24 * i. Port=P0 OldVlan=VLAN1 NewVlan=VLAN0 25 * ii. Port=P1 OldVlan=VLAN0 NewVlan=VLAN1 26 * iii. Ports=P2, P3 ... Pn OldVlan=VLAN0 NewVlan=VLAN2 27 * 5. For HG2 streams: 28 * a. Place port P0 on VLAN0. 29 * b. Place ports P0, P1 ... Pn on VLAN1. 30 * c. Place all ports in the stream except P0, i.e. P1, P2 ... Pn on VLAN2 31 * d. Create 3 entries, say L2MC0, L2MC1 and L2MC2. 32 * i. L2MC0: PORT_BITMAP = P0 33 * ii. L2MC1: PORT_BITMAP = P0 34 * iii. L2MC2: PORT_BITMAP = P1, P2 ... Pn 35 * e. Add the following IFP entries: 36 * i. Qualifier: OuterVlan=VLAN0, Actions: OuterVlanNew=VLAN1, RedirectMcast=L2MC0 37 * ii. Qualifier: OuterVlan=VLAN2, Actions: OuterVlanNew=VLAN1, RedirectMcast=L2MC1 38 * iii.Qualifier: OuterVlan=VLAN1, Actions: OuterVlanNew=VLAN2, RedirectMcast=L2MC2 39 * 6. Send packets from CPU port on VLAN0 of each stream to flood the stream. 40 * If FloodCnt=0, the test will determine the number of packets to send based. 41 * These values are obtained empirically through trial and error for LR ports 42 * for NumCopy=2 and adjusted for oversub configs based on oversub ratio. 43 * Embed the packet size and random seed used to generate each packet in the 44 * payload. 45 * 7. Allow the packets to swill for a fixed amount of time decided by RateCalcInt. 46 * 8. Snoop back all packets in each stream to the CPU using the following sequence: 47 * a. Program CPU_CONTROL_0.UVLAN_TOCPU=1. This sends all packets with an 48 * unknown VLAN to CPU. 49 * b. Invalidate VLAN0 for Ethernet Streams and VLAN1 for HG2 streams by 50 * setting VALID=0 in the VLAN table 51 * 9. Decode each received packet to obtain the random seed and packet size. 52 * Reconstruct the expected packet and check the received packet for integrity. 53 * 54 * Configuration parameters passed from CLI: 55 * PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all 56 * ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes 57 * FloodCnt: Number of packets in each swill. Setting this to 0 will let the 58 * test calculate the number of packets that can be sent to achieve 59 * a lossless swirl at full rate. Set to 0 by default. 60 * NumCopy: Number of multicast copies in each stream (2 by default). 61 * RateCalcInt: Interval in seconds over which rate is to be calculated 62 * TolLr: Rate tolerance percentage for linerate ports (1% by default). 63 * TolOv: Rate tolerance percentage for oversubscribed ports (3% by default). 64 * ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default). 65 * MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set 66 * to 0 for random. 67 */ 68 69 #include <appl/diag/system.h> 70 #include <shared/alloc.h> 71 #include <shared/bsl.h> 72 73 #include <soc/cm.h> 74 #include <soc/dma.h> 75 #include <soc/drv.h> 76 #include <soc/dcb.h> 77 #include <soc/cmicm.h> 78 #include <soc/cmic.h> 79 80 #include <sal/types.h> 81 #include <appl/diag/parse.h> 82 #include <bcm/port.h> 83 #include <bcm/vlan.h> 84 #include <bcm/link.h> 85 86 #include "testlist.h" 87 #include "gen_pkt.h" 88 #include "streaming_lib.h" 89 90 #define MAC_DA {0x01,0x00,0x0c,0xde,0xff,0x00} 91 #define MAC_SA {0xfe,0xdc,0xba,0x98,0x76,0x54} 92 #define VLAN 0x100 93 94 #define MAX_FP_PORTS 130 95 #define MAX_NUM_CELLS_PARAM_DEFAULT 4 96 97 #define FLOOD_CNT_25G 9 98 #define FLOOD_CNT_40G 21 99 #define FLOOD_CNT_50G 28 100 #define FLOOD_CNT_100G 50 101 102 #define MAX_PKTS_PER_STREAM 500 103 104 #define PKT_SIZE_PARAM_DEFAULT 0 105 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0 106 #define NUM_COPY_PARAM_DEFAULT 2 107 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10 108 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 1 109 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 3 110 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 1 111 #define SPEEDUP_FACTOR_PARAM_DEFAULT 1 112 #define NUM_LPORT_TAB_ENTRIES 256 113 #define NUM_PORT_TAB_ENTRIES 136 114 #define CPU_PORT 0 115 116 #if defined(BCM_ESW_SUPPORT) && \ 117 (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) 118 119 typedef struct l2mc_s { 120 121 uint32 num_fp_ports; 122 uint32 num_streams; 123 int *port_speed; 124 int *port_list; 125 int **stream; 126 uint32 *tx_vlan; 127 int *hg_stream; 128 uint32 *port_oversub; 129 uint32 oversub_config; 130 uint32 *port_used; 131 uint32 num_pipes; 132 uint32 total_chip_bw; 133 uint32 bw_per_pipe; 134 uint32 *ovs_ratio_x1000; 135 uint64 *rate; 136 uint64 *exp_rate; 137 uint64 *tpkt_start; 138 uint64 *tpkt_end; 139 uint64 *tbyt_start; 140 uint64 *tbyt_end; 141 uint32 **rand_pkt_sizes; 142 uint32 pkt_size_param; 143 uint32 flood_pkt_cnt_param; 144 uint32 num_copy_param; 145 uint32 rate_calc_interval_param; 146 uint32 rate_tolerance_lr_param; 147 uint32 rate_tolerance_ov_param; 148 uint32 check_packet_integrity_param; 149 uint32 max_num_cells_param; 150 uint32 scaling_factor_param; 151 uint32 bad_input; 152 int test_fail; 153 uint32 pkt_seed; 154 } l2mc_t; 155 156 static l2mc_t *l2mc_parray[SOC_MAX_NUM_DEVICES]; 157 158 /* 159 * Function: 160 * l2mc_print_port_config 161 * Purpose: 162 * Print port config 163 * Parameters: 164 * unit - StrataSwitch Unit #. 165 * 166 * Returns: 167 * Nothing 168 */ 169 static void 170 l2mc_print_port_config(int unit) 171 { 172 int i, port; 173 pbmp_t pbmp; 174 l2mc_t *l2mc_p = l2mc_parray[unit]; 175 176 SOC_PBMP_CLEAR(pbmp); 177 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 178 port = l2mc_p->port_list[i]; 179 if (port < SOC_MAX_NUM_PORTS) { 180 SOC_PBMP_PORT_ADD(pbmp, port); 181 } 182 } 183 stream_print_port_config(unit, pbmp); 184 } 185 186 /* 187 * Function: 188 * l2mc_parse_test_params 189 * Purpose: 190 * Parse CLI parameters, create test structure and flag bad inputs. 191 * Parameters: 192 * unit - StrataSwitch Unit #. 193 * a - Pointer to arguments 194 * 195 * Returns: 196 * Nothing 197 * Notes: 198 * l2mc_p->bad_input set from here - tells test to crash out in case 199 * CLI input combination is invalid. 200 */ 201 static void 202 l2mc_parse_test_params(int unit, args_t *a) 203 { 204 parse_table_t parse_table; 205 l2mc_t *l2mc_p = l2mc_parray[unit]; 206 207 const char tr511_test_usage[] = 208 #ifdef COMPILER_STRING_CONST_LIMIT 209 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 210 #else 211 "The goal of this test is to check basic multicast and broadcast features of\n" 212 "the chip.\n" 213 "Test Sequence:\n" 214 "1. Group all active front panel ports into groups of (NumCopy + 1) ports.\n" 215 " Each group constitutes 1 multicast \"stream\". All ports in a stream should\n" 216 " either be Ethernet or HG2 and have the same line rate, although they may\n" 217 " have different oversub ratios.\n" 218 "2. Let us assume a stream has n ports P0, P1 ... Pn. The ports should be\n" 219 " arranged such that the P1 is the slowest port, i.e. has the highest\n" 220 " oversub ratio.\n" 221 "3. Turn off all flow control, set MAC loopback on all ports and set\n" 222 " IGNORE_MY_MODID to 1 on ING_CONFIG_64.\n" 223 "4. For Ethernet streams:\n" 224 " a. Place all ports in the stream on a single VLAN, say VLAN0.\n" 225 " b. Place ports P0 and P1 on a second VLAN, say VLAN1.\n" 226 " c. Create a 3rd VLAN, say VLAN3 with no ports on it.\n" 227 " d. Add the following VLAN translations:\n" 228 " i. Port=P0 OldVlan=VLAN1 NewVlan=VLAN0\n" 229 " ii. Port=P1 OldVlan=VLAN0 NewVlan=VLAN1\n" 230 " iii. Ports=P2, P3 ... Pn OldVlan=VLAN0 NewVlan=VLAN2\n" 231 "5. For HG2 streams:\n" 232 " a. Place port P0 on VLAN0.\n" 233 " b. Place ports P0, P1 ... Pn on VLAN1.\n" 234 " c. Place all ports in the stream except P0, i.e. P1, P2 ... Pn on VLAN2\n" 235 " d. Create 3 entries, say L2MC0, L2MC1 and L2MC2.\n" 236 " i. L2MC0: PORT_BITMAP = P0\n" 237 " ii. L2MC1: PORT_BITMAP = P0\n" 238 " iii. L2MC2: PORT_BITMAP = P1, P2 ... Pn\n" 239 " e. Add the following IFP entries:\n" 240 " i. Qualifier: OuterVlan=VLAN0, Actions: OuterVlanNew=VLAN1, RedirectMcast=L2MC0\n" 241 " ii. Qualifier: OuterVlan=VLAN2, Actions: OuterVlanNew=VLAN1, RedirectMcast=L2MC1\n" 242 " iii. Qualifier: OuterVlan=VLAN1, Actions: OuterVlanNew=VLAN2, RedirectMcast=L2MC2\n" 243 "6. Send packets from CPU port on VLAN0 of each stream to flood the stream.\n" 244 " If FloodCnt=0, the test will determine the number of packets to send based.\n" 245 " These values are obtained empirically through trial and error for LR ports\n" 246 " for NumCopy=2 and adjusted for oversub configs based on oversub ratio.\n" 247 " Embed the packet size and random seed used to generate each packet in the\n" 248 " payload.\n" 249 "7. Allow the packets to swill for a fixed amount of time decided by RateCalcInt.\n" 250 "8. Snoop back all packets in each stream to the CPU using the following sequence:\n" 251 " a. Program CPU_CONTROL_0.UVLAN_TOCPU=1. This sends all packets with an\n" 252 " unknown VLAN to CPU.\n" 253 " b. Invalidate VLAN0 for Ethernet Streams and VLAN1 for HG2 streams by\n" 254 " setting VALID=0 in the VLAN table\n" 255 "9. Decode each received packet to obtain the random seed and packet size.\n" 256 " Reconstruct the expected packet and check the received packet for integrity.\n" 257 "\n" 258 "Configuration parameters passed from CLI:\n" 259 "PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all\n" 260 " ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes\n" 261 "FloodCnt: Number of packets in each swill. Setting this to 0 will let the\n" 262 " test calculate the number of packets that can be sent to achieve\n" 263 " a lossless swirl at full rate. Set to 0 by default.\n" 264 "NumCopy: Number of multicast copies in each stream (2 by default).\n" 265 "RateCalcInt: Interval in seconds over which rate is to be calculated\n" 266 "TolLr: Rate tolerance percentage for linerate ports (1 percentage by default).\n" 267 "TolOv: Rate tolerance percentage for oversubscribed ports (3 percentage by default).\n" 268 "ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable (default).\n" 269 "MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set\n" 270 " to 0 for random.\n"; 271 #endif 272 273 l2mc_p->bad_input = 0; 274 275 l2mc_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT; 276 l2mc_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT; 277 l2mc_p->num_copy_param = NUM_COPY_PARAM_DEFAULT; 278 l2mc_p->rate_calc_interval_param = RATE_CALC_INTERVAL_PARAM_DEFAULT; 279 l2mc_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT; 280 l2mc_p->rate_tolerance_ov_param = RATE_TOLERANCE_OV_PARAM_DEFAULT; 281 l2mc_p->check_packet_integrity_param 282 = CHECK_PACKET_INTEGRITY_PARAM_DEFAULT; 283 l2mc_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT; 284 l2mc_p->scaling_factor_param = SPEEDUP_FACTOR_PARAM_DEFAULT; 285 286 /*Parse CLI opts */ 287 288 parse_table_init(unit, &parse_table); 289 parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0, 290 &(l2mc_p->pkt_size_param), NULL); 291 parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0, 292 &(l2mc_p->flood_pkt_cnt_param), NULL); 293 parse_table_add(&parse_table, "NumCopy", PQ_INT|PQ_DFL, 0, 294 &(l2mc_p->num_copy_param), NULL); 295 parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0, 296 &(l2mc_p->rate_calc_interval_param), NULL); 297 parse_table_add(&parse_table, "TolLr", PQ_INT|PQ_DFL, 0, 298 &(l2mc_p->rate_tolerance_lr_param), NULL); 299 parse_table_add(&parse_table, "TolOv", PQ_INT|PQ_DFL, 0, 300 &(l2mc_p->rate_tolerance_ov_param), NULL); 301 parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0, 302 &(l2mc_p->check_packet_integrity_param), NULL); 303 parse_table_add(&parse_table, "MaxNumCells", PQ_INT|PQ_DFL, 0, 304 &(l2mc_p->max_num_cells_param), NULL); 305 parse_table_add(&parse_table, "ScalingFactor", PQ_INT|PQ_DFL, 0, 306 &(l2mc_p->scaling_factor_param), NULL); 307 308 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 309 test_msg("%s", tr511_test_usage); 310 test_error(unit, 311 "%s: Invalid option: %s\n", 312 ARG_CMD(a), 313 ARG_CUR(a) ? ARG_CUR(a) : "*"); 314 l2mc_p->bad_input = 1; 315 parse_arg_eq_done(&parse_table); 316 } else { 317 cli_out("\n"); 318 cli_out("------------- PRINTING TEST PARAMS ------------------\n"); 319 cli_out("PktSize = %0d\n", l2mc_p->pkt_size_param); 320 cli_out("FloodCnt = %0d\n", l2mc_p->flood_pkt_cnt_param); 321 cli_out("NumCopy = %0d\n", l2mc_p->num_copy_param); 322 cli_out("RateCalcInt = %0d\n", l2mc_p->rate_calc_interval_param); 323 cli_out("TolLr = %0d\n", l2mc_p->rate_tolerance_lr_param); 324 cli_out("TolOv = %0d\n", l2mc_p->rate_tolerance_ov_param); 325 cli_out("ChkPktInteg = %0d\n", l2mc_p->check_packet_integrity_param); 326 cli_out("MaxNumCells = %0d\n", l2mc_p->max_num_cells_param); 327 cli_out("ScalingFactor= %0d\n", l2mc_p->scaling_factor_param); 328 cli_out("-----------------------------------------------------\n"); 329 } 330 331 if (l2mc_p->max_num_cells_param == 0) { 332 /* coverity[dont_call : FALSE] */ 333 l2mc_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1; 334 } 335 336 if (l2mc_p->pkt_size_param == 0) { 337 cli_out 338 ("\nUsing worst case packet sizes - 145B for Ethernet " 339 "and 76B (64B + 12B hg-hdr) for HG2"); 340 } else if (l2mc_p->pkt_size_param == 1) { 341 cli_out("\nUsing random packet sizes"); 342 } else if (l2mc_p->pkt_size_param < MIN_PKT_SIZE) { 343 test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n", 344 MIN_PKT_SIZE); 345 l2mc_p->bad_input = 1; 346 } else if (l2mc_p->pkt_size_param > MTU) { 347 test_error(unit,"\n*ERROR: Packet size cannot be higher than %0dB (Test Limitation)\n", 348 MTU); 349 l2mc_p->bad_input = 1; 350 } 351 352 if (l2mc_p->flood_pkt_cnt_param == 0) { 353 cli_out("\nFloodCnt=0, test will automatically calculate number of" 354 " packets to flood each port"); 355 } 356 } 357 358 /* 359 * Function: 360 * l2mc_set_lowest_stream_port 361 * Purpose: 362 * Within each stream, put the port with the lowest speed 363 * in the 2nd position. 364 * Parameters: 365 * unit: StrataSwitch Unit #. 366 * 367 * Returns: 368 * Nothing 369 */ 370 static void 371 l2mc_set_lowest_stream_port(int unit) 372 { 373 int i, j, tmp, port, port_speed, min_speed, min_speed_idx; 374 int param_idx; 375 l2mc_t *l2mc_p = l2mc_parray[unit]; 376 377 param_idx = 1; 378 for (i = 0; i < l2mc_p->num_streams; i++) { 379 min_speed_idx = param_idx; 380 port = l2mc_p->port_list[l2mc_p->stream[i][min_speed_idx]]; 381 bcm_port_speed_get(unit, port, &min_speed); 382 383 for (j = 0; j < (l2mc_p->num_copy_param + 1); j++) { 384 port = l2mc_p->port_list[l2mc_p->stream[i][j]]; 385 bcm_port_speed_get(unit, port, &port_speed); 386 if (port_speed < min_speed) { 387 min_speed = port_speed; 388 min_speed_idx = j; 389 } 390 } 391 if (min_speed_idx != param_idx) { 392 tmp = l2mc_p->stream[i][param_idx]; 393 l2mc_p->stream[i][param_idx] = l2mc_p->stream[i][min_speed_idx]; 394 l2mc_p->stream[i][min_speed_idx] = tmp; 395 } 396 } 397 } 398 399 /* 400 * Function: 401 * l2mc_set_port_property_arrays 402 * Purpose: 403 * Set port_list, port_speed 404 * Parameters: 405 * unit: StrataSwitch Unit #. 406 * 407 * Returns: 408 * Nothing. 409 */ 410 static void 411 l2mc_set_port_property_arrays(int unit) 412 { 413 int p; 414 int picked_port; 415 int i, j; 416 uint32 pkt_size; 417 soc_info_t *si = &SOC_INFO(unit); 418 uint32 stream_possible = 0; 419 uint32 ports_found = 0; 420 uint32 ports_picked = 0; 421 uint32 ports_accounted_for = 0; 422 l2mc_t *l2mc_p = l2mc_parray[unit]; 423 424 l2mc_p->num_fp_ports = 0; 425 l2mc_p->num_streams = 0; 426 l2mc_p->oversub_config = 0; 427 428 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 429 l2mc_p->num_fp_ports++; 430 } 431 432 l2mc_p->port_list = 433 (int *)sal_alloc(l2mc_p->num_fp_ports * sizeof(int), 434 "port_list"); 435 l2mc_p->port_speed = 436 (int *)sal_alloc(l2mc_p->num_fp_ports * sizeof(int), 437 "port_speed_array"); 438 l2mc_p->hg_stream = 439 (int *)sal_alloc(l2mc_p->num_fp_ports * sizeof(int), 440 "hg_stream_array"); 441 l2mc_p->port_oversub = 442 (uint32 *) sal_alloc(l2mc_p->num_fp_ports * sizeof(uint32), 443 "port_oversub_array"); 444 l2mc_p->rand_pkt_sizes = 445 (uint32 **) sal_alloc(l2mc_p->num_fp_ports * sizeof(uint32 *), 446 "rand_pkt_sizes_array*"); 447 448 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 449 l2mc_p->rand_pkt_sizes[i] = 450 (uint32 *) sal_alloc(TARGET_CELL_COUNT * sizeof(uint32), 451 "rand_pkt_sizes_array"); 452 } 453 l2mc_p->stream = 454 (int **) sal_alloc(l2mc_p->num_fp_ports * sizeof(int *), 455 "stream_array*"); 456 457 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 458 l2mc_p->stream[i] = 459 (int *) sal_alloc((l2mc_p->num_copy_param + 1) * sizeof(int), 460 "stream_array"); 461 } 462 l2mc_p->port_used = 463 (uint32 *) sal_alloc(l2mc_p->num_fp_ports * sizeof(uint32), 464 "l2mc_p->port_used_array"); 465 466 i = 0; 467 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 468 l2mc_p->port_list[i] = p; 469 i++; 470 } 471 472 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 473 l2mc_p->port_speed[i] = 474 si->port_speed_max[l2mc_p->port_list[i]]; 475 476 switch(l2mc_p->port_speed[i]) { 477 case 11000: l2mc_p->port_speed[i] = 10600; break; 478 case 27000: l2mc_p->port_speed[i] = 26500; break; 479 case 42000: l2mc_p->port_speed[i] = 42400; break; 480 default: break; 481 } 482 } 483 484 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 485 if (SOC_PBMP_MEMBER(si->oversub_pbm, l2mc_p->port_list[i]) 486 && 487 (!(SOC_PBMP_MEMBER(si->management_pbm, l2mc_p->port_list[i])))) { 488 l2mc_p->oversub_config = 1; 489 l2mc_p->port_oversub[i] = 1; 490 } else { 491 l2mc_p->port_oversub[i] = 0; 492 } 493 } 494 495 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 496 l2mc_p->port_used[i] = 0; 497 l2mc_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 < l2mc_p->num_fp_ports; i++) { 502 if (IS_HG_PORT(unit, l2mc_p->port_list[i])) { 503 l2mc_p->port_speed[i] |= 0x1; 504 } 505 } 506 507 while (ports_accounted_for < l2mc_p->num_fp_ports) { 508 do { 509 i = sal_rand() % l2mc_p->num_fp_ports; 510 }while (l2mc_p->port_used[i] != 0); 511 stream_possible = 0; 512 ports_found = 0; 513 for (j = 0;j < l2mc_p->num_fp_ports; j++) { 514 if((l2mc_p->port_used[j] == 0) && 515 (l2mc_p->port_speed[i] == l2mc_p->port_speed[j]) && 516 (i != j)) { 517 ports_found++; 518 } 519 520 if (ports_found >= l2mc_p->num_copy_param) { 521 stream_possible = 1; 522 } 523 } 524 525 ports_accounted_for++; 526 if(stream_possible == 1) { 527 l2mc_p->port_used[i] = 1; 528 ports_picked = 0; 529 l2mc_p->stream[l2mc_p->num_streams][0] = i; 530 if (IS_HG_PORT(unit, l2mc_p->port_list[i])) { 531 l2mc_p->hg_stream[l2mc_p->num_streams] = 1; 532 } 533 while (ports_picked < l2mc_p->num_copy_param) { 534 do { 535 picked_port = sal_rand() % l2mc_p->num_fp_ports; 536 }while((l2mc_p->port_speed[i] != 537 l2mc_p->port_speed[picked_port]) 538 || (l2mc_p->port_used[picked_port] != 0)); 539 540 ports_picked++; 541 l2mc_p->port_used[picked_port] = 1; 542 l2mc_p->stream[l2mc_p->num_streams][ports_picked] 543 = picked_port; 544 ports_accounted_for++; 545 } 546 l2mc_p->num_streams++; 547 } 548 } 549 550 /* restore hg speed */ 551 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 552 if (IS_HG_PORT(unit, l2mc_p->port_list[i])) { 553 l2mc_p->port_speed[i] &= ~0x1; 554 } 555 } 556 l2mc_set_lowest_stream_port(unit); 557 558 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 559 for (j = 0; j < TARGET_CELL_COUNT; j++) { 560 do { 561 /* coverity[dont_call : FALSE] */ 562 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + MIN_PKT_SIZE; 563 } while (stream_get_pkt_cell_cnt(unit, pkt_size, 564 l2mc_p->port_list[i]) > 565 l2mc_p->max_num_cells_param); 566 l2mc_p->rand_pkt_sizes[i][j] = pkt_size; 567 } 568 } 569 570 { 571 /* print */ 572 l2mc_print_port_config(unit); 573 cli_out("\n=========== STREAM INFO ============\n"); 574 cli_out("\n%8s %8s", "Stream", "Port"); 575 for (i = 0; i < l2mc_p->num_streams; i++) { 576 cli_out("\n%8d ", i); 577 for (j = 0; j < (l2mc_p->num_copy_param + 1); j++) { 578 cli_out("%8d", l2mc_p->port_list[l2mc_p->stream[i][j]]); 579 } 580 } 581 } 582 } 583 584 /* 585 * Function: 586 * fp_chg_vlan_and_redirect 587 * Purpose: 588 * Creates entry pointed to by l2mc_index in the L2MC table with 589 * PORT_BITMAP=redirect_pbmp 590 * Create the following FP actions: 591 * Qualifier: OuterVlan=old_vlan 592 * Actions: OuterVlanNew=VLAN1, RedirectMcast=l2mc_index 593 * Parameters: 594 * unit: StrataSwitch Unit #. 595 * old_vlan : Old VLAN of incoming packet 596 * new_vlan: New VLAN after IFP modifies packet 597 * fg : Pointer to Field group for IFP entry 598 * l2mc_index: Index in L2MC table where entry is to be created 599 * redirect_pbmp: PORT_BITMAP field of L2MC entry created 600 * Returns: 601 * Nothing 602 */ 603 static void 604 l2mc_fp_change_vlan_redirect(int unit, bcm_vlan_t old_vlan, bcm_vlan_t new_vlan, 605 bcm_field_group_t *fg, uint32 l2mc_index, 606 soc_pbmp_t *redirect_pbmp) { 607 bcm_field_entry_t fe; 608 l2mc_entry_t l2mc_entry; 609 610 if (SOC_MEM_IS_VALID(unit, L2MCm)) { 611 (void) soc_mem_read(unit, L2MCm, COPYNO_ALL, l2mc_index, 612 l2mc_entry.entry_data); 613 soc_mem_field32_set(unit, L2MCm, l2mc_entry.entry_data, 614 VALIDf, 0x1); 615 soc_mem_pbmp_field_set(unit, L2MCm, l2mc_entry.entry_data, 616 PORT_BITMAPf, redirect_pbmp); 617 (void) soc_mem_write(unit, L2MCm, COPYNO_ALL, l2mc_index, 618 l2mc_entry.entry_data); 619 } else { 620 cli_out("\n*ERROR, invalid mem %s\n", SOC_MEM_NAME(unit, L2MCm)); 621 } 622 623 (void) bcm_field_entry_create(unit, *fg, &fe); 624 bcm_field_qualify_OuterVlan(unit, fe, old_vlan, (bcm_vlan_t)(0xffff)); 625 bcm_field_action_add(unit, fe, bcmFieldActionOuterVlanNew, 626 (uint32)(new_vlan), 0); 627 bcm_field_action_add(unit, fe, bcmFieldActionRedirectMcast, l2mc_index, 0); 628 (void) bcm_field_entry_install(unit, fe); 629 } 630 631 /* 632 * Function: 633 * l2mc_set_up_streams 634 * Purpose: 635 * This function actually sets up the L2MC packet flow. Please refer to 636 * items 3-6 of the "Test Setup" section of the test description at the 637 * beginning of this file. 638 * Parameters: 639 * unit: StrataSwitch Unit #. 640 * 641 * Returns: 642 * Nothing. 643 */ 644 static void 645 l2mc_set_up_streams(int unit) 646 { 647 int i, j; 648 pbmp_t pbm, ubm; 649 soc_pbmp_t redirect_pbmp; 650 uint32 vlan = VLAN; 651 uint32 vlan_0, vlan_1; 652 uint32 l2mc_index = 1; 653 bcm_field_group_t fg; 654 bcm_field_qset_t qset; 655 l2mc_t *l2mc_p = l2mc_parray[unit]; 656 657 l2mc_p->tx_vlan = (uint32*) sal_alloc(l2mc_p->num_streams * sizeof(uint32), 658 "tx_vlan"); 659 BCM_PBMP_CLEAR(ubm); 660 bcm_vlan_destroy_all(unit); 661 bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE); 662 663 BCM_FIELD_QSET_INIT(qset); 664 BCM_FIELD_QSET_ADD(qset, bcmFieldQualifyOuterVlan); 665 (void) bcm_field_group_create(unit, qset, l2mc_index, &fg); 666 667 (void) bcm_switch_control_set(unit, bcmSwitchL3EgressMode, 1); 668 669 for (i = 0; i < l2mc_p->num_streams; i++) { 670 if (l2mc_p->hg_stream[i] == 0) { 671 /*Ethernet Stream*/ 672 BCM_PBMP_CLEAR(pbm); 673 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 674 for (j = 0; j < l2mc_p->num_copy_param + 1; j++) { 675 BCM_PBMP_PORT_ADD(pbm, l2mc_p->port_list[l2mc_p->stream[i][j]]); 676 } 677 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 678 vlan_0 = vlan; 679 vlan++; 680 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 681 BCM_PBMP_CLEAR(pbm); 682 BCM_PBMP_PORT_ADD(pbm, l2mc_p->port_list[l2mc_p->stream[i][0]]); 683 BCM_PBMP_PORT_ADD(pbm, l2mc_p->port_list[l2mc_p->stream[i][1]]); 684 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 685 vlan_1 = vlan; 686 vlan++; 687 bcm_vlan_translate_add(unit, l2mc_p->port_list[l2mc_p->stream[i][0]], 688 vlan_1, vlan_0, 0); 689 bcm_vlan_translate_add(unit, l2mc_p->port_list[l2mc_p->stream[i][1]], 690 vlan_0, vlan_1, 0); 691 692 for (j = 2; j < (l2mc_p->num_copy_param + 1); j++) { 693 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 694 bcm_vlan_translate_add(unit, 695 l2mc_p->port_list[l2mc_p->stream[i][j]], 696 vlan_0, vlan, 0); 697 vlan++; 698 } 699 l2mc_p->tx_vlan[i] = vlan_0; 700 } else { 701 /*HG2 Stream*/ 702 BCM_PBMP_CLEAR(pbm); 703 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 704 BCM_PBMP_PORT_ADD(pbm, l2mc_p->port_list[l2mc_p->stream[i][0]]); 705 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 706 vlan_0 = vlan; 707 vlan++; 708 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 709 BCM_PBMP_CLEAR(pbm); 710 for (j = 0; j < l2mc_p->num_copy_param + 1; j++) { 711 BCM_PBMP_PORT_ADD(pbm, l2mc_p->port_list[l2mc_p->stream[i][j]]); 712 } 713 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 714 vlan_1 = vlan; 715 vlan++; 716 717 SOC_PBMP_CLEAR(redirect_pbmp); 718 SOC_PBMP_PORT_ADD(redirect_pbmp, 719 l2mc_p->port_list[l2mc_p->stream[i][0]]); 720 l2mc_fp_change_vlan_redirect(unit, vlan_0, vlan_1, &fg, 721 l2mc_index, &redirect_pbmp); 722 l2mc_index++; 723 724 BCM_PBMP_CLEAR(pbm); 725 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 726 for (j = 1; j < l2mc_p->num_copy_param + 1; j++) { 727 BCM_PBMP_PORT_ADD(pbm, l2mc_p->port_list[l2mc_p->stream[i][j]]); 728 } 729 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 730 l2mc_fp_change_vlan_redirect(unit, vlan, vlan_1, &fg, 731 l2mc_index, &redirect_pbmp); 732 l2mc_index++; 733 SOC_PBMP_CLEAR(redirect_pbmp); 734 for (j = 1; j < l2mc_p->num_copy_param + 1; j++) { 735 SOC_PBMP_PORT_ADD(redirect_pbmp, 736 l2mc_p->port_list[l2mc_p->stream[i][j]]); 737 } 738 l2mc_fp_change_vlan_redirect(unit, vlan_1, vlan, &fg, 739 l2mc_index, &redirect_pbmp); 740 l2mc_index++; 741 vlan++; 742 l2mc_p->tx_vlan[i] = vlan_0; 743 } 744 } 745 } 746 747 /* 748 * Function: 749 * l2mc_lossless_flood_cnt 750 * Purpose: 751 * Calculates number of packets that need to be sent to a port for a 752 * lossless swirl. 753 * Parameters: 754 * unit - StrataSwitch Unit #. 755 * pkt_size : Packet size in bytes 756 * port: Test port no 757 * Returns: 758 * Number of packets needed for lossless flooding 759 */ 760 static uint32 761 l2mc_lossless_flood_cnt(int unit, int port_speed, int stream_hg_en) 762 { 763 uint32 flood_cnt = 0; 764 int param_flood_cnt; 765 l2mc_t *l2mc_p = l2mc_parray[unit]; 766 767 param_flood_cnt = l2mc_p->flood_pkt_cnt_param; 768 769 if (param_flood_cnt == 0) { 770 switch (port_speed) { 771 case 10000: flood_cnt = 14; break; 772 case 10600: flood_cnt = 14; break; 773 case 25000: flood_cnt = 14; break; 774 case 26500: flood_cnt = 25; break; 775 case 40000: flood_cnt = 20; break; 776 case 42400: flood_cnt = 38; break; 777 case 50000: flood_cnt = 24; break; 778 case 53000: flood_cnt = 45; break; 779 case 100000: flood_cnt = 50; break; 780 case 106000: flood_cnt = 94; break; 781 default: flood_cnt = MAX_PKTS_PER_STREAM; break; 782 } 783 } else { 784 flood_cnt = param_flood_cnt; 785 } 786 787 if (stream_hg_en == 1) { 788 flood_cnt = 2 * flood_cnt; 789 } 790 if (flood_cnt > MAX_PKTS_PER_STREAM) { 791 flood_cnt = MAX_PKTS_PER_STREAM; 792 } 793 794 return (flood_cnt); 795 } 796 797 /* 798 * Function: 799 * l2mc_send_pkts 800 * Purpose: 801 * Send packets from CPU to create a swirl on each stream. Please refer 802 * to item 6 of the "Test Setup" portion of the test description at the 803 * beginning of this file. 804 * Parameters: 805 * unit - StrataSwitch Unit #. 806 * 807 * Returns: 808 * Nothing 809 */ 810 static void 811 l2mc_send_pkts(int unit) 812 { 813 uint8 mac_da[] = MAC_DA; 814 uint8 mac_sa[] = MAC_SA; 815 int i, port; 816 uint32 pkt_size, flood_cnt, pkt_cnt_sum = 0; 817 uint32 use_random_packet_sizes = 0; 818 l2mc_t *l2mc_p = l2mc_parray[unit]; 819 stream_pkt_t *tx_pkt; 820 821 tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt"); 822 sal_memset(tx_pkt, 0, sizeof(stream_pkt_t)); 823 824 if (l2mc_p->pkt_size_param == 1) { 825 use_random_packet_sizes = 1; 826 } 827 828 cli_out("\n=================================================="); 829 cli_out("\nSending packets ...\n"); 830 for (i = 0; i < l2mc_p->num_streams; i++) { 831 port = l2mc_p->stream[i][0]; 832 if (l2mc_p->pkt_size_param == 0) { 833 if (l2mc_p->hg_stream[i] == 1) { 834 pkt_size = HG2_WC_PKT_SIZE; 835 } else { 836 pkt_size = ENET_WC_PKT_SIZE; 837 } 838 } else { 839 pkt_size = l2mc_p->pkt_size_param; 840 } 841 flood_cnt = l2mc_lossless_flood_cnt(unit, 842 l2mc_p->port_speed[port], 843 l2mc_p->hg_stream[i]); 844 845 tx_pkt->port = l2mc_p->port_list[port]; 846 tx_pkt->num_pkt = flood_cnt; 847 tx_pkt->pkt_seed = l2mc_p->pkt_seed + i; 848 tx_pkt->pkt_size = pkt_size; 849 tx_pkt->rand_pkt_size_en = use_random_packet_sizes; 850 tx_pkt->rand_pkt_size = NULL; 851 tx_pkt->tx_vlan = l2mc_p->tx_vlan[i]; 852 sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR); 853 sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR); 854 if (tx_pkt->rand_pkt_size_en) { 855 tx_pkt->rand_pkt_size = l2mc_p->rand_pkt_sizes[port]; 856 } 857 stream_tx_pkt(unit, tx_pkt); 858 /* print */ 859 cli_out("Stream %0d, pkt_flood_count = %0d\n", i, tx_pkt->cnt_pkt); 860 pkt_cnt_sum += tx_pkt->cnt_pkt; 861 } 862 863 cli_out("\nTotal packets sent: %0d\n\n", pkt_cnt_sum); 864 sal_free(tx_pkt); 865 } 866 867 /* 868 * Function: 869 * l2mc_set_up_ports 870 * Purpose: 871 * 1. Enable IFP for CPU port 872 * 2. Program ING_VLAN_TAG_ACTION_PROFILE to remove inner tag for double 873 * tagged packets 874 * 3. Program MMU to not accept any packets from ports l2mc_p->stream[i][2..n] 875 * by setting THDI_INPUT_PORT_XON_ENABLES.INPUT_PORT_RX_ENABLE=0. 876 * This prevents the number of packets in each swill from multiplying. 877 * 4. Set IGNORE_MY_MODID to 1 to prevent dropping HG2 packets after looping 878 * back. 879 * Parameters: 880 * unit - StrataSwitch Unit #. 881 * 882 * Returns: 883 * Nothing 884 */ 885 static void 886 l2mc_set_up_ports(int unit) 887 { 888 int i, j; 889 port_tab_entry_t port_tab_entry; 890 l2mc_t *l2mc_p = l2mc_parray[unit]; 891 ing_vlan_tag_action_profile_entry_t ing_vlan_tag_action_profile_entry; 892 uint64 ing_config; 893 894 if (SOC_MEM_IS_VALID(unit, PORT_TABm)) { 895 (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, 896 CPU_PORT, port_tab_entry.entry_data); 897 soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data, 898 FILTER_ENABLEf, 0x1); 899 (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, CPU_PORT, 900 port_tab_entry.entry_data); 901 } else { 902 cli_out("\n*ERROR, invalid mem %s\n", SOC_MEM_NAME(unit, PORT_TABm)); 903 } 904 905 if (SOC_MEM_IS_VALID(unit, ING_VLAN_TAG_ACTION_PROFILEm)) { 906 (void) soc_mem_read(unit, ING_VLAN_TAG_ACTION_PROFILEm, COPYNO_ALL, 907 0, ing_vlan_tag_action_profile_entry.entry_data); 908 soc_mem_field32_set(unit, ING_VLAN_TAG_ACTION_PROFILEm, 909 ing_vlan_tag_action_profile_entry.entry_data, 910 DT_ITAG_ACTIONf, 0x3); 911 (void) soc_mem_write(unit, ING_VLAN_TAG_ACTION_PROFILEm, COPYNO_ALL, 912 0, ing_vlan_tag_action_profile_entry.entry_data); 913 914 } else { 915 cli_out("\n*ERROR, invalid mem %s\n", 916 SOC_MEM_NAME(unit, ING_VLAN_TAG_ACTION_PROFILEm)); 917 } 918 919 if (SOC_REG_IS_VALID(unit, THDI_INPUT_PORT_XON_ENABLESr)) { 920 for (i = 0; i < l2mc_p->num_streams; i++) { 921 for (j = 2; j < (l2mc_p->num_copy_param + 1); j++) { 922 soc_reg_field32_modify(unit, THDI_INPUT_PORT_XON_ENABLESr, 923 l2mc_p->port_list[l2mc_p->stream[i][j]], 924 INPUT_PORT_RX_ENABLEf, 0x0); 925 } 926 } 927 } else { 928 cli_out("\n*ERROR, invalid reg %s\n", 929 SOC_REG_NAME(unit, THDI_INPUT_PORT_XON_ENABLESr)); 930 } 931 932 if (SOC_REG_IS_VALID(unit, ING_CONFIG_64r)) { 933 (void) soc_reg_get(unit, ING_CONFIG_64r, REG_PORT_ANY, 0, &ing_config); 934 soc_reg64_field32_set(unit, ING_CONFIG_64r, &ing_config, 935 IGNORE_MY_MODIDf, 0x1); 936 (void) soc_reg_set(unit, ING_CONFIG_64r, REG_PORT_ANY, 0, ing_config); 937 } else { 938 cli_out("\n*ERROR, invalid reg %s\n", 939 SOC_REG_NAME(unit, ING_CONFIG_64r)); 940 } 941 } 942 943 /* 944 * Function: 945 * l2mc_chk_port_rate 946 * Purpose: 947 * Check actual port rates against expected port rates. 948 * Parameters: 949 * unit - StrataSwitch Unit #. 950 * 951 * Returns: 952 * SOC_E_XXXX 953 */ 954 static bcm_error_t 955 l2mc_chk_port_rate(int unit) 956 { 957 int i, j, port, port_idx; 958 bcm_error_t rv = BCM_E_NONE; 959 stream_rate_t *rate_calc; 960 l2mc_t *l2mc_p = l2mc_parray[unit]; 961 962 rate_calc = (stream_rate_t *) 963 sal_alloc(sizeof(stream_rate_t), "rate_calc"); 964 if (rate_calc == NULL) { 965 test_error(unit, "Failed to allocate memory for rate_calc\n"); 966 return BCM_E_FAIL; 967 } 968 sal_memset(rate_calc, 0, sizeof(stream_rate_t)); 969 970 rate_calc->mode = 0; /* check act_rate against config_rate */ 971 rate_calc->pkt_size = l2mc_p->pkt_size_param; 972 rate_calc->interval_len = l2mc_p->rate_calc_interval_param; 973 rate_calc->tolerance_lr = l2mc_p->rate_tolerance_lr_param; 974 rate_calc->tolerance_os = l2mc_p->rate_tolerance_ov_param; 975 rate_calc->scaling_factor = l2mc_p->scaling_factor_param; 976 977 SOC_PBMP_CLEAR(rate_calc->pbmp); 978 for (i = 0; i < l2mc_p->num_streams; i++) { 979 for (j = 0; j < (l2mc_p->num_copy_param + 1); j++) { 980 port_idx = l2mc_p->stream[i][j]; 981 port = l2mc_p->port_list[port_idx]; 982 if (port < SOC_MAX_NUM_PORTS) { 983 /* pbmp */ 984 SOC_PBMP_PORT_ADD((rate_calc->pbmp), port); 985 /* num_rep */ 986 /* if (l2mc_p->l3_copy[port_idx] == 0) { 987 rate_calc->num_rep[port] = 0; 988 } else { 989 rate_calc->num_rep[port] = l2mc_p->num_rep[port_idx] + 1; 990 } */ 991 /* src_port */ 992 rate_calc->src_port[port] = 993 l2mc_p->port_list[l2mc_p->stream[i][1]]; 994 } 995 } 996 } 997 998 rv = stream_chk_port_rate(unit, PBMP_PORT_ALL(unit), rate_calc); 999 1000 sal_free(rate_calc); 1001 return rv; 1002 } 1003 1004 /* 1005 * Function: 1006 * l2mc_hg_disable_vlan_ports 1007 * Purpose: 1008 * Workaround to diasble vlan PORT_BITMAP, 1009 * to avoid forwarding between vlan ports after vlan disable 1010 * Parameters: 1011 * unit - StrataSwitch Unit #. 1012 * disable - disable vlan ports 1013 * 1014 * Returns: 1015 * Nothing 1016 */ 1017 static void 1018 l2mc_hg_disable_vlan_ports(int unit, int disable) 1019 { 1020 int i, vlan, param_num_stream, stream_hg_en; 1021 l2mc_t *l2mc_p = l2mc_parray[unit]; 1022 vlan_2_tab_entry_t vlan_2_tab_entry; 1023 soc_pbmp_t pbm; 1024 1025 if (!SOC_IS_TOMAHAWKX(unit)) { 1026 return; 1027 } 1028 1029 param_num_stream = l2mc_p->num_streams; 1030 for (i = 0; i < param_num_stream; i++) { 1031 stream_hg_en = l2mc_p->hg_stream[i]; 1032 if (!stream_hg_en) { 1033 continue; 1034 } 1035 1036 vlan = l2mc_p->tx_vlan[i] + 1; 1037 (void) soc_mem_read(unit, VLAN_2_TABm, COPYNO_ALL, vlan, 1038 vlan_2_tab_entry.entry_data); 1039 if (disable) { 1040 SOC_PBMP_CLEAR(pbm); 1041 } else { 1042 (void) soc_mem_pbmp_field_get(unit, VLAN_2_TABm, 1043 vlan_2_tab_entry.entry_data, ING_PORT_BITMAPf, &pbm); 1044 } 1045 (void) soc_mem_pbmp_field_set(unit, VLAN_2_TABm, 1046 vlan_2_tab_entry.entry_data, PORT_BITMAPf, &pbm); 1047 (void) soc_mem_write(unit, VLAN_2_TABm, COPYNO_ALL, vlan, 1048 vlan_2_tab_entry.entry_data); 1049 } 1050 } 1051 1052 /* 1053 * Function: 1054 * l2mc_chk_pkt_integrity 1055 * Purpose: 1056 * Redirect all packets back to CPU and check packet integrity 1057 * Parameters: 1058 * unit - StrataSwitch Unit #. 1059 * 1060 * Returns: 1061 * Nothing 1062 */ 1063 static bcm_error_t 1064 l2mc_chk_pkt_integrity(int unit) 1065 { 1066 int i, port, port_speed, stream_hg_en, vlan_id; 1067 int param_num_stream, param_pkt_seed; 1068 int *param_port_list, **param_stream, *param_port_speed, 1069 *param_hg_stream; 1070 uint32 flood_cnt; 1071 uint8 mac_da[] = MAC_DA; 1072 uint8 mac_sa[] = MAC_SA; 1073 stream_integrity_t *pkt_intg; 1074 bcm_error_t rv = BCM_E_NONE; 1075 l2mc_t *l2mc_p = l2mc_parray[unit]; 1076 1077 param_num_stream = l2mc_p->num_streams; 1078 param_pkt_seed = l2mc_p->pkt_seed; 1079 param_port_list = l2mc_p->port_list; 1080 param_stream = l2mc_p->stream; 1081 param_port_speed = l2mc_p->port_speed; 1082 param_hg_stream = l2mc_p->hg_stream; 1083 1084 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt_intg"); 1085 if (pkt_intg == NULL) { 1086 test_error(unit, "Failed to allocate memory for pkt_intg\n"); 1087 return BCM_E_FAIL; 1088 } 1089 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 1090 1091 pkt_intg->type = PKT_TYPE_L2; 1092 SOC_PBMP_CLEAR(pkt_intg->rx_pbmp); 1093 for (i = 0; i < param_num_stream; i++) { 1094 port = param_port_list[param_stream[i][0]]; 1095 port_speed = param_port_speed[param_stream[i][0]]; 1096 stream_hg_en = param_hg_stream[i]; 1097 if (port < SOC_MAX_NUM_PORTS) { 1098 /* rx_pbmp */ 1099 SOC_PBMP_PORT_ADD(pkt_intg->rx_pbmp, port); 1100 1101 /* rx_vlan: used to forward pkt to CPU */ 1102 if (stream_hg_en == 1) { 1103 vlan_id = l2mc_p->tx_vlan[i] + 1; 1104 } else { 1105 vlan_id = l2mc_p->tx_vlan[i]; 1106 } 1107 pkt_intg->rx_vlan[port] = vlan_id; 1108 1109 /* tx_vlan: used to re-generate ref_pkt */ 1110 vlan_id = l2mc_p->tx_vlan[i] + 1; 1111 pkt_intg->tx_vlan[port] = vlan_id; 1112 1113 /* port_flood_cnt */ 1114 flood_cnt = l2mc_lossless_flood_cnt(unit, port_speed, stream_hg_en); 1115 if (stream_hg_en == 0) { 1116 flood_cnt = 2 * flood_cnt; 1117 } 1118 pkt_intg->port_flood_cnt[port] = flood_cnt; 1119 1120 /* port_pkt_seed */ 1121 pkt_intg->port_pkt_seed[port] = param_pkt_seed + i; 1122 1123 /* mac_da, mac_sa */ 1124 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR); 1125 sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR); 1126 } 1127 } 1128 1129 l2mc_hg_disable_vlan_ports(unit, 1); 1130 if (stream_chk_pkt_integrity(unit, pkt_intg) != BCM_E_NONE) { 1131 rv = BCM_E_FAIL; 1132 } 1133 l2mc_hg_disable_vlan_ports(unit, 0); 1134 1135 sal_free(pkt_intg); 1136 return rv; 1137 } 1138 1139 /* 1140 * Function: 1141 * l2mc_test_init 1142 * Purpose: 1143 * Test init function. Parse CLI params and do necessary init. 1144 * Parameters: 1145 * unit - StrataSwitch Unit #. 1146 * 1147 * Returns: 1148 * Nothing 1149 */ 1150 int 1151 l2mc_test_init(int unit, args_t *a, void **pa) 1152 { 1153 l2mc_t *l2mc_p; 1154 1155 l2mc_p = l2mc_parray[unit]; 1156 l2mc_p = sal_alloc(sizeof(l2mc_t), "l2mc_test"); 1157 sal_memset(l2mc_p, 0, sizeof(l2mc_t)); 1158 l2mc_parray[unit] = l2mc_p; 1159 cli_out("\n=================================================="); 1160 cli_out("\nCalling l2mc_test_init ...\n"); 1161 l2mc_parse_test_params(unit, a); 1162 1163 l2mc_p->test_fail = 0; 1164 1165 if (l2mc_p->bad_input == 1) { 1166 goto done; 1167 } 1168 1169 stream_set_mac_lpbk(unit, PBMP_PORT_ALL(unit)); 1170 stream_turn_off_cmic_mmu_bkp(unit); 1171 stream_turn_off_fc(unit, PBMP_PORT_ALL(unit)); 1172 /* coverity[dont_call : FALSE] */ 1173 l2mc_p->pkt_seed = sal_rand(); 1174 1175 done: 1176 return 0; 1177 } 1178 1179 /* 1180 * Function: 1181 * l2mc_test 1182 * Purpose: 1183 * Set up ports/streams and send packets. 1184 * Parameters: 1185 * unit - StrataSwitch Unit #. 1186 * 1187 * Returns: 1188 * Nothing 1189 */ 1190 int 1191 l2mc_test(int unit, args_t *a, void *pa) 1192 { 1193 l2mc_t *l2mc_p = l2mc_parray[unit]; 1194 1195 if (l2mc_p->bad_input == 1) { 1196 goto done; 1197 } 1198 1199 cli_out("\n=================================================="); 1200 cli_out("\nCalling l2mc_test ... \n"); 1201 l2mc_set_port_property_arrays(unit); 1202 l2mc_set_up_ports(unit); 1203 l2mc_set_up_streams(unit); 1204 l2mc_send_pkts(unit); 1205 1206 /* check counter */ 1207 if (stream_chk_mib_counters(unit, PBMP_PORT_ALL(unit), 0) != BCM_E_NONE) { 1208 l2mc_p->test_fail = 1; 1209 } 1210 /* check rate */ 1211 if (l2mc_chk_port_rate(unit) != BCM_E_NONE) { 1212 l2mc_p->test_fail = 1; 1213 } 1214 /* check integrity */ 1215 if (l2mc_chk_pkt_integrity(unit) != BCM_E_NONE) { 1216 l2mc_p->test_fail = 1; 1217 } 1218 1219 done: 1220 return 0; 1221 } 1222 1223 /* 1224 * Function: 1225 * l2mc_test_cleanup 1226 * Purpose: 1227 * Do test end checks and free all allocated memory. 1228 * Parameters: 1229 * unit - StrataSwitch Unit #. 1230 * 1231 * Returns: 1232 * Nothing 1233 */ 1234 int 1235 l2mc_test_cleanup(int unit, void *pa) 1236 { 1237 int i, rv; 1238 l2mc_t *l2mc_p = l2mc_parray[unit]; 1239 1240 if (l2mc_p->bad_input == 1) { 1241 goto done; 1242 } 1243 cli_out("\nCalling l2mc_test_cleanup"); 1244 1245 /* free memory */ 1246 sal_free(l2mc_p->port_speed); 1247 sal_free(l2mc_p->port_list); 1248 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 1249 sal_free(l2mc_p->stream[i]); 1250 } 1251 sal_free(l2mc_p->stream); 1252 sal_free(l2mc_p->tx_vlan); 1253 sal_free(l2mc_p->hg_stream); 1254 sal_free(l2mc_p->port_oversub); 1255 sal_free(l2mc_p->ovs_ratio_x1000); 1256 sal_free(l2mc_p->rate); 1257 sal_free(l2mc_p->exp_rate); 1258 sal_free(l2mc_p->tpkt_start); 1259 sal_free(l2mc_p->tpkt_end); 1260 sal_free(l2mc_p->tbyt_start); 1261 sal_free(l2mc_p->tbyt_end); 1262 1263 for (i = 0; i < l2mc_p->num_fp_ports; i++) { 1264 sal_free(l2mc_p->rand_pkt_sizes[i]); 1265 } 1266 sal_free(l2mc_p->rand_pkt_sizes); 1267 1268 done: 1269 if (l2mc_p->bad_input == 1) { 1270 l2mc_p->test_fail = 1; 1271 } 1272 1273 if (l2mc_p->test_fail == 1) { 1274 rv = BCM_E_FAIL; 1275 } 1276 else { 1277 rv = BCM_E_NONE; 1278 } 1279 1280 cli_out("\n=================================================="); 1281 cli_out("\n=================================================="); 1282 if (l2mc_p->test_fail == 1) { 1283 cli_out("\n[L2MC test failed]\n\n"); 1284 } else { 1285 cli_out("\n[L2MC test passed]\n\n"); 1286 } 1287 sal_free(l2mc_p); 1288 1289 return rv; 1290 } 1291 #endif /* BCM_ESW_SUPPORT */