port.c (33368B)
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 * File: port.c 8 * Purpose: TH2 SOC Port driver. 9 */ 10 11 #include <shared/bsl.h> 12 #include <soc/error.h> 13 #include <soc/defs.h> 14 #include <soc/tdm/core/tdm_top.h> 15 16 #if defined(BCM_TOMAHAWK2_SUPPORT) 17 #include <soc/tomahawk2_tdm.h> 18 #include <soc/tomahawk2.h> 19 #include <soc/scache.h> 20 21 #ifdef BCM_WARM_BOOT_SUPPORT 22 23 #define SOC_FLEXPORT_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 24 #define SOC_FLEXPORT_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 25 #define SOC_FLEXPORT_WB_DEFAULT_VERSION SOC_FLEXPORT_WB_VERSION_1_1 26 27 extern int 28 _soc_th2_port_speed_cap[SOC_MAX_NUM_DEVICES][_TH2_DEV_PORTS_PER_DEV]; 29 #endif 30 31 /* 32 * Function: 33 * soc_th2_port_schedule_tdm_init 34 * Purpose: 35 * Initialize TDM information in port_schedule_state that will be passed 36 * to DV FlexPort API 37 * Parameters: 38 * unit - (IN) Unit number. 39 * port_schedule_state - (OUT) Port resource state. 40 * Returns: 41 * BCM_E_xxx 42 * Notes: 43 * If called during Scheduler Initialization, only below values need to be 44 * properly set: 45 * soc_tdm_schedule_pipe_t::num_slices 46 * soc_tdm_schedule_t:: cal_len 47 * soc_tdm_schedule_t:: num_ovs_groups 48 * soc_tdm_schedule_t:: ovs_group_len 49 * soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space 50 * soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len 51 */ 52 int 53 soc_th2_port_schedule_tdm_init(int unit, 54 soc_port_schedule_state_t *port_schedule_state) 55 { 56 soc_control_t *soc = SOC_CONTROL(unit); 57 _soc_tomahawk2_tdm_t *tdm = soc->tdm_info; 58 soc_info_t *si = &SOC_INFO(unit); 59 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 60 soc_tdm_schedule_t *sched; 61 int pipe, hpipe, phy_port, is_flexport, group, slot; 62 int *port_p2PBLK_inst_mapping; 63 64 if (tdm == NULL) { 65 /*XGSSIM will skip tdm configuration on TH2*/ 66 if (SAL_BOOT_XGSSIM) { 67 return SOC_E_NONE; 68 } 69 return SOC_E_INIT; 70 } 71 72 is_flexport = port_schedule_state->is_flexport; 73 74 port_schedule_state->calendar_type = si->fabric_port_enable ? 75 _TH2_TDM_CALENDAR_UNIVERSAL : 76 _TH2_TDM_CALENDAR_ETHERNET_OPTIMIZED; 77 78 /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */ 79 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 80 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 81 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 82 83 tdm_ischd->num_slices = _TH2_OVS_HPIPE_COUNT_PER_PIPE; 84 tdm_eschd->num_slices = _TH2_OVS_HPIPE_COUNT_PER_PIPE; 85 86 if (is_flexport) { 87 /* TDM Calendar is always in slice 0 */ 88 sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 89 tdm->tdm_pipe[pipe].idb_tdm, 90 sizeof(int)*_TH2_TDM_LENGTH); 91 sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 92 tdm->tdm_pipe[pipe].mmu_tdm, 93 sizeof(int)*_TH2_TDM_LENGTH); 94 } 95 96 /* OVS */ 97 for (hpipe = 0; hpipe < _TH2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 98 /* IDB OVERSUB*/ 99 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 100 sched->cal_len = _TH2_TDM_LENGTH; 101 sched->num_ovs_groups = _TH2_OVS_GROUP_COUNT_PER_HPIPE; 102 sched->ovs_group_len = _TH2_OVS_GROUP_TDM_LENGTH; 103 sched->num_pkt_sch_or_ovs_space = 1; 104 sched->pkt_sch_or_ovs_space_len = _TH2_PKT_SCH_LENGTH; 105 106 if (is_flexport) { 107 for (group = 0; group < _TH2_OVS_GROUP_COUNT_PER_HPIPE; group++) { 108 for (slot = 0; slot < _TH2_OVS_GROUP_TDM_LENGTH; slot++) { 109 sched->oversub_schedule[group][slot] = 110 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 111 } 112 } 113 for (slot = 0; slot < _TH2_PKT_SCH_LENGTH; slot++) { 114 sched->pkt_sch_or_ovs_space[0][slot] = 115 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 116 } 117 } 118 119 /* MMU OVERSUB */ 120 sched = &tdm_eschd->tdm_schedule_slice[hpipe]; 121 sched->cal_len = _TH2_TDM_LENGTH; 122 sched->num_ovs_groups = _TH2_OVS_GROUP_COUNT_PER_HPIPE; 123 sched->ovs_group_len = _TH2_OVS_GROUP_TDM_LENGTH; 124 sched->num_pkt_sch_or_ovs_space = 1; 125 sched->pkt_sch_or_ovs_space_len = _TH2_PKT_SCH_LENGTH; 126 127 if (is_flexport) { 128 for (group = 0; group < _TH2_OVS_GROUP_COUNT_PER_HPIPE; group++) { 129 for (slot = 0; slot < _TH2_OVS_GROUP_TDM_LENGTH; slot++) { 130 sched->oversub_schedule[group][slot] = 131 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 132 } 133 } 134 for (slot = 0; slot < _TH2_PKT_SCH_LENGTH; slot++) { 135 sched->pkt_sch_or_ovs_space[0][slot] = 136 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 137 } 138 } 139 } 140 } 141 142 if (is_flexport) { 143 port_p2PBLK_inst_mapping = 144 port_schedule_state->in_port_map.port_p2PBLK_inst_mapping; 145 /* pblk info for phy_port */ 146 for (phy_port = 1; phy_port < SOC_MAX_NUM_PORTS; phy_port++) { 147 if (phy_port < TH2_NUM_EXT_PORTS) { 148 port_p2PBLK_inst_mapping[phy_port] = 149 tdm->pblk_info[phy_port].pblk_cal_idx; 150 } else { 151 port_p2PBLK_inst_mapping[phy_port] = -1; 152 } 153 } 154 sal_memcpy(&port_schedule_state->in_port_map.physical_pbm, 155 &si->pbm_25g_use_50g_tdm, sizeof(pbmp_t)); 156 } 157 return SOC_E_NONE; 158 } 159 160 /* 161 * Function: 162 * soc_th2_soc_tdm_update 163 * Purpose: 164 * Update TDM information in SOC with TDM state return from DV FlexPort API 165 * Parameters: 166 * unit - (IN) Unit number. 167 * port_schedule_state - (OUT) Port resource state. 168 * Returns: 169 * BCM_E_xxx 170 * Notes: 171 */ 172 int 173 soc_th2_soc_tdm_update(int unit, 174 soc_port_schedule_state_t *port_schedule_state) 175 { 176 soc_control_t *soc = SOC_CONTROL(unit); 177 soc_info_t *si = &SOC_INFO(unit); 178 _soc_tomahawk2_tdm_t *tdm = soc->tdm_info; 179 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 180 soc_tdm_schedule_t *sched; 181 int pipe, hpipe, port, phy_port, clport, slot; 182 int length, ovs_core_slot_count, ovs_io_slot_count, port_slot_count; 183 int index, group; 184 185 if (tdm == NULL) { 186 /*XGSSIM will skip tdm configuration on TH2*/ 187 if (SAL_BOOT_XGSSIM) { 188 return SOC_E_NONE; 189 } 190 return SOC_E_INIT; 191 } 192 193 /* Copy info from soc_port_schedule_state_t to _soc_tomahawk2_tdm_t */ 194 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 195 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 196 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 197 198 /* TDM Calendar is always in slice 0 */ 199 sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm, 200 tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 201 sizeof(int)*_TH2_TDM_LENGTH); 202 sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm, 203 tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 204 sizeof(int)*_TH2_TDM_LENGTH); 205 206 for (hpipe = 0; hpipe < _TH2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 207 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 208 for (group = 0; group < _TH2_OVS_GROUP_COUNT_PER_HPIPE; group++) { 209 for (slot = 0; slot < _TH2_OVS_GROUP_TDM_LENGTH; slot++) { 210 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot] = 211 sched->oversub_schedule[group][slot]; 212 } 213 } 214 for (slot = 0; slot < _TH2_PKT_SCH_LENGTH; slot++) { 215 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot] = 216 sched->pkt_sch_or_ovs_space[0][slot]; 217 218 } 219 } 220 } 221 222 /* pblk info init */ 223 for (phy_port = 1; phy_port < TH2_NUM_EXT_PORTS; phy_port++) { 224 tdm->pblk_info[phy_port].pblk_cal_idx = -1; 225 tdm->pblk_info[phy_port].pblk_hpipe_num = -1; 226 } 227 228 /* pblk info for phy_port */ 229 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 230 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 231 for (hpipe = 0; hpipe < _TH2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 232 for (group = 0; group < _TH2_OVS_GROUP_COUNT_PER_HPIPE; group++) { 233 for (index = 0; index < _TH2_OVS_GROUP_TDM_LENGTH; index++) { 234 phy_port = 235 tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 236 if (phy_port < TH2_NUM_EXT_PORTS) { 237 tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe; 238 } 239 } 240 } 241 } 242 } 243 244 for (phy_port = 0; phy_port < TH2_NUM_EXT_PORTS; phy_port++) { 245 tdm->pblk_info[phy_port].pblk_cal_idx = 246 port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port]; 247 } 248 249 /* CLPORT port ratio */ 250 for (clport = 0; clport < _TH2_PBLKS_PER_DEV; clport++) { 251 soc_tomahawk2_port_ratio_get(unit, port_schedule_state, clport, 252 &tdm->port_ratio[clport], 1); 253 } 254 255 /* Calculate the oversub ratio */ 256 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 257 /* At MAX Frequency OVS is always 3:2 */ 258 if (si->frequency == 1700) { 259 for (hpipe = 0; hpipe < _TH2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 260 tdm->ovs_ratio_x1000[pipe][hpipe] = 1500; 261 } 262 continue; 263 } 264 265 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 266 /* Count number of OVSB_TOKEN assigned by the TDM code */ 267 for (length = _TH2_TDM_LENGTH; length > 0; length--) { 268 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[length - 1] 269 != TH2_NUM_EXT_PORTS) { 270 break; 271 } 272 } 273 ovs_core_slot_count = 0; 274 for (index = 0; index < length; index++) { 275 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[index] 276 == TH2_OVSB_TOKEN) { 277 ovs_core_slot_count++; 278 } 279 } 280 281 /* At line-rate with less than max frequency, OVS picks the 2:1 */ 282 if (ovs_core_slot_count == 0) { 283 for (hpipe = 0; hpipe < _TH2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 284 tdm->ovs_ratio_x1000[pipe][hpipe] = 2000; 285 } 286 } 287 288 /* Count number of slot needed for half-pipe's oversub I/O bandwidth */ 289 for (hpipe = 0; hpipe < _TH2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 290 ovs_io_slot_count = 0; 291 for (group = 0; group < _TH2_OVS_GROUP_COUNT_PER_HPIPE; group++) { 292 for (index = 0; index < _TH2_OVS_GROUP_TDM_LENGTH; index++) { 293 phy_port = tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 294 if (phy_port == TH2_NUM_EXT_PORTS) { 295 continue; 296 } 297 port = si->port_p2l_mapping[phy_port]; 298 if ((port == -1) || IS_CPU_PORT(unit, port) || 299 IS_LB_PORT(unit, port) || 300 IS_MANAGEMENT_PORT(unit, port)) { 301 LOG_ERROR(BSL_LS_SOC_PORT, 302 (BSL_META_U(unit, 303 "Flexport: Invalid physical " 304 "port %d in OverSub table.\n"), 305 phy_port)); 306 continue; 307 } 308 port_slot_count = si->port_init_speed[port] / 2500; 309 ovs_io_slot_count += port_slot_count; 310 } 311 } 312 if (ovs_core_slot_count != 0) { 313 tdm->ovs_ratio_x1000[pipe][hpipe] = 314 ovs_io_slot_count * 1000 / (ovs_core_slot_count / 2); 315 } 316 } 317 } 318 319 sal_memcpy(&si->pbm_25g_use_50g_tdm, 320 &port_schedule_state->in_port_map.physical_pbm, sizeof(pbmp_t)); 321 322 return SOC_E_NONE; 323 } 324 325 /* 326 * Function: 327 * soc_th2_max_lr_bandwidth 328 * Purpose: 329 * Get the max line rate bandwidth per pipeline 330 * Parameters: 331 * unit - (IN) Unit number. 332 * max_lr_bw - (OUT) Max line rate bandwidth (Gbps). 333 * Returns: 334 * BCM_E_xxx 335 * Notes: 336 */ 337 int 338 soc_th2_max_lr_bandwidth(int unit, uint32 *max_lr_bw) 339 { 340 soc_info_t *si = &SOC_INFO(unit); 341 int cal_universal; 342 int rv = SOC_E_NONE; 343 344 cal_universal = si->fabric_port_enable ? 1 : 0; 345 346 switch (si->frequency) { 347 case 1700: 348 *max_lr_bw = cal_universal ? 1050 : 1095; 349 break; 350 case 1625: 351 *max_lr_bw = cal_universal ? 1002 : 1047; 352 break; 353 case 1525: 354 *max_lr_bw = cal_universal ? 940 : 980; 355 break; 356 case 1425: 357 *max_lr_bw = cal_universal ? 877 : 915; 358 break; 359 case 1325: 360 *max_lr_bw = cal_universal ? 812 : 847; 361 break; 362 case 1275: 363 *max_lr_bw = cal_universal ? 782 : 815; 364 break; 365 case 1225: 366 *max_lr_bw = cal_universal ? 750 : 782; 367 break; 368 case 1125: 369 *max_lr_bw = cal_universal ? 687 : 717; 370 break; 371 case 1050: 372 *max_lr_bw = cal_universal ? 640 : 667; 373 break; 374 case 950: 375 *max_lr_bw = cal_universal ? 575 : 600; 376 break; 377 case 850: 378 *max_lr_bw = cal_universal ? 512 : 535; 379 break; 380 default: 381 *max_lr_bw = 0; 382 rv = SOC_E_INTERNAL; 383 break; 384 } 385 386 return rv; 387 } 388 389 /* 390 * Function: 391 * soc_th2_support_speeds 392 * Purpose: 393 * Get the supported speed of port for specified lanes 394 * Parameters: 395 * unit - (IN) Unit number. 396 * lanes - (IN) Number of Lanes for the port. 397 * speed_mask - (IN) Bitmap for supported speed. 398 * Returns: 399 * BCM_E_xxx 400 * Notes: 401 */ 402 int 403 soc_th2_support_speeds(int unit, int lanes, uint32 *speed_mask) 404 { 405 soc_info_t *si = &SOC_INFO(unit); 406 uint32 speed_valid; 407 408 switch(lanes) { 409 case 1: 410 /* Single Lane Port Speeds */ 411 speed_valid = SOC_PA_SPEED_1000MB | SOC_PA_SPEED_10GB | 412 SOC_PA_SPEED_25GB; 413 if(soc_feature(unit, soc_feature_higig2)) { 414 speed_valid |= SOC_PA_SPEED_11GB | SOC_PA_SPEED_27GB; 415 } 416 break; 417 case 2: 418 /* Dual Lane Port Speeds */ 419 speed_valid = SOC_PA_SPEED_20GB | SOC_PA_SPEED_40GB | SOC_PA_SPEED_50GB; 420 if(soc_feature(unit, soc_feature_higig2)) { 421 speed_valid |= SOC_PA_SPEED_21GB | SOC_PA_SPEED_42GB | 422 SOC_PA_SPEED_53GB; 423 } 424 break; 425 case 4: 426 /* Quad Lane Port Speeds */ 427 speed_valid = SOC_PA_SPEED_40GB | SOC_PA_SPEED_100GB; 428 if(soc_feature(unit, soc_feature_higig2)) { 429 speed_valid |= SOC_PA_SPEED_42GB | SOC_PA_SPEED_106GB; 430 } 431 break; 432 default: 433 return SOC_E_PARAM; 434 } 435 436 if (FALSE == si->fabric_port_enable) { 437 /* Ethernet-optimized Calendar doesn't support any HG speed */ 438 speed_valid &= ~(SOC_PA_SPEED_11GB | SOC_PA_SPEED_21GB | 439 SOC_PA_SPEED_27GB | SOC_PA_SPEED_42GB | 440 SOC_PA_SPEED_53GB | SOC_PA_SPEED_106GB); 441 } else if (si->frequency < 1125) { 442 speed_valid &= ~(SOC_PA_SPEED_27GB | SOC_PA_SPEED_53GB | 443 SOC_PA_SPEED_106GB); 444 } 445 446 if (si->frequency < 1050) { 447 speed_valid &= ~(SOC_PA_SPEED_25GB | SOC_PA_SPEED_50GB | 448 SOC_PA_SPEED_100GB); 449 } 450 451 *speed_mask = speed_valid; 452 453 return SOC_E_NONE; 454 } 455 456 #ifdef BCM_WARM_BOOT_SUPPORT 457 int soc_th2_flexport_scache_allocate(int unit) 458 { 459 int rv = SOC_E_NONE; 460 uint8 *flexport_scache_ptr; 461 soc_scache_handle_t scache_handle; 462 uint32 alloc_get = 0; 463 uint32 alloc_size = 0; 464 int stable_size; 465 int default_ver = SOC_FLEXPORT_WB_DEFAULT_VERSION; 466 467 alloc_size = (sizeof(int) * _TH2_PHY_PORTS_PER_DEV) + /* phy to logical*/ 468 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* logical to phy */ 469 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* max port speed */ 470 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* init port speed */ 471 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* num of lanes */ 472 (sizeof(pbmp_t)) + /* HG bitmap */ 473 (sizeof(pbmp_t)) + /* Disabled bitmap */ 474 (sizeof(pbmp_t)); /* pbm_25g_use_50g_tdm */ 475 alloc_get = alloc_size; 476 477 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 478 /* check to see if an scache table has been configured */ 479 rv = soc_stable_size_get(unit, &stable_size); 480 if (SOC_FAILURE(rv) || stable_size <= 0) { 481 return rv; 482 } 483 484 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 485 TRUE, &alloc_get, 486 &flexport_scache_ptr, 487 default_ver, 488 NULL); 489 490 if (rv == SOC_E_CONFIG) { 491 /* Probably Level1 */ 492 return SOC_E_NONE; 493 } 494 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 495 if (alloc_get != alloc_size) { 496 /* Expected size doesn't match retrieved size */ 497 LOG_ERROR(BSL_LS_SOC_COMMON, 498 (BSL_META_U(unit, 499 "ERROR: scache memory for flexport size mismatch" 500 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 501 return SOC_E_INTERNAL; 502 } 503 504 if (NULL == flexport_scache_ptr) { 505 LOG_ERROR(BSL_LS_SOC_COMMON, 506 (BSL_META_U(unit, 507 "ERROR: scache memory not allocated for flexport" 508 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 509 return SOC_E_MEMORY; 510 } 511 LOG_VERBOSE(BSL_LS_SOC_COMMON, 512 (BSL_META_U(unit, 513 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 514 return SOC_E_NONE; 515 516 } 517 518 /* 519 * Function: 520 * soc_th2_flexport_scache_sync 521 * Purpose: 522 * Record Port info that maybe changed during flexport for Level 2 WB 523 * 524 * Warm Boot Version Map: 525 * 526 * BCM_WB_VERSION_1_0 527 * port_p2l_mapping 528 * port_l2p_mapping 529 * port_speed_max 530 * port_init_speed 531 * port_num_lanes 532 * disabled_bitmap 533 * 534 * Parameters: 535 * unit - StrataSwitch unit number. 536 * Returns: 537 * SOC_E_XXX 538 */ 539 int soc_th2_flexport_scache_sync(int unit) 540 { 541 uint8 *flexport_scache_ptr; 542 soc_scache_handle_t scache_handle; 543 uint32 alloc_get = 0; 544 uint32 alloc_size = 0; 545 uint32 var_size = 0; 546 soc_info_t *si = &SOC_INFO(unit); 547 uint32 scache_offset=0; 548 int rv = 0; 549 550 alloc_size = (sizeof(int) * _TH2_PHY_PORTS_PER_DEV) + /* phy to logical*/ 551 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* logical to phy */ 552 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* max port speed */ 553 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* init port speed */ 554 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* num of lanes */ 555 (sizeof(pbmp_t)) + /* HG bitmap */ 556 (sizeof(pbmp_t)) + /* Disabled bitmap */ 557 (sizeof(pbmp_t)); /* pbm_25g_use_50g_tdm */ 558 559 alloc_get = alloc_size; 560 561 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 562 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 563 FALSE, &alloc_get, 564 &flexport_scache_ptr, 565 SOC_FLEXPORT_WB_DEFAULT_VERSION, 566 NULL); 567 if (rv == SOC_E_NOT_FOUND) { 568 /* Probably Level1 */ 569 return SOC_E_NONE; 570 } 571 if (alloc_get != alloc_size) { 572 /* Expected size doesn't match retrieved size */ 573 LOG_ERROR(BSL_LS_SOC_COMMON, 574 (BSL_META_U(unit, 575 "ERROR: scache memory for flexport size mismatch" 576 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 577 return SOC_E_INTERNAL; 578 } 579 if (NULL == flexport_scache_ptr) { 580 LOG_ERROR(BSL_LS_SOC_COMMON, 581 (BSL_META_U(unit, 582 "ERROR: scache memory not allocated for flexport" 583 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 584 return SOC_E_MEMORY; 585 } 586 587 /* Physical to logical port mapping */ 588 var_size = sizeof(int) * _TH2_PHY_PORTS_PER_DEV; 589 sal_memcpy(&flexport_scache_ptr[scache_offset], 590 si->port_p2l_mapping, var_size); 591 scache_offset += var_size; 592 593 var_size = sizeof(int) * _TH2_DEV_PORTS_PER_DEV; 594 595 /* Logical to Physical port mapping */ 596 sal_memcpy(&flexport_scache_ptr[scache_offset], 597 si->port_l2p_mapping, var_size); 598 scache_offset += var_size; 599 600 /* Max port speed */ 601 sal_memcpy(&flexport_scache_ptr[scache_offset], 602 si->port_speed_max, var_size); 603 scache_offset += var_size; 604 605 /* Init port speed */ 606 sal_memcpy(&flexport_scache_ptr[scache_offset], 607 si->port_init_speed, var_size); 608 scache_offset += var_size; 609 610 /* Num of lanes */ 611 sal_memcpy(&flexport_scache_ptr[scache_offset], 612 si->port_num_lanes, var_size); 613 scache_offset += var_size; 614 615 616 /* HG Bitmap */ 617 sal_memcpy(&flexport_scache_ptr[scache_offset], 618 &si->hg.bitmap, 619 sizeof(pbmp_t)); 620 scache_offset += sizeof(pbmp_t); 621 622 /* Disabled Port Bitmap */ 623 sal_memcpy(&flexport_scache_ptr[scache_offset], 624 &si->all.disabled_bitmap, 625 sizeof(pbmp_t)); 626 scache_offset += sizeof(pbmp_t); 627 628 /* Bitmap of 25G port use 50G tdm */ 629 sal_memcpy(&flexport_scache_ptr[scache_offset], 630 &si->pbm_25g_use_50g_tdm, 631 sizeof(pbmp_t)); 632 scache_offset += sizeof(pbmp_t); 633 634 LOG_VERBOSE(BSL_LS_SOC_COMMON, 635 (BSL_META_U(unit, 636 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 637 638 return SOC_E_NONE; 639 } 640 641 /* 642 * Function: 643 * soc_th2_flexport_scache_recovery 644 * Purpose: 645 * Recover Port info that maybe changed during flexport for Level 2 WB 646 * 647 * Warm Boot Version Map: 648 * 649 * BCM_WB_VERSION_1_0 650 * port_p2l_mapping 651 * port_l2p_mapping 652 * port_speed_max 653 * port_init_speed 654 * port_num_lanes 655 * disabled_bitmap 656 * 657 * Parameters: 658 * unit - StrataSwitch unit number. 659 * Returns: 660 * SOC_E_XXX 661 */ 662 int soc_th2_flexport_scache_recovery(int unit) 663 { 664 uint32 alloc_get = 0; 665 uint32 alloc_size = 0; 666 int rv = SOC_E_NONE; 667 uint8 *flexport_scache_ptr = NULL; 668 soc_scache_handle_t scache_handle; 669 uint32 scache_offset=0; 670 uint32 var_size = 0; 671 uint16 recovered_ver = 0; 672 int realloc_size = 0; 673 soc_info_t *si = &SOC_INFO(unit); 674 675 alloc_size = (sizeof(int) * _TH2_PHY_PORTS_PER_DEV) + /* phy to logical*/ 676 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* logical to phy */ 677 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* max port speed */ 678 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* init port speed */ 679 (sizeof(int) * _TH2_DEV_PORTS_PER_DEV) + /* num of lanes */ 680 (sizeof(pbmp_t)) + /* HG bitmap */ 681 (sizeof(pbmp_t)) + /* Disabled bitmap */ 682 (sizeof(pbmp_t)); /* pbm_25g_use_50g_tdm */ 683 684 alloc_get = alloc_size; 685 686 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 687 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 688 FALSE, &alloc_get, 689 &flexport_scache_ptr, 690 SOC_FLEXPORT_WB_DEFAULT_VERSION, 691 &recovered_ver); 692 if (SOC_FAILURE(rv)) { 693 if ((rv == SOC_E_CONFIG) || 694 (rv == SOC_E_NOT_FOUND)) { 695 /* warmboot file does not contain this 696 * module, or the warmboot state does not exist. 697 * in this case return SOC_E_NOT_FOUND 698 */ 699 return SOC_E_NOT_FOUND; 700 } else { 701 /* Only Level2 - flexport treat this as a error */ 702 LOG_ERROR(BSL_LS_SOC_COMMON, 703 (BSL_META_U(unit, 704 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 705 return rv; 706 } 707 } 708 if (alloc_get != alloc_size) { 709 /* Expected size doesn't match retrieved size */ 710 LOG_ERROR(BSL_LS_SOC_COMMON, 711 (BSL_META_U(unit, 712 "ERROR: scache recovery for flexport" 713 "%s()[LINE:%d] DONE \n"), 714 FUNCTION_NAME(), __LINE__)); 715 return SOC_E_INTERNAL; 716 } 717 718 if (NULL == flexport_scache_ptr) { 719 LOG_ERROR(BSL_LS_SOC_COMMON, 720 (BSL_META_U(unit, 721 "ERROR: scache recovery for flexport" 722 "%s()[LINE:%d] DONE \n"), 723 FUNCTION_NAME(), __LINE__)); 724 return SOC_E_MEMORY; 725 } 726 727 /*Physical to logical port mapping */ 728 var_size = (sizeof(int) * _TH2_PHY_PORTS_PER_DEV); 729 sal_memcpy(si->port_p2l_mapping, 730 &flexport_scache_ptr[scache_offset], 731 var_size); 732 scache_offset += var_size; 733 734 var_size = (sizeof(int) * _TH2_DEV_PORTS_PER_DEV); 735 736 /*Logical to Physical port mapping*/ 737 sal_memcpy(si->port_l2p_mapping, 738 &flexport_scache_ptr[scache_offset], 739 var_size); 740 scache_offset += var_size; 741 742 /* Max port speed */ 743 sal_memcpy(_soc_th2_port_speed_cap[unit], 744 &flexport_scache_ptr[scache_offset], 745 var_size); 746 scache_offset += var_size; 747 748 /* Init port speed */ 749 sal_memcpy(si->port_speed_max, 750 &flexport_scache_ptr[scache_offset], 751 var_size); 752 scache_offset += var_size; 753 754 /* Num of lanes */ 755 sal_memcpy(si->port_num_lanes, 756 &flexport_scache_ptr[scache_offset], 757 var_size); 758 scache_offset += var_size; 759 760 /* HG Bitmap */ 761 sal_memcpy(&si->hg.bitmap, 762 &flexport_scache_ptr[scache_offset], 763 sizeof(pbmp_t)); 764 scache_offset += sizeof(pbmp_t); 765 766 /* Disabled Port Bitmap */ 767 sal_memcpy(&si->all.disabled_bitmap, 768 &flexport_scache_ptr[scache_offset], 769 sizeof(pbmp_t)); 770 scache_offset += sizeof(pbmp_t); 771 772 /* Bitmap of 25G port use 50G tdm */ 773 if (recovered_ver >= SOC_FLEXPORT_WB_VERSION_1_1) { 774 sal_memcpy(&si->pbm_25g_use_50g_tdm, 775 &flexport_scache_ptr[scache_offset], 776 sizeof(pbmp_t)); 777 scache_offset += sizeof(pbmp_t); 778 } else { 779 realloc_size += sizeof(pbmp_t); 780 } 781 782 if (realloc_size > 0) { 783 SOC_IF_ERROR_RETURN 784 (soc_scache_realloc(unit, scache_handle, realloc_size)); 785 } 786 787 LOG_VERBOSE(BSL_LS_SOC_COMMON, 788 (BSL_META_U(unit, 789 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 790 791 return SOC_E_NONE; 792 } 793 #endif /* BCM_WARM_BOOT_SUPPORT */ 794 795 #ifndef BCM_SW_STATE_DUMP_DISABLE 796 void 797 soc_th2_flexport_sw_dump(int unit) 798 { 799 int port, phy_port, mmu_port, pipe, pm, cosq, numq, uc_cosq, uc_numq; 800 int max_speed, init_speed, num_lanes; 801 char pfmt[SOC_PBMP_FMT_LEN]; 802 803 LOG_CLI((BSL_META_U(unit, 804 " port(log/phy/mmu) pipe pm lanes " 805 "speed(Max) uc_Qbase/Numq mc_Qbase/Numq\n"))); 806 PBMP_ALL_ITER(unit, port) { 807 pipe = SOC_INFO(unit).port_pipe[port]; 808 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 809 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 810 num_lanes = SOC_INFO(unit).port_num_lanes[port]; 811 pm = SOC_INFO(unit).port_serdes[port]; 812 max_speed = SOC_INFO(unit).port_speed_max[port]; 813 init_speed = SOC_INFO(unit).port_init_speed[port]; 814 cosq = SOC_INFO(unit).port_cosq_base[port]; 815 numq = SOC_INFO(unit).port_num_cosq[port]; 816 uc_cosq = SOC_INFO(unit).port_uc_cosq_base[port]; 817 uc_numq = SOC_INFO(unit).port_num_uc_cosq[port]; 818 819 LOG_CLI((BSL_META_U(unit, 820 " %4s(%3d/%3d/%3d) %4d %2d %5d %7d(%7d) " 821 "%6d/%-6d %6d/%-6d\n"), 822 SOC_INFO(unit).port_name[port], port, phy_port, mmu_port, 823 pipe, pm, num_lanes, init_speed, max_speed, 824 uc_cosq, uc_numq, cosq, numq)); 825 } 826 827 LOG_CLI((BSL_META_U(unit, 828 "\n Oversub Bitmap: %s"), 829 SOC_PBMP_FMT(SOC_INFO(unit).oversub_pbm, pfmt))); 830 LOG_CLI((BSL_META_U(unit, 831 "\n Disabled Bitmap: %s \n"), 832 SOC_PBMP_FMT(SOC_INFO(unit).all.disabled_bitmap, pfmt))); 833 } 834 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 835 836 /* 837 * Function: 838 * soc_th2_port_mode_get 839 * Description: 840 * Get port mode by giving any logical port of TSC4 841 * Parameters: 842 * unit - Device number 843 * port - Logical port 844 * int* - Port Mode 845 * 846 * Each TSC4 can be configured into following 5 mode: 847 * Lane number 0 1 2 3 848 * ------------ --- --- --- --- 849 * quad port 25G 25G 25G 25G 850 * tri_012 port 25G 25G 50G x 851 * tri_023 port 50G x 25G 25G 852 * dual port 50G x 50G x 853 * single port 100G x x x 854 */ 855 int 856 soc_th2_port_mode_get(int unit, int logical_port, int *mode) 857 { 858 soc_info_t *si; 859 int lane; 860 int port, first_phyport, phy_port; 861 int num_lanes[_TH2_PORTS_PER_PBLK]; 862 863 si = &SOC_INFO(unit); 864 first_phyport = PORT_BLOCK_BASE_PORT(logical_port); 865 866 for (lane = 0; lane < _TH2_PORTS_PER_PBLK; lane++) { 867 phy_port = first_phyport + lane; 868 port = si->port_p2l_mapping[phy_port]; 869 if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 870 num_lanes[lane] = -1; 871 } else { 872 num_lanes[lane] = si->port_num_lanes[port]; 873 } 874 } 875 876 if (num_lanes[0] == 4) { 877 *mode = SOC_TH2_PORT_MODE_QUAD; 878 } else if (num_lanes[0] == 2 && num_lanes[2] == 2) { 879 *mode = SOC_TH2_PORT_MODE_DUAL; 880 } else if (num_lanes[0] == 2 && (num_lanes[2] == 1 || num_lanes[3] == 1)) { 881 *mode = SOC_TH2_PORT_MODE_TRI_023; 882 } else if ((num_lanes[0] == 1 || num_lanes[1] == 1) && num_lanes[2] == 2) { 883 *mode = SOC_TH2_PORT_MODE_TRI_012; 884 } else { 885 *mode = SOC_TH2_PORT_MODE_SINGLE; 886 } 887 888 return SOC_E_NONE; 889 } 890 891 892 /* 893 * Function: 894 * soc_th2_speed_mix_validate 895 * Purpose: 896 * Check if the mix of all ports speed is valid 897 * Parameters: 898 * unit - Unit. 899 * speed_mask - Bitmap of speed on all ports 900 * Returns: 901 * SOC_E_NONE 902 * SOC_E_CONFIG 903 */ 904 int 905 soc_th2_speed_mix_validate(int unit, uint32 speed_mask) 906 { 907 uint32 count; 908 soc_info_t *si; 909 910 si = &SOC_INFO(unit); 911 912 count = _shr_popcount(speed_mask); 913 914 /* OverSub mode supports 10/25/40/50/100G and 10/20/40/100G , 915 * while LineRate mode only supports 10/25/50/100G and 10/20/40/100G. 916 */ 917 if ((count == 4) && 918 (((!si->oversub_mode) && 919 ((speed_mask & SOC_PA_SPEED_20GB) || (speed_mask & SOC_PA_SPEED_40GB))) 920 || 921 ((si->oversub_mode) && (speed_mask & SOC_PA_SPEED_20GB))) 922 && 923 ((speed_mask & SOC_PA_SPEED_25GB) || 924 (speed_mask & SOC_PA_SPEED_50GB))) { 925 LOG_ERROR(BSL_LS_BCM_COMMON, 926 (BSL_META_U(unit, 927 "Port configurations that contain 4 speed class " 928 "and both 20G/40G and 25G/50G port speed " 929 "are not supported.\n"))); 930 return SOC_E_PARAM; 931 } 932 933 if ((count < 4) && 934 ((speed_mask & SOC_PA_SPEED_20GB) && (speed_mask & SOC_PA_SPEED_25GB))) { 935 LOG_ERROR(BSL_LS_BCM_COMMON, 936 (BSL_META_U(unit, 937 "Port configurations that contain both 20G " 938 "and 25G port speed are not supported.\n"))); 939 return SOC_E_PARAM; 940 } 941 942 if ((count == _TH2_TDM_OS_SPEED_CLASS_MAX) && 943 (speed_mask & SOC_PA_SPEED_20GB)) { 944 LOG_ERROR(BSL_LS_BCM_COMMON, 945 (BSL_META_U(unit, 946 "When contain %d speed class, only combination " 947 "10/25/40/50/100G is supported under oversub " 948 "mode.\n"), _TH2_TDM_OS_SPEED_CLASS_MAX)); 949 return SOC_E_PARAM; 950 } 951 952 return SOC_E_NONE; 953 } 954 955 #endif /* BCM_TOMAHAWK2_SUPPORT */