port.c (28385B)
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: TH3 SOC Port driver. 9 */ 10 #include <shared/bsl.h> 11 #include <soc/error.h> 12 #include <soc/defs.h> 13 #include <soc/tdm/core/tdm_top.h> 14 15 #if defined(BCM_TOMAHAWK3_SUPPORT) 16 #include <soc/init/tomahawk3_tdm.h> 17 #include <soc/tomahawk3.h> 18 #include <soc/scache.h> 19 20 #ifdef BCM_WARM_BOOT_SUPPORT 21 22 #define SOC_FLEXPORT_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 23 #define SOC_FLEXPORT_WB_DEFAULT_VERSION SOC_FLEXPORT_WB_VERSION_1_0 24 25 extern int 26 _soc_th3_port_speed_cap[SOC_MAX_NUM_DEVICES][_TH3_DEV_PORTS_PER_DEV]; 27 #endif 28 29 /* 30 * Function: 31 * soc_th3_port_schedule_tdm_init 32 * Purpose: 33 * Initialize TDM information in port_schedule_state that will be passed 34 * to DV FlexPort API 35 * Parameters: 36 * unit - (IN) Unit number. 37 * port_schedule_state - (OUT) Port resource state. 38 * Returns: 39 * BCM_E_xxx 40 * Notes: 41 * If called during Scheduler Initialization, only below values need to be 42 * properly set: 43 * soc_tdm_schedule_pipe_t::num_slices 44 * soc_tdm_schedule_t:: cal_len 45 * soc_tdm_schedule_t:: num_ovs_groups 46 * soc_tdm_schedule_t:: ovs_group_len 47 * soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space 48 * soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len 49 */ 50 int 51 soc_th3_port_schedule_tdm_init(int unit, 52 soc_port_schedule_state_t *port_schedule_state) 53 { 54 #if 1 55 56 soc_control_t *soc = SOC_CONTROL(unit); 57 _soc_tomahawk3_tdm_t *tdm = soc->tdm_info; 58 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 59 soc_tdm_schedule_t *sched; 60 int pipe, hpipe, is_flexport; 61 62 if (tdm == NULL) { 63 /*XGSSIM will skip tdm configuration on TH3*/ 64 if (SAL_BOOT_SIMULATION) { 65 return SOC_E_NONE; 66 } 67 return SOC_E_INIT; 68 } 69 70 is_flexport = port_schedule_state->is_flexport; 71 72 /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */ 73 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) { 74 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 75 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 76 77 tdm_ischd->num_slices = _TH3_OVS_HPIPE_COUNT_PER_PIPE; 78 tdm_eschd->num_slices = _TH3_OVS_HPIPE_COUNT_PER_PIPE; 79 80 if (is_flexport) { 81 /* TDM Calendar is always in slice 0 */ 82 sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 83 tdm->tdm_pipe[pipe].idb_tdm, 84 sizeof(int)*_TH3_TDM_LENGTH); 85 sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 86 tdm->tdm_pipe[pipe].mmu_tdm, 87 sizeof(int)*_TH3_TDM_LENGTH); 88 } 89 90 /* OVS */ 91 for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 92 /* IDB OVERSUB*/ 93 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 94 sched->cal_len = _TH3_TDM_LENGTH; 95 96 /* TDM says everything related to hpipe and pblk can be removed except 97 * sched->cal_len = _TH3_TDM_LENGTH; */ 98 #if 0 99 sched->num_ovs_groups = _TH3_OVS_GROUP_COUNT_PER_HPIPE; 100 sched->ovs_group_len = _TH3_OVS_GROUP_TDM_LENGTH; 101 sched->num_pkt_sch_or_ovs_space = 1; 102 sched->pkt_sch_or_ovs_space_len = _TH3_PKT_SCH_LENGTH; 103 104 if (is_flexport) { 105 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) { 106 for (slot = 0; slot < _TH3_OVS_GROUP_TDM_LENGTH; slot++) { 107 sched->oversub_schedule[group][slot] = 108 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 109 } 110 } 111 for (slot = 0; slot < _TH3_PKT_SCH_LENGTH; slot++) { 112 sched->pkt_sch_or_ovs_space[0][slot] = 113 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 114 } 115 } 116 117 /* MMU OVERSUB */ 118 sched = &tdm_eschd->tdm_schedule_slice[hpipe]; 119 sched->cal_len = _TH3_TDM_LENGTH; 120 sched->num_ovs_groups = _TH3_OVS_GROUP_COUNT_PER_HPIPE; 121 sched->ovs_group_len = _TH3_OVS_GROUP_TDM_LENGTH; 122 sched->num_pkt_sch_or_ovs_space = 1; 123 sched->pkt_sch_or_ovs_space_len = _TH3_PKT_SCH_LENGTH; 124 125 if (is_flexport) { 126 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) { 127 for (slot = 0; slot < _TH3_OVS_GROUP_TDM_LENGTH; slot++) { 128 sched->oversub_schedule[group][slot] = 129 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 130 } 131 } 132 for (slot = 0; slot < _TH3_PKT_SCH_LENGTH; slot++) { 133 sched->pkt_sch_or_ovs_space[0][slot] = 134 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 135 } 136 } 137 #endif 138 } 139 } 140 141 /* TDM says everything related to hpipe and pblk can be removed except 142 * sched->cal_len = _TH3_TDM_LENGTH; */ 143 #if 0 144 if (is_flexport) { 145 port_p2PBLK_inst_mapping = 146 port_schedule_state->in_port_map.port_p2PBLK_inst_mapping; 147 /* pblk info for phy_port */ 148 for (phy_port = 1; phy_port < TH3_NUM_EXT_PORTS; phy_port++) { 149 if (tdm->pblk_info[phy_port].pblk_cal_idx == -1) { 150 continue; 151 } 152 port_p2PBLK_inst_mapping[phy_port] = 153 tdm->pblk_info[phy_port].pblk_cal_idx; 154 } 155 } 156 #endif 157 #endif 158 return SOC_E_NONE; 159 } 160 161 /* 162 * Function: 163 * soc_th3_soc_tdm_update 164 * Purpose: 165 * Update TDM information in SOC with TDM state return from DV FlexPort API 166 * Parameters: 167 * unit - (IN) Unit number. 168 * port_schedule_state - (OUT) Port resource state. 169 * Returns: 170 * BCM_E_xxx 171 * Notes: 172 */ 173 int 174 soc_th3_soc_tdm_update(int unit, 175 soc_port_schedule_state_t *port_schedule_state) 176 { 177 #if 1 178 179 soc_control_t *soc = SOC_CONTROL(unit); 180 _soc_tomahawk3_tdm_t *tdm = soc->tdm_info; 181 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 182 int pipe, cdport; 183 184 if (tdm == NULL) { 185 /*XGSSIM will skip tdm configuration on TH3*/ 186 if (SAL_BOOT_XGSSIM) { 187 return SOC_E_NONE; 188 } 189 return SOC_E_INIT; 190 } 191 192 /* Copy info from soc_port_schedule_state_t to _soc_tomahawk3_tdm_t */ 193 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) { 194 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 195 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 196 197 /* TDM Calendar is always in slice 0 */ 198 sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm, 199 tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 200 sizeof(int)*_TH3_TDM_LENGTH); 201 sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm, 202 tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 203 sizeof(int)*_TH3_TDM_LENGTH); 204 /* TDM says can be removed */ 205 #if 0 206 for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 207 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 208 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) { 209 for (slot = 0; slot < _TH3_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 < _TH3_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 #endif 221 } 222 /* TDM says pblk stuff can be removed */ 223 #if 0 224 /* pblk info init */ 225 for (phy_port = 1; phy_port < TH3_NUM_EXT_PORTS; phy_port++) { 226 tdm->pblk_info[phy_port].pblk_cal_idx = -1; 227 tdm->pblk_info[phy_port].pblk_hpipe_num = -1; 228 } 229 230 /* pblk info for phy_port */ 231 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) { 232 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 233 for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 234 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) { 235 for (index = 0; index < _TH3_OVS_GROUP_TDM_LENGTH; index++) { 236 phy_port = 237 tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 238 if (phy_port < TH3_NUM_EXT_PORTS) { 239 tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe; 240 tdm->pblk_info[phy_port].pblk_cal_idx = 241 port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port]; 242 } 243 } 244 } 245 } 246 } 247 #endif 248 249 /* Port Macros in TH3 have 2 MACs. Mac 0 is in bits 0-3, Mac 1 is in bits 4-7 */ 250 /* CDPORT port ratio */ 251 for (cdport = 0; cdport < _TH3_PBLKS_PER_DEV; cdport++) { 252 soc_tomahawk3_port_ratio_get_schedule_state(unit, port_schedule_state, cdport, 253 &tdm->port_ratio[cdport], 1); 254 } 255 /* TDM says should be removed or completely redefined for TH3 */ 256 #if 0 257 /* Calculate the oversub ratio */ 258 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) { 259 /* At MAX Frequency OVS is always 3:2 */ 260 if (si->frequency == 1700) { 261 for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 262 tdm->ovs_ratio_x1000[pipe][hpipe] = 1500; 263 } 264 continue; 265 } 266 267 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 268 /* Count number of OVSB_TOKEN assigned by the TDM code */ 269 for (length = _TH3_TDM_LENGTH; length > 0; length--) { 270 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[length - 1] 271 != TH3_NUM_EXT_PORTS) { 272 break; 273 } 274 } 275 ovs_core_slot_count = 0; 276 for (index = 0; index < length; index++) { 277 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[index] 278 == TH3_OVSB_TOKEN) { 279 ovs_core_slot_count++; 280 } 281 } 282 283 /* At line-rate with less than max frequency, OVS picks the 2:1 */ 284 if (ovs_core_slot_count == 0) { 285 for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 286 tdm->ovs_ratio_x1000[pipe][hpipe] = 2000; 287 } 288 } 289 290 /* Count number of slot needed for half-pipe's oversub I/O bandwidth */ 291 for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 292 ovs_io_slot_count = 0; 293 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) { 294 for (index = 0; index < _TH3_OVS_GROUP_TDM_LENGTH; index++) { 295 phy_port = tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 296 if (phy_port == TH3_NUM_EXT_PORTS) { 297 continue; 298 } 299 port = si->port_p2l_mapping[phy_port]; 300 if ((port == -1) || IS_CPU_PORT(unit, port) || 301 IS_LB_PORT(unit, port) || 302 IS_MANAGEMENT_PORT(unit, port)) { 303 LOG_ERROR(BSL_LS_SOC_PORT, 304 (BSL_META_U(unit, 305 "Flexport: Invalid physical " 306 "port %d in OverSub table.\n"), 307 phy_port)); 308 continue; 309 } 310 port_slot_count = si->port_init_speed[port] / 2500; 311 ovs_io_slot_count += port_slot_count; 312 } 313 } 314 if (ovs_core_slot_count != 0) { 315 tdm->ovs_ratio_x1000[pipe][hpipe] = 316 ovs_io_slot_count * 1000 / (ovs_core_slot_count / 2); 317 } 318 } 319 } 320 #endif 321 #endif 322 return SOC_E_NONE; 323 } 324 325 /* 326 * Function: 327 * soc_th3_support_speeds 328 * Purpose: 329 * Get the supported speed of port for specified lanes 330 * Parameters: 331 * unit - (IN) Unit number. 332 * lanes - (IN) Number of Lanes for the port. 333 * speed_mask - (IN) Bitmap for supported speed. 334 * Returns: 335 * BCM_E_xxx 336 * Notes: This is NOT supported because PM8x50 is not supported in 337 * bcm_port_ability_t 338 */ 339 int 340 soc_th3_support_speeds(int unit, int lanes, uint32 *speed_mask) 341 { 342 *speed_mask = 0; 343 344 return SOC_E_NONE; 345 } 346 347 #ifdef BCM_WARM_BOOT_SUPPORT 348 int soc_th3_flexport_scache_allocate(int unit) 349 { 350 int rv = SOC_E_NONE; 351 uint8 *flexport_scache_ptr; 352 soc_scache_handle_t scache_handle; 353 uint32 alloc_get = 0; 354 uint32 alloc_size = 0; 355 int stable_size; 356 int default_ver = SOC_FLEXPORT_WB_DEFAULT_VERSION; 357 358 alloc_size = (sizeof(int) * _TH3_PHY_PORTS_PER_DEV) + /* phy to logical*/ 359 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* logical to phy */ 360 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* max port speed */ 361 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* init port speed */ 362 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* num of lanes */ 363 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port fec*/ 364 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port phy lane config */ 365 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port link training */ 366 (sizeof(pbmp_t)); /* Disabled bitmap */ 367 alloc_get = alloc_size; 368 369 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 370 /* check to see if an scache table has been configured */ 371 rv = soc_stable_size_get(unit, &stable_size); 372 if (SOC_FAILURE(rv) || stable_size <= 0) { 373 return rv; 374 } 375 376 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 377 TRUE, &alloc_get, 378 &flexport_scache_ptr, 379 default_ver, 380 NULL); 381 382 if (rv == SOC_E_CONFIG) { 383 /* Probably Level1 */ 384 return SOC_E_NONE; 385 } 386 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 387 if (alloc_get != alloc_size) { 388 /* Expected size doesn't match retrieved size */ 389 LOG_ERROR(BSL_LS_SOC_COMMON, 390 (BSL_META_U(unit, 391 "ERROR: scache memory for flexport size mismatch" 392 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 393 return SOC_E_INTERNAL; 394 } 395 396 if (NULL == flexport_scache_ptr) { 397 LOG_ERROR(BSL_LS_SOC_COMMON, 398 (BSL_META_U(unit, 399 "ERROR: scache memory not allocated for flexport" 400 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 401 return SOC_E_MEMORY; 402 } 403 LOG_VERBOSE(BSL_LS_SOC_COMMON, 404 (BSL_META_U(unit, 405 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 406 return SOC_E_NONE; 407 408 } 409 410 /* 411 * Function: 412 * soc_th3_flexport_scache_sync 413 * Purpose: 414 * Record Port info that maybe changed during flexport for Level 2 WB 415 * 416 * Warm Boot Version Map: 417 * 418 * BCM_WB_VERSION_1_0 419 * port_p2l_mapping 420 * port_l2p_mapping 421 * port_speed_max 422 * port_init_speed 423 * port_num_lanes 424 * disabled_bitmap 425 * 426 * Parameters: 427 * unit - StrataSwitch unit number. 428 * Returns: 429 * SOC_E_XXX 430 */ 431 int soc_th3_flexport_scache_sync(int unit) 432 { 433 uint8 *flexport_scache_ptr; 434 soc_scache_handle_t scache_handle; 435 uint32 alloc_get = 0; 436 uint32 alloc_size = 0; 437 uint32 var_size = 0; 438 soc_info_t *si = &SOC_INFO(unit); 439 uint32 scache_offset=0; 440 int rv = 0; 441 442 alloc_size = (sizeof(int) * _TH3_PHY_PORTS_PER_DEV) + /* phy to logical*/ 443 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* logical to phy */ 444 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* max port speed */ 445 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* init port speed */ 446 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* num of lanes */ 447 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port fec*/ 448 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port phy lane config */ 449 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port link training */ 450 (sizeof(pbmp_t)); /* Disabled bitmap */ 451 452 alloc_get = alloc_size; 453 454 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 455 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 456 FALSE, &alloc_get, 457 &flexport_scache_ptr, 458 SOC_FLEXPORT_WB_DEFAULT_VERSION, 459 NULL); 460 if (rv == SOC_E_NOT_FOUND) { 461 /* Probably Level1 */ 462 return SOC_E_NONE; 463 } 464 if (alloc_get != alloc_size) { 465 /* Expected size doesn't match retrieved size */ 466 LOG_ERROR(BSL_LS_SOC_COMMON, 467 (BSL_META_U(unit, 468 "ERROR: scache memory for flexport size mismatch" 469 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 470 return SOC_E_INTERNAL; 471 } 472 if (NULL == flexport_scache_ptr) { 473 LOG_ERROR(BSL_LS_SOC_COMMON, 474 (BSL_META_U(unit, 475 "ERROR: scache memory not allocated for flexport" 476 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 477 return SOC_E_MEMORY; 478 } 479 480 /* Physical to logical port mapping */ 481 var_size = sizeof(int) * _TH3_PHY_PORTS_PER_DEV; 482 sal_memcpy(&flexport_scache_ptr[scache_offset], 483 si->port_p2l_mapping, var_size); 484 scache_offset += var_size; 485 486 var_size = sizeof(int) * _TH3_DEV_PORTS_PER_DEV; 487 488 /* Logical to Physical port mapping */ 489 sal_memcpy(&flexport_scache_ptr[scache_offset], 490 si->port_l2p_mapping, var_size); 491 scache_offset += var_size; 492 493 /* Max port speed */ 494 sal_memcpy(&flexport_scache_ptr[scache_offset], 495 si->port_speed_max, var_size); 496 scache_offset += var_size; 497 498 /* Init port speed */ 499 sal_memcpy(&flexport_scache_ptr[scache_offset], 500 si->port_init_speed, var_size); 501 scache_offset += var_size; 502 503 /* Num of lanes */ 504 sal_memcpy(&flexport_scache_ptr[scache_offset], 505 si->port_num_lanes, var_size); 506 scache_offset += var_size; 507 508 /* Fec */ 509 sal_memcpy(&flexport_scache_ptr[scache_offset], 510 si->port_fec_type, var_size); 511 scache_offset += var_size; 512 513 /* Phy Lane Config */ 514 sal_memcpy(&flexport_scache_ptr[scache_offset], 515 si->port_phy_lane_config, var_size); 516 scache_offset += var_size; 517 518 /* Link Training */ 519 sal_memcpy(&flexport_scache_ptr[scache_offset], 520 si->port_link_training, var_size); 521 scache_offset += var_size; 522 523 /* Disabled Port Bitmap */ 524 sal_memcpy(&flexport_scache_ptr[scache_offset], 525 &si->all.disabled_bitmap, 526 sizeof(pbmp_t)); 527 scache_offset += sizeof(pbmp_t); 528 529 LOG_VERBOSE(BSL_LS_SOC_COMMON, 530 (BSL_META_U(unit, 531 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 532 533 return SOC_E_NONE; 534 } 535 536 /* 537 * Function: 538 * soc_th3_flexport_scache_recovery 539 * Purpose: 540 * Recover Port info that maybe changed during flexport for Level 2 WB 541 * 542 * Warm Boot Version Map: 543 * 544 * BCM_WB_VERSION_1_0 545 * port_p2l_mapping 546 * port_l2p_mapping 547 * port_speed_max 548 * port_init_speed 549 * port_num_lanes 550 * disabled_bitmap 551 * 552 * Parameters: 553 * unit - StrataSwitch unit number. 554 * Returns: 555 * SOC_E_XXX 556 */ 557 int soc_th3_flexport_scache_recovery(int unit) 558 { 559 uint32 alloc_get = 0; 560 uint32 alloc_size = 0; 561 int rv = SOC_E_NONE; 562 uint8 *flexport_scache_ptr = NULL; 563 soc_scache_handle_t scache_handle; 564 uint32 scache_offset=0; 565 uint32 var_size = 0; 566 uint16 recovered_ver = 0; 567 soc_info_t *si = &SOC_INFO(unit); 568 569 alloc_size = (sizeof(int) * _TH3_PHY_PORTS_PER_DEV) + /* phy to logical*/ 570 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* logical to phy */ 571 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* max port speed */ 572 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* init port speed */ 573 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* num of lanes */ 574 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port fec*/ 575 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port phy lane config */ 576 (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port link training */ 577 (sizeof(pbmp_t)); /* Disabled bitmap */ 578 579 alloc_get = alloc_size; 580 581 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 582 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 583 FALSE, &alloc_get, 584 &flexport_scache_ptr, 585 SOC_FLEXPORT_WB_DEFAULT_VERSION, 586 &recovered_ver); 587 if (SOC_FAILURE(rv)) { 588 if ((rv == SOC_E_CONFIG) || 589 (rv == SOC_E_NOT_FOUND)) { 590 /* warmboot file does not contain this 591 * module, or the warmboot state does not exist. 592 * in this case return SOC_E_NOT_FOUND 593 */ 594 return SOC_E_NOT_FOUND; 595 } else { 596 /* Only Level2 - flexport treat this as a error */ 597 LOG_ERROR(BSL_LS_SOC_COMMON, 598 (BSL_META_U(unit, 599 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 600 return rv; 601 } 602 } 603 if (alloc_get != alloc_size) { 604 /* Expected size doesn't match retrieved size */ 605 LOG_ERROR(BSL_LS_SOC_COMMON, 606 (BSL_META_U(unit, 607 "ERROR: scache recovery for flexport" 608 "%s()[LINE:%d] DONE \n"), 609 FUNCTION_NAME(), __LINE__)); 610 return SOC_E_INTERNAL; 611 } 612 613 if (NULL == flexport_scache_ptr) { 614 LOG_ERROR(BSL_LS_SOC_COMMON, 615 (BSL_META_U(unit, 616 "ERROR: scache recovery for flexport" 617 "%s()[LINE:%d] DONE \n"), 618 FUNCTION_NAME(), __LINE__)); 619 return SOC_E_MEMORY; 620 } 621 622 /*Physical to logical port mapping */ 623 var_size = (sizeof(int) * _TH3_PHY_PORTS_PER_DEV); 624 sal_memcpy(si->port_p2l_mapping, 625 &flexport_scache_ptr[scache_offset], 626 var_size); 627 scache_offset += var_size; 628 629 var_size = (sizeof(int) * _TH3_DEV_PORTS_PER_DEV); 630 631 /*Logical to Physical port mapping*/ 632 sal_memcpy(si->port_l2p_mapping, 633 &flexport_scache_ptr[scache_offset], 634 var_size); 635 scache_offset += var_size; 636 637 /* Max port speed */ 638 sal_memcpy(_soc_th3_port_speed_cap[unit], 639 &flexport_scache_ptr[scache_offset], 640 var_size); 641 scache_offset += var_size; 642 643 /* Init port speed */ 644 sal_memcpy(si->port_speed_max, 645 &flexport_scache_ptr[scache_offset], 646 var_size); 647 scache_offset += var_size; 648 649 /* Num of lanes */ 650 sal_memcpy(si->port_num_lanes, 651 &flexport_scache_ptr[scache_offset], 652 var_size); 653 scache_offset += var_size; 654 655 /* Fec */ 656 sal_memcpy(si->port_fec_type, 657 &flexport_scache_ptr[scache_offset], 658 var_size); 659 scache_offset += var_size; 660 661 /* Phy Lane Config */ 662 sal_memcpy(si->port_phy_lane_config, 663 &flexport_scache_ptr[scache_offset], 664 var_size); 665 scache_offset += var_size; 666 667 /* Link Training */ 668 sal_memcpy(si->port_link_training, 669 &flexport_scache_ptr[scache_offset], 670 var_size); 671 scache_offset += var_size; 672 673 /* Disabled Port Bitmap */ 674 sal_memcpy(&si->all.disabled_bitmap, 675 &flexport_scache_ptr[scache_offset], 676 sizeof(pbmp_t)); 677 scache_offset += sizeof(pbmp_t); 678 679 LOG_VERBOSE(BSL_LS_SOC_COMMON, 680 (BSL_META_U(unit, 681 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 682 683 return SOC_E_NONE; 684 } 685 #endif /* BCM_WARM_BOOT_SUPPORT */ 686 687 void 688 soc_th3_flexport_sw_dump(int unit) 689 { 690 int port, phy_port, mmu_port, pipe, pm, cosq, numq, uc_cosq, uc_numq; 691 int max_speed, init_speed, num_lanes, fec, link_training, phy_lane_config; 692 char pfmt[SOC_PBMP_FMT_LEN]; 693 694 LOG_CLI((BSL_META_U(unit, 695 " port(log/phy/mmu) pipe pm lanes " 696 "speed(Max) fec link train lane config " 697 "uc_Qbase/Numq mc_Qbase/Numq\n"))); 698 PBMP_ALL_ITER(unit, port) { 699 pipe = SOC_INFO(unit).port_pipe[port]; 700 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 701 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 702 num_lanes = SOC_INFO(unit).port_num_lanes[port]; 703 pm = SOC_INFO(unit).port_serdes[port]; 704 max_speed = SOC_INFO(unit).port_speed_max[port]; 705 init_speed = SOC_INFO(unit).port_init_speed[port]; 706 cosq = SOC_INFO(unit).port_cosq_base[port]; 707 numq = SOC_INFO(unit).port_num_cosq[port]; 708 uc_cosq = SOC_INFO(unit).port_uc_cosq_base[port]; 709 uc_numq = SOC_INFO(unit).port_num_uc_cosq[port]; 710 fec = SOC_INFO(unit).port_fec_type[port]; 711 link_training = SOC_INFO(unit).port_link_training[port]; 712 phy_lane_config = SOC_INFO(unit).port_phy_lane_config[port]; 713 714 LOG_CLI((BSL_META_U(unit, 715 " %4s(%3d/%3d/%3d) %4d %2d %5d %7d(%7d) %3d" 716 "%10d %11d %6d/%-6d %6d/%-6d\n"), 717 SOC_INFO(unit).port_name[port], port, phy_port, mmu_port, 718 pipe, pm, num_lanes, init_speed, max_speed, fec, link_training, 719 phy_lane_config, uc_cosq, uc_numq, cosq, numq)); 720 } 721 722 LOG_CLI((BSL_META_U(unit, 723 "\n Oversub Bitmap: %s"), 724 SOC_PBMP_FMT(SOC_INFO(unit).oversub_pbm, pfmt))); 725 LOG_CLI((BSL_META_U(unit, 726 "\n Disabled Bitmap: %s \n"), 727 SOC_PBMP_FMT(SOC_INFO(unit).all.disabled_bitmap, pfmt))); 728 } 729 730 /* 731 * Function: 732 * soc_th3_port_mode_get 733 * Description: 734 * Get port mode by giving first logical port of TSC4 735 * Parameters: 736 * unit - Device number 737 * port - Logical port 738 * int* - Port Mode 739 * 740 * Each TSC4 can be configured into following 5 mode: 741 * Lane number 0 1 2 3 742 * ------------ --- --- --- --- 743 * quad port 25G 25G 25G 25G 744 * tri_012 port 25G 25G 50G x 745 * tri_023 port 50G x 25G 25G 746 * dual port 50G x 50G x 747 * single port 100G x x x 748 */ 749 int 750 soc_th3_port_mode_get(int unit, int logical_port, int *mode) 751 { 752 #if 0 753 754 soc_info_t *si; 755 int lane; 756 int port, first_phyport, phy_port; 757 int num_lanes[_TH2_PORTS_PER_PBLK]; 758 759 si = &SOC_INFO(unit); 760 first_phyport = si->port_l2p_mapping[logical_port]; 761 762 for (lane = 0; lane < _TH2_PORTS_PER_PBLK; lane++) { 763 phy_port = first_phyport + lane; 764 port = si->port_p2l_mapping[phy_port]; 765 if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 766 num_lanes[lane] = -1; 767 } else { 768 num_lanes[lane] = si->port_num_lanes[port]; 769 } 770 } 771 772 if (num_lanes[0] == 4) { 773 *mode = SOC_TH2_PORT_MODE_QUAD; 774 } else if (num_lanes[0] == 2 && num_lanes[2] == 2) { 775 *mode = SOC_TH2_PORT_MODE_DUAL; 776 } else if (num_lanes[0] == 2 && num_lanes[2] == 1 && num_lanes[3] == 1) { 777 *mode = SOC_TH2_PORT_MODE_TRI_023; 778 } else if (num_lanes[0] == 1 && num_lanes[1] == 1 && num_lanes[2] == 2) { 779 *mode = SOC_TH2_PORT_MODE_TRI_012; 780 } else { 781 *mode = SOC_TH2_PORT_MODE_SINGLE; 782 } 783 #endif 784 return SOC_E_NONE; 785 } 786 787 #endif /* BCM_TOMAHAWK3_SUPPORT */