traffic.c (111796B)
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 * XGS/StrataSwitch Traffic Generator aka. "Traffic, Traf-Test, Snake, etc." 8 * 9 * Switching API Stress Test using A/B Ethernet port pairs as 10 * load generators. Different from Snake test in that packet flow 11 * is between a source and sink port pair (A/B). 12 * 13 * When stress-testing XGS/StrataSwitch devices, usually, one will require 14 * a SmartBits (TM) or IXIA (TM) network testing device to spray 15 * frames to all of the ports and make them switch at line rate. 16 * 17 * The purpose of this test is to configure a pair of ports as 18 * transmitters and receivers while the switch ASIC is configured to only 19 * forward a frame between these two port pairs. 20 * 21 * The CPU then injects a frame into the port pairs going one 22 * direction or the other (or bidirectional), and the packet loops 23 * forever between the port pairs until the H/W fails, or the user 24 * stops the test. Typically, this happens at layer 2, using unicast, 25 * broadcast, multicast, or VLAN traffic, however extensions for layer3 26 * and higher (via the FFP) are possible. 27 * 28 * When testing, a "golden" switch (one known to be free of H/W bugs) 29 * is stress tested and the result is that the port-pairs should 30 * forward the frame forever. Failure for the ASIC to do so indicates 31 * faulty hardware and the problem should be investigated and 32 * debugged. An interesting feature of the XGS/StrataSwitch family of 33 * devices is that they should forward traffic at line rate for all 34 * layers of the test (e.g. MAC, PHY, Wire at 10Mbps, 100Mbps, 1Gbps, etc). 35 * 36 * In addition, this test allows the switch hardware to be used to 37 * test itself, without the cost of a SmartBits or IXIA testing device 38 * per switch; moreover, this speeds up testing as any switch which 39 * passes this traffic test is known to pass a forwarding test between 40 * two theoretical hosts. 41 * 42 * 43 * MAC/PHY (Broadcast Test) 44 * 45 * In the MAC or PHY tests, a VLAN is created with each port pair 46 * (A/B) as a member. The PVLAN table reflects the same VLAN ID 47 * and an untagged packet is sent out the port (with the ports in 48 * loopback) with the matching VLAN. As the packet ingresses into 49 * the switch, a DLF occurs, and the resulting unknown unicast or 50 * broadcast frame floods the VLAN, and packets swirl between 51 * ports A/B at line rate. 52 * 53 * For example, assuming two ports A(ge0), and B (ge1): 54 * 55 * vlan create 10 PBM=portA,portB UBM=portA,portB 56 * pvlan set portA VIDA 57 * pvlan set portB VIDA 58 * 59 * tx 1 PBM=portA UBM=portA L=68 VL=10 P=0x12345678 PI=1 \ 60 * SM=00:00:00:00:00:02 SMI=0 DM=ff:ff:ff:ff:ff:ff DMI=0 \ 61 * COS=0 CRC=Recompute 62 * 63 * tx 1 PBM=portB UBM=portB L=68 VL=10 P=0x12345678 PI=1 \ 64 * SM=00:00:00:00:00:02 SMI=0 DM=ff:ff:ff:ff:ff:ff DMI=0 \ 65 * COS=0 CRC=Recompute 66 * 67 * 68 * External (Unicast Test) 69 * 70 * In external test mode, a VLAN is created for each port (A/B) 71 * and both ports are in the tagged and untagged bitmaps. Next, 72 * the PVLAN table is setup with a unique vlan for both A and B. 73 * Finally, an L2 address is setup for each port in the ARL with a 74 * MAC address (of the port), however, the VLAN entry points to 75 * the opposite port, so that when a packet comes back in the link 76 * partner's port, it gets retagged with a VLAN which will flood 77 * it to the originator. 78 * 79 * For example, assuming two ports A(ge0), and B (ge1): 80 * 81 * vlan create A PBM=portA,portB UBM=portA,portB 82 * vlan create B PBM=portA,portB UBM=portA,portB 83 * pvlan set portA A 84 * pvlan set portB B 85 * 86 * l2 add PBM=portA MAC=00:00:00:00:00:portA V=B ST=T 87 * l2 add PBM=portB MAC=00:00:00:00:00:portB V=A ST=T 88 * 89 * tx 1 PBM=portB UBM=portB L=68 VL=A P=0x12345678 PI=1 \ 90 * SM=00:00:00:00:00:portA SMI=0 DM=00:00:00:00:00:portB \ 91 * DMI=0 COS=0 CRC=Recompute 92 * 93 * tx 1 PBM=portA UBM=portA L=68 VL=B P=0x12345678 PI=1 \ 94 * SM=00:00:00:00:00:portB SMI=0 DM=00:00:00:00:00:portA \ 95 * DMI=0 COS=0 CRC=Recompute 96 * 97 * General 98 * 99 * Both ports are setup to transmit and receive a packet (full-duplex) 100 * by default. 101 * 102 * The test runs forever, looping and reporting statistics until it 103 * detects that a packet is lost, at which point an error is 104 * reported and relevant statistics from the MAC or PHY are reported. 105 * 106 * In general, when bringing up new switch hardware, one should start by 107 * testing at the MAC layer, then moving to the PHY layer, and 108 * finally, externally, by connected each port pair to it's 109 * neighbor (1-2, 3-4, etc). 110 */ 111 #include <sal/types.h> 112 #include <sal/core/boot.h> 113 #include <sal/appl/sal.h> 114 #include <shared/bsl.h> 115 #include <appl/diag/system.h> 116 #include <appl/diag/parse.h> 117 #include <appl/diag/test.h> 118 #include <appl/test/loopback2.h> 119 120 #include <soc/mem.h> 121 #ifdef BCM_ESW_SUPPORT 122 #include <soc/firebolt.h> 123 #include <bcm_int/esw/mbcm.h> 124 #ifdef BCM_ENDURO_SUPPORT 125 #include <soc/error.h> 126 #endif 127 #endif 128 129 #include <bcm/error.h> 130 #include <bcm/l2.h> 131 #include <bcm/pkt.h> 132 #include <bcm/tx.h> 133 #include <bcm/port.h> 134 #include <bcm/vlan.h> 135 #include <bcm/link.h> 136 #include <bcm/stg.h> 137 #include <bcm/link.h> 138 #include <bcm/stat.h> 139 #include <bcm/stack.h> 140 141 #if defined(INCLUDE_MACSEC) 142 #include <bcm/macsec.h> 143 144 static int macsec_stop_poll_task = 1; 145 #endif /* INCLUDE_MACSEC */ 146 147 #if defined(BCM_GREYHOUND2_SUPPORT) 148 #include <soc/port_ability.h> 149 #endif /* BCM_GREYHOUND2_SUPPORT */ 150 #include "traffic.h" 151 152 /* Unicast test */ 153 static sal_mac_addr_t traf_unicast_mac_base = {0,0,0,0,0xfe,0}; 154 155 /* Unicast test */ 156 static sal_mac_addr_t traf_broadcast_mac_base = {0xff,0xff,0xff,0xff,0xff,0xff}; 157 158 159 /* 160 * Module local variables. 161 */ 162 163 /* Test Structure for the CLI */ 164 STATIC traffic_test_t *traf_test[SOC_MAX_NUM_DEVICES]; 165 166 167 /* 168 * The order in this table should mirror traffic_mode_t 169 */ 170 STATIC char * 171 traffic_mode_str[] = { 172 "MAC", 173 "PHY", 174 "External", 175 /* "ExternalUp", 176 "ExternalDown", */ 177 NULL 178 }; 179 180 /* 181 * The order in this table should mirror traffic_speed_t 182 */ 183 STATIC char * 184 traffic_speed_str[] = { 185 LB2_SPEED_INIT_STR, 186 NULL 187 }; 188 189 190 /* Test parameter default options */ 191 static int dfl_speed = 0, /* MAX */ 192 dfl_autoneg = 1, 193 dfl_size = 1518, 194 dfl_count = 1, 195 dfl_poll_interval = 5, /* seconds between polls */ 196 dfl_runtime = 60, /* 60/5 = 12 polls */ 197 dfl_cleanup = 1, 198 dfl_showstats = 0, 199 dfl_run2end = 0; 200 static pbmp_t dfl_portbitmap; 201 static uint32 dfl_pattern = 0xa5a4a3a2, 202 dfl_pattern_inc = 0; 203 static traffic_mode_t dfl_runmode = TRAFFIC_INTERNAL_PHY; 204 205 #if defined(INCLUDE_MACSEC) 206 static int dfl_macsec = 0; 207 #endif /* INCLUDE_MACSEC */ 208 209 /* 210 * Function: 211 * _traffic_xgs3_test_modid_get 212 * Purpose: 213 * Get a set of modids that do not conflict with my_modid 214 * Parameters: 215 * unit - SOC unit# 216 * port - test port 217 * Returns: 218 * module id 219 */ 220 STATIC int 221 _traffic_xgs3_test_modid_get(int unit, int port) 222 { 223 int modid; 224 225 if (bcm_stk_my_modid_get(unit, &modid) < 0) { 226 return -1; 227 } 228 229 if (SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) { 230 return (modid >= 8) ? port : port + 8; 231 } else { 232 return (modid >= 32) ? port : port + 32; 233 } 234 } 235 236 #ifdef BCM_ESW_SUPPORT 237 /* 238 * Function: 239 * _traffic_xgs3_modport_set 240 * Purpose: 241 * Set the port in MODPORT entry for ingress port/modid 242 * Parameters: 243 * unit - SOC unit# 244 * modid - module id 245 * portA - egress Higig port 246 * portB - ingress Higig port 247 * Returns: 248 * BCM_E_XXX 249 */ 250 STATIC int 251 _traffic_xgs3_modport_set(int unit, int modid, int portA, int portB) 252 { 253 modport_map_entry_t uc; 254 modport_map_sw_entry_t sw_entry; 255 bcm_pbmp_t hg; 256 int idx, rv; 257 uint32 hg_reg; 258 259 if (SOC_MEM_FIELD_VALID(unit, MODPORT_MAP_SWm, DEST0f)) { 260 idx = modid; 261 soc_mem_lock(unit, MODPORT_MAP_SWm); 262 rv = soc_mem_read(unit, MODPORT_MAP_SWm, MEM_BLOCK_ANY, idx, 263 &sw_entry); 264 if (SOC_SUCCESS(rv)) { 265 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, DEST0f, 266 portA); 267 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ENABLE0f, 1); 268 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, DEST1f, 269 portB); 270 soc_mem_field32_set(unit, MODPORT_MAP_SWm, &sw_entry, ENABLE1f, 1); 271 rv = soc_mem_write(unit, MODPORT_MAP_SWm, MEM_BLOCK_ALL, idx, 272 &sw_entry); 273 } 274 soc_mem_unlock(unit, MODPORT_MAP_SWm); 275 return rv; 276 } 277 278 BCM_PBMP_CLEAR(hg); 279 280 #ifdef BCM_RAPTOR1_SUPPORT 281 if (SOC_IS_RAPTOR(unit)) { 282 BCM_PBMP_PORT_SET(hg, portA-1); 283 BCM_PBMP_PORT_ADD(hg, portB-1); 284 LOG_ERROR(BSL_LS_APPL_TESTS, 285 (BSL_META_U(unit, 286 "portA %d portB %d\n"), portA, portB)); 287 idx = modid; 288 } else 289 #endif 290 if (SOC_IS_RAVEN(unit) || SOC_IS_TRIUMPH2(unit) || 291 SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) { 292 BCM_PBMP_PORT_SET(hg, portA); 293 BCM_PBMP_PORT_ADD(hg, portB); 294 LOG_ERROR(BSL_LS_APPL_TESTS, 295 (BSL_META_U(unit, 296 "portA %d portB %d\n"), portA, portB)); 297 idx = modid; 298 } else if (SOC_IS_FB_FX_HX(unit)) { 299 BCM_PBMP_PORT_SET(hg, portA-24); 300 BCM_PBMP_PORT_ADD(hg, portB-24); 301 idx = modid; 302 } else if (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) { 303 BCM_PBMP_PORT_SET(hg, portA-26); 304 BCM_PBMP_PORT_ADD(hg, portB-26); 305 idx = modid; 306 } else if (SOC_IS_HBX(unit)) { 307 BCM_PBMP_PORT_SET(hg, portB); 308 idx = (portA * (SOC_MODID_MAX(unit) + 1)) + modid; 309 } else if (SOC_IS_TR_VL(unit)) { 310 uint32 hg_regA, hg_regB; 311 SOC_IF_ERROR_RETURN 312 (soc_xgs3_port_to_higig_bitmap(unit, portA, &hg_regA)); 313 SOC_IF_ERROR_RETURN 314 (soc_xgs3_port_to_higig_bitmap(unit, portB, &hg_regB)); 315 SOC_PBMP_WORD_SET(hg, 0, hg_regA | hg_regB); 316 idx = modid; 317 } else { 318 return BCM_E_INTERNAL; 319 } 320 321 soc_mem_lock(unit, MODPORT_MAPm); 322 323 rv = READ_MODPORT_MAPm(unit, MEM_BLOCK_ANY, idx, &uc); 324 if (SOC_SUCCESS(rv)) { 325 hg_reg = SOC_PBMP_WORD_GET(hg, 0); 326 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 327 SOC_IS_VALKYRIE2(unit)) { 328 soc_MODPORT_MAPm_field32_set(unit, &uc, HIGIG_PORT_BITMAP_LOf, 329 hg_reg); 330 hg_reg = SOC_PBMP_WORD_GET(hg, 1); 331 soc_MODPORT_MAPm_field32_set(unit, &uc, HIGIG_PORT_BITMAP_HIf, 332 hg_reg); 333 } else { 334 soc_MODPORT_MAPm_field32_set(unit, &uc, HIGIG_PORT_BITMAPf, hg_reg); 335 } 336 rv = WRITE_MODPORT_MAPm(unit, MEM_BLOCK_ALL, idx, &uc); 337 } 338 339 soc_mem_unlock(unit, MODPORT_MAPm); 340 341 return rv; 342 } 343 #endif /* BCM_ESW_SUPPORT */ 344 345 /* 346 * Save H/W state and setup test structure for a given unit with the 347 * specified mode. If the test_structure is not allocated, a new one 348 * is created and returned with the mode settings specified. 349 */ 350 351 STATIC traffic_test_t * 352 traffic_test_alloc(int unit) 353 { 354 int port, rv = -1; 355 traffic_test_t *test; 356 357 test = sal_alloc(sizeof(traffic_test_t), "Traffic Test config"); 358 test->port_stats = sal_alloc(SOC_MAX_NUM_PORTS * 359 sizeof(traffic_port_stat_t), 360 "Stats"); 361 test->port_pair = sal_alloc(SOC_MAX_NUM_PORTS * 362 sizeof(traffic_port_config_t), 363 "Port Config"); 364 test->port_info = sal_alloc(SOC_MAX_NUM_PORTS * 365 sizeof(bcm_port_info_t), 366 "Port Test Configuration"); 367 test->saved_port_info = sal_alloc(SOC_MAX_NUM_PORTS * 368 sizeof(bcm_port_info_t), 369 "Original Port Configuration"); 370 #ifdef BCM_ESW_SUPPORT 371 if (SOC_MEM_FIELD_VALID(unit, MODPORT_MAP_SWm, DEST0f)) { 372 test->saved_modport_map_sw = sal_alloc(SOC_MAX_NUM_PORTS * 373 sizeof(modport_map_sw_entry_t), 374 "Original Modport Map"); 375 } else { 376 test->saved_modport_map = sal_alloc(SOC_MAX_NUM_PORTS * 377 sizeof(modport_map_entry_t), 378 "Original Modport Map"); 379 } 380 #endif /* BCM_ESW_SUPPORT */ 381 382 test->unit = unit; 383 test->npkts = dfl_count; 384 test->pattern = dfl_pattern; 385 test->pattern_inc = dfl_pattern_inc; 386 test->ports = dfl_portbitmap; 387 test->pkt_size = dfl_size; 388 test->mode = dfl_runmode; 389 test->req_speed = dfl_speed; 390 test->stop_on_fail = TRUE; 391 test->cleanup = dfl_cleanup; 392 test->showstats = dfl_showstats; 393 test->poll_interval = dfl_poll_interval; 394 test->runtime = dfl_runtime; 395 test->run2end = dfl_run2end; 396 #if defined(INCLUDE_MACSEC) 397 test->macsec_enabled = dfl_macsec; 398 test->macsec_info = sal_alloc(sizeof(traffic_macsec_info_t), 399 "macsec traffic info"); 400 test->macsec_info->num_assoc = 1; 401 #endif /* INCLUDE_MACSEC */ 402 403 /* Save age timer if it's set */ 404 bcm_l2_age_timer_get(test->unit, &test->l2agetime); 405 406 /* Cache original port config */ 407 PBMP_ITER(test->ports, port) { 408 if ((rv = bcm_port_info_save(unit, port, 409 &test->saved_port_info[port])) < 0) { 410 cli_out("traffic_init: port %s: could not get port info: %s\n", 411 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 412 } 413 /* Remove L2 addresses on Switch ASIC's which support them */ 414 /* this is a no-op on fabrics */ 415 rv = bcm_l2_addr_delete_by_port(unit, -1, port, BCM_L2_DELETE_STATIC); 416 if (rv < 0) { 417 cli_out("traffic_test_free: ARL delete by port unsuccessful on port %s: could not set port info: %s\n", 418 SOC_PORT_NAME(unit, port), 419 bcm_errmsg(rv)); 420 } 421 #ifdef BCM_ESW_SUPPORT 422 /* Save modport maps used for Higig port pairs */ 423 if (IS_ST_PORT(unit, port) && SOC_IS_FBX(unit)) { 424 int modid, idx; 425 modid = _traffic_xgs3_test_modid_get(unit, port); 426 if (modid < 0) { 427 cli_out("traffic_init: port %s: could not get modid\n", 428 SOC_PORT_NAME(unit, port)); 429 } 430 if (SOC_IS_HBX(unit)) { 431 idx = (port * (SOC_MODID_MAX(unit) + 1)) + modid; 432 } else { 433 idx = modid; 434 } 435 if (SOC_MEM_FIELD_VALID(unit, MODPORT_MAP_SWm, DEST0f)) { 436 rv = soc_mem_read(unit, MODPORT_MAP_SWm, MEM_BLOCK_ANY, idx, 437 &test->saved_modport_map_sw[port]); 438 } else { 439 rv = soc_mem_read(unit, MODPORT_MAPm, MEM_BLOCK_ANY, idx, 440 &test->saved_modport_map[port]); 441 } 442 if (rv < 0) { 443 cli_out("traffic_init: " 444 "port %s: could not get modport map: %s\n", 445 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 446 } 447 } 448 #endif /* BCM_ESW_SUPPORT */ 449 } 450 451 return test; 452 } 453 454 /* 455 * Free Test structure, restore H/W state. 456 */ 457 STATIC int 458 traffic_test_free(traffic_test_t* test) 459 { 460 int unit, port, rv = -1; 461 int ms; 462 #if defined (BCM_ESW_SUPPORT) 463 uint64 tmp64; 464 #endif 465 466 if (!test) { 467 return rv; 468 } 469 470 /* 471 * Cleanup means shutdown switching test, we have this 472 * option so that on a failure, you can exit the test 473 * and use the CLI to debug. 474 */ 475 unit = test->unit; 476 if (test->cleanup) { 477 478 if (!SAL_BOOT_QUICKTURN) { 479 #if defined (BCM_ESW_SUPPORT) 480 COMPILER_64_ZERO(tmp64); 481 #endif 482 if (SOC_IS_ESW(unit)) { 483 #ifdef BCM_ESW_SUPPORT 484 counter_val_set_by_port(unit, test->ports, tmp64); 485 #endif 486 } else { 487 } 488 } 489 490 if (!SOC_IS_XGS12_FABRIC(unit)) { 491 PBMP_ITER(test->ports, port) { 492 if (port != test->port_pair[port].portA) { 493 continue; 494 } 495 cli_out("TRAFFIC: restoring ports: %s, %s\n", 496 SOC_PORT_NAME(unit, test->port_pair[port].portA), 497 SOC_PORT_NAME(unit, test->port_pair[port].portB)); 498 499 bcm_vlan_destroy(unit, test->port_pair[port].vidA); 500 bcm_vlan_destroy(unit, test->port_pair[port].vidB); 501 502 /* Very Important: clear EPCLINKr to halt traffic */ 503 bcm_port_stp_set(unit, test->port_pair[port].portA, 504 BCM_STG_STP_DISABLE); 505 bcm_port_stp_set(unit, test->port_pair[port].portB, 506 BCM_STG_STP_DISABLE); 507 } 508 bcm_vlan_port_add(unit, VLAN_ID_DEFAULT, test->ports, test->ports); 509 } 510 511 PBMP_ITER(test->ports, port) { 512 /* If port is FE port, remove phy_master attributes controlled by it */ 513 if(IS_FE_PORT(unit, port)) { 514 test->saved_port_info[port].action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 515 } 516 /* If the Master mode is not changed, remove phy_master attributes from action_mask */ 517 ms = 0; 518 if ((rv = bcm_port_master_get(unit, port, &ms)) != BCM_E_NONE) { 519 cli_out("traffic_test_free: port %s: could not get port Master mode: %s\n", 520 SOC_PORT_NAME(unit, port), 521 bcm_errmsg(rv)); 522 goto done; 523 } 524 if (ms == test->saved_port_info[port].phy_master) { 525 test->saved_port_info[port].action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 526 } 527 528 if ((rv = bcm_port_info_restore(unit, port, 529 &test->saved_port_info[port])) < 0) { 530 cli_out("traffic_test_free: port %s: could not set port info: %s\n", 531 SOC_PORT_NAME(unit, port), 532 bcm_errmsg(rv)); 533 goto done; 534 } 535 rv = bcm_l2_addr_delete_by_port(unit, -1, port, 536 BCM_L2_DELETE_STATIC); 537 if (rv < 0) { 538 cli_out("traffic_test_free: ARL delete by port unsuccessful on port %s: could not set port info: %s\n", 539 SOC_PORT_NAME(unit, port), 540 bcm_errmsg(rv)); 541 goto done; 542 } 543 544 #ifdef BCM_ESW_SUPPORT 545 /* Restore modport maps used for Higig port pairs */ 546 if (IS_ST_PORT(unit, port) && SOC_IS_FBX(unit)) { 547 int modid, idx; 548 modid = _traffic_xgs3_test_modid_get(unit, port); 549 if (modid < 0) { 550 cli_out("traffic_test_free: port %s: could not get modid\n", 551 SOC_PORT_NAME(unit, port)); 552 goto done; 553 } 554 if (SOC_IS_HBX(unit) || SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) { 555 idx = (port * (SOC_MODID_MAX(unit) + 1)) + modid; 556 } else { 557 idx = modid; 558 } 559 if (SOC_MEM_FIELD_VALID(unit, MODPORT_MAP_SWm, DEST0f)) { 560 rv = soc_mem_write(unit, MODPORT_MAP_SWm, MEM_BLOCK_ANY, 561 idx, &test->saved_modport_map_sw[port]); 562 } else { 563 rv = soc_mem_write(unit, MODPORT_MAPm, MEM_BLOCK_ANY, idx, 564 &test->saved_modport_map[port]); 565 } 566 if (rv < 0) { 567 cli_out("traffic_test_free: " 568 "port %s: could not set modport map: %s\n", 569 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 570 } 571 } 572 #endif /* BCM_ESW_SUPPORT */ 573 } 574 575 /* Restore l2 age time */ 576 bcm_l2_age_timer_set(unit, test->l2agetime); 577 } 578 done: 579 sal_free(test->port_stats); 580 sal_free(test->port_pair); 581 sal_free(test->port_info); 582 sal_free(test->saved_port_info); 583 #ifdef BCM_ESW_SUPPORT 584 if (SOC_MEM_FIELD_VALID(unit, MODPORT_MAP_SWm, DEST0f)) { 585 sal_free(test->saved_modport_map_sw); 586 } else { 587 sal_free(test->saved_modport_map); 588 } 589 #endif /* BCM_ESW_SUPPORT */ 590 return 0; 591 } 592 593 /* 594 * Send frames to destination port pair index. Each port is a 595 * transmitter and receiver. Packets are sent in external mode 596 * such that DA=00:00:00:00:fe:x where x=portA, and 597 * SA=00:00:00:00:00:portB; in internal test mode, packets 598 * are sent with SA=00:00:00:00:00:01, and DA=broadcast address 599 */ 600 int 601 traffic_test_send_frames(traffic_test_t* test, int port_pair_index) 602 { 603 int rv = BCM_E_NONE; 604 int unit = test->unit; 605 traffic_port_config_t *config = &test->port_pair[port_pair_index]; 606 int portA = config->portA; 607 int portB = config->portB; 608 int mode = test->mode; 609 int pad; 610 int i; 611 612 bcm_pkt_t *pktA; 613 void *bufA; 614 enet_hdr_t *ehdrA; 615 int sizeA; 616 617 bcm_pkt_t *pktB; 618 void *bufB; 619 enet_hdr_t *ehdrB; 620 int sizeB; 621 622 pad = sizeof(uint32); /* Add size of CRC .. */ 623 624 bcm_pkt_alloc(unit, test->pkt_size + pad, 0, &pktA); 625 bcm_pkt_alloc(unit, test->pkt_size + pad, 0, &pktB); 626 627 if (pktA == NULL || pktB == NULL) { 628 cli_out("Error initializing packet buffers\n"); 629 goto error; 630 } 631 632 bufA = pktA->_pkt_data.data; 633 bufB = pktB->_pkt_data.data; 634 635 /* Set packet buffer */ 636 ehdrA = (enet_hdr_t*)bufA; 637 ehdrB = (enet_hdr_t*)bufB; 638 639 pktA->flags = BCM_TX_CRC_APPEND; 640 pktB->flags = BCM_TX_CRC_APPEND; 641 #ifdef BCM_XGS12_FABRIC_SUPPORT 642 if (SOC_IS_XGS12_FABRIC(unit)) { 643 pktA->dest_port = portB; 644 pktA->opcode = BCM_HG_OPCODE_UC; 645 pktB->dest_port = portA; 646 pktB->opcode = BCM_HG_OPCODE_UC; 647 } 648 #endif 649 if (SOC_IS_XGS3_SWITCH(unit)) { 650 651 if (IS_ST_PORT(unit, portA) || IS_ST_PORT(unit, portB)) { 652 int modid = _traffic_xgs3_test_modid_get(unit, portA); 653 if (modid < 0) { 654 cli_out("ERROR: port %s: could not get modid\n", 655 SOC_PORT_NAME(unit, portA)); 656 goto error; 657 } 658 pktA->dest_port = portB; 659 pktA->opcode = BCM_HG_OPCODE_UC; 660 pktA->src_mod = modid + 1; 661 pktA->flags |= BCM_TX_SRC_MOD; 662 pktA->dest_mod = modid; 663 pktB->dest_port = portA; 664 pktB->opcode = BCM_HG_OPCODE_UC; 665 pktB->src_mod = modid + 1; 666 pktB->flags |= BCM_TX_SRC_MOD; 667 pktB->dest_mod = modid; 668 } 669 } 670 test->pattern = packet_store((uint8*)ehdrA, test->pkt_size, 671 test->pattern, test->pattern_inc); 672 673 /* Strata Internal MAC, PHY, or XGS/Fabric packets */ 674 if (SOC_IS_XGS12_FABRIC(unit) || 675 (mode == TRAFFIC_INTERNAL) || 676 (mode == TRAFFIC_INTERNAL_PHY)) { 677 678 /* PortA packet */ 679 ENET_COPY_MACADDR(traf_broadcast_mac_base, &ehdrA->en_dhost); 680 ENET_COPY_MACADDR(traf_unicast_mac_base, &ehdrA->en_shost); 681 if (!SOC_IS_XGS12_FABRIC(unit)) { 682 ehdrA->en_tag_ctrl = soc_htons(VLAN_CTRL(0, 0, config->vidA)); 683 ehdrA->en_tag_tpid = soc_htons(ENET_DEFAULT_TPID ); 684 } 685 ehdrA->en_tag_len = soc_htons(test->pkt_size) - 18; 686 687 sizeA = test->pkt_size; 688 BCM_PKT_PORT_SET(pktA, portA, TRUE, FALSE); 689 BCM_PKT_TX_LEN_SET(pktA, sizeA); 690 691 /* Port B packet */ 692 ENET_COPY_MACADDR(traf_broadcast_mac_base, &ehdrB->en_dhost); 693 ENET_COPY_MACADDR(traf_unicast_mac_base, &ehdrB->en_shost); 694 if (!SOC_IS_XGS12_FABRIC(unit)) { 695 ehdrB->en_tag_ctrl = soc_htons(VLAN_CTRL(0, 0, config->vidB)); 696 ehdrB->en_tag_tpid = soc_htons(ENET_DEFAULT_TPID ); 697 } 698 ehdrB->en_tag_len = soc_htons(test->pkt_size) - 18; 699 700 sizeB = test->pkt_size; 701 BCM_PKT_PORT_SET(pktB, portB, TRUE, FALSE); 702 BCM_PKT_TX_LEN_SET(pktB, sizeB); 703 } else { /* External && !Fabric */ 704 /* PortA packet */ 705 ENET_COPY_MACADDR(&config->l2B.mac, &ehdrA->en_dhost); 706 ENET_COPY_MACADDR(&config->l2A.mac, &ehdrA->en_shost); 707 ehdrA->en_tag_ctrl = soc_htons(VLAN_CTRL(0, 0, config->vidA)); 708 ehdrA->en_tag_tpid = soc_htons(ENET_DEFAULT_TPID ); 709 ehdrA->en_tag_len = soc_htons(test->pkt_size) - 18; 710 711 sizeA = test->pkt_size; 712 BCM_PKT_PORT_SET(pktA, portB, TRUE, FALSE); 713 BCM_PKT_TX_LEN_SET(pktA, sizeA); 714 715 /* Port B packet */ 716 ENET_COPY_MACADDR(&config->l2A.mac, &ehdrB->en_dhost); 717 ENET_COPY_MACADDR(&config->l2B.mac, &ehdrB->en_shost); 718 ehdrB->en_tag_ctrl = soc_htons(VLAN_CTRL(0, 0, config->vidB)); 719 ehdrB->en_tag_tpid = soc_htons(ENET_DEFAULT_TPID ); 720 ehdrB->en_tag_len = soc_htons(test->pkt_size) - 18; 721 722 sizeB = test->pkt_size; 723 BCM_PKT_PORT_SET(pktB, portA, TRUE, FALSE); 724 BCM_PKT_TX_LEN_SET(pktB, sizeB); 725 } 726 727 for (i=0; i < test->npkts; i++) { 728 rv = bcm_tx(unit, pktA, NULL); 729 if (rv < 0) { 730 cli_out("ERROR: port %s: bcm_tx A #%d failed: %s\n", 731 SOC_PORT_NAME(unit, portB), i, bcm_errmsg(rv)); 732 goto error; 733 } 734 735 rv = bcm_tx(unit, pktB, NULL); 736 if (rv < 0) { 737 cli_out("ERROR: port %s: bcm_tx B #%d failed: %s\n", 738 SOC_PORT_NAME(unit, portA), i, bcm_errmsg(rv)); 739 goto error; 740 } 741 } 742 743 error: 744 if (pktA != NULL) { 745 bcm_pkt_free(unit, pktA); 746 } 747 if (pktB != NULL) { 748 bcm_pkt_free(unit, pktB); 749 } 750 751 return BCM_E_NONE; 752 } 753 754 #if defined(INCLUDE_MACSEC) 755 typedef struct traffic_macsec_user_data_s { 756 int unit; 757 bcm_port_t match_port; 758 bcm_macsec_core_t dev_core; 759 int dev_port; 760 int found; 761 pbmp_t pbm; 762 traffic_test_t *test; 763 } traffic_macsec_user_data_t; 764 765 static int _traffic_macsec_port_iter_cb(int unit, 766 bcm_port_t port, 767 bcm_macsec_core_t dev_core, 768 bcm_macsec_dev_addr_t dev_addr, 769 int dev_port, 770 bcm_macsec_dev_io_t devio_f, 771 void *user_data) 772 { 773 traffic_macsec_user_data_t *mdata = (traffic_macsec_user_data_t*) user_data; 774 775 if ((mdata->unit == unit) && (mdata->match_port == port)) { 776 mdata->found = 1; 777 mdata->dev_port = dev_port; 778 mdata->dev_core = dev_core; 779 } 780 return 0; 781 } 782 783 static int _traffic_port_is_macsec_capable(int unit, bcm_port_t port) 784 { 785 traffic_macsec_user_data_t mdata; 786 787 mdata.found = 0; 788 mdata.unit = unit; 789 mdata.match_port = port; 790 791 bcm_macsec_port_traverse(unit, _traffic_macsec_port_iter_cb, (void*) &mdata); 792 return (mdata.found) ? 1 : 0; 793 } 794 795 static int 796 _traffic_alloc_crypto_key(int unit, int port, int ofst, unsigned char *key) 797 { 798 int ii; 799 800 key[0] = unit; 801 key[1] = port; 802 key[2] = (ofst >> 8) & 0xff; 803 key[3] = ofst & 0xff; 804 for (ii = 4; ii < 16; ii++) { 805 key[ii] = ii; 806 } 807 return 0; 808 } 809 810 static int _traffic_setup_new_key(int unit, bcm_port_t port, 811 bcm_port_t portB, traffic_test_t *test) 812 { 813 int symmetric, an, peer_port, rxchanId, txchanId; 814 int old_rx_assocId = -1, old_tx_assocId = -1, new_an, rv = BCM_E_NONE; 815 bcm_macsec_secure_assoc_t assoc; 816 817 symmetric = ((test->mode == TRAFFIC_INTERNAL_PHY) || 818 (test->mode == TRAFFIC_INTERNAL)) ? 1 : 0; 819 820 if (symmetric) { 821 peer_port = port; 822 } else { 823 peer_port = portB; 824 } 825 if (peer_port >= SOC_MAX_NUM_PORTS) { 826 cli_out("peer_port num %d too large \n", peer_port ); 827 return BCM_E_PORT; 828 } 829 if (port >= SOC_MAX_NUM_PORTS) { 830 cli_out("port num %d too large \n", port ); 831 return BCM_E_PORT; 832 } 833 834 an = test->macsec_info->ports[port].cur_an; 835 if (an >= 0) { 836 old_tx_assocId = 837 test->macsec_info->ports[port].tx_keys[an].assocId; 838 old_rx_assocId = 839 test->macsec_info->ports[peer_port].rx_keys[an].assocId; 840 } 841 842 new_an = (an + 1) & 3; 843 844 test->macsec_info->ports[port].cur_an = new_an; 845 846 /* Update RX */ 847 sal_memset(&assoc, 0, sizeof(bcm_macsec_secure_assoc_t)); 848 assoc.an = new_an; 849 assoc.crypto = BCM_MACSEC_CRYPTO_AES_128_GCM; 850 assoc.flags = BCM_MACSEC_ASSOC_ACTIVE; 851 852 /* setup TX crypto key */ 853 _traffic_alloc_crypto_key(unit, port, 854 test->macsec_info->ports[port].num_alloc++, 855 assoc.aes128_gcm.key); 856 857 /* store the key */ 858 sal_memcpy(test->macsec_info->ports[port].tx_keys[new_an].crypto_key, 859 assoc.aes128_gcm.key, 16); 860 861 rxchanId = test->macsec_info->ports[peer_port].rx_chanId; 862 863 /* create RX assoc */ 864 rv = bcm_macsec_secure_assoc_create(unit, peer_port, 0, rxchanId, &assoc, 865 &test->macsec_info->ports[peer_port].rx_keys[new_an].assocId); 866 if (rv < 0) { 867 cli_out("Failed to create RX secure association \n"); 868 return BCM_E_PORT; 869 } 870 871 sal_memset(&assoc, 0, sizeof(bcm_macsec_secure_assoc_t)); 872 assoc.an = new_an; 873 assoc.flags = BCM_MACSEC_ASSOC_ACTIVE; 874 assoc.crypto = BCM_MACSEC_CRYPTO_AES_128_GCM; 875 sal_memcpy(assoc.aes128_gcm.key, 876 test->macsec_info->ports[port].tx_keys[new_an].crypto_key, 16); 877 878 /* switch over now */ 879 txchanId = test->macsec_info->ports[port].tx_chanId; 880 rv = bcm_macsec_secure_assoc_create(unit, port, 0, txchanId, &assoc, 881 &test->macsec_info->ports[port].tx_keys[new_an].assocId); 882 if (rv < 0) { 883 cli_out("Failed to create TX secure association \n"); 884 return BCM_E_PORT; 885 } 886 test->macsec_info->ports[port].cur_an = new_an; 887 888 if (old_tx_assocId >= 0) { 889 bcm_macsec_secure_assoc_destroy(unit, port, old_tx_assocId); 890 } 891 892 if (old_rx_assocId >= 0) { 893 bcm_macsec_secure_assoc_destroy(unit, port, old_rx_assocId); 894 } 895 896 cli_out("Key updated (p=%s) \n", SOC_PORT_NAME(unit, port)); 897 return BCM_E_NONE; 898 } 899 900 static int _macsec_calc_assoc_life(int speedM, uint32 availPkt, int before) 901 { 902 uint32 time_ms; 903 904 /* calculate worst cast life of assoc */ 905 /* 906 time_ms = (availPkt ) / (speedM * 1000); 907 time_ms *= 64 * 8; 908 */ 909 910 switch (speedM) { 911 case 10: 912 time_ms = availPkt / 20; 913 break; 914 case 100: 915 time_ms = availPkt / 195; 916 break; 917 case 1000: 918 time_ms = availPkt / 1953; 919 break; 920 case 10000: 921 default: 922 time_ms = availPkt / 19531; 923 break; 924 } 925 926 return (time_ms <= before) ? 0 : (time_ms - before); 927 } 928 929 static void 930 _macsec_poll_thread(void *data) 931 { 932 traffic_macsec_user_data_t *mdata = (traffic_macsec_user_data_t*) data; 933 traffic_test_t *test; 934 pbmp_t pbm; 935 int unit, cur_an, rv; 936 bcm_port_t port, peer_port; 937 int poll_interval, total_time = 0; 938 int wake_time_ms; 939 unsigned int avail_pkt; 940 int symmetric, rxchanId, txchanId; 941 bcm_macsec_port_config_t config; 942 943 944 /* setup macsec PBMP and */ 945 test = mdata->test; 946 pbm = test->macsec_info->macsec_pbm; 947 unit = mdata->unit; 948 949 if (SOC_PBMP_IS_NULL(pbm)) { 950 return; 951 } 952 953 while (macsec_stop_poll_task == 0) { 954 wake_time_ms = 10000; 955 PBMP_ITER(pbm, port) { 956 cur_an = test->macsec_info->ports[port].cur_an; 957 /* Get the availPkt count for the assoc */ 958 rv = bcm_macsec_stat_get32(unit, port, bcm_txSAavailablePkts, -1, 959 test->macsec_info->ports[port].tx_keys[cur_an].assocId, 960 &avail_pkt); 961 if (rv < 0) { 962 continue; 963 } 964 poll_interval = _macsec_calc_assoc_life(test->port_info[port].speed, 965 avail_pkt, 10000); 966 if (poll_interval == 0) { 967 peer_port = test->port_pair[port].portB; 968 /* Update the keys */ 969 _traffic_setup_new_key(unit, port, peer_port, test); 970 continue; 971 } 972 if (wake_time_ms > poll_interval) { 973 wake_time_ms = poll_interval; 974 } 975 } 976 sal_usleep(wake_time_ms * 1000); 977 total_time += wake_time_ms; 978 } 979 980 symmetric = ((test->mode == TRAFFIC_INTERNAL_PHY) || 981 (test->mode == TRAFFIC_INTERNAL)) ? 1 : 0; 982 983 if (test->cleanup) { 984 PBMP_ITER(pbm, port) { 985 if (symmetric) { 986 peer_port = port; 987 } else { 988 peer_port = test->port_pair[port].portB; 989 } 990 if (peer_port >= SOC_MAX_NUM_PORTS) { 991 cli_out("peer_port num %d >= %d : MACSEC clean failed\n", 992 peer_port, SOC_MAX_NUM_PORTS); 993 994 continue; 995 } 996 txchanId = test->macsec_info->ports[port].tx_chanId; 997 if (txchanId >= 0) { 998 bcm_macsec_secure_chan_destroy(unit, port, txchanId); 999 } 1000 rxchanId = test->macsec_info->ports[peer_port].rx_chanId; 1001 if (rxchanId >= 0) { 1002 bcm_macsec_secure_chan_destroy(unit, peer_port, rxchanId); 1003 } 1004 1005 if (bcm_macsec_port_config_get(unit, port, &config) < 0) { 1006 cli_out("Port %s MACSEC clean failed\n", 1007 SOC_PORT_NAME(unit, port)); 1008 continue; 1009 } 1010 1011 config.flags &= ~BCM_MACSEC_PORT_ENABLE; 1012 if (bcm_macsec_port_config_set(unit, port, &config) < 0) { 1013 cli_out("Port %s MACSEC clean failed\n", 1014 SOC_PORT_NAME(unit, port)); 1015 continue; 1016 } 1017 } 1018 } 1019 1020 cli_out("MACSEC Poll task exiting ...\n"); 1021 return; 1022 } 1023 1024 static int 1025 _traffic_setup_macsec_poll_task(int unit, traffic_test_t* test) 1026 { 1027 traffic_macsec_user_data_t mdata; 1028 1029 if (!test->macsec_enabled) { 1030 return 0; 1031 } 1032 1033 macsec_stop_poll_task = 0; 1034 1035 /* fill up data for poller task */ 1036 mdata.unit = unit; 1037 mdata.test = test; 1038 1039 /* Start task to renew the key when secure assoc expires */ 1040 if (sal_thread_create("macsec_sa_poller", 1041 SAL_THREAD_STKSZ, 100, 1042 (void (*)(void*))_macsec_poll_thread, 1043 (void*) &mdata) == SAL_THREAD_ERROR) { 1044 return BCM_E_MEMORY; 1045 } 1046 return 0; 1047 } 1048 1049 static int 1050 _traffic_setup_macsec(int unit, bcm_port_t portA, 1051 bcm_port_t portB, traffic_test_t* test) 1052 { 1053 bcm_port_t port, alt_port, peer_port; 1054 bcm_macsec_port_config_t config; 1055 bcm_macsec_secure_chan_t chan; 1056 int txchanId, rxchanId; 1057 int symmetric, ii, flowId, jj; 1058 bcm_macsec_flow_match_t flow; 1059 bcm_macsec_flow_action_t action; 1060 1061 symmetric = ((test->mode == TRAFFIC_INTERNAL_PHY) || 1062 (test->mode == TRAFFIC_INTERNAL)) ? 1 : 0; 1063 1064 /* Setup MACSEC flows and keys */ 1065 if ((test->macsec_enabled == 0) || 1066 ((symmetric == 0) && 1067 (!_traffic_port_is_macsec_capable(unit, portA) || 1068 !_traffic_port_is_macsec_capable(unit, portB)))) { 1069 return 0; /* Not macsec capable, nothing to do. */ 1070 } 1071 1072 for (ii = 0; ii < 2; ii++) { 1073 port = (ii == 0) ? portA : portB; 1074 alt_port = (ii == 0) ? portB : portA; 1075 peer_port = (symmetric) ? port : alt_port; 1076 1077 if (!_traffic_port_is_macsec_capable(unit, port)) { 1078 continue; 1079 } 1080 1081 /* Enable controlled port */ 1082 if (bcm_macsec_port_config_get(unit, port, &config) < 0) { 1083 return BCM_E_PORT; 1084 } 1085 1086 config.flags = BCM_MACSEC_PORT_ENABLE; 1087 config.max_frame = 1518 + 32; 1088 for (jj = 0; jj < BCM_MACSEC_PACKET_FORMAT__COUNT; jj++) { 1089 config.egress_flow_match_set[jj] = BCM_MACSEC_FLOW_MATCH_MACSA; 1090 } 1091 if (bcm_macsec_port_config_set(unit, port, &config) < 0) { 1092 return BCM_E_PORT; 1093 } 1094 1095 /* Create TX and RX channels */ 1096 sal_memset(&chan, 0, sizeof(chan)); 1097 chan.flags = BCM_MACSEC_SECURE_CONFIDENTIAL | 1098 BCM_MACSEC_SECURE_SECTAG_TX_SCI; 1099 sal_memset(chan.sci, 0x33, 8); 1100 if (bcm_macsec_secure_chan_create(unit, port, 0, &chan, &txchanId) < 0) { 1101 return BCM_E_PORT; 1102 } 1103 1104 test->macsec_info->ports[port].tx_chanId = txchanId; 1105 1106 /* setup rx channel */ 1107 sal_memset(&chan, 0, sizeof(chan)); 1108 chan.flags = BCM_MACSEC_SECURE_CONFIDENTIAL | 1109 BCM_MACSEC_SECURE_CHAN_INGRESS; 1110 sal_memset(chan.sci, 0x33, 8); 1111 if (bcm_macsec_secure_chan_create(unit, peer_port, 1112 0, &chan, &rxchanId) < 0) { 1113 return BCM_E_PORT; 1114 } 1115 1116 test->macsec_info->ports[peer_port].rx_chanId = rxchanId; 1117 1118 /* setup egress flows */ 1119 sal_memset(&flow, 0, sizeof(flow)); 1120 flow.flags = 0; 1121 flow.direction = BCM_MACSEC_DIR_EGRESS; 1122 flow.pkt_format = BCM_MACSEC_PACKET_FORMAT_802_3; 1123 1124 sal_memset(&action, 0, sizeof(action)); 1125 action.flags = BCM_MACSEC_FLOW_ACTION_CONTROLLED_FORWARD; 1126 1127 if (bcm_macsec_flow_create(unit, port, 0, &flow, &action, &flowId) < 0) { 1128 return BCM_E_PORT; 1129 } 1130 1131 BCM_PBMP_PORT_ADD(test->macsec_info->macsec_pbm, port); 1132 1133 test->macsec_info->ports[port].cur_an = -1; 1134 1135 _traffic_setup_new_key(unit, port, alt_port, test); 1136 } 1137 1138 return BCM_E_NONE; 1139 } 1140 1141 #endif /* INCLUDE_MACSEC */ 1142 1143 /* 1144 * Setup an l2 entry with specified address on 1145 * the given port. 1146 */ 1147 int 1148 traffic_test_setup_l2addr(int unit, bcm_l2_addr_t* l2addr, int vid, int port) 1149 { 1150 int rv = BCM_E_NONE; 1151 #ifdef BCM_TRIUMPH_SUPPORT 1152 int ext_index_max = -1; 1153 #endif /* BCM_TRIUMPH_SUPPORT */ 1154 1155 traf_unicast_mac_base[5] = port; 1156 bcm_l2_addr_t_init(l2addr, traf_unicast_mac_base, vid); 1157 1158 l2addr->flags = BCM_L2_STATIC; 1159 l2addr->port = port; 1160 if ((rv = bcm_stk_my_modid_get(unit, &l2addr->modid)) < 0) { 1161 cli_out("ERROR: could not get modid: %s\n", bcm_errmsg(rv)); 1162 return rv; 1163 } 1164 if (SOC_PORT_MOD1(unit, port)) { 1165 l2addr->modid += 1; 1166 } 1167 1168 #ifdef BCM_TRIUMPH_SUPPORT 1169 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1170 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 1171 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 1172 } 1173 #endif /* BCM_TRIUMPH_SUPPORT */ 1174 1175 if ((rv = bcm_l2_addr_add(unit, l2addr)) < 0) { 1176 cli_out("ERROR: l2 entry add failed: " 1177 "port %s, mac %2x:%2x:%2x:%2x:%2x:%2x vlan %d: %s\n", 1178 SOC_PORT_NAME(unit, port), 1179 traf_unicast_mac_base[0], 1180 traf_unicast_mac_base[1], 1181 traf_unicast_mac_base[2], 1182 traf_unicast_mac_base[3], 1183 traf_unicast_mac_base[4], 1184 traf_unicast_mac_base[5], 1185 vid, 1186 bcm_errmsg(rv)); 1187 } 1188 #ifdef BCM_TRIUMPH_SUPPORT 1189 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1190 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 1191 } 1192 #endif /* BCM_TRIUMPH_SUPPORT */ 1193 return rv; 1194 } 1195 1196 int 1197 traffic_test_setup_maxframe(traffic_test_t *test) 1198 { 1199 pbmp_t pbm; 1200 int unit, max_pkt; 1201 soc_port_t port; 1202 1203 unit = test->unit; 1204 1205 BCM_PBMP_ASSIGN(pbm, PBMP_E_ALL(unit)); 1206 BCM_PBMP_AND(pbm, test->ports); 1207 BCM_PBMP_ITER(pbm, port) { 1208 BCM_IF_ERROR_RETURN 1209 (bcm_port_frame_max_get(unit, port, &max_pkt)); 1210 if (max_pkt < test->pkt_size) { 1211 BCM_IF_ERROR_RETURN 1212 (bcm_port_frame_max_set(unit, port, test->pkt_size)); 1213 } 1214 } 1215 1216 return BCM_E_NONE; 1217 } 1218 1219 /* 1220 * Setup forwarding to occur between port pairs. 1221 */ 1222 int 1223 traffic_test_setup_port_pair(traffic_test_t* test, int port_pair_index, 1224 traffic_mode_t mode, traffic_speed_t speed) 1225 { 1226 int unit = test->unit; 1227 traffic_port_config_t *config = &test->port_pair[port_pair_index]; 1228 bcm_port_info_t *infoA = &test->port_info[config->portA]; 1229 bcm_port_info_t *infoB = &test->port_info[config->portB]; 1230 int portA = config->portA; 1231 int portB = config->portB; 1232 int rv; 1233 int ms; 1234 pbmp_t port_pbm; 1235 bcm_port_resource_t portResrc; 1236 1237 if (SOC_IS_XGS3_SWITCH(unit)) { 1238 if (IS_ST_PORT(unit, portA) || IS_ST_PORT(unit, portB)) { 1239 if (!(IS_ST_PORT(unit, portA) && IS_ST_PORT(unit, portB))) { 1240 cli_out("ERROR: ports %s, %s: " 1241 "Higig port must be paired with Higig port\n", 1242 SOC_PORT_NAME(unit, portA), 1243 SOC_PORT_NAME(unit, portB)); 1244 return -1; 1245 } 1246 } 1247 } 1248 1249 /* Setup Ports */ 1250 if (bcm_port_info_save(unit, portA, infoA) < 0) { 1251 cli_out("ERROR: traffic setup unit %d, ports %s, %s: " 1252 "%s info save failed\n", 1253 unit, 1254 SOC_PORT_NAME(unit, portA), 1255 SOC_PORT_NAME(unit, portB), 1256 SOC_PORT_NAME(unit, portA)); 1257 return -1; 1258 } 1259 if (bcm_port_info_save(unit, portB, infoB) < 0) { 1260 cli_out("ERROR: traffic setup unit %d, ports %s, %s: " 1261 "%s info save failed\n", 1262 unit, 1263 SOC_PORT_NAME(unit, portA), 1264 SOC_PORT_NAME(unit, portB), 1265 SOC_PORT_NAME(unit, portB)); 1266 return -1; 1267 } 1268 1269 /* Get port ability */ 1270 if (!IS_CD_PORT(unit, portA)) { 1271 if (bcm_port_ability_local_get(unit, portA, &infoA->port_ability) < 0) { 1272 cli_out("ERROR: traffic setup unit %d, ports %s: " 1273 "ability get failed\n", 1274 unit, SOC_PORT_NAME(unit, portA)); 1275 return -1; 1276 } 1277 } 1278 if (!IS_CD_PORT(unit, portB)) { 1279 if (bcm_port_ability_local_get(unit, portB, &infoB->port_ability) < 0) { 1280 cli_out("ERROR: traffic setup unit %d, ports %s: " 1281 "ability get failed\n", 1282 unit, SOC_PORT_NAME(unit, portB)); 1283 return -1; 1284 } 1285 } 1286 switch (speed) { 1287 case SPEED_10: 1288 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_10MB) && 1289 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_10MB)) { 1290 infoA->duplex = TRUE; 1291 infoB->duplex = TRUE; 1292 infoA->local_ability.speed_full_duplex = 1293 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_10MB; 1294 infoA->local_ability.speed_half_duplex = 1295 infoB->local_ability.speed_half_duplex = 0; 1296 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_10MB) && 1297 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_10MB)) { 1298 infoA->duplex = FALSE; 1299 infoB->duplex = FALSE; 1300 infoA->local_ability.speed_full_duplex = 1301 infoB->local_ability.speed_full_duplex = 0; 1302 infoA->local_ability.speed_half_duplex = 1303 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_10MB; 1304 } else { 1305 LOG_ERROR(BSL_LS_APPL_TESTS, 1306 (BSL_META_U(unit, 1307 "Unit %d Ports %s-%s: Forcing max speed\n"), 1308 unit, SOC_PORT_NAME(unit, portA), 1309 SOC_PORT_NAME(unit, portB))); 1310 speed = SPEED_MAX; 1311 } 1312 infoA->speed = infoB->speed = 10; 1313 break; 1314 1315 case SPEED_100: 1316 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_100MB) && 1317 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_100MB)) { 1318 infoA->duplex = TRUE; 1319 infoB->duplex = TRUE; 1320 infoA->local_ability.speed_full_duplex = 1321 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_100MB; 1322 infoA->local_ability.speed_half_duplex = 1323 infoB->local_ability.speed_half_duplex = 0; 1324 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_100MB) && 1325 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_100MB)) { 1326 infoA->duplex = FALSE; 1327 infoB->duplex = FALSE; 1328 infoA->local_ability.speed_full_duplex = 1329 infoB->local_ability.speed_full_duplex = 0; 1330 infoA->local_ability.speed_half_duplex = 1331 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_100MB; 1332 } else { 1333 LOG_ERROR(BSL_LS_APPL_TESTS, 1334 (BSL_META_U(unit, 1335 "Unit %d Ports %s-%s: Forcing max speed\n"), 1336 unit, SOC_PORT_NAME(unit, portA), 1337 SOC_PORT_NAME(unit, portB))); 1338 speed = SPEED_MAX; 1339 } 1340 infoA->speed = infoB->speed = 100; 1341 break; 1342 1343 case SPEED_1GIG: 1344 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_1000MB) && 1345 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_1000MB)) { 1346 infoA->duplex = TRUE; 1347 infoB->duplex = TRUE; 1348 infoA->local_ability.speed_full_duplex = 1349 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_1000MB; 1350 infoA->local_ability.speed_half_duplex = 1351 infoB->local_ability.speed_half_duplex = 0; 1352 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_1000MB) && 1353 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_1000MB)) { 1354 infoA->duplex = FALSE; 1355 infoB->duplex = FALSE; 1356 infoA->local_ability.speed_full_duplex = 1357 infoB->local_ability.speed_full_duplex = 0; 1358 infoA->local_ability.speed_half_duplex = 1359 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_1000MB; 1360 } else { 1361 LOG_ERROR(BSL_LS_APPL_TESTS, 1362 (BSL_META_U(unit, 1363 "Unit %d Ports %s-%s: Forcing max speed\n"), 1364 unit, SOC_PORT_NAME(unit, portA), 1365 SOC_PORT_NAME(unit, portB))); 1366 speed = SPEED_MAX; 1367 } 1368 infoA->speed = infoB->speed = 1000; 1369 break; 1370 1371 case SPEED_2_5GIG: 1372 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_2500MB) && 1373 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_2500MB)) { 1374 infoA->duplex = TRUE; 1375 infoB->duplex = TRUE; 1376 infoA->local_ability.speed_full_duplex = 1377 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_2500MB; 1378 infoA->local_ability.speed_half_duplex = 1379 infoB->local_ability.speed_half_duplex = 0; 1380 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_2500MB) && 1381 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_2500MB)) { 1382 infoA->duplex = FALSE; 1383 infoB->duplex = FALSE; 1384 infoA->local_ability.speed_full_duplex = 1385 infoB->local_ability.speed_full_duplex = 0; 1386 infoA->local_ability.speed_half_duplex = 1387 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_2500MB; 1388 } else { 1389 LOG_ERROR(BSL_LS_APPL_TESTS, 1390 (BSL_META_U(unit, 1391 "Unit %d Ports %s-%s: Forcing max speed\n"), 1392 unit, SOC_PORT_NAME(unit, portA), 1393 SOC_PORT_NAME(unit, portB))); 1394 speed = SPEED_MAX; 1395 } 1396 infoA->speed = infoB->speed = 2500; 1397 break; 1398 1399 case SPEED_3GIG: 1400 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_3000MB) && 1401 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_3000MB)) { 1402 infoA->duplex = TRUE; 1403 infoB->duplex = TRUE; 1404 infoA->local_ability.speed_full_duplex = 1405 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_3000MB; 1406 infoA->local_ability.speed_half_duplex = 1407 infoB->local_ability.speed_half_duplex = 0; 1408 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_3000MB) && 1409 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_3000MB)) { 1410 infoA->duplex = FALSE; 1411 infoB->duplex = FALSE; 1412 infoA->local_ability.speed_full_duplex = 1413 infoB->local_ability.speed_full_duplex = 0; 1414 infoA->local_ability.speed_half_duplex = 1415 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_3000MB; 1416 } else { 1417 LOG_ERROR(BSL_LS_APPL_TESTS, 1418 (BSL_META_U(unit, 1419 "Unit %d Ports %s-%s: Forcing max speed\n"), 1420 unit, SOC_PORT_NAME(unit, portA), 1421 SOC_PORT_NAME(unit, portB))); 1422 speed = SPEED_MAX; 1423 } 1424 infoA->speed = infoB->speed = 3000; 1425 break; 1426 1427 case SPEED_10GIG: 1428 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_10GB) && 1429 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_10GB)) { 1430 infoA->duplex = TRUE; 1431 infoB->duplex = TRUE; 1432 infoA->local_ability.speed_full_duplex = 1433 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_10GB; 1434 infoA->local_ability.speed_half_duplex = 1435 infoB->local_ability.speed_half_duplex = 0; 1436 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_10GB) && 1437 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_10GB)) { 1438 infoA->duplex = FALSE; 1439 infoB->duplex = FALSE; 1440 infoA->local_ability.speed_full_duplex = 1441 infoB->local_ability.speed_full_duplex = 0; 1442 infoA->local_ability.speed_half_duplex = 1443 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_10GB; 1444 } else { 1445 LOG_ERROR(BSL_LS_APPL_TESTS, 1446 (BSL_META_U(unit, 1447 "Unit %d Ports %s-%s: Forcing max speed\n"), 1448 unit, SOC_PORT_NAME(unit, portA), 1449 SOC_PORT_NAME(unit, portB))); 1450 speed = SPEED_MAX; 1451 } 1452 infoA->speed = infoB->speed = 10000; 1453 break; 1454 1455 case SPEED_12GIG: 1456 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_12GB) && 1457 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_12GB)) { 1458 infoA->duplex = TRUE; 1459 infoB->duplex = TRUE; 1460 infoA->local_ability.speed_full_duplex = 1461 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_12GB; 1462 infoA->local_ability.speed_half_duplex = 1463 infoB->local_ability.speed_half_duplex = 0; 1464 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_12GB) && 1465 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_12GB)) { 1466 infoA->duplex = FALSE; 1467 infoB->duplex = FALSE; 1468 infoA->local_ability.speed_full_duplex = 1469 infoB->local_ability.speed_full_duplex = 0; 1470 infoA->local_ability.speed_half_duplex = 1471 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_12GB; 1472 } else { 1473 LOG_ERROR(BSL_LS_APPL_TESTS, 1474 (BSL_META_U(unit, 1475 "Unit %d Ports %s-%s: Forcing max speed\n"), 1476 unit, SOC_PORT_NAME(unit, portA), 1477 SOC_PORT_NAME(unit, portB))); 1478 speed = SPEED_MAX; 1479 } 1480 infoA->speed = infoB->speed = 12000; 1481 break; 1482 1483 case SPEED_13GIG: 1484 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_13GB) && 1485 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_13GB)) { 1486 infoA->duplex = TRUE; 1487 infoB->duplex = TRUE; 1488 infoA->local_ability.speed_full_duplex = 1489 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_13GB; 1490 infoA->local_ability.speed_half_duplex = 1491 infoB->local_ability.speed_half_duplex = 0; 1492 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_13GB) && 1493 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_13GB)) { 1494 infoA->duplex = FALSE; 1495 infoB->duplex = FALSE; 1496 infoA->local_ability.speed_full_duplex = 1497 infoB->local_ability.speed_full_duplex = 0; 1498 infoA->local_ability.speed_half_duplex = 1499 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_13GB; 1500 } else { 1501 LOG_ERROR(BSL_LS_APPL_TESTS, 1502 (BSL_META_U(unit, 1503 "Unit %d Ports %s-%s: Forcing max speed\n"), 1504 unit, SOC_PORT_NAME(unit, portA), 1505 SOC_PORT_NAME(unit, portB))); 1506 speed = SPEED_MAX; 1507 } 1508 infoA->speed = infoB->speed = 13000; 1509 break; 1510 1511 case SPEED_16GIG: 1512 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_16GB) && 1513 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_16GB)) { 1514 infoA->duplex = TRUE; 1515 infoB->duplex = TRUE; 1516 infoA->local_ability.speed_full_duplex = 1517 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_16GB; 1518 infoA->local_ability.speed_half_duplex = 1519 infoB->local_ability.speed_half_duplex = 0; 1520 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_16GB) && 1521 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_16GB)) { 1522 infoA->duplex = FALSE; 1523 infoB->duplex = FALSE; 1524 infoA->local_ability.speed_full_duplex = 1525 infoB->local_ability.speed_full_duplex = 0; 1526 infoA->local_ability.speed_half_duplex = 1527 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_16GB; 1528 } else { 1529 LOG_ERROR(BSL_LS_APPL_TESTS, 1530 (BSL_META_U(unit, 1531 "Unit %d Ports %s-%s: Forcing max speed\n"), 1532 unit, SOC_PORT_NAME(unit, portA), 1533 SOC_PORT_NAME(unit, portB))); 1534 speed = SPEED_MAX; 1535 } 1536 infoA->speed = infoB->speed = 16000; 1537 break; 1538 1539 case SPEED_20GIG: 1540 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_20GB) && 1541 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_20GB)) { 1542 infoA->duplex = TRUE; 1543 infoB->duplex = TRUE; 1544 infoA->local_ability.speed_full_duplex = 1545 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_20GB; 1546 infoA->local_ability.speed_half_duplex = 1547 infoB->local_ability.speed_half_duplex = 0; 1548 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_20GB) && 1549 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_20GB)) { 1550 infoA->duplex = FALSE; 1551 infoB->duplex = FALSE; 1552 infoA->local_ability.speed_full_duplex = 1553 infoB->local_ability.speed_full_duplex = 0; 1554 infoA->local_ability.speed_half_duplex = 1555 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_20GB; 1556 } else { 1557 LOG_ERROR(BSL_LS_APPL_TESTS, 1558 (BSL_META_U(unit, 1559 "Unit %d Ports %s-%s: Forcing max speed\n"), 1560 unit, SOC_PORT_NAME(unit, portA), 1561 SOC_PORT_NAME(unit, portB))); 1562 speed = SPEED_MAX; 1563 } 1564 infoA->speed = infoB->speed = 20000; 1565 break; 1566 1567 case SPEED_21GIG: 1568 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_21GB) && 1569 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_21GB)) { 1570 infoA->duplex = TRUE; 1571 infoB->duplex = TRUE; 1572 infoA->local_ability.speed_full_duplex = 1573 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_21GB; 1574 infoA->local_ability.speed_half_duplex = 1575 infoB->local_ability.speed_half_duplex = 0; 1576 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_21GB) && 1577 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_21GB)) { 1578 infoA->duplex = FALSE; 1579 infoB->duplex = FALSE; 1580 infoA->local_ability.speed_full_duplex = 1581 infoB->local_ability.speed_full_duplex = 0; 1582 infoA->local_ability.speed_half_duplex = 1583 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_21GB; 1584 } else { 1585 LOG_ERROR(BSL_LS_APPL_TESTS, 1586 (BSL_META_U(unit, 1587 "Unit %d Ports %s-%s: Forcing max speed\n"), 1588 unit, SOC_PORT_NAME(unit, portA), 1589 SOC_PORT_NAME(unit, portB))); 1590 speed = SPEED_MAX; 1591 } 1592 infoA->speed = infoB->speed = 21000; 1593 break; 1594 1595 case SPEED_24GIG: 1596 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_24GB) && 1597 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_24GB)) { 1598 infoA->duplex = TRUE; 1599 infoB->duplex = TRUE; 1600 infoA->local_ability.speed_full_duplex = 1601 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_24GB; 1602 infoA->local_ability.speed_half_duplex = 1603 infoB->local_ability.speed_half_duplex = 0; 1604 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_24GB) && 1605 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_24GB)) { 1606 infoA->duplex = FALSE; 1607 infoB->duplex = FALSE; 1608 infoA->local_ability.speed_full_duplex = 1609 infoB->local_ability.speed_full_duplex = 0; 1610 infoA->local_ability.speed_half_duplex = 1611 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_24GB; 1612 } else { 1613 LOG_ERROR(BSL_LS_APPL_TESTS, 1614 (BSL_META_U(unit, 1615 "Unit %d Ports %s-%s: Forcing max speed\n"), 1616 unit, SOC_PORT_NAME(unit, portA), 1617 SOC_PORT_NAME(unit, portB))); 1618 speed = SPEED_MAX; 1619 } 1620 infoA->speed = infoB->speed = 24000; 1621 break; 1622 1623 case SPEED_25GIG: 1624 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_25GB) && 1625 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_25GB)) { 1626 infoA->duplex = TRUE; 1627 infoB->duplex = TRUE; 1628 infoA->local_ability.speed_full_duplex = 1629 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_25GB; 1630 infoA->local_ability.speed_half_duplex = 1631 infoB->local_ability.speed_half_duplex = 0; 1632 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_25GB) && 1633 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_25GB)) { 1634 infoA->duplex = FALSE; 1635 infoB->duplex = FALSE; 1636 infoA->local_ability.speed_full_duplex = 1637 infoB->local_ability.speed_full_duplex = 0; 1638 infoA->local_ability.speed_half_duplex = 1639 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_25GB; 1640 } else { 1641 LOG_ERROR(BSL_LS_APPL_TESTS, 1642 (BSL_META_U(unit, 1643 "Unit %d Ports %s-%s: Forcing max speed\n"), 1644 unit, SOC_PORT_NAME(unit, portA), 1645 SOC_PORT_NAME(unit, portB))); 1646 speed = SPEED_MAX; 1647 } 1648 infoA->speed = infoB->speed = 25000; 1649 break; 1650 1651 case SPEED_30GIG: 1652 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_30GB) && 1653 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_30GB)) { 1654 infoA->duplex = TRUE; 1655 infoB->duplex = TRUE; 1656 infoA->local_ability.speed_full_duplex = 1657 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_30GB; 1658 infoA->local_ability.speed_half_duplex = 1659 infoB->local_ability.speed_half_duplex = 0; 1660 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_30GB) && 1661 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_30GB)) { 1662 infoA->duplex = FALSE; 1663 infoB->duplex = FALSE; 1664 infoA->local_ability.speed_full_duplex = 1665 infoB->local_ability.speed_full_duplex = 0; 1666 infoA->local_ability.speed_half_duplex = 1667 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_30GB; 1668 } else { 1669 LOG_ERROR(BSL_LS_APPL_TESTS, 1670 (BSL_META_U(unit, 1671 "Unit %d Ports %s-%s: Forcing max speed\n"), 1672 unit, SOC_PORT_NAME(unit, portA), 1673 SOC_PORT_NAME(unit, portB))); 1674 speed = SPEED_MAX; 1675 } 1676 infoA->speed = infoB->speed = 30000; 1677 break; 1678 1679 case SPEED_32GIG: 1680 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_32GB) && 1681 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_32GB)) { 1682 infoA->duplex = TRUE; 1683 infoB->duplex = TRUE; 1684 infoA->local_ability.speed_full_duplex = 1685 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_32GB; 1686 infoA->local_ability.speed_half_duplex = 1687 infoB->local_ability.speed_half_duplex = 0; 1688 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_32GB) && 1689 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_32GB)) { 1690 infoA->duplex = FALSE; 1691 infoB->duplex = FALSE; 1692 infoA->local_ability.speed_full_duplex = 1693 infoB->local_ability.speed_full_duplex = 0; 1694 infoA->local_ability.speed_half_duplex = 1695 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_32GB; 1696 } else { 1697 LOG_ERROR(BSL_LS_APPL_TESTS, 1698 (BSL_META_U(unit, 1699 "Unit %d Ports %s-%s: Forcing max speed\n"), 1700 unit, SOC_PORT_NAME(unit, portA), 1701 SOC_PORT_NAME(unit, portB))); 1702 speed = SPEED_MAX; 1703 } 1704 infoA->speed = infoB->speed = 32000; 1705 break; 1706 1707 case SPEED_40GIG: 1708 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_40GB) && 1709 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_40GB)) { 1710 infoA->duplex = TRUE; 1711 infoB->duplex = TRUE; 1712 infoA->local_ability.speed_full_duplex = 1713 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_40GB; 1714 infoA->local_ability.speed_half_duplex = 1715 infoB->local_ability.speed_half_duplex = 0; 1716 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_40GB) && 1717 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_40GB)) { 1718 infoA->duplex = FALSE; 1719 infoB->duplex = FALSE; 1720 infoA->local_ability.speed_full_duplex = 1721 infoB->local_ability.speed_full_duplex = 0; 1722 infoA->local_ability.speed_half_duplex = 1723 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_40GB; 1724 } else { 1725 LOG_ERROR(BSL_LS_APPL_TESTS, 1726 (BSL_META_U(unit, 1727 "Unit %d Ports %s-%s: Forcing max speed\n"), 1728 unit, SOC_PORT_NAME(unit, portA), 1729 SOC_PORT_NAME(unit, portB))); 1730 speed = SPEED_MAX; 1731 } 1732 infoA->speed = infoB->speed = 40000; 1733 break; 1734 1735 case SPEED_42GIG: 1736 if ((infoA->port_ability.speed_full_duplex & SOC_PA_SPEED_42GB) && 1737 (infoB->port_ability.speed_full_duplex & SOC_PA_SPEED_42GB)) { 1738 infoA->duplex = TRUE; 1739 infoB->duplex = TRUE; 1740 infoA->local_ability.speed_full_duplex = 1741 infoB->local_ability.speed_full_duplex = SOC_PA_SPEED_42GB; 1742 infoA->local_ability.speed_half_duplex = 1743 infoB->local_ability.speed_half_duplex = 0; 1744 } else if ((infoA->port_ability.speed_half_duplex & SOC_PA_SPEED_42GB) && 1745 (infoB->port_ability.speed_half_duplex & SOC_PA_SPEED_42GB)) { 1746 infoA->duplex = FALSE; 1747 infoB->duplex = FALSE; 1748 infoA->local_ability.speed_full_duplex = 1749 infoB->local_ability.speed_full_duplex = 0; 1750 infoA->local_ability.speed_half_duplex = 1751 infoB->local_ability.speed_half_duplex = SOC_PA_SPEED_42GB; 1752 } else { 1753 LOG_ERROR(BSL_LS_APPL_TESTS, 1754 (BSL_META_U(unit, 1755 "Unit %d Ports %s-%s: Forcing max speed\n"), 1756 unit, SOC_PORT_NAME(unit, portA), 1757 SOC_PORT_NAME(unit, portB))); 1758 speed = SPEED_MAX; 1759 } 1760 infoA->speed = infoB->speed = 42000; 1761 break; 1762 1763 case SPEED_MAX: 1764 default: 1765 speed = SPEED_MAX; 1766 break; 1767 } 1768 1769 if (speed == SPEED_MAX) { 1770 /* compare and take lesser of 1771 * bcm_port_speed_max and SOC_INFO(unit).port_speed_max */ 1772 bcm_port_speed_max(unit, portA, &infoA->speed); 1773 if (infoA->speed > SOC_INFO(unit).port_speed_max[portA]) { 1774 infoA->speed = SOC_INFO(unit).port_speed_max[portA]; 1775 } 1776 bcm_port_speed_max(unit, portB, &infoB->speed); 1777 if (infoB->speed > SOC_INFO(unit).port_speed_max[portB]) { 1778 infoB->speed = SOC_INFO(unit).port_speed_max[portB]; 1779 } 1780 1781 /* Pick lesser of two speeds if gigabit attached to fast */ 1782 if (infoA->speed < infoB->speed) { 1783 cli_out("NOTICE: port %s only capable of speed %d, setting " 1784 "link partner to match.\n", 1785 SOC_PORT_NAME(unit, portA), infoA->speed); 1786 infoB->speed = infoA->speed; 1787 } 1788 if (infoB->speed < infoA->speed) { 1789 cli_out("NOTICE: port %s only capable of speed %d, setting " 1790 "link partner to match.\n", 1791 SOC_PORT_NAME(unit, portB), infoB->speed); 1792 infoA->speed = infoB->speed; 1793 } 1794 infoA->duplex = infoB->duplex = TRUE; 1795 } 1796 1797 /* Setup test mode (internal/external) */ 1798 switch ( mode ) { 1799 default: 1800 case TRAFFIC_EXTERNAL_BI: /* A <-> B */ 1801 case TRAFFIC_EXTERNAL_UP: /* A -> B */ 1802 case TRAFFIC_EXTERNAL_DOWN: /* A <- B */ 1803 infoA->autoneg = infoB->autoneg = dfl_autoneg; 1804 infoA->enable = infoB->enable = TRUE; 1805 infoA->stp_state = infoB->stp_state = BCM_STG_STP_FORWARD; 1806 break; 1807 1808 case TRAFFIC_INTERNAL: 1809 infoA->autoneg = infoB->autoneg = FALSE; 1810 infoA->enable = infoB->enable = TRUE; 1811 infoA->stp_state = infoB->stp_state = BCM_STG_STP_FORWARD; 1812 infoA->loopback = infoB->loopback = BCM_PORT_LOOPBACK_MAC; 1813 break; 1814 1815 case TRAFFIC_INTERNAL_PHY: 1816 infoA->autoneg = infoB->autoneg = FALSE; 1817 infoA->enable = infoB->enable = TRUE; 1818 infoA->stp_state = infoB->stp_state = BCM_STG_STP_FORWARD; 1819 infoA->loopback = infoB->loopback = BCM_PORT_LOOPBACK_PHY; 1820 break; 1821 1822 } 1823 1824 /* When ANA is disabled, on Gigabit port: assign A as master */ 1825 if ((!infoA->autoneg) || (!infoB->autoneg)) { 1826 bcm_port_medium_t medium; 1827 rv = bcm_port_medium_get(unit, portA, &medium); 1828 if (rv >= 0) { 1829 if (medium == BCM_PORT_MEDIUM_COPPER) { 1830 if (IS_GE_PORT(unit, portA)) { 1831 infoA->phy_master = TRUE; 1832 } else if (IS_GE_PORT(unit, portB)) { 1833 infoB->phy_master = TRUE; 1834 } 1835 } 1836 } 1837 } 1838 1839 /* If port is FE port, remove phy_master attributes controlled by it */ 1840 if(IS_FE_PORT(unit, portA)) { 1841 infoA->action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 1842 } 1843 if(IS_FE_PORT(unit, portB)) { 1844 infoB->action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 1845 } 1846 1847 /* If the Master mode is not changed, remove phy_master attributes from action_mask */ 1848 ms = 0; 1849 if ((rv = bcm_port_master_get(unit, portA, &ms)) != BCM_E_NONE) { 1850 cli_out("traffic setup: port %s: could not get port Master mode: %s\n", 1851 SOC_PORT_NAME(unit, portA), 1852 bcm_errmsg(rv)); 1853 return -1; 1854 } 1855 if (ms == infoA->phy_master) { 1856 infoA->action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 1857 } 1858 1859 ms = 0; 1860 if ((rv = bcm_port_master_get(unit, portB, &ms)) != BCM_E_NONE) { 1861 cli_out("traffic setup: port %s: could not get port Master mode: %s\n", 1862 SOC_PORT_NAME(unit, portB), 1863 bcm_errmsg(rv)); 1864 return -1; 1865 } 1866 if (ms == infoB->phy_master) { 1867 infoB->action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 1868 } 1869 1870 /* Commit all changes in one call */ 1871 if (IS_CD_PORT(unit, portA)) { 1872 bcm_port_resource_t_init(&portResrc); 1873 1874 /* Retrieve the port resource details for the given port */ 1875 if ((rv=bcm_port_resource_speed_get(unit, portA, &portResrc)) < 0) { 1876 cli_out("ERROR: traffic setup unit %d, ports %s, %s:" 1877 "%s resource speed get failed: %s\n", 1878 unit, 1879 SOC_PORT_NAME(unit, portA), 1880 SOC_PORT_NAME(unit, portB), 1881 SOC_PORT_NAME(unit, portA), 1882 bcm_errmsg(rv)); 1883 return -1; 1884 } 1885 1886 /* Save the new speed to be set */ 1887 portResrc.speed = infoA->speed; 1888 1889 /* Call the API to set the new port speed */ 1890 rv = bcm_port_resource_speed_set(unit, portA, &portResrc); 1891 1892 } else { 1893 /* Call the API to set the new port speed */ 1894 rv = bcm_port_speed_set(unit, portA, infoA->speed); 1895 } 1896 1897 if (rv < 0) { 1898 cli_out("ERROR: traffic setup unit %d, " 1899 "port %s - speed %d set failed: %s\n", 1900 unit, 1901 SOC_PORT_NAME(unit, portA), 1902 infoA->speed, 1903 bcm_errmsg(rv)); 1904 return -1; 1905 } 1906 1907 if (IS_CD_PORT(unit, portB)) { 1908 bcm_port_resource_t_init(&portResrc); 1909 1910 /* Retrieve the port resource details for the given port */ 1911 if ((rv=bcm_port_resource_speed_get(unit, portB, &portResrc)) < 0) { 1912 cli_out("ERROR: traffic setup unit %d, ports %s, %s:" 1913 "%s resource speed get failed: %s\n", 1914 unit, 1915 SOC_PORT_NAME(unit, portA), 1916 SOC_PORT_NAME(unit, portB), 1917 SOC_PORT_NAME(unit, portB), 1918 bcm_errmsg(rv)); 1919 return -1; 1920 } 1921 1922 /* Save the new speed to be set */ 1923 portResrc.speed = infoB->speed; 1924 1925 /* Call the API to set the new port speed */ 1926 rv = bcm_port_resource_speed_set(unit, portB, &portResrc); 1927 1928 } else { 1929 /* Call the API to set the new port speed */ 1930 rv = bcm_port_speed_set(unit, portB, infoB->speed); 1931 } 1932 1933 if (rv < 0) { 1934 cli_out("ERROR: traffic setup unit %d, " 1935 "port %s - speed %d set failed: %s\n", 1936 unit, 1937 SOC_PORT_NAME(unit, portB), 1938 infoB->speed, 1939 bcm_errmsg(rv)); 1940 return -1; 1941 } 1942 1943 if (((rv = bcm_port_duplex_set(unit, portA, infoA->duplex)) < 0) || 1944 ((rv = bcm_port_duplex_set(unit, portB, infoB->duplex)) < 0) || 1945 ((rv = bcm_port_loopback_set(unit, portA, infoA->loopback)) < 0) || 1946 ((rv = bcm_port_loopback_set(unit, portB, infoB->loopback)) < 0) || 1947 ((rv = bcm_port_info_restore(unit, portA, infoA)) < 0)) { 1948 cli_out("ERROR: traffic setup unit %d, ports %s, %s:" 1949 " %s info restore failed: %s\n", 1950 unit, 1951 SOC_PORT_NAME(unit, portA), 1952 SOC_PORT_NAME(unit, portB), 1953 SOC_PORT_NAME(unit, portA), 1954 bcm_errmsg(rv)); 1955 cli_out("%s: duplex = %d, loopback = %d\n", 1956 SOC_PORT_NAME(unit, portA), infoA->duplex, infoA->loopback); 1957 cli_out("%s: duplex = %d, loopback = %d\n", 1958 SOC_PORT_NAME(unit, portB), infoB->duplex, infoB->loopback); 1959 return -1; 1960 } 1961 if ((rv = bcm_port_info_restore(unit, portB, infoB)) < 0) { 1962 cli_out("ERROR: traffic setup unit %d, ports %s, %s:" 1963 " %s info restore failed: %s\n", 1964 unit, 1965 SOC_PORT_NAME(unit, portA), 1966 SOC_PORT_NAME(unit, portB), 1967 SOC_PORT_NAME(unit, portB), 1968 bcm_errmsg(rv)); 1969 return -1; 1970 } 1971 1972 #if defined(INCLUDE_MACSEC) 1973 if (_traffic_setup_macsec(unit, portA, portB, test) < 0) { 1974 cli_out("ERROR: MACSEC traffic setup unit %d, ports %s, %s: Failed\n", 1975 unit, 1976 SOC_PORT_NAME(unit, portA), 1977 SOC_PORT_NAME(unit, portB)); 1978 return -1; 1979 } 1980 #endif /* INCLUDE_MACSEC */ 1981 1982 cli_out("PORT "); 1983 1984 1985 /* Setup VLAN broadcast domains including only each port-pair */ 1986 #ifdef BCM_XGS12_FABRIC_SUPPORT 1987 if (SOC_IS_XGS12_FABRIC(unit)) { 1988 int mod, rv; 1989 bcm_port_t xport; 1990 1991 /* Setup UC: each module id has every port in it (except CPU) */ 1992 PBMP_PORT_ITER(unit, xport) { 1993 for (mod = 0; mod <= SOC_MODID_MAX(unit); mod++) { 1994 rv = bcm_stk_ucbitmap_set(unit, xport, mod, 1995 PBMP_PORT_ALL(unit)); 1996 if (rv < 0) { 1997 cli_out("ERROR: port %d module %d: " 1998 "bcm_stk_ucbitmap_set failed: %s\n", 1999 xport, mod, bcm_errmsg(rv)); 2000 break; 2001 } 2002 } 2003 } 2004 2005 /* Setup VID=1 to have every port in it (except CPU) */ 2006 BCM_PBMP_CLEAR(port_pbm); 2007 rv = bcm_vlan_port_add(unit, VLAN_ID_DEFAULT, 2008 PBMP_PORT_ALL(unit), port_pbm); 2009 if (rv < 0) { 2010 cli_out("ERROR: vlan %d: add all ports failed: %s\n", 2011 VLAN_ID_DEFAULT, bcm_errmsg(rv)); 2012 } 2013 } else { 2014 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 2015 2016 /* StrataSwitch / Draco */ 2017 config->vidA = TRAFFIC_VID_BASE + portA; 2018 config->vidB = config->vidA + 1; 2019 2020 BCM_PBMP_CLEAR(port_pbm); 2021 BCM_PBMP_PORT_ADD(port_pbm, portA); 2022 BCM_PBMP_PORT_ADD(port_pbm, portB); 2023 2024 bcm_vlan_port_remove(unit, VLAN_ID_DEFAULT, port_pbm); 2025 2026 /* 2027 * Internal MAC/PHY traffic. One VLAN, port A and B both 2028 * members. Port based vlan entry is the same for both 2029 * ports. 2030 */ 2031 if ((mode == TRAFFIC_INTERNAL) || 2032 (mode == TRAFFIC_INTERNAL_PHY)) { 2033 2034 /* Share VLAN */ 2035 config->vidB = config->vidA; 2036 2037 if (bcm_vlan_create(unit, config->vidA) < 0) { 2038 cli_out("ERROR: ports %s, %s vlan %d: cannot create vlan\n", 2039 SOC_PORT_NAME(unit, portA), 2040 SOC_PORT_NAME(unit, portB), 2041 config->vidA); 2042 } 2043 2044 bcm_vlan_port_add(unit, config->vidA, port_pbm, port_pbm); 2045 2046 if (bcm_port_untagged_vlan_set(unit, portA, config->vidA) < 0) { 2047 cli_out("ERROR: port %s vlan %d: cannot set default vlan\n", 2048 SOC_PORT_NAME(unit, portA), 2049 config->vidA); 2050 } 2051 if (bcm_port_untagged_vlan_set(unit, portB, config->vidA) < 0) { 2052 cli_out("ERROR: port %s vlan %d: cannot set default vlan\n", 2053 SOC_PORT_NAME(unit, portB), 2054 config->vidA); 2055 } 2056 } else { 2057 2058 /* External cable traffic, 2 VLANS, port A and B both 2059 * members, native (port-based VLAN id) is vidA for portA, 2060 * and vidB for portB, from the CLI, the structure is: 2061 * 2062 * vlan create A PBM=portA,portB UBM=portA,portB 2063 * vlan create B PBM=portA,portB UBM=portA,portB 2064 * pvlan set portA A 2065 * pvlan set portB B 2066 */ 2067 if (bcm_vlan_create(unit, config->vidA) < 0) { 2068 cli_out("ERROR: ports %s, %s vlan %d: cannot create vlan\n", 2069 SOC_PORT_NAME(unit, portA), 2070 SOC_PORT_NAME(unit, portB), 2071 config->vidA); 2072 } 2073 if (bcm_vlan_create(unit, config->vidB) < 0) { 2074 cli_out("ERROR: ports %s, %s vlan %d: cannot create vlan\n", 2075 SOC_PORT_NAME(unit, portA), 2076 SOC_PORT_NAME(unit, portB), 2077 config->vidB); 2078 } 2079 2080 bcm_vlan_port_add(unit, config->vidA, port_pbm, port_pbm); 2081 bcm_vlan_port_add(unit, config->vidB, port_pbm, port_pbm); 2082 2083 if (bcm_port_untagged_vlan_set(unit, portA, config->vidA) < 0) { 2084 cli_out("ERROR: port %s vlan %d: cannot set default vlan\n", 2085 SOC_PORT_NAME(unit, portA), 2086 config->vidA); 2087 } 2088 2089 if (bcm_port_untagged_vlan_set(unit, portB, config->vidB) < 0) { 2090 cli_out("ERROR: port %s vlan %d: cannot set default vlan\n", 2091 SOC_PORT_NAME(unit, portB), 2092 config->vidB); 2093 } 2094 2095 } 2096 #ifdef BCM_XGS12_FABRIC_SUPPORT 2097 } 2098 #endif 2099 2100 #ifdef BCM_ESW_SUPPORT 2101 if (SOC_IS_XGS3_SWITCH(unit)) { 2102 if (IS_ST_PORT(unit, portA) || IS_ST_PORT(unit, portB)) { 2103 int modid = _traffic_xgs3_test_modid_get(unit, portA); 2104 if (modid < 0) { 2105 cli_out("ERROR: port %s: could not get modid\n", 2106 SOC_PORT_NAME(unit, portA)); 2107 } 2108 _traffic_xgs3_modport_set(unit, modid, portA, portB); 2109 _traffic_xgs3_modport_set(unit, modid, portB, portA); 2110 } 2111 } 2112 #endif /* BCM_ESW_SUPPORT */ 2113 2114 cli_out("VLAN "); 2115 2116 /* Setup ARL, for port to forward traffic of a given 2117 * MAC address and vlan back into each port 2118 */ 2119 if (!SOC_IS_XGS12_FABRIC(unit)) { 2120 /* StrataSwitch / XGS switch */ 2121 if ((mode == TRAFFIC_INTERNAL) || 2122 (mode == TRAFFIC_INTERNAL_PHY)) { 2123 /* DLF storm created */ 2124 2125 } else if (!IS_HG_PORT(unit, portA)) { 2126 /* External 2127 * 2128 * l2 add PBM=portA MAC=00:00:00:00:00:portA V=B ST=T 2129 * l2 add PBM=portA MAC=00:00:00:00:00:portB V=A ST=T 2130 */ 2131 traffic_test_setup_l2addr(unit, 2132 &config->l2A, config->vidB, portA); 2133 traffic_test_setup_l2addr(unit, 2134 &config->l2B, config->vidA, portB); 2135 2136 } 2137 cli_out("L2 "); 2138 } 2139 2140 2141 /* Force ports into STP forwarding state */ 2142 bcm_port_stp_set(unit, portA, BCM_STG_STP_FORWARD); 2143 bcm_port_stp_set(unit, portB, BCM_STG_STP_FORWARD); 2144 2145 /* Clear stats */ 2146 bcm_stat_clear(unit, portA); 2147 bcm_stat_clear(unit, portB); 2148 cli_out("STAT\n"); 2149 2150 return 0; 2151 } 2152 2153 /* 2154 * Print bytes as %d,%2.2fK, %2.2fG, etc. 2155 */ 2156 static void 2157 traffic_show_number(uint64 v) 2158 { 2159 #ifdef COMPILER_HAS_DOUBLE 2160 COMPILER_DOUBLE value; 2161 2162 COMPILER_64_TO_DOUBLE(value, v); 2163 2164 if (value < KILO(1.0)) { 2165 cli_out("%d", (int)value) ; 2166 } else if (value >= TERA(1.0)) { 2167 value /= TERA(1.0); 2168 cli_out("%2.2fT", value); 2169 } else if (value >= GIGA(1.0)) { 2170 value /= GIGA(1.0); 2171 cli_out("%2.2fG", value); 2172 } else if (value >= MEGA(1.0)) { 2173 value /= MEGA(1.0); 2174 cli_out("%2.2fM", value); 2175 } else { 2176 value /= KILO(1.0); 2177 cli_out("%2.2fK", value); 2178 } 2179 #else 2180 uint32 value; 2181 int prec = 100; 2182 char *s; 2183 2184 s = _shr_scale_uint64(v, 1024, prec, &value); 2185 if (*s) { 2186 cli_out("%d.%02d%s", value / prec, value % prec, s); 2187 } else { 2188 cli_out("%d", value / prec); 2189 } 2190 #endif 2191 } 2192 2193 static void 2194 traffic_show_measured_number(uint64 v, int interval) 2195 { 2196 #ifdef COMPILER_HAS_DOUBLE 2197 COMPILER_DOUBLE value; 2198 2199 COMPILER_64_TO_DOUBLE(value, v); 2200 2201 value /= interval; 2202 2203 if (value < KILO(1.0)) { 2204 cli_out("%d", (int)value) ; 2205 } else if (value >= TERA(1.0)) { 2206 value /= TERA(1.0); 2207 cli_out("%2.2fT", value); 2208 } else if (value >= GIGA(1.0)) { 2209 value /= GIGA(1.0); 2210 cli_out("%2.2fG", value); 2211 } else if (value >= MEGA(1.0)) { 2212 value /= MEGA(1.0); 2213 cli_out("%2.2fM", value); 2214 } else { 2215 value /= KILO(1.0); 2216 cli_out("%2.2fK", value); 2217 } 2218 #else 2219 uint64 value64; 2220 int t; 2221 2222 value64 = v; 2223 2224 /* Shift down to 32 bits */ 2225 t = 0; 2226 while (COMPILER_64_HI(value64)) { 2227 COMPILER_64_SHR(value64, 1); 2228 t++; 2229 } 2230 /* Perform 32 bit division with rounding */ 2231 COMPILER_64_SET(value64, 0, _shr_div32r(COMPILER_64_LO(value64), interval)); 2232 /* Shift back - precision is still adequate */ 2233 COMPILER_64_SHL(value64, t); 2234 2235 traffic_show_number(value64); 2236 #endif 2237 } 2238 2239 /* 2240 * Print rate as %d,%2.2fG, etc. 2241 */ 2242 static void 2243 traffic_show_measured_rate(uint64 v, int interval, int bytes) 2244 { 2245 #ifdef COMPILER_HAS_DOUBLE 2246 double value = (COMPILER_64_HI(v) * 4294967296.0 + COMPILER_64_LO(v)); 2247 value /= interval; 2248 if (bytes) { 2249 value *= 8; 2250 } 2251 if (value < 1000.0) { 2252 cli_out("%d", (int)value) ; 2253 } else if (value >= 1000000000.0) { 2254 value /= 1000000000.0; 2255 cli_out("%2.2fG", value); 2256 } else if (value >= 1000000.0) { 2257 value /= 1000000.0; 2258 cli_out("%2.2fM", value); 2259 } else { 2260 value /= 1000.0; 2261 cli_out("%2.2fK", value); 2262 } 2263 #else 2264 uint64 value; 2265 uint32 val32; 2266 int i; 2267 int prec = 100; 2268 char *s; 2269 2270 /* Multiply by 8 if byte count */ 2271 if (bytes) { 2272 COMPILER_64_SHL(v, 3); 2273 } 2274 /* Shift down to 32 bits */ 2275 i = 0; 2276 while (COMPILER_64_HI(v)) { 2277 COMPILER_64_SHR(v, 1); 2278 i++; 2279 } 2280 /* Perform 32 bit division with rounding */ 2281 COMPILER_64_SET(value, 0, _shr_div32r(COMPILER_64_LO(v), interval)); 2282 /* Shift back - precision is still adequate */ 2283 COMPILER_64_SHL(value, i); 2284 2285 s = _shr_scale_uint64(value, 1000, prec, &val32); 2286 if (*s) { 2287 cli_out("%d.%02d%s", val32 / prec, val32 % prec, s); 2288 } else { 2289 cli_out("%d", val32 / prec); 2290 } 2291 #endif 2292 } 2293 2294 /* 2295 * Print time (in seconds) as minutes, hours, etc. 2296 */ 2297 static void 2298 traffic_show_runtime(uint32 value) 2299 { 2300 if (value >= 12*4*7*60*60*24) { 2301 value /= 12*4*7*60*60*24; 2302 cli_out("%d years", value); 2303 } else if (value >= 4*7*60*60*24 ) { 2304 value /= 4*7*60*60*24 ; 2305 cli_out("%d months", value); 2306 } else if (value >= 7*60*60*24 ) { 2307 value /= 7*60*60*24 ; 2308 cli_out("%d weeks", value); 2309 } else if (value >= 60*60*24) { 2310 value /= 60*60*24 ; 2311 cli_out("%d days", value); 2312 } else if (value >= 60*60) { 2313 value /= 60*60; 2314 cli_out("%d hours", value); 2315 } else if (value >= 60) { 2316 value /= 60; 2317 cli_out("%d minutes", value); 2318 } else { 2319 cli_out("%d seconds", value) ; 2320 } 2321 } 2322 2323 /* 2324 * Run test structure. 2325 */ 2326 int 2327 traffic_run_test(traffic_test_t* test) 2328 { 2329 uint32 runtime; 2330 int port, portA, portB, interval; 2331 int waitloop; 2332 int rv; 2333 pbmp_t pbm, portpbm,failedpbm; 2334 bcm_port_ability_t portA_ability; 2335 bcm_port_ability_t portB_ability; 2336 char pfmt[SOC_PBMP_FMT_LEN]; 2337 char bmstr[FORMAT_PBMP_MAX]; 2338 int unit; 2339 int lastportA; 2340 int notraffic; 2341 int passed = 1; 2342 #if defined(BCM_ESW_SUPPORT) 2343 uint32 curr_counter_flags; 2344 int curr_counter_interval; 2345 pbmp_t curr_counter_pbm; 2346 #endif 2347 #if defined(BCM_ENDURO_SUPPORT) 2348 uint32 val=0; 2349 #endif 2350 uint64 rbyt, tbyt, rpkt, tpkt, rerr,raln, rdisc, dropped; 2351 uint64 drbyt, dtbyt, drpkt, dtpkt, drerr, draln, drdisc, ddropped; 2352 2353 COMPILER_64_ZERO(rbyt); COMPILER_REFERENCE(&rbyt); 2354 COMPILER_64_ZERO(tbyt); COMPILER_REFERENCE(&tbyt); 2355 COMPILER_64_ZERO(rpkt); COMPILER_REFERENCE(&rpkt); 2356 COMPILER_64_ZERO(tpkt); COMPILER_REFERENCE(&tpkt); 2357 COMPILER_64_ZERO(rerr); COMPILER_REFERENCE(&rerr); 2358 COMPILER_64_ZERO(raln); COMPILER_REFERENCE(&raln); 2359 COMPILER_64_ZERO(rdisc); COMPILER_REFERENCE(&rdisc); 2360 COMPILER_64_ZERO(dropped); COMPILER_REFERENCE(&dropped); 2361 COMPILER_64_ZERO(drbyt); COMPILER_REFERENCE(&drbyt); 2362 COMPILER_64_ZERO(dtbyt); COMPILER_REFERENCE(&dtbyt); 2363 COMPILER_64_ZERO(drpkt); COMPILER_REFERENCE(&drpkt); 2364 COMPILER_64_ZERO(dtpkt); COMPILER_REFERENCE(&dtpkt); 2365 COMPILER_64_ZERO(drerr); COMPILER_REFERENCE(&drerr); 2366 COMPILER_64_ZERO(draln); COMPILER_REFERENCE(&draln); 2367 COMPILER_64_ZERO(drdisc); COMPILER_REFERENCE(&drdisc); 2368 COMPILER_64_ZERO(ddropped);COMPILER_REFERENCE(&ddropped); 2369 2370 unit = test->unit; 2371 BCM_IF_ERROR_RETURN 2372 (traffic_test_setup_maxframe(test)); 2373 2374 (void)format_pbmp(unit, bmstr, sizeof(bmstr), test->ports); 2375 cli_out("TRAFFIC: unit %d ports %s (%s), %d packets, mode %s\n", 2376 unit, 2377 bmstr, 2378 SOC_PBMP_FMT(test->ports, pfmt), 2379 test->npkts, 2380 traffic_mode_str[test->mode]); 2381 2382 /* Disable l2 address aging ... */ 2383 bcm_l2_age_timer_set(unit, 0); 2384 2385 lastportA = -1; 2386 2387 PBMP_ITER(test->ports, port) { 2388 test->port_pair[port].portA = -1; 2389 if (lastportA < 0) { /* this will be a port A */ 2390 if (!IS_CD_PORT(unit, port)) { 2391 if (bcm_port_ability_local_get(unit, port, &portA_ability) < 0) { 2392 cli_out("ERROR: traffic setup unit %d, ports %s: " 2393 "ability get failed\n", 2394 unit, SOC_PORT_NAME(unit, port)); 2395 return -1; 2396 } 2397 } 2398 lastportA = port; 2399 } else { /* this will be a port B */ 2400 if (!IS_CD_PORT(unit, port)) { 2401 if (bcm_port_ability_local_get(unit, port, &portB_ability) < 0) { 2402 cli_out("ERROR: traffic setup unit %d, ports %s: " 2403 "ability get failed\n", 2404 unit, SOC_PORT_NAME(unit, port)); 2405 return -1; 2406 } 2407 /* coverity[uninit_use:FALSE] */ 2408 if ((!(portA_ability.speed_full_duplex & 2409 portB_ability.speed_full_duplex) && 2410 !(portA_ability.speed_half_duplex & 2411 portB_ability.speed_half_duplex)) || 2412 (portA_ability.encap != portB_ability.encap)) { 2413 BCM_PBMP_PORT_REMOVE(test->ports, lastportA); 2414 cli_out("WARNING: no common speed between ports %s, %s:" 2415 " skip %s\n", 2416 SOC_PORT_NAME(unit, lastportA), 2417 SOC_PORT_NAME(unit, port), 2418 SOC_PORT_NAME(unit, lastportA)); 2419 lastportA = port; 2420 portA_ability = portB_ability; 2421 continue; 2422 } 2423 } 2424 #if defined(BCM_GREYHOUND2_SUPPORT) 2425 if (SOC_IS_GREYHOUND2(unit)) { 2426 int speedmaxA, speedmaxB; 2427 bcm_port_abil_t max_speed_mask; 2428 2429 /* if testing with sp=maximun(default), make sure both portA and B support the least common maximun speed*/ 2430 if (bcm_port_speed_max(unit, lastportA, &speedmaxA) < 0) { 2431 cli_out("Error: Port speed max get fail unit %d, ports %d: " 2432 "ability get failed\n", 2433 unit, lastportA); 2434 return -1; 2435 } 2436 if (speedmaxA > SOC_INFO(unit).port_speed_max[lastportA]) { 2437 speedmaxA = SOC_INFO(unit).port_speed_max[lastportA]; 2438 } 2439 if (bcm_port_speed_max(unit, port, &speedmaxB) < 0) { 2440 cli_out("Error: Port speed max get fail unit %d, ports %d: " 2441 "ability get failed\n", 2442 unit, port); 2443 return -1; 2444 } 2445 if (speedmaxB > SOC_INFO(unit).port_speed_max[port]) { 2446 speedmaxB = SOC_INFO(unit).port_speed_max[port]; 2447 } 2448 if (speedmaxA > speedmaxB) { 2449 max_speed_mask = SOC_PA_SPEED(speedmaxB); 2450 if (!(portA_ability.speed_full_duplex & max_speed_mask)) { 2451 BCM_PBMP_PORT_REMOVE(test->ports, lastportA); 2452 cli_out("WARNING: no common max speed between ports %s, %s:" 2453 " skip %s\n", 2454 SOC_PORT_NAME(unit, lastportA), 2455 SOC_PORT_NAME(unit, port), 2456 SOC_PORT_NAME(unit, lastportA)); 2457 lastportA = port; 2458 portA_ability = portB_ability; 2459 continue; 2460 } 2461 } else if (speedmaxA < speedmaxB) { 2462 max_speed_mask = SOC_PA_SPEED(speedmaxA); 2463 if (!(portB_ability.speed_full_duplex & max_speed_mask)) { 2464 BCM_PBMP_PORT_REMOVE(test->ports, lastportA); 2465 cli_out("WARNING: no common max speed between ports %s, %s:" 2466 " skip %s\n", 2467 SOC_PORT_NAME(unit, lastportA), 2468 SOC_PORT_NAME(unit, port), 2469 SOC_PORT_NAME(unit, lastportA)); 2470 lastportA = port; 2471 /* coverity[uninit_use:FALSE] */ 2472 portA_ability = portB_ability; 2473 continue; 2474 } 2475 2476 } 2477 } 2478 #endif /* BCM_GREYHOUND2_SUPPORT */ 2479 test->port_pair[lastportA].portA = lastportA; 2480 test->port_pair[lastportA].portB = port; 2481 lastportA = -1; 2482 } 2483 } 2484 if (lastportA != -1) { 2485 BCM_PBMP_PORT_REMOVE(test->ports, lastportA); 2486 cli_out("WARNING: odd number of ports, will not use port %s\n", 2487 SOC_PORT_NAME(unit, lastportA)); 2488 } 2489 2490 cli_out("TRAFFIC: Port pairing:"); 2491 PBMP_ITER(test->ports, port) { 2492 if (test->port_pair[port].portA != port) { 2493 /* skip B ports and unused ports */ 2494 continue; 2495 } 2496 cli_out(" %s-%s", 2497 SOC_PORT_NAME(unit, test->port_pair[port].portA), 2498 SOC_PORT_NAME(unit, test->port_pair[port].portB)); 2499 } 2500 cli_out("\n"); 2501 2502 /* First, configure forwarding behaviours */ 2503 PBMP_ITER(test->ports, port) { 2504 if (test->port_pair[port].portA != port) { /* skip B ports */ 2505 continue; 2506 } 2507 cli_out("TRAFFIC: setting up ports %s, %s: ", 2508 SOC_PORT_NAME(unit, test->port_pair[port].portA), 2509 SOC_PORT_NAME(unit, test->port_pair[port].portB)); 2510 traffic_test_setup_port_pair(test, port, test->mode, test->req_speed); 2511 } 2512 2513 #if defined(INCLUDE_MACSEC) 2514 if (test->macsec_enabled) { 2515 _traffic_setup_macsec_poll_task(unit, test); 2516 } 2517 #endif /* INCLUDE_MACSEC */ 2518 2519 SOC_PBMP_ASSIGN(pbm, test->ports); 2520 (void)format_pbmp(unit, bmstr, sizeof(bmstr), pbm); 2521 cli_out("TRAFFIC: waiting for link on ports %s (%s)\n", 2522 bmstr, SOC_PBMP_FMT(pbm, pfmt)); 2523 2524 rv = bcm_link_wait(unit, &pbm, TRAFFIC_LINK_TIMEOUT); 2525 if (!BCM_SUCCESS(rv)) { 2526 SOC_PBMP_ASSIGN(portpbm, test->ports); 2527 SOC_PBMP_REMOVE(portpbm, pbm); 2528 (void)format_pbmp(unit, bmstr, sizeof(bmstr), portpbm); 2529 test_error(unit, "TRAFFIC: failed waiting for link on %s (%s): %s\n", 2530 bmstr, SOC_PBMP_FMT(portpbm, pfmt), bcm_errmsg(rv)); 2531 return -1; 2532 } 2533 2534 /* Link is up - make sure port characteristics from PHY and MAC are match */ 2535 PBMP_ITER(test->ports, port) { 2536 bcm_port_update(unit, port, 1); 2537 } 2538 2539 /* sleep for half second to allow MAC, serdes and PHY to stabilize. 2540 * bcm_link_wait may not reflect the internal serdes link status 2541 */ 2542 sal_usleep(500000); 2543 2544 /* Wait to for MAC to be stable */ 2545 rv = bcm_link_wait(unit, &pbm, TRAFFIC_LINK_TIMEOUT); 2546 if (!BCM_SUCCESS(rv)) { 2547 SOC_PBMP_ASSIGN(portpbm, test->ports); 2548 SOC_PBMP_REMOVE(portpbm, pbm); 2549 (void)format_pbmp(unit, bmstr, sizeof(bmstr), portpbm); 2550 test_error(unit, "TRAFFIC: failed waiting for link on %s (%s): %s\n", 2551 bmstr, SOC_PBMP_FMT(portpbm, pfmt), bcm_errmsg(rv)); 2552 return -1; 2553 } 2554 2555 /* 2556 * Clear all H/W counters using soc driver,we do it here 2557 * so that if we are running an external test, we won't see 2558 * a false-carrier error if it occurs. 2559 */ 2560 #ifdef BCM_ESW_SUPPORT 2561 if (soc_counter_set32_by_port(unit, test->ports, 0) < 0) { 2562 cli_out("ERROR: Clear counters failed\n"); 2563 return -1; 2564 } 2565 #endif 2566 2567 /* Finally, inject the frame on each port pair .... */ 2568 PBMP_ITER(test->ports, port) { 2569 if (test->port_pair[port].portA != port) { /* skip B ports */ 2570 continue; 2571 } 2572 cli_out("TRAFFIC: starting %d byte frames on ports %s, %s\n", 2573 test->pkt_size, 2574 SOC_PORT_NAME(unit, test->port_pair[port].portA), 2575 SOC_PORT_NAME(unit, test->port_pair[port].portB)); 2576 traffic_test_send_frames(test, port); 2577 } 2578 2579 /* Loop until user presses control-C, showing status */ 2580 interval = test->poll_interval; /* seconds */ 2581 runtime = 0; 2582 2583 if (test->runtime <= test->poll_interval) { 2584 test->runtime = test->poll_interval + 1; 2585 cli_out("NOTICE: test will poll in %d seconds" 2586 ", using new test runtime of %d seconds.\n", 2587 test->poll_interval, test->poll_interval + 1); 2588 } 2589 2590 /* Save the current parameters for counter collection task. */ 2591 #ifdef BCM_ESW_SUPPORT 2592 if (soc_counter_status(unit, &curr_counter_flags, &curr_counter_interval, 2593 &curr_counter_pbm) < 0) { 2594 cli_out("ERROR: Failed to get counter collection status\n"); 2595 return -1; 2596 } 2597 #endif 2598 2599 2600 2601 /* 2602 * Start (or re-start) counter collection with an interval which is two 2603 * times longer than the polling interval of the test. This prevents 2604 * the counter collection thread from syncing stats too often 2605 * giving us predictable results when calling bcm_stat_sync below. 2606 * Wrap-around should not be an issue since the HW has 64-bit counters. 2607 */ 2608 #ifdef BCM_ESW_SUPPORT 2609 if (soc_counter_start(unit, curr_counter_flags, 2610 test->poll_interval * 2000000, 2611 test->ports) < 0) { 2612 cli_out("ERROR: Failed to start counter collection\n"); 2613 return -1; 2614 } 2615 #endif 2616 2617 SOC_PBMP_CLEAR(failedpbm); /*Initialize the pbm*/ 2618 2619 /* Wait a configurable amount of time, then check the stats */ 2620 waitloop = 0; 2621 while (runtime <= test->runtime) { 2622 waitloop += 1; 2623 2624 { 2625 /* syncing counters before thread goes to sleep */ 2626 sal_usleep(interval * SECOND_USEC); 2627 bcm_stat_sync(unit); 2628 2629 PBMP_ITER(test->ports, port) { 2630 portA = test->port_pair[port].portA; 2631 portB = test->port_pair[port].portB; 2632 if (port != portA) { 2633 continue; 2634 } 2635 bcm_stat_get(unit, port, snmpIfInOctets, &rbyt); 2636 bcm_stat_get(unit, port, snmpIfOutOctets, &tbyt); 2637 bcm_stat_get(unit, port, snmpDot1dTpPortOutFrames, &tpkt); 2638 bcm_stat_get(unit, port, snmpDot1dTpPortInFrames, &rpkt); 2639 bcm_stat_get(unit, port, snmpDot3StatsAlignmentErrors, &raln); 2640 bcm_stat_get(unit, port, snmpDot3StatsInternalMacReceiveErrors, 2641 &rdisc); 2642 bcm_stat_get(unit, port, snmpIfInDiscards, &dropped); 2643 2644 test->port_stats[port].rbyt = rbyt; 2645 test->port_stats[port].tbyt = tbyt; 2646 test->port_stats[port].rpkt = rpkt; 2647 test->port_stats[port].tpkt = tpkt; 2648 test->port_stats[port].raln = raln; 2649 test->port_stats[port].rdisc = rdisc; 2650 test->port_stats[port].dropped = dropped; 2651 } 2652 } 2653 2654 sal_usleep(interval * SECOND_USEC); 2655 2656 bcm_stat_sync(unit); 2657 2658 if (waitloop == 1) { 2659 cli_out("TRAFFIC: mode %s, %d byte frames, runtime ", 2660 traffic_mode_str[test->mode], test->pkt_size); 2661 traffic_show_runtime(interval); 2662 cli_out(" of "); 2663 traffic_show_runtime(test->runtime); 2664 cli_out("\n"); 2665 cli_out("TRAFFIC: press Ctrl-C to stop test\n"); 2666 } else { 2667 cli_out("TRAFFIC: running... (%d%% complete)\n", 2668 (runtime*100)/test->runtime); 2669 } 2670 runtime += interval; 2671 2672 /* Dump stats */ 2673 PBMP_ITER(test->ports, port) { 2674 portA = test->port_pair[port].portA; 2675 portB = test->port_pair[port].portB; 2676 if (port != portA) { 2677 continue; 2678 } 2679 bcm_stat_get(unit, port, snmpIfInOctets, &rbyt); 2680 bcm_stat_get(unit, port, snmpIfOutOctets, &tbyt); 2681 bcm_stat_get(unit, port, snmpDot1dTpPortOutFrames, &tpkt); 2682 bcm_stat_get(unit, port, snmpDot1dTpPortInFrames, &rpkt); 2683 bcm_stat_get(unit, port, snmpDot3StatsAlignmentErrors, &raln); 2684 bcm_stat_get(unit, port, snmpDot3StatsInternalMacReceiveErrors, 2685 &rdisc); 2686 bcm_stat_get(unit, port, snmpIfInDiscards, &dropped); 2687 2688 { 2689 int speed, duplex; 2690 uint32 dtpktl, dtbytl, drpktl, drbytl; 2691 uint32 dralnl, drdiscl, ddroppedl; 2692 2693 COMPILER_64_DELTA(drbyt, test->port_stats[port].rbyt, rbyt); 2694 COMPILER_64_DELTA(dtbyt, test->port_stats[port].tbyt, tbyt); 2695 COMPILER_64_DELTA(drpkt, test->port_stats[port].rpkt, rpkt); 2696 COMPILER_64_DELTA(dtpkt, test->port_stats[port].tpkt, tpkt); 2697 COMPILER_64_DELTA(draln, test->port_stats[port].raln, raln); 2698 COMPILER_64_DELTA(drdisc, test->port_stats[port].rdisc, 2699 rdisc); 2700 COMPILER_64_DELTA(ddropped, test->port_stats[port].dropped, 2701 dropped); 2702 2703 COMPILER_64_TO_32_LO(drbytl, drbyt); 2704 COMPILER_64_TO_32_LO(dtbytl, dtbyt); 2705 COMPILER_64_TO_32_LO(drpktl, drpkt); 2706 COMPILER_64_TO_32_LO(dtpktl, dtpkt); 2707 COMPILER_64_TO_32_LO(dralnl, draln); 2708 COMPILER_64_TO_32_LO(drdiscl, drdisc); 2709 COMPILER_64_TO_32_LO(ddroppedl, ddropped); 2710 2711 /* Ignore RX counters for BCM5670/BCM5675 */ 2712 if (((SOC_IS_XGS_FABRIC(unit)) || 2713 (SOC_IS_XGS3_SWITCH(unit))) && 2714 (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) && 2715 (test->mode == TRAFFIC_INTERNAL)) { 2716 drpktl = dtpktl; 2717 drbytl = dtbytl; 2718 } 2719 2720 2721 bcm_port_speed_get(unit, port, &speed); 2722 bcm_port_duplex_get(unit, port, &duplex); 2723 cli_out("Port %s (", SOC_PORT_NAME(unit, port)); 2724 if (speed >= 1000) { 2725 if (speed % 1000) { 2726 cli_out("%d.%dG %s", speed / 1000, 2727 (speed % 1000) / 100, 2728 duplex ? "FD" : "HD"); 2729 } else { 2730 cli_out("%dG %s", speed / 1000, 2731 duplex ? "FD" : "HD"); 2732 } 2733 } else if (speed == 0) { 2734 cli_out("-"); 2735 } else { 2736 cli_out("%dM %s", speed, duplex ? "FD" : "HD"); 2737 } 2738 cli_out("): %s\n", 2739 dralnl > 0 ? "ALN Error Detected" : 2740 drdiscl > 0 ? "Discard Error Detected" : 2741 ddroppedl > 0 ? "Dropped Error Detected" : 2742 (drpktl == 0 || dtpktl == 0 || 2743 dtbytl == 0 || drbytl == 0) ? 2744 "FAIL->NO TRAFFIC" :"PASSED"); 2745 2746 2747 cli_out("\tTX packets "); 2748 traffic_show_number(tpkt); 2749 cli_out(" +"); 2750 traffic_show_measured_number(dtpkt, interval); 2751 cli_out("/s TX Bytes "); 2752 traffic_show_number(tbyt); 2753 cli_out("B +"); 2754 traffic_show_measured_number(dtbyt, interval); 2755 cli_out("B/s ["); 2756 traffic_show_measured_rate(dtbyt, interval, TRUE); 2757 cli_out("b/s]"); 2758 cli_out("\n\tRX packets "); 2759 traffic_show_number(rpkt); 2760 cli_out(" +"); 2761 traffic_show_measured_number(drpkt, interval); 2762 cli_out("/s RX bytes "); 2763 traffic_show_number(rbyt); 2764 cli_out("B +"); 2765 traffic_show_measured_number(drbyt, interval); 2766 cli_out("B/s ["); 2767 traffic_show_measured_rate(drbyt, interval, TRUE); 2768 cli_out("b/s]"); 2769 cli_out("\n"); 2770 2771 notraffic = 0; 2772 2773 /* Zero packet rate increase indicates failure */ 2774 if (drpktl == 0 || dtpktl == 0 || dtbytl == 0 || drbytl == 0) { 2775 cli_out("ERROR: traffic stopped on ports %s, %s\n", 2776 SOC_PORT_NAME(unit, portA), 2777 SOC_PORT_NAME(unit, portB)); 2778 notraffic = 1; 2779 } 2780 2781 if (notraffic || test->showstats) { 2782 /* Give us a clue .. */ 2783 cli_out("PortA (%s) statistics:\n", 2784 SOC_PORT_NAME(unit, portA)); 2785 BCM_PBMP_CLEAR(portpbm); 2786 BCM_PBMP_PORT_ADD(portpbm, portA); 2787 if (SOC_IS_ESW(unit)) { 2788 #ifdef BCM_ESW_SUPPORT 2789 do_show_counters(unit, 2790 INVALIDr, 2791 portpbm, 2792 SHOW_CTR_CHANGED| 2793 SHOW_CTR_SAME| 2794 SHOW_CTR_NZ); 2795 #endif 2796 } else { 2797 } 2798 cli_out("PortB (%s) statistics:\n", 2799 SOC_PORT_NAME(unit, portB)); 2800 BCM_PBMP_CLEAR(portpbm); 2801 BCM_PBMP_PORT_ADD(portpbm, portB); 2802 if (SOC_IS_ESW(unit)) { 2803 #ifdef BCM_ESW_SUPPORT 2804 do_show_counters(unit, 2805 INVALIDr, 2806 portpbm, 2807 SHOW_CTR_CHANGED| 2808 SHOW_CTR_SAME| 2809 SHOW_CTR_NZ); 2810 #endif 2811 } else { 2812 } 2813 } 2814 2815 if (notraffic && test->stop_on_fail) { 2816 /* Restore original counter collection settings. */ 2817 #ifdef BCM_ESW_SUPPORT 2818 (void) soc_counter_start(unit, curr_counter_flags, 2819 curr_counter_interval, 2820 curr_counter_pbm); 2821 #endif 2822 passed = 0; 2823 SOC_PBMP_PORT_ADD(failedpbm,port); 2824 if (test->run2end == 0) { 2825 cli_out("Exiting test..\n"); 2826 return -1; 2827 } 2828 } 2829 } 2830 } 2831 } 2832 2833 #if defined(BCM_ENDURO_SUPPORT) 2834 if (SOC_IS_ENDURO(unit)) { 2835 /* Check MMU parity error registers */ 2836 SOC_IF_ERROR_RETURN(READ_MEM_FAIL_INT_STATr(unit, &val)); 2837 if (val) { 2838 cli_out("ERROR: MEM_FAIL_INT_STAT 0x%x\n", val); 2839 return -1; 2840 } 2841 /* coverity[result_independent_of_operands] */ 2842 SOC_IF_ERROR_RETURN(READ_CMIC_CHIP_PARITY_INTR_STATUSr(unit, &val)); 2843 if (val) { 2844 cli_out("ERROR: CMIC_CHIP_PARITY_INTR_STATUS 0x%x\n", val); 2845 return -1; 2846 } 2847 SOC_IF_ERROR_RETURN(READ_EP_INTR_STATUSr(unit, &val)); 2848 if (val) { 2849 cli_out("ERROR: EP_INTR_STATUS 0x%x\n", val); 2850 return -1; 2851 } 2852 SOC_IF_ERROR_RETURN(READ_ECC_SINGLE_BIT_ERRORSr(unit, &val)); 2853 if (val) { 2854 cli_out("ERROR: ECC_SINGLE_BIT_ERRORS 0x%x\n", val); 2855 return -1; 2856 } 2857 } 2858 #endif /* BCM_ENDURO_SUPPORT */ 2859 2860 if (passed) { 2861 cli_out("TEST passed: "); 2862 traffic_show_runtime(test->runtime); 2863 cli_out("\n"); 2864 } else { 2865 cli_out("TEST failed: \n"); 2866 PBMP_ITER(failedpbm, port) { 2867 cli_out("Port %s: FAIL->NO TRAFFIC.\n", 2868 SOC_PORT_NAME(unit, port)); 2869 } 2870 cli_out("\n"); 2871 } 2872 2873 #if defined(INCLUDE_MACSEC) 2874 macsec_stop_poll_task = 1; 2875 #endif 2876 2877 /* Restore original counter collection settings. */ 2878 2879 #ifdef BCM_ESW_SUPPORT 2880 if (soc_counter_start(unit, curr_counter_flags, 2881 curr_counter_interval, curr_counter_pbm) < 0) { 2882 cli_out("ERROR: Failed to restore counter collection\n"); 2883 return -1; 2884 } 2885 #endif 2886 2887 return 0; 2888 } 2889 2890 2891 /* 2892 * Run Traffic Test structure for the test CLI. 2893 */ 2894 STATIC int 2895 traffic_run_cli(int unit, args_t* args, void* pa) 2896 { 2897 return traffic_run_test(traf_test[unit]); 2898 } 2899 2900 2901 /* 2902 * Parse Test Parameters, create test structure 2903 */ 2904 int 2905 traffic_test_init(int unit, args_t *a, void **pa) 2906 { 2907 parse_table_t pt; 2908 int port = 0; 2909 int last_port = 0; 2910 int num_ports = 0; 2911 2912 SOC_PBMP_ASSIGN(dfl_portbitmap, PBMP_PORT_ALL(unit)); 2913 2914 PBMP_ITER(dfl_portbitmap, port) { 2915 last_port = port; 2916 num_ports++; 2917 } 2918 2919 if (num_ports % 2) { 2920 BCM_PBMP_PORT_REMOVE(dfl_portbitmap, last_port); 2921 } 2922 2923 parse_table_init(unit, &pt); 2924 parse_table_add(&pt, "Pattern", PQ_HEX|PQ_DFL, 0, 2925 &dfl_pattern,NULL); 2926 parse_table_add(&pt, "PatternIncrement",PQ_HEX|PQ_DFL, 0, 2927 &dfl_pattern_inc,NULL); 2928 parse_table_add(&pt, "TimeInSeconds", PQ_INT|PQ_DFL,0, 2929 &dfl_runtime, NULL); 2930 parse_table_add(&pt, "CounterPollInterval", PQ_INT|PQ_DFL,0, 2931 &dfl_poll_interval, NULL); 2932 parse_table_add(&pt, "RunMode", PQ_MULTI|PQ_DFL,0, 2933 &dfl_runmode, traffic_mode_str); 2934 parse_table_add(&pt, "SPeed", PQ_MULTI|PQ_DFL,0, 2935 &dfl_speed, traffic_speed_str); 2936 parse_table_add(&pt, "AutoNeg", PQ_BOOL|PQ_DFL, 0, 2937 &dfl_autoneg, NULL); 2938 parse_table_add(&pt, "Length", PQ_INT|PQ_DFL, 0, 2939 &dfl_size, NULL); 2940 parse_table_add(&pt, "Count", PQ_INT|PQ_DFL, 0, 2941 &dfl_count, NULL); 2942 parse_table_add(&pt, "PortBitMap", PQ_PBMP|PQ_DFL, 0, 2943 &dfl_portbitmap, NULL); 2944 parse_table_add(&pt, "CleanUp", PQ_BOOL|PQ_DFL, 0, 2945 &dfl_cleanup, NULL); 2946 parse_table_add(&pt, "ShowStats", PQ_BOOL|PQ_DFL, 0, 2947 &dfl_showstats, NULL); 2948 parse_table_add(&pt, "Run2End", PQ_BOOL|PQ_DFL, 0, 2949 &dfl_run2end, NULL); 2950 #if defined(INCLUDE_MACSEC) 2951 parse_table_add(&pt, "MacSEC", PQ_BOOL|PQ_DFL, 0, 2952 &dfl_macsec, NULL); 2953 #endif /* INCLUDE_MACSEC */ 2954 2955 if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) != 0) { 2956 test_error(unit, 2957 "%s: Invalid option: %s\n", 2958 ARG_CMD(a), 2959 ARG_CUR(a) ? ARG_CUR(a) : "*"); 2960 parse_arg_eq_done(&pt); 2961 return -1; 2962 } 2963 parse_arg_eq_done(&pt); 2964 2965 /* Alloc test, save H/W state, setup defaults */ 2966 traf_test[unit] = traffic_test_alloc(unit); 2967 2968 #if defined(BCM_ENDURO_SUPPORT) 2969 if (SOC_IS_ENDURO(unit)) { 2970 /* Disable parity interrupt */ 2971 /* coverity[result_independent_of_operands] */ 2972 SOC_IF_ERROR_RETURN(WRITE_CMIC_CHIP_PARITY_INTR_ENABLEr(unit, 0)); 2973 } 2974 #endif /* BCM_ENDURO_SUPPORT */ 2975 2976 return 0; 2977 } 2978 2979 int 2980 traffic_test(int unit, args_t *a, void *pa) 2981 { 2982 return traffic_run_cli(unit, a, traf_test[unit]); 2983 } 2984 2985 int 2986 traffic_test_done(int unit, void *pa) 2987 { 2988 #if defined(BCM_ENDURO_SUPPORT) 2989 uint32 val = 0; 2990 #endif 2991 int rv = 0; 2992 2993 if (traf_test[unit]->cleanup) { 2994 /* nothing to do right here */ 2995 } else { 2996 cli_out("WARNING: CleanupOnExit disabled: " 2997 "(H/W configuration still active for debug)\n"); 2998 cli_out("*** Zero EPC_LINK to stop traffic.\n"); 2999 cli_out("*** Reboot switch when done.\n"); 3000 } 3001 3002 rv = traffic_test_free(traf_test[unit]); 3003 sal_free(traf_test[unit]); 3004 3005 #if defined(BCM_ENDURO_SUPPORT) 3006 if (SOC_IS_ENDURO(unit)) { 3007 /* Check MMU outstanding packets/cells */ 3008 SOC_IF_ERROR_RETURN(READ_TOTAL_BUFFER_COUNT_PACKETr(unit, &val)); 3009 if (val) { 3010 cli_out("ERROR: TOTAL_BUFFER_COUNT_PACKET 0x%x\n", val); 3011 } 3012 SOC_IF_ERROR_RETURN(READ_TOTAL_BUFFER_COUNT_CELLr(unit, &val)); 3013 if (val) { 3014 cli_out("ERROR: TOTAL_BUFFER_COUNT_CELL 0x%x\n", val); 3015 } 3016 SOC_IF_ERROR_RETURN(READ_CFAPREADPOINTERr(unit, &val)); 3017 if (val != 0x1c) { 3018 cli_out("ERROR: CFAPREADPOINTER 0x%x\n", val); 3019 } 3020 SOC_IF_ERROR_RETURN(READ_PFAPREADPOINTERr(unit, &val)); 3021 if (val != 0x1c) { 3022 cli_out("ERROR: PFAPREADPOINTER 0x%x\n", val); 3023 } 3024 } 3025 #endif /* BCM_ENDURO_SUPPORT */ 3026 3027 return rv; 3028 }