flexport_td3.c (98612B)
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 * Flexport test is to check the correctness of flexport operation under 8 * ipmc and l3uc traffic background. Ports are divided into two groups: 9 * ports receiving IPMC packets and ports receiving L3UC packets. 10 * Each port in IPMC group can receive L2 or L3 copies. While each port 11 * in L3UC receiving L3UC packets. Test calculates expected rates based 12 * on port config and oversub ratio and checks against it. 13 * Configuration parameters passed from CLI:\n" 14 * 15 * Checks: 16 * 1. Packet counts on each port. 17 * 2. Packet integrity per port per replication. 18 * 3. Port rate. 19 * 20 * Test Limitations 21 * 1. FloodCnt automatically computed in the test supports packet sizes upto 22 * 1518B and NumCopy=2. Any deviations may result in packet drops for LR 23 * configs or false rate errors being reported. For custom configs the user is 24 * encouraged to tweak the FloodCnt value as per their needs. 25 * 26 * Configuration parameters passed from CLI: 27 * PktSize : Packet size in bytes not including HG2 header. Set to 0 for worst 28 * case packet sizes (145B for Ethernet and 76B for HG2). Set to 1 for 29 * random packet sizes. 30 * FloodCnt: Number of packets sent from CPU to flood each stream (packet swill). 31 * Set to 0 for test to automatically calculate. 32 * IpmcNumL2Ports: Number of ports receiving L2 copies in each stream (2 by default). 33 * IpmcNumL3Ports: Number of ports receiving L3 copies in each stream (2 by default). 34 * IpmcNumRep: Number of same-port replications on ports receiving . Set to 0 for 35 * random. 36 * MaxNumCells: Max number of cells for random packet sizes. Default = 4. 37 * Set to 0 for random. 38 * RateCalcInterval: Interval in seconds over which swill is allowed to 39 * run (10s by default). 40 */ 41 42 #include <appl/diag/system.h> 43 #include <shared/alloc.h> 44 #include <shared/bsl.h> 45 46 #include <soc/cm.h> 47 #include <soc/dma.h> 48 #include <soc/drv.h> 49 #include <soc/dcb.h> 50 #include <soc/cmicm.h> 51 #include <soc/cmic.h> 52 53 #include <sal/types.h> 54 #include <appl/diag/parse.h> 55 #include <bcm/port.h> 56 #include <bcm/vlan.h> 57 #include <bcm/link.h> 58 #include <bcm/ipmc.h> 59 #include <bcm/multicast.h> 60 61 #include "testlist.h" 62 #include "gen_pkt.h" 63 #include "streaming_lib.h" 64 65 #define MAC_DA {0x01,0x00,0x5e,0x02,0x03,0x04} 66 #define MAC_SA {0x00,0x00,0x00,0x00,0x00,0x01} 67 #define VLAN 0x2 68 #define DROP_VLAN 0xabc 69 #define SIP 0x02030405 70 #define DIP 0xe0020304 71 #define FIRST_MC_GROUP 0x2000001 72 #define FIRST_INTF_ID 0x2 73 #define TTL 5 74 75 #define MAX_NUM_TSC 65 76 #define NUM_LANES_PER_TSC 4 77 #define MAX_PKTS_PER_STREAM 200 78 79 #define PKT_SIZE_PARAM_DEFAULT 0 80 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0 81 #define NUM_L2_COPY_PARAM_DEFAULT 2 82 #define NUM_L3_COPY_PARAM_DEFAULT 6 83 #define NUM_REP_PARAM_DEFAULT 3 84 #define MAX_NUM_CELLS_PARAM_DEFAULT 4 85 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10 86 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 2 87 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 5 88 #define CHECK_INTEGRITY_PARAM_DEFAULT 1 89 #define CHECK_RATE_PARAM_DEFAULT 1 90 #define CHECK_MIB_PARAM_DEFAULT 0 91 #define MAX_L3_VLANS_PER_TEST 1000 92 #define MAX_NUM_IPMC_STREAMS 10 93 #define MAX_NUM_REP_PER_PORT 10 94 #define NO_SPEED_CHANGE_PARAM_DEFAULT 1 95 #define EMULATION_PARAM_DEFAULT 0 96 #define CLEAR_NEW_PORT_CNT_PARAM_DEFAULT 0 97 #define TEST_COVERITY_PBMP_WID 256 98 99 #if defined(BCM_ESW_SUPPORT) && defined(INCLUDE_L3) && \ 100 (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \ 101 !defined(NO_SAL_APPL) && (!defined(__KERNEL__)) 102 103 typedef struct flexport_mc_s { 104 pbmp_t ipmc_pbmp; 105 uint32 ipmc_num_streams; 106 uint32 ipmc_port_list[SOC_MAX_NUM_PORTS]; 107 uint32 ipmc_port_list_size; 108 int ipmc_stream[MAX_NUM_IPMC_STREAMS][SOC_MAX_NUM_PORTS]; 109 uint32 ipmc_num_rep[SOC_MAX_NUM_PORTS]; 110 uint32 ipmc_port_l3_copy_en[SOC_MAX_NUM_PORTS]; 111 uint32 ipmc_tx_vlan[MAX_NUM_IPMC_STREAMS]; 112 uint32 ipmc_exp_vlan[MAX_NUM_IPMC_STREAMS]; 113 uint8 ipmc_exp_mac_addr[MAX_NUM_IPMC_STREAMS][NUM_BYTES_MAC_ADDR]; 114 uint32 ipmc_drop_vlan[MAX_NUM_IPMC_STREAMS]; 115 uint64 *ipmc_exp_rate; 116 uint64 *ipmc_tpkt_start; 117 uint64 *ipmc_tpkt_end; 118 uint32 ipmc_rand_pkt_sizes[TARGET_CELL_COUNT]; 119 120 uint32 pkt_size_param; 121 uint32 flood_pkt_cnt_param; 122 uint32 ipmc_num_l2_ports_param; 123 uint32 ipmc_num_l3_ports_param; 124 uint32 check_integrity_param; 125 uint32 check_rate_param; 126 uint32 check_mib_param; 127 uint32 ipmc_num_rep_param; 128 uint32 max_num_cells_param; 129 uint32 rate_calc_interval_param; 130 uint32 rate_tolerance_lr_param; 131 uint32 rate_tolerance_os_param; 132 uint32 flex_no_spd_ch_param; 133 uint32 emulation_param; 134 uint32 loopback_mode_param; 135 uint32 clear_new_port_cnt_param; 136 uint32 num_ports_per_stream; 137 138 uint32 bad_input; 139 int test_fail; 140 uint32 pkt_seed; 141 142 uint32 debug_param; 143 uint32 ipmc_port_rep_vlan[SOC_MAX_NUM_PORTS][MAX_NUM_REP_PER_PORT]; 144 uint32 ipmc_port_vlan_cnt[SOC_MAX_NUM_PORTS]; 145 uint32 ipmc_cpu_rx_vlan_cnt[MAX_L3_VLANS_PER_TEST]; 146 uint32 ipmc_next_vlan; 147 uint32 ipmc_next_drop_vlan; 148 uint32 ipmc_next_intf_id; 149 uint32 ipmc_stream_mc_group[MAX_NUM_IPMC_STREAMS]; 150 151 int env_linkscan_enable; 152 uint32 env_counter_flags; 153 int env_counter_interval; 154 pbmp_t env_counter_pbm; 155 156 pbmp_t flex_lport_dn_pbmp; /* pbmp for down-ports */ 157 pbmp_t flex_lport_up_pbmp; /* pbmp for up-ports */ 158 pbmp_t flex_lport_ch_pbmp; /* pbmp for speed_change_lane_unchange-ports */ 159 char *flex_tsc_mode[MAX_NUM_TSC]; 160 uint32 flex_num_del; 161 uint32 flex_num_add; 162 bcm_port_resource_t flex_resource_del[SOC_MAX_NUM_PORTS]; 163 bcm_port_resource_t flex_resource_add[SOC_MAX_NUM_PORTS]; 164 165 pbmp_t l3uc_pbmp; 166 pbmp_t l3uc_vlan_pbmp; 167 168 /* chip dependent test parameters. */ 169 int test_lport_lo_ipmc, test_lport_hi_ipmc; 170 int test_lport_lo_l3uc, test_lport_hi_l3uc; 171 } flexport_mc_t; 172 173 174 typedef struct flexport_l3uc_rate_calc_t { 175 uint32 ovs_ratio_x1000[SOC_MAX_NUM_PIPES]; 176 uint32 rand_pkt_sizes[SOC_MAX_NUM_PORTS][TARGET_CELL_COUNT]; 177 uint64 stime[SOC_MAX_NUM_PORTS]; 178 uint64 exp_rate[SOC_MAX_NUM_PORTS]; 179 uint64 tpkt_start[SOC_MAX_NUM_PORTS]; 180 uint64 tbyt_start[SOC_MAX_NUM_PORTS]; 181 } flexport_l3uc_rate_calc_t; 182 183 184 static flexport_mc_t *flexport_parray[SOC_MAX_NUM_DEVICES]; 185 static flexport_l3uc_rate_calc_t *rate_calc_parray[SOC_MAX_NUM_DEVICES]; 186 187 188 const char flexport_mc_test_usage[] = 189 #ifdef COMPILER_STRING_CONST_LIMIT 190 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 191 #else 192 "Flexport test is to check the correctness of flexport operation under\n" 193 "ipmc and l3uc traffic background. Ports are divided into two groups:\n" 194 "ports receiving IPMC packets and ports receiving L3UC packets. \n" 195 "Each port in IPMC group can receive L2 or L3 copies. While each port\n" 196 "in L3UC receiving L3UC packets. Test calculates expected rates based\n" 197 "on port config and oversub ratio and checks against it.\n" 198 "Configuration parameters passed from CLI:\n" 199 "PktSize: Packet size in bytes. Set it to 0 for worst case packet sizes.\n" 200 " Set it to 1 for random packet sizes.\n" 201 "FloodCnt: Number of packets in each swill. Set it to 0 will let the\n" 202 " test calculate the number of packets that can be sent to\n" 203 " achieve a lossless swirl at full rate. Set to 0 by default.\n" 204 " IpmcNumL2Ports: Number of ports receiving L2 copies (2 by default).\n" 205 " IpmcNumL3Ports: Number of ports receiving L3 copies (2 by default).\n" 206 " IpmcNumRep: Number of replications per port. Set to 0 for random.\n" 207 " MaxNumCells: Max number of cells for random packet sizes. Default = 4.\n" 208 " Set to 0 for random.\n" 209 " RateCalcInterval: Interval in seconds over which swill is allowed to\n" 210 " run (10s by default).\n"; 211 #endif 212 213 const char flexport_mc_td3_supported_mode[] = 214 " 1x100G, 1x40G\n" 215 " 2x50G, 2x40G, 2x20G,\n" 216 " 20G+2x10G, 2x10G+20G,\n" 217 " 50G+2x25G, 2x25G+50G,\n" 218 " 4x25G, 4x10G and 4x1G\n" 219 " The supported mode/speed in HiGig2 encapsulation are:\n" 220 " 1x106G, 1x42G,\n" 221 " 2x53G, 2x42G, 2x21G,\n" 222 " 4x27G, and 4x11G\n" 223 ; 224 225 226 227 /* 228 * Function: 229 * flexport_print_ports 230 * Purpose: 231 * Print ports in port bmp. 232 * Parameters: 233 * unit: StrataSwitch Unit #. 234 * pbmp: port bitmap. 235 * str : string ptr for print title. 236 * 237 * Returns: 238 * Nothing. 239 */ 240 static void 241 flexport_print_ports(int unit, pbmp_t pbmp, char *str) 242 { 243 int p, cnt = 0; 244 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n%s"), str)); 245 PBMP_ITER(pbmp, p) { 246 if (cnt++ % 10 == 0) { 247 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 248 } 249 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "%3d "), p)); 250 } 251 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 252 } 253 254 /* 255 * Function: 256 * flexport_set_chip_dependent_params 257 * Purpose: 258 * Set chip dependent parameters. 259 * Parameters: 260 * 261 * Returns: 262 * Nothing 263 */ 264 static void 265 flexport_set_chip_dependent_params(int unit) 266 { 267 flexport_mc_t *flex_p = flexport_parray[unit]; 268 269 /* MAVERICK2 */ 270 if (SOC_IS_MAVERICK2(unit)) { 271 flex_p->test_lport_lo_ipmc = 1; 272 flex_p->test_lport_hi_ipmc = 32; 273 flex_p->test_lport_lo_l3uc = 41; 274 flex_p->test_lport_hi_l3uc = 64; 275 } 276 /* TRIDENT3 */ 277 else if (SOC_IS_TRIDENT3(unit)) { 278 flex_p->test_lport_lo_ipmc = 1; 279 flex_p->test_lport_hi_ipmc = 32; 280 flex_p->test_lport_lo_l3uc = 64; 281 flex_p->test_lport_hi_l3uc = 128; 282 } 283 else { 284 flex_p->test_lport_lo_ipmc = 1; 285 flex_p->test_lport_hi_ipmc = 32; 286 flex_p->test_lport_lo_l3uc = 64; 287 flex_p->test_lport_hi_l3uc = 128; 288 } 289 } 290 291 /* 292 * Function: 293 * flexport_is_ipmc_port 294 * Purpose: 295 * Check if physial port is belonging to ipmc group. 296 * Parameters: 297 * unit: StrataSwitch Unit #. 298 * phy_port: physical port number. 299 * 300 * Returns: 301 * Return true if port is belonging to impc port_range, 302 * otherwise return false. 303 */ 304 static int 305 flexport_is_ipmc_port(int unit, int phy_port) 306 { 307 flexport_mc_t *flex_p = flexport_parray[unit]; 308 return (phy_port >= flex_p->test_lport_lo_ipmc && 309 phy_port <= flex_p->test_lport_hi_ipmc); 310 } 311 312 /* 313 * Function: 314 * flexport_is_l3uc_port 315 * Purpose: 316 * Check if physial port is belonging to l3uc group. 317 * Parameters: 318 * unit: StrataSwitch Unit #. 319 * phy_port: physical port number. 320 * 321 * Returns: 322 * Return true if port is belonging to l3uc port_range, 323 * otherwise return false. 324 */ 325 static int 326 flexport_is_l3uc_port(int unit, int phy_port) 327 { 328 flexport_mc_t *flex_p = flexport_parray[unit]; 329 return (phy_port >= flex_p->test_lport_lo_l3uc && 330 phy_port <= flex_p->test_lport_hi_l3uc); 331 } 332 333 334 /* 335 * Function: 336 * flexport_parse_test_params 337 * Purpose: 338 * Parse CLI parameters, create test structure and flag bad inputs. 339 * Parameters: 340 * unit - StrataSwitch Unit #. 341 * a - Pointer to arguments 342 * 343 * Returns: 344 * Nothing 345 * Notes: 346 * flex_p->bad_input set from here - tells test to crash out in case 347 * CLI input combination is invalid. 348 */ 349 static void 350 flexport_parse_test_params(int unit, args_t *a) 351 { 352 parse_table_t parse_table; 353 flexport_mc_t *flex_p = flexport_parray[unit]; 354 355 flex_p->bad_input = 0; 356 357 flex_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT; 358 flex_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT; 359 flex_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT; 360 flex_p->ipmc_num_l2_ports_param = NUM_L2_COPY_PARAM_DEFAULT; 361 flex_p->ipmc_num_l3_ports_param = NUM_L3_COPY_PARAM_DEFAULT; 362 flex_p->ipmc_num_rep_param = NUM_REP_PARAM_DEFAULT; 363 flex_p->rate_calc_interval_param= RATE_CALC_INTERVAL_PARAM_DEFAULT; 364 flex_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT; 365 flex_p->rate_tolerance_os_param = RATE_TOLERANCE_OV_PARAM_DEFAULT; 366 flex_p->check_integrity_param = CHECK_INTEGRITY_PARAM_DEFAULT; 367 flex_p->check_rate_param = CHECK_RATE_PARAM_DEFAULT; 368 flex_p->check_mib_param = CHECK_MIB_PARAM_DEFAULT; 369 flex_p->flex_no_spd_ch_param = NO_SPEED_CHANGE_PARAM_DEFAULT; 370 flex_p->emulation_param = EMULATION_PARAM_DEFAULT; 371 flex_p->loopback_mode_param = BCM_PORT_LOOPBACK_MAC; 372 flex_p->clear_new_port_cnt_param= CLEAR_NEW_PORT_CNT_PARAM_DEFAULT; 373 flex_p->debug_param = 0; 374 375 /*Parse CLI opts */ 376 377 parse_table_init(unit, &parse_table); 378 parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0, 379 &(flex_p->pkt_size_param), NULL); 380 parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0, 381 &(flex_p->flood_pkt_cnt_param), NULL); 382 parse_table_add(&parse_table, "IpmcNumL2Ports", PQ_INT|PQ_DFL, 0, 383 &(flex_p->ipmc_num_l2_ports_param), NULL); 384 parse_table_add(&parse_table, "IpmcNumL3Ports", PQ_INT|PQ_DFL, 0, 385 &(flex_p->ipmc_num_l3_ports_param), NULL); 386 parse_table_add(&parse_table, "IpmcNumRep", PQ_INT|PQ_DFL, 0, 387 &(flex_p->ipmc_num_rep_param), NULL); 388 parse_table_add(&parse_table, "RateToleranceLR", PQ_INT|PQ_DFL, 0, 389 &(flex_p->rate_tolerance_lr_param), NULL); 390 parse_table_add(&parse_table, "RateToleranceOS", PQ_INT|PQ_DFL, 0, 391 &(flex_p->rate_tolerance_os_param), NULL); 392 parse_table_add(&parse_table, "RateCalcInterval", PQ_INT|PQ_DFL, 0, 393 &(flex_p->rate_calc_interval_param), NULL); 394 parse_table_add(&parse_table, "CheckIntegrity", PQ_INT|PQ_DFL, 0, 395 &(flex_p->check_integrity_param), NULL); 396 parse_table_add(&parse_table, "CheckRate", PQ_INT|PQ_DFL, 0, 397 &(flex_p->check_rate_param), NULL); 398 parse_table_add(&parse_table, "CheckMib", PQ_INT|PQ_DFL, 0, 399 &(flex_p->check_mib_param), NULL); 400 parse_table_add(&parse_table, "ClrNewPortCnt", PQ_INT|PQ_DFL, 0, 401 &(flex_p->clear_new_port_cnt_param), NULL); 402 parse_table_add(&parse_table, "DebugParam", PQ_INT|PQ_DFL, 0, 403 &(flex_p->debug_param), NULL); 404 405 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 406 test_msg("%s", flexport_mc_test_usage); 407 cli_out("\n%s\n", flexport_mc_td3_supported_mode); 408 test_error(unit, "%s: Invalid option: %s\n", 409 ARG_CMD(a), 410 ARG_CUR(a) ? ARG_CUR(a) : "*"); 411 flex_p->bad_input = 1; 412 parse_arg_eq_done(&parse_table); 413 } else { 414 cli_out("\n"); 415 cli_out("------------- PRINTING TEST PARAMS ------------------\n"); 416 cli_out("PktSize = %0d\n", flex_p->pkt_size_param); 417 cli_out("FloodCnt = %0d\n", flex_p->flood_pkt_cnt_param); 418 cli_out("IpmcNumL3Ports = %0d\n", flex_p->ipmc_num_l3_ports_param); 419 cli_out("IpmcNumRep = %0d\n", flex_p->ipmc_num_rep_param); 420 cli_out("MaxNumCells = %0d\n", flex_p->max_num_cells_param); 421 cli_out("RateToleranceLR = %0d\n", flex_p->rate_tolerance_lr_param); 422 cli_out("RateToleranceOS = %0d\n", flex_p->rate_tolerance_os_param); 423 cli_out("RateCalcInterval = %0d\n", flex_p->rate_calc_interval_param); 424 cli_out("CheckIntegrity = %0d\n", flex_p->check_integrity_param); 425 cli_out("CheckRate = %0d\n", flex_p->check_rate_param); 426 cli_out("FlexNoSpeedChange= %0d\n", flex_p->flex_no_spd_ch_param); 427 cli_out("ClrNewPortCnt = %0d\n", flex_p->clear_new_port_cnt_param); 428 cli_out("DebugParam = %0d\n", flex_p->debug_param); 429 cli_out("-----------------------------------------------------\n"); 430 } 431 432 /* loopback_mode */ 433 if ((flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_MAC) && 434 (flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY) && 435 (flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY_REMOTE) && 436 (flex_p->loopback_mode_param != BCM_PORT_LOOPBACK_NONE)) { 437 /* 438 * 0 - no loopback; only to be used with chip external loopbacks. 439 * 1 - MAC outer loopback. 440 * 2 - PCS local loopback, close to PMD boundary. 441 * 3 - PMD local loopback, close to AFE. 442 */ 443 test_error(unit,"*ERROR: Loopback mode must be either 0, 1, 2 or 3\n"); 444 flex_p->bad_input = 1; 445 } 446 447 if (flex_p->max_num_cells_param == 0) { 448 /* coverity[dont_call : FALSE] */ 449 flex_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1; 450 } 451 452 if (flex_p->pkt_size_param == 0) { 453 flex_p->pkt_size_param = 256; 454 cli_out("Using default packet sizes - %0dB", flex_p->pkt_size_param); 455 } else if (flex_p->pkt_size_param == 1) { 456 cli_out("Using random packet sizes\n"); 457 } else if (flex_p->pkt_size_param < MIN_PKT_SIZE) { 458 test_error(unit,"\n*ERROR: Packet size cannot be lower than %0dB\n", 459 MIN_PKT_SIZE); 460 flex_p->bad_input = 1; 461 } else if (flex_p->pkt_size_param > MTU) { 462 test_error(unit, "\n%s higher than %0dB (Device MTU)\n", 463 "*ERROR: Packet size cannot be ", MTU); 464 flex_p->bad_input = 1; 465 } 466 467 if (flex_p->flood_pkt_cnt_param == 0) { 468 cli_out("FloodCnt=0, test will automatically calculate number of" 469 " packets to flood each port\n"); 470 } 471 472 if (flex_p->ipmc_num_rep_param > MAX_NUM_REP_PER_PORT) { 473 flex_p->ipmc_num_rep_param = MAX_NUM_REP_PER_PORT; 474 cli_out("Max replications supported by this test = %0d," 475 "forcing number of replications to %0d\n", 476 MAX_NUM_REP_PER_PORT, MAX_NUM_REP_PER_PORT); 477 } 478 479 /* total number of ports in each ipmc group */ 480 flex_p->num_ports_per_stream = flex_p->ipmc_num_l2_ports_param + 481 flex_p->ipmc_num_l3_ports_param; 482 cli_out("initial NumPortsIpmc = %0d,\n", flex_p->num_ports_per_stream); 483 } 484 485 /* 486 * Function: 487 * flexport_ipmc_set_port_property 488 * Purpose: 489 * Set port_list, stream, port_l3_copy_en, rand_pkt_size. 490 * Also call set_exp_rates. 491 * Parameters: 492 * unit: StrataSwitch Unit #. 493 * 494 * Returns: 495 * Nothing. 496 */ 497 static void 498 flexport_ipmc_set_port_property(int unit) 499 { 500 int i, j, p, port_idx, pkt_size; 501 flexport_mc_t *flex_p = flexport_parray[unit]; 502 503 cli_out("\n[ipmc] set_port_property()\n"); 504 505 flex_p->ipmc_num_streams = 0; 506 /* coverity[dont_call : FALSE] */ 507 flex_p->pkt_seed = sal_rand(); 508 509 flex_p->ipmc_port_list_size = 0; 510 PBMP_ITER(flex_p->ipmc_pbmp, p) { 511 flex_p->ipmc_port_list[flex_p->ipmc_port_list_size++] = p; 512 } 513 514 /* assign ports for stream 0 by picking up the first n ports */ 515 i = 0; 516 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 517 port_idx = j; /* index of port in ipmc_port_list */ 518 flex_p->ipmc_stream[i][j] = port_idx; 519 } 520 flex_p->ipmc_num_streams = 1; 521 522 /* port_l3_copy_en[]: all ports except P0 and P1 receive L3 copies. 523 * P0 and P1 are used for generating traffic. 524 */ 525 for (i = 0; i < flex_p->ipmc_port_list_size; i++) { 526 p = flex_p->ipmc_port_list[i]; 527 flex_p->ipmc_port_l3_copy_en[p] = i < 2 ? 0 : 1; 528 } 529 530 /* num_rep[]: number of L3 replications of each port */ 531 for (i = 0; i < flex_p->ipmc_port_list_size; i++) { 532 p = flex_p->ipmc_port_list[i]; 533 flex_p->ipmc_num_rep[p] = 0; 534 if (flex_p->ipmc_port_l3_copy_en[p] == 1) { 535 if (flex_p->ipmc_num_rep_param == 0) { 536 /* coverity[dont_call : FALSE] */ 537 flex_p->ipmc_num_rep[p] = sal_rand() % (MAX_NUM_REP_PER_PORT + 1); 538 } else { 539 flex_p->ipmc_num_rep[p] = flex_p->ipmc_num_rep_param; 540 } 541 } 542 } 543 544 /* rand_pkt_sizes[][] */ 545 p = flex_p->ipmc_port_list[0]; 546 for (j = 0; j < TARGET_CELL_COUNT; j++) { 547 do { 548 /* coverity[dont_call : FALSE] */ 549 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + MIN_PKT_SIZE; 550 } while (stream_get_pkt_cell_cnt(unit, pkt_size, p) > 551 flex_p->max_num_cells_param); 552 flex_p->ipmc_rand_pkt_sizes[j] = pkt_size; 553 } 554 555 { 556 /* print */ 557 int port_idx; 558 cli_out("\n=========== IPMC STREAM INFO ============\n"); 559 cli_out("\t[%s]%4s %s/%s\n", "idx", "port", "type", "num_cpy"); 560 561 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 562 cli_out("%4d ", i); 563 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 564 port_idx = flex_p->ipmc_stream[i][j]; 565 p = flex_p->ipmc_port_list[port_idx]; 566 cli_out("\t[%d]%4d ", j, p); 567 if (flex_p->ipmc_port_l3_copy_en[p] == 0) { 568 cli_out("%s/%d", "L2", 0); 569 } else { 570 cli_out("%s/%d", "L3", (flex_p->ipmc_num_rep[p] + 1)); 571 } 572 } 573 cli_out("\n"); 574 } 575 cli_out("\nipmc_num_ports/ipmc_num_avail_ports = %0d / %0d\n", 576 flex_p->num_ports_per_stream, flex_p->ipmc_port_list_size); 577 } 578 } 579 580 /* 581 * Function: 582 * flexport_ipmc_add_l3_intf 583 * Purpose: 584 * This function actually sets up the IPMC packet flow. Please refer to 585 * items 4-6 of the "Test Setup" section of the test description at the 586 * beginning of this file. 587 * Parameters: 588 * unit: StrataSwitch Unit #. 589 * port: physical port. 590 * mc_group: multicast group id. 591 * dst_vlan: used for vlan translation. 592 * 593 * Returns: 594 * Nothing. 595 */ 596 static void 597 flexport_ipmc_add_l3_intf(int unit, int port, bcm_multicast_t mc_group, 598 bcm_vlan_t dst_vlan) 599 { 600 pbmp_t pbm, ubm; 601 bcm_vlan_t vlan; 602 bcm_l3_intf_t l3_intf; 603 bcm_if_t intf_id; 604 bcm_if_t encap_id; 605 uint32 intf_flags = 0; 606 uint8 intf_mac[] = {0x00,0x00,0x00,0x00,0x00,0x00}; 607 bcm_gport_t gport; 608 uint32 port_vlan_cnt; 609 flexport_mc_t *flex_p = flexport_parray[unit]; 610 611 /* init */ 612 intf_flags |= BCM_L3_WITH_ID; 613 BCM_PBMP_CLEAR(ubm); 614 615 /* create vlan */ 616 vlan = (bcm_vlan_t) flex_p->ipmc_next_vlan++; 617 bcm_vlan_create(unit, vlan); 618 BCM_PBMP_CLEAR(pbm); 619 BCM_PBMP_PORT_ADD(pbm, port); 620 bcm_vlan_port_add(unit, vlan, pbm, ubm); 621 622 /* create vlan_translate */ 623 bcm_vlan_translate_add(unit, port, vlan, dst_vlan, 0); 624 625 /* update test variable */ 626 port_vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]++; 627 flex_p->ipmc_port_rep_vlan[port][port_vlan_cnt] = (uint32) vlan; 628 629 /* create l3_intf */ 630 bcm_l3_intf_t_init(&l3_intf); 631 intf_id = (bcm_if_t) flex_p->ipmc_next_intf_id++; 632 intf_mac[NUM_BYTES_MAC_ADDR - 1] = intf_id; 633 intf_mac[NUM_BYTES_MAC_ADDR - 2] = intf_id >> 8; 634 sal_memcpy(l3_intf.l3a_mac_addr, intf_mac, 6); 635 l3_intf.l3a_vid = vlan; 636 l3_intf.l3a_intf_id = intf_id; 637 l3_intf.l3a_flags = intf_flags; 638 bcm_l3_intf_create(unit, &l3_intf); 639 640 /* add l3_intf into mc_group */ 641 bcm_multicast_l3_encap_get(unit, mc_group, port, intf_id, &encap_id); 642 BCM_GPORT_LOCAL_SET(gport, port); 643 bcm_multicast_egress_add(unit, mc_group, gport, encap_id); 644 } 645 646 /* 647 * Function: 648 * flexport_ipmc_print_vlan_info 649 * Purpose: 650 * Print IPMC vlan info. 651 * Parameters: 652 * unit: StrataSwitch Unit #. 653 * 654 * Returns: 655 * Nothing. 656 */ 657 static void 658 flexport_ipmc_print_vlan_info(int unit) 659 { 660 int i, j, port_idx; 661 int port, cnt, vlan_cnt; 662 flexport_mc_t *flex_p = flexport_parray[unit]; 663 664 cli_out("\n=========== port vlan info ============\n"); 665 cli_out("%4s %4s %4s %4s %4s %4s \t%4s\n", 666 "strm", "idx", "tsc", "port", "type", "vlan_cnt", "vlan_id"); 667 668 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 669 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 670 port_idx = flex_p->ipmc_stream[i][j]; 671 port = flex_p->ipmc_port_list[port_idx]; 672 if (flex_p->ipmc_port_l3_copy_en[port] == -1) continue; 673 cli_out("%4d ", i); 674 cli_out("%4d %4d %4d ", j, (port-1)/4, port); 675 if (flex_p->ipmc_port_l3_copy_en[port] == 0) { 676 cli_out("%4s ", "L2"); 677 } else { 678 cli_out("%4s ", "L3"); 679 } 680 vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]; 681 cli_out("%4d \t", vlan_cnt); 682 for (cnt = 0; cnt < vlan_cnt; cnt++) { 683 cli_out("%4d ", flex_p->ipmc_port_rep_vlan[port][cnt]); 684 } 685 cli_out("\n"); 686 } 687 cli_out("\n"); 688 } 689 } 690 691 /* 692 * Function: 693 * flexport_ipmc_set_up_streams 694 * Purpose: 695 * This function actually sets up the IPMC packet flow. Please refer to 696 * items 4-6 of the "Test Setup" section of the test description at the 697 * beginning of this file. 698 * Parameters: 699 * unit: StrataSwitch Unit #. 700 * 701 * Returns: 702 * Nothing. 703 */ 704 static void 705 flexport_ipmc_set_up_streams(int unit) 706 { 707 int i, j, k; 708 pbmp_t pbm, ubm; 709 bcm_vlan_t vlan, vlan_0 = 0, vlan_1 = 0, dst_vlan, drop_vlan; 710 /* uint32 vlan, vlan_0 = 0, vlan_1 = 0; */ 711 bcm_multicast_t mc_group; 712 uint32 mc_flags = 0; 713 bcm_if_t intf_id; 714 bcm_ipmc_addr_t ipmc_addr; 715 uint32 ipmc_flags = 0; 716 uint8 mac_sa[] = MAC_SA; 717 int port; 718 bcm_gport_t gport; 719 uint32 port_vlan_cnt; 720 flexport_mc_t *flex_p = flexport_parray[unit]; 721 722 /* init vlan setup */ 723 bcm_vlan_destroy_all(unit); 724 bcm_vlan_control_set(unit, bcmVlanTranslate, TRUE); 725 BCM_PBMP_CLEAR(ubm); 726 flex_p->ipmc_next_vlan = VLAN + SOC_MAX_NUM_PORTS + 10; 727 flex_p->ipmc_next_drop_vlan = DROP_VLAN; 728 729 (void) bcm_switch_control_set(unit, bcmSwitchL3EgressMode, TRUE); 730 PBMP_ITER(flex_p->ipmc_pbmp, port) { 731 (void) bcm_port_control_set(unit, port, bcmPortControlIP4, TRUE); 732 (void) bcm_port_control_set(unit, port, bcmPortControlIP6, TRUE); 733 (void) bcm_port_control_set(unit, port, bcmSwitchL3McIdxRetType, TRUE); 734 (void) bcm_port_control_set(unit, port, 735 bcmSwitchIpmcReplicationSharing, TRUE); 736 } 737 738 bcm_ipmc_enable(unit, TRUE); 739 mc_group = (bcm_multicast_t)(FIRST_MC_GROUP); 740 mc_flags = BCM_MULTICAST_TYPE_L3 | BCM_MULTICAST_WITH_ID; 741 intf_id = (bcm_if_t)(FIRST_INTF_ID); 742 flex_p->ipmc_next_intf_id = (uint32) intf_id; 743 ipmc_flags |= BCM_IPMC_SOURCE_PORT_NOCHECK; 744 745 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 746 (void) bcm_multicast_create(unit, mc_flags, &mc_group); 747 flex_p->ipmc_stream_mc_group[i] = mc_group; 748 749 /* create drop_vlan */ 750 drop_vlan = (bcm_vlan_t) flex_p->ipmc_next_drop_vlan++; 751 bcm_vlan_create(unit, drop_vlan); 752 flex_p->ipmc_drop_vlan[i] = (uint32) drop_vlan; 753 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 754 "\nstream = %0d, mc_group = 0x%0x, drop_vlan = %0d\n"), 755 i, mc_group, (uint32) drop_vlan)); 756 757 /* vlan_0 for P0 */ 758 vlan = (bcm_vlan_t) flex_p->ipmc_next_vlan++; 759 bcm_vlan_create(unit, vlan); 760 BCM_PBMP_CLEAR(pbm); 761 port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]]; 762 BCM_PBMP_PORT_ADD(pbm, port); 763 bcm_vlan_port_add(unit, vlan, pbm, ubm); 764 vlan_0 = vlan; 765 766 port_vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]++; 767 flex_p->ipmc_port_rep_vlan[port][port_vlan_cnt] = (uint32) vlan; 768 769 /* vlan_1 for ports receiving l2 copies, P0,P1,...,Pn */ 770 vlan = (bcm_vlan_t) flex_p->ipmc_next_vlan++; 771 bcm_vlan_create(unit, vlan); 772 BCM_PBMP_CLEAR(pbm); 773 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 774 port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][j]]; 775 if (flex_p->ipmc_port_l3_copy_en[port] == 0) { 776 BCM_PBMP_PORT_ADD(pbm, port); 777 778 port_vlan_cnt = flex_p->ipmc_port_vlan_cnt[port]++; 779 flex_p->ipmc_port_rep_vlan[port][port_vlan_cnt] = (uint32) vlan; 780 781 BCM_GPORT_LOCAL_SET(gport, port); 782 bcm_multicast_egress_add(unit, mc_group, gport,(bcm_if_t)(-1)); 783 } 784 } 785 bcm_vlan_port_add(unit, vlan, pbm, ubm); 786 vlan_1 = vlan; 787 788 /* vlan_xlate: P0: vlan_0 -> vlan_1 */ 789 port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]]; 790 bcm_vlan_translate_add(unit, port, vlan_0, vlan_1, 0); 791 792 for (j = 1; j < flex_p->num_ports_per_stream; j++) { 793 port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][j]]; 794 if (flex_p->ipmc_port_l3_copy_en[port] == 0) { 795 dst_vlan = (j == 1 ) ? vlan_0 : drop_vlan; 796 bcm_vlan_translate_add(unit, port, vlan_1, dst_vlan, 0); 797 } 798 } 799 800 /* [L3 copy] */ 801 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 802 if (flexport_is_ipmc_port(unit, port)) { 803 if (port == flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]] || 804 port == flex_p->ipmc_port_list[flex_p->ipmc_stream[i][1]]) 805 continue; 806 for (k = 0; k < (flex_p->ipmc_num_rep[port] + 1); k++) { 807 flexport_ipmc_add_l3_intf(unit, port, mc_group, drop_vlan); 808 } 809 } 810 } 811 812 bcm_ipmc_addr_t_init(&ipmc_addr); 813 ipmc_addr.mc_ip_addr = DIP; 814 ipmc_addr.s_ip_addr = SIP; 815 ipmc_addr.vid = vlan_1; 816 ipmc_addr.group = mc_group; 817 ipmc_addr.flags = ipmc_flags; 818 bcm_ipmc_add(unit, &ipmc_addr); 819 mc_group++; 820 821 flex_p->ipmc_tx_vlan[i] = (uint32) vlan_0; 822 flex_p->ipmc_exp_vlan[i] = (uint32) vlan_1; 823 sal_memcpy(flex_p->ipmc_exp_mac_addr[i], mac_sa, 6); 824 825 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 826 "\nstream=%0d, tx_vlan = %0d, rx_vlan = %0d\n"), 827 i, flex_p->ipmc_tx_vlan[i], flex_p->ipmc_exp_vlan[i])); 828 } 829 830 /* print vlan info */ 831 flexport_ipmc_print_vlan_info(unit); 832 } 833 834 /* 835 * Function: 836 * flexport_get_port_pkt_size 837 * Purpose: 838 * Get the packet size of given port. 839 * Parameters: 840 * unit: StrataSwitch Unit #. 841 * port - Device port number 842 * 843 * Returns: 844 * Port packet size. 845 */ 846 static uint32 847 flexport_get_port_pkt_size(int unit, int port) 848 { 849 uint32 pkt_size; 850 flexport_mc_t *flex_p = flexport_parray[unit]; 851 852 if (flex_p->pkt_size_param == 0) { 853 pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port)); 854 } else { 855 pkt_size = flex_p->pkt_size_param; 856 } 857 858 return (pkt_size); 859 } 860 861 /* 862 * Function: 863 * flexport_get_lossless_flood_cnt 864 * Purpose: 865 * Calculates no of packets to be set for the given port 866 * Parameters: 867 * unit: StrataSwitch Unit #. 868 * port - Device port number 869 * 870 * Returns: 871 * flood packet count for the given port. 872 */ 873 static uint32 874 flexport_get_lossless_flood_cnt(int unit, int port) 875 { 876 uint32 pkt_size, flood_cnt = 0; 877 flexport_mc_t *flex_p = flexport_parray[unit]; 878 879 if (flex_p->flood_pkt_cnt_param == 0) { 880 pkt_size = flexport_get_port_pkt_size(unit, port); 881 flood_cnt = stream_get_ll_flood_cnt(unit, port, pkt_size, NULL); 882 } else { 883 flood_cnt = flex_p->flood_pkt_cnt_param; 884 } 885 886 if (flood_cnt > MAX_PKTS_PER_STREAM) { 887 flood_cnt = MAX_PKTS_PER_STREAM; 888 } 889 890 return (flood_cnt); 891 } 892 893 /* 894 * Function: 895 * flexport_ipmc_send_pkts 896 * Purpose: 897 * Send packets from CPU to create a swirl on each stream. Please refer 898 * to item 6 of the "Test Setup" portion of the test description at the 899 * beginning of this file. 900 * Parameters: 901 * unit - StrataSwitch Unit #. 902 * 903 * Returns: 904 * Nothing 905 */ 906 static void 907 flexport_ipmc_send_pkts(int unit) 908 { 909 uint8 mac_da[] = MAC_DA; 910 uint8 mac_sa[] = MAC_SA; 911 uint32 pkt_size = 0, pkt_count = 0, flood_cnt = 0; 912 int i, port; 913 uint32 use_random_packet_sizes = 0; 914 flexport_mc_t *flex_p = flexport_parray[unit]; 915 stream_pkt_t *tx_pkt; 916 917 tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt"); 918 sal_memset(tx_pkt, 0, sizeof(stream_pkt_t)); 919 920 if (flex_p->pkt_size_param == 1) { 921 use_random_packet_sizes = 1; 922 } 923 924 cli_out("\n==================================================\n"); 925 cli_out("\nSending packets ...\n\n"); 926 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 927 port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]]; 928 flood_cnt = flexport_get_lossless_flood_cnt(unit, port); 929 pkt_size = (flex_p->pkt_size_param == 0) ? 930 ENET_WC_PKT_SIZE : flex_p->pkt_size_param; 931 932 tx_pkt->l3_en = 1; 933 tx_pkt->ipv6_en = 0; 934 tx_pkt->ip_da = DIP; 935 tx_pkt->ip_sa = SIP; 936 tx_pkt->ttl = TTL; 937 tx_pkt->port = port; 938 tx_pkt->num_pkt = flood_cnt; 939 tx_pkt->pkt_seed = flex_p->pkt_seed + i; 940 tx_pkt->pkt_size = pkt_size; 941 tx_pkt->tx_vlan = flex_p->ipmc_tx_vlan[i]; 942 sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR); 943 sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR); 944 tx_pkt->rand_pkt_size_en = use_random_packet_sizes; 945 tx_pkt->rand_pkt_size = NULL; 946 if (tx_pkt->rand_pkt_size_en) { 947 tx_pkt->rand_pkt_size = flex_p->ipmc_rand_pkt_sizes; 948 } 949 950 stream_tx_pkt(unit, tx_pkt); 951 952 pkt_count += tx_pkt->cnt_pkt; 953 cli_out("flood_cnt for stream %0d = %0d\n", i, tx_pkt->cnt_pkt); 954 } 955 956 cli_out("\nTotal packet sent: %0d\n\n", pkt_count); 957 sal_free(tx_pkt); 958 } 959 960 /* 961 * Function: 962 * flexport_ipmc_chk_rate 963 * Purpose: 964 * Check actual port rates against expected port rates. 965 * Parameters: 966 * unit - StrataSwitch Unit #. 967 * 968 * Returns: 969 * SOC_E_XXXX 970 */ 971 static bcm_error_t 972 flexport_ipmc_chk_rate(int unit) 973 { 974 int i, j, port, port_idx; 975 bcm_error_t rv = BCM_E_NONE; 976 stream_rate_t *rate_calc; 977 flexport_mc_t *flex_p = flexport_parray[unit]; 978 979 /* check mib counters */ 980 if (flex_p->check_mib_param == 1) { 981 if (stream_chk_mib_counters(unit, flex_p->ipmc_pbmp, 0) != BCM_E_NONE) { 982 flex_p->test_fail = 1; 983 } 984 } 985 986 /* check rate */ 987 if(!flex_p->check_rate_param) return rv; 988 rate_calc = (stream_rate_t *) 989 sal_alloc(sizeof(stream_rate_t), "rate_calc"); 990 if (rate_calc == NULL) { 991 test_error(unit, "Failed to allocate memory for rate_calc\n"); 992 return BCM_E_FAIL; 993 } 994 sal_memset(rate_calc, 0, sizeof(stream_rate_t)); 995 996 rate_calc->mode = 1; 997 rate_calc->pkt_size = flex_p->pkt_size_param; 998 rate_calc->interval_len = flex_p->rate_calc_interval_param; 999 rate_calc->tolerance_lr = flex_p->rate_tolerance_lr_param; 1000 rate_calc->tolerance_os = flex_p->rate_tolerance_os_param; 1001 1002 SOC_PBMP_CLEAR(rate_calc->pbmp); 1003 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 1004 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 1005 port_idx = flex_p->ipmc_stream[i][j]; 1006 port = flex_p->ipmc_port_list[port_idx]; 1007 if (port < SOC_MAX_NUM_PORTS && port < TEST_COVERITY_PBMP_WID) { 1008 if (flex_p->ipmc_port_l3_copy_en[port] == -1) continue; 1009 /* pbmp */ 1010 SOC_PBMP_PORT_ADD((rate_calc->pbmp), port); 1011 /* num_l3_rep */ 1012 if (flex_p->ipmc_port_l3_copy_en[port] == 0) { 1013 rate_calc->num_rep[port] = 0; 1014 } else { 1015 rate_calc->num_rep[port] = flex_p->ipmc_num_rep[port] + 1; 1016 } 1017 /* src_port */ 1018 rate_calc->src_port[port] = 1019 flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]]; 1020 } 1021 } 1022 } 1023 1024 rv = stream_chk_port_rate(unit, flex_p->ipmc_pbmp, rate_calc); 1025 if (rv != BCM_E_NONE) flex_p->test_fail = 1; 1026 1027 sal_free(rate_calc); 1028 return rv; 1029 } 1030 1031 /* 1032 * Function: 1033 * flexport_ipmc_chk_integrity_l3 1034 * Purpose: 1035 * Redirect all packets back to CPU and check packet integrity 1036 * Parameters: 1037 * unit - StrataSwitch Unit #. 1038 * pkt_intg - ptr to packet integrity struct, containing all necessary 1039 * parameters needed for integrity check. 1040 * 1041 * Returns: 1042 * SOC_E_XXXX 1043 */ 1044 static bcm_error_t 1045 flexport_ipmc_chk_integrity_l3(int unit, stream_integrity_t *pkt_intg) 1046 { 1047 bcm_error_t rv = BCM_E_NONE; 1048 uint8 *rx_pkt, *ref_pkt; 1049 int i, j, k, port, port_speed, chk_fail = 0, stream_cnt = 0; 1050 int rst_vlan; 1051 dv_t *dv_rx; 1052 uint32 vlan; 1053 uint32 pkt_size; 1054 uint32 port_exp_pkt_cnt, port_act_pkt_cnt, pkt_cnt_sum = 0; 1055 uint32 header_size = 0; 1056 uint32 rx_vlan; 1057 flexport_mc_t *flex_p = flexport_parray[unit]; 1058 1059 cli_out("\n==================================================\n"); 1060 cli_out("IPMC Checking Packet Integrity ...\n\n"); 1061 /* initialize */ 1062 soc_dma_header_size_get(unit, &header_size); 1063 1064 dv_rx = soc_dma_dv_alloc(unit, DV_RX, 3); 1065 ref_pkt = sal_dma_alloc(MTU * sizeof(uint8), "ref_packet"); 1066 rx_pkt = sal_dma_alloc(MTU * sizeof(uint8) + header_size, "rx_pkt"); 1067 if (dv_rx == NULL || ref_pkt == NULL || rx_pkt == NULL) { 1068 soc_dma_dv_free(unit, dv_rx); 1069 sal_dma_free(ref_pkt); 1070 sal_dma_free(rx_pkt); 1071 test_error(unit, "Failed to allocate memory for integrity check\n"); 1072 return BCM_E_FAIL; 1073 } 1074 1075 /* config all channels as RX */ 1076 soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 1, 0xffffffff); 1077 soc_dma_chan_cos_ctrl_set(unit, RX_CHAN, 2, 0xffffffff); 1078 1079 /* config unmatched VLAN packet to be forwarded to CPU */ 1080 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_0r, 0, 1081 UVLAN_TOCPUf, 0x1)); 1082 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPU_CONTROL_1r, 0, 1083 L3_MTU_FAIL_TOCPUf, 0x1)); 1084 1085 /* check packet integrity for each port */ 1086 LOG_INFO(BSL_LS_APPL_TESTS, 1087 (BSL_META_U(unit, "%4s %4s %4s %8s %8s\n"), 1088 "idx", "port", "spd", "tx_pkt", "rx_pkt")); 1089 PBMP_ITER(pkt_intg->rx_pbmp, port) { 1090 if (port < SOC_MAX_NUM_PORTS) { 1091 /* check integrity of each packet */ 1092 port_exp_pkt_cnt = pkt_intg->port_flood_cnt[port]; 1093 port_act_pkt_cnt = 0; 1094 vlan = pkt_intg->rx_vlan[port]; 1095 1096 for (j = 0; j < port_exp_pkt_cnt; j++) { 1097 rst_vlan = 0; 1098 if (j == 0) { 1099 if (pkt_intg->type == PKT_TYPE_L3UC) { 1100 rst_vlan = 2; /* L3 packet*/ 1101 } else { 1102 rst_vlan = 1; /* L2 packet*/ 1103 } 1104 } 1105 /* receive one packet from CPU though rx_pkt_dma */ 1106 if (stream_pktdma_rx(unit, rst_vlan, vlan, dv_rx, rx_pkt, 1107 MTU + header_size) != BCM_E_NONE) { 1108 break; 1109 } 1110 port_act_pkt_cnt ++; 1111 1112 /* record rx_vlan */ 1113 rx_vlan = (rx_pkt[14+header_size] << 8) + 1114 rx_pkt[15+header_size]; 1115 flex_p->ipmc_cpu_rx_vlan_cnt[rx_vlan]++; 1116 1117 /* generate reference packet */ 1118 if (stream_gen_ref_pkt(unit, port, pkt_intg, rx_pkt, ref_pkt, 1119 &pkt_size) != BCM_E_NONE) { 1120 cli_out("*ERROR, failed to generate ref_pkt " 1121 "for integrity check, port %d\n", 1122 port); 1123 chk_fail = 1; 1124 break; 1125 } 1126 1127 /* check packet content (payload) */ 1128 for (k = 0; k < (pkt_size - NUM_BYTES_CRC); k++) { 1129 if (rx_pkt[k + header_size] != ref_pkt[k]) { 1130 /* mac_sa and vlan are used for rep identification */ 1131 if (( 6 <= k && k <= 11) || /* mac_sa */ 1132 (14 <= k && k <= 15)) /* vlan */ 1133 continue; 1134 1135 cli_out("*ERROR: Packet corruption, " 1136 "Stream %d, Port %3d, Packet %d, " 1137 "pkt_size=%0d, header_size=%0d, k=%0d, " 1138 "rx_pkt[%0d]=0x%0x, ref_pkt[%0d]=0x%0x\n", 1139 stream_cnt, port, j, 1140 pkt_size, header_size, k, 1141 k + header_size, rx_pkt[k + header_size], 1142 k, ref_pkt[k]); 1143 1144 cli_out("-- Expected Packet:"); 1145 tgp_print_pkt(ref_pkt, pkt_size); 1146 cli_out("-- Received Packet:"); 1147 tgp_print_pkt(rx_pkt, pkt_size+header_size); 1148 1149 chk_fail = 1; 1150 break; 1151 } 1152 } 1153 } 1154 1155 /* disable forwarding pkt to cpu for current port */ 1156 if (pkt_intg->type == PKT_TYPE_L3UC) { 1157 stream_set_l3mtu_valid(unit, vlan); 1158 } else { 1159 stream_set_vlan_valid(unit, vlan); 1160 } 1161 1162 /* check packet count */ 1163 bcm_port_speed_get(unit, port, &port_speed); 1164 LOG_INFO(BSL_LS_APPL_TESTS, 1165 (BSL_META_U(unit, "%4d %4d %3dG %8d %8d "), 1166 stream_cnt, port, port_speed/1000, 1167 port_exp_pkt_cnt, port_act_pkt_cnt)); 1168 if (port_act_pkt_cnt == 0) { 1169 chk_fail = 1; 1170 LOG_INFO(BSL_LS_APPL_TESTS, 1171 (BSL_META_U(unit, "*WARNING"))); 1172 } else if (port_act_pkt_cnt < port_exp_pkt_cnt && 1173 !(SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port))) { 1174 chk_fail = 1; 1175 LOG_INFO(BSL_LS_APPL_TESTS, 1176 (BSL_META_U(unit, "*WARNING"))); 1177 } 1178 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 1179 1180 pkt_cnt_sum += port_act_pkt_cnt; 1181 stream_cnt++; 1182 } 1183 } 1184 1185 /* check l3 copy: at least one pkt of each l3 replication is received. */ 1186 { 1187 int vlan_num, port_idx, pkt_cnt, k; 1188 LOG_INFO(BSL_LS_APPL_TESTS, 1189 (BSL_META_U(unit, "Check Port L3 Replication Reception\n"))); 1190 LOG_INFO(BSL_LS_APPL_TESTS, 1191 (BSL_META_U(unit, "%4s %4s %6s %8s\n"), 1192 "port", "rep", "vlan", "pkt_cnt")); 1193 1194 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 1195 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 1196 port_idx = flex_p->ipmc_stream[i][j]; 1197 port = flex_p->ipmc_port_list[port_idx]; 1198 if (flex_p->ipmc_port_l3_copy_en[port] != 1) continue; 1199 1200 for (k = 0; k < flex_p->ipmc_port_vlan_cnt[port]; k++){ 1201 vlan_num= flex_p->ipmc_port_rep_vlan[port][k]; 1202 pkt_cnt = flex_p->ipmc_cpu_rx_vlan_cnt[vlan_num]; 1203 LOG_INFO(BSL_LS_APPL_TESTS, 1204 (BSL_META_U(unit, "%4d %4d %4d %4d"), 1205 port, k, vlan_num, pkt_cnt)); 1206 if (flex_p->ipmc_cpu_rx_vlan_cnt[vlan_num] == 0) { 1207 chk_fail = 1; 1208 LOG_INFO(BSL_LS_APPL_TESTS, 1209 (BSL_META_U(unit, 1210 "\t*ERROR, no l3 packet received"))); 1211 } 1212 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "\n"))); 1213 } 1214 } 1215 } 1216 } 1217 1218 cli_out("Total packets received: %d\n", pkt_cnt_sum); 1219 if (chk_fail == 0) { 1220 cli_out("\n**** PACKET INTEGRITY CHECK PASSED *****\n"); 1221 } else { 1222 cli_out("\n**** PACKET INTEGRITY CHECK FAILED *****\n"); 1223 rv = BCM_E_FAIL; 1224 } 1225 1226 soc_dma_abort_dv(unit, dv_rx); 1227 soc_dma_dv_free(unit, dv_rx); 1228 sal_dma_free(rx_pkt); 1229 sal_dma_free(ref_pkt); 1230 1231 return rv; 1232 } 1233 1234 /* 1235 * Function: 1236 * flexport_ipmc_chk_integrity 1237 * Purpose: 1238 * Redirect all packets back to CPU and check packet integrity 1239 * Parameters: 1240 * unit - StrataSwitch Unit #. 1241 * 1242 * Returns: 1243 * Nothing 1244 */ 1245 static bcm_error_t 1246 flexport_ipmc_chk_integrity(int unit) 1247 { 1248 int i, port; 1249 uint32 flood_cnt; 1250 uint8 mac_da[] = MAC_DA; 1251 stream_integrity_t *pkt_intg; 1252 bcm_error_t rv = BCM_E_NONE; 1253 flexport_mc_t *flex_p = flexport_parray[unit]; 1254 1255 if (!flex_p->check_integrity_param) return rv; 1256 1257 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt_intg"); 1258 if (pkt_intg == NULL) { 1259 test_error(unit, "Failed to allocate memory for pkt_intg\n"); 1260 return BCM_E_FAIL; 1261 } 1262 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 1263 1264 pkt_intg->type = PKT_TYPE_IPMC; 1265 pkt_intg->ipv6_en = 0; 1266 SOC_PBMP_CLEAR(pkt_intg->rx_pbmp); 1267 for (i = 0; i < flex_p->ipmc_num_streams; i++) { 1268 port = flex_p->ipmc_port_list[flex_p->ipmc_stream[i][0]]; 1269 if (port < SOC_MAX_NUM_PORTS && port < TEST_COVERITY_PBMP_WID) { 1270 /* rx_pbmp */ 1271 SOC_PBMP_PORT_ADD(pkt_intg->rx_pbmp, port); 1272 1273 /* rx_vlan: used to forward pkt to CPU */ 1274 pkt_intg->rx_vlan[port] = flex_p->ipmc_drop_vlan[i]; 1275 1276 /* tx_vlan: used to re-generate ref_pkt */ 1277 pkt_intg->tx_vlan[port] = flex_p->ipmc_exp_vlan[i]; 1278 1279 /* port_flood_cnt */ 1280 /* flood_cnt = flexport_get_lossless_flood_cnt(unit, port); */ 1281 flood_cnt = flex_p->num_ports_per_stream * 1282 flex_p->ipmc_num_l3_ports_param * 30; 1283 pkt_intg->port_flood_cnt[port] = flood_cnt; 1284 1285 /* port_pkt_seed */ 1286 pkt_intg->port_pkt_seed[port] = flex_p->pkt_seed + i; 1287 1288 /* mac_da, mac_sa */ 1289 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR); 1290 sal_memcpy(pkt_intg->mac_sa[port], flex_p->ipmc_exp_mac_addr[i], 1291 NUM_BYTES_MAC_ADDR); 1292 1293 /* ip_da, ip_sa */ 1294 pkt_intg->ip_da[port] = DIP; 1295 pkt_intg->ip_sa[port] = SIP; 1296 } 1297 } 1298 1299 if (flexport_ipmc_chk_integrity_l3(unit, pkt_intg) != BCM_E_NONE) { 1300 flex_p->test_fail = 1; 1301 rv = BCM_E_FAIL; 1302 } 1303 1304 sal_free(pkt_intg); 1305 return rv; 1306 } 1307 1308 /* 1309 * Function: 1310 * flexport_call_bcm_api 1311 * Purpose: 1312 * Call the bcm_port_resource_multi_set API 1313 * Parameters: 1314 * unit - StrataSwitch Unit #. 1315 * 1316 * Returns: 1317 * SOC_E_XXXX 1318 */ 1319 static bcm_error_t 1320 flexport_call_bcm_api(int unit) 1321 { 1322 flexport_mc_t *flex_p = flexport_parray[unit]; 1323 int i; 1324 bcm_port_t lport; 1325 uint32 nports; 1326 bcm_port_resource_t *resource; 1327 bcm_error_t rv; 1328 1329 nports = flex_p->flex_num_del + flex_p->flex_num_add; 1330 resource = (bcm_port_resource_t *) sal_alloc(nports * 1331 sizeof(bcm_port_resource_t), 1332 "flexport_resource_array"); 1333 sal_memset(resource, 0, sizeof(bcm_port_resource_t)); 1334 1335 for (i = 0; i < flex_p->flex_num_del; i ++) { 1336 resource[i] = flex_p->flex_resource_del[i]; 1337 } 1338 for (i = 0; i < flex_p->flex_num_add; i ++) { 1339 resource[flex_p->flex_num_del + i] = flex_p->flex_resource_add[i]; 1340 } 1341 1342 PBMP_ITER(flex_p->flex_lport_dn_pbmp, lport) { 1343 if (lport < SOC_MAX_NUM_PORTS) { 1344 rv = bcm_port_enable_set(unit, lport, 0); 1345 if (BCM_FAILURE(rv)) { 1346 cli_out("\nbcm_port_disable_set %0d: %s", 1347 lport, bcm_errmsg(rv)); 1348 sal_free(resource); 1349 return rv; 1350 } 1351 } 1352 } 1353 1354 LOG_INFO(BSL_LS_APPL_TESTS, 1355 (BSL_META_U(unit, "\nCalling bcm_port_resource_multi:"))); 1356 for (i = 0; i < nports; i ++) { 1357 LOG_INFO(BSL_LS_APPL_TESTS, 1358 (BSL_META_U(unit, "\nresource[%3d]: pport = %3d, "), 1359 i, resource[i].physical_port)); 1360 LOG_INFO(BSL_LS_APPL_TESTS, 1361 (BSL_META_U(unit, "lport = %3d, "), 1362 resource[i].port)); 1363 LOG_INFO(BSL_LS_APPL_TESTS, 1364 (BSL_META_U(unit, "speed = %3dG, "), 1365 resource[i].speed/1000)); 1366 LOG_INFO(BSL_LS_APPL_TESTS, 1367 (BSL_META_U(unit, "lanes = %0d, "), 1368 resource[i].lanes)); 1369 LOG_INFO(BSL_LS_APPL_TESTS, 1370 (BSL_META_U(unit, "encap = %0d"), 1371 resource[i].encap)); 1372 } 1373 rv = bcm_port_resource_multi_set(unit, nports, resource); 1374 if (BCM_FAILURE(rv)) { 1375 cli_out("\nbcm_port_resource_multi_set: %s", bcm_errmsg(rv)); 1376 sal_free(resource); 1377 return rv; 1378 } 1379 1380 cli_out("\nWait 20s for TSC configuration changes to take effect\n"); 1381 sal_sleep(20); 1382 1383 PBMP_ITER(flex_p->flex_lport_up_pbmp, lport) { 1384 if (lport < SOC_MAX_NUM_PORTS) { 1385 rv = bcm_port_enable_set(unit, lport, 1); 1386 if (BCM_FAILURE(rv)) { 1387 cli_out("\nbcm_port_enable_set %0d: %s", lport, bcm_errmsg(rv)); 1388 sal_free(resource); 1389 return rv; 1390 } 1391 } 1392 } 1393 1394 sal_free(resource); 1395 1396 return BCM_E_NONE; 1397 } 1398 1399 1400 /* 1401 * Function: 1402 * flexport_ipmc_update_stream 1403 * Purpose: 1404 * This function actually sets up the IPMC packet flow. Please refer to 1405 * items 4-6 of the "Test Setup" section of the test description at the 1406 * beginning of this file. 1407 * Parameters: 1408 * unit: StrataSwitch Unit #. 1409 * 1410 * Returns: 1411 * Nothing. 1412 */ 1413 static void 1414 flexport_ipmc_update_stream(int unit) 1415 { 1416 int i, j, stream_id, port, port_idx, port_exist; 1417 flexport_mc_t *flex_p = flexport_parray[unit]; 1418 1419 stream_id = 0; 1420 PBMP_ITER(flex_p->ipmc_pbmp, port) { 1421 if (SOC_PBMP_MEMBER(flex_p->flex_lport_up_pbmp, port)) { 1422 /* if port exists in stream, continue */ 1423 port_exist = 0; 1424 i = stream_id; 1425 for (j = 0; j < flex_p->num_ports_per_stream; j++) { 1426 if (port == flex_p->ipmc_port_list[flex_p->ipmc_stream[i][j]]) { 1427 port_exist = 1; 1428 break; 1429 } 1430 } 1431 if (port_exist) continue; 1432 1433 /* add port to stream */ 1434 port_exist = 0; 1435 for (j = 0; j < flex_p->ipmc_port_list_size; j++) { 1436 if (port == flex_p->ipmc_port_list[j]) { 1437 port_exist = 1; 1438 break; 1439 } 1440 } 1441 if (port_exist) { 1442 port_idx = j; 1443 } else { 1444 port_idx = flex_p->ipmc_port_list_size++; 1445 flex_p->ipmc_port_list[port_idx] = port; 1446 } 1447 flex_p->ipmc_stream[i][flex_p->num_ports_per_stream++] = port_idx; 1448 flex_p->ipmc_port_l3_copy_en[port] = 1; 1449 1450 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 1451 "[IPMC] add lport %3d to mc stream\n"), port)); 1452 } 1453 } 1454 PBMP_ITER(flex_p->flex_lport_dn_pbmp, port) { 1455 if (flexport_is_ipmc_port(unit, port) && 1456 !SOC_PBMP_MEMBER(flex_p->flex_lport_up_pbmp, port)) { 1457 flex_p->ipmc_port_l3_copy_en[port] = -1; 1458 1459 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 1460 "[IPMC] remove lport %3d from mc stream\n"), port)); 1461 } 1462 } 1463 1464 /* print */ 1465 flexport_ipmc_print_vlan_info(unit); 1466 } 1467 1468 /* 1469 * Function: 1470 * flexport_flex_ports 1471 * Purpose: 1472 * flex ports. 1473 * -- do flex by calling bcm apis. 1474 * -- set test env for up-ports. 1475 * -- send traffic 1476 * -- measure rate 1477 * -- 1478 * -- 1479 * Parameters: 1480 * unit: StrataSwitch Unit #. 1481 * port_pbmp: port bitmap for down ports. 1482 * 1483 * Returns: 1484 * BCM_E_XXXX 1485 */ 1486 static bcm_error_t 1487 flexport_flex_ports(int unit) 1488 { 1489 pbmp_t start_traffic_pbmp; 1490 flexport_mc_t *flex_p = flexport_parray[unit]; 1491 uint64 val64; 1492 int rv = BCM_E_NONE; 1493 1494 /* call bcm apis. */ 1495 if (flex_p->flex_num_del + flex_p->flex_num_add > 0) { 1496 stream_set_lpbk(unit, flex_p->flex_lport_dn_pbmp, 1497 BCM_PORT_LOOPBACK_NONE); 1498 flexport_call_bcm_api(unit); 1499 stream_set_lpbk(unit, flex_p->flex_lport_up_pbmp, 1500 flex_p->loopback_mode_param); 1501 } 1502 1503 /* set test env for up-ports */ 1504 SOC_PBMP_CLEAR(start_traffic_pbmp); 1505 start_traffic_pbmp = flex_p->flex_lport_up_pbmp; 1506 BCM_PBMP_OR(start_traffic_pbmp, flex_p->flex_lport_ch_pbmp); 1507 1508 /* clear counter */ 1509 if (flex_p->clear_new_port_cnt_param) { 1510 COMPILER_64_ZERO(val64); 1511 BCM_IF_ERROR_RETURN(soc_counter_set_by_port(unit, start_traffic_pbmp, 1512 val64)); 1513 } 1514 1515 /* turn off fc for up_ports */ 1516 stream_turn_off_fc(unit, flex_p->flex_lport_up_pbmp); 1517 1518 return rv; 1519 } 1520 1521 /* 1522 * Function: 1523 * flexport_get_tsc_speed_by_mode 1524 * Purpose: 1525 * Get tsc speed list by converting tsc mode from string to int. 1526 * Parameters: 1527 * unit: StrataSwitch Unit #. 1528 * tsc: TSC # 1529 * mode: target port speed/mode 1530 * speed: prt to tsc speed list 1531 * 1532 * Returns: 1533 * BCM_E_XXXX 1534 */ 1535 static bcm_error_t 1536 flexport_get_tsc_speed_by_mode(int unit, uint32 tsc, char *mode, int* speed) 1537 { 1538 int rv = BCM_E_NONE; 1539 int i; 1540 1541 for (i = 0; i < NUM_LANES_PER_TSC; i++) speed[i] = 0; 1542 1543 if (sal_strstr(mode, "4x0G")) { 1544 return rv; 1545 } else if (sal_strstr(mode, "1x100G") || sal_strstr(mode, "1x106G")) { 1546 speed[0] = 100000; 1547 } else if (sal_strstr(mode, "50G+2x25G")) { 1548 speed[0] = 50000; speed[2] = 25000; speed[3] = 25000; 1549 } else if (sal_strstr(mode, "2x25G+50G")) { 1550 speed[0] = 25000; speed[1] = 25000; speed[2] = 50000; 1551 } else if (sal_strstr(mode, "20G+2x10G")) { 1552 speed[0] = 20000; speed[2] = 10000; speed[3] = 10000; 1553 } else if (sal_strstr(mode, "2x10G+20G")) { 1554 speed[0] = 10000; speed[1] = 10000; speed[2] = 20000; 1555 } else if (sal_strstr(mode, "40G+2x10G")) { 1556 speed[0] = 40000; speed[2] = 10000; speed[3] = 10000; 1557 } else if (sal_strstr(mode, "2x10G+40G")) { 1558 speed[0] = 10000; speed[1] = 10000; speed[2] = 40000; 1559 } else if (sal_strstr(mode, "1x50G") || sal_strstr(mode, "1x53G")) { 1560 speed[0] = 50000; 1561 } else if (sal_strstr(mode, "1x40G") || sal_strstr(mode, "1x42G")) { 1562 speed[0] = 40000; 1563 } else if (sal_strstr(mode, "1x25G") || sal_strstr(mode, "1x27G")) { 1564 speed[0] = 25000; 1565 } else if (sal_strstr(mode, "1x20G") || sal_strstr(mode, "1x21G")) { 1566 speed[0] = 20000; 1567 } else if ((sal_strstr(mode, "1x10G") || sal_strstr(mode, "1x11G"))) { 1568 speed[0] = 10000; 1569 } else if (sal_strstr(mode, "2x50G") || sal_strstr(mode, "2x53G")) { 1570 speed[0] = 50000; speed[2] = 50000; 1571 } else if (sal_strstr(mode, "2x40G") || sal_strstr(mode, "2x42G")) { 1572 speed[0] = 40000; speed[2] = 40000; 1573 } else if (sal_strstr(mode, "2x25G") || sal_strstr(mode, "2x27G")) { 1574 speed[0] = 25000; speed[2] = 25000; 1575 } else if (sal_strstr(mode, "2x20G") || sal_strstr(mode, "2x21G")) { 1576 speed[0] = 20000; speed[2] = 20000; 1577 } else if (sal_strstr(mode, "2x10G") || sal_strstr(mode, "2x11G")) { 1578 speed[0] = 10000; speed[2] = 10000; 1579 } else if (sal_strstr(mode, "40G+20G")) { 1580 speed[0] = 40000; speed[2] = 20000; 1581 } else if (sal_strstr(mode, "20G+40G")) { 1582 speed[0] = 20000; speed[2] = 40000; 1583 } else if (sal_strstr(mode, "4x25G") || sal_strstr(mode, "4x27G")) { 1584 speed[0] = 25000; speed[1] = 25000; speed[2] = 25000; speed[3] = 25000; 1585 } else if (sal_strstr(mode, "4x10G") || sal_strstr(mode, "4x11G")) { 1586 speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000; 1587 } else if (sal_strstr(mode, "4x1G")) { 1588 speed[0] = 1000; speed[1] = 1000; speed[2] = 1000; speed[3] = 1000; 1589 } else if (sal_strstr(mode, "10G_25G_mix")) { 1590 int subport_bmp = sal_rand() % 16; 1591 speed[0] = 25000; speed[1] = 25000; speed[2] = 25000; speed[3] = 25000; 1592 if (subport_bmp & 1) speed[0] = 10000; 1593 if (subport_bmp & 2) speed[1] = 10000; 1594 if (subport_bmp & 4) speed[2] = 10000; 1595 if (subport_bmp & 8) speed[3] = 10000; 1596 } else { 1597 test_error(unit, "*ERROR: Mode %s is not supported\n", mode); 1598 } 1599 1600 return rv; 1601 } 1602 1603 /* 1604 * Function: 1605 * flexport_get_tsc_encap_by_mode 1606 * Purpose: 1607 * Get tsc encap (HiGig or Enthernet) by tsc mode. 1608 * Parameters: 1609 * unit: StrataSwitch Unit #. 1610 * tsc: TSC # 1611 * mode: target port speed/mode 1612 * 1613 * Returns: 1614 * BCM_E_XXXX 1615 */ 1616 static bcm_error_t 1617 flexport_get_tsc_encap_by_mode(int unit, uint32 tsc, char *mode, int *encap) 1618 { 1619 int rv = BCM_E_NONE; 1620 int encap_enum = BCM_PORT_ENCAP_IEEE; 1621 1622 if (sal_strstr(mode, "11G") || sal_strstr(mode, "21G") || 1623 sal_strstr(mode, "27G") || sal_strstr(mode, "53G") || 1624 sal_strstr(mode, "42G") || sal_strstr(mode, "106G") || 1625 sal_strstr(mode, "127G")) { 1626 encap_enum = BCM_PORT_ENCAP_HIGIG2; 1627 } else { 1628 encap_enum = BCM_PORT_ENCAP_IEEE; 1629 } 1630 (*encap) = encap_enum; 1631 1632 return rv; 1633 } 1634 1635 /* 1636 * Function: 1637 * flexport_get_speed_lanes 1638 * Purpose: 1639 * Converts hex string to 4-bit binary map 1640 * Parameters: 1641 * unit - StrataSwitch Unit #. 1642 * num_subport: number of subports 1643 * speed: pointer to a port speed array 1644 * lanes: pointer to a lane array 1645 * 1646 * Returns: 1647 * Nothing 1648 */ 1649 static void 1650 flexport_get_speed_lanes(int unit, int num_subport, int *speed, int *lanes) 1651 { 1652 int i; 1653 1654 for (i = 0; i < num_subport; i++) { 1655 switch(speed[i]) { 1656 case 1000 : lanes[i] = 1; break; 1657 case 10000 : lanes[i] = 1; break; 1658 case 20000 : lanes[i] = 2; break; 1659 case 25000 : lanes[i] = 1; break; 1660 case 40000 : lanes[i] = ((i==0) && (speed[2] == 0))? 4 : 2; break; 1661 case 50000 : lanes[i] = 2; break; 1662 case 100000 : lanes[i] = 4; break; 1663 default : lanes[i] = 0; break; 1664 } 1665 } 1666 } 1667 1668 /* 1669 * Function: 1670 * flexport_assign_lport_by_pport 1671 * Purpose: 1672 * Find an available logical port number for given physical up-port. 1673 * Parameters: 1674 * unit - StrataSwitch Unit #. 1675 * pport: physical port number. 1676 * 1677 * Returns: 1678 * Return -1 if there is no available logical port. 1679 * Otherwise return a valid unused logial port number. 1680 */ 1681 static int 1682 flexport_assign_lport_by_pport(int unit, int pport) 1683 { 1684 int lport = -1; 1685 1686 /* Maverick2: mv2 has flexed p2l mapping, 32 lport per halfpipe. */ 1687 if (SOC_IS_MAVERICK2(unit)) { 1688 lport = ((pport >= 1 && pport <= 32) || 1689 (pport >= 41 && pport <= 64)) ? pport : -1; 1690 } 1691 else if (SOC_IS_HELIX5(unit)) { 1692 lport = (pport <= 68) ? (pport) : (-1); 1693 } 1694 /* Trident3: td3 has fixed p2l mapping */ 1695 else if (SOC_IS_TRIDENT3(unit)) { 1696 lport = (pport > 64) ? (2 + pport) : (pport); 1697 } 1698 /* default */ 1699 else { 1700 lport = (pport > 64) ? (2 + pport) : (pport); 1701 } 1702 1703 return lport; 1704 } 1705 1706 /* 1707 * Function: 1708 * flexport_fill_resource_per_tsc 1709 * Purpose: 1710 * Prepare port_dn_pbmp, port_up_pbmp and port_ch_pbmp for one TSC. 1711 * Parameters: 1712 * unit - StrataSwitch Unit #. 1713 * num_subport: number of subports 1714 * first_phy_port: first physical port number of the TSC 1715 * encap: Ethernet or HiGig2 1716 * 1717 * Returns: 1718 * SOC_E_XXXX 1719 */ 1720 static bcm_error_t 1721 flexport_fill_resource_per_tsc(int unit, int num_subport, int first_phy_port, 1722 int *speed, int encap) 1723 { 1724 soc_info_t *si; 1725 flexport_mc_t *flex_p = flexport_parray[unit]; 1726 int i, resource_idx; 1727 int tsc = (num_subport > 0) ? ((first_phy_port - 1) / num_subport) : -1; 1728 int cur_speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1729 int cur_lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1730 int cur_encap = BCM_PORT_ENCAP_IEEE; 1731 int lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1732 int lanes_changed = 0; 1733 bcm_port_t lport, pport; 1734 int rv; 1735 1736 si = &SOC_INFO(unit); 1737 1738 LOG_INFO(BSL_LS_APPL_TESTS, 1739 (BSL_META_U(unit, "\nFlexing TSC_%02d, port[%0d..%0d] to ["), 1740 tsc, first_phy_port, first_phy_port + num_subport - 1)); 1741 for (i = 0; i < num_subport; i++) { 1742 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " %0dG"), speed[i] / 1000)); 1743 } 1744 if (encap == BCM_PORT_ENCAP_IEEE) { 1745 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "] Ethernet"))); 1746 } else if (encap == BCM_PORT_ENCAP_HIGIG2) { 1747 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "] Higig2"))); 1748 } 1749 1750 lport = si->port_p2l_mapping[first_phy_port]; 1751 if (lport != -1 && IS_HG2_ENABLED_PORT(unit, lport)) { 1752 cur_encap = BCM_PORT_ENCAP_HIGIG2; 1753 } 1754 1755 for (i = 0; i < num_subport; i++) { 1756 pport = first_phy_port + i; 1757 lport = si->port_p2l_mapping[pport]; 1758 if (lport != -1) { 1759 rv = bcm_port_speed_get(unit, lport, &cur_speed[i]); 1760 if (BCM_FAILURE(rv) && rv != BCM_E_PORT) { 1761 cli_out("\nbcm_port_speed_get %0d %0d: %s", 1762 lport, rv, bcm_errmsg(rv)); 1763 return rv; 1764 } 1765 } 1766 } 1767 1768 flexport_get_speed_lanes(unit, num_subport, cur_speed, cur_lanes); 1769 flexport_get_speed_lanes(unit, num_subport, speed, lanes); 1770 for (i = 0; i < num_subport; i++) { 1771 if (lanes[i] != cur_lanes[i]) { 1772 lanes_changed = 1; 1773 break; 1774 } 1775 } 1776 1777 if (lanes_changed == 0 && encap == cur_encap && 1778 flex_p->flex_no_spd_ch_param == 0) { 1779 for (i = 0; i < num_subport; i++) { 1780 if (speed[i] != cur_speed[i]) { 1781 pport = first_phy_port + i; 1782 lport = si->port_p2l_mapping[pport]; 1783 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 1784 "\nTSC_%02d, Changing pport %0d, from %0dG to %0dG"), 1785 tsc, pport, cur_speed[i] / 1000, speed[i] / 1000)); 1786 rv = bcm_port_speed_set(unit, lport, speed[i]); 1787 if (BCM_FAILURE(rv) && rv != BCM_E_PORT) { 1788 cli_out("\nbcm_port_speed_set %0d %0d: %s", 1789 lport, speed[i], bcm_errmsg(rv)); 1790 return rv; 1791 } 1792 SOC_PBMP_PORT_ADD(flex_p->flex_lport_ch_pbmp, lport); 1793 } 1794 } 1795 return BCM_E_NONE; 1796 } 1797 1798 for (i = 0; i < num_subport; i++) { 1799 pport = first_phy_port + i; 1800 lport = si->port_p2l_mapping[pport]; 1801 if (lport != -1) { 1802 if (cur_speed[i] > 0 && 1803 (speed[i] != cur_speed[i] || encap != cur_encap || 1804 lanes[i] != cur_lanes[i])) { 1805 LOG_INFO(BSL_LS_APPL_TESTS, 1806 (BSL_META_U(unit, 1807 "\nTSC_%02d, Removing pport %0d, speed %0dG"), 1808 tsc, pport, cur_speed[i] / 1000)); 1809 resource_idx = flex_p->flex_num_del++; 1810 bcm_port_resource_t_init( 1811 &flex_p->flex_resource_del[resource_idx]); 1812 flex_p->flex_resource_del[resource_idx].physical_port = -1; 1813 flex_p->flex_resource_del[resource_idx].port = lport; 1814 SOC_PBMP_PORT_ADD(flex_p->flex_lport_dn_pbmp, lport); 1815 } 1816 } 1817 } 1818 1819 for (i = 0; i < num_subport; i++) { 1820 if (speed[i] > 0 && 1821 (speed[i] != cur_speed[i] || encap != cur_encap || 1822 lanes[i] != cur_lanes[i])) { 1823 pport = first_phy_port + i; 1824 /* lport = (pport > 64) ? (2 + pport) : (pport); */ 1825 lport = flexport_assign_lport_by_pport(unit, pport); 1826 if(lport == -1) { 1827 cli_out("\nERROR : Unable to find valid logical port for" 1828 " physical port %0d", pport); 1829 return BCM_E_INTERNAL; 1830 } 1831 resource_idx = flex_p->flex_num_add++; 1832 bcm_port_resource_t_init( 1833 &flex_p->flex_resource_add[resource_idx]); 1834 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 1835 "\nTSC_%02d, Adding pport %0d, speed %0dG, lane %0d"), 1836 tsc, pport, speed[i] / 1000, lanes[i])); 1837 flex_p->flex_resource_add[resource_idx].physical_port = pport; 1838 flex_p->flex_resource_add[resource_idx].port = lport; 1839 flex_p->flex_resource_add[resource_idx].speed = 1840 stream_get_exact_speed(speed[i], encap); 1841 flex_p->flex_resource_add[resource_idx].lanes = lanes[i]; 1842 flex_p->flex_resource_add[resource_idx].encap = encap; 1843 SOC_PBMP_PORT_ADD(flex_p->flex_lport_up_pbmp, lport); 1844 } 1845 } 1846 1847 return BCM_E_NONE; 1848 } 1849 1850 /* 1851 * Function: 1852 * flexport_cfg_resource_per_tsc 1853 * Purpose: 1854 * Configure resource for one tsc by tsc mode. 1855 * Parameters: 1856 * unit: StrataSwitch Unit #. 1857 * tsc: TSC # 1858 * mode: target port speed/mode 1859 * 1860 * Returns: 1861 * BCM_E_XXXX 1862 */ 1863 static bcm_error_t 1864 flexport_cfg_resource_per_tsc(int unit, uint32 tsc, char *mode) 1865 { 1866 int rv = BCM_E_NONE; 1867 int speed[NUM_LANES_PER_TSC]; 1868 int num_subport = 4; 1869 int encap = BCM_PORT_ENCAP_IEEE; 1870 1871 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 1872 "\nFlexing TSC_%02d to %s"), tsc, mode)); 1873 1874 flexport_get_tsc_speed_by_mode(unit, tsc, mode, speed); 1875 flexport_get_tsc_encap_by_mode(unit, tsc, mode, &encap); 1876 1877 rv = flexport_fill_resource_per_tsc(unit, num_subport, 1878 tsc * NUM_LANES_PER_TSC + 1, 1879 speed, encap); 1880 if (BCM_FAILURE(rv)) { 1881 cli_out("\nflex_tsc %0d: %s", tsc , bcm_errmsg(rv)); 1882 } 1883 1884 return rv; 1885 } 1886 1887 /* 1888 * Function: 1889 * flexport_is_ovsb_cfg 1890 * Purpose: 1891 * Configure resource for flexports. 1892 * Parameters: 1893 * unit: StrataSwitch Unit #. 1894 * 1895 * Returns: 1896 * BCM_E_XXXX 1897 */ 1898 static int 1899 flexport_is_ovsb_cfg(int unit) 1900 { 1901 int is_ovsb = 0; 1902 int port_speed, port; 1903 1904 PBMP_ITER(PBMP_E_ALL(unit), port) { 1905 if ((port < SOC_MAX_NUM_PORTS) && 1906 (flexport_is_ipmc_port(unit, port) || 1907 flexport_is_l3uc_port(unit, port)) ) { 1908 bcm_port_speed_get(unit, port, &port_speed); 1909 if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port) && port_speed > 0) { 1910 is_ovsb = 1; 1911 break; 1912 } 1913 } 1914 } 1915 1916 return is_ovsb; 1917 } 1918 1919 /* 1920 * Function: 1921 * flexport_rand_tsc_mode 1922 * Purpose: 1923 * Randomly select TSCs for flexing. 1924 * Parameters: 1925 * unit: StrataSwitch Unit #. 1926 * min_tsc: lowest tsc number. 1927 * max_tsc: highest tsc number. 1928 * num_req_tsc: number of required tsc. 1929 * tsc_selected: ptr to tsc selected status. 1:selected, 0:available. 1930 * 1931 * Returns: 1932 * BCM_E_XXXX 1933 */ 1934 static void 1935 flexport_rand_tsc_mode(int unit, int min_tsc, int max_tsc, int num_req_tsc, 1936 uint32 *tsc_selected) 1937 { 1938 int tsc_cnt = 0, tsc = 1, num_tsc, num_avail_tsc; 1939 1940 num_avail_tsc = max_tsc - min_tsc + 1; 1941 if (min_tsc >= 0 && min_tsc < MAX_NUM_TSC && 1942 max_tsc >= 0 && max_tsc < MAX_NUM_TSC && 1943 num_avail_tsc > 0 && num_req_tsc > 0) { 1944 num_tsc = (num_req_tsc <= num_avail_tsc) ? num_req_tsc : num_avail_tsc; 1945 for (tsc_cnt = 0; tsc_cnt < num_tsc; tsc_cnt++) { 1946 do { 1947 /* coverity[dont_call : FALSE] */ 1948 tsc = (sal_rand() % num_avail_tsc) + min_tsc; 1949 } while (tsc_selected[tsc % MAX_NUM_TSC]); 1950 tsc_selected[tsc] = 1; 1951 } 1952 } 1953 } 1954 1955 /* 1956 * Function: 1957 * flexport_cfg_test_case 1958 * Purpose: 1959 * Configure resource for flexports. 1960 * Parameters: 1961 * unit: StrataSwitch Unit #. 1962 * 1963 * Returns: 1964 * BCM_E_XXXX 1965 */ 1966 static void 1967 flexport_cfg_test_case(int unit, int case_num) 1968 { 1969 int i; 1970 int tsc_cnt; 1971 uint32 tsc_selected[MAX_NUM_TSC]; 1972 int tsc_lo, tsc_hi, tsc_mid; 1973 int tsc_lo_ipmc = -1, tsc_hi_ipmc = -1; 1974 int tsc_lo_l3uc = -1, tsc_hi_l3uc = -1; 1975 flexport_mc_t *flex_p = flexport_parray[unit]; 1976 1977 for (i = 0; i < MAX_NUM_TSC; i++) flex_p->flex_tsc_mode[i] = NULL; 1978 1979 if (SOC_IS_MAVERICK2(unit)) { 1980 tsc_lo = 0; 1981 tsc_hi = 19; 1982 tsc_mid = (tsc_lo + tsc_hi + 1) / 2; 1983 1984 tsc_lo_ipmc = 0; 1985 tsc_hi_ipmc = 7; 1986 tsc_lo_l3uc = 10; 1987 tsc_hi_l3uc = 14; 1988 } else if (SOC_IS_HELIX5(unit)) { 1989 /* Only test TSCf */ 1990 tsc_lo = 17; 1991 tsc_hi = 19; 1992 tsc_mid = (tsc_lo + tsc_hi + 1) / 2; 1993 } else if (SOC_IS_TRIDENT3X(unit)) { 1994 tsc_lo = 0; 1995 tsc_hi = 31; 1996 tsc_mid = (tsc_lo + tsc_hi + 1) / 2; 1997 tsc_hi = 30; /* ignore the last PM due to 2nd mgmt port */ 1998 } else { 1999 tsc_lo = 0; 2000 tsc_hi = 31; 2001 tsc_mid = (tsc_lo + tsc_hi + 1) / 2; 2002 } 2003 2004 if (tsc_lo_ipmc == -1 || tsc_hi_ipmc == -1 || 2005 tsc_lo_l3uc == -1 || tsc_hi_l3uc == -1) { 2006 if (tsc_lo_ipmc == -1) tsc_lo_ipmc = tsc_lo; 2007 if (tsc_hi_ipmc == -1) tsc_hi_ipmc = tsc_mid - 1; 2008 if (tsc_lo_l3uc == -1) tsc_lo_l3uc = tsc_mid; 2009 if (tsc_hi_l3uc == -1) tsc_hi_l3uc = tsc_hi; 2010 } 2011 2012 if (case_num == 0) { 2013 if (SOC_IS_MAVERICK2(unit)) { 2014 /* Maverick 2 has mixed 10G/25G PM config */ 2015 for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc ; i++) 2016 flex_p->flex_tsc_mode[i] = "10G_25G_mix"; 2017 for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc ; i++) 2018 flex_p->flex_tsc_mode[i] = "10G_25G_mix"; 2019 } 2020 else { 2021 /* oversub */ 2022 if(flexport_is_ovsb_cfg(unit)) { 2023 for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc ; i++) 2024 flex_p->flex_tsc_mode[i] = "4x25G"; 2025 for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc ; i++) 2026 flex_p->flex_tsc_mode[i] = "4x25G"; 2027 } 2028 /* linerate */ 2029 else { 2030 if (tsc_mid > 0) { 2031 for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc ; i++) 2032 flex_p->flex_tsc_mode[i] = ((i % tsc_mid) < 6) ? 2033 "4x25G" : "4x0G"; 2034 for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc ; i++) 2035 flex_p->flex_tsc_mode[i] = ((i % tsc_mid) < 6) ? 2036 "4x25G" : "4x0G"; 2037 } 2038 } 2039 } 2040 2041 if ((!flexport_is_ovsb_cfg(unit)) || 2042 (flexport_is_ovsb_cfg(unit) && SOC_IS_MAVERICK2(unit))) { 2043 for (i = tsc_lo; i <= tsc_hi ; i++) { 2044 if (!((i >= tsc_lo_ipmc && i <= tsc_hi_ipmc) || 2045 (i >= tsc_lo_l3uc && i <= tsc_hi_l3uc))) 2046 flex_p->flex_tsc_mode[i] = "4x0G"; 2047 } 2048 } 2049 } 2050 else if (case_num == 1) { 2051 /* randomly select tsc for flexport */ 2052 sal_memset(tsc_selected, 0, sizeof(uint32) * MAX_NUM_TSC); 2053 flexport_rand_tsc_mode(unit, 1, tsc_hi_ipmc, 6, tsc_selected); 2054 flexport_rand_tsc_mode(unit, tsc_lo_l3uc, tsc_hi_l3uc, 6, tsc_selected); 2055 2056 /* oversub */ 2057 if(flexport_is_ovsb_cfg(unit)) { 2058 /* ipmc */ 2059 tsc_cnt = 0; 2060 for (i = tsc_lo_ipmc; i <= tsc_hi_ipmc; i++) { 2061 if (tsc_selected[i] == 0) continue; 2062 tsc_cnt++; 2063 switch (tsc_cnt) { 2064 case 1: flex_p->flex_tsc_mode[i] = "1x50G"; break; 2065 case 2: flex_p->flex_tsc_mode[i] = "1x100G"; break; 2066 case 3: flex_p->flex_tsc_mode[i] = "2x50G"; break; 2067 case 4: flex_p->flex_tsc_mode[i] = "4x25G"; break; 2068 case 5: flex_p->flex_tsc_mode[i] = "2x40G"; break; 2069 case 6: flex_p->flex_tsc_mode[i] = "1x40G"; break; 2070 default:flex_p->flex_tsc_mode[i] = NULL; break; 2071 } 2072 } 2073 /* l3uc */ 2074 tsc_cnt = 0; 2075 for (i = tsc_lo_l3uc; i <= tsc_hi_l3uc; i++) { 2076 if (tsc_selected[i] == 0 || i == 22) { 2077 flex_p->flex_tsc_mode[i] = "4x0G"; 2078 continue; 2079 } 2080 tsc_cnt++; 2081 switch (tsc_cnt) { 2082 case 1: flex_p->flex_tsc_mode[i] = "1x100G"; break; 2083 case 2: flex_p->flex_tsc_mode[i] = "2x53G"; break; 2084 case 3: flex_p->flex_tsc_mode[i] = "4x25G"; break; 2085 case 4: flex_p->flex_tsc_mode[i] = "4x27G"; break; 2086 case 5: flex_p->flex_tsc_mode[i] = "1x40G"; break; 2087 default:flex_p->flex_tsc_mode[i] = "4x0G"; break; 2088 } 2089 } 2090 } 2091 /* linerate */ 2092 else { 2093 /* ipmc: The 1st tsc is reserved for traffic gen */ 2094 tsc_cnt = 0; 2095 for (i = tsc_lo_ipmc + 1; i <= tsc_hi_ipmc; i++) { 2096 if (tsc_selected[i] == 0) { 2097 flex_p->flex_tsc_mode[i] = "4x0G"; 2098 continue; 2099 } 2100 tsc_cnt++; 2101 switch (tsc_cnt) { 2102 case 1: flex_p->flex_tsc_mode[i] = NULL; break; 2103 case 2: flex_p->flex_tsc_mode[i] = "2x25G+50G"; break; 2104 case 3: flex_p->flex_tsc_mode[i] = "4x0G"; break; 2105 case 4: flex_p->flex_tsc_mode[i] = "2x50G"; break; 2106 case 5: flex_p->flex_tsc_mode[i] = "2x40G"; break; 2107 case 6: flex_p->flex_tsc_mode[i] = "1x50G"; break; 2108 default:flex_p->flex_tsc_mode[i] = "4x0G"; break; 2109 } 2110 } 2111 2112 /* l3uc */ 2113 tsc_cnt = 0; 2114 for (i = tsc_lo_l3uc + 1; i <= tsc_hi_l3uc; i++) { 2115 if (tsc_selected[i] == 0) { 2116 flex_p->flex_tsc_mode[i] = "4x0G"; 2117 continue; 2118 } 2119 tsc_cnt++; 2120 switch (tsc_cnt) { 2121 /* case 1: flex_p->flex_tsc_mode[i] = "4x27G"; break; */ 2122 case 1: flex_p->flex_tsc_mode[i] = "4x25G"; break; 2123 case 2: flex_p->flex_tsc_mode[i] = "50G+2x25G";break; 2124 case 3: flex_p->flex_tsc_mode[i] = "2x40G"; break; 2125 /* case 4: flex_p->flex_tsc_mode[i] = "1x53G"; break; */ 2126 case 4: flex_p->flex_tsc_mode[i] = "1x50G"; break; 2127 case 5: flex_p->flex_tsc_mode[i] = "2x50G"; break; 2128 case 6: flex_p->flex_tsc_mode[i] = "1x40G"; break; 2129 default:flex_p->flex_tsc_mode[i] = "4x0G"; break; 2130 } 2131 } 2132 } 2133 } 2134 2135 /* print */ 2136 cli_out("\nFlexport Config: case_num = %0d\n", case_num); 2137 cli_out("%4s\t%s\n","Tsc ", "TscMode"); 2138 for (i = 0; i < MAX_NUM_TSC; i++) { 2139 if (flex_p->flex_tsc_mode[i] != NULL) 2140 cli_out("%4d, \t%s\n", i, flex_p->flex_tsc_mode[i]); 2141 } 2142 2143 } 2144 2145 /* 2146 * Function: 2147 * flexport_cfg_resource 2148 * Purpose: 2149 * Configure resource for flexports. 2150 * Parameters: 2151 * unit: StrataSwitch Unit #. 2152 * 2153 * Returns: 2154 * BCM_E_XXXX 2155 */ 2156 static bcm_error_t 2157 flexport_cfg_resource(int unit) 2158 { 2159 int i, rv = BCM_E_NONE; 2160 char *mode; 2161 flexport_mc_t *flex_p = flexport_parray[unit]; 2162 2163 /* init */ 2164 flex_p->flex_num_del = 0; 2165 flex_p->flex_num_add = 0; 2166 2167 SOC_PBMP_CLEAR(flex_p->flex_lport_dn_pbmp); 2168 SOC_PBMP_CLEAR(flex_p->flex_lport_up_pbmp); 2169 SOC_PBMP_CLEAR(flex_p->flex_lport_ch_pbmp); 2170 2171 for (i = 0; i < MAX_NUM_TSC; i++) { 2172 mode = flex_p->flex_tsc_mode[i]; 2173 if (mode != NULL) { 2174 BCM_IF_ERROR_RETURN(flexport_cfg_resource_per_tsc(unit, i, mode)); 2175 } 2176 } 2177 2178 /* print */ 2179 flexport_print_ports(unit, flex_p->flex_lport_dn_pbmp, "Down Ports"); 2180 flexport_print_ports(unit, flex_p->flex_lport_up_pbmp, "UP Ports"); 2181 flexport_print_ports(unit, flex_p->flex_lport_ch_pbmp, "Changed Ports"); 2182 2183 return rv; 2184 } 2185 2186 2187 /* 2188 * Function: 2189 * flexport_l3uc_set_port_property 2190 * Purpose: 2191 * Set rand_pkt_sizes, port_oversub, and exp_rates arrays. 2192 * Parameters: 2193 * unit: StrataSwitch Unit #. 2194 * pbmp - Device port bitmap 2195 * pkt_size_param - Packet size in bytes 2196 * max_num_cells_param - Maximum number of cells 2197 * 2198 * Returns: 2199 * BCM_E_XXXX 2200 */ 2201 static bcm_error_t 2202 flexport_l3uc_set_port_property(int unit, pbmp_t pbmp, int pkt_size_param, 2203 int max_num_cells_param) 2204 { 2205 int p, j, pkt_size; 2206 stream_rate_t *stream_rate_calc_p; 2207 flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 2208 flexport_mc_t *flex_p = flexport_parray[unit]; 2209 2210 stream_rate_calc_p = sal_alloc(sizeof(stream_rate_t), "streaming_rate"); 2211 sal_memset(stream_rate_calc_p, 0, sizeof(stream_rate_t)); 2212 2213 stream_rate_calc_p->mode = 0; 2214 stream_rate_calc_p->tolerance_lr = flex_p->rate_tolerance_lr_param; 2215 stream_rate_calc_p->tolerance_os = flex_p->rate_tolerance_os_param; 2216 SOC_PBMP_CLEAR(stream_rate_calc_p->pbmp); 2217 PBMP_ITER(PBMP_E_ALL(unit), p) { 2218 if (p < SOC_MAX_NUM_PORTS && p < TEST_COVERITY_PBMP_WID) { 2219 stream_rate_calc_p->pkt_size = flexport_get_port_pkt_size(unit, p); 2220 SOC_PBMP_PORT_ADD(stream_rate_calc_p->pbmp, p); 2221 } 2222 } 2223 2224 if (SOC_FAILURE(stream_calc_exp_rate_by_rx(unit, rate_calc_p->exp_rate, 2225 stream_rate_calc_p))) { 2226 cli_out("\n*ERROR, stream_calc_exp_rate_by_rx failed.\n"); 2227 sal_free(stream_rate_calc_p); 2228 return BCM_E_FAIL; 2229 } 2230 sal_free(stream_rate_calc_p); 2231 2232 PBMP_ITER(pbmp, p) { 2233 if (p < SOC_MAX_NUM_PORTS) { 2234 for (j = 0; j < TARGET_CELL_COUNT; j++) { 2235 do { 2236 /* coverity[dont_call : FALSE] */ 2237 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + 2238 MIN_PKT_SIZE; 2239 } while (stream_get_pkt_cell_cnt(unit, pkt_size, p) > 2240 max_num_cells_param); 2241 rate_calc_p->rand_pkt_sizes[p][j] = pkt_size; 2242 } 2243 } 2244 } 2245 2246 return BCM_E_NONE; 2247 } 2248 2249 /* 2250 * Function: 2251 * flexport_l3uc_set_up_ports 2252 * Purpose: 2253 * Enable port bridging and HiGig lookup for HG2 ports 2254 * Parameters: 2255 * unit - StrataSwitch Unit #. 2256 * pbmp - Device port bitmap 2257 * 2258 * Returns: 2259 * Nothing 2260 */ 2261 static void 2262 flexport_l3uc_set_up_ports(int unit, pbmp_t pbmp) 2263 { 2264 int i, p; 2265 lport_tab_entry_t lport_tab_entry; 2266 port_tab_entry_t port_tab_entry; 2267 soc_field_t ihg_lookup_fields[] = 2268 { HYBRID_MODE_ENABLEf, USE_MH_PKT_PRIf, USE_MH_VIDf, HG_LOOKUP_ENABLEf, 2269 REMOVE_MH_SRC_PORTf 2270 }; 2271 uint32 ihg_lookup_values[] = { 0x0, 0x1, 0x1, 0x1, 0x0 }; 2272 2273 cli_out("\nEnabling HG_LOOKUP on HG ports"); 2274 2275 PBMP_ITER(pbmp, p) { 2276 if (p < SOC_MAX_NUM_PORTS && IS_HG_PORT(unit, p)) { 2277 soc_reg_fields32_modify(unit, IHG_LOOKUPr, p, 5, 2278 ihg_lookup_fields, ihg_lookup_values); 2279 } 2280 } 2281 2282 cli_out("\nEnabling Port bridging"); 2283 2284 for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) { 2285 (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i, 2286 lport_tab_entry.entry_data); 2287 soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data, 2288 ALLOW_SRC_MODf, 0x1); 2289 soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data, 2290 PORT_BRIDGEf, 0x1); 2291 (void) soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i, 2292 lport_tab_entry.entry_data); 2293 } 2294 2295 for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) { 2296 (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i, 2297 port_tab_entry.entry_data); 2298 soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data, 2299 PORT_BRIDGEf, 0x1); 2300 (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i, 2301 port_tab_entry.entry_data); 2302 } 2303 } 2304 2305 /* 2306 * Function: 2307 * flexport_l3uc_set_up_streams 2308 * Purpose: 2309 * VLAN programming. Each port is put on an unique VLAN. 2310 * Parameters: 2311 * unit: StrataSwitch Unit #. 2312 * pbmp - Device port bitmap 2313 * vlan_bmp - bitmap of device ports that have vlan set up 2314 * 2315 * Returns: 2316 * vlan_pbmp - bitmap of device ports that have vlan set up. 2317 */ 2318 static pbmp_t 2319 flexport_l3uc_set_up_streams(int unit, pbmp_t pbmp, pbmp_t vlan_pbmp) 2320 { 2321 int p; 2322 pbmp_t pbm, ubm; 2323 bcm_vlan_t vlan; 2324 2325 BCM_PBMP_CLEAR(ubm); 2326 2327 PBMP_ITER(pbmp, p) { 2328 if (p < SOC_MAX_NUM_PORTS) { 2329 vlan = VLAN + p; 2330 if (SOC_PBMP_MEMBER(vlan_pbmp, p)) { 2331 stream_set_vlan(unit, vlan, 1); 2332 } else { 2333 BCM_PBMP_CLEAR(pbm); 2334 bcm_vlan_create(unit, vlan); 2335 BCM_PBMP_PORT_ADD(pbm, p); 2336 bcm_vlan_port_add(unit, vlan, pbm, ubm); 2337 } 2338 } 2339 } 2340 2341 SOC_PBMP_OR(vlan_pbmp, pbmp); 2342 2343 return vlan_pbmp; 2344 } 2345 2346 /* 2347 * Function: 2348 * flexport_l3uc_send_pkts 2349 * Purpose: 2350 * Sends packet for all the ports in the port bitmap 2351 * Parameters: 2352 * unit: StrataSwitch Unit #. 2353 * pbmp - port bitmap 2354 * pkt_size_param - 2355 * pkt_seed - 2356 * 2357 * Returns: 2358 * flood packet count for the given port. 2359 */ 2360 static void 2361 flexport_l3uc_send_pkts(int unit, pbmp_t pbmp, uint32 pkt_size_param, 2362 uint32 pkt_seed) 2363 { 2364 int port; 2365 uint8 mac_da[] = MAC_DA; 2366 uint8 mac_sa[] = MAC_SA; 2367 uint32 pkt_size; 2368 stream_pkt_t *tx_pkt; 2369 flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 2370 2371 tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt"); 2372 sal_memset(tx_pkt, 0, sizeof(stream_pkt_t)); 2373 2374 cli_out("\n==================================================\n"); 2375 cli_out("\nSending packets ...\n\n"); 2376 PBMP_ITER(pbmp, port) { 2377 if (port < SOC_MAX_NUM_PORTS) { 2378 /* if (pkt_size_param == 0) { 2379 pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port)); 2380 } else { 2381 pkt_size = pkt_size_param; 2382 } */ 2383 pkt_size = flexport_get_port_pkt_size(unit, port); 2384 2385 tx_pkt->port = port; 2386 tx_pkt->num_pkt = flexport_get_lossless_flood_cnt(unit, port); 2387 tx_pkt->pkt_seed = pkt_seed; 2388 tx_pkt->pkt_size = pkt_size; 2389 cli_out("\nSending packets on port %0d size %0d num %0d.", 2390 port, pkt_size, tx_pkt->num_pkt); 2391 if(pkt_size_param == 1) { 2392 tx_pkt->rand_pkt_size_en = 1; 2393 tx_pkt->rand_pkt_size = rate_calc_p->rand_pkt_sizes[port]; 2394 } else { 2395 tx_pkt->rand_pkt_size_en = 0; 2396 tx_pkt->rand_pkt_size = NULL; 2397 } 2398 tx_pkt->tx_vlan = VLAN + port; 2399 sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR); 2400 sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR); 2401 stream_tx_pkt(unit, tx_pkt); 2402 } 2403 } 2404 sal_free(tx_pkt); 2405 } 2406 2407 /* 2408 * Function: 2409 * flexport_l3uc_start_rate_record 2410 * Purpose: 2411 * Get current time, packet count & byte count needed to calculate port 2412 * rate 2413 * Parameters: 2414 * unit - StrataSwitch Unit #. 2415 * pbmp - Device port bitmap to be used 2416 * emulation_param - 1: test run in emulator platform 2417 * 0: test run is actual hardware(chip) 2418 * 2419 * Returns: 2420 * SOC_E_XXXX 2421 */ 2422 static bcm_error_t 2423 flexport_l3uc_start_rate_record(int unit, pbmp_t pbmp, uint32 emulation_param) 2424 { 2425 flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 2426 2427 return record_rate_information(unit, emulation_param, pbmp, 2428 rate_calc_p->stime, 2429 rate_calc_p->tpkt_start, 2430 rate_calc_p->tbyt_start); 2431 2432 } 2433 2434 2435 /* 2436 * Function: 2437 * flexport_l3uc_chk_rate_run 2438 * Purpose: 2439 * Check rates against expected rates. 2440 * Parameters: 2441 * unit - StrataSwitch Unit #. 2442 * pbmp - Device port bitmap to be checked 2443 * tolerance_lr - Percentage of rate tolerance for line rate ports 2444 * tolerance_os - Percentage of rate tolerance for oversub ports 2445 * 2446 * Returns: 2447 * SOC_E_XXXX 2448 */ 2449 static bcm_error_t 2450 flexport_l3uc_chk_rate_run(int unit, pbmp_t pbmp, uint32 tolerance_lr, 2451 uint32 tolerance_os, uint32 emulation_param) 2452 { 2453 uint64 *etime; 2454 uint64 *tpkt_end; 2455 uint64 *tbyt_end; 2456 uint64 *rate; 2457 flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 2458 bcm_error_t rv = BCM_E_NONE; 2459 2460 etime = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 2461 "etime"); 2462 tpkt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 2463 "tpkt_end"); 2464 tbyt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 2465 "tbyt_end"); 2466 rate = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 2467 "rate"); 2468 2469 sal_memset(etime, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 2470 sal_memset(tpkt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 2471 sal_memset(tbyt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 2472 sal_memset(rate, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 2473 2474 rv = record_rate_information(unit, emulation_param, pbmp, etime, 2475 tpkt_end, tbyt_end); 2476 2477 calc_act_port_rate(unit, pbmp, rate_calc_p->stime, etime, 2478 rate_calc_p->tpkt_start, tpkt_end, 2479 rate_calc_p->tbyt_start, tbyt_end, rate); 2480 2481 rv = compare_rates(unit, pbmp, tolerance_lr, tolerance_os, 2482 rate_calc_p->exp_rate, rate); 2483 2484 if (rv != BCM_E_NONE) { 2485 test_error(unit, "********** [L3UC] RATE CHECK FAILED ***********\n"); 2486 } else { 2487 cli_out("\n********** [L3UC] RATE CHECK PASSED ***********"); 2488 } 2489 2490 sal_free(etime); 2491 sal_free(tpkt_end); 2492 sal_free(tbyt_end); 2493 sal_free(rate); 2494 return rv; 2495 } 2496 2497 /* 2498 * Function: 2499 * flexport_l3uc_chk_counter 2500 * Purpose: 2501 * Check rate for ports in L3UC categories. 2502 * Parameters: 2503 * unit - StrataSwitch Unit #. 2504 * a - Pointer to arguments 2505 * 2506 * Returns: 2507 * SOC_E_XXXX 2508 */ 2509 static void 2510 flexport_l3uc_chk_rate(int unit, pbmp_t pbmp) 2511 { 2512 flexport_mc_t *flex_p = flexport_parray[unit]; 2513 2514 /* check mib counter */ 2515 if (flex_p->check_mib_param == 1) { 2516 if (stream_chk_mib_counters(unit, pbmp, 0) != BCM_E_NONE) { 2517 flex_p->test_fail = 1; 2518 } 2519 } 2520 2521 /* check rate */ 2522 if (flex_p->check_rate_param == 1) { 2523 cli_out("\nWait 2s for traffic to stabilize"); 2524 sal_sleep(2); 2525 /* start rate measurement */ 2526 flexport_l3uc_start_rate_record(unit, pbmp, flex_p->emulation_param); 2527 cli_out("\nMeasuring Rate over a period of %0ds", 2528 flex_p->rate_calc_interval_param); 2529 sal_sleep(flex_p->rate_calc_interval_param); 2530 2531 /* start rate checking */ 2532 if (flexport_l3uc_chk_rate_run(unit, pbmp, 2533 flex_p->rate_tolerance_lr_param, 2534 flex_p->rate_tolerance_os_param, 2535 flex_p->emulation_param) != BCM_E_NONE) { 2536 flex_p->test_fail = 1; 2537 } 2538 } 2539 } 2540 2541 /* 2542 * Function: 2543 * flexport_l3uc_chk_integrity 2544 * Purpose: 2545 * Check integrity for ports in L3UC categories. 2546 * Parameters: 2547 * unit - StrataSwitch Unit #. 2548 * a - Pointer to arguments 2549 * 2550 * Returns: 2551 * SOC_E_XXXX 2552 */ 2553 static void 2554 flexport_l3uc_chk_integrity(int unit, pbmp_t pbmp) 2555 { 2556 int p; 2557 uint8 mac_da[] = MAC_DA; 2558 uint8 mac_sa[] = MAC_SA; 2559 flexport_mc_t *flex_p = flexport_parray[unit]; 2560 stream_integrity_t *pkt_intg; 2561 int rv = BCM_E_NONE; 2562 2563 cli_out("\nWait 2s for traffic to stabilize"); 2564 sal_sleep(2); 2565 2566 /* check integrity */ 2567 if (flex_p->check_integrity_param != 0) { 2568 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity"); 2569 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 2570 2571 pkt_intg->rx_pbmp = pbmp; 2572 PBMP_ITER(pbmp, p) { 2573 if (p < SOC_MAX_NUM_PORTS) { 2574 pkt_intg->port_pkt_seed[p] = flex_p->pkt_seed; 2575 pkt_intg->port_flood_cnt[p] = 2576 flexport_get_lossless_flood_cnt(unit, p); 2577 pkt_intg->rx_vlan[p] = VLAN + p; 2578 pkt_intg->tx_vlan[p] = VLAN + p; 2579 sal_memcpy(pkt_intg->mac_da[p], mac_da, NUM_BYTES_MAC_ADDR); 2580 sal_memcpy(pkt_intg->mac_sa[p], mac_sa, NUM_BYTES_MAC_ADDR); 2581 } 2582 } 2583 2584 rv = stream_chk_pkt_integrity(unit, pkt_intg); 2585 if (rv != BCM_E_NONE) { 2586 flex_p->test_fail = 1; 2587 } 2588 sal_free(pkt_intg); 2589 } 2590 } 2591 2592 /* 2593 * Function: 2594 * flexport_l3uc_update_stream 2595 * Purpose: 2596 * flex ports. 2597 * -- do flex by calling bcm apis. 2598 * -- set test env for up-ports. 2599 * -- send traffic 2600 * -- measure rate 2601 * -- 2602 * -- 2603 * Parameters: 2604 * unit: StrataSwitch Unit #. 2605 * port_pbmp: port bitmap for down ports. 2606 * 2607 * Returns: 2608 * BCM_E_XXXX 2609 */ 2610 static bcm_error_t 2611 flexport_l3uc_update_stream(int unit, pbmp_t pbmp) 2612 { 2613 flexport_mc_t *flex_p = flexport_parray[unit]; 2614 int rv = BCM_E_NONE; 2615 2616 /* set port property: rand_pkt_size */ 2617 flexport_l3uc_set_port_property(unit, pbmp, 2618 flex_p->pkt_size_param, 2619 flex_p->max_num_cells_param); 2620 /* enable port bridging for loopback */ 2621 flexport_l3uc_set_up_ports(unit, flex_p->flex_lport_up_pbmp); 2622 2623 /* set stream */ 2624 flex_p->l3uc_vlan_pbmp = flexport_l3uc_set_up_streams(unit, pbmp, 2625 flex_p->l3uc_vlan_pbmp); 2626 2627 /* send traffic */ 2628 flexport_l3uc_send_pkts(unit, pbmp, flex_p->pkt_size_param, 2629 flex_p->pkt_seed); 2630 2631 return rv; 2632 } 2633 2634 2635 2636 /* 2637 * Function: 2638 * flexport_divide_ports_for_l3uc_ipmc 2639 * Purpose: 2640 * Divide ports into IPMC and L3UC categories. 2641 * Parameters: 2642 * unit: StrataSwitch Unit #. 2643 * 2644 * Returns: 2645 * BCM_E_XXXX 2646 */ 2647 static void 2648 flexport_divide_ports_for_l3uc_ipmc(int unit) 2649 { 2650 int p; 2651 flexport_mc_t *flex_p = flexport_parray[unit]; 2652 2653 cli_out("\nDivide ports into l3uc and ipmc groups\n"); 2654 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, 2655 "SOC_MAX_NUM_PORTS %3d\n"), SOC_MAX_NUM_PORTS)); 2656 BCM_PBMP_CLEAR(flex_p->ipmc_pbmp); 2657 BCM_PBMP_CLEAR(flex_p->l3uc_pbmp); 2658 2659 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 2660 if (flexport_is_ipmc_port(unit, p)) { 2661 BCM_PBMP_PORT_ADD(flex_p->ipmc_pbmp, p); 2662 } else if (flexport_is_l3uc_port(unit, p)) { 2663 BCM_PBMP_PORT_ADD(flex_p->l3uc_pbmp, p); 2664 } 2665 } 2666 2667 /* print */ 2668 flexport_print_ports(unit, flex_p->ipmc_pbmp, 2669 "Ports reserved for IMPC traffic"); 2670 flexport_print_ports(unit, flex_p->l3uc_pbmp, 2671 "Ports reserved for L3UC traffic"); 2672 } 2673 2674 /* 2675 * Function: 2676 * flexport_l3uc_init_env 2677 * Purpose: 2678 * Test init function. Parse CLI params and do necessary init. 2679 * Parameters: 2680 * unit - StrataSwitch Unit #. 2681 * a - Pointer to arguments 2682 * 2683 * Returns: 2684 * SOC_E_XXXX 2685 */ 2686 static int 2687 flexport_l3uc_init_env(int unit, args_t *a, void **pa) 2688 { 2689 flexport_mc_t *flex_p = flexport_parray[unit]; 2690 2691 cli_out("\nCalling flexport_l3uc_init_env"); 2692 2693 /* counter */ 2694 BCM_IF_ERROR_RETURN(soc_counter_status(unit, &flex_p->env_counter_flags, 2695 &flex_p->env_counter_interval, 2696 &flex_p->env_counter_pbm)); 2697 if (flex_p->env_counter_interval > 0) { 2698 cli_out("\nDisabling counter collection"); 2699 soc_counter_stop(unit); 2700 } 2701 2702 /* linkscan */ 2703 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_get(unit, 2704 &flex_p->env_linkscan_enable)); 2705 if (flex_p->env_linkscan_enable) { 2706 cli_out("\nDisabling linkscan"); 2707 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0)); 2708 } 2709 2710 return BCM_E_NONE; 2711 } 2712 2713 /* 2714 * Function: 2715 * flexport_run_flex 2716 * Purpose: 2717 * flex ports. 2718 * -- do flex by calling bcm apis. 2719 * -- set test env for up-ports. 2720 * -- send traffic 2721 * -- measure rate 2722 * -- 2723 * -- 2724 * Parameters: 2725 * unit: StrataSwitch Unit #. 2726 * case_num: flex case number. 0 is reserved for init. 2727 * 2728 * Returns: 2729 * BCM_E_XXXX 2730 */ 2731 static void 2732 flexport_run_flex(int unit, int case_num) 2733 { 2734 pbmp_t pbm; 2735 flexport_mc_t *flex_p = flexport_parray[unit]; 2736 2737 /* config tsc mode for flexports */ 2738 flexport_cfg_test_case(unit, case_num); 2739 2740 /* prepare resource struct for flexports */ 2741 flexport_cfg_resource(unit); 2742 2743 /* cal bcm api to flex ports */ 2744 flexport_flex_ports(unit); 2745 2746 /* print: for non-initial flex, only print up/changed ports */ 2747 if (case_num == 0) { 2748 pbm = PBMP_PORT_ALL(unit); 2749 } else { 2750 pbm = flex_p->flex_lport_up_pbmp; 2751 SOC_PBMP_OR(pbm, flex_p->flex_lport_ch_pbmp); 2752 } 2753 stream_print_port_config(unit, pbm); 2754 } 2755 2756 /* 2757 * Function: 2758 * flexport_td3_test_init 2759 * Purpose: 2760 * Test init function. Parse CLI params and do necessary init. 2761 * Parameters: 2762 * unit - StrataSwitch Unit #. 2763 * 2764 * Returns: 2765 * Nothing 2766 */ 2767 int 2768 flexport_td3_test_init(int unit, args_t *a, void **pa) 2769 { 2770 flexport_mc_t *flex_p; 2771 flexport_l3uc_rate_calc_t *rate_calc_p; 2772 2773 flex_p = flexport_parray[unit]; 2774 flex_p = sal_alloc(sizeof(flexport_mc_t), "ipmc_test"); 2775 sal_memset(flex_p, 0, sizeof(flexport_mc_t)); 2776 flexport_parray[unit] = flex_p; 2777 2778 2779 rate_calc_p = rate_calc_parray[unit]; 2780 rate_calc_p = sal_alloc(sizeof(flexport_l3uc_rate_calc_t), "rac_calc_p"); 2781 sal_memset(rate_calc_p, 0, sizeof(flexport_l3uc_rate_calc_t)); 2782 rate_calc_parray[unit] = rate_calc_p; 2783 2784 2785 stream_print_port_config(unit, PBMP_PORT_ALL(unit)); 2786 cli_out("\n=================================================="); 2787 cli_out("\nCalling flexport_test_init ...\n"); 2788 flexport_parse_test_params(unit, a); 2789 flexport_l3uc_init_env(unit, a, pa); 2790 flexport_set_chip_dependent_params(unit); 2791 2792 flex_p->test_fail = 0; 2793 2794 if (flex_p->bad_input == 1 || 2795 flex_p->test_fail == 1) { 2796 goto done; 2797 } 2798 2799 stream_set_mac_lpbk(unit, PBMP_PORT_ALL(unit)); 2800 stream_turn_off_cmic_mmu_bkp(unit); 2801 stream_turn_off_fc(unit, PBMP_PORT_ALL(unit)); 2802 2803 done: 2804 return 0; 2805 } 2806 2807 /* 2808 * Function: 2809 * flexport_td3_test 2810 * Purpose: 2811 * Set up ports/streams and send packets. 2812 * Parameters: 2813 * unit - StrataSwitch Unit #. 2814 * 2815 * Returns: 2816 * Nothing 2817 */ 2818 int 2819 flexport_td3_test(int unit, args_t *a, void *pa) 2820 { 2821 int p; 2822 pbmp_t pbm; 2823 flexport_mc_t *flex_p = flexport_parray[unit]; 2824 2825 if (flex_p->bad_input == 1 || 2826 flex_p->test_fail == 1) { 2827 goto done; 2828 } 2829 2830 cli_out("\n=================================================="); 2831 cli_out("\nCalling flexport_test ... \n"); 2832 /* init port config */ 2833 flexport_run_flex(unit, 0); 2834 2835 /* divide ports into l3uc usage and impc usage */ 2836 flexport_divide_ports_for_l3uc_ipmc(unit); 2837 2838 /* 1.1 set traffic for ipmc */ 2839 flexport_ipmc_set_port_property(unit); 2840 flexport_ipmc_set_up_streams(unit); 2841 flexport_ipmc_send_pkts(unit); 2842 2843 /* 1.2 set traffic for l3uc */ 2844 flexport_l3uc_update_stream(unit, flex_p->l3uc_pbmp); 2845 2846 /* 1.3 check port rate for l3uc and ipmc */ 2847 flexport_l3uc_chk_rate(unit, flex_p->l3uc_pbmp); 2848 flexport_ipmc_chk_rate(unit); 2849 2850 /* 2 flex port */ 2851 flexport_run_flex(unit, 1); 2852 2853 /* 3.1 update ipmc stream */ 2854 flexport_ipmc_update_stream(unit); 2855 2856 /* 3.2 update l3uc stream*/ 2857 BCM_PBMP_CLEAR(pbm); 2858 PBMP_ITER(flex_p->flex_lport_up_pbmp, p) { 2859 if (flexport_is_l3uc_port(unit, p)) SOC_PBMP_PORT_ADD(pbm, p); 2860 } 2861 PBMP_ITER(flex_p->flex_lport_ch_pbmp, p) { 2862 if (flexport_is_l3uc_port(unit, p)) SOC_PBMP_PORT_ADD(pbm, p); 2863 } 2864 flexport_l3uc_update_stream(unit, pbm); 2865 2866 /* 4.1 check counter, rate, integrity for l3uc */ 2867 flexport_l3uc_chk_rate(unit, pbm); 2868 flexport_l3uc_chk_integrity(unit, pbm); 2869 2870 /* 4.2 check counter, rate, integrity for ipmc */ 2871 flexport_ipmc_chk_rate(unit); 2872 flexport_ipmc_chk_integrity(unit); 2873 2874 2875 done: 2876 return 0; 2877 } 2878 2879 /* 2880 * Function: 2881 * flexport_td3_test_cleanup 2882 * Purpose: 2883 * Do test end checks and free all allocated memory. 2884 * Parameters: 2885 * unit - StrataSwitch Unit #. 2886 * 2887 * Returns: 2888 * Nothing 2889 */ 2890 int 2891 flexport_td3_test_cleanup(int unit, void *pa) 2892 { 2893 int rv; 2894 flexport_mc_t *flex_p = flexport_parray[unit]; 2895 flexport_l3uc_rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 2896 2897 if (flex_p->bad_input == 1) { 2898 flex_p->test_fail = 1; 2899 goto done; 2900 } 2901 cli_out("\nCalling flexport_test_cleanup"); 2902 2903 done: 2904 2905 /* reset env to initial state */ 2906 if (flex_p->env_linkscan_enable) { 2907 cli_out("\nEnabling linkscan"); 2908 BCM_IF_ERROR_RETURN(bcm_linkscan_mode_set_pbm(unit, 2909 PBMP_PORT_ALL(unit), BCM_LINKSCAN_MODE_SW)); 2910 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 1)); 2911 } 2912 if (flex_p->env_counter_interval > 0) { 2913 cli_out("\nEnabling counter collection with interval %0d", 2914 flex_p->env_counter_interval); 2915 BCM_IF_ERROR_RETURN(soc_counter_start(unit, flex_p->env_counter_flags, 2916 flex_p->env_counter_interval, 2917 PBMP_PORT_ALL(unit))); 2918 } 2919 bcm_vlan_init(unit); 2920 2921 /* print */ 2922 rv = (flex_p->test_fail == 1) ? BCM_E_FAIL : BCM_E_NONE; 2923 cli_out("\n=================================================="); 2924 cli_out("\n=================================================="); 2925 if (flex_p->test_fail == 1) { 2926 cli_out("\n[Flexport test failed]\n\n"); 2927 } else { 2928 cli_out("\n[Flexport test passed]\n\n"); 2929 } 2930 2931 /* free mem */ 2932 sal_free(rate_calc_p); 2933 sal_free(flex_p->ipmc_exp_rate); 2934 sal_free(flex_p->ipmc_tpkt_start); 2935 sal_free(flex_p->ipmc_tpkt_end); 2936 sal_free(flex_p); 2937 2938 return rv; 2939 } 2940 2941 #endif /* BCM_ESW_SUPPORT */