streaming_ipmc.c (46238B)
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 * Setup and Test Sequence: 18 * 1. Group all active front panel ports into groups of 19 * (NumL2Copy + NumL3Copy+ 1) ports. Each group constitutes 1 IPMC "stream". 20 * All ports in a stream should have the same line rate, although they may 21 * have different oversub ratios. 22 * 2. Let us assume a stream has n ports P0, P1 ... Pn. The ports should be 23 * arranged such that the P1 is the slowest port, i.e. has the highest oversub 24 * ratio and the highest number of same port replications. 25 * 3. Turn off all flow control, set MAC loopback on all ports and disable TTL 26 * decrement by setting EGR_IPMC_CFG2.DISABLE_TTL_DECREMENT=1. 27 * 4. Randomly decide whether each receiving port in the stream (P1, P2, ... Pn) 28 * should receive L2 or L3 copies. If port P1 receives L2 copies, the IPMC 29 * stream is designated an "L2 stream". If it receives L3 copies the stream 30 * is designated an "L3 stream". 31 * 5. For each stream: 32 * a. Place port P0 on VLAN0. Create an empty VLAN called DROP_VLAN with 33 * no ports 34 * b. Add all ports receiving L2 copies to VLAN1 and multicast group MC0 35 * using bcm_multicast_egress_add(). This programs the L2MC table. 36 * c. Add the following VLAN translations: 37 * i. For L2 streams: Port=P2, P3 ... Pn OldVlan=VLAN1 NewVlan=DROP_VLAN 38 * ii. For L3 streams: Port=P1, P2 ... Pn OldVlan=VLAN1 NewVlan=DROP_VLAN 39 * iii. Port=P0 OldVlan=VLAN0 NewVlan=VLAN1 40 * iv. For L2 streams: Port=P1 OldVlan=VLAN1 NewVlan=DROP_VLAN 41 * d. For each port Pk receiving L3 copies, let the number of L3 copies received at a port be m (=NumRep+1). 42 * i. Create m VLANs (VLANk0, VLANk1, .... VLANk(m-1)), each with port Pk 43 * ii. For L3 streams: If k=1, VLAN2=VLANk0 44 * iii. For L3 streams: Create the following VLAN translation: Port=Pk OldVlan=VLAN2 NewVlan=VLAN0 45 * iv. For L2 streams: Create the following VLAN translation: Port=Pk OldVlan= VLANk0, VLANk1, ... VLANk(m-1)) NewVlan=DROP_VLAN 46 * v. Create m L3 interfaces I0, I1 ... I(m-1) with VLANk0, VLANk1, .... VLANk(m-1) 47 * vi. Add interface to multicat group MC1 using bcm_multicast_egress_add(). 48 * vii. Program IPMC table with necessary SIP, DIP and multicast group MC1. 49 * 6. Send packets from CPU port on VLAN0 of each stream to flood the stream. 50 * If FloodCnt=0, the test will determine the number of packets to send based. 51 * These values are obtained empirically through trial and error for LR ports 52 * for NumCopy=2 and adjusted for oversub configs based on oversub ratio. 53 * Embed the packet size and random seed used to generate each packet in the 54 * payload. 55 * 7. Allow the packets to swill for a fixed amount of time decided by RunTime. 56 * 8. Snoop back all packets in each stream to the CPU using the following sequence: 57 * a. Program CPU_CONTROL_0.UVLAN_TOCPU=1. This sends all packets with an unknown VLAN to CPU. 58 * b. Invalidate VLAN0 for all streams by setting VALID=0 in the VLAN table 59 * 9. Decode each received packet to obtain the random seed and packet size. 60 * Reconstruct the expected packet and check the received packet for integrity. 61 * Checks: 62 * 1. Packet counts on each port. 63 * 2. No packet drops on any stream for LR configs. 64 * 3. All packets in a given stream snooped back to CPU port and checked for integrity. 65 * 66 * Test Limitations 67 * 1. FloodCnt automatically computed in the test supports packet sizes upto 68 * 1518B and NumCopy=2. Any deviations may result in packet drops for LR 69 * configs or false rate errors being reported. For custom configs the user is 70 * encouraged to tweak the FloodCnt value as per their needs. 71 * 72 * PktSize : Packet size in bytes not including HG2 header. Set to 0 for worst 73 * case packet sizes (145B for Ethernet and 76B for HG2). Set to 1 for 74 * random packet sizes. 75 * FloodCnt: Number of packets sent from CPU to flood each stream (packet swill). 76 * Set to 0 for test to automatically calculate. 77 * NumL2Copy: Number of ports receiving L2 copies in each stream (2 by default). 78 * NumL3Copy: Number of ports receiving L3 copies in each stream (2 by default). 79 * NumRep: Number of same-port replications on ports receiving . Set to 0 for 80 * random. 81 * MaxNumRep: Max number of replications if NumRep=0. Set both MaxNumRep and 82 * NumRep to 0 for no same port replication. 83 * MaxNumCells: Max number of cells for random packet sizes. Default = 4. 84 * Set to 0 for random. 85 * RunTime: Interval in seconds over which swill is allowed to 86 * run (10s by default). 87 */ 88 89 #include <appl/diag/system.h> 90 #include <shared/alloc.h> 91 #include <shared/bsl.h> 92 93 #include <soc/cm.h> 94 #include <soc/dma.h> 95 #include <soc/drv.h> 96 #include <soc/dcb.h> 97 #include <soc/cmicm.h> 98 #include <soc/cmic.h> 99 100 #include <sal/types.h> 101 #include <appl/diag/parse.h> 102 #include <bcm/port.h> 103 #include <bcm/vlan.h> 104 #include <bcm/link.h> 105 #include <bcm/ipmc.h> 106 #include <bcm/multicast.h> 107 108 #include "testlist.h" 109 #include "gen_pkt.h" 110 #include "streaming_lib.h" 111 112 #define MAC_DA {0x01,0x00,0x5e,0x02,0x03,0x04} 113 #define MAC_SA {0x00,0x00,0x00,0x00,0x00,0x01} 114 #define VLAN 0x2 115 116 #define TARGET_PKT_COUNT 100 117 #define MAX_FP_PORTS 130 118 119 #define TTL 5 120 121 #define DROP_VLAN 0xabc 122 #define FIRST_MC_GROUP 0x2000001 123 #define FIRST_INTF_ID 0x2 124 125 #define SIP 0x02030405 126 #define DIP 0xe0020304 127 128 #define MAX_PKTS_PER_STREAM 30 129 #define PKT_COUNT_CHECK_TOL 5 130 131 #define PKT_SIZE_PARAM_DEFAULT 0 132 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0 133 #define NUM_L2_COPY_PARAM_DEFAULT 2 134 #define NUM_L3_COPY_PARAM_DEFAULT 2 135 #define NUM_REP_PARAM_DEFAULT 1 136 #define MAX_NUM_REP_PARAM_DEFAULT 3 137 #define RUN_TIME_PARAM_DEFAULT 10 138 #define MAX_NUM_CELLS_PARAM_DEFAULT 4 139 #define SPEEDUP_FACTOR_PARAM_DEFAULT 1 140 #define CPU_PORT 0 141 142 #if defined(BCM_ESW_SUPPORT) && defined(INCLUDE_L3) && \ 143 (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) 144 145 typedef struct ipmc_s { 146 uint32 num_fp_ports; 147 uint32 num_streams; 148 int *port_speed; 149 int *port_list; 150 int **stream; 151 uint32 *num_rep; 152 uint32 *l3_copy; 153 uint32 *tx_vlan; 154 uint32 *exp_vlan; 155 uint8 (*exp_mac_addr)[NUM_BYTES_MAC_ADDR]; 156 uint32 *port_oversub; 157 uint32 oversub_config; 158 uint32 *port_used; 159 uint32 num_pipes; 160 uint32 total_chip_bw; 161 uint32 bw_per_pipe; 162 uint32 *ovs_ratio_x1000; 163 uint64 *exp_rate; 164 uint64 *tpkt_start; 165 uint64 *tpkt_end; 166 uint32 **rand_pkt_sizes; 167 uint32 pkt_size_param; 168 uint32 flood_pkt_cnt_param; 169 uint32 num_l2_copy_param; 170 uint32 num_l3_copy_param; 171 uint32 check_packet_integrity_param; 172 uint32 num_rep_param; 173 uint32 max_num_rep_param; 174 uint32 max_num_cells_param; 175 uint32 run_time_param; 176 uint32 scaling_factor_param; 177 uint32 bad_input; 178 int test_fail; 179 uint32 pkt_seed; 180 uint32 num_copy; 181 } ipmc_t; 182 183 static ipmc_t *ipmc_parray[SOC_MAX_NUM_DEVICES]; 184 185 /* 186 * Function: 187 * ipmc_parse_test_params 188 * Purpose: 189 * Parse CLI parameters, create test structure and flag bad inputs. 190 * Parameters: 191 * unit - StrataSwitch Unit #. 192 * a - Pointer to arguments 193 * 194 * Returns: 195 * Nothing 196 * Notes: 197 * ipmc_p->bad_input set from here - tells test to crash out in case 198 * CLI input combination is invalid. 199 */ 200 static void 201 ipmc_parse_test_params(int unit, args_t *a) 202 { 203 parse_table_t parse_table; 204 ipmc_t *ipmc_p = ipmc_parray[unit]; 205 206 const char tr513_test_usage[] = 207 #ifdef COMPILER_STRING_CONST_LIMIT 208 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 209 #else 210 "Streaming test to check TDM table and programming. Each port loops traffic\n" 211 "back to itself using port bridging and higig lookup for HG ports. Test test\n" 212 "calculates expected rates based on port config and oversub ratio and checks\n" 213 "against it.\n" 214 "Configuration parameters passed from CLI:\n" 215 "PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all\n" 216 " ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes\n" 217 "FloodCnt: Number of packets in each swill. Setting this to 0 will let the\n" 218 " test calculate the number of packets that can be sent to achieve\n" 219 " a lossless swirl at full rate. Set to 0 by default.\n" 220 "Setup and Test Sequence:\n" 221 "1. Group all active front panel ports into groups of\n" 222 " (NumL2Copy + NumL3Copy+ 1) ports. Each group constitutes 1 IPMC \"stream\".\n" 223 " All ports in a stream should have the same line rate, although they may\n" 224 " have different oversub ratios.\n" 225 "2. Let us assume a stream has n ports P0, P1 ... Pn. The ports should be\n" 226 " arranged such that the P1 is the slowest port, i.e. has the highest oversub\n" 227 " ratio and the highest number of same port replications.\n" 228 "3. Turn off all flow control, set MAC loopback on all ports and disable TTL\n" 229 " decrement by setting EGR_IPMC_CFG2.DISABLE_TTL_DECREMENT=1.\n" 230 "4. Randomly decide whether each receiving port in the stream (P1, P2, ... Pn)\n" 231 " should receive L2 or L3 copies. If port P1 receives L2 copies, the IPMC\n" 232 " stream is designated an \"L2 stream\". If it receives L3 copies the stream\n" 233 " is designated an \"L3 stream\".\n" 234 "5. For each stream:\n" 235 " a. Place port P0 on VLAN0. Create an empty VLAN called DROP_VLAN with\n" 236 " no ports\n" 237 " b. Add all ports receiving L2 copies to VLAN1 and multicast group MC0\n" 238 " using bcm_multicast_egress_add(). This programs the L2MC table.\n" 239 " c. Add the following VLAN translations:\n" 240 " i. For L2 streams: Port=P2, P3 ... Pn OldVlan=VLAN1 NewVlan=DROP_VLAN\n" 241 " ii. For L3 streams: Port=P1, P2 ... Pn OldVlan=VLAN1 NewVlan=DROP_VLAN\n" 242 " iii. Port=P0 OldVlan=VLAN0 NewVlan=VLAN1\n" 243 " iv. For L2 streams: Port=P1 OldVlan=VLAN1 NewVlan=DROP_VLAN\n" 244 " d. For each port Pk receiving L3 copies, let the number of L3 copies received at a port be m (=NumRep+1).\n" 245 " i. Create m VLANs (VLANk0, VLANk1, .... VLANk(m-1)), each with port Pk\n" 246 " ii. For L3 streams: If k=1, VLAN2=VLANk0\n" 247 " iii. For L3 streams: Create the following VLAN translation: Port=Pk OldVlan=VLAN2 NewVlan=VLAN0\n" 248 " iv. For L2 streams: Create the following VLAN translation: Port=Pk OldVlan= VLANk0, VLANk1, ... VLANk(m-1)) NewVlan=DROP_VLAN\n" 249 " v. Create m L3 interfaces I0, I1 ... I(m-1) with VLANk0, VLANk1, .... VLANk(m-1)\n" 250 " vi. Add interface to multicat group MC1 using bcm_multicast_egress_add().\n" 251 " vii. Program IPMC table with necessary SIP, DIP and multicast group MC1.\n" 252 "6. Send packets from CPU port on VLAN0 of each stream to flood the stream.\n" 253 " If FloodCnt=0, the test will determine the number of packets to send based.\n" 254 " These values are obtained empirically through trial and error for LR ports\n" 255 " for NumCopy=2 and adjusted for oversub configs based on oversub ratio.\n" 256 " Embed the packet size and random seed used to generate each packet in the\n" 257 " payload.\n" 258 "7. Allow the packets to swill for a fixed amount of time decided by RunTime.\n" 259 "8. Snoop back all packets in each stream to the CPU using the following sequence:\n" 260 " a. Program CPU_CONTROL_0.UVLAN_TOCPU=1. This sends all packets with an unknown VLAN to CPU.\n" 261 " b. Invalidate VLAN0 for all streams by setting VALID=0 in the VLAN table\n" 262 "9. Decode each received packet to obtain the random seed and packet size.\n" 263 " Reconstruct the expected packet and check the received packet for integrity.\n" 264 "Checks:\n" 265 "1. Packet counts on each port.\n" 266 "2. No packet drops on any stream for LR configs.\n" 267 "3. All packets in a given stream snooped back to CPU port and checked for integrity.\n" 268 "\n" 269 " Test Limitations\n" 270 " 1. FloodCnt automatically computed in the test supports packet sizes upto\n" 271 " 1518B and NumCopy=2. Any deviations may result in packet drops for LR\n" 272 " configs or false rate errors being reported. For custom configs the user is\n" 273 " encouraged to tweak the FloodCnt value as per their needs.\n" 274 "\n" 275 " PktSize : Packet size in bytes not including HG2 header. Set to 0 for worst\n" 276 " case packet sizes (145B for Ethernet and 76B for HG2). Set to 1 for\n" 277 " random packet sizes.\n" 278 " FloodCnt: Number of packets sent from CPU to flood each stream (packet swill).\n" 279 " Set to 0 for test to automatically calculate.\n" 280 " NumL2Copy: Number of ports receiving L2 copies in each stream (2 by default).\n" 281 " NumL3Copy: Number of ports receiving L3 copies in each stream (2 by default).\n" 282 " NumRep: Number of same-port replications on ports receiving . Set to 0 for\n" 283 " random.\n" 284 " MaxNumRep: Max number of replications if NumRep=0. Set both MaxNumRep and\n" 285 " NumRep to 0 for no same port replication.\n" 286 " MaxNumCells: Max number of cells for random packet sizes. Default = 4.\n" 287 " Set to 0 for random.\n" 288 " RunTime: Interval in seconds over which swill is allowed to\n" 289 " run (10s by default).\n"; 290 #endif 291 ipmc_p->bad_input = 0; 292 293 ipmc_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT; 294 ipmc_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT; 295 ipmc_p->num_l2_copy_param = NUM_L2_COPY_PARAM_DEFAULT; 296 ipmc_p->num_l3_copy_param = NUM_L3_COPY_PARAM_DEFAULT; 297 ipmc_p->num_rep_param = NUM_REP_PARAM_DEFAULT; 298 ipmc_p->max_num_rep_param = MAX_NUM_REP_PARAM_DEFAULT; 299 ipmc_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT; 300 ipmc_p->run_time_param = RUN_TIME_PARAM_DEFAULT; 301 ipmc_p->scaling_factor_param = SPEEDUP_FACTOR_PARAM_DEFAULT; 302 303 /*Parse CLI opts */ 304 305 parse_table_init(unit, &parse_table); 306 parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0, 307 &(ipmc_p->pkt_size_param), NULL); 308 parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0, 309 &(ipmc_p->flood_pkt_cnt_param), NULL); 310 parse_table_add(&parse_table, "NumL2Copy", PQ_INT|PQ_DFL, 0, 311 &(ipmc_p->num_l2_copy_param), NULL); 312 parse_table_add(&parse_table, "NumL3Copy", PQ_INT|PQ_DFL, 0, 313 &(ipmc_p->num_l3_copy_param), NULL); 314 parse_table_add(&parse_table, "NumRep", PQ_INT|PQ_DFL, 0, 315 &(ipmc_p->num_rep_param), NULL); 316 parse_table_add(&parse_table, "MaxNumRep", PQ_INT|PQ_DFL, 0, 317 &(ipmc_p->max_num_rep_param), NULL); 318 parse_table_add(&parse_table, "MaxNumCells", PQ_INT|PQ_DFL, 0, 319 &(ipmc_p->max_num_cells_param), NULL); 320 parse_table_add(&parse_table, "RunTime", PQ_INT|PQ_DFL, 0, 321 &(ipmc_p->run_time_param), NULL); 322 parse_table_add(&parse_table, "ScalingFactor", PQ_INT|PQ_DFL, 0, 323 &(ipmc_p->scaling_factor_param), NULL); 324 325 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 326 test_msg("%s", tr513_test_usage); 327 test_error(unit, 328 "%s: Invalid option: %s\n", 329 ARG_CMD(a), 330 ARG_CUR(a) ? ARG_CUR(a) : "*"); 331 ipmc_p->bad_input = 1; 332 parse_arg_eq_done(&parse_table); 333 } else { 334 cli_out("\n"); 335 cli_out("------------- PRINTING TEST PARAMS ------------------\n"); 336 cli_out("PktSize = %0d\n", ipmc_p->pkt_size_param); 337 cli_out("FloodCnt = %0d\n", ipmc_p->flood_pkt_cnt_param); 338 cli_out("NumL2Copy = %0d\n", ipmc_p->num_l2_copy_param); 339 cli_out("NumL3Copy = %0d\n", ipmc_p->num_l3_copy_param); 340 cli_out("NumRep = %0d\n", ipmc_p->num_rep_param); 341 cli_out("MaxNumRep = %0d\n", ipmc_p->max_num_rep_param); 342 cli_out("MaxNumCells = %0d\n", ipmc_p->max_num_cells_param); 343 cli_out("RunTime = %0d\n", ipmc_p->run_time_param); 344 cli_out("ScalingFactor= %0d\n", ipmc_p->scaling_factor_param); 345 cli_out("-----------------------------------------------------\n"); 346 } 347 348 if (ipmc_p->max_num_cells_param == 0) { 349 /* coverity[dont_call : FALSE] */ 350 ipmc_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1; 351 } 352 353 if (ipmc_p->pkt_size_param == 0) { 354 cli_out 355 ("\nUsing worst case packet sizes - 145B for Ethernet " 356 "and 76B (64B + 12B hg-hdr) for HG2"); 357 } else if (ipmc_p->pkt_size_param == 1) { 358 cli_out("\nUsing random packet sizes"); 359 } else if (ipmc_p->pkt_size_param < MIN_PKT_SIZE) { 360 test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n", 361 MIN_PKT_SIZE); 362 ipmc_p->bad_input = 1; 363 } else if (ipmc_p->pkt_size_param > MTU) { 364 test_error(unit,"\n*ERROR: Packet size cannot be higher than %0dB (Device MTU)\n", 365 MTU); 366 ipmc_p->bad_input = 1; 367 } 368 369 if (ipmc_p->flood_pkt_cnt_param == 0) { 370 cli_out("\nFloodCnt=0, test will automatically calculate number of" 371 " packets to flood each port"); 372 } 373 374 if (ipmc_p->num_rep_param > MAX_NUM_REP_PARAM_DEFAULT) { 375 ipmc_p->max_num_rep_param = MAX_NUM_REP_PARAM_DEFAULT; 376 cli_out("\nMax replications supported by this test = %0d," 377 "forcing number of replications to %0d", 378 MAX_NUM_REP_PARAM_DEFAULT, MAX_NUM_REP_PARAM_DEFAULT); 379 } 380 381 ipmc_p->num_copy = ipmc_p->num_l2_copy_param + ipmc_p->num_l3_copy_param; 382 } 383 384 /* 385 * Function: 386 * ipmc_set_lowest_stream_port 387 * Purpose: 388 * Within each stream, put the port with the lowest speed 389 * in the 2nd position. 390 * Parameters: 391 * unit: StrataSwitch Unit #. 392 * 393 * Returns: 394 * Nothing 395 */ 396 static void 397 ipmc_set_lowest_stream_port(int unit) 398 { 399 int i, j, tmp, port, port_speed, min_speed, min_speed_idx; 400 ipmc_t *ipmc_p = ipmc_parray[unit]; 401 402 for (i = 0; i < ipmc_p->num_streams; i++) { 403 min_speed_idx = 1; 404 port = ipmc_p->port_list[ipmc_p->stream[i][min_speed_idx]]; 405 bcm_port_speed_get(unit, port, &min_speed); 406 407 for (j = 0; j < (ipmc_p->num_copy + 1); j++) { 408 port = ipmc_p->port_list[ipmc_p->stream[i][j]]; 409 bcm_port_speed_get(unit, port, &port_speed); 410 if (port_speed < min_speed) { 411 min_speed = port_speed; 412 min_speed_idx = j; 413 } 414 } 415 if (min_speed_idx != 1) { 416 tmp = ipmc_p->stream[i][1]; 417 ipmc_p->stream[i][1] = ipmc_p->stream[i][min_speed_idx]; 418 ipmc_p->stream[i][min_speed_idx] = tmp; 419 } 420 } 421 } 422 423 /* 424 * Function: 425 * ipmc_set_port_property 426 * Purpose: 427 * Set port_list, port_speed, port_oversub arrays and l3_copy. 428 * Also call set_exp_rates. 429 * Parameters: 430 * unit: StrataSwitch Unit #. 431 * 432 * Returns: 433 * Nothing. 434 */ 435 static void 436 ipmc_set_port_property(int unit) 437 { 438 int i, j, k, p, picked_port; 439 uint32 temp, pkt_size, ports_found = 0, ports_picked = 0, 440 ports_accounted_for = 0, stream_possible = 0; 441 soc_info_t *si = &SOC_INFO(unit); 442 ipmc_t *ipmc_p = ipmc_parray[unit]; 443 444 ipmc_p->num_fp_ports = 0; 445 ipmc_p->num_streams = 0; 446 ipmc_p->oversub_config = 0; 447 448 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 449 ipmc_p->num_fp_ports++; 450 } 451 452 ipmc_p->port_list = 453 (int *)sal_alloc(ipmc_p->num_fp_ports * sizeof(int), 454 "port_list"); 455 ipmc_p->port_speed = 456 (int *)sal_alloc(ipmc_p->num_fp_ports * sizeof(int), 457 "port_speed_array"); 458 ipmc_p->port_oversub = 459 (uint32 *) sal_alloc(ipmc_p->num_fp_ports * sizeof(uint32), 460 "port_oversub_array"); 461 462 ipmc_p->l3_copy = 463 (uint32 *) sal_alloc(ipmc_p->num_fp_ports * sizeof(uint32), 464 "l3_copy"); 465 ipmc_p->rand_pkt_sizes = 466 (uint32 **) sal_alloc(ipmc_p->num_fp_ports * sizeof(uint32 *), 467 "rand_pkt_sizes_array*"); 468 469 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 470 ipmc_p->rand_pkt_sizes[i] = 471 (uint32 *) sal_alloc(TARGET_PKT_COUNT * sizeof(uint32), 472 "rand_pkt_sizes_array"); 473 } 474 475 ipmc_p->num_rep = 476 (uint32 *) sal_alloc(ipmc_p->num_fp_ports * sizeof(uint32), 477 "num_rep_array"); 478 479 ipmc_p->stream = 480 (int **) sal_alloc(ipmc_p->num_fp_ports * sizeof(int *), 481 "stream_array*"); 482 483 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 484 ipmc_p->stream[i] = 485 (int *) sal_alloc((ipmc_p->num_copy + 1) * sizeof(int), 486 "stream_array"); 487 } 488 ipmc_p->port_used = 489 (uint32 *) sal_alloc(ipmc_p->num_fp_ports * sizeof(uint32), 490 "ipmc_p->port_used_array"); 491 492 i = 0; 493 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 494 ipmc_p->port_list[i] = p; 495 i++; 496 } 497 498 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 499 ipmc_p->port_speed[i] = 500 si->port_speed_max[ipmc_p->port_list[i]]; 501 502 switch(ipmc_p->port_speed[i]) { 503 case 11000: ipmc_p->port_speed[i] = 10600; break; 504 case 27000: ipmc_p->port_speed[i] = 26500; break; 505 case 42000: ipmc_p->port_speed[i] = 42400; break; 506 default: break; 507 } 508 } 509 510 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 511 if (SOC_PBMP_MEMBER(si->oversub_pbm, ipmc_p->port_list[i]) && 512 (!(SOC_PBMP_MEMBER(si->management_pbm, ipmc_p->port_list[i])))) { 513 ipmc_p->oversub_config = 1; 514 ipmc_p->port_oversub[i] = 1; 515 } else { 516 ipmc_p->port_oversub[i] = 0; 517 } 518 } 519 520 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 521 ipmc_p->port_used[i] = 0; 522 } 523 524 while (ports_accounted_for < ipmc_p->num_fp_ports) { 525 do { 526 i = sal_rand() % ipmc_p->num_fp_ports; 527 }while (ipmc_p->port_used[i] != 0); 528 stream_possible = 0; 529 ports_found = 0; 530 for (j = 0;j < ipmc_p->num_fp_ports; j++) { 531 if((ipmc_p->port_used[j] == 0) 532 && (ipmc_p->port_speed[i] 533 == ipmc_p->port_speed[j]) 534 && (i!=j)) { 535 ports_found++; 536 } 537 538 if (ports_found >= ipmc_p->num_copy) { 539 stream_possible = 1; 540 } 541 } 542 543 ports_accounted_for++; 544 if(stream_possible == 1) { 545 ipmc_p->port_used[i] = 1; 546 ports_picked = 0; 547 ipmc_p->stream[ipmc_p->num_streams][0] = i; 548 while (ports_picked < ipmc_p->num_copy) { 549 do { 550 picked_port = sal_rand() % ipmc_p->num_fp_ports; 551 }while((ipmc_p->port_speed[i] != 552 ipmc_p->port_speed[picked_port]) 553 || (ipmc_p->port_used[picked_port] != 0)); 554 555 ports_picked++; 556 ipmc_p->port_used[picked_port] = 1; 557 ipmc_p->stream[ipmc_p->num_streams][ports_picked] 558 = picked_port; 559 ports_accounted_for++; 560 } 561 ipmc_p->num_streams++; 562 } 563 } 564 ipmc_set_lowest_stream_port(unit); 565 566 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 567 ipmc_p->l3_copy[i] = 0; 568 } 569 for (i = 0; i < ipmc_p->num_streams; i++) { 570 for (j = 0; j < ipmc_p->num_l3_copy_param; j++) { 571 do { 572 k = (sal_rand() % ipmc_p->num_copy) + 1; 573 } while(ipmc_p->l3_copy[ipmc_p->stream[i][k]] == 1); 574 575 ipmc_p->l3_copy[ipmc_p->stream[i][k]] = 1; 576 } 577 } 578 579 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 580 if (ipmc_p->l3_copy[i] == 1) { 581 if (ipmc_p->num_rep_param == 0) { 582 ipmc_p->num_rep[i] = sal_rand() % 583 (ipmc_p->max_num_rep_param + 1); 584 } else { 585 ipmc_p->num_rep[i] = ipmc_p->num_rep_param; 586 } 587 } 588 else { 589 ipmc_p->num_rep[i] = 0; 590 } 591 } 592 593 for (i = 0; i < ipmc_p->num_streams; i++) { 594 for (j = 0; j < (ipmc_p->num_copy + 1); j++) { 595 if (ipmc_p->l3_copy[ipmc_p->stream[i][1]] == 0) { 596 ipmc_p->num_rep[ipmc_p->stream[i][j]] = 0; 597 } else if (ipmc_p->num_rep[ipmc_p->stream[i][j]] > 598 ipmc_p->num_rep[ipmc_p->stream[i][1]]) { 599 temp = ipmc_p->num_rep[ipmc_p->stream[i][j]]; 600 ipmc_p->num_rep[ipmc_p->stream[i][j]] 601 = ipmc_p->num_rep[ipmc_p->stream[i][1]]; 602 ipmc_p->num_rep[ipmc_p->stream[i][1]] = temp; 603 } 604 } 605 } 606 607 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 608 for (j = 0; j < TARGET_PKT_COUNT; j++) { 609 do { 610 /* coverity[dont_call : FALSE] */ 611 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + MIN_PKT_SIZE; 612 } while (stream_get_pkt_cell_cnt(unit, pkt_size, ipmc_p->port_list[i]) > 613 ipmc_p->max_num_cells_param); 614 ipmc_p->rand_pkt_sizes[i][j] = pkt_size; 615 } 616 } 617 618 { 619 /* print */ 620 int port_idx; 621 cli_out("\n=========== STREAM INFO ============\n"); 622 cli_out("%4s %4s \t[%s]%4s %s/%s\n", 623 "strm", "type", "j", "port", "type", "num_l3cpy"); 624 625 for (i = 0; i < ipmc_p->num_streams; i++) { 626 cli_out("%4d ", i); 627 if (ipmc_p->l3_copy[ipmc_p->stream[i][1]] == 0) { 628 cli_out("%4s ", "L2"); 629 } else { 630 cli_out("%4s ", "L3"); 631 } 632 for (j = 0; j < (ipmc_p->num_copy + 1); j++) { 633 port_idx = ipmc_p->stream[i][j]; 634 cli_out("\t[%d]%4d ", j, ipmc_p->port_list[port_idx]); 635 if (ipmc_p->l3_copy[port_idx] == 0) { 636 cli_out("%s/%d", "L2", 0); 637 } else { 638 cli_out("%s/%d", "L3", (ipmc_p->num_rep[port_idx] + 1)); 639 } 640 } 641 cli_out("\n"); 642 } 643 } 644 } 645 646 /* 647 * Function: 648 * ipmc_set_up_streams 649 * Purpose: 650 * This function actually sets up the IPMC packet flow. Please refer to 651 * items 4-6 of the "Test Setup" section of the test description at the 652 * beginning of this file. 653 * Parameters: 654 * unit: StrataSwitch Unit #. 655 * 656 * Returns: 657 * Nothing. 658 */ 659 static void 660 ipmc_set_up_streams(int unit) 661 { 662 int i, j, k, p; 663 pbmp_t pbm, ubm; 664 uint32 vlan = VLAN; 665 uint32 vlan_0 = 0, vlan_1 = 0, vlan_2 = 0; 666 uint32 l3_stream; 667 bcm_multicast_t mc_group; 668 uint32 mc_flags = 0; 669 bcm_l3_intf_t l3_intf; 670 bcm_if_t intf_id; 671 bcm_if_t encap_id; 672 uint32 intf_flags = 0; 673 uint8 intf_mac[] = {0x00,0x00,0x00,0x00,0x00,0x00}; 674 uint8 mac_0[NUM_BYTES_MAC_ADDR]; 675 bcm_ipmc_addr_t ipmc_addr; 676 uint32 ipmc_flags = 0; 677 uint8 mac_sa[] = MAC_SA; 678 bcm_gport_t gport; 679 ipmc_t *ipmc_p = ipmc_parray[unit]; 680 681 ipmc_p->tx_vlan = (uint32*) sal_alloc(ipmc_p->num_streams * sizeof(uint32), 682 "tx_vlan"); 683 684 ipmc_p->exp_vlan = (uint32*) sal_alloc(ipmc_p->num_streams * sizeof(uint32), 685 "exp_vlan"); 686 687 ipmc_p->exp_mac_addr = sal_alloc(ipmc_p->num_streams * 688 sizeof(uint8) * NUM_BYTES_MAC_ADDR, 689 "exp_mac_addr"); 690 BCM_PBMP_CLEAR(ubm); 691 692 bcm_vlan_destroy_all(unit); 693 bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE); 694 (void) bcm_switch_control_set(unit, bcmSwitchL3EgressMode, TRUE); 695 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 696 (void) bcm_port_control_set(unit, p, bcmPortControlIP4, TRUE); 697 (void) bcm_port_control_set(unit, p, bcmPortControlIP6, TRUE); 698 (void) bcm_port_control_set(unit, p, bcmSwitchL3McIdxRetType, TRUE); 699 (void) bcm_port_control_set(unit, p, 700 bcmSwitchIpmcReplicationSharing, TRUE); 701 } 702 703 bcm_ipmc_enable(unit, TRUE); 704 bcm_vlan_create(unit, (bcm_vlan_t)(DROP_VLAN)); 705 706 mc_group = (bcm_multicast_t)(FIRST_MC_GROUP); 707 mc_flags = BCM_MULTICAST_TYPE_L3 | BCM_MULTICAST_WITH_ID; 708 intf_id = (bcm_if_t)(FIRST_INTF_ID); 709 intf_flags |= BCM_L3_WITH_ID; 710 ipmc_flags |= BCM_IPMC_SOURCE_PORT_NOCHECK; 711 712 for (i = 0; i < ipmc_p->num_streams; i++) { 713 if (ipmc_p->l3_copy[ipmc_p->stream[i][1]] == 0) { 714 l3_stream = 0; 715 } else { 716 l3_stream = 1; 717 } 718 (void) bcm_multicast_create(unit, mc_flags, &mc_group); 719 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 720 BCM_PBMP_CLEAR(pbm); 721 BCM_PBMP_PORT_ADD(pbm, ipmc_p->port_list[ipmc_p->stream[i][0]]); 722 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 723 vlan_0 = vlan; 724 vlan++; 725 726 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 727 BCM_PBMP_CLEAR(pbm); 728 for (j = 0; j < (ipmc_p->num_copy + 1); j++) { 729 if (ipmc_p->l3_copy[ipmc_p->stream[i][j]] == 0) { 730 BCM_PBMP_PORT_ADD(pbm, ipmc_p->port_list[ipmc_p->stream[i][j]]); 731 BCM_GPORT_LOCAL_SET(gport, 732 ipmc_p->port_list[ipmc_p->stream[i][j]]); 733 bcm_multicast_egress_add(unit, mc_group, gport,(bcm_if_t)(-1)); 734 if ((j > 0 && l3_stream == 1) || (j > 1 && l3_stream == 0)) { 735 bcm_vlan_translate_add(unit, 736 ipmc_p->port_list[ipmc_p->stream[i][j]], 737 (bcm_vlan_t)(vlan), 738 (bcm_vlan_t)(DROP_VLAN), 0); 739 } 740 } 741 } 742 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 743 vlan_1 = vlan; 744 vlan++; 745 746 bcm_vlan_translate_add(unit, ipmc_p->port_list[ipmc_p->stream[i][0]], 747 (bcm_vlan_t)(vlan_0), (bcm_vlan_t)(vlan_1), 0); 748 749 if (l3_stream == 0) { 750 bcm_vlan_translate_add(unit, ipmc_p->port_list[ipmc_p->stream[i][1]], 751 (bcm_vlan_t)(vlan_1), (bcm_vlan_t)(vlan_0), 0); 752 } else { 753 bcm_vlan_translate_add(unit, ipmc_p->port_list[ipmc_p->stream[i][1]], 754 (bcm_vlan_t)(vlan_1), (bcm_vlan_t)(DROP_VLAN), 0); 755 } 756 757 for (j = 0; j < (ipmc_p->num_copy + 1); j++) { 758 if (ipmc_p->l3_copy[ipmc_p->stream[i][j]] == 1) { 759 for (k = 0; 760 k < (ipmc_p->num_rep[ipmc_p->stream[i][j]] + 1); 761 k++) { 762 BCM_PBMP_CLEAR(pbm); 763 BCM_PBMP_PORT_ADD(pbm, 764 ipmc_p->port_list[ipmc_p->stream[i][j]]); 765 bcm_vlan_create(unit, (bcm_vlan_t)(vlan)); 766 bcm_vlan_port_add(unit, (bcm_vlan_t)(vlan), pbm, ubm); 767 intf_mac[NUM_BYTES_MAC_ADDR - 1] = intf_id; 768 if (l3_stream == 1 && j == 1 && k == 0) { 769 vlan_2 = vlan; 770 bcm_vlan_translate_add(unit, 771 ipmc_p->port_list[ipmc_p->stream[i][1]], 772 (bcm_vlan_t)(vlan_2), 773 (bcm_vlan_t)(vlan_0), 0); 774 sal_memcpy(mac_0, intf_mac, 6); 775 } 776 else { 777 bcm_vlan_translate_add(unit, 778 ipmc_p->port_list[ipmc_p->stream[i][j]], 779 (bcm_vlan_t)(vlan), 780 (bcm_vlan_t)(DROP_VLAN), 0); 781 } 782 bcm_l3_intf_t_init(&l3_intf); 783 sal_memcpy(l3_intf.l3a_mac_addr, intf_mac, 6); 784 l3_intf.l3a_vid = vlan; 785 l3_intf.l3a_intf_id = intf_id; 786 l3_intf.l3a_flags = intf_flags; 787 bcm_l3_intf_create(unit, &l3_intf); 788 bcm_multicast_l3_encap_get(unit, mc_group, 789 ipmc_p->port_list[ipmc_p->stream[i][j]], 790 intf_id, &encap_id); 791 BCM_GPORT_LOCAL_SET(gport, 792 ipmc_p->port_list[ipmc_p->stream[i][j]]); 793 bcm_multicast_egress_add(unit, mc_group, gport, encap_id); 794 vlan++; 795 intf_id++; 796 } 797 } 798 } 799 800 bcm_ipmc_addr_t_init(&ipmc_addr); 801 ipmc_addr.mc_ip_addr = DIP; 802 ipmc_addr.s_ip_addr = SIP; 803 ipmc_addr.vid = vlan_1; 804 ipmc_addr.group = mc_group; 805 ipmc_addr.flags = ipmc_flags; 806 bcm_ipmc_add(unit, &ipmc_addr); 807 mc_group++; 808 809 ipmc_p->tx_vlan[i] = vlan_0; 810 811 if (l3_stream == 0) { 812 ipmc_p->exp_vlan[i] = vlan_1; 813 sal_memcpy(ipmc_p->exp_mac_addr[i], mac_sa, 6); 814 } else { 815 ipmc_p->exp_vlan[i] = vlan_2; 816 sal_memcpy(ipmc_p->exp_mac_addr[i], mac_0, 6); 817 } 818 } 819 } 820 821 /* 822 * Function: 823 * ipmc_lossless_flood_cnt 824 * Purpose: 825 * Calculates number of packets that need to be sent to a port for a 826 * lossless swirl. 827 * Parameters: 828 * unit - StrataSwitch Unit #. 829 * pkt_size : Packet size in bytes 830 * port: Test port no 831 * Returns: 832 * Number of packets needed for lossless flooding 833 */ 834 static uint32 835 ipmc_lossless_flood_cnt(int unit, int port) 836 { 837 uint32 pkt_size, flood_cnt = 0; 838 int param_flood_cnt, param_pkt_size; 839 ipmc_t *ipmc_p = ipmc_parray[unit]; 840 841 param_flood_cnt = ipmc_p->flood_pkt_cnt_param; 842 param_pkt_size = ipmc_p->pkt_size_param; 843 844 if (param_flood_cnt == 0) { 845 if (param_pkt_size == 0) { 846 pkt_size = ENET_WC_PKT_SIZE; 847 } else { 848 pkt_size = param_pkt_size; 849 } 850 flood_cnt = stream_get_ll_flood_cnt(unit, port, pkt_size, NULL); 851 } else { 852 flood_cnt = param_flood_cnt; 853 } 854 855 if (flood_cnt > MAX_PKTS_PER_STREAM) { 856 flood_cnt = MAX_PKTS_PER_STREAM; 857 } 858 return (flood_cnt); 859 } 860 861 /* 862 * Function: 863 * ipmc_send_pkts 864 * Purpose: 865 * Send packets from CPU to create a swirl on each stream. Please refer 866 * to item 6 of the "Test Setup" portion of the test description at the 867 * beginning of this file. 868 * Parameters: 869 * unit - StrataSwitch Unit #. 870 * 871 * Returns: 872 * Nothing 873 */ 874 static void 875 ipmc_send_pkts(int unit) 876 { 877 uint8 mac_da[] = MAC_DA; 878 uint8 mac_sa[] = MAC_SA; 879 uint32 pkt_size = 0, pkt_count = 0, flood_cnt = 0; 880 int i, port; 881 uint32 use_random_packet_sizes = 0; 882 ipmc_t *ipmc_p = ipmc_parray[unit]; 883 stream_pkt_t *tx_pkt; 884 885 tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt"); 886 sal_memset(tx_pkt, 0, sizeof(stream_pkt_t)); 887 888 if (ipmc_p->pkt_size_param == 1) { 889 use_random_packet_sizes = 1; 890 } 891 892 cli_out("\n==================================================\n"); 893 cli_out("\nSending packets ...\n\n"); 894 for (i = 0; i < ipmc_p->num_streams; i++) { 895 port = ipmc_p->port_list[ipmc_p->stream[i][0]]; 896 flood_cnt = ipmc_lossless_flood_cnt(unit, port); 897 if (ipmc_p->pkt_size_param == 0) { 898 pkt_size = ENET_WC_PKT_SIZE; 899 } else { 900 pkt_size = ipmc_p->pkt_size_param; 901 } 902 903 tx_pkt->port = port; 904 tx_pkt->num_pkt = flood_cnt; 905 tx_pkt->pkt_seed = ipmc_p->pkt_seed + i; 906 tx_pkt->pkt_size = pkt_size; 907 tx_pkt->rand_pkt_size_en = use_random_packet_sizes; 908 tx_pkt->rand_pkt_size = NULL; 909 tx_pkt->tx_vlan = ipmc_p->tx_vlan[i]; 910 sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR); 911 sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR); 912 if (tx_pkt->rand_pkt_size_en) { 913 tx_pkt->rand_pkt_size = ipmc_p->rand_pkt_sizes[port]; 914 } 915 tx_pkt->l3_en = 1; 916 tx_pkt->ipv6_en = 0; 917 tx_pkt->ip_da = DIP; 918 tx_pkt->ip_sa = SIP; 919 tx_pkt->ttl = TTL; 920 stream_tx_pkt(unit, tx_pkt); 921 922 /* print */ 923 cli_out("flood_cnt for stream %0d = %0d\n", i, tx_pkt->cnt_pkt); 924 pkt_count += tx_pkt->cnt_pkt; 925 } 926 927 cli_out("\nTotal packet sent: %0d\n\n", pkt_count); 928 sal_free(tx_pkt); 929 } 930 931 /* 932 * Function: 933 * ipmc_set_up_ports 934 * Purpose: 935 * Disable TTL decrement and TTL check. This makes sure the stream does not 936 * die out. 937 * 938 * Parameters: 939 * unit - StrataSwitch Unit #. 940 * 941 * Returns: 942 * Nothing 943 */ 944 static void 945 ipmc_set_up_ports(int unit) 946 { 947 int p; 948 if (SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r)) { 949 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 950 soc_reg_field32_modify(unit, EGR_IPMC_CFG2r, p, 951 DISABLE_TTL_DECREMENTf, 0x1); 952 soc_reg_field32_modify(unit, EGR_IPMC_CFG2r, p, 953 DISABLE_TTL_CHECKf, 0x1); 954 } 955 } else { 956 cli_out("\n*ERROR, invalid reg %s\n", 957 SOC_REG_NAME(unit, EGR_IPMC_CFG2r)); 958 } 959 } 960 961 /* 962 * Function: 963 * ipmc_chk_port_rate 964 * Purpose: 965 * Check actual port rates against expected port rates. 966 * Parameters: 967 * unit - StrataSwitch Unit #. 968 * 969 * Returns: 970 * SOC_E_XXXX 971 */ 972 static bcm_error_t 973 ipmc_chk_port_rate(int unit) 974 { 975 int i, j, port, port_idx; 976 bcm_error_t rv = BCM_E_NONE; 977 stream_rate_t *rate_calc; 978 ipmc_t *ipmc_p = ipmc_parray[unit]; 979 980 rate_calc = (stream_rate_t *) 981 sal_alloc(sizeof(stream_rate_t), "rate_calc"); 982 if (rate_calc == NULL) { 983 test_error(unit, "Failed to allocate memory for rate_calc\n"); 984 return BCM_E_FAIL; 985 } 986 sal_memset(rate_calc, 0, sizeof(stream_rate_t)); 987 988 rate_calc->mode = 1; 989 rate_calc->pkt_size = ipmc_p->pkt_size_param; 990 rate_calc->interval_len = ipmc_p->run_time_param; 991 rate_calc->tolerance_lr = PKT_COUNT_CHECK_TOL; 992 rate_calc->tolerance_os = PKT_COUNT_CHECK_TOL; 993 rate_calc->scaling_factor = ipmc_p->scaling_factor_param; 994 995 SOC_PBMP_CLEAR(rate_calc->pbmp); 996 for (i = 0; i < ipmc_p->num_streams; i++) { 997 for (j = 0; j < (ipmc_p->num_copy + 1); j++) { 998 port_idx = ipmc_p->stream[i][j]; 999 port = ipmc_p->port_list[port_idx]; 1000 if (port < SOC_MAX_NUM_PORTS) { 1001 /* pbmp */ 1002 SOC_PBMP_PORT_ADD((rate_calc->pbmp), port); 1003 /* num_l3_rep */ 1004 if (ipmc_p->l3_copy[port_idx] == 0) { 1005 rate_calc->num_rep[port] = 0; 1006 } else { 1007 rate_calc->num_rep[port] = ipmc_p->num_rep[port_idx] + 1; 1008 } 1009 /* src_port */ 1010 rate_calc->src_port[port] = 1011 ipmc_p->port_list[ipmc_p->stream[i][0]]; 1012 } 1013 } 1014 } 1015 1016 rv = stream_chk_port_rate(unit, PBMP_PORT_ALL(unit), rate_calc); 1017 1018 sal_free(rate_calc); 1019 return rv; 1020 } 1021 1022 /* 1023 * Function: 1024 * ipmc_chk_pkt_integrity 1025 * Purpose: 1026 * Redirect all packets back to CPU and check packet integrity 1027 * Parameters: 1028 * unit - StrataSwitch Unit #. 1029 * 1030 * Returns: 1031 * Nothing 1032 */ 1033 static bcm_error_t 1034 ipmc_chk_pkt_integrity(int unit) 1035 { 1036 int i, port, vlan_id; 1037 int param_num_stream, param_pkt_seed; 1038 int *param_port_list, **param_stream; 1039 uint32 flood_cnt; 1040 uint8 mac_da[] = MAC_DA; 1041 /* uint8 mac_sa[] = MAC_SA; */ 1042 stream_integrity_t *pkt_intg; 1043 bcm_error_t rv = BCM_E_NONE; 1044 ipmc_t *ipmc_p = ipmc_parray[unit]; 1045 1046 param_num_stream = ipmc_p->num_streams; 1047 param_pkt_seed = ipmc_p->pkt_seed; 1048 param_port_list = ipmc_p->port_list; 1049 param_stream = ipmc_p->stream; 1050 1051 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt_intg"); 1052 if (pkt_intg == NULL) { 1053 test_error(unit, "Failed to allocate memory for pkt_intg\n"); 1054 return BCM_E_FAIL; 1055 } 1056 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 1057 1058 pkt_intg->type = PKT_TYPE_IPMC; 1059 pkt_intg->ipv6_en = 0; 1060 SOC_PBMP_CLEAR(pkt_intg->rx_pbmp); 1061 for (i = 0; i < param_num_stream; i++) { 1062 port = param_port_list[param_stream[i][0]]; 1063 if (port < SOC_MAX_NUM_PORTS) { 1064 /* rx_pbmp */ 1065 SOC_PBMP_PORT_ADD(pkt_intg->rx_pbmp, port); 1066 /* rx_vlan: used to forward pkt to CPU */ 1067 vlan_id = ipmc_p->tx_vlan[i]; 1068 pkt_intg->rx_vlan[port] = vlan_id; 1069 /* tx_vlan: used to re-generate ref_pkt */ 1070 vlan_id = ipmc_p->exp_vlan[i]; 1071 pkt_intg->tx_vlan[port] = vlan_id; 1072 /* port_flood_cnt */ 1073 flood_cnt = ipmc_lossless_flood_cnt(unit, port); 1074 pkt_intg->port_flood_cnt[port] = flood_cnt; 1075 /* port_pkt_seed */ 1076 pkt_intg->port_pkt_seed[port] = param_pkt_seed + i; 1077 /* mac_da, mac_sa */ 1078 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR); 1079 sal_memcpy(pkt_intg->mac_sa[port], ipmc_p->exp_mac_addr[i], NUM_BYTES_MAC_ADDR); 1080 /* ip_da, ip_sa */ 1081 pkt_intg->ip_da[port] = DIP; 1082 pkt_intg->ip_sa[port] = SIP; 1083 } 1084 } 1085 1086 if (stream_chk_pkt_integrity(unit, pkt_intg) != BCM_E_NONE) { 1087 rv = BCM_E_FAIL; 1088 } 1089 1090 sal_free(pkt_intg); 1091 return rv; 1092 } 1093 1094 /* 1095 * Function: 1096 * ipmc_free_all_memory 1097 * Purpose: 1098 * Free all allocated memory. 1099 * Parameters: 1100 * unit - StrataSwitch Unit #. 1101 * 1102 * Returns: 1103 * Nothing 1104 */ 1105 static void 1106 ipmc_free_all_memory(int unit) 1107 { 1108 int i; 1109 ipmc_t *ipmc_p = ipmc_parray[unit]; 1110 1111 sal_free(ipmc_p->port_speed); 1112 sal_free(ipmc_p->port_list); 1113 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 1114 sal_free(ipmc_p->stream[i]); 1115 } 1116 sal_free(ipmc_p->stream); 1117 sal_free(ipmc_p->num_rep); 1118 sal_free(ipmc_p->l3_copy); 1119 sal_free(ipmc_p->tx_vlan); 1120 sal_free(ipmc_p->exp_vlan); 1121 sal_free(ipmc_p->exp_mac_addr); 1122 sal_free(ipmc_p->port_oversub); 1123 sal_free(ipmc_p->port_used); 1124 sal_free(ipmc_p->ovs_ratio_x1000); 1125 sal_free(ipmc_p->exp_rate); 1126 sal_free(ipmc_p->tpkt_start); 1127 sal_free(ipmc_p->tpkt_end); 1128 for (i = 0; i < ipmc_p->num_fp_ports; i++) { 1129 sal_free(ipmc_p->rand_pkt_sizes[i]); 1130 } 1131 sal_free(ipmc_p->rand_pkt_sizes); 1132 } 1133 1134 /* 1135 * Function: 1136 * ipmc_test_init 1137 * Purpose: 1138 * Test init function. Parse CLI params and do necessary init. 1139 * Parameters: 1140 * unit - StrataSwitch Unit #. 1141 * 1142 * Returns: 1143 * Nothing 1144 */ 1145 int 1146 ipmc_test_init(int unit, args_t *a, void **pa) 1147 { 1148 ipmc_t *ipmc_p; 1149 1150 ipmc_p = ipmc_parray[unit]; 1151 ipmc_p = sal_alloc(sizeof(ipmc_t), "ipmc_test"); 1152 sal_memset(ipmc_p, 0, sizeof(ipmc_t)); 1153 ipmc_parray[unit] = ipmc_p; 1154 1155 stream_print_port_config(unit, PBMP_PORT_ALL(unit)); 1156 cli_out("\n=================================================="); 1157 cli_out("\nCalling ipmc_test_init ...\n"); 1158 ipmc_parse_test_params(unit, a); 1159 1160 ipmc_p->test_fail = 0; 1161 1162 if (ipmc_p->bad_input == 1) { 1163 goto done; 1164 } 1165 1166 stream_set_mac_lpbk(unit, PBMP_PORT_ALL(unit)); 1167 stream_turn_off_cmic_mmu_bkp(unit); 1168 stream_turn_off_fc(unit, PBMP_PORT_ALL(unit)); 1169 /* coverity[dont_call : FALSE] */ 1170 ipmc_p->pkt_seed = sal_rand(); 1171 1172 done: 1173 return 0; 1174 } 1175 1176 /* 1177 * Function: 1178 * ipmc_test 1179 * Purpose: 1180 * Set up ports/streams and send packets. 1181 * Parameters: 1182 * unit - StrataSwitch Unit #. 1183 * 1184 * Returns: 1185 * Nothing 1186 */ 1187 int 1188 ipmc_test(int unit, args_t *a, void *pa) 1189 { 1190 ipmc_t *ipmc_p = ipmc_parray[unit]; 1191 1192 if (ipmc_p->bad_input == 1) { 1193 goto done; 1194 } 1195 1196 cli_out("\n=================================================="); 1197 cli_out("\nCalling ipmc_test ... \n"); 1198 ipmc_set_port_property(unit); 1199 ipmc_set_up_ports(unit); 1200 ipmc_set_up_streams(unit); 1201 ipmc_send_pkts(unit); 1202 1203 /* check counter */ 1204 if (stream_chk_mib_counters(unit, PBMP_PORT_ALL(unit), 0) != BCM_E_NONE) { 1205 ipmc_p->test_fail = 1; 1206 } 1207 /* check rate */ 1208 if (ipmc_chk_port_rate(unit) != BCM_E_NONE) { 1209 ipmc_p->test_fail = 1; 1210 } 1211 /* check integrity */ 1212 if (ipmc_chk_pkt_integrity(unit) != BCM_E_NONE) { 1213 ipmc_p->test_fail = 1; 1214 } 1215 1216 done: 1217 return 0; 1218 } 1219 1220 /* 1221 * Function: 1222 * ipmc_test_cleanup 1223 * Purpose: 1224 * Do test end checks and free all allocated memory. 1225 * Parameters: 1226 * unit - StrataSwitch Unit #. 1227 * 1228 * Returns: 1229 * Nothing 1230 */ 1231 int 1232 ipmc_test_cleanup(int unit, void *pa) 1233 { 1234 int rv; 1235 ipmc_t *ipmc_p = ipmc_parray[unit]; 1236 1237 if (ipmc_p->bad_input == 1) { 1238 goto done; 1239 } 1240 cli_out("\nCalling ipmc_test_cleanup"); 1241 1242 done: 1243 if (ipmc_p->bad_input == 1) { 1244 ipmc_p->test_fail = 1; 1245 } 1246 1247 if (ipmc_p->test_fail == 1) { 1248 rv = BCM_E_FAIL; 1249 } 1250 else { 1251 rv = BCM_E_NONE; 1252 } 1253 1254 cli_out("\n=================================================="); 1255 cli_out("\n=================================================="); 1256 if (ipmc_p->test_fail == 1) { 1257 cli_out("\n[IPMC test failed]\n\n"); 1258 } else { 1259 cli_out("\n[IPMC test passed]\n\n"); 1260 } 1261 1262 ipmc_free_all_memory(unit); 1263 sal_free(ipmc_p); 1264 1265 return rv; 1266 } 1267 1268 #endif /* BCM_ESW_SUPPORT && INCLUDE_L3 */