flexport.c (86907B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * The flexport test checks the flexport and TDM functionalities by streaming 8 * L2UC packets on all ports at maximum rate. All ports are configured in 9 * MAC or PHY loopback mode and each port is associated with one VLAN. The test 10 * calculates the number of packets needed to saturate each port and send the 11 * L2UC packets with the port's VLAN tag from the CPU to each port initially. 12 * Then the packets DLF and flood to the VLAN which contains one port. Port 13 * bridging is enabled to allow the DLF packet to go back to its ingress port. 14 * Thus, the packets keep looping back within each port indefinitely. The 15 * flexport functionality is checked by flexing one or more port macros to 16 * a different mode/speed/encapsulation. The port macros and mode/speed/ 17 * encapsulation can be specify either by command line or through a series of 18 * config.bcm files. Once the traffic reaches steady state, rate and packet 19 * integrity are checked on the flex ports. Then, traffic will be stopped on the 20 * flex ports before calling the BCM FlexPort API to performance the flexport 21 * operation. Traffic on the non-flex ports will not be interrupted. The rate 22 * calculation is done by dividing the transmit packet count changes and 23 * transmit byte count changes over a programmable interval. The rates are 24 * checked against expected rates based on port configuration and 25 * oversubscription ratio. Packet integrity check is achieved by disabling the 26 * VLAN so the packets go back to the CPU as unknown VLAN. The packets are 27 * compared against expected packets to ensure packet integrity. 28 * 29 * Configuration parameters passed from CLI: 30 * PktSize: Packet size in bytes. Set to 0 for worst case packet sizes on all 31 * ports (145B for ENET, 76B for HG2). Set to 1 for random packet sizes 32 * FloodCnt: Number of packets in each swirl. Setting this to 0 will let the 33 * test calculate the number of packets that can be sent to achieve 34 * a lossless swirl at full rate. Set to 0 by default. 35 * RateCalcInt: Interval in seconds over which rate is to be calculated 36 * TolLr: Rate tolerance percentage for line rate ports (1% by default). 37 * TolOv: Rate tolerance percentage for oversubscribed ports (3% by default). 38 * ChkPktInteg: Set to 0 to disable packet integrity checks, 1 to enable 39 (default). 40 * MaxNumCells: Max number of cells for random packet sizes. Default = 4. Set 41 * to 0 for random. 42 * LoopbackMode: Loopback mode. Set to 1 for MAC loopback, 2 for PHY loopback. 43 * (default is MAC loopback). 44 * ConfigFile: Config files for each succession flexport operation. 45 * (default is none) 46 * Tsc<num>: TSC to be flexed and port mode to flex to, e.g. Tsc5=4x10G. 47 */ 48 49 #include <appl/diag/system.h> 50 #include <shared/alloc.h> 51 #include <shared/bsl.h> 52 53 #include <soc/cm.h> 54 #include <soc/dma.h> 55 #include <soc/drv.h> 56 #include <soc/dcb.h> 57 #include <soc/cmicm.h> 58 #include <soc/cmic.h> 59 60 #include <sal/types.h> 61 #include <appl/diag/parse.h> 62 #include <bcm/port.h> 63 #include <bcm/vlan.h> 64 #include <bcm/link.h> 65 66 #include "testlist.h" 67 #include "gen_pkt.h" 68 #include "streaming_lib.h" 69 70 #define PKT_SIZE_PARAM_DEFAULT 0 71 #define FLOOD_PKT_CNT_PARAM_DEFAULT 0 72 #define RATE_CALC_INTERVAL_PARAM_DEFAULT 10 73 #define RATE_TOLERANCE_LR_PARAM_DEFAULT 1 74 #define RATE_TOLERANCE_OV_PARAM_DEFAULT 3 75 #define CHECK_PACKET_INTEGRITY_PARAM_DEFAULT 1 76 #define EMULATION_PARAM_DEFAULT 0 77 #define MAX_NUM_CELLS_PARAM_DEFAULT 4 78 #define NO_SPEED_CHANGE_PARAM_DEFAULT 1 79 80 #define TCP_CMD_BUF_LEN 512 81 82 #define MAC_DA {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc} 83 #define MAC_SA {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54} 84 #define TPID 0x8100 85 #define VLAN 0x0a00 86 87 88 #if defined(BCM_ESW_SUPPORT) && \ 89 (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \ 90 !defined(NO_SAL_APPL) && (!defined(__KERNEL__)) 91 92 #include <unistd.h> 93 #include <sys/socket.h> 94 #include <netinet/in.h> 95 #include <netdb.h> 96 97 #define MAX_TSC_NUM 65 98 99 /* TSC Info */ 100 #define TDMV_NUM_TSC(unit) (SOC_IS_TOMAHAWK2(unit) ? 64 : 32) 101 #define NUM_PORT_MODULES(unit) (TDMV_NUM_TSC(unit) + 1) 102 #define TDMV_NUM_TSC_LANES 4 103 104 /* Encap types */ 105 #define PM_ENCAP__HIGIG2 999 106 #define PM_ENCAP__ETHRNT 998 107 108 enum port_state_e { 109 PORT_STATE__DISABLED = 0x0, 110 PORT_STATE__LINERATE = 0x1, 111 PORT_STATE__OVERSUB = 0x2, 112 PORT_STATE__COMBINE = 0x3, 113 PORT_STATE__LINERATE_HG = 0x5, 114 PORT_STATE__OVERSUB_HG = 0x6, 115 PORT_STATE__COMBINE_HG = 0x7, 116 PORT_STATE__MANAGEMENT = 0x9, 117 PORT_STATE__MUTABLE = 0x11, 118 PORT_STATE__CARDINAL = 0x19 119 }; 120 121 /* Speed set (Gbps) */ 122 typedef enum { 123 SPEED_UI_0 = 0, 124 SPEED_UI_1G = 1, 125 SPEED_UI_2p5G = 2, 126 SPEED_UI_10G = 10, 127 SPEED_UI_20G = 20, 128 SPEED_UI_21G_DUAL = 21, 129 SPEED_UI_25G = 25, 130 SPEED_UI_40G = 40, 131 SPEED_UI_41G_DUAL = 41, 132 SPEED_UI_42G = 42, 133 SPEED_UI_50G = 50, 134 SPEED_UI_100G = 100, 135 SPEED_UI_120G = 120 136 } port_speed_t; 137 138 typedef struct flexport_s { 139 pbmp_t vlan_pbmp; 140 pbmp_t port_down_pbmp; 141 pbmp_t port_up_pbmp; 142 pbmp_t speed_change_pbmp; 143 uint32 pkt_size_param; 144 uint32 flood_pkt_cnt_param; 145 uint32 rate_calc_interval_param; 146 uint32 rate_tolerance_lr_param; 147 uint32 rate_tolerance_ov_param; 148 uint32 check_packet_integrity_param; 149 uint32 emulation_param; 150 char *server_name_param; 151 uint32 socket_num_param; 152 uint32 max_num_cells_param; 153 uint32 loopback_mode_param; 154 uint32 no_speed_change_param; 155 uint32 init_tsc_shim; 156 uint32 flex_by_command_line; 157 char *config_file_name; 158 char *tsc_param[MAX_TSC_NUM]; 159 uint32 num_del; 160 uint32 num_add; 161 bcm_port_resource_t del_resource[SOC_MAX_NUM_PORTS]; 162 bcm_port_resource_t add_resource[SOC_MAX_NUM_PORTS]; 163 int last_assigned_port[SOC_MAX_NUM_PIPES]; 164 int flex_tsc_map[MAX_TSC_NUM]; 165 int linkscan_enable; 166 uint32 counter_flags; 167 int counter_interval; 168 pbmp_t counter_pbm; 169 uint32 bad_input; 170 uint32 test_fail; 171 uint32 pkt_seed; 172 int sockfd; 173 char tsc_cfg_buffer[12][TCP_CMD_BUF_LEN]; 174 int tsc_cfg_cmds; 175 int tsc_cfg_ptr; 176 int clear_new_port_counts; 177 } flexport_t; 178 179 typedef struct rate_calc_s { 180 uint32 ovs_ratio_x1000[SOC_MAX_NUM_PIPES]; 181 uint32 rand_pkt_sizes[SOC_MAX_NUM_PORTS][TARGET_CELL_COUNT]; 182 uint64 stime[SOC_MAX_NUM_PORTS]; 183 uint64 exp_rate[SOC_MAX_NUM_PORTS]; 184 uint64 tpkt_start[SOC_MAX_NUM_PORTS]; 185 uint64 tbyt_start[SOC_MAX_NUM_PORTS]; 186 } rate_calc_t; 187 188 static flexport_t *flexport_parray[SOC_MAX_NUM_DEVICES]; 189 static rate_calc_t *rate_calc_parray[SOC_MAX_NUM_DEVICES]; 190 191 static const char flexport_test_usage[] = 192 #ifdef COMPILER_STRING_CONST_LIMIT 193 "\nDocumentation too long to be displayed with -pedantic compiler\n"; 194 #else 195 "\nFlexPort test usage:\n" 196 " \n" 197 "PktSize: Packet size in bytes. Set to 1 for random packet sizes.\n" 198 " Set to 0 (default) for worst case packet sizes on all ports\n" 199 " (145B for ENET, 76B for HG2).\n" 200 "FloodCnt: Number of packets in each swirl between.\n" 201 " Set to 0 (default) for a lossless swirl at full rate.\n" 202 "RateCalcInt: Interval in seconds over which rate is to be calculated.\n" 203 "TolLr: Rate tolerance percentage for line rate ports.\n" 204 " (1% by default)\n" 205 "TolOv: Rate tolerance percentage for oversubscribed ports.\n" 206 " (3% by default).\n" 207 "ChkPktInteg: Set to 0 to disable packet integrity checks.\n" 208 " Set to 1 to enable (default).\n" 209 "Emulation: Set to 1 to send TSC clock commands for emulation.\n" 210 " Set to 0 to disable (default).\n" 211 "ServerName: Name (Linux) or IP address (VxWorks) of the TSC clock server.\n" 212 " Required for emulation\n." 213 "SocketNum: Socket number of the TSC clock server.\n" 214 " Required for emulation\n." 215 "MaxNumCells: Maximum number of cells for random packet sizes.\n" 216 " Set to 0 for random cell sizes. (default is 4)\n" 217 "LoopbackMode: Loopback mode. Set to 1 for MAC loopback, 2 for PHY loopback.\n" 218 " (default is MAC loopback)\n" 219 "ConfigFile: Config files for each succession flexport operation.\n" 220 " (default is none)\n" 221 "Tsc<num>: TSC to be flexed and port mode to flex to, e.g. Tsc5=4x10G\n" 222 " The supported mode/speed in Ethernet encapsulation are:\n" 223 "NoSpeedChg: Do not call the bcm_port_speed change. (default)\n" 224 ; 225 #endif 226 227 static const char td2p_supported_mode[] = 228 " 1x100G, 1x120G, 10x10G, 12x10G,\n" 229 " 1x40G, 1x20G, 1x10G, 2x20G, 2x10G,\n" 230 " 20G+2x10G, 2x10G+20G,\n" 231 " 4x10G, 4x2.5G, and 4x1G\n" 232 " The supported mode/speed in HiGig2 encapsulation are:\n" 233 " 1x106G, 1x127G, 10x11G, 12x11G,\n" 234 " 1x42G, 1x21G, 1x11G, 2x21G, and 4x11G\n" 235 ; 236 237 static const char th2_supported_mode[] = 238 " 1x100G, 1x40G\n" 239 " 2x50G, 2x40G, 2x20G,\n" 240 " 20G+2x10G, 2x10G+20G,\n" 241 " 50G+2x25G, 2x25G+50G,\n" 242 " 4x25G, and 4x10G\n" 243 " The supported mode/speed in HiGig2 encapsulation are:\n" 244 " 1x106G, 1x42G,\n" 245 " 2x53G, 2x42G, 2x21G,\n" 246 " 4x27G, and 4x11G\n" 247 ; 248 249 static const char td3_supported_mode[] = 250 " 1x100G, 1x40G\n" 251 " 2x50G, 2x40G, 2x20G,\n" 252 " 20G+2x10G, 2x10G+20G,\n" 253 " 50G+2x25G, 2x25G+50G,\n" 254 " 4x25G, 4x10G and 4x1G\n" 255 " The supported mode/speed in HiGig2 encapsulation are:\n" 256 " 1x106G, 1x42G,\n" 257 " 2x53G, 2x42G, 2x21G,\n" 258 " 4x27G, and 4x11G\n" 259 ; 260 261 /* 262 * Function: 263 * flexport_parse_test_params 264 * Purpose: 265 * Parse CLI parameters, create test structure and flag bad inputs. 266 * Parameters: 267 * unit - StrataSwitch Unit #. 268 * a - Pointer to arguments 269 * 270 * Returns: 271 * Nothing 272 * Notes: 273 * flexport_p->bad_input set from here - tells test to crash out in case 274 * CLI input combination is invalid. 275 */ 276 277 static void 278 flexport_parse_test_params(int unit, args_t *a) 279 { 280 int i; 281 parse_table_t parse_table; 282 flexport_t *flexport_p = flexport_parray[unit]; 283 284 flexport_p->bad_input = 0; 285 286 flexport_p->pkt_size_param = PKT_SIZE_PARAM_DEFAULT; 287 flexport_p->flood_pkt_cnt_param = FLOOD_PKT_CNT_PARAM_DEFAULT; 288 flexport_p->rate_calc_interval_param = RATE_CALC_INTERVAL_PARAM_DEFAULT; 289 flexport_p->rate_tolerance_lr_param = RATE_TOLERANCE_LR_PARAM_DEFAULT; 290 flexport_p->rate_tolerance_ov_param = RATE_TOLERANCE_OV_PARAM_DEFAULT; 291 flexport_p->check_packet_integrity_param 292 = CHECK_PACKET_INTEGRITY_PARAM_DEFAULT; 293 flexport_p->emulation_param = EMULATION_PARAM_DEFAULT; 294 flexport_p->socket_num_param = 0; 295 flexport_p->max_num_cells_param = MAX_NUM_CELLS_PARAM_DEFAULT; 296 flexport_p->loopback_mode_param = BCM_PORT_LOOPBACK_MAC; 297 flexport_p->no_speed_change_param = NO_SPEED_CHANGE_PARAM_DEFAULT; 298 flexport_p->init_tsc_shim = 0; 299 flexport_p->flex_by_command_line = 0; 300 flexport_p->clear_new_port_counts = 0; 301 302 /*Parse CLI opts */ 303 304 parse_table_init(unit, &parse_table); 305 parse_table_add(&parse_table, "PktSize", PQ_INT|PQ_DFL, 0, 306 &flexport_p->pkt_size_param, NULL); 307 parse_table_add(&parse_table, "FloodCnt", PQ_INT|PQ_DFL, 0, 308 &flexport_p->flood_pkt_cnt_param, NULL); 309 parse_table_add(&parse_table, "RateCalcInt", PQ_INT|PQ_DFL, 0, 310 &flexport_p->rate_calc_interval_param, NULL); 311 parse_table_add(&parse_table, "TolLr", PQ_INT|PQ_DFL, 0, 312 &flexport_p->rate_tolerance_lr_param, NULL); 313 parse_table_add(&parse_table, "TolOv", PQ_INT|PQ_DFL, 0, 314 &flexport_p->rate_tolerance_ov_param, NULL); 315 parse_table_add(&parse_table, "ChkPktInteg", PQ_INT|PQ_DFL, 0, 316 &flexport_p->check_packet_integrity_param, NULL); 317 parse_table_add(&parse_table, "Emulation", PQ_INT|PQ_DFL, 0, 318 &flexport_p->emulation_param, NULL); 319 parse_table_add(&parse_table, "ServerName", PQ_STRING|PQ_DFL, 0, 320 &flexport_p->server_name_param, NULL); 321 parse_table_add(&parse_table, "SocketNum", PQ_INT|PQ_DFL, 0, 322 &flexport_p->socket_num_param, NULL); 323 parse_table_add(&parse_table, "MaxNumCells", PQ_INT|PQ_DFL, 0, 324 &flexport_p->max_num_cells_param, NULL); 325 parse_table_add(&parse_table, "LoopbackMode", PQ_INT|PQ_DFL, 0, 326 &flexport_p->loopback_mode_param, NULL); 327 parse_table_add(&parse_table, "ConfigFile", PQ_STRING|PQ_DFL, 0, 328 &flexport_p->config_file_name, NULL); 329 parse_table_add(&parse_table, "Tsc0", PQ_STRING|PQ_DFL, 0, 330 &flexport_p->tsc_param[0], NULL); 331 parse_table_add(&parse_table, "Tsc1", PQ_STRING|PQ_DFL, 0, 332 &flexport_p->tsc_param[1], NULL); 333 parse_table_add(&parse_table, "Tsc2", PQ_STRING|PQ_DFL, 0, 334 &flexport_p->tsc_param[2], NULL); 335 parse_table_add(&parse_table, "Tsc3", PQ_STRING|PQ_DFL, 0, 336 &flexport_p->tsc_param[3], NULL); 337 parse_table_add(&parse_table, "Tsc4", PQ_STRING|PQ_DFL, 0, 338 &flexport_p->tsc_param[4], NULL); 339 parse_table_add(&parse_table, "Tsc5", PQ_STRING|PQ_DFL, 0, 340 &flexport_p->tsc_param[5], NULL); 341 parse_table_add(&parse_table, "Tsc6", PQ_STRING|PQ_DFL, 0, 342 &flexport_p->tsc_param[6], NULL); 343 parse_table_add(&parse_table, "Tsc7", PQ_STRING|PQ_DFL, 0, 344 &flexport_p->tsc_param[7], NULL); 345 parse_table_add(&parse_table, "Tsc8", PQ_STRING|PQ_DFL, 0, 346 &flexport_p->tsc_param[8], NULL); 347 parse_table_add(&parse_table, "Tsc9", PQ_STRING|PQ_DFL, 0, 348 &flexport_p->tsc_param[9], NULL); 349 parse_table_add(&parse_table, "Tsc10", PQ_STRING|PQ_DFL, 0, 350 &flexport_p->tsc_param[10], NULL); 351 parse_table_add(&parse_table, "Tsc11", PQ_STRING|PQ_DFL, 0, 352 &flexport_p->tsc_param[11], NULL); 353 parse_table_add(&parse_table, "Tsc12", PQ_STRING|PQ_DFL, 0, 354 &flexport_p->tsc_param[12], NULL); 355 parse_table_add(&parse_table, "Tsc13", PQ_STRING|PQ_DFL, 0, 356 &flexport_p->tsc_param[13], NULL); 357 parse_table_add(&parse_table, "Tsc14", PQ_STRING|PQ_DFL, 0, 358 &flexport_p->tsc_param[14], NULL); 359 parse_table_add(&parse_table, "Tsc15", PQ_STRING|PQ_DFL, 0, 360 &flexport_p->tsc_param[15], NULL); 361 parse_table_add(&parse_table, "Tsc16", PQ_STRING|PQ_DFL, 0, 362 &flexport_p->tsc_param[16], NULL); 363 parse_table_add(&parse_table, "Tsc17", PQ_STRING|PQ_DFL, 0, 364 &flexport_p->tsc_param[17], NULL); 365 parse_table_add(&parse_table, "Tsc18", PQ_STRING|PQ_DFL, 0, 366 &flexport_p->tsc_param[18], NULL); 367 parse_table_add(&parse_table, "Tsc19", PQ_STRING|PQ_DFL, 0, 368 &flexport_p->tsc_param[19], NULL); 369 parse_table_add(&parse_table, "Tsc20", PQ_STRING|PQ_DFL, 0, 370 &flexport_p->tsc_param[20], NULL); 371 parse_table_add(&parse_table, "Tsc21", PQ_STRING|PQ_DFL, 0, 372 &flexport_p->tsc_param[21], NULL); 373 parse_table_add(&parse_table, "Tsc22", PQ_STRING|PQ_DFL, 0, 374 &flexport_p->tsc_param[22], NULL); 375 parse_table_add(&parse_table, "Tsc23", PQ_STRING|PQ_DFL, 0, 376 &flexport_p->tsc_param[23], NULL); 377 parse_table_add(&parse_table, "Tsc24", PQ_STRING|PQ_DFL, 0, 378 &flexport_p->tsc_param[24], NULL); 379 parse_table_add(&parse_table, "Tsc25", PQ_STRING|PQ_DFL, 0, 380 &flexport_p->tsc_param[25], NULL); 381 parse_table_add(&parse_table, "Tsc26", PQ_STRING|PQ_DFL, 0, 382 &flexport_p->tsc_param[26], NULL); 383 parse_table_add(&parse_table, "Tsc27", PQ_STRING|PQ_DFL, 0, 384 &flexport_p->tsc_param[27], NULL); 385 parse_table_add(&parse_table, "Tsc28", PQ_STRING|PQ_DFL, 0, 386 &flexport_p->tsc_param[28], NULL); 387 parse_table_add(&parse_table, "Tsc29", PQ_STRING|PQ_DFL, 0, 388 &flexport_p->tsc_param[29], NULL); 389 parse_table_add(&parse_table, "Tsc30", PQ_STRING|PQ_DFL, 0, 390 &flexport_p->tsc_param[30], NULL); 391 parse_table_add(&parse_table, "Tsc31", PQ_STRING|PQ_DFL, 0, 392 &flexport_p->tsc_param[31], NULL); 393 parse_table_add(&parse_table, "Tsc32", PQ_STRING|PQ_DFL, 0, 394 &flexport_p->tsc_param[32], NULL); 395 parse_table_add(&parse_table, "Tsc33", PQ_STRING|PQ_DFL, 0, 396 &flexport_p->tsc_param[33], NULL); 397 parse_table_add(&parse_table, "Tsc34", PQ_STRING|PQ_DFL, 0, 398 &flexport_p->tsc_param[34], NULL); 399 parse_table_add(&parse_table, "Tsc35", PQ_STRING|PQ_DFL, 0, 400 &flexport_p->tsc_param[35], NULL); 401 parse_table_add(&parse_table, "Tsc36", PQ_STRING|PQ_DFL, 0, 402 &flexport_p->tsc_param[36], NULL); 403 parse_table_add(&parse_table, "Tsc37", PQ_STRING|PQ_DFL, 0, 404 &flexport_p->tsc_param[37], NULL); 405 parse_table_add(&parse_table, "Tsc38", PQ_STRING|PQ_DFL, 0, 406 &flexport_p->tsc_param[38], NULL); 407 parse_table_add(&parse_table, "Tsc39", PQ_STRING|PQ_DFL, 0, 408 &flexport_p->tsc_param[39], NULL); 409 parse_table_add(&parse_table, "Tsc40", PQ_STRING|PQ_DFL, 0, 410 &flexport_p->tsc_param[40], NULL); 411 parse_table_add(&parse_table, "Tsc41", PQ_STRING|PQ_DFL, 0, 412 &flexport_p->tsc_param[41], NULL); 413 parse_table_add(&parse_table, "Tsc42", PQ_STRING|PQ_DFL, 0, 414 &flexport_p->tsc_param[42], NULL); 415 parse_table_add(&parse_table, "Tsc43", PQ_STRING|PQ_DFL, 0, 416 &flexport_p->tsc_param[43], NULL); 417 parse_table_add(&parse_table, "Tsc44", PQ_STRING|PQ_DFL, 0, 418 &flexport_p->tsc_param[44], NULL); 419 parse_table_add(&parse_table, "Tsc45", PQ_STRING|PQ_DFL, 0, 420 &flexport_p->tsc_param[45], NULL); 421 parse_table_add(&parse_table, "Tsc46", PQ_STRING|PQ_DFL, 0, 422 &flexport_p->tsc_param[46], NULL); 423 parse_table_add(&parse_table, "Tsc47", PQ_STRING|PQ_DFL, 0, 424 &flexport_p->tsc_param[47], NULL); 425 parse_table_add(&parse_table, "Tsc48", PQ_STRING|PQ_DFL, 0, 426 &flexport_p->tsc_param[48], NULL); 427 parse_table_add(&parse_table, "Tsc49", PQ_STRING|PQ_DFL, 0, 428 &flexport_p->tsc_param[49], NULL); 429 parse_table_add(&parse_table, "Tsc50", PQ_STRING|PQ_DFL, 0, 430 &flexport_p->tsc_param[50], NULL); 431 parse_table_add(&parse_table, "Tsc51", PQ_STRING|PQ_DFL, 0, 432 &flexport_p->tsc_param[51], NULL); 433 parse_table_add(&parse_table, "Tsc52", PQ_STRING|PQ_DFL, 0, 434 &flexport_p->tsc_param[52], NULL); 435 parse_table_add(&parse_table, "Tsc53", PQ_STRING|PQ_DFL, 0, 436 &flexport_p->tsc_param[53], NULL); 437 parse_table_add(&parse_table, "Tsc54", PQ_STRING|PQ_DFL, 0, 438 &flexport_p->tsc_param[54], NULL); 439 parse_table_add(&parse_table, "Tsc55", PQ_STRING|PQ_DFL, 0, 440 &flexport_p->tsc_param[55], NULL); 441 parse_table_add(&parse_table, "Tsc56", PQ_STRING|PQ_DFL, 0, 442 &flexport_p->tsc_param[56], NULL); 443 parse_table_add(&parse_table, "Tsc57", PQ_STRING|PQ_DFL, 0, 444 &flexport_p->tsc_param[57], NULL); 445 parse_table_add(&parse_table, "Tsc58", PQ_STRING|PQ_DFL, 0, 446 &flexport_p->tsc_param[58], NULL); 447 parse_table_add(&parse_table, "Tsc59", PQ_STRING|PQ_DFL, 0, 448 &flexport_p->tsc_param[59], NULL); 449 parse_table_add(&parse_table, "Tsc60", PQ_STRING|PQ_DFL, 0, 450 &flexport_p->tsc_param[60], NULL); 451 parse_table_add(&parse_table, "Tsc61", PQ_STRING|PQ_DFL, 0, 452 &flexport_p->tsc_param[61], NULL); 453 parse_table_add(&parse_table, "Tsc62", PQ_STRING|PQ_DFL, 0, 454 &flexport_p->tsc_param[62], NULL); 455 parse_table_add(&parse_table, "Tsc63", PQ_STRING|PQ_DFL, 0, 456 &flexport_p->tsc_param[63], NULL); 457 parse_table_add(&parse_table, "NoSpeedChg", PQ_INT|PQ_DFL, 0, 458 &flexport_p->no_speed_change_param, NULL); 459 parse_table_add(&parse_table, "InitTscShim", PQ_INT|PQ_DFL, 0, 460 &flexport_p->init_tsc_shim, NULL); 461 parse_table_add(&parse_table, "ClrNewPortCounts", PQ_INT|PQ_DFL, 0, 462 &flexport_p->clear_new_port_counts, NULL); 463 464 if (parse_arg_eq(a, &parse_table) < 0 || ARG_CNT(a) != 0) { 465 if (SOC_IS_TRIDENT2X(unit)) { 466 cli_out("%s%s", flexport_test_usage, td2p_supported_mode); 467 } 468 if (SOC_IS_TOMAHAWK2(unit)) { 469 cli_out("%s%s", flexport_test_usage, th2_supported_mode); 470 } 471 if (SOC_IS_TRIDENT3X(unit)) { 472 cli_out("%s%s", flexport_test_usage, td3_supported_mode); 473 } 474 test_error(unit, "\n*ERROR PARSING ARGS\n"); 475 } 476 477 cli_out("\n ------------- PRINTING TEST PARAMS ------------------"); 478 cli_out("\nPktSize = %0d", flexport_p->pkt_size_param); 479 cli_out("\nRateCalcInt = %0d", flexport_p->rate_calc_interval_param); 480 cli_out("\nFloodCnt = %0d", flexport_p->flood_pkt_cnt_param); 481 cli_out("\nTolLr = %0d", flexport_p->rate_tolerance_lr_param); 482 cli_out("\nTolOv = %0d", flexport_p->rate_tolerance_ov_param); 483 cli_out("\nChkPktInteg = %0d", flexport_p->check_packet_integrity_param); 484 cli_out("\nEmulation = %0d", flexport_p->emulation_param); 485 cli_out("\nMaxNumCells = %0d", flexport_p->max_num_cells_param); 486 cli_out("\nLoopbackMode = %0d", flexport_p->loopback_mode_param); 487 cli_out("\nConfigFile = %s", flexport_p->config_file_name); 488 cli_out("\nClrNewPortCounts = %0d", flexport_p->clear_new_port_counts); 489 for (i = 0; i < MAX_TSC_NUM; i++) { 490 if (flexport_p->tsc_param[i] != NULL) { 491 cli_out("\nTsc%2d = %s", i, flexport_p->tsc_param[i]); 492 if(i >= TDMV_NUM_TSC(unit)) { 493 flexport_p->bad_input = 1; 494 } 495 flexport_p->flex_by_command_line = 1; 496 } 497 } 498 if (flexport_p->flex_by_command_line == 0) { 499 cli_out("\nTsc<num> = (null)"); 500 } 501 cli_out("\nNoSpeeedChg = %0d", flexport_p->no_speed_change_param); 502 cli_out("\nInitTscShim = %0d", flexport_p->init_tsc_shim); 503 cli_out("\n -----------------------------------------------------"); 504 505 if (flexport_p->max_num_cells_param == 0) { 506 /* coverity[dont_call : FALSE] */ 507 flexport_p->max_num_cells_param = (sal_rand() % (MTU_CELL_CNT - 1)) + 1; 508 } 509 510 if (flexport_p->pkt_size_param == 0) { 511 if(SOC_IS_TRIDENT3X(unit)) 512 cli_out 513 ("\nUsing worst case packet sizes - 64B for Ethernet and HG2"); 514 else 515 cli_out 516 ("\nUsing worst case packet sizes - 145B for Ethernet and " 517 "76B for HG2"); 518 } else if (flexport_p->pkt_size_param == 1) { 519 cli_out("\nUsing random packet sizes"); 520 } else if (flexport_p->pkt_size_param < MIN_PKT_SIZE) { 521 test_error(unit,"*ERROR: Packet size cannot be lower than %0dB\n", 522 MIN_PKT_SIZE); 523 flexport_p->bad_input = 1; 524 } else if (flexport_p->pkt_size_param > MTU) { 525 test_error(unit,"*ERROR: Packet size higher than %0dB (Device MTU)\n", 526 MTU); 527 flexport_p->bad_input = 1; 528 } 529 530 if (flexport_p->flood_pkt_cnt_param == 0) { 531 cli_out("\nFloodCnt=0, automatically calculate number of packets to " 532 "flood each port"); 533 } 534 535 if ((flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_MAC) && 536 (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY) && 537 (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_PHY_REMOTE) && 538 (flexport_p->loopback_mode_param != BCM_PORT_LOOPBACK_NONE)) { 539 /* 540 * 0 - no loopback; only to be used with chip external loopbacks. 541 * 1 - MAC outer loopback. 542 * 2 - PCS local loopback, close to PMD boundary. 543 * 3 - PMD local loopback, close to AFE. 544 */ 545 test_error(unit,"*ERROR: Loopback mode must be either 0, 1, 2 or 3\n"); 546 flexport_p->bad_input = 1; 547 } 548 549 if ((flexport_p->config_file_name != NULL && 550 flexport_p->flex_by_command_line != 0) || 551 (flexport_p->config_file_name == NULL && 552 flexport_p->flex_by_command_line == 0)) { 553 test_error(unit,"*ERROR: Please specify ConfigFile or Tsc\n"); 554 flexport_p->bad_input = 1; 555 } 556 557 if (flexport_p->emulation_param && 558 (flexport_p->server_name_param == NULL || 559 flexport_p->socket_num_param == 0)) { 560 test_error(unit,"*ERROR: ServerName and SocketNum must be specified\n"); 561 flexport_p->bad_input = 1; 562 } 563 564 } 565 566 567 static int 568 connectToSocket(int portno, char* serverName) 569 { 570 int sockfd; 571 struct sockaddr_in serv_addr; 572 struct hostent *server = NULL; 573 574 sockfd = socket(AF_INET, SOCK_STREAM, 0); 575 if (sockfd < 0) { 576 cli_out("\nconnectToSocket : ERROR opening socket\n"); 577 return -1; 578 } 579 sal_memset((char *) &serv_addr, 0, sizeof(serv_addr)); 580 581 server = gethostbyname(serverName); 582 if (server == NULL) { 583 cli_out("\nconnectToSocket : ERROR no such host '%s'\n", serverName); 584 close(sockfd); 585 return -1; 586 } 587 sal_memcpy((char *) &serv_addr.sin_addr.s_addr, server->h_addr_list[0], 588 server->h_length); 589 serv_addr.sin_family = AF_INET; 590 serv_addr.sin_port = htons(portno); 591 if (connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { 592 cli_out("\nconnectToSocket : ERROR connecting\n"); 593 close(sockfd); 594 return -1; 595 } else { 596 cli_out("\nconnectToSocket : Connected to '%s' %0d\n", serverName, portno); 597 } 598 return sockfd; 599 } 600 601 602 static bcm_error_t 603 sendDataToSocket(int sockfd, char* msg) 604 { 605 int rv; 606 rv = write(sockfd, msg, strlen(msg)); 607 if (rv < 0) { 608 cli_out("\nsendDataToSocket : ERROR writing to socket\n"); 609 return -1; 610 } 611 cli_out("\nsendDataToSocket : %s \n", msg); 612 return BCM_E_NONE; 613 } 614 615 616 /* 617 * Function: 618 * tdm_chomp 619 * Purpose: 620 * Removes newline from portmap strings 621 * Parameters: 622 * str: Pointer to a string 623 * 624 * Returns: 625 * Nothing 626 */ 627 628 static 629 void tdm_chomp(char *str) 630 { 631 while (*str && *str != '\n' && *str != '\r') { 632 str++; 633 } 634 *str = 0; 635 } 636 637 638 /* 639 * Function: 640 * convert_hex2bin 641 * Purpose: 642 * Converts hex string to 4-bit binary map 643 * Parameters: 644 * str: single hex digit string 645 * bmp: 4 bit bitmap 646 * 647 * Returns: 648 * Nothing 649 */ 650 651 static 652 void convert_hex2bin(char str, unsigned char bmp[4]){ 653 char str_tmp[2]; 654 long num; 655 str_tmp[0]=str; str_tmp[1]='\0'; 656 num = strtol(str_tmp, NULL, 16); 657 658 switch(num){ 659 case 0: 660 bmp[3]=0; bmp[2]=0; bmp[1]=0; bmp[0]=0; 661 break; 662 case 1: 663 bmp[3]=0; bmp[2]=0; bmp[1]=0; bmp[0]=1; 664 break; 665 case 2: 666 bmp[3]=0; bmp[2]=0; bmp[1]=1; bmp[0]=0; 667 break; 668 case 3: 669 bmp[3]=0; bmp[2]=0; bmp[1]=1; bmp[0]=1; 670 break; 671 case 4: 672 bmp[3]=0; bmp[2]=1; bmp[1]=0; bmp[0]=0; 673 break; 674 case 5: 675 bmp[3]=0; bmp[2]=1; bmp[1]=0; bmp[0]=1; 676 break; 677 case 6: 678 bmp[3]=0; bmp[2]=1; bmp[1]=1; bmp[0]=0; 679 break; 680 case 7: 681 bmp[3]=0; bmp[2]=1; bmp[1]=1; bmp[0]=1; 682 break; 683 case 8: 684 bmp[3]=1; bmp[2]=0; bmp[1]=0; bmp[0]=0; 685 break; 686 case 9: 687 bmp[3]=1; bmp[2]=0; bmp[1]=0; bmp[0]=1; 688 break; 689 case 0xa: 690 bmp[3]=1; bmp[2]=0; bmp[1]=1; bmp[0]=0; 691 break; 692 case 0xb: 693 bmp[3]=1; bmp[2]=0; bmp[1]=1; bmp[0]=1; 694 break; 695 case 0xc: 696 bmp[3]=1; bmp[2]=1; bmp[1]=0; bmp[0]=0; 697 break; 698 case 0xd: 699 bmp[3]=1; bmp[2]=1; bmp[1]=0; bmp[0]=1; 700 break; 701 case 0xe: 702 bmp[3]=1; bmp[2]=1; bmp[1]=1; bmp[0]=0; 703 break; 704 case 0xf: 705 bmp[3]=1; bmp[2]=1; bmp[1]=1; bmp[0]=1; 706 break; 707 default: 708 bmp[3]=0; bmp[2]=0; bmp[1]=0; bmp[0]=0; 709 break; 710 } 711 } 712 713 714 /* 715 * Function: 716 * get_lanes 717 * Purpose: 718 * Converts hex string to 4-bit binary map 719 * Parameters: 720 * unit - StrataSwitch Unit #. 721 * num_subport: number of subports 722 * speed: pointer to a port speed array 723 * lanes: pointer to a lane array 724 * 725 * Returns: 726 * Nothing 727 */ 728 729 static void 730 get_lanes(int unit, int num_subport, int *speed, int *lanes) 731 { 732 int i; 733 734 for (i = 0; i < num_subport; i++) { 735 switch(speed[i]) { 736 case 1000 : lanes[i] = 1; break; 737 case 10000 : lanes[i] = 1; break; 738 case 20000 : lanes[i] = 2; break; 739 case 25000 : lanes[i] = 1; break; 740 case 40000 : lanes[i] = ((i==0) && (speed[2] == 0))? 4 : 2; break; 741 case 50000 : lanes[i] = 2; break; 742 case 100000 : lanes[i] = ((i==0) && (SOC_IS_TRIDENT2X(unit))) ? 743 10 : 4; break; 744 default : lanes[i] = 0; break; 745 } 746 } 747 } 748 749 750 static void 751 get_per_pipe_log_port_range(int unit, int pport, 752 int *log_start, int *log_end, int *pipe) { 753 754 if(SOC_IS_TOMAHAWK2(unit)) { 755 *pipe = (pport - 1) / 64; 756 *log_start = (*pipe) * 34; 757 *log_end = (*pipe) * 34 + 34 - 1; 758 } else { 759 *pipe = 0; 760 *log_start = 0; 761 *log_end = SOC_MAX_NUM_PORTS; 762 } 763 } 764 765 /* 766 * Function: 767 * get_logical_port_no 768 * Purpose: 769 * assign logical port number for physical port 770 * Parameters: 771 * unit - StrataSwitch Unit #. 772 * pport: physical port number 773 * 774 * Returns: 775 * logical port number 776 */ 777 static int 778 get_logical_port_no(int unit, int pport){ 779 soc_info_t *si; 780 int l, lport; 781 int lstart, lend, pipe; 782 flexport_t *flexport_p = flexport_parray[unit]; 783 784 si = &SOC_INFO(unit); 785 lport = -1; 786 get_per_pipe_log_port_range(unit, pport, &lstart, &lend, &pipe); 787 788 if(SOC_IS_TRIDENT3X(unit)) { 789 lport = (pport > 64) ? (2 + pport) : (pport); 790 } else { 791 if(flexport_p->last_assigned_port[pipe] == -1) { 792 flexport_p->last_assigned_port[pipe] = lstart; 793 } 794 795 for (l = (flexport_p->last_assigned_port[pipe] + 1); 796 l <= lend && l < SOC_MAX_NUM_PORTS; l++) { 797 if(si->port_l2p_mapping[l] == -1) { 798 flexport_p->last_assigned_port[pipe] = l; 799 lport = l; 800 LOG_INFO(BSL_LS_APPL_TESTS, 801 (BSL_META_U(unit, "\nAssigned logical port"))); 802 LOG_INFO(BSL_LS_APPL_TESTS, 803 (BSL_META_U(unit, " %0d to physical port %0d"), 804 l, pport)); 805 break; 806 } 807 } 808 } 809 return lport; 810 } 811 812 static int 813 config_tsc_shim(int unit, int tsc_num, int num_subport, int *speed, int encap) 814 { 815 int i, lane_speed = 0, vco_sel = 0, higig = 0, tsc_lane_mode = 0; 816 int lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 817 int update_tscf = 0; 818 char buffer[TCP_CMD_BUF_LEN]; 819 flexport_t *flexport_p = flexport_parray[unit]; 820 821 get_lanes(unit, num_subport, speed, lanes); 822 for(i = 0; i < num_subport; i++) { 823 if(speed[i] > 0) { 824 update_tscf = 1; 825 switch (speed[i]) { 826 case 100000: 827 lane_speed = 12; vco_sel = 1; tsc_lane_mode = 1; 828 update_tscf = 1; 829 break; 830 case 50000: 831 lane_speed = 12; vco_sel = 1; tsc_lane_mode = 5; 832 update_tscf = 1; 833 break; 834 case 40000: 835 lane_speed = (lanes[i] == 4) ? 5 : 10; 836 vco_sel = 0; 837 tsc_lane_mode = (lanes[i] == 4) ? 1 : 5; 838 update_tscf = 1; 839 break; 840 case 25000: 841 lane_speed = 12; vco_sel = 1; tsc_lane_mode = 15; 842 update_tscf = 1; 843 break; 844 case 20000: 845 lane_speed = 5; vco_sel = 0; tsc_lane_mode = 5; 846 update_tscf = 1; 847 break; 848 case 10000: 849 lane_speed = 5; vco_sel = 0; tsc_lane_mode = 15; 850 update_tscf = 1; 851 break; 852 default: 853 test_error(unit, "*ERROR: Speed %0dG is not supported\n", 854 speed[i] / 1000); 855 break; 856 } 857 sal_memset(buffer, 0, TCP_CMD_BUF_LEN); 858 sprintf(buffer, "config_tscf_lane TscNum %0d LaneNum %0d LaneSpeed %0d\n", 859 tsc_num, i, lane_speed); 860 sal_strcpy(flexport_p->tsc_cfg_buffer[flexport_p->tsc_cfg_ptr++], buffer); 861 flexport_p->tsc_cfg_cmds = 1; 862 } 863 } 864 865 higig = (encap == BCM_PORT_ENCAP_HIGIG2) ? 1 : 0; 866 /* Now, correct the TSC lane mode if the port macro is configured */ 867 /* as a tri-port. */ 868 if ((speed[0] > 0) && (speed[0] == speed[1]) && (speed[0] != speed[2])) { 869 tsc_lane_mode = 7; 870 } 871 if ((speed[2] > 0) && (speed[2] == speed[3]) && (speed[0] != speed[2])) { 872 tsc_lane_mode = 13; 873 } 874 875 if (update_tscf) { 876 sal_memset(buffer, 0, TCP_CMD_BUF_LEN); 877 sprintf(buffer, "config_tscf TscNum %0d VcoSel %0d Higig %0d TscLaneMode %0d HddcNum %0d\n", 878 tsc_num, vco_sel, higig, tsc_lane_mode, tsc_num); 879 sal_strcpy(flexport_p->tsc_cfg_buffer[flexport_p->tsc_cfg_ptr++], buffer); 880 flexport_p->tsc_cfg_cmds = 1; 881 } 882 883 for (i = 0; i < 12; i++) { 884 if (flexport_p->tsc_cfg_buffer[i][0] != '\0') { 885 if (BCM_E_NONE != sendDataToSocket(flexport_p->sockfd, 886 flexport_p->tsc_cfg_buffer[i])) { 887 return BCM_E_INTERNAL; 888 } 889 sal_memset(flexport_p->tsc_cfg_buffer[i], 0, TCP_CMD_BUF_LEN); 890 } 891 } 892 flexport_p->tsc_cfg_cmds = 0; 893 flexport_p->tsc_cfg_ptr = 0; 894 895 return BCM_E_NONE; 896 } 897 898 /* 899 * Function: 900 * flex_tsc 901 * Purpose: 902 * Prepare speed_change_pbmp, port_down_pbmp, port_up_pbmp for one TSC 903 * Parameters: 904 * unit - StrataSwitch Unit #. 905 * num_subport: number of subports 906 * first_phy_port: first physical port number of the TSC 907 * encap: Ethernet or HiGig2 908 * 909 * Returns: 910 * SOC_E_XXXX 911 */ 912 913 static bcm_error_t 914 flex_tsc(int unit, int num_subport, int first_phy_port, int *speed, int encap) 915 { 916 soc_info_t *si; 917 flexport_t *flexport_p = flexport_parray[unit]; 918 int i; 919 int cur_speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 920 int cur_lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 921 int cur_encap = BCM_PORT_ENCAP_IEEE; 922 int lanes[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 923 int lanes_changed = 0; 924 int exact_speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 925 bcm_port_t lport, pport; 926 int rv; 927 928 si = &SOC_INFO(unit); 929 930 LOG_INFO(BSL_LS_APPL_TESTS, 931 (BSL_META_U(unit, "\nFlexing port %0d..%0d to"), 932 first_phy_port, first_phy_port + num_subport - 1)); 933 for (i = 0; i < num_subport; i++) { 934 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " %0dG"), speed[i] / 1000)); 935 } 936 if (encap == BCM_PORT_ENCAP_IEEE) { 937 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " Ethernet"))); 938 } else if (encap == BCM_PORT_ENCAP_HIGIG2) { 939 LOG_INFO(BSL_LS_APPL_TESTS, (BSL_META_U(unit, " Higig2"))); 940 } 941 942 lport = si->port_p2l_mapping[first_phy_port]; 943 if (lport != -1 && IS_HG2_ENABLED_PORT(unit, lport)) { 944 cur_encap = BCM_PORT_ENCAP_HIGIG2; 945 } 946 947 for (i = 0; i < num_subport; i++) { 948 pport = first_phy_port + i; 949 lport = si->port_p2l_mapping[pport]; 950 if (lport != -1) { 951 rv = bcm_port_speed_get(unit, lport, &cur_speed[i]); 952 if (BCM_FAILURE(rv) && rv != BCM_E_PORT) { 953 cli_out("\nbcm_port_speed_get %0d %0d: %s", 954 lport, rv, bcm_errmsg(rv)); 955 return rv; 956 } 957 } 958 } 959 960 get_lanes(unit, num_subport, cur_speed, cur_lanes); 961 get_lanes(unit, num_subport, speed, lanes); 962 for (i = 0; i < num_subport; i++) { 963 if (lanes[i] != cur_lanes[i]) { 964 lanes_changed = 1; 965 break; 966 } 967 } 968 969 if (lanes_changed == 0 && encap == cur_encap && 970 flexport_p->no_speed_change_param == 0) { 971 for (i = 0; i < num_subport; i++) { 972 exact_speed[i] = stream_get_exact_speed(speed[i], encap); 973 if (exact_speed[i] != cur_speed[i]) { 974 pport = first_phy_port + i; 975 lport = si->port_p2l_mapping[pport]; 976 LOG_INFO(BSL_LS_APPL_TESTS, 977 (BSL_META_U(unit, "\nChanging port %0d from %0d G to %0d G"), 978 pport, cur_speed[i] / 1000, 979 exact_speed[i] / 1000)); 980 rv = bcm_port_speed_set(unit, lport, exact_speed[i]); 981 if (BCM_FAILURE(rv) && rv != BCM_E_PORT) { 982 cli_out("\nbcm_port_speed_set %0d %0d: %s", 983 lport, exact_speed[i], bcm_errmsg(rv)); 984 return rv; 985 } 986 SOC_PBMP_PORT_ADD(flexport_p->speed_change_pbmp, lport); 987 } 988 } 989 return BCM_E_NONE; 990 } 991 992 for (i = 0; i < num_subport; i++) { 993 pport = first_phy_port + i; 994 lport = si->port_p2l_mapping[pport]; 995 if (lport != -1) { 996 exact_speed[i] = stream_get_exact_speed(speed[i], encap); 997 if (cur_speed[i] > 0 && 998 (exact_speed[i] != cur_speed[i] || encap != cur_encap || 999 lanes[i] != cur_lanes[i])) { 1000 LOG_INFO(BSL_LS_APPL_TESTS, 1001 (BSL_META_U(unit, "\nRemoving %0d G port %0d"), 1002 cur_speed[i] / 1000, pport)); 1003 bcm_port_resource_t_init( 1004 &flexport_p->del_resource[flexport_p->num_del]); 1005 flexport_p->del_resource[flexport_p->num_del].physical_port = -1; 1006 flexport_p->del_resource[flexport_p->num_del].port = lport; 1007 flexport_p->num_del++; 1008 SOC_PBMP_PORT_ADD(flexport_p->port_down_pbmp, lport); 1009 } 1010 } 1011 } 1012 1013 for (i = 0; i < num_subport; i++) { 1014 exact_speed[i] = stream_get_exact_speed(speed[i], encap); 1015 if (speed[i] > 0 && 1016 (exact_speed[i] != cur_speed[i] || encap != cur_encap || 1017 lanes[i] != cur_lanes[i])) { 1018 pport = first_phy_port + i; 1019 lport = get_logical_port_no(unit, pport); 1020 if(lport == -1) { 1021 cli_out("\nERROR : Unable to find valid logical port for" 1022 " physical port %0d", pport); 1023 return BCM_E_INTERNAL; 1024 } 1025 bcm_port_resource_t_init( 1026 &flexport_p->add_resource[flexport_p->num_add]); 1027 LOG_INFO(BSL_LS_APPL_TESTS, 1028 (BSL_META_U(unit, "\nAdding %0d G port %0d lane %0d"), 1029 exact_speed[i] / 1000, pport, lanes[i])); 1030 flexport_p->add_resource[flexport_p->num_add].physical_port = pport; 1031 flexport_p->add_resource[flexport_p->num_add].port = lport; 1032 flexport_p->add_resource[flexport_p->num_add].speed = exact_speed[i]; 1033 flexport_p->add_resource[flexport_p->num_add].lanes = lanes[i]; 1034 flexport_p->add_resource[flexport_p->num_add].encap = encap; 1035 flexport_p->num_add++; 1036 SOC_PBMP_PORT_ADD(flexport_p->port_up_pbmp, lport); 1037 } 1038 } 1039 flexport_p->flex_tsc_map[(first_phy_port - 1) / num_subport] = 1; 1040 1041 return BCM_E_NONE; 1042 } 1043 1044 1045 /* 1046 * Function: 1047 * flexport_call_bcm_api 1048 * Purpose: 1049 * Call the bcm_port_resource_multi_set API 1050 * Parameters: 1051 * unit - StrataSwitch Unit #. 1052 * 1053 * Returns: 1054 * SOC_E_XXXX 1055 */ 1056 1057 static bcm_error_t 1058 flexport_call_bcm_api(int unit) 1059 { 1060 flexport_t *flexport_p = flexport_parray[unit]; 1061 int i; 1062 bcm_port_t lport; 1063 uint32 nports; 1064 bcm_port_resource_t *resource; 1065 bcm_error_t rv; 1066 1067 nports = flexport_p->num_del + flexport_p->num_add; 1068 resource = (bcm_port_resource_t *) sal_alloc(nports * 1069 sizeof(bcm_port_resource_t), 1070 "flexport_resource_array"); 1071 sal_memset(resource, 0, sizeof(bcm_port_resource_t)); 1072 1073 for (i = 0; i < flexport_p->num_del; i ++) { 1074 resource[i] = flexport_p->del_resource[i]; 1075 } 1076 for (i = 0; i < flexport_p->num_add; i ++) { 1077 resource[flexport_p->num_del + i] = flexport_p->add_resource[i]; 1078 } 1079 1080 PBMP_ITER(flexport_p->port_down_pbmp, lport) { 1081 if (lport < SOC_MAX_NUM_PORTS) { 1082 rv = bcm_port_enable_set(unit, lport, 0); 1083 if (BCM_FAILURE(rv)) { 1084 cli_out("\nbcm_port_disable_set %0d: %s", lport, bcm_errmsg(rv)); 1085 sal_free(resource); 1086 return rv; 1087 } 1088 } 1089 } 1090 1091 LOG_INFO(BSL_LS_APPL_TESTS, 1092 (BSL_META_U(unit, "\nCalling bcm_port_resource_multi:"))); 1093 for (i = 0; i < nports; i ++) { 1094 LOG_INFO(BSL_LS_APPL_TESTS, 1095 (BSL_META_U(unit, "\nresource[%0d]: physical_port = %0d"), 1096 i, resource[i].physical_port)); 1097 LOG_INFO(BSL_LS_APPL_TESTS, 1098 (BSL_META_U(unit, "\nresource[%0d]: port = %0d"), 1099 i, resource[i].port)); 1100 LOG_INFO(BSL_LS_APPL_TESTS, 1101 (BSL_META_U(unit, "\nresource[%0d]: speed = %0d"), 1102 i, resource[i].speed)); 1103 LOG_INFO(BSL_LS_APPL_TESTS, 1104 (BSL_META_U(unit, "\nresource[%0d]: lanes = %0d"), 1105 i, resource[i].lanes)); 1106 LOG_INFO(BSL_LS_APPL_TESTS, 1107 (BSL_META_U(unit, "\nresource[%0d]: encap = %0d"), 1108 i, resource[i].encap)); 1109 } 1110 rv = bcm_port_resource_multi_set(unit, nports, resource); 1111 if (BCM_FAILURE(rv)) { 1112 cli_out("\nbcm_port_resource_multi_set: %s", bcm_errmsg(rv)); 1113 sal_free(resource); 1114 return rv; 1115 } 1116 1117 cli_out("\nWait 20s for TSC configuration changes to take effect\n"); 1118 sal_sleep(20); 1119 1120 PBMP_ITER(flexport_p->port_up_pbmp, lport) { 1121 if (lport < SOC_MAX_NUM_PORTS) { 1122 rv = bcm_port_enable_set(unit, lport, 1); 1123 if (BCM_FAILURE(rv)) { 1124 cli_out("\nbcm_port_enable_set %0d: %s", lport, bcm_errmsg(rv)); 1125 sal_free(resource); 1126 return rv; 1127 } 1128 } 1129 } 1130 1131 sal_free(resource); 1132 1133 return BCM_E_NONE; 1134 } 1135 1136 /* 1137 * Function: 1138 * flexport_by_config_file 1139 * Purpose: 1140 * Load a BCM config file and flex accordingly 1141 * Parameters: 1142 * unit: StrataSwitch Unit #. 1143 * fname: filename of the bcm config file 1144 * 1145 * Returns: 1146 * BCM_E_XXXX 1147 */ 1148 1149 static bcm_error_t 1150 flexport_by_config_file(int unit, char *fname) 1151 { 1152 int port_speed; 1153 int *port_speeds; 1154 int *port_states; 1155 int traffic[MAX_TSC_NUM]; 1156 char line[256], line_cpy1[256], line_cpy2[32], line_cpy3[32]; 1157 char *port_str[32], *port_data[32], *l2p_str[16]; 1158 char *split1 = NULL, *split2 = NULL, *split3 = NULL; 1159 const char *dic_portmap, *dic_pbmp_xe, *dic_pbmp_os, *dic_dev_bw; 1160 const char *dic_higig; 1161 int i, j, port_idx, l2p_idx, port_lgcID, port_data_idx, tmp_port, tmp_speed; 1162 int port_phyID, highest_lgcID = 0, clk_freq, lgc_2_phy_portmap[SOC_MAX_NUM_PORTS]; 1163 int port_lanenum = 0; 1164 unsigned char os_bmp[SOC_MAX_NUM_PORTS], xe_bmp[SOC_MAX_NUM_PORTS], 1165 bmp_4bit[4]; 1166 long int hg_bmp=0; 1167 FILE *fp; 1168 soc_info_t *si; 1169 int p; 1170 char eth_hig_str[3], line_ovsb_str[4]; 1171 int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1172 int encap; 1173 int num_subport; 1174 int rv = BCM_E_NONE; 1175 1176 port_speeds = (int *) sal_alloc(sizeof(int) * SOC_MAX_NUM_PORTS, 1177 "port_speeds"); 1178 port_states = (int *) sal_alloc(sizeof(int) * SOC_MAX_NUM_PORTS, 1179 "port_states"); 1180 sal_memset(port_speeds, 0, sizeof(int) * SOC_MAX_NUM_PORTS); 1181 sal_memset(port_states, 0, sizeof(int) * SOC_MAX_NUM_PORTS); 1182 1183 si = &SOC_INFO(unit); 1184 cli_out("\nCurrent bcm config:"); 1185 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 1186 if (p < SOC_MAX_NUM_PORTS) { 1187 bcm_port_speed_get(unit, p, &port_speed); 1188 if (SOC_PBMP_MEMBER(PBMP_E_ALL(unit), p)) { 1189 sal_sprintf(eth_hig_str, "ETH"); 1190 } else { 1191 sal_sprintf(eth_hig_str, "HG2"); 1192 } 1193 if (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), p)) { 1194 sal_sprintf(line_ovsb_str, "OVSB"); 1195 } else { 1196 sal_sprintf(line_ovsb_str, "LINE"); 1197 } 1198 cli_out("\nDev Port %3d, Phy Port %3d, %3d G %s %s", 1199 p, si->port_l2p_mapping[p], port_speed / 1000, 1200 eth_hig_str, line_ovsb_str); 1201 } 1202 } 1203 1204 /* Open bcm config file */ 1205 fp = sal_fopen(fname, "r"); 1206 if (fp == NULL) { 1207 test_error(unit, "*ERROR: Cannot open bcm config file: '%s'\n", fname); 1208 rv = BCM_E_FAIL; 1209 goto done; 1210 } else { 1211 cli_out("\nLoading bcm config file: '%s'", fname); 1212 } 1213 1214 /* Dictionary */ 1215 dic_portmap = "portmap_"; 1216 dic_pbmp_xe = "pbmp_xport_xe"; 1217 dic_pbmp_os = "pbmp_oversubscribe"; 1218 dic_dev_bw = "device_bandwidth"; 1219 dic_higig = "bmp_higig"; 1220 1221 /* Initialize parameters */ 1222 for (i=0; i < SOC_MAX_NUM_PORTS; i++) { port_states[i] = 0; } 1223 for (i=1; i < SOC_MAX_NUM_PORTS; i++) { port_speeds[i] = SPEED_UI_0; } 1224 port_speeds[0] = SPEED_UI_10G; port_speeds[129] = SPEED_UI_1G; 1225 for (i=0; i < MAX_TSC_NUM; i++) { traffic[i] = PM_ENCAP__ETHRNT; } 1226 for (i=0; i < SOC_MAX_NUM_PORTS; i++) { lgc_2_phy_portmap[i] = 9999; } 1227 for (i=0; i < SOC_MAX_NUM_PORTS; i++) { os_bmp[i] = 0; xe_bmp[i] = 0; } 1228 1229 while (sal_fgets(line, sizeof(line), fp)) { 1230 if (sal_strstr(line, "#") != line) { 1231 if (sal_strlen(line) > 256) { 1232 sal_fclose(fp); 1233 rv = BCM_E_FAIL; 1234 goto done; 1235 } 1236 sal_strcpy(line_cpy1, line); 1237 split1 = sal_strtok(line_cpy1,"="); 1238 port_idx = 0; 1239 while (split1) { 1240 port_str[port_idx++] = split1; 1241 split1 = sal_strtok(NULL,"="); 1242 } 1243 tdm_chomp(port_str[1]); 1244 if (sal_strstr(line, dic_portmap)) { 1245 if (sal_strlen(port_str[1]) > 32) { 1246 sal_fclose(fp); 1247 rv = BCM_E_FAIL; 1248 goto done; 1249 } 1250 sal_strcpy(line_cpy2, port_str[1]); 1251 split2 = sal_strtok(line_cpy2,":"); 1252 port_data_idx = 0; 1253 while (split2) { 1254 port_data[port_data_idx++] = split2; 1255 split2 = sal_strtok(NULL,":"); 1256 } 1257 tmp_port = sal_atoi(port_data[0]); 1258 tmp_speed = sal_atoi(port_data[1]); 1259 if (tmp_port<129 && tmp_port>0) { 1260 port_speeds[tmp_port] = tmp_speed; 1261 port_states[tmp_port-1] = 9; 1262 } 1263 if (sal_strlen(port_str[0]) > 32) { 1264 sal_fclose(fp); 1265 rv = BCM_E_FAIL; 1266 goto done; 1267 } 1268 sal_strcpy(line_cpy3, port_str[0]); 1269 split3 = sal_strtok(line_cpy3,"_"); 1270 l2p_idx = 0; 1271 while (split3) { 1272 l2p_str[l2p_idx++] = split3; 1273 split3 = sal_strtok(NULL,"_"); 1274 } 1275 port_lgcID = sal_atoi(l2p_str[1]); 1276 if (port_lgcID > 0 && port_lgcID < SOC_MAX_NUM_PORTS) { 1277 lgc_2_phy_portmap[port_lgcID] = tmp_port; 1278 highest_lgcID = (port_lgcID>highest_lgcID) ? 1279 (port_lgcID) : (highest_lgcID); 1280 } 1281 } 1282 if (sal_strstr(line, dic_dev_bw)) { 1283 clk_freq = sal_atoi(port_str[1]); 1284 clk_freq /= 1000; 1285 /* Check clock frequency */ 1286 if (clk_freq != si->frequency) { 1287 test_error(unit, "*ERROR: Cannot change freq from %0d to %0d\n", 1288 si->frequency, clk_freq); 1289 } 1290 } 1291 if (sal_strstr(line, dic_pbmp_xe)) { 1292 if (sal_strlen(port_str[1]) > 32) { 1293 sal_fclose(fp); 1294 rv = BCM_E_FAIL; 1295 goto done; 1296 } 1297 sal_strcpy(line_cpy2, port_str[1]); 1298 split2 = sal_strtok(line_cpy2,"x"); 1299 port_data_idx=0; 1300 while (split2) { 1301 port_data[port_data_idx++] = split2; 1302 split2 = sal_strtok(NULL,"x"); 1303 } 1304 /* Potentially 128 bit, so cannot just strtol entire string */ 1305 j = 0; 1306 for (i = (strlen(port_data[1])-1); i >= 0; i--) { 1307 if ((j * 4 + 3) < SOC_MAX_NUM_PORTS) { 1308 convert_hex2bin(port_data[1][i], bmp_4bit); 1309 xe_bmp[j * 4 ] = bmp_4bit[0]; 1310 xe_bmp[j * 4 + 1] = bmp_4bit[1]; 1311 xe_bmp[j * 4 + 2] = bmp_4bit[2]; 1312 xe_bmp[j * 4 + 3] = bmp_4bit[3]; 1313 j++; 1314 } 1315 } 1316 } 1317 if (sal_strstr(line, dic_pbmp_os)) { 1318 if (sal_strlen(port_str[1]) > 32) { 1319 sal_fclose(fp); 1320 rv = BCM_E_FAIL; 1321 goto done; 1322 } 1323 sal_strcpy(line_cpy2, port_str[1]); 1324 split2 = sal_strtok(line_cpy2, "x"); 1325 port_data_idx = 0; 1326 while (split2) { 1327 port_data[port_data_idx++] = split2; 1328 split2 = sal_strtok(NULL, "x"); 1329 } 1330 /* Potentially 128 bit, so cannot just strtol entire string */ 1331 j = 0; 1332 for (i = (strlen(port_data[1]) - 1); i >= 0; i--) { 1333 if ((j * 4 + 3) < 128) { 1334 convert_hex2bin(port_data[1][i], bmp_4bit); 1335 os_bmp[j * 4 ] = bmp_4bit[0]; 1336 os_bmp[j * 4 + 1] = bmp_4bit[1]; 1337 os_bmp[j * 4 + 2] = bmp_4bit[2]; 1338 os_bmp[j * 4 + 3] = bmp_4bit[3]; 1339 j++; 1340 } 1341 } 1342 } 1343 if (sal_strstr(line, dic_higig)) { 1344 if (sal_strlen(port_str[1]) > 32) { 1345 sal_fclose(fp); 1346 rv = BCM_E_FAIL; 1347 goto done; 1348 } 1349 sal_strcpy(line_cpy2, port_str[1]); 1350 split2 = sal_strtok(line_cpy2, "x"); 1351 port_data_idx = 0; 1352 while (split2) { 1353 port_data[port_data_idx++] = split2; 1354 split2 = sal_strtok(NULL, "x"); 1355 } 1356 hg_bmp = strtol(port_data[1], NULL, 16); 1357 } 1358 } 1359 } 1360 1361 /* Set port state: oversub, linerate, combined */ 1362 for (i = 1; i < (SOC_MAX_NUM_PORTS - 1); i++) { 1363 port_phyID = lgc_2_phy_portmap[i]; 1364 if (port_phyID > 0 && port_phyID < (SOC_MAX_NUM_PORTS - 1)) { 1365 if (port_states[port_phyID - 1] == 9 && xe_bmp[i] == 1) { 1366 /* linerate/oversub */ 1367 port_states[port_phyID - 1] = (os_bmp[i] == 1) ? 1368 (PORT_STATE__OVERSUB) : (PORT_STATE__LINERATE); 1369 1370 /* Combined */ 1371 if (SOC_IS_TRIDENT2X(unit)) { 1372 switch (port_speeds[port_phyID]) { 1373 case SPEED_UI_120G : port_lanenum = 12; break; 1374 case SPEED_UI_100G : port_lanenum = 10; break; 1375 case SPEED_UI_42G : 1376 case SPEED_UI_40G : port_lanenum = 4; break; 1377 case SPEED_UI_21G_DUAL : 1378 case SPEED_UI_20G : port_lanenum = 2; break; 1379 case SPEED_UI_10G : 1380 case SPEED_UI_2p5G : 1381 case SPEED_UI_1G : port_lanenum = 1; break; 1382 default : port_lanenum = 0; break; 1383 } 1384 } 1385 if (SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) { 1386 switch (port_speeds[port_phyID]) { 1387 case SPEED_UI_100G : 1388 case SPEED_UI_40G : port_lanenum = 4; break; 1389 case SPEED_UI_50G : 1390 case SPEED_UI_41G_DUAL : 1391 case SPEED_UI_20G : port_lanenum = 2; break; 1392 case SPEED_UI_25G : 1393 case SPEED_UI_10G : port_lanenum = 1; break; 1394 default : port_lanenum = 0; break; 1395 } 1396 } 1397 for (j = 1; j < port_lanenum; j++){ 1398 port_states[port_phyID + j - 1] = PORT_STATE__COMBINE; 1399 } 1400 } 1401 } 1402 } 1403 1404 /* Set tsc type: higig, ethernet */ 1405 if (hg_bmp > 0) { 1406 for (i = 0; i < TDMV_NUM_TSC(unit); i++) { 1407 if ((((hg_bmp >> i) & 0x1) == 0x1)) { 1408 traffic[i] = PM_ENCAP__HIGIG2; 1409 } 1410 } 1411 } 1412 1413 /* Transfer port state to TDM-5 specification */ 1414 for (i = 1; i < (SOC_MAX_NUM_PORTS - 7); i++) { 1415 j = (i - 1) / TDMV_NUM_TSC_LANES; 1416 if (j < TDMV_NUM_TSC(unit)) { 1417 if (traffic[j] == PM_ENCAP__HIGIG2) { 1418 switch (port_states[i - 1]) { 1419 case PORT_STATE__LINERATE: 1420 port_states[i-1] = PORT_STATE__LINERATE_HG; 1421 break; 1422 case PORT_STATE__OVERSUB: 1423 port_states[i-1] = PORT_STATE__OVERSUB_HG; 1424 break; 1425 default: 1426 break; 1427 } 1428 } 1429 } 1430 } 1431 1432 sal_fclose(fp); 1433 1434 for (i = 1; i < (SOC_MAX_NUM_PORTS - 1); i++) { 1435 port_phyID = lgc_2_phy_portmap[i]; 1436 if (port_phyID > 0 && port_phyID < (SOC_MAX_NUM_PORTS - 1)) { 1437 if ((port_states[port_phyID-1] == PORT_STATE__LINERATE_HG) || 1438 (port_states[port_phyID-1] == PORT_STATE__OVERSUB_HG)) { 1439 switch (port_speeds[port_phyID]) { 1440 case 120: port_speeds[port_phyID] = 127; break; 1441 case 100: port_speeds[port_phyID] = 106; break; 1442 case 50: port_speeds[port_phyID] = 53; break; 1443 case 40: port_speeds[port_phyID] = 42; break; 1444 case 25: port_speeds[port_phyID] = 27; break; 1445 case 20: port_speeds[port_phyID] = 21; break; 1446 case 10: port_speeds[port_phyID] = 11; break; 1447 default: break; 1448 } 1449 } 1450 if ((port_states[port_phyID-1] == PORT_STATE__LINERATE) || 1451 (port_states[port_phyID-1] == PORT_STATE__OVERSUB)) { 1452 sal_sprintf(eth_hig_str, "ETH"); 1453 } else { 1454 sal_sprintf(eth_hig_str, "HG2"); 1455 } 1456 if ((port_states[port_phyID-1] == PORT_STATE__OVERSUB_HG) || 1457 (port_states[port_phyID-1] == PORT_STATE__OVERSUB)) { 1458 sal_sprintf(line_ovsb_str, "OVSB"); 1459 } else { 1460 sal_sprintf(line_ovsb_str, "LINE"); 1461 } 1462 cli_out("\nDev Port %3d, Phy Port %3d, %3d G %s %s", 1463 i, port_phyID, port_speeds[port_phyID], 1464 eth_hig_str, line_ovsb_str); 1465 } 1466 } 1467 1468 for (i = 0; i < TDMV_NUM_TSC(unit); i++) { 1469 port_idx = i * TDMV_NUM_TSC_LANES + 1; 1470 num_subport = 4; 1471 if (SOC_IS_TRIDENT2X(unit) && port_speeds[port_idx] >= 100) { 1472 num_subport = 12; 1473 i += 2; 1474 } 1475 for (j = 0; j < num_subport; j++) { 1476 speed[j] = port_speeds[port_idx + j] * 1000; 1477 } 1478 if (traffic[i] == PM_ENCAP__HIGIG2) { 1479 encap = BCM_PORT_ENCAP_HIGIG2; 1480 } else { 1481 encap = BCM_PORT_ENCAP_IEEE; 1482 } 1483 1484 rv = flex_tsc(unit, num_subport, port_idx, speed, encap); 1485 if (BCM_FAILURE(rv)) { 1486 cli_out("\nflex_tsc %0d: %s", port_idx, bcm_errmsg(rv)); 1487 break; 1488 } 1489 } 1490 1491 done: 1492 sal_free(port_speeds); 1493 sal_free(port_states); 1494 return rv; 1495 } 1496 1497 /* 1498 * Function: 1499 * flexport_by_tsc 1500 * Purpose: 1501 * Flex one TSC according to the command line inputs 1502 * Parameters: 1503 * unit: StrataSwitch Unit #. 1504 * tsc: TSC # 1505 * mode: target port speed/mode 1506 * 1507 * Returns: 1508 * BCM_E_XXXX 1509 */ 1510 1511 static bcm_error_t 1512 flexport_by_tsc(int unit, uint32 tsc, char *mode) 1513 { 1514 int rv = BCM_E_NONE; 1515 int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 1516 int num_subport = 4; 1517 int encap_enum = BCM_PORT_ENCAP_IEEE; 1518 1519 cli_out("\nFlexing TSC %d to %s", tsc, mode); 1520 1521 if (sal_strstr(mode, "4x0G") || sal_strstr(mode, "12x0G")) { 1522 cli_out("\nShutting down TSC %d", tsc); 1523 } else if (sal_strstr(mode, "1x100G") || sal_strstr(mode, "1x106G")) { 1524 speed[0] = 100000; 1525 if (SOC_IS_TRIDENT2X(unit)) { 1526 num_subport = 12; 1527 } 1528 } else if (SOC_IS_TRIDENT2X(unit) && 1529 (sal_strstr(mode, "1x120G") || sal_strstr(mode, "1x126G"))) { 1530 speed[0] = 120000; 1531 num_subport = 12; 1532 } else if (SOC_IS_TRIDENT2X(unit) && 1533 (sal_strstr(mode, "10x10G") || sal_strstr(mode, "10x11G"))) { 1534 speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000; 1535 speed[4] = 10000; speed[5] = 10000; speed[6] = 10000; speed[7] = 10000; 1536 speed[8] = 10000; speed[9] = 10000; 1537 num_subport = 12; 1538 } else if (SOC_IS_TRIDENT2X(unit) && 1539 (sal_strstr(mode, "12x10G") || sal_strstr(mode, "12x11G"))) { 1540 speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000; 1541 speed[4] = 10000; speed[5] = 10000; speed[6] = 10000; speed[7] = 10000; 1542 speed[8] = 10000; speed[9] = 10000; speed[10] = 10000; speed[11] = 10000; 1543 num_subport = 12; 1544 } else if (sal_strstr(mode, "50G+2x25G")) { 1545 speed[0] = 50000; speed[2] = 25000; speed[3] = 25000; 1546 } else if (sal_strstr(mode, "2x25G+50G")) { 1547 speed[0] = 25000; speed[1] = 25000; speed[2] = 50000; 1548 } else if (sal_strstr(mode, "20G+2x10G")) { 1549 speed[0] = 20000; speed[2] = 10000; speed[3] = 10000; 1550 } else if (sal_strstr(mode, "2x10G+20G")) { 1551 speed[0] = 10000; speed[1] = 10000; speed[2] = 20000; 1552 } else if (sal_strstr(mode, "40G+2x10G")) { 1553 speed[0] = 40000; speed[2] = 10000; speed[3] = 10000; 1554 } else if (sal_strstr(mode, "2x10G+40G")) { 1555 speed[0] = 10000; speed[1] = 10000; speed[2] = 40000; 1556 } else if (sal_strstr(mode, "1x50G") || sal_strstr(mode, "1x53G")) { 1557 speed[0] = 50000; 1558 } else if (sal_strstr(mode, "1x40G") || sal_strstr(mode, "1x42G")) { 1559 speed[0] = 40000; 1560 } else if (sal_strstr(mode, "1x25G") || sal_strstr(mode, "1x27G")) { 1561 speed[0] = 25000; 1562 } else if (sal_strstr(mode, "1x20G") || sal_strstr(mode, "1x21G")) { 1563 speed[0] = 20000; 1564 } else if ((sal_strstr(mode, "1x10G") || sal_strstr(mode, "1x11G"))) { 1565 speed[0] = 10000; 1566 } else if (sal_strstr(mode, "2x50G") || sal_strstr(mode, "2x53G")) { 1567 speed[0] = 50000; speed[2] = 50000; 1568 } else if (sal_strstr(mode, "2x40G") || sal_strstr(mode, "2x42G")) { 1569 speed[0] = 40000; speed[2] = 40000; 1570 } else if (sal_strstr(mode, "2x25G") || sal_strstr(mode, "2x27G")) { 1571 speed[0] = 25000; speed[2] = 25000; 1572 } else if (sal_strstr(mode, "2x20G") || sal_strstr(mode, "2x21G")) { 1573 speed[0] = 20000; speed[2] = 20000; 1574 } else if (sal_strstr(mode, "2x10G") || sal_strstr(mode, "2x11G")) { 1575 speed[0] = 10000; speed[2] = 10000; 1576 } else if (sal_strstr(mode, "40G+20G")) { 1577 speed[0] = 40000; speed[2] = 20000; 1578 } else if (sal_strstr(mode, "20G+40G")) { 1579 speed[0] = 20000; speed[2] = 40000; 1580 } else if (sal_strstr(mode, "4x25G") || sal_strstr(mode, "4x27G")) { 1581 speed[0] = 25000; speed[1] = 25000; speed[2] = 25000; speed[3] = 25000; 1582 } else if (sal_strstr(mode, "4x10G") || sal_strstr(mode, "4x11G")) { 1583 speed[0] = 10000; speed[1] = 10000; speed[2] = 10000; speed[3] = 10000; 1584 } else if (SOC_IS_TRIDENT2X(unit) && 1585 (sal_strstr(mode, "4x2.5G"))) { 1586 speed[0] = 2500; speed[1] = 2500; speed[2] = 2500; speed[3] = 2500; 1587 } else if (sal_strstr(mode, "4x1G")) { 1588 speed[0] = 1000; speed[1] = 1000; speed[2] = 1000; speed[3] = 1000; 1589 } else { 1590 test_error(unit, "*ERROR: Mode %s is not supported\n", mode); 1591 } 1592 1593 if (sal_strstr(mode, "11G") || sal_strstr(mode, "21G") || 1594 sal_strstr(mode, "27G") || sal_strstr(mode, "53G") || 1595 sal_strstr(mode, "42G") || sal_strstr(mode, "106G") || 1596 sal_strstr(mode, "127G")) { 1597 encap_enum = BCM_PORT_ENCAP_HIGIG2; 1598 } else { 1599 encap_enum = BCM_PORT_ENCAP_IEEE; 1600 } 1601 1602 rv = flex_tsc(unit, num_subport, tsc * TDMV_NUM_TSC_LANES + 1, speed, 1603 encap_enum); 1604 if (BCM_FAILURE(rv)) { 1605 cli_out("\nflex_tsc %0d: %s", 1606 tsc * TDMV_NUM_TSC_LANES + 1, bcm_errmsg(rv)); 1607 } 1608 1609 return rv; 1610 } 1611 1612 1613 /* 1614 * Function: 1615 * lossless_flood_cnt 1616 * Purpose: 1617 * Calculates no of packets to be set for the given port 1618 * Parameters: 1619 * unit: StrataSwitch Unit #. 1620 * port - Device port number 1621 * 1622 * Returns: 1623 * flood packet count for the given port. 1624 */ 1625 static uint32 1626 lossless_flood_cnt(int unit, int port) 1627 { 1628 uint32 pkt_size, flood_cnt = 0; 1629 int param_flood_cnt, param_pkt_size; 1630 flexport_t *flexport_p = flexport_parray[unit]; 1631 1632 param_flood_cnt = flexport_p->flood_pkt_cnt_param; 1633 param_pkt_size = flexport_p->pkt_size_param; 1634 1635 if (param_flood_cnt == 0) { 1636 if (param_pkt_size == 0) { 1637 pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port)); 1638 } else { 1639 pkt_size = param_pkt_size; 1640 } 1641 flood_cnt = stream_get_ll_flood_cnt(unit, port, pkt_size, NULL); 1642 } else { 1643 flood_cnt = param_flood_cnt; 1644 } 1645 1646 return (flood_cnt); 1647 } 1648 1649 static int 1650 get_packet_size(int unit, int port) 1651 { 1652 int pkt_size, flood_cnt, i; 1653 rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 1654 flexport_t *flexport_p = flexport_parray[unit]; 1655 1656 pkt_size = flexport_p->pkt_size_param; 1657 if(pkt_size == 0) { 1658 if (IS_HG_PORT(unit, port)) { 1659 pkt_size = HG2_WC_PKT_SIZE; 1660 } else { 1661 pkt_size = ENET_WC_PKT_SIZE; 1662 } 1663 } 1664 1665 if (pkt_size == 1) { 1666 if (flexport_p->flood_pkt_cnt_param == 0) { 1667 flood_cnt = lossless_flood_cnt(unit, port); 1668 } else { 1669 flood_cnt = flexport_p->flood_pkt_cnt_param; 1670 } 1671 for(i = 0; i< flood_cnt; i++) { 1672 pkt_size += rate_calc_p->rand_pkt_sizes[port][i]; 1673 } 1674 pkt_size = pkt_size / flood_cnt; 1675 } 1676 return pkt_size; 1677 } 1678 1679 /* 1680 * Function: 1681 * set_port_property_arrays 1682 * Purpose: 1683 * Set rand_pkt_sizes, port_oversub, and exp_rates arrays. 1684 * Parameters: 1685 * unit: StrataSwitch Unit #. 1686 * pbmp - Device port bitmap 1687 * pkt_size_param - Packet size in bytes 1688 * max_num_cells_param - Maximum number of cells 1689 * 1690 * Returns: 1691 * BCM_E_XXXX 1692 */ 1693 1694 static bcm_error_t 1695 set_port_property_arrays(int unit, pbmp_t pbmp, int pkt_size_param, 1696 int max_num_cells_param) 1697 { 1698 int p, j, pkt_size; 1699 stream_rate_t *stream_rate_calc_p; 1700 rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 1701 flexport_t *flexport_p = flexport_parray[unit]; 1702 1703 stream_rate_calc_p = sal_alloc(sizeof(stream_rate_t), "streaming_rate"); 1704 sal_memset(stream_rate_calc_p, 0, sizeof(stream_rate_t)); 1705 1706 stream_rate_calc_p->mode = 0; 1707 stream_rate_calc_p->emulation_param = flexport_p->emulation_param; 1708 stream_rate_calc_p->tolerance_lr = flexport_p->rate_tolerance_lr_param; 1709 stream_rate_calc_p->tolerance_os = flexport_p->rate_tolerance_ov_param; 1710 SOC_PBMP_CLEAR(stream_rate_calc_p->pbmp); 1711 PBMP_ITER(PBMP_E_ALL(unit), p) { 1712 if (p < SOC_MAX_NUM_PORTS) { 1713 stream_rate_calc_p->pkt_size = get_packet_size(unit, p); 1714 SOC_PBMP_PORT_ADD(stream_rate_calc_p->pbmp, p); 1715 } 1716 } 1717 1718 if (SOC_FAILURE(stream_calc_exp_rate_by_rx(unit, rate_calc_p->exp_rate, stream_rate_calc_p))) { 1719 cli_out("\n*ERROR, stream_calc_exp_rate_by_rx failed.\n"); 1720 sal_free(stream_rate_calc_p); 1721 return BCM_E_FAIL; 1722 } 1723 sal_free(stream_rate_calc_p); 1724 1725 PBMP_ITER(pbmp, p) { 1726 if (p < SOC_MAX_NUM_PORTS) { 1727 for (j = 0; j < TARGET_CELL_COUNT; j++) { 1728 do { 1729 /* coverity[dont_call : FALSE] */ 1730 pkt_size = (sal_rand() % (MTU - MIN_PKT_SIZE + 1)) + 1731 MIN_PKT_SIZE; 1732 } while (stream_get_pkt_cell_cnt(unit, pkt_size, p) > max_num_cells_param); 1733 rate_calc_p->rand_pkt_sizes[p][j] = pkt_size; 1734 } 1735 } 1736 } 1737 1738 return BCM_E_NONE; 1739 } 1740 1741 /* 1742 * Function: 1743 * set_up_ports 1744 * Purpose: 1745 * Enable port bridging and HiGig lookup for HG2 ports 1746 * Parameters: 1747 * unit - StrataSwitch Unit #. 1748 * pbmp - Device port bitmap 1749 * 1750 * Returns: 1751 * Nothing 1752 */ 1753 1754 static void 1755 set_up_ports(int unit, pbmp_t pbmp) 1756 { 1757 int i, p; 1758 lport_tab_entry_t lport_tab_entry; 1759 port_tab_entry_t port_tab_entry; 1760 soc_field_t ihg_lookup_fields[] = 1761 { HYBRID_MODE_ENABLEf, USE_MH_PKT_PRIf, USE_MH_VIDf, HG_LOOKUP_ENABLEf, 1762 REMOVE_MH_SRC_PORTf 1763 }; 1764 uint32 ihg_lookup_values[] = { 0x0, 0x1, 0x1, 0x1, 0x0 }; 1765 1766 cli_out("\nEnabling HG_LOOKUP on HG ports"); 1767 1768 PBMP_ITER(pbmp, p) { 1769 if (p < SOC_MAX_NUM_PORTS && IS_HG_PORT(unit, p)) { 1770 soc_reg_fields32_modify(unit, IHG_LOOKUPr, p, 5, 1771 ihg_lookup_fields, ihg_lookup_values); 1772 } 1773 } 1774 1775 cli_out("\nEnabling Port bridging"); 1776 1777 for (i = 0; i < soc_mem_index_max(unit, LPORT_TABm); i++) { 1778 (void) soc_mem_read(unit, LPORT_TABm, COPYNO_ALL, i, 1779 lport_tab_entry.entry_data); 1780 soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data, 1781 ALLOW_SRC_MODf, 0x1); 1782 soc_mem_field32_set(unit, LPORT_TABm, lport_tab_entry.entry_data, 1783 PORT_BRIDGEf, 0x1); 1784 (void) soc_mem_write(unit, LPORT_TABm, COPYNO_ALL, i, 1785 lport_tab_entry.entry_data); 1786 } 1787 1788 for (i = 0; i < soc_mem_index_max(unit, PORT_TABm); i++) { 1789 (void) soc_mem_read(unit, PORT_TABm, COPYNO_ALL, i, 1790 port_tab_entry.entry_data); 1791 soc_mem_field32_set(unit, PORT_TABm, port_tab_entry.entry_data, 1792 PORT_BRIDGEf, 0x1); 1793 (void) soc_mem_write(unit, PORT_TABm, COPYNO_ALL, i, 1794 port_tab_entry.entry_data); 1795 } 1796 } 1797 1798 /* 1799 * Function: 1800 * set_up_streams 1801 * Purpose: 1802 * VLAN programming. Each port is put on an unique VLAN. 1803 * Parameters: 1804 * unit: StrataSwitch Unit #. 1805 * pbmp - Device port bitmap 1806 * vlan_bmp - bitmap of device ports that have vlan set up 1807 * 1808 * Returns: 1809 * vlan_pbmp - bitmap of device ports that have vlan set up. 1810 */ 1811 1812 static pbmp_t 1813 set_up_streams(int unit, pbmp_t pbmp, pbmp_t vlan_pbmp) 1814 { 1815 int p; 1816 pbmp_t pbm, ubm; 1817 bcm_vlan_t vlan; 1818 1819 BCM_PBMP_CLEAR(ubm); 1820 1821 PBMP_ITER(pbmp, p) { 1822 if (p < SOC_MAX_NUM_PORTS) { 1823 vlan = VLAN + p; 1824 if (SOC_PBMP_MEMBER(vlan_pbmp, p)) { 1825 stream_set_vlan(unit, vlan, 1); 1826 } else { 1827 vlan = VLAN + p; 1828 BCM_PBMP_CLEAR(pbm); 1829 bcm_vlan_create(unit, vlan); 1830 BCM_PBMP_PORT_ADD(pbm, p); 1831 bcm_vlan_port_add(unit, vlan, pbm, ubm); 1832 } 1833 } 1834 } 1835 1836 SOC_PBMP_OR(vlan_pbmp, pbmp); 1837 1838 return vlan_pbmp; 1839 } 1840 1841 1842 /* 1843 * Function: 1844 * send_pkts 1845 * Purpose: 1846 * Sends packet for all the ports in the port bitmap 1847 * Parameters: 1848 * unit: StrataSwitch Unit #. 1849 * pbmp - port bitmap 1850 * pkt_size_param - 1851 * pkt_seed - 1852 * 1853 * Returns: 1854 * flood packet count for the given port. 1855 */ 1856 static void 1857 send_pkts(int unit, pbmp_t pbmp, uint32 pkt_size_param, uint32 pkt_seed) 1858 { 1859 int port; 1860 uint8 mac_da[] = MAC_DA; 1861 uint8 mac_sa[] = MAC_SA; 1862 uint32 pkt_size; 1863 stream_pkt_t *tx_pkt; 1864 flexport_t *flexport_p = flexport_parray[unit]; 1865 rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 1866 1867 tx_pkt = sal_alloc(sizeof(stream_pkt_t), "tx_pkt"); 1868 sal_memset(tx_pkt, 0, sizeof(stream_pkt_t)); 1869 1870 cli_out("\n==================================================\n"); 1871 cli_out("\nSending packets ...\n\n"); 1872 PBMP_ITER(pbmp, port) { 1873 if (port < SOC_MAX_NUM_PORTS) { 1874 if (flexport_p->pkt_size_param == 0) { 1875 pkt_size = stream_get_wc_pkt_size(unit, IS_HG_PORT(unit, port)); 1876 } else { 1877 pkt_size = flexport_p->pkt_size_param; 1878 } 1879 1880 tx_pkt->port = port; 1881 tx_pkt->num_pkt = lossless_flood_cnt(unit, port); 1882 tx_pkt->pkt_seed = pkt_seed; 1883 tx_pkt->pkt_size = pkt_size; 1884 cli_out("\nSending packets on port %0d size %0d num %0d.", port, pkt_size, tx_pkt->num_pkt); 1885 if(pkt_size_param == 1) { 1886 tx_pkt->rand_pkt_size_en = 1; 1887 tx_pkt->rand_pkt_size = rate_calc_p->rand_pkt_sizes[port]; 1888 } else { 1889 tx_pkt->rand_pkt_size_en = 0; 1890 tx_pkt->rand_pkt_size = NULL; 1891 } 1892 tx_pkt->tx_vlan = VLAN + port; 1893 sal_memcpy(tx_pkt->mac_da, mac_da, NUM_BYTES_MAC_ADDR); 1894 sal_memcpy(tx_pkt->mac_sa, mac_sa, NUM_BYTES_MAC_ADDR); 1895 stream_tx_pkt(unit, tx_pkt); 1896 } 1897 } 1898 sal_free(tx_pkt); 1899 } 1900 1901 /* 1902 * Function: 1903 * start_rate_measurement 1904 * Purpose: 1905 * Get current time, packet count & byte count needed to calculate port 1906 * rate 1907 * Parameters: 1908 * unit - StrataSwitch Unit #. 1909 * pbmp - Device port bitmap to be used 1910 * emulation_param - 1: test run in emulator platform 1911 * 0: test run is actual hardware(chip) 1912 * 1913 * Returns: 1914 * SOC_E_XXXX 1915 */ 1916 static bcm_error_t 1917 start_rate_measurement(int unit, pbmp_t pbmp, uint32 emulation_param) 1918 { 1919 rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 1920 1921 return record_rate_information(unit, emulation_param, pbmp, rate_calc_p->stime, 1922 rate_calc_p->tpkt_start, rate_calc_p->tbyt_start); 1923 1924 } 1925 1926 /* 1927 * Function: 1928 * check_rates 1929 * Purpose: 1930 * Check rates against expected rates. 1931 * Parameters: 1932 * unit - StrataSwitch Unit #. 1933 * pbmp - Device port bitmap to be checked 1934 * tolerance_lr - Percentage of rate tolerance for line rate ports 1935 * tolerance_os - Percentage of rate tolerance for oversub ports 1936 * 1937 * Returns: 1938 * SOC_E_XXXX 1939 */ 1940 1941 static bcm_error_t 1942 check_rates(int unit, pbmp_t pbmp, uint32 tolerance_lr, 1943 uint32 tolerance_os, uint32 emulation_param) 1944 { 1945 uint64 *etime; 1946 uint64 *tpkt_end; 1947 uint64 *tbyt_end; 1948 uint64 *rate; 1949 rate_calc_t *rate_calc_p = rate_calc_parray[unit]; 1950 bcm_error_t rv = BCM_E_NONE; 1951 1952 etime = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1953 "etime"); 1954 tpkt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1955 "tpkt_end"); 1956 tbyt_end = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1957 "tbyt_end"); 1958 rate = (uint64 *) sal_alloc(SOC_MAX_NUM_PORTS * sizeof(uint64), 1959 "rate"); 1960 1961 sal_memset(etime, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 1962 sal_memset(tpkt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 1963 sal_memset(tbyt_end, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 1964 sal_memset(rate, 0, sizeof(uint64) * SOC_MAX_NUM_PORTS); 1965 1966 rv = record_rate_information(unit, emulation_param, pbmp, etime, 1967 tpkt_end, tbyt_end); 1968 1969 calc_act_port_rate(unit, pbmp, rate_calc_p->stime, etime, 1970 rate_calc_p->tpkt_start, tpkt_end, 1971 rate_calc_p->tbyt_start, tbyt_end, rate); 1972 1973 rv = compare_rates(unit, pbmp, tolerance_lr, tolerance_os, 1974 rate_calc_p->exp_rate, rate); 1975 1976 if (rv != BCM_E_NONE) { 1977 test_error(unit, "********** RATE CHECK FAILED ***********\n"); 1978 } else { 1979 cli_out("\n********** RATE CHECK PASSED ***********"); 1980 } 1981 1982 sal_free(etime); 1983 sal_free(tpkt_end); 1984 sal_free(tbyt_end); 1985 sal_free(rate); 1986 return rv; 1987 } 1988 1989 /* 1990 * Function: 1991 * flexport_test_init 1992 * Purpose: 1993 * Test init function. Parse CLI params and do necessary init. 1994 * Parameters: 1995 * unit - StrataSwitch Unit #. 1996 * a - Pointer to arguments 1997 * 1998 * Returns: 1999 * SOC_E_XXXX 2000 */ 2001 2002 int 2003 flexport_test_init(int unit, args_t *a, void **pa) 2004 { 2005 flexport_t *flexport_p; 2006 rate_calc_t *rate_calc_p; 2007 int i, tsc, sub_port, pport, lport; 2008 int encap; 2009 int num_subport = 4; 2010 int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2011 2012 flexport_p = flexport_parray[unit]; 2013 flexport_p = sal_alloc(sizeof(flexport_t), "flexport_test"); 2014 sal_memset(flexport_p, 0, sizeof(flexport_t)); 2015 flexport_parray[unit] = flexport_p; 2016 2017 rate_calc_p = rate_calc_parray[unit]; 2018 rate_calc_p = sal_alloc(sizeof(rate_calc_t), "streaming_library"); 2019 sal_memset(rate_calc_p, 0, sizeof(rate_calc_t)); 2020 rate_calc_parray[unit] = rate_calc_p; 2021 2022 cli_out("\nCalling flexport_test_init"); 2023 flexport_parse_test_params(unit, a); 2024 2025 flexport_p->test_fail = 0; 2026 2027 if(flexport_p->emulation_param) { 2028 start_cmic_timesync(unit); 2029 } 2030 2031 BCM_IF_ERROR_RETURN(soc_counter_status(unit, &flexport_p->counter_flags, 2032 &flexport_p->counter_interval, 2033 &flexport_p->counter_pbm)); 2034 if (flexport_p->counter_interval > 0) { 2035 cli_out("\nDisabling counter collection"); 2036 soc_counter_stop(unit); 2037 } 2038 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_get(unit, 2039 &flexport_p->linkscan_enable)); 2040 if (flexport_p->linkscan_enable) { 2041 cli_out("\nDisabling linkscan"); 2042 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 0)); 2043 } 2044 2045 if (flexport_p->emulation_param) { 2046 /* The server address and port number changes in each session. */ 2047 /* So, the image must be recompiled after changing the following */ 2048 /* code before every session. */ 2049 flexport_p->sockfd = connectToSocket(flexport_p->socket_num_param, 2050 flexport_p->server_name_param); 2051 2052 /* Initialize tsc_cfg_buffer*/ 2053 for (i = 0; i < 12; i++) { 2054 sal_memset(flexport_p->tsc_cfg_buffer[i], 0, TCP_CMD_BUF_LEN); 2055 } 2056 flexport_p->tsc_cfg_cmds = 0; 2057 flexport_p->tsc_cfg_ptr = 0; 2058 2059 /* Perform TSC config based on SOC_INFO*/ 2060 if(flexport_p->init_tsc_shim) { 2061 for(tsc = 0; tsc < TDMV_NUM_TSC(unit); tsc++) { 2062 encap = BCM_PORT_ENCAP_IEEE; 2063 for(sub_port = 0; sub_port < num_subport; sub_port++) { 2064 pport = 1 + (tsc * 4) + sub_port; 2065 lport = SOC_INFO(unit).port_p2l_mapping[pport]; 2066 2067 speed[sub_port] = 0; 2068 if(lport == -1) continue; 2069 2070 if(IS_HG_PORT(unit, lport)) { 2071 encap = BCM_PORT_ENCAP_HIGIG2; 2072 } 2073 2074 BCM_IF_ERROR_RETURN(bcm_port_speed_get(unit, lport, &speed[sub_port])); 2075 } 2076 config_tsc_shim(unit, tsc, num_subport, speed, encap); 2077 } 2078 } 2079 } 2080 2081 return BCM_E_NONE; 2082 } 2083 2084 2085 /* 2086 * Function: 2087 * flexport_test 2088 * Purpose: 2089 * Set up ports/streams and send packets. 2090 * Parameters: 2091 * unit - StrataSwitch Unit #. 2092 * a - Pointer to arguments 2093 * 2094 * Returns: 2095 * SOC_E_XXXX 2096 */ 2097 2098 int 2099 flexport_test(int unit, args_t *a, void *pa) 2100 { 2101 int i, tsc, sub_port, pport, lport, port; 2102 pbmp_t stop_traffic_pbmp; 2103 pbmp_t start_traffic_pbmp; 2104 uint8 mac_da[] = MAC_DA; 2105 uint8 mac_sa[] = MAC_SA; 2106 flexport_t *flexport_p; 2107 stream_integrity_t *pkt_intg; 2108 uint64 val64; 2109 int encap; 2110 int speed[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 2111 int rv = BCM_E_NONE; 2112 2113 flexport_p = flexport_parray[unit]; 2114 2115 if (flexport_p->bad_input) { 2116 goto done; 2117 } 2118 2119 cli_out("\nCalling flexport_test"); 2120 2121 flexport_p->pkt_seed = sal_rand(); 2122 stream_set_lpbk(unit, PBMP_PORT_ALL(unit), flexport_p->loopback_mode_param); 2123 stream_turn_off_cmic_mmu_bkp(unit); 2124 stream_turn_off_fc(unit, PBMP_PORT_ALL(unit)); 2125 set_port_property_arrays(unit, PBMP_PORT_ALL(unit), 2126 flexport_p->pkt_size_param, 2127 flexport_p->max_num_cells_param); 2128 set_up_ports(unit, PBMP_PORT_ALL(unit)); 2129 flexport_p->vlan_pbmp = set_up_streams(unit, PBMP_PORT_ALL(unit), 2130 flexport_p->vlan_pbmp); 2131 send_pkts(unit, PBMP_PORT_ALL(unit), flexport_p->pkt_size_param, 2132 flexport_p->pkt_seed); 2133 2134 cli_out("\nWait 2s for traffic to stabilize"); 2135 sal_sleep(2); 2136 start_rate_measurement(unit, PBMP_PORT_ALL(unit), flexport_p->emulation_param); 2137 cli_out("\nMeasuring Rate over a period of %0ds", 2138 flexport_p->rate_calc_interval_param); 2139 sal_sleep(flexport_p->rate_calc_interval_param); 2140 2141 flexport_p->num_del = 0; 2142 flexport_p->num_add = 0; 2143 for(i = 0; i < SOC_MAX_NUM_PIPES; i++) { 2144 flexport_p->last_assigned_port[i] = -1; 2145 } 2146 SOC_PBMP_CLEAR(stop_traffic_pbmp); 2147 SOC_PBMP_CLEAR(start_traffic_pbmp); 2148 SOC_PBMP_CLEAR(flexport_p->port_down_pbmp); 2149 SOC_PBMP_CLEAR(flexport_p->port_up_pbmp); 2150 SOC_PBMP_CLEAR(flexport_p->speed_change_pbmp); 2151 if (flexport_p->flex_by_command_line) { 2152 for (i = 0; i < TDMV_NUM_TSC(unit); i++) { 2153 if (flexport_p->tsc_param[i] != NULL) { 2154 BCM_IF_ERROR_RETURN(flexport_by_tsc(unit, i, 2155 flexport_p->tsc_param[i])); 2156 } 2157 } 2158 } else if (flexport_p->config_file_name != NULL){ 2159 BCM_IF_ERROR_RETURN(flexport_by_config_file(unit, 2160 flexport_p->config_file_name)); 2161 } 2162 2163 stop_traffic_pbmp = flexport_p->port_down_pbmp; 2164 BCM_PBMP_OR(stop_traffic_pbmp, flexport_p->speed_change_pbmp); 2165 if (BCM_PBMP_NOT_NULL(stop_traffic_pbmp)) { 2166 if (stream_chk_mib_counters(unit, stop_traffic_pbmp, 0) != BCM_E_NONE) { 2167 flexport_p->test_fail = 1; 2168 } 2169 2170 if (check_rates(unit, stop_traffic_pbmp, 2171 flexport_p->rate_tolerance_lr_param, 2172 flexport_p->rate_tolerance_ov_param, 2173 flexport_p->emulation_param) != BCM_E_NONE) { 2174 flexport_p->test_fail = 1; 2175 } 2176 2177 if (flexport_p->check_packet_integrity_param != 0) { 2178 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity"); 2179 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 2180 2181 pkt_intg->rx_pbmp = stop_traffic_pbmp; 2182 PBMP_ITER(stop_traffic_pbmp, port) { 2183 if (port < SOC_MAX_NUM_PORTS) { 2184 pkt_intg->port_pkt_seed[port] = flexport_p->pkt_seed; 2185 pkt_intg->port_flood_cnt[port] = lossless_flood_cnt(unit, port); 2186 pkt_intg->rx_vlan[port] = VLAN + port; 2187 pkt_intg->tx_vlan[port] = VLAN + port; 2188 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR); 2189 sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR); 2190 } 2191 } 2192 rv = stream_chk_pkt_integrity(unit, pkt_intg); 2193 if (rv != BCM_E_NONE) { 2194 flexport_p->test_fail = 1; 2195 } 2196 sal_free(pkt_intg); 2197 } 2198 } 2199 2200 if (flexport_p->num_del + flexport_p->num_add > 0) { 2201 stream_set_lpbk(unit, flexport_p->port_down_pbmp, BCM_PORT_LOOPBACK_NONE); 2202 flexport_call_bcm_api(unit); 2203 stream_set_lpbk(unit, flexport_p->port_up_pbmp, flexport_p->loopback_mode_param); 2204 } 2205 2206 if (flexport_p->emulation_param) { 2207 for(tsc = 0; tsc < TDMV_NUM_TSC(unit); tsc++) { 2208 if(flexport_p->flex_tsc_map[tsc] == 1) { 2209 encap = BCM_PORT_ENCAP_IEEE; 2210 for(sub_port = 0; sub_port < TDMV_NUM_TSC_LANES; sub_port++) { 2211 pport = 1 + (tsc * 4) + sub_port; 2212 lport = SOC_INFO(unit).port_p2l_mapping[pport]; 2213 2214 speed[sub_port] = 0; 2215 if(lport == -1) continue; 2216 2217 if(IS_HG_PORT(unit, lport)) { 2218 encap = BCM_PORT_ENCAP_HIGIG2; 2219 } 2220 2221 BCM_IF_ERROR_RETURN(bcm_port_speed_get(unit, lport, &speed[sub_port])); 2222 } 2223 config_tsc_shim(unit, tsc, TDMV_NUM_TSC_LANES, speed, encap); 2224 } 2225 } 2226 } 2227 2228 start_traffic_pbmp = flexport_p->port_up_pbmp; 2229 BCM_PBMP_OR(start_traffic_pbmp, flexport_p->speed_change_pbmp); 2230 2231 if (flexport_p->clear_new_port_counts) { 2232 COMPILER_64_ZERO(val64); 2233 BCM_IF_ERROR_RETURN(soc_counter_set_by_port(unit, start_traffic_pbmp, val64)); 2234 } 2235 2236 stream_turn_off_fc(unit, flexport_p->port_up_pbmp); 2237 set_port_property_arrays(unit, start_traffic_pbmp, 2238 flexport_p->pkt_size_param, 2239 flexport_p->max_num_cells_param); 2240 set_up_ports(unit, flexport_p->port_up_pbmp); 2241 flexport_p->vlan_pbmp = set_up_streams(unit, start_traffic_pbmp, 2242 flexport_p->vlan_pbmp); 2243 send_pkts(unit, start_traffic_pbmp, flexport_p->pkt_size_param, 2244 flexport_p->pkt_seed); 2245 2246 2247 cli_out("\nWait 2s for traffic to stabilize"); 2248 sal_sleep(2); 2249 2250 start_rate_measurement(unit, start_traffic_pbmp, flexport_p->emulation_param); 2251 2252 cli_out("\nMeasuring Rate over a period of %0ds", 2253 flexport_p->rate_calc_interval_param); 2254 sal_sleep(flexport_p->rate_calc_interval_param); 2255 2256 if (stream_chk_mib_counters(unit, PBMP_PORT_ALL(unit), 0) != BCM_E_NONE) { 2257 flexport_p->test_fail = 1; 2258 } 2259 if (check_rates(unit, PBMP_PORT_ALL(unit), 2260 flexport_p->rate_tolerance_lr_param, 2261 flexport_p->rate_tolerance_ov_param, 2262 flexport_p->emulation_param) != BCM_E_NONE) { 2263 flexport_p->test_fail = 1; 2264 } 2265 if (flexport_p->check_packet_integrity_param != 0) { 2266 pkt_intg = sal_alloc(sizeof(stream_integrity_t), "pkt integrity"); 2267 sal_memset(pkt_intg, 0, sizeof(stream_integrity_t)); 2268 2269 pkt_intg->rx_pbmp = PBMP_PORT_ALL(unit); 2270 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 2271 if (port < SOC_MAX_NUM_PORTS) { 2272 pkt_intg->port_pkt_seed[port] = flexport_p->pkt_seed; 2273 pkt_intg->port_flood_cnt[port] = lossless_flood_cnt(unit, port); 2274 pkt_intg->rx_vlan[port] = VLAN + port; 2275 pkt_intg->tx_vlan[port] = VLAN + port; 2276 sal_memcpy(pkt_intg->mac_da[port], mac_da, NUM_BYTES_MAC_ADDR); 2277 sal_memcpy(pkt_intg->mac_sa[port], mac_sa, NUM_BYTES_MAC_ADDR); 2278 } 2279 } 2280 rv = stream_chk_pkt_integrity(unit, pkt_intg); 2281 if (rv != BCM_E_NONE) { 2282 flexport_p->test_fail = 1; 2283 } 2284 sal_free(pkt_intg); 2285 } 2286 2287 done: 2288 return rv; 2289 } 2290 2291 2292 /* 2293 * Function: 2294 * flexport_test_cleanup 2295 * Purpose: 2296 * Do test end checks and free all allocated memory. 2297 * Parameters: 2298 * unit - StrataSwitch Unit #. 2299 * a - Pointer to arguments 2300 * 2301 * Returns: 2302 * SOC_E_XXXX 2303 */ 2304 2305 int 2306 flexport_test_cleanup(int unit, void *pa) 2307 { 2308 flexport_t *flexport_p; 2309 rate_calc_t *rate_calc_p; 2310 int rv = BCM_E_NONE; 2311 2312 cli_out("\nCalling flexport_test_cleanup"); 2313 2314 flexport_p = flexport_parray[unit]; 2315 2316 if (flexport_p->emulation_param) { 2317 close(flexport_p->sockfd); 2318 } 2319 2320 if (flexport_p->linkscan_enable) { 2321 cli_out("\nEnabling linkscan"); 2322 BCM_IF_ERROR_RETURN(bcm_linkscan_mode_set_pbm(unit, PBMP_PORT_ALL(unit), 2323 BCM_LINKSCAN_MODE_SW)); 2324 BCM_IF_ERROR_RETURN(bcm_linkscan_enable_set(unit, 1)); 2325 } 2326 if (flexport_p->counter_interval > 0) { 2327 cli_out("\nEnabling counter collection with interval %0d", flexport_p->counter_interval); 2328 BCM_IF_ERROR_RETURN(soc_counter_start(unit, flexport_p->counter_flags, 2329 flexport_p->counter_interval, 2330 PBMP_PORT_ALL(unit))); 2331 } 2332 2333 if (flexport_p->bad_input == 1) { 2334 flexport_p->test_fail = 1; 2335 } 2336 2337 if (flexport_p->test_fail == 1) { 2338 rv = BCM_E_FAIL; 2339 } 2340 2341 rate_calc_p = rate_calc_parray[unit]; 2342 2343 sal_free(flexport_p); 2344 sal_free(rate_calc_p); 2345 bcm_vlan_init(unit); 2346 2347 cli_out("\n"); 2348 2349 return rv; 2350 } 2351 2352 #endif /*(BCM_ESW_SUPPORT) && \ 2353 (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT)) && \ 2354 !defined(NO_SAL_APPL) && (!defined(__KERNEL__)) */