lb_util.c (157152B)
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 * Utilities for Loopback Tests, Mark 2 8 */ 9 10 #include <shared/bsl.h> 11 12 #include <sal/core/boot.h> 13 #include <sal/appl/sal.h> 14 #include <shared/bsl.h> 15 #include <appl/diag/system.h> 16 #include <appl/diag/test.h> 17 18 19 #include <soc/debug.h> 20 #include <soc/hash.h> 21 #include <soc/higig.h> 22 #include <soc/drv.h> 23 #ifdef BCM_ESW_SUPPORT 24 #include <soc/firebolt.h> 25 #endif 26 #ifdef BCM_TRIUMPH3_SUPPORT 27 #include <soc/ism.h> 28 #endif /* BCM_TRIUMPH3_SUPPORT */ 29 #ifdef BCM_ESW_SUPPORT 30 #include <bcm_int/esw/mbcm.h> 31 #endif 32 33 34 #include <bcm/error.h> 35 #include <bcm/vlan.h> 36 #include <bcm/link.h> 37 #include <bcm/stg.h> 38 #include <bcm/tx.h> 39 #include <bcm/stat.h> 40 #include <bcm/mcast.h> 41 #include <bcm/stack.h> 42 #include <bcm/cosq.h> 43 #include <bcm/port.h> 44 45 #include <appl/test/loopback.h> 46 #include <appl/test/loopback2.h> 47 #include <appl/test/lb_util.h> 48 49 #ifdef PORTMOD_SUPPORT 50 #include <soc/portmod/portmod.h> 51 #include <soc/portmod/portmod_common.h> 52 #endif /* PORTMOD_SUPPORT */ 53 54 #ifdef BCM_TOMAHAWK3_SUPPORT 55 #include <soc/tomahawk3.h> 56 #endif 57 58 /* 59 * De-allocate any packet buffers in the RX packet pool. 60 * Then clear all that memory. 61 */ 62 #define CLEAR_RX_PKTS(lw, lp) \ 63 do { \ 64 int idxm; \ 65 for (idxm = 0; idxm < lp->ppt_end; idxm++) { \ 66 if (LB2_RX_PKT(lw, idxm)->alloc_ptr) { \ 67 bcm_rx_free((lw)->unit, LB2_RX_PKT(lw, idxm)->alloc_ptr); \ 68 } \ 69 } \ 70 sal_memset((lw)->rx_pkts, 0, (lp)->ppt_end * sizeof(bcm_pkt_t));\ 71 } while (0) 72 73 74 /* sal_mac_addr_t lbu_mac_default = {0x00, 0x00, 0x00, 0xde, 0xad, 0x00}; */ 75 sal_mac_addr_t lbu_mac_src = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; 76 sal_mac_addr_t lbu_mac_dst = {0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb}; 77 78 const char *lb2_parse_speed[] = { 79 LB2_SPEED_INIT_STR, 80 NULL 81 }; 82 83 84 STATIC uint32 lbu_saved_srcmod[SOC_MAX_NUM_DEVICES]; 85 STATIC uint32 lbu_saved_srcport[SOC_MAX_NUM_DEVICES]; 86 87 STATIC 88 char *lb2_crc_mode[] = { "CpuNone", "CpuAppend", "MacRegen", NULL }; 89 90 const char *lb2_parse_snake[] = { 91 "INCreasing", 92 "DECreasing", 93 "TWOways", 94 NULL 95 }; 96 97 const char *lb2_parse_lbmode[] = { 98 "MAC", 99 "PHY", 100 "EXTernal", 101 NULL 102 }; 103 104 static char *send_mech_list[] = { 105 "Single", "Array", NULL /* "LinkList" */ 106 }; 107 108 /* Forward declarations */ 109 STATIC void mac_params_init(int unit, int num_cos, loopback2_testdata_t *lp); 110 STATIC void phy_params_init(int unit, int num_cos, loopback2_testdata_t *lp); 111 STATIC void ext_params_init(int unit, int num_cos, loopback2_testdata_t *lp); 112 STATIC void snake_params_init(int unit, int num_cos, loopback2_testdata_t *lp); 113 114 STATIC uint32 115 lbu_timeout_usec(int unit) 116 { 117 uint32 defl; 118 119 /* These values are given in seconds, then converted to us below */ 120 if (SAL_BOOT_QUICKTURN) { 121 defl = LB2_PACKET_TIMEOUT_QT; 122 } else if (SAL_BOOT_PLISIM) { 123 defl = LB2_PACKET_TIMEOUT_PLI; 124 } else { 125 defl = LB2_PACKET_TIMEOUT; 126 } 127 128 return (soc_property_get(unit, spn_DIAG_LB_PACKET_TIMEOUT, defl) * 129 SECOND_USEC); 130 } 131 132 /* 133 * Loopback work structure 134 */ 135 136 void 137 lbu_pkt_param_add(int unit, parse_table_t *pt, loopback2_testdata_t *lp) 138 /* 139 * Returns: 0 for success, -1 for failed. 140 */ 141 { 142 if (lp->test_type == LB2_TT_EXT) { 143 parse_table_add(pt, "TxPortBitMap",PQ_PBMP|PQ_DFL, 0, 144 &lp->pbm_tx, NULL); 145 parse_table_add(pt, "DestinationIncrement",PQ_INT|PQ_DFL, 0, 146 &lp->dst_inc, NULL); 147 } else { 148 parse_table_add(pt, "PortBitMap", PQ_PBMP | PQ_DFL, 0, 149 &lp->pbm, NULL); 150 } 151 if ((lp->test_type == LB2_TT_MAC) || (lp->test_type == LB2_TT_PHY)) { 152 if (!SOC_IS_XGS12_FABRIC(unit)){ 153 parse_table_add(pt, "UntagBitMap", PQ_PBMP|PQ_DFL, 0, 154 &lp->ubm, NULL); 155 } 156 } 157 158 parse_table_add(pt, "HGDestMOD", PQ_DFL|PQ_INT, 0, 159 &lp->d_mod, NULL); 160 if (lp->test_type == LB2_TT_SNAKE) { 161 parse_table_add(pt, "HGDestMODInc", PQ_DFL|PQ_INT, 0, 162 &lp->d_mod_inc, NULL); 163 } 164 parse_table_add(pt, "HGDestPORT", PQ_DFL|PQ_INT, 0, 165 &lp->d_port, NULL); 166 parse_table_add(pt, "OpCode", PQ_DFL|PQ_INT, 0, 167 &lp->opcode, NULL); 168 169 parse_table_add(pt, "SourceMac", PQ_DFL|PQ_MAC, 0, 170 &lp->mac_src, NULL); 171 parse_table_add(pt, "SourceMacInc",PQ_DFL|PQ_INT, 0, 172 &lp->mac_src_inc,NULL); 173 parse_table_add(pt, "DestMac", PQ_DFL|PQ_MAC, 0, 174 &lp->mac_dst, NULL); 175 parse_table_add(pt, "DestMacInc", PQ_DFL|PQ_INT, 0, 176 &lp->mac_dst_inc,NULL); 177 parse_table_add(pt, "Pattern", PQ_HEX | PQ_DFL, 0, &lp->pattern, NULL); 178 parse_table_add(pt, "PatternIncrement", PQ_HEX | PQ_DFL, 0, 179 &lp->pattern_inc, NULL); 180 parse_table_add(pt, "VLantag", PQ_INT|PQ_DFL, 0, 181 &lp->vlan, NULL); 182 parse_table_add(pt, "LengthStart", PQ_INT | PQ_DFL, 0, 183 &lp->len_start, NULL); 184 parse_table_add(pt, "LengthEnd", PQ_INT|PQ_DFL, 0, 185 &lp->len_end, NULL); 186 parse_table_add(pt, "LengthIncrement",PQ_INT|PQ_DFL, 0, 187 &lp->len_inc, NULL); 188 parse_table_add(pt, "PktsPerTrialStart",PQ_INT|PQ_DFL, 0, 189 &lp->ppt_start, NULL); 190 parse_table_add(pt, "PktsPerTrialEnd",PQ_INT|PQ_DFL, 0, 191 &lp->ppt_end, NULL); 192 parse_table_add(pt, "PktsPerTrialInc",PQ_INT|PQ_DFL, 0, 193 &lp->ppt_inc, NULL); 194 parse_table_add(pt, "SENDMethod", PQ_DFL|PQ_MULTI, 0, 195 &lp->send_mech, send_mech_list); 196 parse_table_add(pt, "Count", PQ_INT | PQ_DFL, 0, &lp->iterations, NULL); 197 parse_table_add(pt, "CRC", PQ_MULTI|PQ_DFL, 0, 198 &lp->crc_mode, lb2_crc_mode); 199 parse_table_add(pt, "PortSelectMode", PQ_INT|PQ_DFL, 0, 200 &lp->port_select_mode, NULL); 201 } 202 203 void 204 lbu_port_param_add(int unit, parse_table_t *pt, loopback2_testdata_t *lp) 205 { 206 parse_table_add(pt, "Speed", PQ_MULTI|PQ_DFL,0, 207 &lp->speed, lb2_parse_speed); 208 parse_table_add(pt, "AutoNeg", PQ_BOOL|PQ_DFL, 0, 209 &lp->autoneg, NULL); 210 if (lp->test_type == LB2_TT_SNAKE) { 211 parse_table_add(pt, "LoopbackMode", PQ_MULTI | PQ_DFL, 0, 212 &lp->loopback, lb2_parse_lbmode); 213 } 214 } 215 216 void 217 lbu_other_param_add(int unit, parse_table_t *pt, loopback2_testdata_t *lp) 218 { 219 parse_table_add(pt, "COSStart", PQ_INT|PQ_DFL, 0, 220 &lp->cos_start,NULL); 221 parse_table_add(pt, "COSEnd", PQ_INT|PQ_DFL, 0, 222 &lp->cos_end,NULL); 223 parse_table_add(pt, "CheckData", PQ_BOOL|PQ_DFL, 0, 224 &lp->check_data,NULL); 225 parse_table_add(pt, "CheckCrc", PQ_BOOL|PQ_DFL, 0, 226 &lp->check_crc,NULL); 227 parse_table_add(pt, "InjectPackets", PQ_BOOL | PQ_DFL, 0, 228 &lp->inject, NULL); 229 if (lp->test_type == LB2_TT_SNAKE) { 230 parse_table_add(pt, "Duration", PQ_INT | PQ_DFL, 0, 231 &lp->duration, NULL); 232 parse_table_add(pt, "Interval", PQ_INT | PQ_DFL, 0, 233 &lp->interval, NULL); 234 parse_table_add(pt, "SnakePath", PQ_MULTI | PQ_DFL, 0, 235 &lp->snake_way, lb2_parse_snake); 236 #ifdef BCM_TOMAHAWK_SUPPORT 237 parse_table_add(pt, "LineRate", PQ_BOOL | PQ_DFL, 0, 238 &lp->line_rate, NULL); 239 #endif 240 } 241 } 242 243 bcm_rx_t 244 lbu_rx_callback(int unit, bcm_pkt_t *info, void *cookie) 245 /* 246 * Function: lbu_rx_callback 247 * Purpose: This is the callback handler for the packets forwarded to 248 * the CMIC. 249 * Parameters: 250 * unit - device code. 251 * info - received packet description structure. 252 * cookie - lw - pointer to lb work. 253 * Returns: 0 - success, -1 failed. 254 * Notes: 255 * Called in INTERRUPT CONTEXT 256 */ 257 { 258 loopback2_test_t *lw = (loopback2_test_t *)cookie; 259 int num_pkts = lw->tx_ppt; 260 bcm_pkt_t *local_info; 261 262 if (lw->expect_pkts) { 263 /* Queue the packet */ 264 /* Copy pkt into array at location rx_pkt_cnt */ 265 local_info = LB2_RX_CUR_PKT(lw); 266 sal_memcpy(local_info, info, sizeof(bcm_pkt_t)); 267 /* Fix internal packet pointer */ 268 local_info->pkt_data = &local_info->_pkt_data; 269 if (++lw->rx_pkt_cnt >= num_pkts) { 270 lw->expect_pkts = FALSE; 271 /* Wake up thread to check things out */ 272 if (!lw->sema_woke) { 273 lw->sema_woke = TRUE; 274 if (sal_sem_give(lw->sema)) { 275 cli_out("Warning: LB RX done give failed\n"); 276 } 277 } 278 } 279 return BCM_RX_HANDLED_OWNED; 280 } 281 282 /* Not accepting packets; let rx discard */ 283 return BCM_RX_NOT_HANDLED; 284 285 } 286 287 int 288 lbu_port_monitor_task(int unit, bcm_rx_cb_f callback, void *cookie) 289 { 290 int rv = BCM_E_NONE; 291 bcm_rx_cfg_t rx_cfg; 292 293 #ifdef INCLUDE_RCPU 294 295 if ((soc_property_get_str(unit, spn_RCPU_PORT) == NULL) && (BCM_RX_INIT_DONE(unit))) { 296 cli_out("lbu monitor: RX already running (u=%d)\n", unit); 297 return BCM_E_INIT; 298 } 299 #else 300 if (BCM_RX_INIT_DONE(unit)) { 301 cli_out("lbu monitor: RX already running (u=%d)\n", unit); 302 return BCM_E_INIT; 303 } 304 #endif /* INCLUDE_RCPU */ 305 306 /* Get current configuration */ 307 bcm_rx_cfg_init(unit); /* Re-init in case in bad state */ 308 bcm_rx_cfg_get(unit, &rx_cfg); 309 rx_cfg.global_pps = BCM_RX_RATE_NOLIMIT; 310 rx_cfg.chan_cfg[BCM_RX_CHAN_DFLT].rate_pps = BCM_RX_RATE_NOLIMIT; 311 rv = bcm_rx_start(unit, &rx_cfg); 312 #ifdef INCLUDE_RCPU 313 #else 314 if (BCM_E_NONE != rv) { 315 cli_out("lbu_port_monitor_task:" 316 "rx_start failed: %s\n", bcm_errmsg(rv)); 317 return rv; 318 } 319 #endif /* INCLUDE_RCPU */ 320 321 /* Allow BCM Rx thread to prepare DMA buffers */ 322 sal_usleep(500000); 323 324 rv = bcm_rx_register(unit, "loopback test", callback, 325 BCM_RX_PRIO_MAX, cookie, 326 BCM_RCO_F_ALL_COS); 327 if (BCM_E_NONE != rv) { 328 cli_out("lbu_port_monitor_task:" 329 "rx_register failed: %s\n", bcm_errmsg(rv)); 330 return rv; 331 } 332 333 return BCM_E_NONE; 334 } 335 336 STATIC int 337 lbu_packet_compare(loopback2_test_t *lw, bcm_pkt_t *tx_info, 338 bcm_pkt_t *rx_info) 339 { 340 loopback2_testdata_t *lp = lw->cur_params; 341 int unit = lw->unit; 342 int i; 343 int rv = 0; 344 int tx_compare_len, crc_length = 0; 345 uint8 *tx_data, *rx_data; 346 347 tx_data = BCM_PKT_IEEE(tx_info); 348 rx_data = BCM_PKT_IEEE(rx_info); 349 350 #ifdef BCM_XGS_SUPPORT 351 /* Inspect HIGIG/XGS header if received from HG port */ 352 if (SOC_IS_XGS12_FABRIC(unit)) { 353 soc_higig_hdr_t *tx_hdr = (soc_higig_hdr_t*)tx_info->_higig; 354 soc_higig_hdr_t *rx_hdr = (soc_higig_hdr_t*)rx_info->_higig; 355 356 if (soc_higig_field_get(unit, rx_hdr, HG_start) != 357 SOC_HIGIG_START) { 358 cli_out("ERROR: HIGIG START not detected (rx=%x)\n", 359 soc_higig_field_get(unit, rx_hdr, HG_start)); 360 rv = -1; 361 } 362 363 if (soc_higig_field_get(unit, rx_hdr, HG_hgi) != 364 SOC_HIGIG_HGI) { 365 cli_out("ERROR: HIGIG identifier not detected (rx=%x)\n", 366 soc_higig_field_get(unit, rx_hdr, HG_hgi)); 367 rv = -1; 368 } 369 370 if (soc_higig_field_get(unit, tx_hdr, HG_vlan_pri) != 371 soc_higig_field_get(unit, rx_hdr, HG_vlan_pri)) { 372 cli_out("ERROR: HIGIG VLAN priority miscompare (tx=%x,rx=%x)\n", 373 soc_higig_field_get(unit, tx_hdr, HG_vlan_pri), 374 soc_higig_field_get(unit, rx_hdr, HG_vlan_pri)); 375 rv = -1; 376 } 377 378 if (soc_higig_field_get(unit, tx_hdr, HG_vlan_cfi) != 379 soc_higig_field_get(unit, rx_hdr, HG_vlan_cfi)) { 380 cli_out("ERROR: HIGIG VLAN cfi miscompare (tx=%x,rx=%x)\n", 381 soc_higig_field_get(unit, tx_hdr, HG_vlan_cfi), 382 soc_higig_field_get(unit, rx_hdr, HG_vlan_cfi)); 383 rv = -1; 384 } 385 386 if (soc_higig_field_get(unit, tx_hdr, HG_vlan_id) != 387 soc_higig_field_get(unit, rx_hdr, HG_vlan_id)) { 388 cli_out("ERROR: HIGIG VLAN id miscompare (tx=%x,rx=%x)\n", 389 soc_higig_field_get(unit, tx_hdr, HG_vlan_id), 390 soc_higig_field_get(unit, rx_hdr, HG_vlan_id)); 391 rv = -1; 392 } 393 394 if (soc_higig_field_get(unit, tx_hdr, HG_opcode) != 395 soc_higig_field_get(unit, rx_hdr, HG_opcode)) { 396 cli_out("ERROR: HIGIG opcode miscompare (tx=%x,rx=%x)\n", 397 soc_higig_field_get(unit, tx_hdr, HG_opcode), 398 soc_higig_field_get(unit, rx_hdr, HG_opcode)); 399 rv = -1; 400 } 401 402 /* What about remapping the COS? */ 403 if (soc_higig_field_get(unit, tx_hdr, HG_cos) != 404 soc_higig_field_get(unit, rx_hdr, HG_cos)) { 405 cli_out("ERROR: HIGIG cos miscompare (tx=%x,rx=%x)\n", 406 soc_higig_field_get(unit, tx_hdr, HG_cos), 407 soc_higig_field_get(unit, rx_hdr, HG_cos)); 408 rv = -1; 409 } 410 411 412 } 413 #endif /* BCM_XGS_SUPPORT */ 414 415 /* Check source and destination MAC address */ 416 417 if (ENET_CMP_MACADDR(BCM_PKT_DMAC(tx_info), BCM_PKT_DMAC(rx_info)) || 418 ENET_CMP_MACADDR(BCM_PKT_DMAC(tx_info) + 6, 419 BCM_PKT_DMAC(rx_info) + 6)) { 420 char src_mac[SAL_MACADDR_STR_LEN], 421 dst_mac[SAL_MACADDR_STR_LEN], 422 exp_src_mac[SAL_MACADDR_STR_LEN], 423 exp_dst_mac[SAL_MACADDR_STR_LEN]; 424 format_macaddr(exp_src_mac, BCM_PKT_DMAC(tx_info) + 6); 425 format_macaddr(exp_dst_mac, BCM_PKT_DMAC(tx_info)); 426 format_macaddr(src_mac, BCM_PKT_DMAC(rx_info) + 6); 427 format_macaddr(dst_mac, BCM_PKT_DMAC(rx_info)); 428 cli_out("ERROR: MAC address miscompare:\n" 429 "\tExpected src=%s dst=%s\n\tReceived src=%s dst=%s\n", 430 exp_src_mac, exp_dst_mac, src_mac, dst_mac); 431 432 rv = -1; 433 } 434 435 #ifdef BCM_ESW_SUPPORT 436 crc_length = ((lp->crc_mode == LB2_CRC_MODE_CPU_APPEND) ? 4 : 0); 437 #endif /* BCM_ESW_SUPPORT */ 438 439 /* Verify lengths, and if they match, verify payload */ 440 tx_compare_len = tx_info->_pkt_data.len; 441 if (lp->crc_mode != LB2_CRC_MODE_CPU_APPEND) { 442 tx_compare_len -= 4; 443 } 444 445 if (rx_info->pkt_len != (tx_info->_pkt_data.len + crc_length)) { 446 #ifdef BCM_ESW_SUPPORT 447 if (SOC_IS_ESW(unit)) { 448 soc_pci_analyzer_trigger(unit); 449 } 450 #endif /* BCM_ESW_SUPPORT */ 451 cli_out("ERROR: Length miscompare: TX(%d) RX(%d)\n", 452 tx_info->_pkt_data.len, rx_info->pkt_len); 453 rv = -1; 454 } else if ((i = packet_compare(BCM_PKT_VLAN_PTR(rx_info), 455 BCM_PKT_VLAN_PTR(tx_info), 456 4)) >= 0) { 457 cli_out("ERROR: VLAN tag miscompare: offset 0x%x\n", i + 12); 458 rv = -1; 459 } else if ((i = packet_compare(rx_data + 16, 460 tx_data + 16, 461 4)) >= 0) { 462 cli_out("ERROR: Sequence # miscompare: offset 0x%x\n" 463 "\tExpected 0x%08x, Received 0x%08x\n", 16, 464 packet_load(tx_data + 16, 4), 465 packet_load(rx_data + 16, 4)); 466 rv = -1; 467 } else if ((i = packet_compare(rx_data + 20, 468 tx_data + 20, 469 tx_compare_len - 20)) >= 0) { 470 cli_out("ERROR: Payload miscompare: offset 0x%x\n", i + 20); 471 rv = -1; 472 } 473 474 if (lp->check_crc) { 475 uint32 calc_crc = 0, rx_crc; 476 if (lp->vlan) { 477 if (rx_info->pkt_len > 0) { 478 /* Skip Vlan Tag for CRC calculation */ 479 uint8 *rx_data_crc; 480 rx_data_crc = sal_alloc(rx_info->pkt_len, "rx_data_crc"); 481 sal_memset(rx_data_crc, 0, rx_info->pkt_len); 482 sal_memcpy(rx_data_crc, rx_data, 12); 483 sal_memcpy(rx_data_crc + 12, rx_data + 16, 484 rx_info->pkt_len - 16); 485 calc_crc = ~_shr_crc32(~0, rx_data_crc, rx_info->pkt_len - 8); 486 sal_free(rx_data_crc); 487 } 488 } else { 489 calc_crc = ~_shr_crc32(~0, rx_data, rx_info->pkt_len - 4); 490 } 491 rx_crc = packet_load(rx_data + rx_info->pkt_len - 4, 4); 492 493 if (calc_crc != rx_crc) { 494 cli_out("ERROR: CRC miscompare: calc=0x%08x rx=0x%08x\n", 495 calc_crc, rx_crc); 496 497 rv = -1; 498 } 499 } 500 501 if (rv) { 502 /* On error, dump tx/rx packets, and call test_error once */ 503 504 cli_out("TX packet: len=%d\n", tx_info->_pkt_data.len); 505 #ifdef BCM_ESW_SUPPORT 506 soc_dma_dump_pkt(unit, " ", tx_data, tx_info->_pkt_data.len, TRUE); 507 cli_out("RX packet: len=%d\n", rx_info->pkt_len); 508 soc_dma_dump_pkt(unit, " ", rx_data, rx_info->pkt_len, TRUE); 509 #endif 510 test_error(unit, 511 "ERROR Found when verifying received packet\n"); 512 } 513 514 return(rv); 515 } 516 517 STATIC int 518 lbu_snake_pkt_match(loopback2_test_t *lw, bcm_pkt_t *rx_info, int *match_idx) 519 /* 520 * Function: lb_isnake_pkt_match 521 * Purpose: Search for tx packet matching rx packet. 522 * Parameters: lw - pointer to lb work. 523 * rx_info - pointer to rx packet info 524 * match_idx - return index for tx matching packet 525 * Returns: 0 for match, -1 for no match, -2 for duplicate match. 526 */ 527 { 528 int tx_idx; 529 bcm_pkt_t *compare_info; 530 531 for (tx_idx = 0; tx_idx < lw->tx_ppt; tx_idx++) { 532 533 compare_info = lw->tx_pkts[tx_idx]; 534 535 if (ENET_CMP_MACADDR(BCM_PKT_DMAC(compare_info), 536 BCM_PKT_DMAC(rx_info)) || 537 ENET_CMP_MACADDR(BCM_PKT_DMAC(compare_info) + 6, 538 BCM_PKT_DMAC(rx_info) + 6)) { 539 /* Wrong macs */ 540 continue; 541 } 542 543 if (BCM_PKT_DMAC(compare_info)[LB2_ID_POS] != 544 BCM_PKT_DMAC(rx_info)[LB2_ID_POS]) { 545 /* Wrong SW identifying tag */ 546 continue; 547 } 548 549 *match_idx = tx_idx; 550 551 if (lw->tx_pkt_match[tx_idx]) { 552 /* Already matched this packet, duplicate arrival */ 553 return -2; 554 } 555 556 lw->tx_pkt_match[tx_idx] = TRUE; 557 558 return 0; 559 } 560 561 return -1; 562 } 563 564 int 565 lbu_snake_analysis(loopback2_test_t *lw) 566 { 567 int unit = lw->unit; 568 int ix, ev = 0; 569 bcm_pkt_t *tx_info, *rx_info; 570 int match_idx; 571 572 for (ix = 0; ix < lw->rx_pkt_cnt; ix++) { 573 rx_info = LB2_RX_PKT(lw, ix); 574 match_idx = -1; 575 if ((ev = lbu_snake_pkt_match(lw, rx_info, &match_idx)) < 0) { 576 if (match_idx >=0) { 577 tx_info = lw->tx_pkts[match_idx]; 578 cli_out("TX packet: len=%d\n", tx_info->_pkt_data.len); 579 580 #ifdef BCM_ESW_SUPPORT 581 soc_dma_dump_pkt(unit, " ", BCM_PKT_IEEE(tx_info), 582 tx_info->_pkt_data.len, TRUE); 583 #endif 584 } else { 585 cli_out("No TX match\n"); 586 } 587 588 if (ev == -2) { 589 test_error(unit, 590 "Duplicate packet from port %s\n", 591 SOC_PORT_NAME(unit, rx_info->rx_port)); 592 } else { 593 test_error(unit, 594 "Unrecognized packet from port %s\n", 595 SOC_PORT_NAME(unit, rx_info->rx_port)); 596 } 597 598 return -1; 599 } 600 601 tx_info = lw->tx_pkts[match_idx]; 602 603 if (lbu_packet_compare(lw, tx_info, rx_info) < 0) { 604 return -1; 605 } 606 } 607 return 0; 608 } 609 610 STATIC int 611 lbu_set_l2_addr(int unit, bcm_port_t p, bcm_vlan_t vlan, 612 bcm_l2_addr_t *l2_addr, sal_mac_addr_t mac_addr) 613 /* 614 * Function: lbu_set_l2_addr 615 * Purpose: Set an L2 entry 616 * Parameters: unit - SOC unit # 617 * p - port to set address for. 618 * vlan - vlan tag to use in ARL entry. 619 * l2_addr - pointer to arl entry to use. 620 * Returns: 0 - success, -1 failed. 621 */ 622 { 623 int rv; 624 625 if ((rv = bcm_l2_addr_delete(unit, mac_addr, vlan)) < 0) { 626 if (rv != BCM_E_NOT_FOUND) { 627 cli_out("bcm_l2_addr_delete FAILED\n"); 628 return rv; 629 } /* else, non-existent entry */ 630 } 631 632 sal_memcpy(l2_addr->mac, mac_addr, sizeof(sal_mac_addr_t)); 633 l2_addr->vid = vlan; 634 l2_addr->flags = BCM_L2_STATIC; 635 l2_addr->port = p; 636 return(bcm_l2_addr_add(unit, l2_addr)); 637 } 638 639 int 640 lbu_setup_arl_cmic(loopback2_test_t *lw) 641 /* 642 * Function: lbu_setup_arl 643 * Purpose: Setup an ARL entry for the specified port 644 * Parameters: unit - unit # 645 * dst_port - port to which packet is sent 646 * Returns: 0 - success 647 * -1 - failed. 648 * Notes: Only the destination port CBIT is returned, as only 649 * it is required for the test. 650 */ 651 { 652 loopback2_testdata_t *lp = lw->cur_params; 653 int unit = lw->unit; 654 int rv = 0; 655 sal_mac_addr_t cur_mac; 656 bcm_l2_addr_t *l2_addr = &lw->l2_addr_scratch; 657 int pkt_cur; 658 #ifdef BCM_TRIUMPH_SUPPORT 659 int ext_index_max = -1; 660 #endif /* BCM_TRIUMPH_SUPPORT */ 661 662 ENET_SET_MACADDR(cur_mac, lw->base_mac_dst); 663 bcm_l2_addr_t_init(l2_addr, cur_mac, 0); 664 665 /* Get the module ID for this unit */ 666 if (SOC_IS_XGS_SWITCH(unit)) { 667 if ((rv = bcm_stk_my_modid_get(unit, &l2_addr->modid)) < 0) { 668 test_error(unit, 669 "Modid retrieval failed: %s\n", 670 soc_errmsg(rv)); 671 return(-1); 672 } 673 } 674 675 #ifdef BCM_TRIUMPH_SUPPORT 676 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 677 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 678 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 679 } 680 #endif /* BCM_TRIUMPH_SUPPORT */ 681 for (pkt_cur = 0; pkt_cur < lp->ppt_end; pkt_cur++) { 682 rv |= lbu_set_l2_addr(unit, CMIC_PORT(unit), lp->vlan, 683 l2_addr, cur_mac); 684 increment_macaddr(cur_mac, lp->mac_dst_inc); 685 } 686 #ifdef BCM_TRIUMPH_SUPPORT 687 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 688 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 689 } 690 #endif /* BCM_TRIUMPH_SUPPORT */ 691 692 if (rv) { 693 test_error(unit, 694 "Failed to set up L2 address: port %s\n", 695 SOC_PORT_NAME(unit, CMIC_PORT(unit))); 696 return(-1); 697 } else if (l2_addr->port != CMIC_PORT(unit)) { 698 test_error(unit, 699 "Port %s: invalid destination arl port: %s\n", 700 SOC_PORT_NAME(unit, CMIC_PORT(unit)), 701 SOC_PORT_NAME(unit, l2_addr->port)); 702 return(-1); 703 } 704 705 return 0; 706 } 707 708 #ifdef BCM_HERCULES_SUPPORT 709 STATIC int 710 lbu_connect_herc_ports(int unit, lb2s_port_connect_t *pc_info, 711 int connect) 712 { 713 pbmp_t uc; 714 uint32 ucdata; 715 int blk; 716 717 /* Configure UC table for packet forwarding */ 718 SOC_PBMP_CLEAR(uc); 719 blk = SOC_PORT_BLOCK(unit, pc_info->this_port); 720 if (connect) { 721 SOC_PBMP_PORT_ADD(uc, pc_info->to_port); 722 ucdata = SOC_PBMP_WORD_GET(uc, 0); 723 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MEM_UCm, blk, 724 pc_info->src_modid, &ucdata)); 725 } else { 726 ucdata = SOC_PBMP_WORD_GET(uc, 0); 727 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MEM_UCm, blk, 728 pc_info->src_modid, &ucdata)); 729 } 730 return 0; 731 } 732 #endif 733 734 STATIC int 735 lbu_connect_ether_ports(int unit, lb2s_port_connect_t *pc_info, 736 int connect) 737 { 738 int rv; 739 #ifdef BCM_TRIUMPH_SUPPORT 740 int ext_index_max = -1; 741 #endif /* BCM_TRIUMPH_SUPPORT */ 742 743 if (MAC_IS_MCAST(pc_info->dst_mac)) { 744 if (connect) { 745 bcm_mcast_addr_t l2mc_addr; 746 sal_memset(&l2mc_addr, 0, sizeof (bcm_mcast_addr_t)); 747 ENET_SET_MACADDR(l2mc_addr.mac, pc_info->dst_mac); 748 l2mc_addr.vid = pc_info->added_vlan; 749 SOC_PBMP_CLEAR(l2mc_addr.pbmp); 750 SOC_PBMP_PORT_ADD(l2mc_addr.pbmp, pc_info->this_port); 751 SOC_PBMP_PORT_ADD(l2mc_addr.pbmp, pc_info->to_port); 752 SOC_PBMP_ASSIGN(l2mc_addr.ubmp, l2mc_addr.pbmp); 753 BCM_IF_ERROR_RETURN(bcm_mcast_addr_add(unit, &l2mc_addr)); 754 } else { 755 BCM_IF_ERROR_RETURN(bcm_mcast_addr_remove(unit, pc_info->dst_mac, 756 pc_info->added_vlan)); 757 } 758 } else { 759 if (connect) { 760 bcm_l2_addr_t l2_addr; 761 bcm_l2_addr_t_init(&l2_addr, 762 pc_info->dst_mac, pc_info->added_vlan); 763 if (NUM_MODID(unit) == 3 && 764 pc_info->to_port % (SOC_PORT_ADDR_MAX(unit) + 1) > 63) { 765 l2_addr.port = 766 (pc_info->to_port % (SOC_PORT_ADDR_MAX(unit) + 1)) - 64; 767 l2_addr.modid = pc_info->dst_modid + 2; 768 } else if (NUM_MODID(unit) >= 2 && 769 pc_info->to_port % (SOC_PORT_ADDR_MAX(unit) + 1) > 31) { 770 l2_addr.port = 771 (pc_info->to_port % (SOC_PORT_ADDR_MAX(unit) + 1)) - 32; 772 l2_addr.modid = pc_info->dst_modid + 1; 773 } else { 774 l2_addr.port = 775 pc_info->to_port % (SOC_PORT_ADDR_MAX(unit) + 1); 776 l2_addr.modid = pc_info->dst_modid; 777 } 778 #ifdef BCM_TRIUMPH_SUPPORT 779 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 780 ext_index_max = 781 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 782 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 783 } 784 #endif /* BCM_TRIUMPH_SUPPORT */ 785 rv = bcm_l2_addr_add(unit, &l2_addr); 786 #ifdef BCM_TRIUMPH_SUPPORT 787 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 788 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = 789 ext_index_max; 790 } 791 #endif /* BCM_TRIUMPH_SUPPORT */ 792 if (BCM_FAILURE(rv)) { 793 return rv; 794 } 795 796 if ((pc_info->this_port == pc_info->to_port) && 797 (pc_info->dst_modid == pc_info->src_modid)) { 798 BCM_IF_ERROR_NOT_UNAVAIL_RETURN( 799 bcm_port_control_set(unit, pc_info->this_port, 800 bcmPortControlBridge, 1)); 801 } 802 } else { 803 #ifdef BCM_TRIUMPH_SUPPORT 804 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 805 ext_index_max = 806 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 807 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 808 } 809 #endif /* BCM_TRIUMPH_SUPPORT */ 810 rv = bcm_l2_addr_delete(unit, pc_info->dst_mac, 811 pc_info->added_vlan); 812 #ifdef BCM_TRIUMPH_SUPPORT 813 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 814 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = 815 ext_index_max; 816 } 817 #endif /* BCM_TRIUMPH_SUPPORT */ 818 if (BCM_FAILURE(rv)) { 819 if (rv != BCM_E_NOT_FOUND) { 820 return rv; 821 } /* else, non-existent entry */ 822 } 823 824 /* Disable Port bridging if src and dest ports are same */ 825 if ((pc_info->this_port == pc_info->to_port) && 826 (pc_info->dst_modid == pc_info->src_modid)) { 827 BCM_IF_ERROR_NOT_UNAVAIL_RETURN( 828 bcm_port_control_set(unit, pc_info->this_port, 829 bcmPortControlBridge, 0)); 830 } 831 } 832 } 833 return 0; 834 } 835 836 STATIC int 837 lbu_set_modport(int unit, bcm_port_t src_port, int dst_port, int modid) 838 { 839 /* 840 * A ghastly construct. Select correct modid field, 841 * and modify dest port into field. 842 */ 843 844 #ifdef BCM_FIREBOLT_SUPPORT 845 if (SOC_IS_FB_FX_HX(unit) || SOC_IS_TR_VL(unit)) { 846 return 0; 847 } 848 if (SOC_IS_HBX(unit)) { 849 int rv; 850 modport_map_entry_t uc; 851 int idx = (src_port * (SOC_MODID_MAX(unit) + 1)) + modid; 852 soc_mem_lock(unit, MODPORT_MAPm); 853 rv = READ_MODPORT_MAPm(unit, MEM_BLOCK_ANY, idx, &uc); 854 if (SOC_SUCCESS(rv)) { 855 /* Use MODPORT_MAP for forwarding packets for both HG and XE ports. 856 */ 857 soc_MODPORT_MAPm_field32_set(unit, &uc, HIGIG_PORT_BITMAPf, 858 1 << dst_port); 859 rv = WRITE_MODPORT_MAPm(unit, MEM_BLOCK_ALL, idx, &uc); 860 } 861 soc_mem_unlock(unit, MODPORT_MAPm); 862 return rv; 863 } 864 #endif /* BCM_FIREBOLT_SUPPORT */ 865 return 0; 866 } 867 868 STATIC int 869 lbu_connect_ether_to_hg_port(int unit, lb2s_port_connect_t *pc_info, 870 int connect) 871 { 872 bcm_l2_addr_t l2_addr; 873 874 if (connect) { 875 bcm_l2_addr_t_init(&l2_addr, pc_info->dst_mac, pc_info->added_vlan); 876 l2_addr.modid = pc_info->dst_modid; 877 l2_addr.port = pc_info->to_port % (SOC_PORT_ADDR_MAX(unit) + 1); 878 BCM_IF_ERROR_RETURN(bcm_l2_addr_add(unit, &l2_addr)); 879 SOC_IF_ERROR_RETURN(lbu_set_modport(unit, pc_info->this_port, 880 pc_info->to_port, pc_info->dst_modid)); 881 } else { 882 int rv; 883 884 if ((rv = bcm_l2_addr_delete(unit, pc_info->dst_mac, 885 pc_info->added_vlan)) < 0) { 886 if (rv != BCM_E_NOT_FOUND) { 887 return rv; 888 } /* else, non-existent entry */ 889 } 890 891 } 892 return 0; 893 } 894 895 STATIC int 896 lbu_connect_hg_to_ether_port(int unit, lb2s_port_connect_t *pc_info, 897 int connect) 898 { 899 if (connect) { 900 SOC_IF_ERROR_RETURN(lbu_set_modport(unit, pc_info->this_port, 901 pc_info->to_port, pc_info->src_modid)); 902 } else { 903 904 } 905 return 0; 906 } 907 908 int 909 lbu_connect_ports(int unit, lb2s_port_connect_t *pc_info, 910 int connect) 911 { 912 int rv; 913 914 if (!pc_info->valid_info) { 915 /* Nothing to do */ 916 return 0; 917 } 918 919 if (connect) { 920 LOG_INFO(BSL_LS_APPL_TESTS, 921 (BSL_META_U(unit, 922 "Port connection:\n" 923 " RX(mod,port)=%d,%d, TX(mod,port)=%d,%d, VLAN=0x%03x,\n" 924 " SA=%02x:%02x:%02x:%02x:%02x:%02x, " 925 "DA=%02x:%02x:%02x:%02x:%02x:%02x\n"), 926 pc_info->src_modid, pc_info->this_port, 927 pc_info->dst_modid, pc_info->to_port, 928 pc_info->added_vlan, 929 pc_info->src_mac[0], pc_info->src_mac[1], pc_info->src_mac[2], 930 pc_info->src_mac[3], pc_info->src_mac[4], pc_info->src_mac[5], 931 pc_info->dst_mac[0], pc_info->dst_mac[1], pc_info->dst_mac[2], 932 pc_info->dst_mac[3], pc_info->dst_mac[4], pc_info->dst_mac[5])); 933 } 934 /* Sort out things into the proper subsettings */ 935 #ifdef BCM_HERCULES_SUPPORT 936 if (SOC_IS_HERCULES(unit)) { 937 rv = lbu_connect_herc_ports(unit, pc_info, connect); 938 } else 939 #endif 940 { 941 if (IS_E_PORT(unit, pc_info->this_port)) { 942 if (IS_E_PORT(unit, pc_info->to_port)) { 943 rv = lbu_connect_ether_ports(unit, pc_info, connect); 944 } else if (IS_ST_PORT(unit, pc_info->to_port)) { 945 rv = lbu_connect_ether_to_hg_port(unit, pc_info, connect); 946 } else { /* Should be CMIC */ 947 rv = lbu_connect_ether_ports(unit, pc_info, connect); 948 } 949 } else { 950 if (IS_ST_PORT(unit, pc_info->to_port)) { 951 if (SOC_IS_HBX(unit)) { 952 rv = lbu_set_modport(unit, pc_info->this_port, 953 pc_info->to_port, pc_info->dst_modid); 954 } else { 955 /* Uhhh, now what? Two HG ports */ 956 /* Not supported for FB/ER */ 957 LOG_INFO(BSL_LS_APPL_TESTS, 958 (BSL_META_U(unit, 959 "lbu_connect_ports: Two HG ports rv = %d\n"), 960 BCM_E_UNAVAIL)); 961 return BCM_E_UNAVAIL; 962 } 963 } else { /* Ether or CMIC */ 964 rv = lbu_connect_hg_to_ether_port(unit, pc_info, connect); 965 } 966 } 967 } 968 LOG_INFO(BSL_LS_APPL_TESTS, 969 (BSL_META_U(unit, 970 "lbu_connect_ports: rv = %d\n"), rv)); 971 return rv; 972 } 973 974 975 void 976 lbu_cleanup_arl(loopback2_test_t *lw) 977 { 978 loopback2_testdata_t *lp; 979 int unit; 980 sal_mac_addr_t cur_mac; 981 int pkt_cur; 982 #ifdef BCM_TRIUMPH_SUPPORT 983 int ext_index_max = -1; 984 #endif /* BCM_TRIUMPH_SUPPORT */ 985 986 if (lw == NULL) { 987 return; 988 } 989 unit = lw->unit; 990 lp = lw->cur_params; 991 if (lp == NULL) { 992 return; 993 } 994 995 #ifdef BCM_TRIUMPH_SUPPORT 996 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 997 ext_index_max = SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max; 998 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = -1; 999 } 1000 #endif /* BCM_TRIUMPH_SUPPORT */ 1001 1002 /* Source MAC flush */ 1003 ENET_SET_MACADDR(cur_mac, lw->base_mac_src); 1004 for (pkt_cur = 0; pkt_cur < lp->ppt_end; pkt_cur++) { 1005 (void)bcm_l2_addr_delete(unit, cur_mac, lp->vlan); 1006 increment_macaddr(cur_mac, lp->mac_src_inc); 1007 } 1008 1009 /* Destination MAC flush */ 1010 ENET_SET_MACADDR(cur_mac, lw->base_mac_dst); 1011 for (pkt_cur = 0; pkt_cur < lp->ppt_end; pkt_cur++) { 1012 (void)bcm_l2_addr_delete(unit, cur_mac, lp->vlan); 1013 increment_macaddr(cur_mac, lp->mac_dst_inc); 1014 } 1015 1016 #ifdef BCM_TRIUMPH_SUPPORT 1017 if (soc_mem_is_valid(unit, EXT_L2_ENTRYm)) { 1018 SOC_PERSIST(unit)->memState[EXT_L2_ENTRYm].index_max = ext_index_max; 1019 } 1020 #endif /* BCM_TRIUMPH_SUPPORT */ 1021 } 1022 1023 STATIC int 1024 lbu_save_port(loopback2_test_t *lw, loopback2_testdata_t *lp) 1025 { 1026 int rv; 1027 bcm_port_t port; 1028 pbmp_t save_ports; 1029 int unit = lw->unit; 1030 1031 if (SOC_IS_XGS12_FABRIC(unit)) { 1032 BCM_PBMP_ASSIGN(save_ports, PBMP_PORT_ALL(unit)); 1033 } else { 1034 BCM_PBMP_ASSIGN(save_ports, PBMP_PORT_ALL(unit)); 1035 BCM_PBMP_AND(save_ports, lp->pbm); 1036 } 1037 1038 PBMP_ITER(save_ports, port) { 1039 if ((rv = bcm_port_info_save(unit, port, 1040 &lw->save_port[port])) < 0) { 1041 test_error(unit, 1042 "Port %s: Could not get port info: %s\n", 1043 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 1044 return(-1); 1045 } 1046 #ifdef BCM_TOMAHAWK3_SUPPORT 1047 /* Save original fec, phy config and link training info. Note pm8x50 1048 * (cd ports) need this information 1049 */ 1050 if ((SOC_IS_TOMAHAWK3(unit)) && (IS_CD_PORT(unit, port))) { 1051 rv = bcm_port_resource_speed_get(unit, port, 1052 &lw->port_info[port]); 1053 if (rv < 0) { 1054 test_error(unit, 1055 "Port %s: bcm_port_resource_speed_get failed:" 1056 " %s\n", SOC_PORT_NAME(unit, port), 1057 bcm_errmsg(rv)); 1058 return(-1); 1059 } 1060 } 1061 #endif /* BCM_TOMAHAWK3_SUPPORT */ 1062 } 1063 1064 1065 if (bcm_rx_cfg_get(unit, NULL) == BCM_E_NONE) { 1066 test_error(unit, "BCM_RX is currently not active; cannot run test\n"); 1067 return(-1); 1068 } 1069 1070 #ifdef BCM_ESW_SUPPORT 1071 if (SOC_IS_XGS_SWITCH(unit)) { 1072 int not_my_mod; 1073 /* Save current source port/module and change to != lp->d_mod */ 1074 1075 lbu_saved_srcmod[unit] = SOC_DEFAULT_DMA_SRCMOD_GET(unit); 1076 lbu_saved_srcport[unit] = SOC_DEFAULT_DMA_SRCPORT_GET(unit); 1077 not_my_mod = (lp->d_mod == 0); 1078 SOC_DEFAULT_DMA_SRCMOD_SET(unit, not_my_mod); 1079 SOC_DEFAULT_DMA_SRCPORT_SET(unit, CMIC_PORT(unit)); 1080 #ifdef BCM_XGS3_SWITCH_SUPPORT 1081 if (SOC_IS_XGS3_SWITCH(unit)) { 1082 /* 1083 * Should save(Not yet done here) ICONTROL_OPCODE_BITMAP before 1084 * the test and restore it after test is done 1085 * Redirect all packets with CPU control opcode 1086 * from HG ports to CPU. 1087 * Replace with API. 1088 */ 1089 int pbm_len; 1090 uint32 cpu_pbm; 1091 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 1092 cpu_pbm = 0; /* init it, some compiler has false warning */ 1093 } else if (SOC_IS_TR_VL(unit) && !SOC_IS_TRIUMPH2(unit) 1094 && !SOC_IS_APOLLO(unit) && !SOC_IS_VALKYRIE2(unit)) { 1095 SOC_IF_ERROR_RETURN 1096 (soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit), 1097 &cpu_pbm)); 1098 } else if (CMIC_PORT(unit)) { 1099 pbm_len = soc_reg_field_length(unit, ICONTROL_OPCODE_BITMAPr, 1100 BITMAPf); 1101 /* Bad shift complaint by Coverity */ 1102 cpu_pbm = pbm_len > 0? 1 << (pbm_len - 1): 0; 1103 } else { 1104 cpu_pbm = 1; 1105 } 1106 PBMP_ST_ITER(unit, port) { 1107 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 1108 icontrol_opcode_bitmap_entry_t entry; 1109 sal_memset(&entry, 0, sizeof(entry)); 1110 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, 1111 &entry, BITMAPf, &PBMP_CMIC(unit)); 1112 rv = soc_mem_write(unit, ICONTROL_OPCODE_BITMAPm, 1113 MEM_BLOCK_ANY, port, &entry); 1114 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 1115 SOC_IS_VALKYRIE2(unit)) { 1116 uint64 cpu_pbm_64; 1117 COMPILER_64_ZERO(cpu_pbm_64); 1118 COMPILER_64_SET(cpu_pbm_64, 0, cpu_pbm); 1119 SOC_IF_ERROR_RETURN 1120 (WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, 1121 cpu_pbm_64)); 1122 } else if (SOC_REG_IS_VALID(unit, ICONTROL_OPCODE_BITMAP_LOr) && 1123 SOC_REG_IS_VALID(unit, ICONTROL_OPCODE_BITMAP_HIr)) { 1124 1125 uint64 fval64, rval64; 1126 uint32 t_port; 1127 pbmp_t curr_pbmp; 1128 soc_reg_t reg; 1129 1130 BCM_PBMP_CLEAR(curr_pbmp); 1131 COMPILER_64_ZERO(fval64); 1132 1133 /* Set HG ingress CPU Opcode map to the CPU */ 1134 if (CMIC_PORT(unit) < 64) { 1135 reg = ICONTROL_OPCODE_BITMAP_LOr; 1136 t_port = CMIC_PORT(unit); 1137 } else { 1138 reg = ICONTROL_OPCODE_BITMAP_HIr; 1139 t_port = CMIC_PORT(unit) - 64; 1140 } 1141 1142 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 1143 1144 SOC_IF_ERROR_RETURN( 1145 soc_reg_get(unit, reg, port, 0, &rval64)); 1146 COMPILER_64_SET(fval64, 1147 SOC_PBMP_WORD_GET(curr_pbmp, 1), 1148 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 1149 1150 soc_reg64_field_set(unit, 1151 reg, &rval64, BITMAPf, fval64); 1152 SOC_IF_ERROR_RETURN( 1153 soc_reg_set(unit, reg, port, 0, rval64)); 1154 } else { 1155 SOC_IF_ERROR_RETURN 1156 (WRITE_ICONTROL_OPCODE_BITMAPr(unit, port, cpu_pbm)); 1157 } 1158 } 1159 } 1160 #endif 1161 } 1162 #ifdef BCM_XGS12_FABRIC_SUPPORT 1163 else if (SOC_IS_XGS12_FABRIC(unit)) { 1164 uint32 ucdata; 1165 pbmp_t uc; 1166 int blk; 1167 1168 SOC_PBMP_CLEAR(uc); 1169 SOC_PBMP_PORT_ADD(uc, CMIC_PORT(unit)); 1170 ucdata = SOC_PBMP_WORD_GET(uc, 0); 1171 PBMP_ITER(save_ports, port) { 1172 blk = SOC_PORT_BLOCK(unit, port); 1173 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MEM_UCm, blk, 1174 lp->d_mod, &ucdata)); 1175 } 1176 } 1177 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 1178 #endif /* BCM_ESW_SUPPORT */ 1179 1180 return(0); 1181 } 1182 1183 int 1184 lbu_setup_port(int unit, bcm_port_t port, int req_speed, int autoneg) 1185 { 1186 int speed = 0, duplex = 0, max_speed; 1187 bcm_port_ability_t req_ability; 1188 bcm_port_ability_t actual_ability; 1189 bcm_port_medium_t medium; 1190 1191 sal_memset(&req_ability, 0, sizeof(bcm_port_ability_t)); 1192 1193 BCM_IF_ERROR_RETURN( 1194 bcm_port_speed_max(unit, port, &max_speed)); 1195 if (max_speed > SOC_INFO(unit).port_speed_max[port]) { 1196 max_speed = SOC_INFO(unit).port_speed_max[port]; 1197 } 1198 1199 switch (req_speed) { 1200 case LB_SPEED_10FD: 1201 speed = 10 ; 1202 req_ability.speed_full_duplex = SOC_PA_SPEED_10MB; 1203 duplex = SOC_PORT_DUPLEX_FULL; 1204 break; 1205 case LB_SPEED_100FD: 1206 speed = 100; 1207 req_ability.speed_full_duplex = SOC_PA_SPEED_100MB; 1208 duplex = SOC_PORT_DUPLEX_FULL; 1209 break; 1210 case LB_SPEED_1000FD: 1211 speed = 1000; 1212 req_ability.speed_full_duplex = SOC_PA_SPEED_1000MB; 1213 duplex = SOC_PORT_DUPLEX_FULL; 1214 break; 1215 case LB_SPEED_2500FD: 1216 speed = 2500; 1217 req_ability.speed_full_duplex = SOC_PA_SPEED_2500MB; 1218 duplex = SOC_PORT_DUPLEX_FULL; 1219 break; 1220 case LB_SPEED_3000FD: 1221 speed = 3000; 1222 req_ability.speed_full_duplex = SOC_PA_SPEED_3000MB; 1223 duplex = SOC_PORT_DUPLEX_FULL; 1224 break; 1225 case LB_SPEED_5000FD: 1226 speed = 5000; 1227 req_ability.speed_full_duplex = SOC_PA_SPEED_5000MB; 1228 duplex = SOC_PORT_DUPLEX_FULL; 1229 break; 1230 case LB_SPEED_10G_FD: 1231 speed = 10000; 1232 req_ability.speed_full_duplex = SOC_PA_SPEED_10GB; 1233 duplex = SOC_PORT_DUPLEX_FULL; 1234 break; 1235 case LB_SPEED_11G_FD: 1236 speed = 11000; 1237 req_ability.speed_full_duplex = SOC_PA_SPEED_11GB; 1238 duplex = SOC_PORT_DUPLEX_FULL; 1239 break; 1240 case LB_SPEED_12G_FD: 1241 speed = 12000; 1242 req_ability.speed_full_duplex = SOC_PA_SPEED_12GB; 1243 duplex = SOC_PORT_DUPLEX_FULL; 1244 break; 1245 case LB_SPEED_13G_FD: 1246 speed = 13000; 1247 req_ability.speed_full_duplex = SOC_PA_SPEED_13GB; 1248 duplex = SOC_PORT_DUPLEX_FULL; 1249 break; 1250 case LB_SPEED_15G_FD: 1251 speed = 15000; 1252 req_ability.speed_full_duplex = SOC_PA_SPEED_15GB; 1253 duplex = SOC_PORT_DUPLEX_FULL; 1254 break; 1255 case LB_SPEED_16G_FD: 1256 speed = 16000; 1257 req_ability.speed_full_duplex = SOC_PA_SPEED_16GB; 1258 duplex = SOC_PORT_DUPLEX_FULL; 1259 break; 1260 case LB_SPEED_20G_FD: 1261 speed = 20000; 1262 req_ability.speed_full_duplex = SOC_PA_SPEED_20GB; 1263 duplex = SOC_PORT_DUPLEX_FULL; 1264 break; 1265 case LB_SPEED_21G_FD: 1266 speed = 21000; 1267 req_ability.speed_full_duplex = SOC_PA_SPEED_21GB; 1268 duplex = SOC_PORT_DUPLEX_FULL; 1269 break; 1270 case LB_SPEED_23G_FD: 1271 speed = 23000; 1272 req_ability.speed_full_duplex = SOC_PA_SPEED_23GB; 1273 duplex = SOC_PORT_DUPLEX_FULL; 1274 break; 1275 case LB_SPEED_24G_FD: 1276 speed = 24000; 1277 req_ability.speed_full_duplex = SOC_PA_SPEED_24GB; 1278 duplex = SOC_PORT_DUPLEX_FULL; 1279 break; 1280 case LB_SPEED_25G_FD: 1281 speed = 25000; 1282 req_ability.speed_full_duplex = SOC_PA_SPEED_25GB; 1283 duplex = SOC_PORT_DUPLEX_FULL; 1284 break; 1285 case LB_SPEED_30G_FD: 1286 speed = 30000; 1287 req_ability.speed_full_duplex = SOC_PA_SPEED_30GB; 1288 duplex = SOC_PORT_DUPLEX_FULL; 1289 break; 1290 case LB_SPEED_32G_FD: 1291 speed = 32000; 1292 req_ability.speed_full_duplex = SOC_PA_SPEED_32GB; 1293 duplex = SOC_PORT_DUPLEX_FULL; 1294 break; 1295 case LB_SPEED_40G_FD: 1296 speed = 40000; 1297 req_ability.speed_full_duplex = SOC_PA_SPEED_40GB; 1298 duplex = SOC_PORT_DUPLEX_FULL; 1299 break; 1300 case LB_SPEED_42G_FD: 1301 speed = 42000; 1302 req_ability.speed_full_duplex = SOC_PA_SPEED_42GB; 1303 duplex = SOC_PORT_DUPLEX_FULL; 1304 break; 1305 case LB_SPEED_50G_FD: 1306 speed = 50000; 1307 duplex = SOC_PORT_DUPLEX_FULL; 1308 break; 1309 case LB_SPEED_100G_FD: 1310 speed = 100000; 1311 req_ability.speed_full_duplex = SOC_PA_SPEED_100GB; 1312 duplex = SOC_PORT_DUPLEX_FULL; 1313 break; 1314 case LB_SPEED_106G_FD: 1315 speed = 106000; 1316 req_ability.speed_full_duplex = SOC_PA_SPEED_106GB; 1317 duplex = SOC_PORT_DUPLEX_FULL; 1318 break; 1319 case LB_SPEED_120G_FD: 1320 speed = 120000; 1321 req_ability.speed_full_duplex = SOC_PA_SPEED_120GB; 1322 duplex = SOC_PORT_DUPLEX_FULL; 1323 break; 1324 case LB_SPEED_127G_FD: 1325 speed = 127000; 1326 req_ability.speed_full_duplex = SOC_PA_SPEED_127GB; 1327 duplex = SOC_PORT_DUPLEX_FULL; 1328 break; 1329 case LB_SPEED_200G_FD: 1330 speed = 200000; 1331 duplex = SOC_PORT_DUPLEX_FULL; 1332 break; 1333 case LB_SPEED_400G_FD: 1334 speed = 400000; 1335 duplex = SOC_PORT_DUPLEX_FULL; 1336 break; 1337 case LB_SPEED_MAX: 1338 /* PM8x50 does not support port_ability_local_get. Use max speed */ 1339 if (!IS_CD_PORT(unit, port)) { 1340 BCM_IF_ERROR_RETURN( 1341 bcm_port_ability_local_get(unit, port, &req_ability)); 1342 } 1343 duplex = SOC_PORT_DUPLEX_FULL; 1344 speed = max_speed; 1345 break; 1346 default: 1347 return(BCM_E_PARAM); 1348 } 1349 1350 BCM_IF_ERROR_RETURN( 1351 bcm_port_enable_set(unit, port, TRUE)); 1352 BCM_IF_ERROR_RETURN( 1353 bcm_port_medium_get(unit, port, &medium)); 1354 if ((medium == BCM_PORT_MEDIUM_FIBER) && 1355 (duplex != SOC_PORT_DUPLEX_FULL)) { 1356 LOG_ERROR(BSL_LS_APPL_TESTS, 1357 (BSL_META_U(unit, 1358 "unit %d Port %s is in Fiber mode. " 1359 "Forcing FullDuplex\n"), 1360 unit, SOC_PORT_NAME(unit, port))); 1361 duplex = SOC_PORT_DUPLEX_FULL; 1362 } 1363 1364 if (autoneg) { 1365 BCM_IF_ERROR_RETURN( 1366 bcm_port_ability_advert_set(unit, port, &req_ability)); 1367 BCM_IF_ERROR_RETURN( 1368 bcm_port_autoneg_set(unit, port, TRUE)); 1369 } else { 1370 /* PM8x50 does not support port_ability_local_get. Use max speed */ 1371 if (!IS_CD_PORT(unit, port)) { 1372 BCM_IF_ERROR_RETURN( 1373 bcm_port_ability_local_get(unit, port, &actual_ability)); 1374 1375 if (!(actual_ability.speed_full_duplex & req_ability.speed_full_duplex)) { 1376 LOG_ERROR(BSL_LS_APPL_TESTS, 1377 (BSL_META_U(unit, 1378 "unit %d Port %s: Speed %uMbps is unsupported, " 1379 "Forcing %uMbps\n"), 1380 unit, SOC_PORT_NAME(unit, port), speed, max_speed)); 1381 speed = max_speed; 1382 } 1383 } 1384 1385 BCM_IF_ERROR_RETURN( 1386 bcm_port_autoneg_set(unit, port, FALSE)); 1387 if (IS_CD_PORT(unit, port)) { 1388 bcm_port_resource_t pr; 1389 BCM_IF_ERROR_RETURN(bcm_port_resource_speed_get(unit, port, 1390 &pr)); 1391 #ifdef BCM_TOMAHAWK3_SUPPORT 1392 if (SOC_IS_TOMAHAWK3(unit)) { 1393 int lanes_match = 1; 1394 bcm_port_phy_fec_t fec_type = bcmPortPhyFecNone; 1395 int phy_lane_config; 1396 int link_training; 1397 1398 /* We will proceed only if speed specified by the user matches 1399 * (for a given number of lanes) one of the speeds with equal 1400 * number of lanes 1401 */ 1402 switch(pr.lanes) { 1403 case 8: 1404 if (speed != 400000) { 1405 lanes_match = 0; 1406 } 1407 1408 fec_type = bcmPortPhyFecRs544_2xN; 1409 break; 1410 case 4: 1411 if ((speed != 200000) && 1412 (speed != 100000) && 1413 (speed != 40000)) { 1414 lanes_match = 0; 1415 } 1416 switch (speed) { 1417 case 200000: 1418 fec_type = bcmPortPhyFecRs544; 1419 break; 1420 case 100000: 1421 case 40000: 1422 default: 1423 fec_type = bcmPortPhyFecNone; 1424 break; 1425 } 1426 break; 1427 case 2: 1428 if ((speed != 100000) && 1429 (speed != 50000) && 1430 (speed != 40000)) { 1431 lanes_match = 0; 1432 } 1433 1434 switch (speed) { 1435 case 100000: 1436 case 50000: 1437 fec_type = bcmPortPhyFecRs544; 1438 break; 1439 case 40000: 1440 default: 1441 fec_type = bcmPortPhyFecNone; 1442 break; 1443 } 1444 break; 1445 case 1: 1446 if ((speed != 50000) && 1447 (speed != 25000) && 1448 (speed != 10000)) { 1449 lanes_match = 0; 1450 } 1451 1452 switch (speed) { 1453 case 50000: 1454 fec_type = bcmPortPhyFecRs544; 1455 break; 1456 case 25000: 1457 case 10000: 1458 default: 1459 fec_type = bcmPortPhyFecNone; 1460 break; 1461 } 1462 break; 1463 1464 default: 1465 lanes_match = 0; 1466 break; 1467 } 1468 1469 phy_lane_config = -1; 1470 link_training = 0; 1471 1472 if (!lanes_match) { 1473 LOG_ERROR(BSL_LS_APPL_TESTS, (BSL_META_U(unit, "unit %d" 1474 " Port %s: Speed %uMbps is not supported for %d" 1475 " lane(s)\n"), unit, 1476 SOC_PORT_NAME(unit, port), speed, pr.lanes)); 1477 return(BCM_E_PARAM); 1478 } 1479 1480 pr.fec_type = fec_type; 1481 pr.phy_lane_config = phy_lane_config; 1482 pr.link_training = link_training; 1483 } 1484 #endif /* BCM_TOMAHAWK3_SUPPORT */ 1485 if (pr.speed != speed) { 1486 LOG_INFO(BSL_LS_BCM_PORT, 1487 (BSL_META_U(unit, 1488 "port speed (%d) does NOT match " 1489 " current speed (%d).\n"), 1490 pr.speed, speed)); 1491 } 1492 pr.speed = speed; 1493 BCM_IF_ERROR_RETURN(bcm_port_resource_speed_set(unit, port, &pr)); 1494 } else { 1495 BCM_IF_ERROR_RETURN( 1496 bcm_port_speed_set(unit, port, speed)); 1497 } 1498 BCM_IF_ERROR_RETURN( 1499 bcm_port_duplex_set(unit, port, duplex)); 1500 } 1501 1502 return (BCM_E_NONE); 1503 } 1504 1505 STATIC int 1506 lbu_port_init(loopback2_test_t *lw, loopback2_testdata_t *lp) 1507 { 1508 char pfmt[SOC_PBMP_FMT_LEN]; 1509 bcm_port_t p; 1510 int rv, unit = lw->unit; 1511 int rcpu; 1512 1513 /* Save all the current port states */ 1514 1515 LOG_INFO(BSL_LS_APPL_TESTS, 1516 (BSL_META("Saving ports\n"))); 1517 if (lbu_save_port(lw, lp) < 0) { 1518 return (-1); 1519 } 1520 1521 /* Port setup */ 1522 LOG_INFO(BSL_LS_APPL_TESTS, 1523 (BSL_META("Port setup, bitmap %s\n"), 1524 SOC_PBMP_FMT(lp->pbm, pfmt))); 1525 if (lp->loopback == LB2_MODE_EXT) { 1526 PBMP_ITER(lp->pbm, p) { 1527 /* Forwarding, egress enable, epc_link */ 1528 if ((rv = bcm_port_stp_set(unit, p, 1529 BCM_STG_STP_FORWARD)) < 0) { 1530 test_error(unit, 1531 "Unable to set port %s in forwarding state: %s\n", 1532 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1533 return -1; 1534 } 1535 } 1536 } 1537 1538 if (lp->loopback == LB2_MODE_MAC) { 1539 LOG_INFO(BSL_LS_APPL_TESTS, 1540 (BSL_META("MAC loopback at speed %s\n"), 1541 lb2_parse_speed[lp->speed])); 1542 1543 PBMP_ITER(lp->pbm, p) { 1544 if (SOC_IS_HAWKEYE(unit)||SOC_IS_GREYHOUND2(unit)) { 1545 if ((rv = lbu_setup_port(unit, p, lp->speed, FALSE)) < 0) { 1546 test_error(unit, 1547 "Port %s: Port setup failed: %s\n", 1548 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1549 return(-1); 1550 } 1551 if ((rv = bcm_port_loopback_set(unit, p, 1552 BCM_PORT_LOOPBACK_MAC)) < 0) { 1553 test_error(unit, 1554 "Port %s: Failed to set MAC loopback: %s\n", 1555 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1556 return(-1); 1557 } 1558 } else { 1559 /* 1560 * Set loopback mode before speed, since it may affect 1561 * the allowable speeds. 1562 */ 1563 1564 if ((rv = bcm_port_loopback_set(unit, p, 1565 BCM_PORT_LOOPBACK_MAC)) < 0) { 1566 test_error(unit, 1567 "Port %s: Failed to set MAC loopback: %s\n", 1568 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1569 return(-1); 1570 } 1571 1572 if (IS_HG_PORT(unit, p)) { 1573 /* 1574 * Disabling pause reuiqred on IPIC/XPORT 1575 * HG ports. Should already be disabled on 1576 * GE (stack) ports during init. 1577 */ 1578 bcm_port_pause_set(unit, p, FALSE, FALSE); 1579 } 1580 1581 if ((rv = lbu_setup_port(unit, p, lp->speed, FALSE)) < 0) { 1582 test_error(unit, 1583 "Port %s: Port setup failed: %s\n", 1584 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1585 return(-1); 1586 } 1587 } 1588 } 1589 1590 if (SOC_IS_XGS12_FABRIC(unit)) { 1591 pbmp_t pbm; 1592 1593 /* 1594 * If there is an external cable looped back, 5670 will 1595 * receive packets on ports that may not be in the test 1596 * and these packets will go to the CPU and interfere. 1597 */ 1598 1599 BCM_PBMP_ASSIGN(pbm, lp->pbm); 1600 BCM_PBMP_XOR(pbm, PBMP_PORT_ALL(unit)); 1601 PBMP_ITER(pbm, p) { 1602 if ((rv = bcm_port_enable_set(unit, p, FALSE)) < 0) { 1603 test_error(unit, 1604 "Port %s: Failed to set MAC enable: %s\n", 1605 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1606 return(-1); 1607 } 1608 } 1609 } 1610 } else if (lp->loopback == LB2_MODE_PHY) { 1611 LOG_INFO(BSL_LS_APPL_TESTS, 1612 (BSL_META("PHY loopback at speed %s\n"), 1613 lb2_parse_speed[lp->speed])); 1614 1615 rcpu = soc_property_get(unit, spn_RCPU_PORT, -1); 1616 PBMP_ITER(lp->pbm, p) { 1617 if (rcpu !=0 && rcpu != -1 && SOC_IS_RAVEN(unit)) { 1618 if ((rv = bcm_port_loopback_set(unit, p, 1619 BCM_PORT_LOOPBACK_PHY)) < 0) { 1620 test_error(unit, 1621 "Port %s: Failed to set PHY loopback: %s\n", 1622 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1623 return(-1); /* In case they continue */ 1624 } 1625 1626 if ((rv = lbu_setup_port(unit, p, lp->speed, FALSE)) < 0) { 1627 test_error(unit, 1628 "Port %s: Port setup failed: %s\n", 1629 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1630 return(-1); 1631 } 1632 1633 } else { 1634 if ((rv = lbu_setup_port(unit, p, lp->speed, FALSE)) < 0) { 1635 test_error(unit, 1636 "Port %s: Port setup failed: %s\n", 1637 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1638 return(-1); 1639 } 1640 1641 if ((rv = bcm_port_loopback_set(unit, p, 1642 BCM_PORT_LOOPBACK_PHY)) < 0) { 1643 test_error(unit, 1644 "Port %s: Failed to set PHY loopback: %s\n", 1645 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1646 return(-1); /* In case they continue */ 1647 } 1648 } 1649 } 1650 } else { /* External */ 1651 1652 PBMP_ITER(lp->pbm, p) { 1653 if ((rv = lbu_setup_port(unit, p, lp->speed, FALSE)) < 0) { 1654 test_error(unit, 1655 "Port %s: Port setup failed: %s\n", 1656 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1657 return(-1); 1658 } 1659 } 1660 } 1661 if(SOC_IS_ESW(unit)){ 1662 if (lp->test_type == LB2_TT_SNAKE) { 1663 PBMP_ITER(lp->pbm, p) { 1664 if ((rv = bcm_port_learn_set(unit, p, BCM_PORT_LEARN_FWD)) < 0) { 1665 test_error(unit, 1666 "Unable to set learn state: port %s: %s\n", 1667 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1668 return (-1); 1669 } 1670 } 1671 } 1672 } 1673 #ifdef BCM_TRIUMPH_SUPPORT 1674 if(SOC_IS_TRX(unit)){ 1675 PBMP_ITER(lp->pbm, p) { 1676 #ifdef BCM_TRIDENT2PLUS_SUPPORT 1677 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 1678 if (soc_feature(unit, soc_feature_egr_all_profile)) { 1679 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 1680 p, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 0)); 1681 } else { 1682 egr_vlan_control_1_entry_t entry; 1683 BCM_IF_ERROR_RETURN 1684 (READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, p, &entry)); 1685 soc_EGR_VLAN_CONTROL_1m_field32_set(unit, &entry, 1686 REMARK_OUTER_DOT1Pf, 0); 1687 BCM_IF_ERROR_RETURN 1688 (WRITE_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, p, &entry)); 1689 } 1690 } else 1691 #endif 1692 if ((rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, p, 1693 REMARK_OUTER_DOT1Pf, 0x0)) < 0) { 1694 test_error(unit, 1695 "Unable to disable outer dot1p remarking: port %s: %s\n", 1696 SOC_PORT_NAME(unit, p), bcm_errmsg(rv)); 1697 return (-1); 1698 } 1699 } 1700 } 1701 #endif 1702 { 1703 bcm_pbmp_t lw_pbm; 1704 BCM_PBMP_ASSIGN(lw_pbm, lp->pbm); 1705 rv = bcm_link_wait(unit, &lw_pbm, 1000000); 1706 if (rv < 0) { 1707 return -1; 1708 } 1709 } 1710 1711 1712 return 0; 1713 } 1714 1715 STATIC int 1716 lbu_vlan_init(loopback2_test_t *lw, loopback2_testdata_t *lp) 1717 { 1718 int rv, unit = lw->unit; 1719 pbmp_t empty_pbm, vlan_pbm; 1720 bcm_port_t p; 1721 bcm_vlan_t vlan; 1722 1723 if (!lp->inject) { 1724 if ((rv = bcm_vlan_destroy_all(unit)) < 0) { 1725 test_error(unit, 1726 "Could not destroy existing VLANs: %s\n", 1727 bcm_errmsg(rv)); 1728 return (-1); 1729 } 1730 } 1731 1732 if (lp->test_type == LB2_TT_SNAKE) { 1733 PBMP_ITER(lp->pbm, p) { 1734 /* Each port in all VLANs for test */ 1735 vlan = lp->vlan + p + 1; 1736 if ( ((rv = bcm_vlan_create(unit, vlan)) < 0) && 1737 (rv != BCM_E_EXISTS) ) { 1738 test_error(unit, 1739 "Could not create VLAN %d: %s\n", 1740 vlan, bcm_errmsg(rv)); 1741 return (-1); 1742 } 1743 1744 /* Untagged! */ 1745 BCM_PBMP_ASSIGN(vlan_pbm, lp->pbm); 1746 BCM_PBMP_PORT_ADD(vlan_pbm, CMIC_PORT(unit)); 1747 if ((rv = bcm_vlan_port_add(unit, vlan, vlan_pbm, vlan_pbm)) < 0) { 1748 test_error(unit, 1749 "Could not add test ports to VLAN %d: %s\n", 1750 vlan, bcm_errmsg(rv)); 1751 return (-1); 1752 } 1753 1754 /* Set port to tag with vlan */ 1755 if (IS_E_PORT(unit, p)) { 1756 if ((rv = bcm_port_untagged_vlan_set(unit, p, vlan)) < 0) { 1757 test_error(unit, 1758 "Could not set port %s to " 1759 "tag packet with VLAN %d: %s\n", 1760 SOC_PORT_NAME(unit, p), vlan, bcm_errmsg(rv)); 1761 return (-1); 1762 } 1763 } 1764 } 1765 } else { 1766 if ((rv = bcm_vlan_create(unit, lp->vlan)) < 0 && 1767 rv != BCM_E_EXISTS) { 1768 test_error(unit, 1769 "Could not create VLAN %d: %s\n", 1770 lp->vlan, bcm_errmsg(rv)); 1771 return (-1); 1772 } 1773 1774 SOC_PBMP_CLEAR(empty_pbm); 1775 SOC_PBMP_ASSIGN(vlan_pbm, lp->pbm); 1776 SOC_PBMP_PORT_ADD(vlan_pbm, CMIC_PORT(unit)); 1777 if ((rv = bcm_vlan_port_add(unit, lp->vlan, vlan_pbm, 1778 empty_pbm)) < 0) { 1779 test_error(unit, 1780 "Could not add selected ports to VLAN %d: %s\n", 1781 lp->vlan, bcm_errmsg(rv)); 1782 return (-1); 1783 } 1784 1785 SOC_PBMP_ASSIGN(vlan_pbm, lp->pbm); 1786 SOC_PBMP_AND(vlan_pbm, PBMP_E_ALL(unit)); 1787 PBMP_ITER(vlan_pbm, p) { 1788 if ((rv = bcm_port_untagged_vlan_set(unit, p, lp->vlan)) < 0) { 1789 test_error(unit, 1790 "Could not set port %s to tag packet with VLAN %d: %s\n", 1791 SOC_PORT_NAME(unit, p), lp->vlan, bcm_errmsg(rv)); 1792 return (-1); 1793 } 1794 } 1795 } 1796 1797 return 0; 1798 } 1799 1800 STATIC int 1801 lbu_stack_check(int unit) 1802 { 1803 if (SOC_SL_MODE(unit)) { 1804 return -1; 1805 } 1806 return 0; 1807 } 1808 1809 int 1810 lbu_init(loopback2_test_t *lw, loopback2_testdata_t *lp) 1811 { 1812 int unit = lw->unit; 1813 uint32 flags = BCM_TX_NO_PAD; 1814 1815 if (NULL == (lw->sema = sal_sem_create("lb2-sema", sal_sem_BINARY, 0))) { 1816 return (-1); 1817 } 1818 1819 lw->sema_woke = FALSE; 1820 lw->timeout_usec = lbu_timeout_usec(unit); 1821 1822 lw->tx_seq = 0; 1823 lw->tx_len = 0; 1824 1825 /* Don't want any stack ports lying about */ 1826 if (lbu_stack_check(unit) < 0) { 1827 return (-1); 1828 } 1829 1830 if (lbu_vlan_init(lw, lp) < 0) { 1831 return (-1); 1832 } 1833 1834 /* Initialize ports */ 1835 if (lbu_port_init(lw, lp) < 0) { 1836 return (-1); 1837 } 1838 1839 /* Allocate the tx packets */ 1840 /* Set up TX pkts once, for max length */ 1841 if (lp->crc_mode == LB2_CRC_MODE_MAC_REGEN) { 1842 flags |= BCM_TX_CRC_REGEN; 1843 } else if (lp->crc_mode == LB2_CRC_MODE_CPU_APPEND) { 1844 flags |= BCM_TX_CRC_APPEND; 1845 } /* else, do not add a flag */ 1846 bcm_pkt_blk_alloc(unit, lp->ppt_end, lp->len_end, flags, &(lw->tx_pkts)); 1847 if (!lw->tx_pkts) { 1848 test_error(unit, "Unable to allocate tx packet memory\n"); 1849 return -1; 1850 } 1851 lw->rx_pkts = sal_alloc(lp->ppt_end * sizeof(bcm_pkt_t), "lb2 rx pkts"); 1852 if (!lw->rx_pkts) { 1853 bcm_pkt_blk_free(unit, lw->tx_pkts, lp->ppt_end); 1854 test_error(unit, "Unable to allocate rx packet memory\n"); 1855 return -1; 1856 } 1857 sal_memset(lw->rx_pkts, 0, lp->ppt_end * sizeof(bcm_pkt_t)); 1858 1859 /* Now that all mems are safely created, fire off the handler */ 1860 if (!lp->inject) { 1861 LOG_INFO(BSL_LS_APPL_TESTS, 1862 (BSL_META_U(unit, 1863 "Port monitor init\n"))); 1864 /* Let rx handler ignore packets until testing */ 1865 lw->expect_pkts = FALSE; 1866 lw->rx_pkt_cnt = 0; 1867 if (lbu_port_monitor_task(unit, lbu_rx_callback, lw) < 0) { 1868 return (-1); 1869 } 1870 } 1871 1872 lw->cur_params = lp; 1873 1874 return 0; 1875 } 1876 1877 int 1878 lbu_snake_init(loopback2_test_t *lw, loopback2_testdata_t *lp) 1879 /* 1880 * Function: lbu_snake_init 1881 * Purpose: Link adjacent ports to forward packets. 1882 * Parameters: lw - pointer to current work structure. 1883 * Returns: 0 - OK 1884 * -1 - failed. 1885 */ 1886 { 1887 int unit = lw->unit; 1888 int snake_way = lp->snake_way; 1889 bcm_port_t port, first_port, last_port; 1890 int forward, reverse; 1891 lb2s_port_connect_t *work_info, *f_info, *r_info; 1892 int modid = 0, modid_hi = 0, ipic_my_modid, ipic_my_modid_hi; 1893 int rv, pix; /* port index */ 1894 int port_count, install_count; 1895 int close_loop = (lp->duration != 0); 1896 #ifdef BCM_TOMAHAWK_SUPPORT 1897 int line_rate = lp->line_rate; 1898 int speed_linerate = 0, speed = 0; 1899 #endif 1900 /* Get the module ID for this unit */ 1901 if (SOC_IS_XGS_SWITCH(unit)) { 1902 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_get(unit, &modid)); 1903 } 1904 #ifdef BCM_ESW_SUPPORT 1905 /* Why does this make the snake work? */ 1906 #ifdef BCM_TRIUMPH3_SUPPORT 1907 if (soc_feature(unit, soc_feature_ism_memory)) { 1908 1909 uint8 banks[_SOC_ISM_MAX_BANKS], count, bank_ix; 1910 uint32 bank_size[_SOC_ISM_MAX_BANKS]; 1911 rv = soc_ism_get_banks_for_mem(unit, L2_ENTRY_1m, 1912 banks, bank_size, &count); 1913 if (rv < 0) { 1914 test_error(unit, "ISM L2 bank enumeration retrieval failed\n"); 1915 return rv; 1916 } 1917 1918 for (bank_ix = 0; bank_ix < count; bank_ix++) { 1919 /* Offset 0 is CRC32 low */ 1920 rv = soc_ism_hash_offset_config(unit, banks[bank_ix], 0); 1921 if (rv < 0) { 1922 test_error(unit, "ISM L2 bank %d hash offset set failure\n", 1923 banks[bank_ix]); 1924 return rv; 1925 } 1926 } 1927 } else 1928 #endif /* BCM_TRIUMPH3_SUPPORT */ 1929 if (SOC_IS_XGS3_SWITCH(unit) && !(SOC_IS_TOMAHAWK3(unit))) { 1930 #ifdef BCM_XGS3_SWITCH_SUPPORT 1931 uint32 hc; 1932 LOG_INFO(BSL_LS_APPL_TESTS, 1933 (BSL_META_U(unit, 1934 "Hash select reset to CRC32 low\n"))); 1935 rv = READ_HASH_CONTROLr(unit, &hc); 1936 if (rv >= 0) { 1937 soc_reg_field_set(unit, HASH_CONTROLr, &hc, 1938 L2_AND_VLAN_MAC_HASH_SELECTf, 1939 FB_HASH_CRC32_LOWER); 1940 rv = WRITE_HASH_CONTROLr(unit, hc); 1941 } 1942 if (rv < 0) { 1943 test_error(unit, "Hash select setting failed\n"); 1944 return rv; 1945 } 1946 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 1947 } else if (SOC_IS_XGS_SWITCH(unit)) { 1948 LOG_INFO(BSL_LS_APPL_TESTS, 1949 (BSL_META_U(unit, 1950 "Hash select reset to CRC32 low\n"))); 1951 if ((rv = WRITE_HASH_CONTROLr(unit, XGS_HASH_CRC32_LOWER)) < 0) { 1952 test_error(unit, "Hash select setting failed\n"); 1953 return rv; 1954 } 1955 } 1956 #endif 1957 1958 ipic_my_modid = lp->d_mod + lp->d_mod_inc; 1959 if ((ipic_my_modid == (lp->d_mod == 0)) || (ipic_my_modid == modid)) { 1960 ipic_my_modid += lp->d_mod_inc; 1961 } 1962 if ((ipic_my_modid == (lp->d_mod == 0)) || (ipic_my_modid == modid)) { 1963 ipic_my_modid += lp->d_mod_inc; 1964 } 1965 1966 ipic_my_modid_hi = ipic_my_modid; 1967 1968 forward = (snake_way == LB2_SNAKE_BOTH) || (snake_way == LB2_SNAKE_INCR); 1969 reverse = (snake_way == LB2_SNAKE_BOTH) || (snake_way == LB2_SNAKE_DECR); 1970 1971 first_port = last_port = -1; 1972 PBMP_ITER(lp->pbm, port) { 1973 last_port = port; 1974 if (first_port < 0) { 1975 first_port = port; 1976 } 1977 } 1978 1979 if (first_port < 0) { 1980 return BCM_E_NOT_FOUND; 1981 } 1982 1983 BCM_PBMP_COUNT(lp->pbm, port_count); 1984 lw->port_count = port_count; 1985 1986 #ifdef BCM_TOMAHAWK_SUPPORT 1987 if (line_rate) { 1988 PBMP_ITER(lp->pbm, port) { 1989 BCM_IF_ERROR_RETURN(bcm_port_speed_get(unit,port,&speed)); 1990 if (speed_linerate && speed && (speed != speed_linerate)){ 1991 cli_out("line rate snake test requires all tested ports have same speed\n"); 1992 return BCM_E_PORT; 1993 } 1994 speed_linerate = speed; 1995 } 1996 /*For each one 10G port, we send 10 packets to achieve line rate in snake test. 1997 *This is not a precise value but should be enough. 1998 */ 1999 lp->line_rate_count= speed_linerate / 1000 * lw->port_count; 2000 } 2001 #endif 2002 2003 if (forward) { 2004 if (!(lw->port_cnct_f = 2005 sal_alloc((port_count + 1) * sizeof(lb2s_port_connect_t), 2006 "Forward snake port info"))) { 2007 return BCM_E_MEMORY; 2008 } 2009 sal_memset(lw->port_cnct_f, 0, (port_count + 1)* 2010 sizeof(lb2s_port_connect_t)); 2011 } else { 2012 lw->port_cnct_f = NULL; 2013 } 2014 2015 if (reverse) { 2016 if (!(lw->port_cnct_r = 2017 sal_alloc((port_count + 1) * sizeof(lb2s_port_connect_t), 2018 "Reverse snake port info"))) { 2019 return BCM_E_MEMORY; 2020 } 2021 sal_memset(lw->port_cnct_r, 0, (port_count + 1) * 2022 sizeof(lb2s_port_connect_t)); 2023 } else { 2024 lw->port_cnct_r = NULL; 2025 } 2026 2027 if (!(lw->tx_pkt_match = sal_alloc(lp->ppt_end * sizeof(int), 2028 "Snake TX match markers"))) { 2029 return BCM_E_MEMORY; 2030 } 2031 sal_memset(lw->tx_pkt_match, 0, lp->ppt_end * sizeof(int)); 2032 2033 f_info = lw->port_cnct_f; 2034 r_info = lw->port_cnct_r; 2035 work_info = forward ? f_info : r_info; 2036 2037 work_info->this_port = work_info->to_port = first_port; 2038 work_info->added_vlan = lp->vlan + first_port + 1; 2039 ENET_SET_MACADDR(work_info->src_mac, lp->mac_src); 2040 ENET_SET_MACADDR(work_info->dst_mac, lp->mac_dst); 2041 2042 if (!IS_E_PORT(unit, first_port)) { 2043 work_info->src_modid = ipic_my_modid_hi + lp->d_mod_inc; 2044 } else { 2045 work_info->src_modid = 2046 SOC_PORT_MOD1(unit, first_port) ? modid_hi : modid; 2047 } 2048 work_info->dst_modid = work_info->src_modid; 2049 2050 if (snake_way == LB2_SNAKE_BOTH) { 2051 r_info->to_port = f_info->this_port; 2052 r_info->dst_modid = f_info->src_modid; 2053 ENET_SET_MACADDR(r_info->src_mac, f_info->src_mac); 2054 increment_macaddr(r_info->src_mac, lp->mac_src_inc); 2055 ENET_SET_MACADDR(r_info->dst_mac, f_info->dst_mac); 2056 increment_macaddr(r_info->dst_mac, lp->mac_dst_inc); 2057 } 2058 2059 if (snake_way == LB2_SNAKE_BOTH || snake_way == LB2_SNAKE_DECR) { 2060 if (SOC_IS_XGS12_FABRIC(unit) || 2061 (SOC_IS_HBX(unit) && IS_ST_PORT(unit, first_port))) { 2062 r_info->dst_modid += lp->d_mod_inc; 2063 } 2064 } 2065 2066 2067 2068 /* Generate the port connection info */ 2069 pix = 0; 2070 PBMP_ITER(lp->pbm, port) { 2071 if (pix > 0) { 2072 if (forward) { 2073 f_info[pix].this_port = f_info[pix - 1].to_port = port; 2074 2075 if (IS_ST_PORT(unit, port) && SOC_IS_XGS_SWITCH(unit)) { 2076 f_info[pix].added_vlan = f_info[pix - 1].added_vlan; 2077 f_info[pix].src_modid = 2078 f_info[pix - 1].dst_modid = 2079 ipic_my_modid_hi + lp->d_mod_inc; 2080 } else { 2081 f_info[pix].added_vlan = lp->vlan + port + 1; 2082 if (IS_E_PORT(unit, port)) { 2083 f_info[pix].src_modid = 2084 f_info[pix - 1].dst_modid = 2085 SOC_PORT_MOD1(unit, port) ? 2086 modid_hi : modid; 2087 } else { 2088 f_info[pix].src_modid = 2089 f_info[pix - 1].dst_modid = 2090 f_info[pix - 1].src_modid; 2091 } 2092 2093 } 2094 ENET_SET_MACADDR(f_info[pix].src_mac, f_info[pix - 1].src_mac); 2095 ENET_SET_MACADDR(f_info[pix].dst_mac, f_info[pix - 1].dst_mac); 2096 2097 f_info[pix - 1].valid_info = TRUE; 2098 } 2099 2100 if (reverse) { 2101 r_info[pix].to_port = r_info[pix - 1].this_port = port; 2102 if (!IS_E_PORT(unit, port) && SOC_IS_XGS_SWITCH(unit)) { 2103 r_info[pix - 1].added_vlan = r_info[pix - 2].added_vlan; 2104 r_info[pix].dst_modid = 2105 r_info[pix - 1].src_modid = 2106 ipic_my_modid_hi + (2 * lp->d_mod_inc); 2107 } else { 2108 r_info[pix - 1].added_vlan = lp->vlan + port + 1; 2109 if (IS_E_PORT(unit, port)) { 2110 r_info[pix].dst_modid = 2111 r_info[pix - 1].src_modid = 2112 SOC_PORT_MOD1(unit, port) ? 2113 modid_hi : modid; 2114 } else { 2115 r_info[pix].dst_modid = 2116 r_info[pix - 1].src_modid = 2117 r_info[pix - 1].dst_modid; 2118 } 2119 } 2120 ENET_SET_MACADDR(r_info[pix].src_mac, r_info[pix - 1].src_mac); 2121 ENET_SET_MACADDR(r_info[pix].dst_mac, r_info[pix - 1].dst_mac); 2122 r_info[pix - 1].valid_info = TRUE; 2123 } 2124 } 2125 2126 #ifdef BCM_ESW_SUPPORT 2127 if (IS_ST_PORT(unit, port) && SOC_IS_XGS_SWITCH(unit)) { 2128 if (SOC_IS_FBX(unit)) { 2129 #ifdef BCM_FIREBOLT_SUPPORT 2130 port_tab_entry_t pte; 2131 int hg_port; 2132 uint32 config = 0; 2133 2134 2135 if (soc_mem_field_valid(unit, PORT_TABm, MY_MODIDf)) { 2136 PBMP_ST_ITER(unit, hg_port) { 2137 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, 2138 MEM_BLOCK_ANY, hg_port, &pte)); 2139 soc_PORT_TABm_field32_set(unit, &pte, MY_MODIDf, 2140 ipic_my_modid); 2141 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, 2142 MEM_BLOCK_ALL, hg_port, &pte)); 2143 } 2144 } else if (soc_reg_field_valid(unit, XPORT_CONFIGr, MY_MODIDf)) { 2145 PBMP_ST_ITER(unit, hg_port) { 2146 if (SOC_REG_PORT_VALID(unit, XPORT_CONFIGr, hg_port )) { 2147 BCM_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, hg_port, 2148 &config)); 2149 soc_reg_field_set(unit, XPORT_CONFIGr, &config, 2150 MY_MODIDf, ipic_my_modid); 2151 BCM_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, 2152 hg_port, config)); 2153 } 2154 } 2155 } 2156 #endif /* BCM_FIREBOLT_SUPPORT */ 2157 } 2158 } 2159 #endif /* BCM_ESW_SUPPORT */ 2160 pix++; 2161 } 2162 2163 assert(pix == port_count); 2164 if (forward) { 2165 /* Close loop */ 2166 f_info[pix - 1].to_port = f_info[0].this_port; 2167 f_info[pix - 1].dst_modid = f_info[0].src_modid; 2168 f_info[pix - 1].valid_info = close_loop; 2169 2170 /* Record CPU redirect */ 2171 f_info[pix].this_port = f_info[pix - 1].this_port; 2172 f_info[pix].added_vlan = f_info[pix - 1].added_vlan; 2173 f_info[pix].src_modid = f_info[pix - 1].src_modid; 2174 ENET_SET_MACADDR(f_info[pix].src_mac, f_info[pix - 1].src_mac); 2175 ENET_SET_MACADDR(f_info[pix].dst_mac, f_info[pix - 1].dst_mac); 2176 f_info[pix].to_port = CMIC_PORT(unit); 2177 f_info[pix].dst_modid = modid; 2178 f_info[pix].valid_info = TRUE; 2179 } 2180 if (reverse) { 2181 /* Close loop */ 2182 r_info[pix - 1].this_port = r_info[0].to_port; 2183 r_info[pix - 1].added_vlan = 2184 lp->vlan + r_info[pix - 1].this_port + 1; 2185 r_info[pix - 1].src_modid = r_info[0].dst_modid; 2186 r_info[pix - 1].valid_info = close_loop; 2187 2188 /* Record CPU redirect */ 2189 r_info[pix].this_port = r_info[pix - 1].this_port; 2190 r_info[pix].added_vlan = r_info[pix - 1].added_vlan; 2191 r_info[pix].src_modid = r_info[pix - 1].src_modid; 2192 ENET_SET_MACADDR(r_info[pix].src_mac, r_info[pix - 1].src_mac); 2193 ENET_SET_MACADDR(r_info[pix].dst_mac, r_info[pix - 1].dst_mac); 2194 r_info[pix].to_port = CMIC_PORT(unit); 2195 r_info[pix].dst_modid = modid; 2196 r_info[pix].valid_info = TRUE; 2197 } 2198 2199 /* If not closing loop, install the CPU return path also. */ 2200 install_count = port_count + (close_loop ? 0 : 1); 2201 2202 for (pix = 0; pix < install_count; pix++) { 2203 if (forward) { 2204 if ((rv = lbu_connect_ports(unit, &f_info[pix], TRUE)) < 0 ) { 2205 return rv; 2206 } 2207 } 2208 if (reverse) { 2209 if ((rv = lbu_connect_ports(unit, &r_info[pix], TRUE)) < 0 ) { 2210 return rv; 2211 } 2212 } 2213 } 2214 2215 return 0; 2216 } 2217 2218 int 2219 lbu_snake_done(loopback2_test_t *lw) 2220 /* 2221 * Function: lbu_snake_done 2222 * Purpose: Link adjacent ports to forward packets. 2223 * Parameters: lw - pointer to current work structure. 2224 * Returns: 0 - OK 2225 * -1 - failed. 2226 */ 2227 { 2228 int unit = lw->unit; 2229 int pix, rv; 2230 lb2s_port_connect_t *f_info, *r_info; 2231 2232 f_info = lw->port_cnct_f; 2233 r_info = lw->port_cnct_r; 2234 for (pix = 0; pix < lw->port_count; pix++) { 2235 if (f_info) { 2236 if ((rv = lbu_connect_ports(unit, &f_info[pix], FALSE)) < 0 ) { 2237 return rv; 2238 } 2239 } 2240 if (r_info) { 2241 if ((rv = lbu_connect_ports(unit, &r_info[pix], FALSE)) < 0 ) { 2242 return rv; 2243 } 2244 } 2245 } 2246 2247 if (lw->port_cnct_f) { 2248 sal_free(lw->port_cnct_f); 2249 } 2250 lw->port_cnct_f = NULL; 2251 if (lw->port_cnct_r) { 2252 sal_free(lw->port_cnct_r); 2253 } 2254 lw->port_cnct_r = NULL; 2255 if (lw->tx_pkt_match) { 2256 sal_free(lw->tx_pkt_match); 2257 } 2258 lw->tx_pkt_match = NULL; 2259 2260 return 0; 2261 } 2262 2263 2264 /* These values are used to keep the number of packets per test within the 2265 * limits that the MMU COS settings can handle. */ 2266 static int _lb_ppte_initval(int unit, int *lene, int *ppte) 2267 { 2268 int max_cells, num_cells, num_ports, num_cos, mmu_cell_size; 2269 int len = *lene; 2270 #if defined(BCM_HERCULES_SUPPORT) 2271 int port = 0, cos = 0; 2272 uint32 num_cells_per_port_cos = 0; 2273 #endif 2274 int ppte_max = SOC_DV_PKTS_MAX; 2275 2276 2277 *ppte = ppte_max; 2278 2279 if (SOC_IS_XGS_SWITCH(unit) || SOC_IS_XGS12_FABRIC(unit)) { 2280 /* Check that we don't overload the MMU HOL cell limits */ 2281 /* (This should be from #defines somewhere else) */ 2282 mmu_cell_size = 128; 2283 BCM_IF_ERROR_RETURN(bcm_cosq_config_get(unit, &num_cos)); 2284 max_cells = (len + mmu_cell_size - 1) / mmu_cell_size; 2285 #if defined(BCM_FIREBOLT_SUPPORT) 2286 if (SOC_IS_FBX(unit) && !SOC_IS_KATANAX(unit)) { 2287 #ifdef BCM_TOMAHAWK3_SUPPORT 2288 if (SOC_IS_TOMAHAWK3(unit)) { 2289 num_cells = _TH3_MMU_TOTAL_CELLS_PER_ITM; 2290 } else 2291 #endif 2292 { 2293 num_cells = soc_mem_index_count(unit, MMU_CBPDATA0m); 2294 } 2295 } else 2296 #endif /* BCM_FIREBOLT_SUPPORT */ 2297 { 2298 num_cells = 8192; 2299 } 2300 num_ports = NUM_ALL_PORT(unit); 2301 *ppte = (num_cells / (num_cos * num_ports * max_cells)) - 1; 2302 2303 #if defined(BCM_HERCULES_SUPPORT) 2304 if (SOC_IS_HERCULES(unit)) { 2305 /* look at what is configured for any port/cos 0,0 */ 2306 SOC_IF_ERROR_RETURN(READ_MMU_CELLLMTCOS_LOWERr(unit, port, cos, 2307 &num_cells_per_port_cos)); 2308 /* overwrite ppte */ 2309 *ppte = (num_cells_per_port_cos / max_cells) - 1; 2310 } 2311 #endif /* BCM_HERCULES_SUPPORT */ 2312 2313 if (*ppte < 1) { 2314 *ppte = 1; 2315 } 2316 if (*ppte > ppte_max) { 2317 *ppte = ppte_max; 2318 } 2319 /* 2320 * Number of cells allocated to this port 2321 * Assume DYNCELL_PERCENT 50 2322 */ 2323 len = num_cells / num_ports / 2; 2324 2325 /* 2326 * Number of cells usable by a cos queue 2327 */ 2328 len += (len / num_cos); 2329 /* 2330 * Max packet size supported 2331 */ 2332 len *= mmu_cell_size; 2333 if (*lene > len) { 2334 *lene = len; 2335 } 2336 } 2337 return(SOC_E_NONE); 2338 } 2339 2340 int 2341 lbu_check_parms(loopback2_test_t *lw, loopback2_testdata_t *lp) 2342 /* 2343 * Function: lbu_check_parms 2344 * Purpose: Check parameters for reasonable values. 2345 * Parameters: lw - pointer to current work structure. 2346 * Returns: 0 - OK 2347 * -1 - failed. 2348 */ 2349 { 2350 int nLen, nCOS, nPort; 2351 int unit = lw->unit; 2352 pbmp_t pbm; 2353 char pfmt[SOC_PBMP_FMT_LEN]; 2354 int max_pkt; 2355 int max_adj = 0; 2356 int jumbo_adj = 0; 2357 int num_ports, num_cos; 2358 int ppt_max = SOC_DV_PKTS_MAX; 2359 #ifdef BCM_ESW_SUPPORT 2360 int max_set; 2361 bcm_port_t port; 2362 #endif 2363 2364 if (lp->len_start < 64) { 2365 test_error(unit, "Packet start length %d too small\n", lp->len_start); 2366 return(-1); 2367 } 2368 2369 /* 2370 * Adjust FE_MAXFr, MAXFRr, and GTH_MAXFr as necessary, to 2371 * accommodate requested packet size. 2372 */ 2373 max_pkt = lp->len_start; 2374 2375 if (max_pkt < lp->len_end) { 2376 max_pkt = lp->len_end; 2377 } 2378 2379 if (max_pkt > LB_JUMBO_MAXSZ) { 2380 max_pkt = LB_JUMBO_MAXSZ; 2381 } 2382 2383 if (lp->ppt_start > ppt_max || lp->ppt_end > ppt_max) { 2384 test_error(unit, "Too many packets per trial (%d, %d). Max is %d.\n", 2385 lp->ppt_start, lp->ppt_end, ppt_max); 2386 lp->ppt_end = lp->ppt_start = ppt_max; 2387 return -1; 2388 } 2389 #ifdef BCM_ESW_SUPPORT 2390 { 2391 BCM_PBMP_ASSIGN(pbm, PBMP_E_ALL(unit)); 2392 BCM_PBMP_AND(pbm, lp->pbm); 2393 BCM_PBMP_ITER(pbm, port) { 2394 BCM_IF_ERROR_RETURN 2395 (bcm_port_frame_max_get(unit, port, &max_set)); 2396 if (max_set < max_pkt) { 2397 BCM_IF_ERROR_RETURN 2398 (bcm_port_frame_max_set(unit, port, max_pkt)); 2399 max_adj = 1; 2400 } 2401 } 2402 2403 BCM_PBMP_ASSIGN(pbm, PBMP_GE_ALL(unit)); 2404 BCM_PBMP_AND(pbm, lp->pbm); 2405 PBMP_ITER(pbm, port) { 2406 if (max_pkt > 1536) { 2407 if (soc_feature(unit, soc_feature_trimac)) { 2408 uint32 gmacc1; 2409 2410 SOC_IF_ERROR_RETURN 2411 (READ_GMACC1r(unit, port, &gmacc1)); 2412 2413 if (! soc_reg_field_get(unit, GMACC1r, gmacc1, JUMBOf)) { 2414 soc_reg_field_set(unit, GMACC1r, &gmacc1, JUMBOf, 1); 2415 SOC_IF_ERROR_RETURN 2416 (WRITE_GMACC1r(unit, port, gmacc1)); 2417 jumbo_adj = 1; 2418 } 2419 } 2420 #if defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 2421 else if (soc_feature(unit, soc_feature_unimac)) { 2422 SOC_IF_ERROR_RETURN(WRITE_FRM_LENGTHr(unit, port, LB_JUMBO_MAXSZ)); 2423 } 2424 #endif 2425 } 2426 } 2427 } 2428 #endif 2429 2430 if (max_adj) { 2431 cli_out("NOTICE: Increased max frame size for %d-byte packets\n", 2432 max_pkt); 2433 } 2434 2435 if (jumbo_adj) { 2436 cli_out("NOTICE: Enabled JUMBO frames on GE\n"); 2437 } 2438 2439 if (lp->len_inc <= 0) { 2440 test_error(unit, "Increments must be > 0\n"); 2441 return(-1); 2442 } 2443 2444 if (SOC_IS_XGS(unit) && (lp->test_type == LB2_TT_SNAKE)) { 2445 if (lp->d_mod_inc <= 0) { 2446 test_error(unit, "Module increments must be > 0\n"); 2447 return(-1); 2448 } 2449 } 2450 2451 BCM_PBMP_ASSIGN(pbm, lp->pbm); 2452 BCM_PBMP_REMOVE(pbm, PBMP_PORT_ALL(unit)); 2453 if (BCM_PBMP_NOT_NULL(pbm)) { 2454 test_error(unit, 2455 "Invalid bits in port bitmap.\n" 2456 "Allowable ports are %s\n", 2457 SOC_PBMP_FMT(PBMP_PORT_ALL(unit), pfmt)); 2458 return(-1); 2459 } 2460 2461 if (lp->cos_start < 0 || 2462 lp->cos_end < lp->cos_start || 2463 lp->cos_end >= NUM_COS(unit)) { 2464 test_error(unit, 2465 "Invalid COS values: start=%d end=%d\n", 2466 lp->cos_start, lp->cos_end); 2467 return(-1); 2468 } 2469 2470 if (lp->check_crc) { 2471 if (lp->crc_mode == LB2_CRC_MODE_CPU_NONE) { 2472 test_error(unit, "Can't check CRC if not generating it\n"); 2473 return(-1); 2474 } 2475 if (lp->loopback == LB2_MODE_MAC) { 2476 /* CRC not generated in MAC loopback */ 2477 test_error(unit, "Can't check CRC (not generated in MAC loopback mode)\n"); 2478 return(-1); 2479 } 2480 } 2481 2482 nLen = (lp->len_end - lp->len_start) / lp->len_inc + 1; 2483 nCOS = (lp->cos_end - lp->cos_start) / 1 + 1; 2484 BCM_PBMP_COUNT(lp->pbm, nPort); 2485 2486 if (lp->test_type == LB2_TT_EXT) { 2487 assert(nPort % 2 == 0); 2488 nPort /= 2; 2489 } 2490 2491 BCM_PBMP_ASSIGN(pbm, lp->pbm); 2492 BCM_PBMP_AND(pbm, PBMP_HG_ALL(unit)); 2493 2494 /* 2495 * Packet accumulaion and discard possible due to speed mismatch. 2496 * Check if MMU bufering is capable of absorbing this. 2497 */ 2498 if (SOC_IS_XGS_SWITCH(unit) && 2499 ((lp->speed == LB_SPEED_10FD) || 2500 (SOC_IS_RAPTOR(unit)) || 2501 BCM_PBMP_NOT_NULL(pbm))) { 2502 int ppte; 2503 int lene = lp->len_end; 2504 /* Check that we don't overload the MMU HOL cell limits */ 2505 BCM_IF_ERROR_RETURN(bcm_cosq_config_get(unit, &num_cos)); 2506 num_ports = NUM_ALL_PORT(unit); 2507 SOC_IF_ERROR_RETURN(_lb_ppte_initval(unit, &lene, &ppte)); 2508 if (lp->len_end > lene) { 2509 test_error(unit, 2510 "Packet length (%d) too Large. Try (%d)\n" 2511 "\twith current configuration of %d COS, %d ports.\n", 2512 lp->len_end, lene, num_cos, num_ports); 2513 return (-1); 2514 } 2515 if ((lp->ppt_end > ppte) && 2516 ((lp->speed == LB_SPEED_100FD) || 2517 (lp->speed == LB_SPEED_10FD))) { 2518 test_error(unit, 2519 "Too many packets per chain (%d) for maximum length: %d\n" 2520 "\twith current configuration of %d COS, %d ports.\n", 2521 lp->ppt_end, lp->len_end, num_cos, num_ports); 2522 return (-1); 2523 } 2524 } 2525 2526 if (lp->test_type == LB2_TT_SNAKE) { 2527 int icnt, pkt; 2528 lw->tx_total = 0; 2529 pkt = lp->ppt_start; 2530 for (icnt = 0; icnt < lp->iterations; icnt++ ) { 2531 lw->tx_total += pkt; 2532 2533 if ( lp->ppt_end != lp->ppt_start ) { 2534 pkt += lp->ppt_inc; 2535 while ( pkt > lp->ppt_end ) { 2536 pkt -= lp->ppt_end - lp->ppt_start; 2537 } 2538 } 2539 } 2540 test_msg("LB: total %d pkt over %d runs\n", 2541 lw->tx_total, lp->iterations); 2542 } else { 2543 int ppt, nPkt = 0; 2544 2545 /* Count up total number of pkts per run */ 2546 for (ppt = lp->ppt_start; ppt <= lp->ppt_end; ppt += lp->ppt_inc) { 2547 nPkt += ppt; 2548 } 2549 lw->tx_total = nLen * nCOS * nPort * nPkt * lp->iterations; 2550 test_msg("LB: total %d pkt (%d len " 2551 "* %d COS * %d port * %d packets * %d count)\n", 2552 lw->tx_total, 2553 nLen, nCOS, nPort, nPkt, lp->iterations); 2554 } 2555 2556 #ifdef BCM_TOMAHAWK_SUPPORT 2557 if (!SOC_IS_TOMAHAWKX(unit) && lp->line_rate){ 2558 test_error(unit, 2559 "Line rate snake test is only supported on TH/TH2\n"); 2560 lp->line_rate = 0; 2561 lp->line_rate_count = 1; 2562 return (-1); 2563 } 2564 if (SOC_IS_TOMAHAWKX(unit) && lp->line_rate && SOC_INFO(unit).mmu_lossless){ 2565 test_error(unit, "Line rate snake test is not supported when mmu_lossless = 1\n"); 2566 lp->line_rate = 0; 2567 lp->line_rate_count = 1; 2568 return (-1); 2569 } 2570 #endif 2571 2572 return(0); 2573 } 2574 2575 /* 2576 * Loopback Statistics Report 2577 */ 2578 2579 void 2580 lbu_stats_init(loopback2_test_t *lw) 2581 { 2582 lw->tx_count = 0; 2583 lw->rx_count = 0; 2584 2585 lw->tx_bytes = 0; 2586 lw->rx_bytes = 0; 2587 2588 lw->tx_stime = sal_time(); 2589 lw->tx_rtime = lw->tx_stime + sh_set_report_time; 2590 2591 lw->stats_init = TRUE; 2592 } 2593 2594 STATIC void 2595 lbu_stats_report(loopback2_test_t *lw) 2596 { 2597 sal_time_t now; 2598 int secs; 2599 2600 if (!sh_set_report_status) { 2601 return; 2602 } 2603 2604 /* 2605 * Feel free to call this routine after every packet sent. 2606 * It will only report stats every "sh_set_report_time" seconds. 2607 */ 2608 2609 now = sal_time(); 2610 2611 if ((secs = (now - lw->tx_stime)) == 0) { 2612 secs = 1; 2613 } 2614 2615 if (now >= lw->tx_rtime) { 2616 test_msg("LB: xmit %d pkt (%d%%, %d pkt/s, %d KB/s avg), " 2617 "recv %d pkt (%d sec)\n", lw->tx_count, 2618 100 * lw->rx_count / lw->tx_total, 2619 lw->tx_count / secs, 2620 lw->tx_bytes / 1024 / secs, 2621 lw->rx_count, secs); 2622 2623 lw->tx_rtime += sh_set_report_time; 2624 } 2625 } 2626 2627 void 2628 lbu_stats_done(loopback2_test_t *lw) 2629 { 2630 if (lw->stats_init && lw->tx_count > 0) { 2631 lw->tx_rtime = 0; /* Force output now */ 2632 lbu_stats_report(lw); 2633 } 2634 } 2635 2636 2637 /* 2638 * Print bytes as %d,%2.2fK, %2.2fG, etc. 2639 */ 2640 static void 2641 snake_show_number(uint64 size) 2642 { 2643 uint32 value; 2644 char *s; 2645 2646 s = _shr_scale_uint64(size, 1024, 100, &value); 2647 if (s) { 2648 cli_out("%d.%02d%s", value / 100, value % 100, s); 2649 } else { 2650 value = COMPILER_64_LO(size); 2651 cli_out("%d", value); 2652 } 2653 } 2654 2655 /* 2656 * Print rate as %d,%2.2fG, etc. 2657 */ 2658 static void 2659 snake_show_rate(uint32 size) 2660 { 2661 uint64 size64; 2662 uint32 value; 2663 char *s; 2664 2665 COMPILER_64_SET(size64, 0, size); 2666 s = _shr_scale_uint64(size64, 1024, 100, &value); 2667 if (s) { 2668 cli_out("%d.%02d%s", value / 100, value % 100, s); 2669 } else { 2670 cli_out("%d", size); 2671 } 2672 } 2673 2674 int 2675 lbu_snake_stats(int unit, bcm_pbmp_t sel_pbm, int lb_mode, 2676 lb2_port_stat_t *stats) 2677 /* 2678 * Function: lbu_snake_stats 2679 * Purpose: Check error/pkt stats during run to see if packets still 2680 * running smoothly. Notify if not. 2681 * Most of this routine is blantanly stolen from the 2682 * traffic test. 2683 * Parameters: unit - device number. 2684 * sel_pbm - port bitmap of selected ports. 2685 * mac_lb - (BOOL) TRUE if MAC loopback mode. 2686 * stats - pointer to stats records. 2687 * Returns: 0 - success, -1 error detected. 2688 */ 2689 { 2690 int port; 2691 int port_error, error = 0; 2692 int stopped; 2693 pbmp_t pbm; 2694 uint32 tolerance; 2695 2696 uint64 rbyt, tbyt, rpkt, tpkt, rerr,raln, rdisc, dropped; 2697 uint64 drbyt, dtbyt, drpkt, dtpkt, drerr, draln, drdisc, ddropped; 2698 2699 COMPILER_64_ZERO(rbyt); COMPILER_REFERENCE(&rbyt); 2700 COMPILER_64_ZERO(tbyt); COMPILER_REFERENCE(&tbyt); 2701 COMPILER_64_ZERO(rpkt); COMPILER_REFERENCE(&rpkt); 2702 COMPILER_64_ZERO(tpkt); COMPILER_REFERENCE(&tpkt); 2703 COMPILER_64_ZERO(rerr); COMPILER_REFERENCE(&rerr); 2704 COMPILER_64_ZERO(raln); COMPILER_REFERENCE(&raln); 2705 COMPILER_64_ZERO(rdisc); COMPILER_REFERENCE(&rdisc); 2706 COMPILER_64_ZERO(dropped); COMPILER_REFERENCE(&dropped); 2707 COMPILER_64_ZERO(drbyt); COMPILER_REFERENCE(&drbyt); 2708 COMPILER_64_ZERO(dtbyt); COMPILER_REFERENCE(&dtbyt); 2709 COMPILER_64_ZERO(drpkt); COMPILER_REFERENCE(&drpkt); 2710 COMPILER_64_ZERO(dtpkt); COMPILER_REFERENCE(&dtpkt); 2711 COMPILER_64_ZERO(drerr); COMPILER_REFERENCE(&drerr); 2712 COMPILER_64_ZERO(draln); COMPILER_REFERENCE(&draln); 2713 COMPILER_64_ZERO(drdisc); COMPILER_REFERENCE(&drdisc); 2714 COMPILER_64_ZERO(ddropped);COMPILER_REFERENCE(&ddropped); 2715 2716 bcm_stat_sync(unit); 2717 2718 PBMP_ITER(sel_pbm, port) { 2719 /* 2720 * To account for counters such as IRDISC 2721 */ 2722 tolerance = IS_HG_PORT(unit, port) ? 1 : 0; 2723 port_error = 0; 2724 stopped = 0; 2725 2726 bcm_stat_get(unit, port, snmpIfInOctets, &rbyt); 2727 bcm_stat_get(unit, port, snmpIfOutOctets,&tbyt); 2728 bcm_stat_get(unit, port, snmpDot1dTpPortOutFrames, &tpkt); 2729 bcm_stat_get(unit, port, snmpDot1dTpPortInFrames, &rpkt); 2730 bcm_stat_get(unit, port, snmpDot3StatsAlignmentErrors, 2731 &raln); 2732 bcm_stat_get(unit, port, 2733 snmpDot3StatsInternalMacReceiveErrors, &rdisc); 2734 bcm_stat_get(unit, port, snmpIfInDiscards, &dropped); 2735 2736 if (!stats[port].initialized) { 2737 stats[port].rbyt = rbyt; 2738 stats[port].tbyt = tbyt; 2739 stats[port].rpkt = rpkt; 2740 stats[port].tpkt = tpkt; 2741 2742 stats[port].raln = raln; 2743 stats[port].rdisc = rdisc; 2744 stats[port].dropped = dropped; 2745 stats[port].error = 0; 2746 #ifdef BCM_TOMAHAWK_SUPPORT 2747 COMPILER_64_ZERO(stats[port].rate); 2748 #endif 2749 stats[port].initialized = TRUE; 2750 } else { 2751 int speed, duplex; 2752 uint32 dtpktl, dtbytl, drpktl, drbytl; 2753 uint32 dralnl, drdiscl, ddroppedl; 2754 2755 COMPILER_64_DELTA(drbyt, stats[port].rbyt, rbyt); 2756 COMPILER_64_DELTA(dtbyt, stats[port].tbyt, tbyt); 2757 COMPILER_64_DELTA(drpkt, stats[port].rpkt, rpkt); 2758 COMPILER_64_DELTA(dtpkt, stats[port].tpkt, tpkt); 2759 COMPILER_64_DELTA(draln, stats[port].raln, raln); 2760 COMPILER_64_DELTA(drdisc, stats[port].rdisc, 2761 rdisc); 2762 COMPILER_64_DELTA(ddropped, stats[port].dropped, 2763 dropped); 2764 2765 COMPILER_64_TO_32_LO(drbytl, drbyt); 2766 COMPILER_64_TO_32_LO(dtbytl, dtbyt); 2767 COMPILER_64_TO_32_LO(drpktl, drpkt); 2768 COMPILER_64_TO_32_LO(dtpktl, dtpkt); 2769 COMPILER_64_TO_32_LO(dralnl, draln); 2770 COMPILER_64_TO_32_LO(drdiscl, drdisc); 2771 COMPILER_64_TO_32_LO(ddroppedl, ddropped); 2772 2773 switch (lb_mode) { 2774 case LB2_MODE_MAC: 2775 if (dtpktl == 0 || dtbytl == 0 || 2776 ((drpktl == 0 || drbytl == 0) && 2777 (IS_FE_PORT(unit, port) || IS_GE_PORT(unit, port)))) { 2778 stopped = -1; 2779 } 2780 break; 2781 case LB2_MODE_PHY: 2782 if (dtpktl == 0 || dtbytl == 0 || 2783 drpktl == 0 || drbytl == 0) { 2784 stopped = -1; 2785 } 2786 break; 2787 case LB2_MODE_EXT: 2788 /* Don't check for stopped yet */ 2789 break; 2790 default: 2791 assert(0); 2792 } 2793 2794 if ((drdiscl > tolerance) || (ddroppedl > 0) || 2795 (stopped < 0) || 2796 ((dralnl > tolerance) && 2797 (IS_FE_PORT(unit, port) || IS_GE_PORT(unit, port)))) { 2798 port_error = -1; 2799 error = -1; 2800 } 2801 2802 bcm_port_speed_get(unit, port, &speed); 2803 bcm_port_duplex_get(unit, port, &duplex); 2804 2805 if (port_error < 0) { 2806 cli_out("Port %s (%d) (", 2807 SOC_PORT_NAME(unit, port), port); 2808 snake_show_rate(speed * 1000000); 2809 cli_out("b %s): ", 2810 duplex ? "FD" : "HD"); 2811 if ((dralnl > tolerance) && 2812 (IS_FE_PORT(unit, port) || IS_GE_PORT(unit, port))) { 2813 cli_out("ALN Error Detected\n"); 2814 } else if (drdiscl > tolerance) { 2815 cli_out("Discard Error Detected\n"); 2816 } else if (ddroppedl > 0) { 2817 cli_out("Dropped Error Detected\n"); 2818 } else if (stopped < 0) { 2819 cli_out("FAIL->NO TRAFFIC\n"); 2820 } else { 2821 cli_out("PASSED\n"); 2822 } 2823 2824 cli_out("\tTX packets "); 2825 snake_show_number(tpkt); 2826 cli_out(" +"); 2827 snake_show_number(dtpkt); 2828 cli_out("/s, bytes "); 2829 snake_show_number(tbyt); 2830 cli_out("B +"); 2831 snake_show_number(dtbyt); 2832 cli_out("B/s ["); 2833 snake_show_rate(dtbytl*8); 2834 cli_out("b/s]\n"); 2835 cli_out("\tRX packets "); 2836 snake_show_number(rpkt); 2837 cli_out(" +"); 2838 snake_show_number(drpkt); 2839 cli_out("/s, bytes "); 2840 snake_show_number(rbyt); 2841 cli_out("B +"); 2842 snake_show_number(drbyt); 2843 cli_out("B/s ["); 2844 snake_show_rate(drbytl*8); 2845 cli_out("b/s]\n"); 2846 } 2847 2848 /* Zero packet rate increase indicates failure */ 2849 2850 if (stopped < 0) { 2851 test_error(unit, 2852 "ERROR: traffic stopped on port %s (%d)\n", 2853 SOC_PORT_NAME(unit, port), port); 2854 2855 /* Give us a clue .. */ 2856 cli_out("Port %s (%d) statistics:\n", 2857 SOC_PORT_NAME(unit, port), port); 2858 SOC_PBMP_CLEAR(pbm); 2859 SOC_PBMP_PORT_ADD(pbm, port); 2860 if (SOC_IS_ESW(unit)) { 2861 #ifdef BCM_ESW_SUPPORT 2862 do_show_counters(unit, 2863 INVALIDr, 2864 pbm, 2865 SHOW_CTR_CHANGED| 2866 SHOW_CTR_SAME| 2867 SHOW_CTR_NZ); 2868 #endif 2869 } else { 2870 } 2871 } 2872 2873 stats[port].rbyt = rbyt; 2874 stats[port].tbyt = tbyt; 2875 stats[port].rpkt = rpkt; 2876 stats[port].tpkt = tpkt; 2877 2878 stats[port].raln = raln; 2879 stats[port].rdisc = rdisc; 2880 stats[port].dropped = dropped; 2881 stats[port].error = port_error; 2882 } 2883 } 2884 2885 return error; 2886 } 2887 2888 STATIC int 2889 lbu_snake_diag(loopback2_test_t *lw, lb2_port_stat_t *stats, 2890 lb2s_port_connect_t *connect_info) 2891 /* 2892 * Function: lbu_snake_diag 2893 * Purpose: Attempt to determing snake failure cause 2894 * Parameters: lw - pointer to lb work. 2895 * stats - pointer to port statistics. 2896 * connect_info - port interlink data. 2897 * Returns: 0 - success, -1 failed. 2898 */ 2899 { 2900 loopback2_testdata_t *lp = lw->cur_params; 2901 int unit = lw->unit; 2902 soc_port_t thisPort, toPort; 2903 int ix, rv = 0; 2904 uint32 tempStat, tolerance = 0; 2905 uint64 tempDiff; 2906 2907 COMPILER_64_ZERO(tempDiff); 2908 2909 for (ix = 0; ix < lw->port_count; ix++) { 2910 thisPort = connect_info[ix].this_port; 2911 toPort = connect_info[ix].to_port; 2912 2913 COMPILER_64_TO_32_LO(tempStat, stats[thisPort].tpkt); 2914 LOG_INFO(BSL_LS_APPL_TESTS, 2915 (BSL_META_U(unit, 2916 "Port %s Tx Count = 0x%x\n"), 2917 SOC_PORT_NAME(unit, thisPort), tempStat)); 2918 2919 if (tempStat == 0) { 2920 test_error(unit, "Port %s failed to send packets\n", 2921 SOC_PORT_NAME(unit, thisPort)); 2922 rv = -1; 2923 } 2924 2925 /* BigMac receive counters don't work in MAC loopback */ 2926 if (((IS_FE_PORT(unit, thisPort) || IS_GE_PORT(unit, thisPort)) && 2927 (lp->loopback == LB2_MODE_MAC))) { 2928 COMPILER_64_TO_32_LO(tempStat, stats[thisPort].rpkt); 2929 LOG_INFO(BSL_LS_APPL_TESTS, 2930 (BSL_META_U(unit, 2931 "Port %s Rx Count = 0x%x\n"), 2932 SOC_PORT_NAME(unit, thisPort), tempStat)); 2933 2934 if (tempStat == 0) { 2935 test_error(unit, "Port %s failed to receive packets\n", 2936 SOC_PORT_NAME(unit, thisPort)); 2937 rv = -1; 2938 } 2939 2940 COMPILER_64_DELTA(tempDiff, stats[thisPort].rpkt, 2941 stats[thisPort].tpkt); 2942 COMPILER_64_TO_32_LO(tempStat, tempDiff); 2943 if ((tempStat > tolerance) && (tempStat < (~tolerance + 1))) { 2944 COMPILER_64_TO_32_LO(tempStat, stats[thisPort].tpkt); 2945 cli_out("\t0x%x packets transmitted by port %s\n", 2946 tempStat, SOC_PORT_NAME(unit, thisPort)); 2947 COMPILER_64_TO_32_LO(tempStat, stats[thisPort].rpkt); 2948 cli_out("\t0x%x packets received by port %s\n", 2949 tempStat, SOC_PORT_NAME(unit, thisPort)); 2950 test_error(unit, "Port %s loopback failure\n", 2951 SOC_PORT_NAME(unit, thisPort)); 2952 rv = -1; 2953 } 2954 } 2955 2956 /* BigMac receive counters don't work in MAC loopback */ 2957 if (((IS_FE_PORT(unit, toPort) || IS_GE_PORT(unit, toPort)) && 2958 (lp->loopback == LB2_MODE_MAC))) { 2959 COMPILER_64_DELTA(tempDiff, stats[toPort].tpkt, 2960 stats[toPort].rpkt); 2961 COMPILER_64_TO_32_LO(tempStat, tempDiff); 2962 2963 tolerance = (IS_HG_PORT(unit, toPort) || 2964 IS_HG_PORT(unit, thisPort)) ? 2965 lw->tx_ppt : 0; 2966 if ((tempStat > tolerance) && (tempStat < (~tolerance + 1))) { 2967 COMPILER_64_TO_32_LO(tempStat, stats[toPort].rpkt); 2968 cli_out("\t0x%x packets received by port %s\n", 2969 tempStat, SOC_PORT_NAME(unit, toPort)); 2970 COMPILER_64_TO_32_LO(tempStat, stats[thisPort].tpkt); 2971 cli_out("\t0x%x packets transmitted by port %s\n", 2972 tempStat, SOC_PORT_NAME(unit, thisPort)); 2973 test_error(unit, 2974 "Port %s failed to switch packets to port %s\n", 2975 SOC_PORT_NAME(unit, toPort), 2976 SOC_PORT_NAME(unit, thisPort)); 2977 rv = -1; 2978 } 2979 } 2980 2981 2982 } 2983 2984 return rv; 2985 } 2986 2987 void 2988 lbu_snake_dump_stats(int unit, bcm_pbmp_t sel_pbm, lb2_port_stat_t *stats) 2989 /* 2990 * Function: lbu_snake_dump_stats 2991 * Purpose: Display port stats for diagnosis purposes 2992 * Parameters: unit - device number. 2993 * sel_pbm - port bitmap of selected ports. 2994 * stats - pointer to stats records. 2995 */ 2996 { 2997 soc_port_t port; 2998 #ifdef BCM_TOMAHAWK_SUPPORT 2999 char buf_rate[32]; 3000 int commachr = soc_property_get(unit, spn_DIAG_COMMA, ','); 3001 #endif 3002 COMPILER_REFERENCE(unit); 3003 3004 PBMP_ITER(sel_pbm, port) { 3005 cli_out("Port %s", SOC_PORT_NAME(unit, port)); 3006 cli_out("\tTX "); 3007 snake_show_number(stats[port].tpkt); 3008 cli_out("pkt "); 3009 snake_show_number(stats[port].tbyt); 3010 cli_out("B,\tRX "); 3011 snake_show_number(stats[port].rpkt); 3012 cli_out("pkt "); 3013 snake_show_number(stats[port].rbyt); 3014 cli_out("B"); 3015 #ifdef BCM_TOMAHAWK_SUPPORT 3016 if (!COMPILER_64_IS_ZERO(stats[port].rate)){ 3017 format_uint64_decimal(buf_rate, stats[port].rate, commachr); 3018 cli_out(" Rate %16sB/s", buf_rate); 3019 } 3020 #endif 3021 cli_out("\n"); 3022 } 3023 } 3024 3025 3026 /* Set up the basic packet data that can vary with each transmit */ 3027 3028 STATIC void 3029 lbu_serial_higig_setup(int unit, loopback2_testdata_t *lp, bcm_pkt_t *pkt) 3030 { 3031 pkt->opcode = lp->opcode; 3032 pkt->dest_port = lp->d_port; 3033 pkt->dest_mod = lp->d_mod; 3034 bcm_tx_pkt_setup(unit, pkt); 3035 } 3036 3037 STATIC void 3038 lbu_snake_higig_setup(int unit, loopback2_testdata_t *lp, 3039 lb2s_port_connect_t *port_info, bcm_pkt_t *pkt) 3040 { 3041 pkt->opcode = lp->opcode; 3042 pkt->dest_port = port_info->to_port; 3043 pkt->dest_mod = port_info->dst_modid; 3044 bcm_tx_pkt_setup(unit, pkt); 3045 } 3046 3047 STATIC void 3048 lbu_pkt_data_setup(loopback2_test_t *lw, bcm_pkt_t *pkt, bcm_vlan_t vlan, 3049 sal_mac_addr_t mac_dst, sal_mac_addr_t mac_src, int seq_no) 3050 { 3051 loopback2_testdata_t *lp = lw->cur_params; 3052 enet_hdr_t *eh = NULL; 3053 int tx_len, payload_len; 3054 uint8 *sequence_p; 3055 int cur_offset; 3056 3057 tx_len = pkt->pkt_data[0].len; 3058 if (pkt->flags & BCM_TX_CRC_ALLOC) { 3059 payload_len = tx_len - 18; 3060 } else { 3061 payload_len = tx_len - 22; 3062 } 3063 3064 eh = (enet_hdr_t *)BCM_PKT_DMAC(pkt); 3065 3066 /* Write source/destination MAC address */ 3067 ENET_SET_MACADDR(&eh->en_dhost, mac_dst); 3068 ENET_SET_MACADDR(&eh->en_shost, mac_src); 3069 3070 /* Write VLAN tag (16 + 16 bits) and sequence number (32 bits) */ 3071 packet_store((uint8 *)&eh->en_tag_tpid, 2, 0x8100 << 16, 0); 3072 packet_store((uint8 *)&eh->en_tag_ctrl, 2, 3073 VLAN_CTRL(0, 0, vlan) << 16, 0); 3074 packet_store((uint8*)eh + 16, 4, lw->tx_seq++, 0); 3075 packet_store((uint8*)&eh->en_tag_len, 2, payload_len << 16, 0); 3076 3077 /* 3078 * Fill data from after header & seq # to end of packet. Byte data 3079 * starts with the pattern MSByte through LSByte and recycles. 3080 * Optionally overwrite last 4 bytes of packet with correct CRC. 3081 */ 3082 cur_offset = 20; 3083 lp->pattern = packet_store((uint8*)eh + cur_offset, tx_len - cur_offset, 3084 lp->pattern, lp->pattern_inc); 3085 3086 /* Store the sequence number of the packet */ 3087 sequence_p = (uint8 *)eh + LB2_ID_POS; 3088 *sequence_p = (uint8)seq_no; 3089 3090 if (lp->crc_mode == LB2_CRC_MODE_CPU_APPEND) { 3091 packet_store((uint8*)eh + tx_len - 4, 4, 3092 ~_shr_crc32(~0, (uint8*)eh, tx_len - 4), 0); 3093 } 3094 3095 if (SOC_IS_XGS12_FABRIC(lw->unit)) { 3096 if (lp->crc_mode == LB2_CRC_MODE_MAC_REGEN) { 3097 /* hercules always requires CRC field to be zero */ 3098 packet_store(((uint8*)eh + (tx_len) - 4), 4, 0, 0); 3099 } 3100 } 3101 } 3102 3103 /* 3104 * This routine is called by 3105 * The dest ports only need to be set up once */ 3106 3107 STATIC void 3108 lbu_pkt_init(bcm_pkt_t **pkts, int max_ppt, int tx_port, int tagged) 3109 { 3110 int i; 3111 bcm_pkt_t *pkt; 3112 3113 for (i = 0; i < max_ppt; i++) { 3114 pkt = pkts[i]; 3115 3116 SOC_PBMP_CLEAR(pkt->tx_pbmp); 3117 SOC_PBMP_PORT_ADD(pkt->tx_pbmp, tx_port); 3118 SOC_PBMP_CLEAR(pkt->tx_upbmp); 3119 if (!tagged) { 3120 SOC_PBMP_PORT_ADD(pkt->tx_upbmp, tx_port); 3121 } 3122 } 3123 } 3124 3125 /* Set up a chain of packets according to current settings */ 3126 3127 STATIC int 3128 lbu_pkt_chain_setup(bcm_pkt_t **pkts, int ppt, int len, int cos, 3129 loopback2_test_t *lw) 3130 { 3131 loopback2_testdata_t *lp = lw->cur_params; 3132 int i; 3133 sal_mac_addr_t cur_mac_dst, cur_mac_src; 3134 bcm_pkt_t *pkt; 3135 3136 /* Init the src/dest mac addresses each chain */ 3137 ENET_SET_MACADDR(cur_mac_dst, lw->base_mac_dst); 3138 ENET_SET_MACADDR(cur_mac_src, lw->base_mac_src); 3139 3140 for (i = 0; i < ppt; i++) { 3141 3142 pkt = pkts[i]; 3143 pkt->cos = cos; 3144 /* For now, internal priority matches COS (or v.v.) */ 3145 pkt->prio_int = cos; 3146 pkt->pkt_data[0].len = len; /* Set length properly for pkt */ 3147 3148 lbu_pkt_data_setup(lw, pkt, lp->vlan, cur_mac_dst, cur_mac_src, i); 3149 if (SOC_IS_XGS(lw->unit)) { 3150 lbu_serial_higig_setup(lw->unit, lp, pkt); 3151 } 3152 #ifdef BCM_XGS3_SWITCH_SUPPORT 3153 /* 3154 * Setup the Higig header for XGS3 devices 3155 */ 3156 if (SOC_IS_XGS3_SWITCH(lw->unit) && !(SOC_IS_TOMAHAWK3(lw->unit))) { 3157 int dmod; 3158 uint32 vlan; 3159 int unit = lw->unit; 3160 soc_higig_hdr_t *xgh = (soc_higig_hdr_t*)pkt->_higig; 3161 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_get(unit, &dmod)); 3162 if (SOC_IS_HAWKEYE(unit) || (SOC_IS_RAPTOR(unit) && IS_E_PORT(unit, lw->tx_port))) { 3163 } else { 3164 /* Fabric mapped mode TX */ 3165 pkt->flags |= (BCM_TX_ETHER | BCM_TX_HG_READY); 3166 } 3167 pkt->dest_mod = dmod; 3168 pkt->src_mod = dmod + 1; 3169 pkt->src_port = CMIC_PORT(unit); 3170 pkt->dest_port = lw->tx_port; 3171 if (IS_ST_PORT(unit, pkt->dest_port)) { 3172 pkt->opcode = 0; /* CPU control for HG ports */ 3173 } else { 3174 pkt->opcode = 1; /* UNICAST for E ports */ 3175 } 3176 sal_memset(xgh, 0, sizeof(pkt->_higig)); 3177 #ifdef BCM_HIGIG2_SUPPORT 3178 if (soc_feature(unit, soc_feature_higig2)) { 3179 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG2_START); 3180 } else { 3181 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG_START); 3182 } 3183 #else 3184 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG_START); 3185 #endif 3186 soc_higig_field_set(unit, xgh, HG_hgi, SOC_HIGIG_HGI); 3187 soc_higig_field_set(unit, xgh, HG_opcode, pkt->opcode); 3188 soc_higig_field_set(unit, xgh, HG_hdr_format, SOC_HIGIG_HDR_DEFAULT); 3189 vlan = BCM_PKT_VLAN_CONTROL(pkt); 3190 soc_higig_field_set(unit, xgh, HG_vlan_tag, vlan); 3191 soc_higig_field_set(unit, xgh, HG_dst_mod, pkt->dest_mod); 3192 soc_higig_field_set(unit, xgh, HG_dst_port, pkt->dest_port); 3193 soc_higig_field_set(unit, xgh, HG_src_mod, pkt->src_mod); 3194 soc_higig_field_set(unit, xgh, HG_src_port, pkt->src_port); 3195 soc_higig_field_set(unit, xgh, HG_cos, pkt->cos); 3196 soc_higig_field_set(unit, xgh, HG_ingress_tagged, 1); 3197 } 3198 #endif 3199 increment_macaddr(cur_mac_dst, lp->mac_dst_inc); 3200 increment_macaddr(cur_mac_src, lp->mac_src_inc); 3201 } 3202 3203 return BCM_E_NONE; 3204 } 3205 3206 /* Set up a chain of packets according to current settings */ 3207 3208 STATIC int 3209 lbu_snake_pkt_chain_setup(bcm_pkt_t **pkts, int ppt, int len, int cos, 3210 loopback2_test_t *lw) 3211 { 3212 loopback2_testdata_t *lp = lw->cur_params; 3213 int i; 3214 bcm_pkt_t *pkt; 3215 lb2s_port_connect_t *work_info, *f_info, *r_info; 3216 int snake_way = lp->snake_way; 3217 int forward, both; 3218 3219 both = (snake_way == LB2_SNAKE_BOTH); 3220 forward = (snake_way == LB2_SNAKE_BOTH) || (snake_way == LB2_SNAKE_INCR); 3221 3222 f_info = lw->port_cnct_f; 3223 r_info = lw->port_cnct_r; 3224 work_info = forward ? f_info : r_info; 3225 3226 for (i = 0; i < ppt; i++) { 3227 3228 pkt = pkts[i]; 3229 pkt->cos = cos; 3230 /* For now, internal priority matches COS (or v.v.) */ 3231 pkt->prio_int = cos; 3232 pkt->pkt_data[0].len = len; /* Set length properly for pkt */ 3233 SOC_PBMP_CLEAR(pkt->tx_pbmp); 3234 SOC_PBMP_PORT_ADD(pkt->tx_pbmp, work_info->this_port); 3235 SOC_PBMP_CLEAR(pkt->tx_upbmp); 3236 SOC_PBMP_PORT_ADD(pkt->tx_upbmp, work_info->this_port); 3237 3238 if (both) { 3239 work_info = (i % 2) ? r_info : f_info; 3240 } 3241 3242 lbu_pkt_data_setup(lw, pkt, work_info[lw->port_count].added_vlan, 3243 work_info->dst_mac, work_info->src_mac, i); 3244 if (SOC_IS_XGS(lw->unit)) { 3245 lbu_snake_higig_setup(lw->unit, lp, work_info, pkt); 3246 } 3247 #ifdef BCM_XGS3_SWITCH_SUPPORT 3248 /* 3249 * Setup the Higig header for XGS3 devices 3250 */ 3251 if (SOC_IS_XGS3_SWITCH(lw->unit) && 3252 !IS_ST_PORT(lw->unit, work_info->this_port) && 3253 !SOC_IS_TOMAHAWK3(lw->unit)) { 3254 int dmod; 3255 uint32 vlan; 3256 int unit = lw->unit; 3257 soc_higig_hdr_t *xgh = (soc_higig_hdr_t*)pkt->_higig; 3258 BCM_IF_ERROR_RETURN(bcm_stk_my_modid_get(unit, &dmod)); 3259 if (SOC_IS_HAWKEYE(unit) || (SOC_IS_RAPTOR(unit) && IS_E_PORT(unit, work_info->this_port))) { 3260 } else { 3261 /* Fabric mapped mode TX */ 3262 pkt->flags |= (BCM_TX_ETHER | BCM_TX_HG_READY); 3263 } 3264 pkt->src_mod = pkt->dest_mod = dmod; 3265 pkt->src_port = CMIC_PORT(unit); 3266 pkt->dest_port = work_info->this_port; 3267 pkt->opcode = lp->opcode; 3268 sal_memset(xgh, 0, sizeof(pkt->_higig)); 3269 #ifdef BCM_HIGIG2_SUPPORT 3270 if (SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit) || SOC_IS_TR_VL(unit)) { 3271 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG2_START); 3272 } else { 3273 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG_START); 3274 } 3275 #else 3276 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG_START); 3277 #endif 3278 soc_higig_field_set(unit, xgh, HG_hgi, SOC_HIGIG_HGI); 3279 soc_higig_field_set(unit, xgh, HG_opcode, pkt->opcode); 3280 soc_higig_field_set(unit, xgh, HG_hdr_format, SOC_HIGIG_HDR_DEFAULT); 3281 vlan = BCM_PKT_VLAN_CONTROL(pkt); 3282 soc_higig_field_set(unit, xgh, HG_vlan_tag, vlan); 3283 soc_higig_field_set(unit, xgh, HG_dst_mod, pkt->dest_mod); 3284 soc_higig_field_set(unit, xgh, HG_dst_port, pkt->dest_port); 3285 soc_higig_field_set(unit, xgh, HG_src_mod, pkt->src_mod); 3286 soc_higig_field_set(unit, xgh, HG_src_port, pkt->src_port); 3287 soc_higig_field_set(unit, xgh, HG_cos, pkt->cos); 3288 soc_higig_field_set(unit, xgh, HG_ingress_tagged, 1); 3289 } 3290 #endif 3291 } 3292 3293 return BCM_E_NONE; 3294 } 3295 3296 STATIC int 3297 lbu_send_packets(int unit, bcm_pkt_t **pkts, int ppt, loopback2_test_t *lw) 3298 { 3299 int rv = BCM_E_NONE, i; 3300 int try_cnt = 0; 3301 #ifdef BCM_TOMAHAWK_SUPPORT 3302 int j; 3303 #endif 3304 3305 lw->expect_pkts = TRUE; /* Let RX handler accept packets */ 3306 3307 switch (lw->cur_params->send_mech) { 3308 case LBD_SEND_SINGLE: 3309 #ifdef BCM_TOMAHAWK_SUPPORT 3310 if (!lw->cur_params->line_rate) { 3311 lw->cur_params->line_rate_count = 1; 3312 } 3313 for (j = 0; j < lw->cur_params->line_rate_count; j++) { 3314 #endif 3315 for (i = 0; i < ppt; i++ ) { 3316 /*Need try until the memor was free and then send next one*/ 3317 for (try_cnt = 50; try_cnt > 0; try_cnt--) { 3318 rv = bcm_tx(unit, pkts[i], NULL); 3319 if (rv == BCM_E_MEMORY) { 3320 sal_usleep(1); 3321 continue; 3322 } 3323 break; 3324 } 3325 3326 if (rv < 0) { 3327 cli_out("lbu_send_packets: ERROR: port%d: bcm_tx:%s\n", 3328 lw->tx_port, bcm_errmsg(rv)); 3329 } 3330 lw->tx_count++; 3331 lw->tx_bytes += lw->tx_len; 3332 } 3333 #ifdef BCM_TOMAHAWK_SUPPORT 3334 } 3335 #endif 3336 break; 3337 case LBD_SEND_ARRAY: 3338 if ((rv = bcm_tx_array(unit, pkts, ppt, NULL, NULL)) < 0) { 3339 cli_out("lbu_send_packets (array): ERROR: port %d; ppt %d; " 3340 "bcm_tx: %s\n", lw->tx_port, ppt, bcm_errmsg(rv)); 3341 } 3342 lw->tx_count += ppt; 3343 lw->tx_bytes += lw->tx_len * ppt; 3344 break; 3345 case LBD_SEND_LLIST: 3346 default: 3347 cli_out("lbu_send_packets: Unsupported send mechanism\n"); 3348 return BCM_E_UNAVAIL; 3349 break; 3350 } 3351 3352 return rv; 3353 } 3354 3355 STATIC int 3356 lbu_serial_wait(loopback2_test_t *lw) 3357 { 3358 int unit = lw->unit; 3359 int ix; 3360 bcm_pkt_t *next_rx; 3361 3362 if (sal_sem_take(lw->sema, lw->timeout_usec)) { 3363 cli_out("Time-out waiting for completion Tx(%s) Rx(%s)\n", 3364 SOC_PORT_NAME(unit, lw->tx_port), 3365 SOC_PORT_NAME(unit, lw->rx_port)); 3366 cli_out("Receive count is %d; expecting %d pkts.\n", 3367 lw->rx_pkt_cnt, lw->tx_ppt); 3368 lbu_stats_report(lw); 3369 lw->sema_woke = FALSE; 3370 return (-1); 3371 } 3372 3373 lw->sema_woke = FALSE; 3374 /* 3375 The reason for this change is some strange SW synchronization 3376 issue that is observed only on NSX CPU with Linux 2.6 OS 3377 Seems that an RX handler releases the semaphor but not all 3378 packets are updated in the SW structure. 3379 */ 3380 #if 0 3381 lw->expect_pkts = FALSE; /* Let RX handler ignore packets */ 3382 #endif 3383 3384 for (ix = 0; ix < lw->tx_ppt; ix++) { 3385 next_rx = LB2_RX_PKT(lw, ix); 3386 if (!next_rx->_pkt_data.data) { 3387 /* This change is intentional to avoid a strange miss 3388 synchronization on NSX CPU with Linux 2.6 OS */ 3389 ix--; 3390 continue; 3391 } 3392 if (lbu_packet_compare(lw, lw->tx_pkts[ix], next_rx) < 0) { 3393 cli_out("Compare error on packet %d in chain\n", ix); 3394 return (-1); 3395 } 3396 lw->rx_bytes += next_rx->pkt_len; 3397 lw->rx_count++; 3398 } 3399 3400 return 0; 3401 } 3402 3403 /* Dump TX packets on error */ 3404 STATIC void 3405 lbu_dump_tx_packets(loopback2_test_t *lw) 3406 { 3407 int ix; 3408 3409 cli_out("Transmitted packets\n"); 3410 for (ix = 0; ix < lw->tx_ppt; ix++) { 3411 cli_out("TX packet %d: len=%d\n", 3412 ix, lw->tx_pkts[ix]->_pkt_data.len); 3413 3414 #ifdef BCM_ESW_SUPPORT 3415 soc_dma_dump_pkt(lw->unit, " ", lw->tx_pkts[ix]->_pkt_data.data, 3416 lw->tx_pkts[ix]->_pkt_data.len, TRUE); 3417 #endif 3418 } 3419 } 3420 3421 /* Setup a chain of packets, tx it and wait for packets back */ 3422 STATIC int 3423 lbu_do_chain(int unit, int len, int ppt, int cos, int i, 3424 loopback2_test_t *lw) 3425 { 3426 loopback2_testdata_t *lp = lw->cur_params; 3427 int rv = BCM_E_NONE; 3428 3429 if ((rv = lbu_pkt_chain_setup(lw->tx_pkts, ppt, len, cos, lw)) < 0) { 3430 test_error(unit, "Could not setup chain\n\tPort TX(%s) RX(%s)\n" 3431 "\tPacket Length=%d bytes\n" 3432 "\tPPT=%d\n" 3433 "\tCurrent COS=%d\n" 3434 "\tIteration %d of %d\n", 3435 SOC_PORT_NAME(unit, lw->tx_port), 3436 SOC_PORT_NAME(unit, lw->rx_port), 3437 len, ppt, cos, i + 1, lp->iterations); 3438 return rv; 3439 } 3440 3441 if ((rv = lbu_send_packets(unit, lw->tx_pkts, ppt, lw)) < 0) { 3442 test_error(unit, "Packet TX failed: ERROR: %s\n", 3443 bcm_errmsg(rv)); 3444 lbu_dump_tx_packets(lw); 3445 return rv; 3446 } 3447 if (lp->inject) { /* Diagnostic */ 3448 return 0; 3449 } 3450 3451 if ((rv = lbu_serial_wait(lw)) < 0) { 3452 test_error(unit, "See error description\n\tPort TX(%s) RX(%s)\n" 3453 "\tPacket Length=%d bytes\n" 3454 "\tPPT=%d\n" 3455 "\tCurrent COS=%d\n" 3456 "\tIteration %d of %d\n", 3457 SOC_PORT_NAME(unit, lw->tx_port), 3458 SOC_PORT_NAME(unit, lw->rx_port), 3459 len, ppt, cos, i + 1, lp->iterations); 3460 lbu_dump_tx_packets(lw); 3461 return rv; 3462 } 3463 3464 lbu_stats_report(lw); 3465 CLEAR_RX_PKTS(lw, lp); 3466 3467 return 0; 3468 } 3469 3470 3471 int 3472 lbu_serial_txrx(loopback2_test_t *lw) 3473 /* 3474 * Function: lbu_serial_txrx 3475 * Purpose: Loop over requested lengths and chaining sizes, and 3476 * transmit/receive packets. 3477 * Parameters: lw - pointer to work structure 3478 * Returns: 0 - success 3479 * -1- failed. 3480 */ 3481 { 3482 loopback2_testdata_t *lp = lw->cur_params; 3483 int len, ppt, cos, i; 3484 int unit = lw->unit; 3485 int tagged, rv, test_rv = 0; 3486 uint32 tx_count, rx_count; 3487 uint32 rx_count0, rx_count1, rx_count2, rx_count3; 3488 3489 /* Clear port rx/tx counters */ 3490 if ((rv = bcm_stat_clear(unit, lw->tx_port)) < 0) { 3491 test_error(unit, "Could not clear port %s counters: %s\n", 3492 SOC_PORT_NAME(unit, lw->tx_port), 3493 soc_errmsg(rv)); 3494 test_rv = -1; 3495 goto error; 3496 } 3497 3498 if ((rv = bcm_stat_clear(unit, lw->rx_port)) < 0) { 3499 test_error(unit, "Could not clear port %s counters: %s\n", 3500 SOC_PORT_NAME(unit, lw->rx_port), 3501 soc_errmsg(rv)); 3502 test_rv = -1; 3503 goto error; 3504 } 3505 3506 LOG_INFO(BSL_LS_APPL_TESTS, 3507 (BSL_META_U(unit, 3508 "Testing Port %s --> %s cnt(%d) pkt/trial(%d,%d += %d) " 3509 "l(%d,%d += %d) cos(%d,%d)\n"), 3510 SOC_PORT_NAME(unit, lw->tx_port), 3511 SOC_PORT_NAME(unit, lw->rx_port), 3512 lp->iterations, 3513 lp->ppt_start, lp->ppt_end, lp->ppt_inc, 3514 lp->len_start, lp->len_end, lp->len_inc, 3515 lp->cos_start, lp->cos_end)); 3516 3517 /* One time setup of packets */ 3518 tagged = !SOC_PBMP_MEMBER(lp->ubm, lw->tx_port); 3519 lbu_pkt_init(lw->tx_pkts, lp->ppt_end, lw->tx_port, tagged); 3520 3521 for (i = 0; i < lp->iterations; i++) { 3522 for (len = lp->len_start; len <= lp->len_end; len += lp->len_inc) { 3523 for (cos = lp->cos_start; cos <= lp->cos_end; cos++) { 3524 for (ppt = lp->ppt_start; ppt <= lp->ppt_end; 3525 ppt += lp->ppt_inc) { 3526 lw->tx_ppt = ppt; 3527 lw->tx_len = len; 3528 lw->rx_pkt_cnt = 0; 3529 if (lbu_do_chain(unit, len, ppt, cos, i, lw) < 0) { 3530 test_rv = -1; 3531 goto done; 3532 } 3533 } 3534 } 3535 } 3536 } /* Test iterations */ 3537 3538 done: 3539 /* Verify port rx/tx stats */ 3540 bcm_stat_sync(unit); 3541 if ((IS_FE_PORT(unit, lw->rx_port) || IS_GE_PORT(unit, lw->rx_port))) { 3542 bcm_stat_val_t rx_stat; 3543 bcm_stat_val_t tx_stat; 3544 if ((SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) && 3545 IS_ST_PORT(unit, lw->tx_port)) { 3546 /* WAR for stacking ports of Raptor/Raven, where Higig unicast 3547 packets are accounted as multicast by the MAC */ 3548 tx_stat = snmpIfOutMulticastPkts; 3549 rx_stat = snmpIfInMulticastPkts; 3550 } else { 3551 tx_stat = snmpIfOutUcastPkts; 3552 rx_stat = snmpIfInUcastPkts; 3553 } 3554 if ((rv = bcm_stat_get32(unit, lw->tx_port, 3555 tx_stat, &tx_count)) < 0) { 3556 test_error(unit, 3557 "Could not get port %s tx %s stats : %s\n", 3558 SOC_PORT_NAME(unit, lw->tx_port), 3559 "snmpIfOutUcastPkts", 3560 soc_errmsg(rv)); 3561 test_rv = -1; 3562 goto error; 3563 } 3564 if ((rv = bcm_stat_get32(unit, lw->rx_port, 3565 rx_stat, &rx_count)) < 0) { 3566 test_error(unit, 3567 "Could not get port %s rx %s stats : %s\n", 3568 SOC_PORT_NAME(unit, lw->rx_port), 3569 "snmpIfInUcastPkts", 3570 soc_errmsg(rv)); 3571 test_rv = -1; 3572 goto error; 3573 } 3574 if (tx_count != rx_count) { 3575 test_error(unit, 3576 "TX/RX packet stats mismatch: (%s) TX=%d, (%s) RX=%d\n", 3577 SOC_PORT_NAME(unit, lw->tx_port), 3578 (int) tx_count, 3579 SOC_PORT_NAME(unit, lw->rx_port), 3580 (int) rx_count); 3581 test_rv = -1; 3582 } 3583 } 3584 3585 /* Check for port TX error statistics */ 3586 if ((rv = bcm_stat_get32(unit, lw->tx_port, 3587 snmpIfOutErrors, &tx_count)) < 0) { 3588 test_error(unit, 3589 "Could not get port %s tx error %s stats : %s\n", 3590 SOC_PORT_NAME(unit, lw->tx_port), 3591 "snmpIfOutErrors", 3592 soc_errmsg(rv)); 3593 test_rv = -1; 3594 goto error; 3595 } 3596 if (tx_count) { 3597 test_error(unit, 3598 "TX error stats found: TX (%s) error count=%d\n", 3599 SOC_PORT_NAME(unit, lw->tx_port), (int) tx_count); 3600 test_rv = -1; 3601 } 3602 3603 /* Check for port RX error statistics 3604 * Use individual stat to count rx errors instead of snmpIfInErrors 3605 * which includes good oversize packets. 3606 */ 3607 if ((rv = bcm_stat_get32(unit, lw->rx_port, 3608 snmpEtherStatsUndersizePkts, &rx_count0)) < 0) { 3609 test_error(unit, 3610 "Could not get port %s rx %s stats : %s\n", 3611 SOC_PORT_NAME(unit, lw->rx_port), 3612 "snmpEtherStatsUndersizePkts", 3613 soc_errmsg(rv)); 3614 test_rv = -1; 3615 goto error; 3616 } 3617 if ((rv = bcm_stat_get32(unit, lw->rx_port, 3618 snmpEtherStatsFragments, &rx_count1)) < 0) { 3619 test_error(unit, 3620 "Could not get port %s rx %s stats : %s\n", 3621 SOC_PORT_NAME(unit, lw->rx_port), 3622 "snmpEtherStatsFragments", 3623 soc_errmsg(rv)); 3624 test_rv = -1; 3625 goto error; 3626 } 3627 if ((rv = bcm_stat_get32(unit, lw->rx_port, 3628 snmpEtherStatsCRCAlignErrors, &rx_count2)) < 0) { 3629 test_error(unit, 3630 "Could not get port %s rx %s stats : %s\n", 3631 SOC_PORT_NAME(unit, lw->rx_port), 3632 "snmpEtherStatsCRCAlignErrors", 3633 soc_errmsg(rv)); 3634 test_rv = -1; 3635 goto error; 3636 } 3637 if ((rv = bcm_stat_get32(unit, lw->rx_port, 3638 snmpEtherStatsJabbers, &rx_count3)) < 0) { 3639 test_error(unit, 3640 "Could not get port %s rx %s stats : %s\n", 3641 SOC_PORT_NAME(unit, lw->rx_port), 3642 "snmpEtherStatsJabbers", 3643 soc_errmsg(rv)); 3644 test_rv = -1; 3645 goto error; 3646 } 3647 rx_count = rx_count0 + rx_count1 + rx_count2 + rx_count3; 3648 if (rx_count) { 3649 test_error(unit, 3650 "RX error stats found: RX (%s) error count=%d\n", 3651 SOC_PORT_NAME(unit, lw->rx_port), (int) rx_count); 3652 test_rv = -1; 3653 } 3654 3655 if (test_rv) { 3656 goto error; 3657 } 3658 return(0); 3659 3660 error: 3661 CLEAR_RX_PKTS(lw, lp); 3662 return (test_rv); 3663 } 3664 3665 int 3666 lbu_snake_tx(loopback2_test_t *lw) 3667 /* 3668 * Function: lbu_snake_tx 3669 * Purpose: Inject packets into snake sources. 3670 * Parameters: lw - pointer to work structure 3671 * Returns: 0 - success 3672 * -1- failed. 3673 */ 3674 { 3675 int rv = BCM_E_NONE; 3676 3677 if ((rv = lbu_snake_pkt_chain_setup(lw->tx_pkts, lw->tx_ppt, lw->tx_len, 3678 lw->tx_cos, lw)) < 0) { 3679 test_error(lw->unit, "Could not setup snake\n" 3680 "\tPacket Length=%d bytes\n" 3681 "\tPPT=%d\n" 3682 "\tCurrent COS=%d\n", 3683 lw->tx_len, lw->tx_ppt, lw->tx_cos); 3684 return rv; 3685 } 3686 3687 if ((rv = lbu_send_packets(lw->unit, lw->tx_pkts, lw->tx_ppt, lw)) < 0) { 3688 test_error(lw->unit, "Packet TX failed: ERROR: %s\n", 3689 bcm_errmsg(rv)); 3690 lbu_dump_tx_packets(lw); 3691 return rv; 3692 } 3693 return 0; 3694 } 3695 #ifdef BCM_TOMAHAWK_SUPPORT 3696 /* 3697 * Function: 3698 * lbu_snake_check_mib_counters 3699 * Purpose: 3700 * Checks Error counters in MAC. 3701 */ 3702 3703 static int 3704 lbu_snake_check_mib_counters(int unit, loopback2_testdata_t *lp) 3705 { 3706 uint32 j, column; 3707 uint64 rdata; 3708 int rv; 3709 int pblk; 3710 bcm_port_t pt; 3711 3712 soc_reg_t error_counters[][4] = { 3713 {RFLRr, XLMIB_RFLRr, CLMIB_RFLRr, GRFLRr}, 3714 {RFCSr, XLMIB_RFCSr, CLMIB_RFCSr, GRFCSr}, 3715 {RJBRr, XLMIB_RJBRr, CLMIB_RJBRr, GRJBRr}, 3716 {RMTUEr, XLMIB_RMTUEr, CLMIB_RMTUEr, GRMTUEr}, 3717 {RTRFUr, XLMIB_RTRFUr, CLMIB_RTRFUr, INVALIDr}, 3718 {RERPKTr, XLMIB_RERPKTr, CLMIB_RERPKTr, GRCDEr}, 3719 {RRPKTr, XLMIB_RRPKTr, CLMIB_RRPKTr, GRRPKTr}, 3720 {RUNDr, XLMIB_RUNDr, CLMIB_RUNDr, GRUNDr}, 3721 {RFRGr, XLMIB_RFRGr, CLMIB_RFRGr, GRFRGr}, 3722 {RRBYTr, XLMIB_RRBYTr, CLMIB_RRBYTr, GRRBYTr}, 3723 {TJBRr, XLMIB_TJBRr, CLMIB_TJBRr, GTJBRr}, 3724 {TFCSr, XLMIB_TFCSr, CLMIB_TFCSr, GTFCSr}, 3725 {TERRr, XLMIB_TERRr, CLMIB_TERRr, GTXCLr}, 3726 {TFRGr, XLMIB_TFRGr, CLMIB_TFRGr, GTFRGr}, 3727 {TRPKTr, XLMIB_TRPKTr, CLMIB_TRPKTr, INVALIDr}, 3728 {TUFLr, XLMIB_TUFLr, CLMIB_TUFLr, INVALIDr}, 3729 {TPCEr, TPCE_64r, TPCE_64r, TPCE_64r}, 3730 {RDISCr, RDISC_64r, RDISC_64r, RDISC_64r}, 3731 {RIPHE4r, RIPHE4_64r, RIPHE4_64r, RIPHE4_64r}, 3732 {RIPHE6r, RIPHE6_64r, RIPHE6_64r, RIPHE6_64r}, 3733 {RIPD4r, RIPD4_64r, RIPD4_64r, RIPD4_64r}, 3734 {RIPD6r, RIPD6_64r, RIPD6_64r, RIPD6_64r}, 3735 {RPORTDr, RPORTD_64r, RPORTD_64r, RPORTD_64r} 3736 }; 3737 3738 PBMP_ITER(lp->pbm, pt) { 3739 column = 0; 3740 if (soc_feature(unit, soc_feature_cxl_mib)) { 3741 pblk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[pt]); 3742 if (SOC_BLOCK_IS_CMP(unit, pblk, SOC_BLK_CLPORT)) { 3743 column = 2; 3744 } else if (IS_QSGMII_PORT(unit, pt)) { 3745 column = 3; 3746 } else if (SOC_BLOCK_IS_CMP(unit, pblk, SOC_BLK_XLPORT)) { 3747 column = 1; 3748 } 3749 } 3750 for (j = 0; j < (sizeof(error_counters) / sizeof(error_counters[0])); j++) { 3751 if (SOC_REG_IS_VALID(unit, error_counters[j][column])) { 3752 rv = soc_reg_get(unit, error_counters[j][column], pt, 0, &rdata); 3753 3754 if (SOC_FAILURE(rv)) { 3755 test_error(unit, "\nError reading MIB counter %s", 3756 SOC_REG_NAME(unit, error_counters[j][column])); 3757 return -1; 3758 } else if (!(COMPILER_64_IS_ZERO(rdata))) { 3759 test_error (unit, "\n*ERROR: Error counter %s has a non zero value " 3760 "for device port %0d", 3761 SOC_REG_NAME(unit, error_counters[j][column]), pt); 3762 return -1; 3763 } 3764 } 3765 } 3766 } 3767 return 0; 3768 } 3769 3770 /* 3771 * Function: 3772 * lbu_snake_check_rate 3773 * Purpose: 3774 * check rate in snake test. 3775 */ 3776 static int 3777 lbu_snake_check_rate(int unit, loopback2_test_t *lw, lb2_port_stat_t *stats) 3778 { 3779 bcm_port_t pt; 3780 int speed, first = TRUE, cell_num, pipe, dpp_ratio = 10; 3781 uint32 rate_core, rate_pipe, rate_limit; 3782 uint64 rate_tolerance, act_rate; 3783 loopback2_testdata_t *lp = lw->cur_params; 3784 soc_reg_t reg = INVALIDr; 3785 soc_info_t *si; 3786 int port_c[4] = {0,0,0,0}, max_port_num = 0; 3787 3788 si = &SOC_INFO(unit); 3789 COMPILER_64_ZERO(rate_tolerance); 3790 cell_num = lw->tx_len <= 144 ? 1: (1 + (lw->tx_len - 144 + 207) / 208); 3791 rate_core = si->frequency * (lw->tx_len + 20) * 8 / cell_num; 3792 if (SOC_IS_TOMAHAWK2(unit)){ 3793 dpp_ratio = si->dpp_clk_ratio_x10; 3794 } 3795 rate_pipe = si->frequency * (lw->tx_len + 20) * 8 * 10 / dpp_ratio; 3796 3797 PBMP_ITER(lp->pbm, pt) { 3798 BCM_IF_ERROR_RETURN(soc_port_pipe_get(unit,pt,&pipe)); 3799 if (pipe >= 0 && pipe < 4){ 3800 port_c[pipe]++; 3801 if (port_c[pipe] > max_port_num) { 3802 max_port_num = port_c[pipe]; 3803 } 3804 } 3805 } 3806 rate_limit = rate_core < rate_pipe ? 3807 rate_core / max_port_num : rate_pipe / max_port_num; 3808 3809 PBMP_ITER(lp->pbm, pt) { 3810 if (first) { 3811 if (soc_feature(unit, soc_feature_cxl_mib)) { 3812 if (SOC_BLOCK_IS_CMP(unit, SOC_PORT_BLOCK(unit, 3813 SOC_INFO(unit).port_l2p_mapping[pt]), SOC_BLK_CLPORT)) { 3814 reg = CLMIB_TBYTr; 3815 } else if (IS_QSGMII_PORT(unit, pt)) { 3816 reg = GTBYTr; 3817 } else { 3818 reg = XLMIB_TBYTr; 3819 } 3820 } else { 3821 reg = TBYTr; 3822 } 3823 if (!SOC_REG_IS_VALID(unit, reg)) { 3824 cli_out("reg %s is not valid", SOC_REG_NAME(unit,reg)); 3825 return -1; 3826 } 3827 BCM_IF_ERROR_RETURN(bcm_port_speed_get(unit, pt, &speed)); 3828 if (speed > rate_limit) { 3829 speed = rate_limit; 3830 } 3831 cli_out("port max line rate is %d MB/s for packet length %d Byte \n", 3832 speed, lw->tx_len); 3833 /*give a 5% margin, rate_tolerance = speed * 1000000 * 95 / 100 */ 3834 COMPILER_64_SET(rate_tolerance, 0, speed); 3835 COMPILER_64_UMUL_32(rate_tolerance, 950000); 3836 first = FALSE; 3837 } 3838 3839 soc_counter_get_rate(unit, pt, reg, 0, &(stats[pt].rate)); 3840 /*change to real rate in bit. 3841 *act_rate = stats[pt].rate * 8 * (lw->tx_len + 20) / (lw->tx_len) 3842 */ 3843 COMPILER_64_COPY(act_rate, stats[pt].rate); 3844 COMPILER_64_UMUL_32(act_rate, (8 * (lw->tx_len + 20))); 3845 COMPILER_64_UDIV_32(act_rate, lw->tx_len); 3846 3847 if (COMPILER_64_LT(act_rate, rate_tolerance)) { 3848 cli_out("Cannot reach line rate for port %s\n", 3849 SOC_PORT_NAME(unit, pt)); 3850 return -1; 3851 } 3852 } 3853 return 0; 3854 } 3855 3856 /* 3857 * Function: 3858 * lbu_snake_check_drop_pkt 3859 * Purpose: 3860 * check packet loss in snake test. 3861 */ 3862 3863 static int 3864 lbu_snake_check_drop_pkt(int unit, loopback2_testdata_t *lp, lb2_port_stat_t *stats) 3865 { 3866 bcm_port_t pt; 3867 int first = TRUE; 3868 uint64 byte, pkt; 3869 COMPILER_64_ZERO(byte); 3870 COMPILER_64_ZERO(pkt); 3871 3872 PBMP_ITER(lp->pbm, pt) { 3873 if (first) { 3874 COMPILER_64_COPY(byte, stats[pt].tbyt); 3875 COMPILER_64_COPY(pkt, stats[pt].tpkt); 3876 first = FALSE; 3877 } 3878 if (!(COMPILER_64_EQ(byte, stats[pt].rbyt) && COMPILER_64_EQ(byte, stats[pt].tbyt) && 3879 COMPILER_64_EQ(pkt, stats[pt].rpkt) && COMPILER_64_EQ(pkt, stats[pt].tpkt))) { 3880 cli_out("pkt counter mismatch for port %s\n", SOC_PORT_NAME(unit, pt)); 3881 return -1; 3882 } 3883 } 3884 return 0; 3885 } 3886 #endif /*BCM_TOMAHAWK_SUPPORT */ 3887 3888 int 3889 lbu_snake_txrx(loopback2_test_t *lw, lb2_port_stat_t *stats) 3890 /* 3891 * Function: lbu_snake_txrx 3892 * Purpose: Transmit and receive packets from snake. 3893 * Parameters: lw - pointer to work structure 3894 * Returns: 0 - success 3895 * -1- failed. 3896 */ 3897 { 3898 loopback2_testdata_t *lp = lw->cur_params; 3899 int unit = lw->unit; 3900 int rv = BCM_E_NONE; 3901 int ix, timer, sleep_time; 3902 lb2s_port_connect_t *work_info; 3903 3904 /* This is the init call */ 3905 if (lbu_snake_stats(unit, lp->pbm, lp->loopback, stats) < 0) { 3906 lbu_snake_dump_stats(unit, lp->pbm, stats); 3907 return (-1); 3908 } 3909 3910 lw->rx_pkt_cnt = 0; 3911 lbu_snake_tx(lw); 3912 3913 timer = 0; 3914 while (lp->duration > timer) { 3915 sleep_time = lp->interval; 3916 3917 if (lp->interval > (lp->duration - timer)) { 3918 sleep_time = (lp->duration - timer); 3919 } 3920 3921 sal_sleep(sleep_time); 3922 timer += sleep_time; 3923 cli_out("Time elapsed: %d seconds\n", timer); 3924 3925 if (!SAL_BOOT_QUICKTURN) { 3926 if (lbu_snake_stats(unit, lp->pbm, lp->loopback, stats) < 0) { 3927 lbu_snake_dump_stats(unit, lp->pbm, stats); 3928 return (-1); 3929 } 3930 } else { 3931 /* JUMBO: */ 3932 uint64 tpkt; 3933 uint32 tempStat; 3934 bcm_port_t port; 3935 3936 work_info = (lw->port_cnct_f != NULL) ? 3937 lw->port_cnct_f : lw->port_cnct_r; 3938 3939 port = work_info[0].this_port; 3940 3941 COMPILER_64_ZERO(tpkt); COMPILER_REFERENCE(&tpkt); 3942 bcm_stat_get(unit, port, 3943 snmpDot1dTpPortOutFrames, &tpkt); 3944 COMPILER_64_TO_32_LO(tempStat, tpkt); 3945 cli_out("Port %s Tx Count = 0x%x\n", 3946 SOC_PORT_NAME(unit, port), 3947 tempStat); 3948 } 3949 } 3950 #ifdef BCM_TOMAHAWK_SUPPORT 3951 /*check line rate*/ 3952 if (lp->line_rate){ 3953 if(lbu_snake_check_rate(unit, lw, stats) < 0) { 3954 lbu_snake_dump_stats(unit, lp->pbm, stats); 3955 return -1; 3956 } 3957 } 3958 #endif 3959 /* Redirect packets to CPU if loop was closed */ 3960 if (lp->duration) { 3961 lw->expect_pkts = TRUE; 3962 if (lw->port_cnct_f != NULL) { 3963 work_info = &(lw->port_cnct_f[lw->port_count]); 3964 if ((rv = lbu_connect_ports(unit, work_info, TRUE)) < 0) { 3965 test_error(unit, 3966 "CPU redirect failure on forward loop: %s\n", 3967 soc_errmsg(rv)); 3968 return -1; 3969 } 3970 } 3971 3972 if (lw->port_cnct_r != NULL) { 3973 work_info = &(lw->port_cnct_r[lw->port_count]); 3974 if ((rv = lbu_connect_ports(unit, work_info, TRUE)) < 0) { 3975 test_error(unit, 3976 "CPU redirect failure on reverse loop: %s\n", 3977 soc_errmsg(rv)); 3978 return -1; 3979 } 3980 } 3981 } 3982 3983 bcm_stat_sync(unit); 3984 3985 if (sal_sem_take(lw->sema, lw->timeout_usec)) { 3986 cli_out("Time-out waiting for snake completion\n"); 3987 cli_out("Receive count is %d; expecting %d pkts.\n", 3988 lw->rx_pkt_cnt, lw->tx_ppt); 3989 lbu_snake_stats(unit, lp->pbm, lp->loopback, stats); 3990 lbu_snake_dump_stats(unit, lp->pbm, stats); 3991 lw->sema_woke = FALSE; 3992 return (-1); 3993 } 3994 3995 lw->sema_woke = FALSE; 3996 lw->expect_pkts = FALSE; /* Let RX handler ignore packets */ 3997 3998 if (lbu_snake_analysis(lw) < 0) { 3999 if (lbu_snake_stats(unit, lp->pbm, lp->loopback, stats) < 0) { 4000 if (lw->port_cnct_f != NULL) { 4001 lbu_snake_diag(lw, stats, lw->port_cnct_f); 4002 } 4003 if (lw->port_cnct_r != NULL) { 4004 lbu_snake_diag(lw, stats, lw->port_cnct_r); 4005 } 4006 } 4007 lbu_snake_dump_stats(unit, lp->pbm, stats); 4008 return (-1); 4009 } 4010 4011 rv = 0; 4012 for (ix = 0; ix < lw->tx_ppt; ix++) { 4013 if (lw->tx_pkt_match[ix] == 0) { 4014 rv = -1; 4015 test_error(unit, 4016 "TX packet %d did not return to CPU\n", (ix + 1)); 4017 } 4018 } 4019 4020 if (lbu_snake_stats(unit, lp->pbm, lp->loopback, stats) < 0) { 4021 rv = -1; 4022 } 4023 4024 #ifdef BCM_TOMAHAWK_SUPPORT 4025 if (lp->line_rate){ 4026 if (lbu_snake_check_mib_counters(unit, lp) < 0) { 4027 return -1; 4028 } 4029 /*skip packet drop check for small packets*/ 4030 if (lw->tx_len > 352){ 4031 if (lbu_snake_check_drop_pkt(unit, lp, stats) < 0) { 4032 rv = -1; 4033 } 4034 } 4035 } 4036 #endif 4037 4038 lbu_snake_dump_stats(unit, lp->pbm, stats); 4039 4040 if (rv < 0) { 4041 return rv; 4042 } 4043 4044 /* Close loop again */ 4045 if (lp->duration) { 4046 if (lw->port_cnct_f != NULL) { 4047 work_info = &(lw->port_cnct_f[lw->port_count]); 4048 if ((rv = lbu_connect_ports(unit, work_info, FALSE)) < 0) { 4049 test_error(unit, 4050 "CPU undirect failure on forward loop: %s\n", 4051 soc_errmsg(rv)); 4052 return -1; 4053 } 4054 4055 work_info = &(lw->port_cnct_f[lw->port_count - 1]); 4056 if ((rv = lbu_connect_ports(unit, work_info, TRUE)) < 0) { 4057 test_error(unit, 4058 "Forward loop closure failed: %s\n", 4059 soc_errmsg(rv)); 4060 return -1; 4061 } 4062 } 4063 4064 if (lw->port_cnct_r != NULL) { 4065 work_info = &(lw->port_cnct_r[lw->port_count]); 4066 if ((rv = lbu_connect_ports(unit, work_info, FALSE)) < 0) { 4067 test_error(unit, 4068 "CPU redirect failure on reverse loop: %s\n", 4069 soc_errmsg(rv)); 4070 return -1; 4071 } 4072 4073 work_info = &(lw->port_cnct_r[lw->port_count - 1]); 4074 if ((rv = lbu_connect_ports(unit, work_info, TRUE)) < 0) { 4075 test_error(unit, 4076 "Reverse loop closure failed: %s\n", 4077 soc_errmsg(rv)); 4078 return -1; 4079 } 4080 } 4081 } 4082 4083 /* Clean up packet data */ 4084 CLEAR_RX_PKTS(lw, lp); 4085 sal_memset(lw->tx_pkt_match, 0, lp->ppt_end * sizeof(int)); 4086 4087 return 0; 4088 } 4089 4090 void 4091 lbu_setup(int unit, loopback2_test_t *lw) 4092 /* 4093 * Function: lbu_setup 4094 * Purpose: Fill in defaults for the parameters. 4095 * Parameters: unit - unit #. 4096 * lw - pointer to work struct. 4097 * Returns: Nothing 4098 */ 4099 { 4100 int num_cos; 4101 4102 /* Keep statistics from printing if user ^C's before test starts */ 4103 lw->stats_init = FALSE; 4104 4105 if (lw->set_up) { 4106 return; 4107 } 4108 4109 if (bcm_cosq_config_get(unit, &num_cos) < 0 || num_cos == 0) { 4110 num_cos = 1; 4111 } 4112 4113 lw->unit = unit; 4114 4115 /* Set up parameters for different tests */ 4116 mac_params_init(unit, num_cos, &lw->params[LB2_TT_MAC]); 4117 phy_params_init(unit, num_cos, &lw->params[LB2_TT_PHY]); 4118 ext_params_init(unit, num_cos, &lw->params[LB2_TT_EXT]); 4119 snake_params_init(unit, num_cos, &lw->params[LB2_TT_SNAKE]); 4120 4121 lw->set_up = TRUE; 4122 } 4123 4124 STATIC int 4125 lbu_restore_port(loopback2_test_t *lw) 4126 { 4127 loopback2_testdata_t *lp = lw->cur_params; 4128 int rv; 4129 int unit = lw->unit; 4130 soc_port_t port; 4131 pbmp_t save_ports; 4132 int ms; 4133 4134 if (SOC_IS_XGS12_FABRIC(unit)) { 4135 SOC_PBMP_ASSIGN(save_ports, PBMP_PORT_ALL(unit)); 4136 } else { 4137 SOC_PBMP_ASSIGN(save_ports, PBMP_PORT_ALL(unit)); 4138 SOC_PBMP_AND(save_ports, lp->pbm); 4139 } 4140 4141 PBMP_ITER(save_ports, port) { 4142 /* If port is FE port, remove phy_master attributes controlled by it */ 4143 if(IS_FE_PORT(unit, port)) { 4144 lw->save_port[port].action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 4145 } 4146 /* If the Master mode is not changed, remove phy_master attributes from action_mask*/ 4147 ms = 0; 4148 if ((rv = bcm_port_master_get(unit, port, &ms)) != BCM_E_NONE) { 4149 test_error(unit, 4150 "Port %s: Could not get port Master mode: %s\n", 4151 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 4152 return (-1); 4153 } 4154 if (ms == lw->save_port[port].phy_master) { 4155 lw->save_port[port].action_mask &= ~BCM_PORT_ATTR_PHY_MASTER_MASK; 4156 } 4157 if ((rv = bcm_port_info_restore(unit, port, 4158 &lw->save_port[port])) < 0) { 4159 test_error(unit, 4160 "Port %s: Could not restore port info: %s\n", 4161 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 4162 return(-1); 4163 } 4164 #ifdef BCM_TOMAHAWK3_SUPPORT 4165 /* Restore original fec, phy config and link training info. Note pm8x50 4166 * (cd ports) have this additional configuration information 4167 */ 4168 if ((SOC_IS_TOMAHAWK3(unit)) && (IS_CD_PORT(unit, port))) { 4169 rv = bcm_port_resource_speed_set(unit, port, 4170 &lw->port_info[port]); 4171 if (rv < 0) { 4172 test_error(unit, 4173 "Port %s: bcm_port_resource_set failed: %s\n", 4174 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 4175 return(-1); 4176 } 4177 } 4178 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4179 } 4180 4181 if (SOC_IS_XGS_SWITCH(unit)) { 4182 /* Restore source port/module for ipic */ 4183 SOC_DEFAULT_DMA_SRCMOD_SET(unit, lbu_saved_srcmod[unit]); 4184 SOC_DEFAULT_DMA_SRCPORT_SET(unit, lbu_saved_srcport[unit]); 4185 } 4186 #ifdef BCM_TRIUMPH_SUPPORT 4187 if(SOC_IS_TRX(unit)){ 4188 PBMP_ITER(save_ports, port) { 4189 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4190 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 4191 if (soc_feature(unit, soc_feature_egr_all_profile)) { 4192 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_set(unit, 4193 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 1)); 4194 } else { 4195 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 4196 EGR_VLAN_CONTROL_1m, port, REMARK_OUTER_DOT1Pf, 1)); 4197 } 4198 } else 4199 #endif 4200 if ((rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 4201 REMARK_OUTER_DOT1Pf, 0x1)) < 0) { 4202 test_error(unit, 4203 "Unable to re-enable outer dot1p remarking: port %s: %s\n", 4204 SOC_PORT_NAME(unit, port), bcm_errmsg(rv)); 4205 return (-1); 4206 } 4207 } 4208 } 4209 #endif 4210 return(0); 4211 } 4212 4213 int 4214 lbu_done(loopback2_test_t *lw) 4215 /* 4216 * Function: lbu_done 4217 * Purpose: Generic loopback done function 4218 * Parameters: lw - pointer to lw to clean up. 4219 * Returns: 4220 */ 4221 { 4222 int rv = 0; 4223 loopback2_testdata_t *lp = lw->cur_params; 4224 int unit = lw->unit; 4225 4226 if (lp) { 4227 if (!lp->inject) { 4228 /* Unregister the callback */ 4229 if ((rv = bcm_rx_unregister(lw->unit, lbu_rx_callback, 4230 BCM_RX_PRIO_MAX)) < 0) { 4231 test_error(lw->unit, 4232 "Failed to unregister RX handler.\n"); 4233 } 4234 #if defined(__KERNEL__) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT)) 4235 (void)soc_cmicm_cmcx_intr0_disable(unit, 0, 0xff00); 4236 sal_usleep(500); 4237 #endif 4238 /* lbu_restore_port resets initial state below */ 4239 if ((rv = bcm_rx_stop(lw->unit, NULL)) < 0) { 4240 cli_out("lbu_done: could not stop packet driver: %s\n", 4241 bcm_errmsg(rv)); 4242 } 4243 4244 if (lw->tx_pkts) { 4245 bcm_pkt_blk_free(unit, lw->tx_pkts, lp->ppt_end); 4246 lw->tx_pkts = NULL; 4247 } 4248 if (lw->rx_pkts) { 4249 CLEAR_RX_PKTS(lw, lp); 4250 sal_free(lw->rx_pkts); 4251 lw->rx_pkts = NULL; 4252 } 4253 } 4254 4255 } 4256 4257 4258 #if defined(__KERNEL__) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT)) 4259 sal_sem_destroy(lw->sema); 4260 lw->sema = NULL; 4261 #endif 4262 4263 if (lw->sema) { 4264 sal_sem_destroy(lw->sema); 4265 lw->sema = NULL; 4266 } 4267 4268 /* Clean up ARL if interrupted in middle */ 4269 lbu_cleanup_arl(lw); 4270 4271 /* ENABLE ALL PORTS */ 4272 if (lp) { 4273 rv |= lbu_restore_port(lw); 4274 } 4275 4276 lp = NULL; 4277 4278 #if defined(__KERNEL__) && (defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICDV2_SUPPORT)) 4279 bcm_vlan_destroy_all(unit); 4280 #endif 4281 4282 return(rv); 4283 } 4284 4285 /* Test parameter init routines */ 4286 4287 STATIC void 4288 mac_params_init(int unit, int num_cos, loopback2_testdata_t *lp) 4289 { 4290 int lene_ignore = 0; 4291 4292 lp->test_type = LB2_TT_MAC; 4293 4294 SOC_PBMP_ASSIGN(lp->pbm, PBMP_PORT_ALL(unit)); 4295 lp->dst_inc = 0; 4296 SOC_PBMP_CLEAR(lp->ubm); 4297 lp->pattern = 0xa5a4a3a2; 4298 lp->pattern_inc = 0; 4299 lp->vlan = LB2_VLAN_ID; 4300 lp->d_port = CMIC_PORT(unit); 4301 if (SOC_IS_XGS_SWITCH(unit)) { 4302 if (bcm_stk_my_modid_get(unit, &lp->d_mod) < 0) { 4303 lp->d_mod = 0; 4304 } 4305 } else { 4306 #ifdef BCM_XGS_SUPPORT 4307 lp->d_mod = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_DST_MOD_CPU : 0; 4308 #else 4309 lp->d_mod = 0; 4310 #endif 4311 } 4312 #ifdef BCM_XGS_SUPPORT 4313 lp->opcode = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_OP_UC : 0; 4314 #else 4315 lp->opcode = 0; 4316 #endif 4317 lp->len_start = 68; 4318 lp->len_end = 1522; 4319 lp->len_inc = 512; 4320 lp->ppt_start = 1; 4321 lene_ignore = lp->len_end; 4322 (void)_lb_ppte_initval(unit, &lene_ignore, &lp->ppt_end); 4323 lp->ppt_inc = lp->ppt_end - lp->ppt_start; 4324 #ifdef BCM_TOMAHAWK_SUPPORT 4325 lp->line_rate = 0; 4326 lp->line_rate_count = 1; 4327 #endif 4328 lp->cos_start = 0; 4329 lp->cos_end = num_cos - 1; 4330 lp->iterations = 10; 4331 lp->crc_mode = LB2_CRC_MODE_MAC_REGEN; 4332 lp->check_data = TRUE; 4333 lp->check_crc = FALSE; 4334 lp->loopback = LB2_MODE_MAC; 4335 lp->inject = FALSE; 4336 lp->port_select_mode = LB2_TH_ASCEND_PORT_MODE; 4337 if (lp->ppt_inc == 0) { 4338 lp->ppt_inc = 1; 4339 } 4340 4341 ENET_SET_MACADDR(lp->mac_src, lbu_mac_src); 4342 lp->mac_src_inc = 0; 4343 ENET_SET_MACADDR(lp->mac_dst, lbu_mac_dst); 4344 lp->mac_dst_inc = 0; 4345 } 4346 4347 STATIC void 4348 phy_params_init(int unit, int num_cos, loopback2_testdata_t *lp) 4349 { 4350 int lene_ignore = 0; 4351 4352 lp->test_type = LB2_TT_PHY; 4353 4354 SOC_PBMP_ASSIGN(lp->pbm, PBMP_PORT_ALL(unit)); 4355 4356 4357 lp->dst_inc = 0; 4358 SOC_PBMP_CLEAR(lp->ubm); 4359 lp->pattern = 0xa5a4a3a2; 4360 lp->pattern_inc = 0; 4361 lp->vlan = LB2_VLAN_ID; 4362 lp->d_port = CMIC_PORT(unit); 4363 if (SOC_IS_XGS_SWITCH(unit)) { 4364 if (bcm_stk_my_modid_get(unit, &lp->d_mod) < 0) { 4365 lp->d_mod = 0; 4366 } 4367 } else { 4368 #ifdef BCM_XGS_SUPPORT 4369 lp->d_mod = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_DST_MOD_CPU : 0; 4370 #else 4371 lp->d_mod = 0; 4372 #endif 4373 } 4374 #ifdef BCM_XGS_SUPPORT 4375 lp->opcode = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_OP_UC : 0; 4376 #else 4377 lp->opcode = 0; 4378 #endif 4379 lp->len_start = 68; 4380 lp->len_end = 1522; 4381 lp->len_inc = 512; 4382 lp->ppt_start = 1; 4383 lene_ignore = lp->len_end; 4384 (void)_lb_ppte_initval(unit, &lene_ignore, &lp->ppt_end); 4385 lp->ppt_inc = lp->ppt_end - lp->ppt_start; 4386 #ifdef BCM_TOMAHAWK_SUPPORT 4387 lp->line_rate = 0; 4388 lp->line_rate_count = 1; 4389 #endif 4390 lp->cos_start = 0; 4391 lp->cos_end = num_cos - 1; 4392 lp->iterations = 10; 4393 lp->crc_mode = LB2_CRC_MODE_MAC_REGEN; 4394 lp->check_data = TRUE; 4395 lp->check_crc = FALSE; 4396 lp->loopback = LB2_MODE_PHY; 4397 lp->inject = FALSE; 4398 lp->port_select_mode = LB2_TH_ASCEND_PORT_MODE; 4399 4400 if (lp->ppt_inc == 0) { 4401 lp->ppt_inc = 1; 4402 } 4403 4404 ENET_SET_MACADDR(lp->mac_src, lbu_mac_src); 4405 lp->mac_src_inc = 0; 4406 ENET_SET_MACADDR(lp->mac_dst, lbu_mac_dst); 4407 lp->mac_dst_inc = 0; 4408 } 4409 4410 STATIC void 4411 ext_params_init(int unit, int num_cos, loopback2_testdata_t *lp) 4412 { 4413 int setport; 4414 int p; 4415 int lene_ignore = 0; 4416 4417 lp->test_type = LB2_TT_EXT; 4418 4419 SOC_PBMP_CLEAR(lp->pbm); 4420 /* set up pairs of transmitting and receiving ports */ 4421 SOC_PBMP_CLEAR(lp->pbm_tx); 4422 setport = 1; 4423 PBMP_PORT_ITER(unit, p) { 4424 if (setport) { 4425 SOC_PBMP_PORT_ADD(lp->pbm_tx, p); 4426 } 4427 setport = !setport; 4428 } 4429 lp->dst_inc = 1; 4430 SOC_PBMP_CLEAR(lp->ubm); 4431 lp->pattern = 0xa5a4a3a2; 4432 lp->pattern_inc = 0; 4433 lp->vlan = LB2_VLAN_ID; 4434 lp->d_port = CMIC_PORT(unit); 4435 if (SOC_IS_XGS_SWITCH(unit)) { 4436 if (bcm_stk_my_modid_get(unit, &lp->d_mod) < 0) { 4437 lp->d_mod = 0; 4438 } 4439 } else { 4440 #ifdef BCM_XGS_SUPPORT 4441 lp->d_mod = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_DST_MOD_CPU : 0; 4442 #else 4443 lp->d_mod = 0; 4444 #endif 4445 } 4446 #ifdef BCM_XGS_SUPPORT 4447 lp->opcode = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_OP_UC : 0; 4448 #else 4449 lp->opcode = 0; 4450 #endif 4451 lp->len_start = 68; 4452 lp->len_end = 1522; 4453 lp->len_inc = 512; 4454 lp->ppt_start = 1; 4455 lene_ignore = lp->len_end; 4456 (void)_lb_ppte_initval(unit, &lene_ignore, &lp->ppt_end); 4457 lp->ppt_inc = lp->ppt_end - lp->ppt_start; 4458 #ifdef BCM_TOMAHAWK_SUPPORT 4459 lp->line_rate = 0; 4460 lp->line_rate_count = 1; 4461 #endif 4462 lp->cos_start = 0; 4463 lp->cos_end = num_cos - 1; 4464 lp->iterations = 10; 4465 lp->crc_mode = LB2_CRC_MODE_MAC_REGEN; 4466 lp->check_data = TRUE; 4467 lp->check_crc = FALSE; 4468 lp->loopback = LB2_MODE_EXT; 4469 lp->inject = FALSE; 4470 lp->port_select_mode = LB2_TH_ASCEND_PORT_MODE; 4471 4472 if (lp->ppt_inc == 0) { 4473 lp->ppt_inc = 1; 4474 } 4475 4476 ENET_SET_MACADDR(lp->mac_src, lbu_mac_src); 4477 lp->mac_src_inc = 0; 4478 ENET_SET_MACADDR(lp->mac_dst, lbu_mac_dst); 4479 lp->mac_dst_inc = 0; 4480 } 4481 4482 STATIC void 4483 snake_params_init(int unit, int num_cos, loopback2_testdata_t *lp) 4484 { 4485 int lene_ignore = 0; 4486 4487 lp->test_type = LB2_TT_SNAKE; 4488 4489 SOC_PBMP_ASSIGN(lp->pbm, PBMP_PORT_ALL(unit)); 4490 4491 /* Snake test supported only on Ethernet ports on FB */ 4492 if (SOC_IS_FB_FX_HX(unit)) { 4493 SOC_PBMP_AND(lp->pbm, PBMP_E_ALL(unit)); 4494 } 4495 4496 lp->dst_inc = 1; 4497 SOC_PBMP_CLEAR(lp->ubm); 4498 lp->pattern = 0xa5a4a3a2; 4499 lp->pattern_inc = 0; 4500 lp->vlan = LB2_VLAN_ID; 4501 lp->d_port = CMIC_PORT(unit); 4502 if (SOC_IS_XGS_SWITCH(unit)) { 4503 if (bcm_stk_my_modid_get(unit, &lp->d_mod) < 0) { 4504 lp->d_mod = 0; 4505 } 4506 } else { 4507 #ifdef BCM_XGS_SUPPORT 4508 lp->d_mod = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_DST_MOD_CPU : 0; 4509 #else 4510 lp->d_mod = 0; 4511 #endif 4512 } 4513 #ifdef BCM_XGS_SUPPORT 4514 lp->opcode = SOC_IS_XGS12_FABRIC(unit) ? SOC_HIGIG_OP_UC : 0; 4515 #else 4516 lp->opcode = 0; 4517 #endif 4518 lp->d_mod_inc = 1; 4519 lp->len_start = 68; 4520 lp->len_end = 1522; 4521 lp->len_inc = 512; 4522 lp->ppt_start = 1; 4523 lene_ignore = lp->len_end; 4524 (void)_lb_ppte_initval(unit, &lene_ignore, &lp->ppt_end); 4525 lp->ppt_inc = 6; 4526 #ifdef BCM_TOMAHAWK_SUPPORT 4527 lp->line_rate = 0; 4528 lp->line_rate_count = 1; 4529 #endif 4530 lp->cos_start = 0; 4531 lp->cos_end = num_cos - 1; 4532 lp->iterations = 5; 4533 lp->crc_mode = SOC_IS_XGS12_FABRIC(unit) ? LB2_CRC_MODE_MAC_REGEN : 4534 LB2_CRC_MODE_CPU_APPEND; 4535 lp->check_data = FALSE; 4536 lp->check_crc = FALSE; 4537 lp->duration = 10; 4538 lp->interval = sh_set_report_time; 4539 lp->snake_way = LB2_SNAKE_INCR; 4540 lp->port_select_mode = LB2_TH_ASCEND_PORT_MODE; 4541 4542 lp->loopback = LB2_MODE_MAC; 4543 lp->inject = FALSE; 4544 4545 if (lp->ppt_inc == 0) { 4546 lp->ppt_inc = 1; 4547 } 4548 4549 #ifdef BCM_FIREBOLT_SUPPORT 4550 if (SOC_IS_HBX(unit)) { 4551 int port; 4552 PBMP_ITER(lp->pbm, port) { 4553 if (IS_ST_PORT(unit, port)) { 4554 lp->opcode = SOC_HIGIG_OP_UC; 4555 } 4556 } 4557 } 4558 #endif 4559 4560 ENET_SET_MACADDR(lp->mac_src, lbu_mac_src); 4561 lp->mac_src_inc = 0; 4562 ENET_SET_MACADDR(lp->mac_dst, lbu_mac_dst); 4563 lp->mac_dst_inc = 1; 4564 } 4565