portctrl.c (44193B)
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 * portctrl soc routines 8 */ 9 10 #include <sal/core/libc.h> 11 12 #include <soc/debug.h> 13 #include <soc/util.h> 14 #include <soc/mem.h> 15 #include <soc/esw/portctrl.h> 16 #include <soc/esw/portctrl_internal.h> 17 #include <soc/td2_td2p.h> 18 #include <shared/bsl.h> 19 #include <soc/phy/phymod_sim.h> 20 #include <soc/portmod/portmod.h> 21 22 #ifdef BCM_TRIDENT2PLUS_SUPPORT 23 #ifdef PORTMOD_PM4X10TD_SUPPORT 24 #define SOC_TD2P_PM4X10_COUNT 8 25 26 #define SOC_TD2P_PM4X10_PORT_1 13 27 #define SOC_TD2P_PM4X10_PORT_2 17 28 #define SOC_TD2P_PM4X10_PORT_3 45 29 #define SOC_TD2P_PM4X10_PORT_4 49 30 #define SOC_TD2P_PM4X10_PORT_5 77 31 #define SOC_TD2P_PM4X10_PORT_6 81 32 #define SOC_TD2P_PM4X10_PORT_7 109 33 #define SOC_TD2P_PM4X10_PORT_8 113 34 35 static uint32_t _td2p_pm4x10_addr[SOC_TD2P_PM4X10_COUNT] = { 36 0x8D, 0x91, 0xC1, 0xC5, 0xED, 0xF1, 0x1A1, 0x1A5}; 37 38 static uint32_t _td2p_pm4x10_core_num[SOC_TD2P_PM4X10_COUNT] = { 39 3, 4, 11, 12, 19, 20, 27, 28}; 40 41 static uint32_t _td2p_pm4x10_port[SOC_TD2P_PM4X10_COUNT] = { 42 SOC_TD2P_PM4X10_PORT_1, 43 SOC_TD2P_PM4X10_PORT_2, 44 SOC_TD2P_PM4X10_PORT_3, 45 SOC_TD2P_PM4X10_PORT_4, 46 SOC_TD2P_PM4X10_PORT_5, 47 SOC_TD2P_PM4X10_PORT_6, 48 SOC_TD2P_PM4X10_PORT_7, 49 SOC_TD2P_PM4X10_PORT_8 50 }; 51 #endif 52 #ifdef PORTMOD_PM12X10_SUPPORT 53 #define SOC_TD2P_PM12X10_COUNT 8 54 55 #define SOC_TD2P_PM12X10_PORT_1 1 56 #define SOC_TD2P_PM12X10_PORT_2 21 57 #define SOC_TD2P_PM12X10_PORT_3 33 58 #define SOC_TD2P_PM12X10_PORT_4 53 59 #define SOC_TD2P_PM12X10_PORT_5 65 60 #define SOC_TD2P_PM12X10_PORT_6 85 61 #define SOC_TD2P_PM12X10_PORT_7 97 62 #define SOC_TD2P_PM12X10_PORT_8 117 63 64 static uint32_t _td2p_pm12x10_addr[SOC_TD2P_PM12X10_COUNT*SOC_PM12X10_PM4X10_COUNT] = { 65 0x81, 0x85, 0x89, /* PM12X10 Inst 1, Core 0-2 */ 66 0xA1, 0xA5, 0xA9, /* PM12X10 Inst 2, Core 2-0 */ 67 0xAD, 0xB1, 0xB5, /* PM12X10 Inst 3, Core 0-2 */ 68 0xC9, 0xCD, 0xD1, /* PM12X10 Inst 4, Core 2-0 */ 69 0xE1, 0xE5, 0xE9, /* PM12X10 Inst 5, Core 0-2 */ 70 0x181, 0x185, 0x189, /* PM12X10 Inst 6, Core 2-0 */ 71 0x18D, 0x191, 0x195, /* PM12X10 Inst 7, Core 0-2 */ 72 0x1A9, 0x1AD, 0x1B1}; /* PM12X10 Inst 8, Core 2-0 */ 73 74 static uint32_t _td2p_pm12x10_core_num[SOC_TD2P_PM12X10_COUNT*SOC_PM12X10_PM4X10_COUNT] = { 75 0, 1, 2, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 21, 22, 23, 24, 25, 26, 29, 30, 31}; 76 77 static uint32_t _td2p_pm12x10_port[SOC_TD2P_PM12X10_COUNT] = { 78 SOC_TD2P_PM12X10_PORT_1, 79 SOC_TD2P_PM12X10_PORT_2, 80 SOC_TD2P_PM12X10_PORT_3, 81 SOC_TD2P_PM12X10_PORT_4, 82 SOC_TD2P_PM12X10_PORT_5, 83 SOC_TD2P_PM12X10_PORT_6, 84 SOC_TD2P_PM12X10_PORT_7, 85 SOC_TD2P_PM12X10_PORT_8 86 }; 87 #endif 88 89 static portmod_pm_instances_t td2p_pm_types[] = { 90 #ifdef PORTMOD_PM4X10TD_SUPPORT 91 {portmodDispatchTypePm4x10td, SOC_TD2P_PM4X10_COUNT}, 92 #endif 93 #ifdef PORTMOD_PM12X10_SUPPORT 94 {portmodDispatchTypePm12x10, SOC_TD2P_PM12X10_COUNT}, 95 #endif 96 }; 97 98 #define SOC_TD2P_MAX_PHYS 160 /* 128 XLMACS, 32 CLMAC's */ 99 100 #define SOC_TD2P_NIB_SWAP(data) \ 101 (((data & 0x0f) << 12) | ((data & 0xf0) << 4 ) | \ 102 ((data >> 4) & 0xf0) | ((data >>12) & 0xf)) 103 #define SOC_TD2P_NIB_TRX(data) \ 104 ((0x3-(data&0x0f)) | (0x30-(data&0xf0)) | \ 105 (0x300-(data&0xf00)) | (0x3000-(data&0xf000))) 106 107 #ifdef PORTMOD_PM4X10TD_SUPPORT 108 static portmod_default_user_access_t *pm4x10_td2p_user_acc[SOC_MAX_NUM_DEVICES]; 109 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 110 111 #ifdef PORTMOD_PM12X10_SUPPORT 112 static portmod_default_user_access_t *pm12x10_td2p_user_acc[SOC_MAX_NUM_DEVICES]; 113 static portmod_default_user_access_t *pm12_4x10_td2p_user_acc[SOC_MAX_NUM_DEVICES]; 114 static portmod_default_user_access_t *pm12_4x25_td2p_user_acc[SOC_MAX_NUM_DEVICES]; 115 #endif /* PORTMOD_PM12X10_SUPPORT */ 116 117 #ifdef PORTMOD_PM4X25_SUPPORT 118 static portmod_default_user_access_t *pm4x25_td2p_user_acc[SOC_MAX_NUM_DEVICES]; 119 #endif /* PORTMOD_PM4X25_SUPPORT */ 120 121 122 soc_portctrl_functions_t soc_td2p_portctrl_func = { 123 soc_td2p_portctrl_pm_portmod_init, 124 soc_td2p_portctrl_pm_portmod_deinit, 125 soc_td2p_portctrl_pm_port_config_get, 126 soc_td2p_portctrl_pm_port_phyaddr_get, 127 NULL, 128 soc_td2p_portctrl_pm_type_get, 129 NULL, 130 NULL 131 }; 132 133 STATIC int 134 _soc_td2p_portctrl_pm_init(int unit, int *max_phys, 135 portmod_pm_instances_t **pm_types, 136 int *pms_arr_len) 137 { 138 *max_phys = SOC_TD2P_MAX_PHYS; 139 *pm_types = td2p_pm_types; 140 *pms_arr_len = sizeof(td2p_pm_types)/sizeof(portmod_pm_instances_t); 141 return SOC_E_NONE; 142 } 143 144 STATIC int 145 _soc_td2p_portctrl_device_addr_port_get(int unit, int pm_type, 146 uint32_t **addr, 147 uint32_t **port, 148 uint32_t **core_num) 149 { 150 *addr = NULL; 151 *port = NULL; 152 *core_num = NULL; 153 #ifdef PORTMOD_PM4X10TD_SUPPORT 154 if (pm_type == portmodDispatchTypePm4x10td) { 155 *addr = _td2p_pm4x10_addr; 156 *port = _td2p_pm4x10_port; 157 *core_num = _td2p_pm4x10_core_num; 158 } else 159 #endif 160 #ifdef PORTMOD_PM12X10_SUPPORT 161 if (pm_type == portmodDispatchTypePm12x10){ 162 *addr = _td2p_pm12x10_addr; 163 *port = _td2p_pm12x10_port; 164 *core_num = _td2p_pm12x10_core_num; 165 } 166 #endif 167 168 return SOC_E_NONE; 169 } 170 171 STATIC int 172 _soc_td2p_portctrl_pm_user_acc_flag_set(int unit, 173 portmod_default_user_access_t* pm_user_access) 174 { 175 PORTMOD_USER_ACCESS_REG_VAL_OFFSET_ZERO_SET((pm_user_access)); 176 return SOC_E_NONE; 177 } 178 179 STATIC int 180 _soc_td2p_portctrl_is_chip_bonding_swap(int unit, int pm_inst, 181 int core_num, int type, int is_tx) 182 { 183 #ifdef PORTMOD_PM12X10_SUPPORT 184 int is_pm12x10 = (type == portmodDispatchTypePm12x10) ? 1: 0; 185 /* 186 * PM4X10 : ODD Inst: Rx Flip 187 * PM4X10 : EVEN Inst: Tx Flip 188 * PM12x10: ODD Inst: Core 0,2 Rx Flip, Core 1 Tx Flip 189 * PM12x10: EVEN Inst: Core 0,2 Tx Flip, Core 1 Rx Flip 190 */ 191 return is_tx ? 192 (is_pm12x10? ((pm_inst&1)? !(core_num&1): (core_num&1)) : !(pm_inst&1)) : 193 (is_pm12x10? ((pm_inst&1)? (core_num&1): !(core_num&1)) : (pm_inst&1)); 194 #endif /* PORTMOD_PM12X10_SUPPORT */ 195 return (0); 196 } 197 198 /* 199 * Polarity get looks for physical port based config first. This will enable 200 * the user to define the polarity for all ports weather mapped to logical 201 * port or not. 202 * 203 * For legacy compatibility - we still look for the logical port 204 * config setup. 205 */ 206 STATIC 207 void _pm_port_polarity_get (int unit, int logical_port, int physical_port, int lane, 208 int core_num,uint32 *tx_pol, uint32* rx_pol) 209 { 210 uint32 rx_polarity, tx_polarity, num_lanes=1; 211 212 if (logical_port != -1) { 213 num_lanes = SOC_INFO(unit).port_num_lanes[logical_port]; 214 } 215 216 rx_polarity = soc_property_phy_get (unit, physical_port, 0, 0, lane, 217 spn_PHY_CHAIN_RX_POLARITY_FLIP_PHYSICAL, 0xFFFFFFFF); 218 if (rx_polarity == 0xFFFFFFFF) { 219 rx_polarity = soc_property_port_get(unit, logical_port, 220 spn_PHY_XAUI_RX_POLARITY_FLIP, 0); 221 *rx_pol = (num_lanes == 1) ? ((rx_polarity & 0x1) << lane): rx_polarity; 222 if (logical_port != -1) { 223 if (IS_C_PORT(unit, logical_port)) { 224 *rx_pol = ((rx_polarity >> (core_num * SOC_PM4X10_NUM_LANES)) & 0xf); 225 } 226 } 227 } else { 228 *rx_pol = (rx_polarity & 0x1) << lane; 229 /* *rx_pol = (num_lanes == 1) ? ((rx_polarity & 0x1) << lane): rx_polarity;*/ 230 } 231 232 tx_polarity = soc_property_phy_get (unit, physical_port, 0, 0, lane, 233 spn_PHY_CHAIN_TX_POLARITY_FLIP_PHYSICAL, 0xFFFFFFFF); 234 if (tx_polarity == 0xFFFFFFFF) { 235 tx_polarity = soc_property_port_get(unit, logical_port, 236 spn_PHY_XAUI_TX_POLARITY_FLIP, 0); 237 *tx_pol = (num_lanes == 1) ? ((tx_polarity & 0x1) << lane) : tx_polarity; 238 if (logical_port != -1) { 239 if (IS_C_PORT(unit, logical_port)) { 240 *tx_pol = ((tx_polarity >> (core_num * SOC_PM4X10_NUM_LANES)) & 0xf); 241 } 242 } 243 } else { 244 *tx_pol = (tx_polarity & 0x1) << lane; 245 /* *tx_pol = (num_lanes == 1) ? ((tx_polarity & 0x1) << lane) : tx_polarity;*/ 246 } 247 } 248 249 /* 250 * lanemap get looks for physical port based config first. This will enable 251 * the user to define the lanemap for all ports weather mapped to logical 252 * port or not. 253 * 254 * For legacy compatibility - we still look for the logical port 255 * config setup. 256 */ 257 STATIC 258 void _pm_port_lanemap_get (int unit, int logical_port, int physical_port, int core_num, 259 uint32 *txlane_map, uint32* rxlane_map) 260 { 261 262 *rxlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 263 spn_PHY_CHAIN_RX_LANE_MAP_PHYSICAL, 0xFFFFFFFF); 264 265 if (*rxlane_map == 0xFFFFFFFF) { 266 *rxlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 267 spn_PHY_RX_LANE_MAP, 0xFFFFFFFF); 268 } 269 if (*rxlane_map == 0xFFFFFFFF) { 270 *rxlane_map = soc_property_port_suffix_num_get(unit, logical_port, core_num, 271 spn_XGXS_RX_LANE_MAP, 272 "core", 0x3210); 273 } 274 275 *txlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 276 spn_PHY_CHAIN_TX_LANE_MAP_PHYSICAL, 0xFFFFFFFF); 277 278 if (*txlane_map == 0xFFFFFFFF) { 279 *txlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 280 spn_PHY_TX_LANE_MAP, 0xFFFFFFFF); 281 } 282 if (*txlane_map == 0xFFFFFFFF) { 283 *txlane_map = soc_property_port_suffix_num_get(unit, logical_port, core_num, 284 spn_XGXS_TX_LANE_MAP, 285 "core", 0x3210); 286 } 287 } 288 289 STATIC int 290 _soc_td2p_portctrl_pm4x10_portmod_init(int unit, int num_of_instances) 291 { 292 #ifdef PORTMOD_PM4X10TD_SUPPORT 293 int rv = SOC_E_NONE; 294 portmod_pm_create_info_t pm_info; 295 int pmid = 0, blk, is_sim, found, logical_port; 296 int first_port, idx, core_num, core_cnt; 297 uint32 *pAddr, *pPort, *pCoreNum; 298 int mode; 299 300 SOC_IF_ERROR_RETURN 301 (_soc_td2p_portctrl_device_addr_port_get(unit, 302 portmodDispatchTypePm4x10td, 303 &pAddr, &pPort, &pCoreNum)); 304 if (!pAddr || !pPort) { 305 return SOC_E_INTERNAL; 306 } 307 308 /* Allocate PMs */ 309 SOC_IF_ERROR_RETURN 310 (soc_esw_portctrl_pm_user_access_alloc(unit, 311 num_of_instances, 312 &pm4x10_td2p_user_acc[unit])); 313 314 for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) { 315 316 rv = portmod_pm_create_info_t_init(unit, &pm_info); 317 if (PORTMOD_FAILURE(rv)) { 318 break; 319 } 320 /* PM info */ 321 first_port = pPort[pmid]; 322 323 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port); 324 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+1); 325 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+2); 326 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+3); 327 328 found = 0; 329 for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 330 blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 331 if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_XLPORT){ 332 found = 1; 333 break; 334 } 335 } 336 337 if (!found) { 338 rv = SOC_E_INTERNAL; 339 break; 340 } 341 342 pm_info.type = portmodDispatchTypePm4x10td; 343 344 /* Init user_acc for phymod access struct */ 345 rv = portmod_default_user_access_t_init(unit, 346 &(pm4x10_td2p_user_acc[unit][pmid])); 347 if (PORTMOD_FAILURE(rv)) { 348 break; 349 } 350 351 SOC_IF_ERROR_RETURN( 352 _soc_td2p_portctrl_pm_user_acc_flag_set(unit, 353 &(pm4x10_td2p_user_acc[unit][pmid]))); 354 355 pm4x10_td2p_user_acc[unit][pmid].unit = unit; 356 pm4x10_td2p_user_acc[unit][pmid].blk_id = blk; 357 pm4x10_td2p_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex"); 358 if (pm4x10_td2p_user_acc[unit][pmid].mutex == NULL) { 359 rv = SOC_E_MEMORY; 360 break; 361 } 362 363 /* Specific info for PM4x10 */ 364 rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x10.access); 365 if (PORTMOD_FAILURE(rv)) { 366 break; 367 } 368 369 pm_info.pm_specific_info.pm4x10.access.user_acc = 370 &(pm4x10_td2p_user_acc[unit][pmid]); 371 pm_info.pm_specific_info.pm4x10.access.addr = pAddr[pmid]; 372 pm_info.pm_specific_info.pm4x10.access.bus = NULL; /* Use default bus */ 373 374 rv = soc_physim_check_sim(unit, phymodDispatchTypeTsce, 375 &(pm_info.pm_specific_info.pm4x10.access), 376 0, &is_sim); 377 if (PORTMOD_FAILURE(rv)) { 378 break; 379 } 380 381 if (is_sim) { 382 pm_info.pm_specific_info.pm4x10.access.bus->bus_capabilities |= 383 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL); 384 385 /* Firmward loader : Don't allow FW load on sim enviroment */ 386 pm_info.pm_specific_info.pm4x10.fw_load_method = 387 phymodFirmwareLoadMethodNone; 388 } 389 390 /* Use default external loader if NULL */ 391 pm_info.pm_specific_info.pm4x10.external_fw_loader = NULL; 392 393 logical_port = SOC_INFO(unit).port_p2l_mapping[first_port]; 394 core_cnt = 1; 395 396 for (core_num = 0; core_num < core_cnt; core_num++) { 397 pm_info.pm_specific_info.pm4x10.core_num = pCoreNum? pCoreNum[pmid] : pmid; 398 pm_info.pm_specific_info.pm4x10.core_num_int = 0; 399 pm_info.pm_specific_info.pm4x10.rescal = -1; 400 } 401 402 pm_info.pm_specific_info.pm4x10.portmod_phy_external_reset 403 = soc_esw_portctrl_reset_tsc3_cb; 404 405 SOC_IF_ERROR_RETURN(soc_td2p_port_mode_get(unit, logical_port, &mode)); 406 if (mode == portmodPortModeTri012 || mode == portmodPortModeTri023) { 407 pm_info.pm_specific_info.pm4x10.port_mode_aux_info = portmodModeInfoThreePorts; 408 } 409 /* Add PM to PortMod */ 410 rv = portmod_port_macro_add(unit, &pm_info); 411 } 412 413 if (PORTMOD_FAILURE(rv)) { 414 for (pmid=0; pmid < num_of_instances; pmid++) { 415 if (pm4x10_td2p_user_acc[unit][pmid].mutex) { 416 sal_mutex_destroy(pm4x10_td2p_user_acc[unit][pmid].mutex); 417 pm4x10_td2p_user_acc[unit][pmid].mutex = NULL; 418 } 419 } 420 } 421 422 return rv; 423 #else /* PORTMOD_PM4X10TD_SUPPORT */ 424 return SOC_E_UNAVAIL; 425 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 426 } 427 428 STATIC int 429 _soc_td2p_portctrl_pm4x25_portmod_init(int unit, int num_of_instances) 430 { 431 #ifdef PORTMOD_PM4X25_SUPPORT 432 int rv = SOC_E_NONE; 433 portmod_pm_create_info_t pm_info; 434 int pmid = 0, blk, is_sim, lane, phy, found, logical_port; 435 int first_port, idx, ref_clk_prop, core_num, core_cnt; 436 uint32 txlane_map, rxlane_map, *pAddr, *pPort,*pCoreNum; 437 int bonding_swap_tx, bonding_swap_rx ; /*TEMP */ 438 uint32 tx_polarity, rx_polarity; 439 440 SOC_IF_ERROR_RETURN 441 (_soc_td2p_portctrl_device_addr_port_get(unit, 442 portmodDispatchTypePm4x25, 443 &pAddr, &pPort,&pCoreNum)); 444 if (!pAddr || !pPort) { 445 return SOC_E_INTERNAL; 446 } 447 448 /* Allocate PMs */ 449 SOC_IF_ERROR_RETURN 450 (soc_esw_portctrl_pm_user_access_alloc(unit, 451 num_of_instances, 452 &pm4x25_td2p_user_acc[unit])); 453 454 for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) { 455 456 rv = portmod_pm_create_info_t_init(unit, &pm_info); 457 if (PORTMOD_FAILURE(rv)) { 458 break; 459 } 460 /* PM info */ 461 first_port = pPort[pmid]; 462 463 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port); 464 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+1); 465 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+2); 466 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+3); 467 468 found = 0; 469 for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 470 blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 471 if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_CLPORT){ 472 found = 1; 473 break; 474 } 475 } 476 477 if (!found) { 478 rv = SOC_E_INTERNAL; 479 break; 480 } 481 482 pm_info.type = portmodDispatchTypePm4x25; 483 484 /* Init user_acc for phymod access struct */ 485 rv = portmod_default_user_access_t_init(unit, 486 &(pm4x25_td2p_user_acc[unit][pmid])); 487 if (PORTMOD_FAILURE(rv)) { 488 break; 489 } 490 491 PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x25_td2p_user_acc[unit][pmid]))); 492 PORTMOD_USER_ACCESS_REG_VAL_OFFSET_ZERO_CLR((&(pm4x25_td2p_user_acc[unit][pmid]))); 493 pm4x25_td2p_user_acc[unit][pmid].unit = unit; 494 pm4x25_td2p_user_acc[unit][pmid].blk_id = blk; 495 pm4x25_td2p_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex"); 496 if (pm4x25_td2p_user_acc[unit][pmid].mutex == NULL) { 497 rv = SOC_E_MEMORY; 498 break; 499 } 500 501 /* Specific info for PM4x25 */ 502 rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x25.access); 503 if (PORTMOD_FAILURE(rv)) { 504 break; 505 } 506 507 pm_info.pm_specific_info.pm4x25.access.user_acc = 508 &(pm4x25_td2p_user_acc[unit][pmid]); 509 pm_info.pm_specific_info.pm4x25.access.addr = pAddr[pmid]; 510 pm_info.pm_specific_info.pm4x25.access.bus = NULL; /* Use default bus */ 511 512 rv = soc_physim_check_sim(unit, phymodDispatchTypeTscf, 513 &(pm_info.pm_specific_info.pm4x25.access), 514 0, &is_sim); 515 516 if (PORTMOD_FAILURE(rv)) { 517 break; 518 } 519 520 if (is_sim) { 521 pm_info.pm_specific_info.pm4x25.access.bus->bus_capabilities |= 522 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL); 523 524 /* Firmward loader : Don't allow FW load on sim enviroment */ 525 pm_info.pm_specific_info.pm4x25.fw_load_method = 526 phymodFirmwareLoadMethodNone; 527 } else { 528 pm_info.pm_specific_info.pm4x25.fw_load_method = 529 soc_property_suffix_num_get(unit, pmid, 530 spn_LOAD_FIRMWARE, "quad", 531 phymodFirmwareLoadMethodExternal); 532 pm_info.pm_specific_info.pm4x25.fw_load_method &= 0xff; 533 } 534 535 /* Use default external loader if NULL */ 536 pm_info.pm_specific_info.pm4x25.external_fw_loader = NULL; 537 538 /* Polarity */ 539 rv = phymod_polarity_t_init (&(pm_info.pm_specific_info.pm4x25.polarity)); 540 if (PORTMOD_FAILURE(rv)) { 541 break; 542 } 543 544 for (lane = 0; lane < SOC_PM4X25_NUM_LANES; lane++) { 545 phy = first_port+lane; 546 logical_port = SOC_INFO(unit).port_p2l_mapping[phy]; 547 548 _pm_port_polarity_get (unit, logical_port, phy, lane,0, &tx_polarity, &rx_polarity); 549 550 pm_info.pm_specific_info.pm4x25.polarity.rx_polarity |= rx_polarity; 551 pm_info.pm_specific_info.pm4x25.polarity.tx_polarity |= tx_polarity; 552 553 if (SOC_INFO(unit).port_num_lanes[logical_port] >= SOC_PM4X25_NUM_LANES) break; 554 } 555 556 /* Lane map */ 557 rv = phymod_lane_map_t_init 558 (&(pm_info.pm_specific_info.pm4x25.lane_map)); 559 if (PORTMOD_FAILURE(rv)) { 560 break; 561 } 562 563 logical_port = SOC_INFO(unit).port_p2l_mapping[first_port]; 564 core_cnt = 1; 565 566 for (core_num = 0; core_num < core_cnt; core_num++) { 567 _pm_port_lanemap_get (unit, logical_port, first_port, core_num, &txlane_map, &rxlane_map); 568 569 bonding_swap_tx = _soc_td2p_portctrl_is_chip_bonding_swap(unit, pmid, core_num, portmodDispatchTypePm4x25, 1) ; 570 txlane_map = bonding_swap_tx ? 571 SOC_TD2P_NIB_SWAP(txlane_map) : txlane_map; 572 573 bonding_swap_rx = _soc_td2p_portctrl_is_chip_bonding_swap(unit, pmid, core_num, portmodDispatchTypePm4x25, 0) ; 574 rxlane_map = bonding_swap_rx ? 575 SOC_TD2P_NIB_SWAP(rxlane_map) : rxlane_map; 576 577 pm_info.pm_specific_info.pm4x25.lane_map.num_of_lanes = 578 SOC_PM4X25_NUM_LANES; 579 580 pm_info.pm_specific_info.pm4x25.core_num = pCoreNum? pCoreNum[pmid] : pmid; 581 pm_info.pm_specific_info.pm4x25.core_num_int = 0; 582 pm_info.pm_specific_info.pm4x25.rescal = -1; 583 584 for(lane=0 ; lane<SOC_PM4X25_NUM_LANES; lane++) { 585 pm_info.pm_specific_info.pm4x25.lane_map.lane_map_tx[lane] = 586 (txlane_map >> (lane * SOC_PM4X25_NUM_LANES)) & 587 SOC_PM4X25_LANE_MASK; 588 pm_info.pm_specific_info.pm4x25.lane_map.lane_map_rx[lane] = 589 (rxlane_map >> (lane * SOC_PM4X25_NUM_LANES)) & 590 SOC_PM4X25_LANE_MASK; 591 } 592 } 593 594 ref_clk_prop = soc_property_port_get(unit, first_port, 595 spn_XGXS_LCPLL_XTAL_REFCLK, 156); 596 597 if ((ref_clk_prop == 156) ||( ref_clk_prop == 1)){ 598 pm_info.pm_specific_info.pm4x25.ref_clk = phymodRefClk156Mhz; 599 } 600 else if (ref_clk_prop == 125){ 601 pm_info.pm_specific_info.pm4x25.ref_clk = phymodRefClk125Mhz; 602 } 603 else { 604 LOG_ERROR(BSL_LS_SOC_PORT, 605 (BSL_META_UP(unit, first_port, 606 "ERROR: This %d MHz clk freq is not supported. Only 156 MHz and 125 MHz.\n"),ref_clk_prop)); 607 return SOC_E_PARAM ; 608 609 } 610 /* Add PM to PortMod */ 611 rv = portmod_port_macro_add(unit, &pm_info); 612 } 613 614 if (PORTMOD_FAILURE(rv)) { 615 for (pmid=0; pmid < num_of_instances; pmid++) { 616 if (pm4x25_td2p_user_acc[unit][pmid].mutex) { 617 sal_mutex_destroy(pm4x25_td2p_user_acc[unit][pmid].mutex); 618 pm4x25_td2p_user_acc[unit][pmid].mutex = NULL; 619 } 620 } 621 } 622 623 return rv; 624 #else /* PORTMOD_PM4X25_SUPPORT */ 625 return SOC_E_UNAVAIL; 626 #endif /* PORTMOD_PM4X25_SUPPORT */ 627 } 628 629 630 STATIC int 631 _soc_td2p_portctrl_pm12x10_portmod_init(int unit, int num_of_instances) 632 { 633 #if defined(PORTMOD_PM12X10_SUPPORT) 634 int rv = SOC_E_NONE; 635 portmod_pm_create_info_t pm_info; 636 portmod_pm4x10_create_info_t *pm4x10_info; 637 portmod_pm4x25_create_info_t *pm4x25_info; 638 int pmid = 0, blk, is_sim, phy, found, logical_port; 639 int first_port, idx, core_num=0; 640 uint32 *pAddr, *pPort, *pCoreNum; 641 int mode; 642 643 SOC_IF_ERROR_RETURN 644 (_soc_td2p_portctrl_device_addr_port_get(unit, 645 portmodDispatchTypePm12x10, 646 &pAddr, &pPort, &pCoreNum)); 647 if (!pAddr || !pPort) { 648 return SOC_E_INTERNAL; 649 } 650 651 SOC_IF_ERROR_RETURN 652 (soc_esw_portctrl_pm_user_access_alloc(unit, 653 num_of_instances, 654 &pm12x10_td2p_user_acc[unit])); 655 656 SOC_IF_ERROR_RETURN 657 (soc_esw_portctrl_pm_user_access_alloc(unit, 658 num_of_instances*SOC_PM12X10_PM4X10_COUNT, 659 &pm12_4x10_td2p_user_acc[unit])); 660 661 SOC_IF_ERROR_RETURN 662 (soc_esw_portctrl_pm_user_access_alloc(unit, 663 num_of_instances, 664 &pm12_4x25_td2p_user_acc[unit])); 665 666 667 /* Register PM12x10 */ 668 for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) { 669 int core_idx, core_blk; 670 671 rv = portmod_pm_create_info_t_init(unit, &pm_info); 672 if (PORTMOD_FAILURE(rv)) { 673 break; 674 } 675 676 pm_info.pm_specific_info.pm12x10.refclk_source = 0; 677 678 /* PM info */ 679 first_port = pPort[pmid]; 680 681 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port); 682 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+1); 683 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+2); 684 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+3); 685 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+4); 686 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+5); 687 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+6); 688 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+7); 689 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+8); 690 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+9); 691 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+10); 692 PORTMOD_PBMP_PORT_ADD(pm_info.phys, first_port+11); 693 694 found = 0; 695 for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 696 blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 697 if (SOC_BLOCK_INFO(unit, blk).type == SOC_BLK_XLPORT){ 698 found = 1; 699 break; 700 } 701 } 702 703 if (!found) { 704 rv = SOC_E_INTERNAL; 705 break; 706 } 707 pm_info.type = portmodDispatchTypePm12x10; 708 709 710 /* init user_acc for phymod access struct */ 711 rv = portmod_default_user_access_t_init(unit, 712 &(pm12x10_td2p_user_acc[unit][pmid])); 713 if (PORTMOD_FAILURE(rv)) { 714 break; 715 } 716 717 PORTMOD_USER_ACCESS_REG_VAL_OFFSET_ZERO_SET((&(pm12x10_td2p_user_acc[unit][pmid]))); 718 pm12x10_td2p_user_acc[unit][pmid].unit = unit; 719 pm12x10_td2p_user_acc[unit][pmid].blk_id = blk; 720 pm12x10_td2p_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex"); 721 if (pm12x10_td2p_user_acc[unit][pmid].mutex == NULL) { 722 rv = SOC_E_MEMORY; 723 break; 724 } 725 726 for (core_num = 0; 727 PORTMOD_SUCCESS(rv) && (core_num < SOC_PM12X10_PM4X10_COUNT); 728 core_num++) { 729 730 /* PM4X10 INFO UPDATE */ 731 pm4x10_info = &pm_info.pm_specific_info.pm12x10.pm4x10_infos[core_num]; 732 733 /* Specific info for PM12x10 */ 734 rv = phymod_access_t_init(&pm4x10_info->access); 735 if (PORTMOD_FAILURE(rv)) { 736 break; 737 } 738 pm12_4x10_td2p_user_acc[unit][(pmid*3)+core_num] = pm12x10_td2p_user_acc[unit][pmid]; 739 740 found = 0; 741 for(core_idx = 0; core_idx < SOC_DRIVER(unit)->port_num_blktype; core_idx++){ 742 core_blk = SOC_PORT_IDX_INFO(unit, (first_port+(4*core_num)), core_idx).blk; 743 if (SOC_BLOCK_INFO(unit, core_blk).type == SOC_BLK_XLPORT){ 744 found = 1; 745 break; 746 } 747 } 748 749 if (!found) { 750 /* Internal Error */ 751 break; 752 } 753 754 pm12_4x10_td2p_user_acc[unit][(pmid*3)+core_num].blk_id = core_blk; 755 pm4x10_info->access.user_acc = &(pm12_4x10_td2p_user_acc[unit][(pmid*3)+core_num]); 756 pm4x10_info->access.addr = pAddr[(pmid*3) + core_num]; 757 pm4x10_info->access.bus = NULL; 758 pm4x10_info->core_num = pCoreNum? pCoreNum[(pmid*3)+core_num] : ((pmid*3)+core_num); 759 pm4x10_info->core_num_int = core_num; 760 pm4x10_info->rescal = -1; 761 762 rv = soc_physim_check_sim(unit, phymodDispatchTypeTsce, 763 &(pm4x10_info->access), 0, &is_sim); 764 if (PORTMOD_FAILURE(rv)) { 765 break; 766 } 767 768 if (is_sim) { 769 pm4x10_info->access.bus->bus_capabilities |= 770 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL); 771 772 /* Firmward loader : Don't allow FW load on sim enviroment */ 773 pm4x10_info->fw_load_method = phymodFirmwareLoadMethodNone; 774 } 775 776 /* Use default external loader */ 777 pm4x10_info->external_fw_loader = NULL; 778 779 /* Three Port Mode */ 780 { 781 phy = first_port+(core_num*4); 782 logical_port = SOC_INFO(unit).port_p2l_mapping[phy]; 783 784 SOC_IF_ERROR_RETURN(soc_td2p_port_mode_get(unit, logical_port, &mode)); 785 if (mode == portmodPortModeTri012 || mode == portmodPortModeTri023) { 786 pm4x10_info->port_mode_aux_info = portmodModeInfoThreePorts; 787 } 788 } 789 790 } 791 792 PORTMOD_PM12x10_F_EXTERNAL_TOP_MODE_SET(pm_info.pm_specific_info.pm12x10.flags); 793 PORTMOD_PM12x10_F_USE_PM_TD_SET(pm_info.pm_specific_info.pm12x10.flags); 794 795 pm_info.pm_specific_info.pm12x10.pm4x10_infos[1].portmod_phy_external_reset = 796 soc_esw_portctrl_reset_tsc1_cb; 797 pm_info.pm_specific_info.pm12x10.pm4x10_infos[0].portmod_phy_external_reset = 798 (pmid&1)? soc_esw_portctrl_reset_tsc2_cb : soc_esw_portctrl_reset_tsc0_cb; 799 pm_info.pm_specific_info.pm12x10.pm4x10_infos[2].portmod_phy_external_reset = 800 (pmid&1)? soc_esw_portctrl_reset_tsc0_cb : soc_esw_portctrl_reset_tsc2_cb; 801 802 803 /* PM4X25 INFO UPDATE */ 804 pm4x25_info = &pm_info.pm_specific_info.pm12x10.pm4x25_info; 805 806 /* Specific info for PM12x10 */ 807 rv = phymod_access_t_init(&pm4x25_info->access); 808 if (PORTMOD_FAILURE(rv)) { 809 break; 810 } 811 pm12_4x25_td2p_user_acc[unit][pmid] = pm12x10_td2p_user_acc[unit][pmid]; 812 found = 0; 813 first_port = pPort[pmid]; 814 for(core_idx = 0; core_idx < SOC_DRIVER(unit)->port_num_blktype; core_idx++){ 815 core_blk = SOC_PORT_IDX_INFO(unit, first_port, core_idx).blk; 816 if (SOC_BLOCK_INFO(unit, core_blk).type == SOC_BLK_CPORT){ 817 found = 1; 818 break; 819 } 820 } 821 822 if (!found) { 823 rv = SOC_E_INTERNAL; 824 break; 825 } 826 827 pm12_4x25_td2p_user_acc[unit][pmid].blk_id = core_blk; 828 pm4x25_info->lane_map.num_of_lanes = SOC_PM4X25_NUM_LANES; 829 pm4x25_info->access.user_acc = &(pm12_4x25_td2p_user_acc[unit][pmid]); 830 pm4x25_info->access.addr = pAddr[pmid]; 831 pm4x25_info->access.bus = NULL; 832 pm4x25_info->core_num = pmid; 833 pm4x25_info->external_fw_loader = NULL; 834 pm4x25_info->fw_load_method = phymodFirmwareLoadMethodNone; 835 pm4x25_info->rescal = -1; 836 837 838 rv = portmod_port_macro_add(unit, &pm_info); 839 } 840 841 if (PORTMOD_FAILURE(rv)) { 842 for (pmid=0; pmid < num_of_instances; pmid++) { 843 if (pm12x10_td2p_user_acc[unit][pmid].mutex) { 844 sal_mutex_destroy(pm12x10_td2p_user_acc[unit][pmid].mutex); 845 pm12x10_td2p_user_acc[unit][pmid].mutex = NULL; 846 } 847 } 848 } 849 return rv; 850 #else /* PORTMOD_PM12X10_SUPPORT */ 851 return SOC_E_UNAVAIL; 852 #endif /* PORTMOD_PM12X10_SUPPORT */ 853 } 854 855 /* 856 * Function: 857 * soc_td2p_portctrl_pm_portmod_init 858 * Purpose: 859 * Initialize PortMod and PortMacro for Trident2Plus 860 * Add port macros (PM) to the unit's PortMod Manager (PMM). 861 * Parameters: 862 * unit - (IN) Unit number. 863 * Returns: 864 * SOC_E_XXX 865 */ 866 int 867 soc_td2p_portctrl_pm_portmod_init(int unit) 868 { 869 uint32 flags = 0; 870 int rv = SOC_E_NONE, pms_arr_len = 0, count, max_phys= 0; 871 portmod_pm_instances_t *pm_types = NULL; 872 873 /* Call PortMod library initialization */ 874 SOC_IF_ERROR_RETURN( 875 _soc_td2p_portctrl_pm_init(unit, &max_phys, 876 &pm_types, &pms_arr_len)); 877 if (pms_arr_len == 0) { 878 return SOC_E_UNAVAIL; 879 } 880 881 /* 882 * If portmod was create - destroy and create again 883 * Better way would be to create once and leave it. 884 */ 885 if (SOC_E_NONE == soc_esw_portctrl_init_check(unit)) { 886 SOC_IF_ERROR_RETURN(portmod_destroy(unit)); 887 } 888 889 PORTMOD_CREATE_F_PM_NULL_SET(flags); 890 891 SOC_IF_ERROR_RETURN 892 (portmod_create(unit, flags, SOC_MAX_NUM_PORTS, max_phys, 893 pms_arr_len, pm_types)); 894 895 for (count = 0; SOC_SUCCESS(rv) && (count < pms_arr_len); count++) { 896 #ifdef PORTMOD_PM4X10TD_SUPPORT 897 if (pm_types[count].type == portmodDispatchTypePm4x10td) { 898 rv = _soc_td2p_portctrl_pm4x10_portmod_init 899 (unit, pm_types[count].instances); 900 } else 901 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 902 #ifdef PORTMOD_PM4X25_SUPPORT 903 if (pm_types[count].type == portmodDispatchTypePm4x25) { 904 rv = _soc_td2p_portctrl_pm4x25_portmod_init 905 (unit, pm_types[count].instances); 906 } else 907 #endif /* PORTMOD_PM4X25_SUPPORT */ 908 #ifdef PORTMOD_PM12X10_SUPPORT 909 if (pm_types[count].type == portmodDispatchTypePm12x10) { 910 rv = _soc_td2p_portctrl_pm12x10_portmod_init 911 (unit, pm_types[count].instances); 912 } else 913 #endif /* PORTMOD_PM12X10_SUPPORT */ 914 { 915 rv = SOC_E_INTERNAL; 916 } 917 } 918 919 return rv; 920 } 921 922 /* 923 * Function: 924 * soc_td2p_portctrl_pm_portmod_deinit 925 * Purpose: 926 * Deinitialize PortMod and PortMacro for Trident2Plus. 927 * Free pm user access data. 928 * Parameters: 929 * unit - (IN) Unit number. 930 * Returns: 931 * SOC_E_NONE 932 */ 933 int 934 soc_td2p_portctrl_pm_portmod_deinit(int unit) 935 { 936 if (SOC_E_INIT == soc_esw_portctrl_init_check(unit)) { 937 return SOC_E_NONE; 938 } 939 940 /* Free PMs structures */ 941 #ifdef PORTMOD_PM4X10TD_SUPPORT 942 if (pm4x10_td2p_user_acc[unit] != NULL) { 943 sal_free(pm4x10_td2p_user_acc[unit]); 944 pm4x10_td2p_user_acc[unit] = NULL; 945 } 946 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 947 948 #ifdef PORTMOD_PM12X10_SUPPORT 949 if (pm12x10_td2p_user_acc[unit] != NULL) { 950 sal_free(pm12x10_td2p_user_acc[unit]); 951 pm12x10_td2p_user_acc[unit] = NULL; 952 } 953 #endif /* PORTMOD_PM12X10_SUPPORT */ 954 955 #ifdef PORTMOD_PM4X25_SUPPORT 956 if (pm4x25_td2p_user_acc[unit] != NULL) { 957 sal_free(pm4x25_td2p_user_acc[unit]); 958 pm4x25_td2p_user_acc[unit] = NULL; 959 } 960 #endif /* PORTMOD_PM4X25_SUPPORT */ 961 962 SOC_IF_ERROR_RETURN(portmod_destroy(unit)); 963 964 return SOC_E_NONE; 965 } 966 967 int 968 soc_td2p_portctrl_pm_port_config_get(int unit, soc_port_t port, void *port_config) 969 { 970 #ifdef PORTMOD_PM4X10TD_SUPPORT 971 int rv = SOC_E_NONE; 972 int pmid = 0, lane, phy, phy_port, logical_port, f_logical_port, port_mode; 973 int first_port, core_num = 0, core_index, is_sim; 974 int type = portmodDispatchTypeCount; 975 uint32 txlane_map, rxlane_map, rxlane_map_l, i; 976 uint32 *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL; 977 uint32 tx_polarity, rx_polarity; 978 portmod_port_init_config_t *port_config_info; 979 phymod_firmware_load_method_t fw_load_method; 980 phymod_polarity_t polarity; /**< Lanes Polarity */ 981 phymod_lane_map_t lane_map; 982 983 port_config_info = (portmod_port_init_config_t *)port_config; 984 985 SOC_IF_ERROR_RETURN(soc_td2p_port_mode_get(unit, port, &port_mode)); 986 if (port_mode == portmodPortModeTri012 || port_mode == portmodPortModeTri023) { 987 port_config_info->port_mode_aux_info = portmodModeInfoThreePorts; 988 } 989 990 phy = SOC_INFO(unit).port_l2p_mapping[port]; 991 992 /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */ 993 core_index = (phy - 1) / SOC_PM4X10_NUM_LANES; 994 for (i=0; i<SOC_TD2P_PM4X10_COUNT; i++) { 995 if (core_index == _td2p_pm4x10_core_num[i]) { 996 type = portmodDispatchTypePm4x10td; 997 SOC_IF_ERROR_RETURN 998 (_soc_td2p_portctrl_device_addr_port_get(unit, 999 portmodDispatchTypePm4x10td, 1000 &pAddr, &pPort, &pCoreNum)); 1001 pmid = i; 1002 core_num = 1; 1003 break; 1004 } 1005 } 1006 /* When port dones't find PM4x10, find PM12x10 again. */ 1007 if (i == SOC_TD2P_PM4X10_COUNT) { 1008 for (i=0; i<SOC_TD2P_PM12X10_COUNT*SOC_PM12X10_PM4X10_COUNT; i++) { 1009 if (core_index == _td2p_pm12x10_core_num[i]) { 1010 type = portmodDispatchTypePm12x10; 1011 SOC_IF_ERROR_RETURN 1012 (_soc_td2p_portctrl_device_addr_port_get(unit, 1013 portmodDispatchTypePm12x10, 1014 &pAddr, &pPort, &pCoreNum)); 1015 /* Because one PM12x10 has three cores and one corresponding pmid. */ 1016 pmid = i / SOC_PM12X10_PM4X10_COUNT; 1017 core_num = SOC_PM12X10_PM4X10_COUNT; 1018 break; 1019 } 1020 } 1021 } 1022 1023 if (!pAddr || !pPort || type == portmodDispatchTypeCount) { 1024 return SOC_E_INTERNAL; 1025 } 1026 1027 /* PM info */ 1028 first_port = pPort[pmid]; 1029 1030 for (core_index = 0; core_index < core_num; core_index++) { 1031 fw_load_method = phymodFirmwareLoadMethodExternal; 1032 1033 soc_physim_enable_get(unit, &is_sim); 1034 1035 if (is_sim) { 1036 /* Firmward loader : Don't allow FW load on sim enviroment */ 1037 fw_load_method = phymodFirmwareLoadMethodNone; 1038 } else { 1039 fw_load_method = soc_property_suffix_num_get(unit, pmid, 1040 spn_LOAD_FIRMWARE, "quad", 1041 phymodFirmwareLoadMethodExternal); 1042 fw_load_method &= 0xff; 1043 } 1044 1045 rv = phymod_polarity_t_init(&polarity); 1046 if (PORTMOD_FAILURE(rv)) { 1047 break; 1048 } 1049 1050 f_logical_port = SOC_INFO(unit).port_p2l_mapping[first_port]; 1051 1052 /* Polarity */ 1053 for (lane = 0; lane < SOC_PM4X10_NUM_LANES; lane++) { 1054 phy_port = first_port + lane + (core_index*4); 1055 logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 1056 1057 /* in case of 100G - there is no logical port for core1, core2 */ 1058 /* so if the logical port is -1, check 100G and use core0 */ 1059 /* This could be a 100G port. so mapping is available for core0 only */ 1060 if (core_index && (logical_port == -1)) { 1061 if (IS_C_PORT(unit, f_logical_port)) { 1062 logical_port = f_logical_port; 1063 } 1064 } 1065 1066 _pm_port_polarity_get(unit, logical_port, phy_port, lane, core_index, &tx_polarity, &rx_polarity); 1067 1068 polarity.rx_polarity |= rx_polarity; 1069 polarity.tx_polarity |= tx_polarity; 1070 1071 } 1072 1073 /* Lane map */ 1074 rv = phymod_lane_map_t_init(&lane_map); 1075 if (PORTMOD_FAILURE(rv)) { 1076 break; 1077 } 1078 1079 phy_port = first_port + (core_index*4); 1080 logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 1081 1082 if (core_index && (logical_port == -1)) { 1083 if (IS_C_PORT(unit, f_logical_port)) { 1084 logical_port = f_logical_port; 1085 } 1086 } 1087 1088 _pm_port_lanemap_get(unit, logical_port, phy_port, core_index, &txlane_map, &rxlane_map); 1089 1090 rxlane_map_l = rxlane_map ; 1091 /* For TSC-E/F family, both lane_map_rx and lane_map_tx are logic lane base */ 1092 /* TD2/TD2+ xgxs_rx_lane_map is phy-lane base */ 1093 if(SOC_IS_TRIDENT2PLUS(unit)) { /* use TD2 legacy notion system */ 1094 rxlane_map_l = 0 ; 1095 for (i=0; i<SOC_PM4X10_NUM_LANES; i++) { 1096 rxlane_map_l |= i << SOC_PM4X10_NUM_LANES *((rxlane_map >> (i*SOC_PM4X10_NUM_LANES))& SOC_PM4X10_LANE_MASK) ; 1097 } 1098 } 1099 1100 if (type == portmodDispatchTypePm12x10) { 1101 txlane_map = (_soc_td2p_portctrl_is_chip_bonding_swap(unit, pmid, core_index, portmodDispatchTypePm12x10, 1)) ? 1102 SOC_TD2P_NIB_TRX(txlane_map) : txlane_map; 1103 rxlane_map = (_soc_td2p_portctrl_is_chip_bonding_swap(unit, pmid, core_index, portmodDispatchTypePm12x10, 0)) ? 1104 SOC_TD2P_NIB_TRX(rxlane_map_l) : rxlane_map_l; 1105 } else { 1106 txlane_map = (_soc_td2p_portctrl_is_chip_bonding_swap(unit, pmid, core_index, portmodDispatchTypePm4x10td, 1)) ? 1107 SOC_TD2P_NIB_TRX(txlane_map) : txlane_map; 1108 1109 rxlane_map = (_soc_td2p_portctrl_is_chip_bonding_swap(unit, pmid, core_index, portmodDispatchTypePm4x10td, 0)) ? 1110 SOC_TD2P_NIB_TRX(rxlane_map_l) : rxlane_map_l; 1111 } 1112 1113 lane_map.num_of_lanes = SOC_PM4X10_NUM_LANES; 1114 1115 for(lane = 0 ; lane < SOC_PM4X10_NUM_LANES; lane++) { 1116 lane_map.lane_map_tx[lane] = 1117 (txlane_map >> (lane * SOC_PM4X10_NUM_LANES)) & 1118 SOC_PM4X10_LANE_MASK; 1119 lane_map.lane_map_rx[lane] = 1120 (rxlane_map >> (lane * SOC_PM4X10_NUM_LANES)) & 1121 SOC_PM4X10_LANE_MASK; 1122 } 1123 1124 sal_memcpy(&port_config_info->fw_load_method[core_index], &fw_load_method, 1125 sizeof(phymod_firmware_load_method_t)); 1126 port_config_info->fw_load_method_overwrite = 1; 1127 sal_memcpy(&port_config_info->polarity[core_index], &polarity, 1128 sizeof(phymod_polarity_t)); 1129 port_config_info->polarity_overwrite = 1; 1130 sal_memcpy(&port_config_info->lane_map[core_index], &lane_map, 1131 sizeof(phymod_lane_map_t)); 1132 port_config_info->lane_map_overwrite = 1; 1133 } 1134 1135 return rv; 1136 #else /* PORTMOD_PM4X10TD_SUPPORT */ 1137 return SOC_E_UNAVAIL; 1138 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 1139 } 1140 1141 int 1142 soc_td2p_portctrl_pm_port_phyaddr_get(int unit, soc_port_t port) 1143 { 1144 #if defined(PORTMOD_PM4X10TD_SUPPORT) || defined(PORTMOD_PM12X10_SUPPORT) 1145 int phy, core_index; 1146 uint32 i, *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL; 1147 1148 phy = SOC_INFO(unit).port_l2p_mapping[port]; 1149 1150 /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */ 1151 core_index = (phy - 1) / SOC_PM4X10_NUM_LANES; 1152 #ifdef PORTMOD_PM4X10TD_SUPPORT 1153 for (i=0; i<SOC_TD2P_PM4X10_COUNT; i++) { 1154 if (core_index == _td2p_pm4x10_core_num[i]) { 1155 SOC_IF_ERROR_RETURN 1156 (_soc_td2p_portctrl_device_addr_port_get(unit, 1157 portmodDispatchTypePm4x10td, 1158 &pAddr, &pPort, &pCoreNum)); 1159 return pAddr[i]; 1160 } 1161 } 1162 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 1163 1164 #ifdef PORTMOD_PM12X10_SUPPORT 1165 /* When port dones't find PM4x10, find PM12x10 again. */ 1166 for (i=0; i<SOC_TD2P_PM12X10_COUNT*SOC_PM12X10_PM4X10_COUNT; i++) { 1167 if (core_index == _td2p_pm12x10_core_num[i]) { 1168 SOC_IF_ERROR_RETURN 1169 (_soc_td2p_portctrl_device_addr_port_get(unit, 1170 portmodDispatchTypePm12x10, 1171 &pAddr, &pPort, &pCoreNum)); 1172 return pAddr[i]; 1173 } 1174 } 1175 #endif /* PORTMOD_PM12X10_SUPPORT */ 1176 #endif 1177 return -1; 1178 } 1179 1180 int 1181 soc_td2p_portctrl_pm_type_get(int unit, soc_port_t phy_port, 1182 int* pm_type) 1183 { 1184 if ((phy_port < 0) || (phy_port > 128)) { 1185 return SOC_E_PARAM; 1186 } 1187 1188 #ifdef PORTMOD_PM4X10TD_SUPPORT 1189 *pm_type = portmodDispatchTypePm4x10; 1190 return SOC_E_NONE; 1191 #else /* PORTMOD_PM4X10TD_SUPPORT */ 1192 *pm_type = -1; 1193 return SOC_E_UNAVAIL; 1194 #endif /* PORTMOD_PM4X10TD_SUPPORT */ 1195 } 1196 1197 #endif /* BCM_TRIDENT2PLUS_SUPPORT */