portctrl.c (44356B)
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/bondoptions.h> 15 #include <soc/mem.h> 16 #include <soc/esw/portctrl.h> 17 #include <soc/monterey.h> 18 #include <shared/bsl.h> 19 #include <soc/phy/phymod_sim.h> 20 #include <soc/portmod/portmod.h> 21 22 #ifdef BCM_MONTEREY_SUPPORT 23 24 #define SOC_MN_PM4X10_COUNT 6 25 #define SOC_MN_PM4X25_COUNT 4 26 #define SOC_MN_CPM4X25_COUNT 6 27 28 #define SOC_MN_56671_PM4X25_COUNT 5 29 #define SOC_MN_56671_CPM4X25_COUNT 5 30 31 #define SOC_MN_MAX_PORTS_PER_TSC 4 32 33 #define SOC_MN_PM4X10_PORT_1 21 34 #define SOC_MN_PM4X10_PORT_2 25 35 #define SOC_MN_PM4X10_PORT_3 29 36 #define SOC_MN_PM4X10_PORT_4 33 37 #define SOC_MN_PM4X10_PORT_5 37 38 #define SOC_MN_PM4X10_PORT_6 41 39 40 41 #define SOC_MN_PM4X25_PORT_1 13 42 #define SOC_MN_PM4X25_PORT_2 17 43 #define SOC_MN_PM4X25_PORT_3 45 44 #define SOC_MN_PM4X25_PORT_4 49 45 46 #define SOC_MN_56671_PM4X25_PORT_1 13 47 #define SOC_MN_56671_PM4X25_PORT_2 17 48 #define SOC_MN_56671_PM4X25_PORT_3 45 49 #define SOC_MN_56671_PM4X25_PORT_4 49 50 #define SOC_MN_56671_PM4X25_PORT_5 53 51 52 #define SOC_MN_CPM4X25_PORT_1 1 53 #define SOC_MN_CPM4X25_PORT_2 5 54 #define SOC_MN_CPM4X25_PORT_3 9 55 #define SOC_MN_CPM4X25_PORT_4 53 56 #define SOC_MN_CPM4X25_PORT_5 57 57 #define SOC_MN_CPM4X25_PORT_6 61 58 59 60 #define SOC_MN_56671_CPM4X25_PORT_1 1 61 #define SOC_MN_56671_CPM4X25_PORT_2 5 62 #define SOC_MN_56671_CPM4X25_PORT_3 9 63 #define SOC_MN_56671_CPM4X25_PORT_4 57 64 #define SOC_MN_56671_CPM4X25_PORT_5 61 65 66 static uint32_t _mn_pm4x10_addr[SOC_MN_PM4X10_COUNT] = { 67 0xC1, 0xC5, 0xC9, 0xCD, 0xD1, 0xD5 68 }; 69 70 static uint32_t _mn_pm4x10_core_num[SOC_MN_PM4X10_COUNT] = { 71 5, 6, 7, 8, 9, 10 72 }; 73 74 static uint32_t _mn_pm4x10_port[SOC_MN_PM4X10_COUNT] = { 75 SOC_MN_PM4X10_PORT_1, 76 SOC_MN_PM4X10_PORT_2, 77 SOC_MN_PM4X10_PORT_3, 78 SOC_MN_PM4X10_PORT_4, 79 SOC_MN_PM4X10_PORT_5, 80 SOC_MN_PM4X10_PORT_6 81 }; 82 83 84 85 static uint32_t _mn_pm4x25_addr[SOC_MN_PM4X25_COUNT] = { 86 0xA1, 0xA5, 87 0xA9, 0xAD 88 }; 89 90 static uint32_t _mn_pm4x25_core_num[SOC_MN_PM4X25_COUNT] = { 91 3, 4, 11, 12 92 }; 93 94 static uint32_t _mn_pm4x25_port[SOC_MN_PM4X25_COUNT] = { 95 SOC_MN_PM4X25_PORT_1, 96 SOC_MN_PM4X25_PORT_2, 97 SOC_MN_PM4X25_PORT_3, 98 SOC_MN_PM4X25_PORT_4, 99 }; 100 101 static uint32_t _mn_56671_pm4x25_addr[SOC_MN_56671_PM4X25_COUNT] = { 102 0xA1, 0xA5, 103 0xA9, 0xAD,0x8D 104 }; 105 106 static uint32_t _mn_56671_pm4x25_core_num[SOC_MN_56671_PM4X25_COUNT] = { 107 3, 4, 11, 12, 13 108 }; 109 110 111 static uint32_t _mn_56671_pm4x25_port[SOC_MN_56671_PM4X25_COUNT] = { 112 SOC_MN_56671_PM4X25_PORT_1, 113 SOC_MN_56671_PM4X25_PORT_2, 114 SOC_MN_56671_PM4X25_PORT_3, 115 SOC_MN_56671_PM4X25_PORT_4, 116 SOC_MN_56671_PM4X25_PORT_5, 117 }; 118 119 static uint32_t _mn_cpm4x25_addr[SOC_MN_CPM4X25_COUNT] = { 120 0x81, 0x85, 0x89, 121 0x8D, 0x91, 0x95 122 }; 123 124 static uint32_t _mn_cpm4x25_core_num[SOC_MN_CPM4X25_COUNT] = { 125 0, 1, 2, 13, 14, 15 126 }; 127 128 static uint32_t _mn_cpm4x25_port[SOC_MN_CPM4X25_COUNT] = { 129 SOC_MN_CPM4X25_PORT_1, 130 SOC_MN_CPM4X25_PORT_2, 131 SOC_MN_CPM4X25_PORT_3, 132 SOC_MN_CPM4X25_PORT_4, 133 SOC_MN_CPM4X25_PORT_5, 134 SOC_MN_CPM4X25_PORT_6, 135 }; 136 137 static uint32_t _mn_56671_cpm4x25_addr[SOC_MN_56671_CPM4X25_COUNT] = { 138 0x81, 0x85, 0x89, 139 0x91, 0x95 140 }; 141 142 static uint32_t _mn_56671_cpm4x25_core_num[SOC_MN_56671_CPM4X25_COUNT] = { 143 0, 1, 2, 14, 15 144 }; 145 146 static uint32_t _mn_56671_cpm4x25_port[SOC_MN_56671_CPM4X25_COUNT] = { 147 SOC_MN_56671_CPM4X25_PORT_1, 148 SOC_MN_56671_CPM4X25_PORT_2, 149 SOC_MN_56671_CPM4X25_PORT_3, 150 SOC_MN_56671_CPM4X25_PORT_4, 151 SOC_MN_56671_CPM4X25_PORT_5, 152 }; 153 #define SOC_MN_MAX_PHYS 65 /* 24 XLMACS, 40 CLMAC's */ 154 155 156 static portmod_pm_instances_t mn_pm_types[] = { 157 #ifdef PORTMOD_PM4X10_SUPPORT 158 {portmodDispatchTypePm4x10, SOC_MN_PM4X10_COUNT}, 159 #endif 160 #ifdef PORTMOD_PM4X25_SUPPORT 161 {portmodDispatchTypePm4x25, SOC_MN_PM4X25_COUNT}, 162 #endif 163 #ifdef PORTMOD_CPM4X25_SUPPORT 164 {portmodDispatchTypeCpm4x25, SOC_MN_CPM4X25_COUNT}, 165 #endif 166 }; 167 168 static portmod_pm_instances_t mn_56671_pm_types[] = { 169 #ifdef PORTMOD_PM4X10_SUPPORT 170 {portmodDispatchTypePm4x10, SOC_MN_PM4X10_COUNT}, 171 #endif 172 #ifdef PORTMOD_PM4X25_SUPPORT 173 {portmodDispatchTypePm4x25, SOC_MN_56671_PM4X25_COUNT}, 174 #endif 175 #ifdef PORTMOD_CPM4X25_SUPPORT 176 {portmodDispatchTypeCpm4x25, SOC_MN_56671_CPM4X25_COUNT}, 177 #endif 178 }; 179 180 #ifdef PORTMOD_PM4X10_SUPPORT 181 static portmod_default_user_access_t *pm4x10_mn_user_acc[SOC_MAX_NUM_DEVICES]; 182 #endif /* PORTMOD_PM4X10_SUPPORT */ 183 184 185 #ifdef PORTMOD_PM4X25_SUPPORT 186 static portmod_default_user_access_t *pm4x25_mn_user_acc[SOC_MAX_NUM_DEVICES]; 187 #endif /* PORTMOD_PM4X25_SUPPORT */ 188 189 #ifdef PORTMOD_CPM4X25_SUPPORT 190 static portmod_default_user_access_t *cpm4x25_mn_user_acc[SOC_MAX_NUM_DEVICES]; 191 #endif /* PORTMOD_CPM4X25_SUPPORT */ 192 193 soc_portctrl_functions_t soc_mn_portctrl_func = { 194 soc_mn_portctrl_pm_portmod_init, 195 soc_mn_portctrl_pm_portmod_deinit, 196 soc_mn_portctrl_pm_port_config_get, 197 soc_mn_portctrl_pm_port_phyaddr_get, 198 soc_mn_portctrl_port_ability_update, 199 soc_mn_portctrl_pm_type_get, 200 NULL 201 }; 202 203 STATIC int 204 _soc_mn_portctrl_pm_init(int unit, int *max_phys, 205 portmod_pm_instances_t **pm_types, 206 int *pms_arr_len) 207 { 208 uint16 dev_id; 209 uint8 rev_id; 210 211 soc_cm_get_id(unit, &dev_id, &rev_id); 212 *max_phys = SOC_MN_MAX_PHYS; 213 if (dev_id == BCM56671_DEVICE_ID) { 214 *pm_types = mn_56671_pm_types; 215 } else { 216 *pm_types = mn_pm_types; 217 218 } 219 *pms_arr_len = (sizeof(mn_pm_types) / sizeof(portmod_pm_instances_t)); 220 221 return SOC_E_NONE; 222 } 223 224 STATIC int 225 _soc_mn_portctrl_device_addr_port_get(int unit, int pm_type, 226 uint32_t **addr, 227 uint32_t **port, 228 uint32_t **core_num) 229 { 230 uint16 dev_id; 231 uint8 rev_id; 232 233 soc_cm_get_id(unit, &dev_id, &rev_id); 234 235 *addr = NULL; 236 *port = NULL; 237 *core_num = NULL; 238 239 if (pm_type == portmodDispatchTypePm4x10) { 240 *addr = _mn_pm4x10_addr; 241 *port = _mn_pm4x10_port; 242 *core_num = _mn_pm4x10_core_num; 243 } else if (pm_type == portmodDispatchTypePm4x25){ 244 if (dev_id == BCM56671_DEVICE_ID) { 245 *addr = _mn_56671_pm4x25_addr; 246 *port = _mn_56671_pm4x25_port; 247 *core_num = _mn_56671_pm4x25_core_num; 248 } else { 249 *addr = _mn_pm4x25_addr; 250 *port = _mn_pm4x25_port; 251 *core_num = _mn_pm4x25_core_num; 252 } 253 } else if (pm_type == portmodDispatchTypeCpm4x25){ 254 if (dev_id == BCM56671_DEVICE_ID) { 255 *addr = _mn_56671_cpm4x25_addr; 256 *port = _mn_56671_cpm4x25_port; 257 *core_num = _mn_56671_cpm4x25_core_num; 258 } else { 259 *addr = _mn_cpm4x25_addr; 260 *port = _mn_cpm4x25_port; 261 *core_num = _mn_cpm4x25_core_num; 262 } 263 } 264 265 return SOC_E_NONE; 266 } 267 268 STATIC int 269 _soc_mn_portctrl_pm_user_acc_flag_set(int unit, 270 portmod_default_user_access_t* pm_user_access) 271 { 272 return SOC_E_NONE; 273 } 274 275 276 #define NIBBLE_SWAP(data) (\ 277 (((data) & 0x0f) << 12) | \ 278 (((data) & 0xf0) << 4 ) | \ 279 (((data) >> 4) & 0xf0 ) | \ 280 (((data) >> 12) & 0x0f )) 281 282 #define LANE_SWAP(data) \ 283 ((0x3-(data&0x0f)) | (0x30-(data&0xf0)) | \ 284 (0x300-(data&0xf00)) | (0x3000-(data&0xf000))) 285 286 #define NIBBLE_GET(data, num) \ 287 (num == 0) ? (data & 0x0f) : \ 288 (num == 1) ? ((data & 0xf0) >> 4) : \ 289 (num == 2) ? ((data & 0xf00) >> 8) : \ 290 (num == 3) ? ((data & 0xf000) >> 12): \ 291 -1 292 293 /* Indexed by direction (rx=0; tx=1) and physical port number */ 294 static int monterey_def_pkg_rx_polarity_flip[64] = {0}; 295 static int monterey_def_pkg_tx_polarity_flip[64] = {0}; 296 297 /* Indexed by direction (rx=0; tx=1) and TSC instance */ 298 static int monterey_def_pkg_rx_lane_swap[16] = {0}; 299 static int monterey_def_pkg_tx_lane_swap[16] = {0}; 300 301 STATIC void 302 _soc_monterey_portctrl_pkg_config_set(int unit, int phy_port, uint32 *rx_pol, uint32 *tx_pol, 303 uint32 *rxlane_map, uint32 *txlane_map) 304 { 305 int *pkg_rx_lane_swap, *pkg_tx_lane_swap; 306 int *pkg_rx_polarity_flip, *pkg_tx_polarity_flip; 307 int tsc_num, lane, i; 308 309 tsc_num = (phy_port - 1) / SOC_PM4X10_NUM_LANES; 310 311 /* socBondInfoFeatureApachePkg42p5mm 312 * 42.5mm x 42.5mm original/base package */ 313 pkg_rx_lane_swap = &(monterey_def_pkg_rx_lane_swap[0]); 314 pkg_tx_lane_swap = &(monterey_def_pkg_tx_lane_swap[0]); 315 pkg_rx_polarity_flip = &(monterey_def_pkg_rx_polarity_flip[0]); 316 pkg_tx_polarity_flip = &(monterey_def_pkg_tx_polarity_flip[0]); 317 318 for (i = 0; i < SOC_PM4X10_NUM_LANES; i++) { 319 if (pkg_rx_polarity_flip[phy_port + i]) { 320 if (pkg_rx_lane_swap[tsc_num] == 0) { 321 lane = NIBBLE_GET(*rxlane_map, i); 322 if (lane >= 0) { 323 *rx_pol = (*rx_pol) ^ (0x1 << lane); 324 } 325 } 326 } 327 if (pkg_tx_polarity_flip[phy_port + i]) { 328 if (pkg_tx_lane_swap[tsc_num] == 0) { 329 lane = NIBBLE_GET(*txlane_map, i); 330 if (lane >= 0) { 331 *tx_pol = (*tx_pol) ^ (0x1 << lane); 332 } 333 } 334 } 335 } 336 337 if (pkg_rx_lane_swap[tsc_num] == 1) { 338 for (i = 0; i < SOC_PM4X10_NUM_LANES; i++) { 339 if (pkg_rx_polarity_flip[phy_port + i]) { 340 lane = NIBBLE_GET(*rxlane_map, ((SOC_PM4X10_NUM_LANES - 1) - i)); 341 if (lane >= 0) { 342 *rx_pol = (*rx_pol) ^ (0x1 << lane); 343 } 344 } 345 } 346 *rxlane_map = LANE_SWAP(*rxlane_map); 347 } 348 if (pkg_tx_lane_swap[tsc_num] == 1) { 349 for (i = 0; i < SOC_PM4X10_NUM_LANES; i++) { 350 if (pkg_tx_polarity_flip[phy_port + i]) { 351 lane = NIBBLE_GET(*txlane_map, ((SOC_PM4X10_NUM_LANES - 1) - i)); 352 if (lane >= 0) { 353 *tx_pol = (*tx_pol) ^ (0x1 << lane); 354 } 355 } 356 } 357 *txlane_map = LANE_SWAP(*txlane_map); 358 } 359 360 return; 361 } 362 /* 363 * Polarity get looks for physical port based config first. This will enable 364 * the user to define the polarity for all ports weather mapped to logical 365 * port or not. 366 * 367 * For legacy compatibility - we still look for the logical port 368 * config setup. 369 */ 370 STATIC 371 void monterey_pm_port_polarity_get(int unit, int logical_port, int physical_port, int lane, 372 int core_num, uint32 *tx_pol, uint32* rx_pol) 373 { 374 uint32 rx_polarity, tx_polarity, num_lanes=1; 375 376 if (logical_port != -1) { 377 num_lanes = SOC_INFO(unit).port_num_lanes[logical_port]; 378 } 379 rx_polarity = soc_property_phy_get (unit, physical_port, 0, 0, lane, 380 spn_PHY_CHAIN_RX_POLARITY_FLIP_PHYSICAL, 0xFFFFFFFF); 381 if (rx_polarity == 0xFFFFFFFF) { 382 rx_polarity = soc_property_port_get(unit, logical_port, 383 spn_PHY_XAUI_RX_POLARITY_FLIP, 0); 384 *rx_pol = (num_lanes == 1) ? ((rx_polarity & 0x1) << lane): rx_polarity; 385 } else { 386 *rx_pol = (rx_polarity & 0x1) << lane; 387 } 388 389 tx_polarity = soc_property_phy_get (unit, physical_port, 0, 0, lane, 390 spn_PHY_CHAIN_TX_POLARITY_FLIP_PHYSICAL, 0xFFFFFFFF); 391 if (tx_polarity == 0xFFFFFFFF) { 392 tx_polarity = soc_property_port_get(unit, logical_port, 393 spn_PHY_XAUI_TX_POLARITY_FLIP, 0); 394 *tx_pol = (num_lanes == 1) ? ((tx_polarity & 0x1) << lane) : tx_polarity; 395 } else { 396 *tx_pol = (tx_polarity & 0x1) << lane; 397 } 398 } 399 400 /* 401 * lanemap get looks for physical port based config first. This will enable 402 * the user to define the lanemap for all ports weather mapped to logical 403 * port or not. 404 * 405 * For legacy compatibility - we still look for the logical port 406 * config setup. 407 */ 408 STATIC 409 void monterey_pm_port_lanemap_get (int unit, int logical_port, int physical_port, 410 int core_num, uint32 *txlane_map, uint32* rxlane_map) 411 { 412 413 *rxlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 414 spn_PHY_CHAIN_RX_LANE_MAP_PHYSICAL, 0xFFFFFFFF); 415 416 if (*rxlane_map == 0xFFFFFFFF) { 417 *rxlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 418 spn_PHY_RX_LANE_MAP, 0xFFFFFFFF); 419 } 420 if (*rxlane_map == 0xFFFFFFFF) { 421 *rxlane_map = soc_property_port_suffix_num_get(unit, logical_port, core_num, 422 spn_XGXS_RX_LANE_MAP, 423 "core", 0x3210); 424 } 425 426 *txlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 427 spn_PHY_CHAIN_TX_LANE_MAP_PHYSICAL, 0xFFFFFFFF); 428 429 if (*txlane_map == 0xFFFFFFFF) { 430 *txlane_map = soc_property_phy_get (unit, physical_port, 0, 0, 0, 431 spn_PHY_TX_LANE_MAP, 0xFFFFFFFF); 432 } 433 if (*txlane_map == 0xFFFFFFFF) { 434 *txlane_map = soc_property_port_suffix_num_get(unit, logical_port, core_num, 435 spn_XGXS_TX_LANE_MAP, 436 "core", 0x3210); 437 } 438 } 439 440 441 STATIC int 442 _soc_mn_portctrl_pm4x10_portmod_init(int unit, int num_of_instances) 443 { 444 #ifdef PORTMOD_PM4X10_SUPPORT 445 int rv = SOC_E_NONE; 446 portmod_pm_create_info_t pm_info; 447 int pmid = 0, blk, is_sim, found, logical_port; 448 int first_port, idx, core_num, core_cnt; 449 uint32 *pAddr, *pPort, *pCoreNum; 450 int mode; 451 452 SOC_IF_ERROR_RETURN 453 (_soc_mn_portctrl_device_addr_port_get(unit, 454 portmodDispatchTypePm4x10, 455 &pAddr, &pPort, &pCoreNum)); 456 if (!pAddr || !pPort) { 457 return SOC_E_INTERNAL; 458 } 459 460 /* Allocate PMs */ 461 SOC_IF_ERROR_RETURN 462 (soc_esw_portctrl_pm_user_access_alloc(unit, 463 num_of_instances, 464 &pm4x10_mn_user_acc[unit])); 465 466 for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) { 467 468 rv = portmod_pm_create_info_t_init(unit, &pm_info); 469 if (PORTMOD_FAILURE(rv)) { 470 break; 471 } 472 /* PM info */ 473 first_port = pPort[pmid]; 474 475 SOC_PBMP_PORT_ADD(pm_info.phys, first_port); 476 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+1); 477 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+2); 478 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+3); 479 480 found = 0; 481 for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 482 blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 483 if (SOC_BLOCK_INFO(unit, blk).type == 484 ( SOC_BLK_XLPORT)){ 485 found = 1; 486 break; 487 } 488 489 } 490 if (!found) { 491 rv = SOC_E_INTERNAL; 492 break; 493 } 494 495 pm_info.type = portmodDispatchTypePm4x10; 496 497 /* Init user_acc for phymod access struct */ 498 rv = portmod_default_user_access_t_init(unit, 499 &(pm4x10_mn_user_acc[unit][pmid])); 500 if (PORTMOD_FAILURE(rv)) { 501 break; 502 } 503 504 SOC_IF_ERROR_RETURN( 505 _soc_mn_portctrl_pm_user_acc_flag_set(unit, 506 &(pm4x10_mn_user_acc[unit][pmid]))); 507 508 PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x10_mn_user_acc[unit][pmid]))); 509 pm4x10_mn_user_acc[unit][pmid].unit = unit; 510 pm4x10_mn_user_acc[unit][pmid].blk_id = blk; 511 pm4x10_mn_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex"); 512 if (pm4x10_mn_user_acc[unit][pmid].mutex == NULL) { 513 rv = SOC_E_MEMORY; 514 break; 515 } 516 517 /* Specific info for PM4x10 */ 518 rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x10.access); 519 if (PORTMOD_FAILURE(rv)) { 520 break; 521 } 522 523 pm_info.pm_specific_info.pm4x10.access.user_acc = 524 &(pm4x10_mn_user_acc[unit][pmid]); 525 pm_info.pm_specific_info.pm4x10.access.addr = pAddr[pmid]; 526 pm_info.pm_specific_info.pm4x10.access.bus = NULL; /* Use default bus */ 527 528 rv = soc_physim_check_sim(unit, phymodDispatchTypeTsce_dpll, 529 &(pm_info.pm_specific_info.pm4x10.access), 530 0, &is_sim); 531 if (PORTMOD_FAILURE(rv)) { 532 break; 533 } 534 535 if (is_sim) { 536 pm_info.pm_specific_info.pm4x10.access.bus->bus_capabilities |= 537 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL); 538 539 /* Firmward loader : Don't allow FW load on sim enviroment */ 540 pm_info.pm_specific_info.pm4x10.fw_load_method = 541 phymodFirmwareLoadMethodNone; 542 } 543 544 /* Use default external loader if NULL */ 545 pm_info.pm_specific_info.pm4x10.external_fw_loader = NULL; 546 547 logical_port = SOC_INFO(unit).port_p2l_mapping[first_port]; 548 core_cnt = 1; 549 550 for (core_num = 0; core_num < core_cnt; core_num++) { 551 pm_info.pm_specific_info.pm4x10.core_num = pCoreNum? pCoreNum[pmid] : pmid; 552 pm_info.pm_specific_info.pm4x10.core_num_int = 0; 553 pm_info.pm_specific_info.pm4x10.rescal = -1; 554 } 555 556 SOC_IF_ERROR_RETURN(soc_monterey_port_mode_get(unit, logical_port, &mode)); 557 558 /* Add PM to PortMod */ 559 rv = portmod_port_macro_add(unit, &pm_info); 560 } 561 562 if (PORTMOD_FAILURE(rv)) { 563 for (pmid=0; pmid < num_of_instances; pmid++) { 564 if (pm4x10_mn_user_acc[unit][pmid].mutex) { 565 sal_mutex_destroy(pm4x10_mn_user_acc[unit][pmid].mutex); 566 pm4x10_mn_user_acc[unit][pmid].mutex = NULL; 567 } 568 } 569 } 570 571 return rv; 572 #else /* PORTMOD_PM4X10_SUPPORT */ 573 return SOC_E_UNAVAIL; 574 #endif /* PORTMOD_PM4X10_SUPPORT */ 575 } 576 577 STATIC int 578 _soc_mn_portctrl_pm4x25_portmod_init(int unit, int num_of_instances) 579 { 580 #ifdef PORTMOD_PM4X25_SUPPORT 581 int rv = SOC_E_NONE; 582 portmod_pm_create_info_t pm_info; 583 int pmid = 0, blk, is_sim, found, logical_port; 584 int first_port, idx, core_num, core_cnt; 585 uint32 *pAddr, *pPort,*pCoreNum; 586 int mode; 587 588 SOC_IF_ERROR_RETURN 589 (_soc_mn_portctrl_device_addr_port_get(unit, 590 portmodDispatchTypePm4x25, 591 &pAddr, &pPort,&pCoreNum)); 592 if (!pAddr || !pPort) { 593 return SOC_E_INTERNAL; 594 } 595 596 /* Allocate PMs */ 597 SOC_IF_ERROR_RETURN 598 (soc_esw_portctrl_pm_user_access_alloc(unit, 599 num_of_instances, 600 &pm4x25_mn_user_acc[unit])); 601 602 for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) { 603 604 rv = portmod_pm_create_info_t_init(unit, &pm_info); 605 if (PORTMOD_FAILURE(rv)) { 606 break; 607 } 608 /* PM info */ 609 first_port = pPort[pmid]; 610 611 SOC_PBMP_PORT_ADD(pm_info.phys, first_port); 612 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+1); 613 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+2); 614 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+3); 615 616 found = 0; 617 for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 618 blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 619 if (SOC_BLOCK_INFO(unit, blk).type == 620 ( SOC_BLK_CLPORT)){ 621 found = 1; 622 break; 623 } 624 } 625 if (!found) { 626 rv = SOC_E_INTERNAL; 627 break; 628 } 629 630 pm_info.type = portmodDispatchTypePm4x25; 631 632 /* Init user_acc for phymod access struct */ 633 rv = portmod_default_user_access_t_init(unit, 634 &(pm4x25_mn_user_acc[unit][pmid])); 635 if (PORTMOD_FAILURE(rv)) { 636 break; 637 } 638 639 PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(pm4x25_mn_user_acc[unit][pmid]))); 640 pm4x25_mn_user_acc[unit][pmid].unit = unit; 641 pm4x25_mn_user_acc[unit][pmid].blk_id = blk; 642 pm4x25_mn_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex"); 643 if (pm4x25_mn_user_acc[unit][pmid].mutex == NULL) { 644 rv = SOC_E_MEMORY; 645 break; 646 } 647 648 /* Specific info for PM4x25 */ 649 rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x25.access); 650 if (PORTMOD_FAILURE(rv)) { 651 break; 652 } 653 654 pm_info.pm_specific_info.pm4x25.access.user_acc = 655 &(pm4x25_mn_user_acc[unit][pmid]); 656 pm_info.pm_specific_info.pm4x25.access.addr = pAddr[pmid]; 657 pm_info.pm_specific_info.pm4x25.access.bus = NULL; /* Use default bus */ 658 659 rv = soc_physim_check_sim(unit, phymodDispatchTypeTscf_gen3, 660 &(pm_info.pm_specific_info.pm4x25.access), 661 0, &is_sim); 662 663 if (PORTMOD_FAILURE(rv)) { 664 break; 665 } 666 667 if (is_sim) { 668 pm_info.pm_specific_info.pm4x25.access.bus->bus_capabilities |= 669 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL); 670 671 /* Firmward loader : Don't allow FW load on sim enviroment */ 672 pm_info.pm_specific_info.pm4x25.fw_load_method = 673 phymodFirmwareLoadMethodNone; 674 } 675 676 /* Use default external loader if NULL */ 677 pm_info.pm_specific_info.pm4x25.external_fw_loader = NULL; 678 679 logical_port = SOC_INFO(unit).port_p2l_mapping[first_port]; 680 core_cnt = 1; 681 682 for (core_num = 0; core_num < core_cnt; core_num++) { 683 pm_info.pm_specific_info.pm4x25.core_num = pCoreNum? pCoreNum[pmid] : pmid; 684 pm_info.pm_specific_info.pm4x25.core_num_int = 0; 685 pm_info.pm_specific_info.pm4x25.rescal = -1; 686 } 687 688 SOC_IF_ERROR_RETURN(soc_monterey_port_mode_get(unit, logical_port, &mode)); 689 pm_info.pm_specific_info.pm4x25.port_mode_aux_info = mode; 690 691 /* Add PM to PortMod */ 692 rv = portmod_port_macro_add(unit, &pm_info); 693 } 694 695 if (PORTMOD_FAILURE(rv)) { 696 for (pmid=0; pmid < num_of_instances; pmid++) { 697 if (pm4x25_mn_user_acc[unit][pmid].mutex) { 698 sal_mutex_destroy(pm4x25_mn_user_acc[unit][pmid].mutex); 699 pm4x25_mn_user_acc[unit][pmid].mutex = NULL; 700 } 701 } 702 } 703 704 return rv; 705 #else /* PORTMOD_PM4X25_SUPPORT */ 706 return SOC_E_UNAVAIL; 707 #endif /* PORTMOD_PM4X25_SUPPORT */ 708 } 709 710 STATIC int 711 _soc_mn_portctrl_cpm4x25_portmod_init(int unit, int num_of_instances) 712 { 713 #ifdef PORTMOD_CPM4X25_SUPPORT 714 int rv = SOC_E_NONE; 715 portmod_pm_create_info_t pm_info; 716 int pmid = 0, blk, is_sim, found, logical_port; 717 int first_port, idx, core_num, core_cnt; 718 uint32 *pAddr, *pPort,*pCoreNum; 719 int mode; 720 721 SOC_IF_ERROR_RETURN 722 (_soc_mn_portctrl_device_addr_port_get(unit, 723 portmodDispatchTypeCpm4x25, 724 &pAddr, &pPort,&pCoreNum)); 725 if (!pAddr || !pPort) { 726 return SOC_E_INTERNAL; 727 } 728 729 /* Allocate PMs */ 730 SOC_IF_ERROR_RETURN 731 (soc_esw_portctrl_pm_user_access_alloc(unit, 732 num_of_instances, 733 &cpm4x25_mn_user_acc[unit])); 734 735 for (pmid = 0; PORTMOD_SUCCESS(rv) && (pmid < num_of_instances); pmid++) { 736 737 rv = portmod_pm_create_info_t_init(unit, &pm_info); 738 if (PORTMOD_FAILURE(rv)) { 739 break; 740 } 741 /* PM info */ 742 first_port = pPort[pmid]; 743 744 SOC_PBMP_PORT_ADD(pm_info.phys, first_port); 745 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+1); 746 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+2); 747 SOC_PBMP_PORT_ADD(pm_info.phys, first_port+3); 748 749 found = 0; 750 for(idx = 0; idx < SOC_DRIVER(unit)->port_num_blktype; idx++){ 751 blk = SOC_PORT_IDX_INFO(unit, first_port, idx).blk; 752 if (SOC_BLOCK_INFO(unit, blk).type == 753 ( SOC_BLK_CLPORT)){ 754 found = 1; 755 break; 756 } 757 } 758 if (!found) { 759 rv = SOC_E_INTERNAL; 760 break; 761 } 762 763 pm_info.type = portmodDispatchTypeCpm4x25; 764 765 /* Init user_acc for phymod access struct */ 766 rv = portmod_default_user_access_t_init(unit, 767 &(cpm4x25_mn_user_acc[unit][pmid])); 768 if (PORTMOD_FAILURE(rv)) { 769 break; 770 } 771 772 PORTMOD_USER_ACCESS_FW_LOAD_REVERSE_SET((&(cpm4x25_mn_user_acc[unit][pmid]))); 773 cpm4x25_mn_user_acc[unit][pmid].unit = unit; 774 cpm4x25_mn_user_acc[unit][pmid].blk_id = blk; 775 cpm4x25_mn_user_acc[unit][pmid].mutex = sal_mutex_create("core mutex"); 776 if (cpm4x25_mn_user_acc[unit][pmid].mutex == NULL) { 777 rv = SOC_E_MEMORY; 778 break; 779 } 780 781 /* Specific info for PM4x25 */ 782 rv = phymod_access_t_init(&pm_info.pm_specific_info.pm4x25.access); 783 if (PORTMOD_FAILURE(rv)) { 784 break; 785 } 786 787 pm_info.pm_specific_info.pm4x25.access.user_acc = 788 &(cpm4x25_mn_user_acc[unit][pmid]); 789 pm_info.pm_specific_info.pm4x25.access.addr = pAddr[pmid]; 790 pm_info.pm_specific_info.pm4x25.access.bus = NULL; /* Use default bus */ 791 792 rv = soc_physim_check_sim(unit, phymodDispatchTypeTscf_gen3, 793 &(pm_info.pm_specific_info.pm4x25.access), 794 0, &is_sim); 795 796 if (PORTMOD_FAILURE(rv)) { 797 break; 798 } 799 800 if (is_sim) { 801 pm_info.pm_specific_info.pm4x25.access.bus->bus_capabilities |= 802 (PHYMOD_BUS_CAP_WR_MODIFY | PHYMOD_BUS_CAP_LANE_CTRL); 803 804 /* Firmward loader : Don't allow FW load on sim enviroment */ 805 pm_info.pm_specific_info.pm4x25.fw_load_method = 806 phymodFirmwareLoadMethodNone; 807 } 808 809 /* Use default external loader if NULL */ 810 pm_info.pm_specific_info.pm4x25.external_fw_loader = NULL; 811 812 logical_port = SOC_INFO(unit).port_p2l_mapping[first_port]; 813 core_cnt = 1; 814 815 for (core_num = 0; core_num < core_cnt; core_num++) { 816 pm_info.pm_specific_info.pm4x25.core_num = pCoreNum? pCoreNum[pmid] : pmid; 817 pm_info.pm_specific_info.pm4x25.core_num_int = 0; 818 pm_info.pm_specific_info.pm4x25.rescal = -1; 819 } 820 821 SOC_IF_ERROR_RETURN(soc_monterey_port_mode_get(unit, logical_port, &mode)); 822 823 /* Add PM to PortMod */ 824 rv = portmod_port_macro_add(unit, &pm_info); 825 } 826 827 if (PORTMOD_FAILURE(rv)) { 828 for (pmid=0; pmid < num_of_instances; pmid++) { 829 if (cpm4x25_mn_user_acc[unit][pmid].mutex) { 830 sal_mutex_destroy(cpm4x25_mn_user_acc[unit][pmid].mutex); 831 cpm4x25_mn_user_acc[unit][pmid].mutex = NULL; 832 } 833 } 834 } 835 836 return rv; 837 #else /* PORTMOD_PM4X25_SUPPORT */ 838 return SOC_E_UNAVAIL; 839 #endif /* PORTMOD_PM4X25_SUPPORT */ 840 } 841 842 /* 843 * Function: 844 * soc_mn_portctrl_pm_portmod_init 845 * Purpose: 846 * Initialize PortMod and PortMacro for Trident2Plus 847 * Add port macros (PM) to the unit's PortMod Manager (PMM). 848 * Parameters: 849 * unit - (IN) Unit number. 850 * Returns: 851 * SOC_E_XXX 852 */ 853 int 854 soc_mn_portctrl_pm_portmod_init(int unit) 855 { 856 uint32 flags = 0; 857 int rv = SOC_E_NONE, pms_arr_len = 0, count, max_phys= 0; 858 portmod_pm_instances_t *pm_types = NULL; 859 860 /* Call PortMod library initialization */ 861 SOC_IF_ERROR_RETURN( 862 _soc_mn_portctrl_pm_init(unit, &max_phys, 863 &pm_types, &pms_arr_len)); 864 if (pms_arr_len == 0) { 865 return SOC_E_UNAVAIL; 866 } 867 868 /* 869 * If portmod was create - destroy and create again 870 * Better way would be to create once and leave it. 871 */ 872 if (SOC_E_NONE == soc_esw_portctrl_init_check(unit)) { 873 SOC_IF_ERROR_RETURN(portmod_destroy(unit)); 874 } 875 876 PORTMOD_CREATE_F_PM_NULL_SET(flags); 877 878 SOC_IF_ERROR_RETURN 879 (portmod_create(unit, flags, SOC_MAX_NUM_PORTS, max_phys, 880 pms_arr_len, pm_types)); 881 882 for (count = 0; SOC_SUCCESS(rv) && (count < pms_arr_len); count++) { 883 #ifdef PORTMOD_PM4X10_SUPPORT 884 if (pm_types[count].type == portmodDispatchTypePm4x10) { 885 rv = _soc_mn_portctrl_pm4x10_portmod_init 886 (unit, pm_types[count].instances); 887 } else 888 #endif /* PORTMOD_PM4X10_SUPPORT */ 889 #ifdef PORTMOD_PM4X25_SUPPORT 890 if (pm_types[count].type == portmodDispatchTypePm4x25) { 891 rv = _soc_mn_portctrl_pm4x25_portmod_init 892 (unit, pm_types[count].instances); 893 } else 894 #endif /* PORTMOD_PM4X25_SUPPORT */ 895 #ifdef PORTMOD_CPM4X25_SUPPORT 896 if (pm_types[count].type == portmodDispatchTypeCpm4x25) { 897 rv = _soc_mn_portctrl_cpm4x25_portmod_init 898 (unit, pm_types[count].instances); 899 } else 900 #endif /* PORTMOD_CPM4X25_SUPPORT */ 901 { 902 rv = SOC_E_INTERNAL; 903 } 904 } 905 906 return rv; 907 } 908 909 /* 910 * Function: 911 * soc_mn_portctrl_pm_portmod_deinit 912 * Purpose: 913 * Deinitialize PortMod and PortMacro for Trident2Plus. 914 * Free pm user access data. 915 * Parameters: 916 * unit - (IN) Unit number. 917 * Returns: 918 * SOC_E_NONE 919 */ 920 int 921 soc_mn_portctrl_pm_portmod_deinit(int unit) 922 { 923 if (SOC_E_INIT == soc_esw_portctrl_init_check(unit)) { 924 return SOC_E_NONE; 925 } 926 927 /* Free PMs structures */ 928 #ifdef PORTMOD_PM4X10_SUPPORT 929 if (pm4x10_mn_user_acc[unit] != NULL) { 930 sal_free(pm4x10_mn_user_acc[unit]); 931 pm4x10_mn_user_acc[unit] = NULL; 932 } 933 #endif /* PORTMOD_PM4X10_SUPPORT */ 934 935 936 #ifdef PORTMOD_PM4X25_SUPPORT 937 if (pm4x25_mn_user_acc[unit] != NULL) { 938 sal_free(pm4x25_mn_user_acc[unit]); 939 pm4x25_mn_user_acc[unit] = NULL; 940 } 941 #endif /* PORTMOD_PM4X25_SUPPORT */ 942 #ifdef PORTMOD_CPM4X25_SUPPORT 943 if (cpm4x25_mn_user_acc[unit] != NULL) { 944 sal_free(cpm4x25_mn_user_acc[unit]); 945 cpm4x25_mn_user_acc[unit] = NULL; 946 } 947 #endif /* PORTMOD_CPM4X25_SUPPORT */ 948 949 SOC_IF_ERROR_RETURN(portmod_destroy(unit)); 950 951 return SOC_E_NONE; 952 } 953 954 int 955 soc_mn_portctrl_pm_port_config_get(int unit, soc_port_t port, void *port_config) 956 { 957 #ifdef PORTMOD_PM4X10_SUPPORT 958 int rv = SOC_E_NONE; 959 int pmid = 0, lane, phy, phy_port, logical_port, port_mode; 960 int first_port, core_num = 0, core_index, is_sim, type = 0; 961 uint32 txlane_map, rxlane_map, rxlane_map_l, i; 962 uint32 *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL; 963 uint32 tx_polarity, rx_polarity; 964 portmod_port_init_config_t *port_config_info; 965 phymod_firmware_load_method_t fw_load_method; 966 phymod_polarity_t polarity; /**< Lanes Polarity */ 967 phymod_lane_map_t lane_map; 968 uint8_t pm_found=0; 969 int cpri_mode = 0, eth_mode = 0; 970 uint16 dev_id; 971 uint8 rev_id; 972 int core_idx = 0 ; 973 int pm4x25_count = 0 ; 974 int cpm4x25_count = 0; 975 soc_cm_get_id(unit, &dev_id, &rev_id); 976 977 port_config_info = (portmod_port_init_config_t *)port_config; 978 SOC_IF_ERROR_RETURN(soc_monterey_port_mode_get(unit, port, &port_mode)); 979 if (port_mode == portmodPortModeTri012 || port_mode == portmodPortModeTri023) { 980 port_config_info->port_mode_aux_info = portmodModeInfoThreePorts; 981 } 982 983 phy = SOC_INFO(unit).port_l2p_mapping[port]; 984 985 /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */ 986 pm_found = 0; 987 core_index = (phy - 1) / SOC_PM4X10_NUM_LANES; 988 for (i=0; i<SOC_MN_PM4X10_COUNT; i++) { 989 if (core_index == _mn_pm4x10_core_num[i]) { 990 type = portmodDispatchTypePm4x10; 991 SOC_IF_ERROR_RETURN 992 (_soc_mn_portctrl_device_addr_port_get(unit, 993 portmodDispatchTypePm4x10, 994 &pAddr, &pPort, &pCoreNum)); 995 pmid = i; 996 core_num = 1; 997 pm_found = 1; 998 break; 999 } 1000 } 1001 /* When port dones't find PM4x10, find PM4x25 again. */ 1002 if (!pm_found) { 1003 if (dev_id == BCM56671_DEVICE_ID) { 1004 pm4x25_count = SOC_MN_56671_PM4X25_COUNT; 1005 } else { 1006 pm4x25_count = SOC_MN_PM4X25_COUNT; 1007 } 1008 for (i=0; i<pm4x25_count; i++) { 1009 if (dev_id == BCM56671_DEVICE_ID) { 1010 core_idx = _mn_56671_pm4x25_core_num[i] ; 1011 } else { 1012 core_idx = _mn_pm4x25_core_num[i]; 1013 } 1014 if (core_index ==core_idx) { 1015 type = portmodDispatchTypePm4x25; 1016 SOC_IF_ERROR_RETURN 1017 (_soc_mn_portctrl_device_addr_port_get(unit, 1018 portmodDispatchTypePm4x25, 1019 &pAddr, &pPort, &pCoreNum)); 1020 /* Because one PM4x25 has three cores and one corresponding pmid. */ 1021 pmid = i; 1022 core_num = 1; 1023 pm_found = 1; 1024 break; 1025 } 1026 } 1027 } 1028 1029 if (!pm_found) { 1030 if (dev_id == BCM56671_DEVICE_ID) { 1031 cpm4x25_count = SOC_MN_56671_CPM4X25_COUNT; 1032 } else { 1033 cpm4x25_count = SOC_MN_CPM4X25_COUNT; 1034 } 1035 for (i=0; i<cpm4x25_count; i++) { 1036 if (dev_id == BCM56671_DEVICE_ID) { 1037 core_idx = _mn_56671_cpm4x25_core_num[i]; 1038 } else { 1039 core_idx = _mn_cpm4x25_core_num[i]; 1040 } 1041 if (core_index ==core_idx) { 1042 type = portmodDispatchTypeCpm4x25; 1043 SOC_IF_ERROR_RETURN 1044 (_soc_mn_portctrl_device_addr_port_get(unit, 1045 portmodDispatchTypeCpm4x25, 1046 &pAddr, &pPort, &pCoreNum)); 1047 /* Because one PM4x25 has three cores and one corresponding pmid. */ 1048 pmid = i; 1049 core_num = 1; 1050 pm_found = 1; 1051 break; 1052 } 1053 } 1054 } 1055 1056 if (!pAddr || !pPort) { 1057 return SOC_E_INTERNAL; 1058 } 1059 1060 /* PM info */ 1061 first_port = pPort[pmid]; 1062 1063 for (core_index = 0; core_index < core_num; core_index++) { 1064 fw_load_method = phymodFirmwareLoadMethodExternal; 1065 1066 soc_physim_enable_get(unit, &is_sim); 1067 1068 if (is_sim) { 1069 /* Firmward loader : Don't allow FW load on sim enviroment */ 1070 fw_load_method = phymodFirmwareLoadMethodNone; 1071 } else { 1072 fw_load_method = soc_property_suffix_num_get(unit, pmid, 1073 spn_LOAD_FIRMWARE, "quad", 1074 phymodFirmwareLoadMethodExternal); 1075 fw_load_method &= 0xff; 1076 } 1077 1078 rv = phymod_polarity_t_init(&polarity); 1079 if (PORTMOD_FAILURE(rv)) { 1080 break; 1081 } 1082 1083 1084 /* Polarity */ 1085 for (lane = 0; lane < SOC_PM4X10_NUM_LANES; lane++) { 1086 phy_port = first_port + lane + (core_index*4); 1087 logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 1088 1089 /* in case of 100G - there is no logical port for core1, core2 */ 1090 /* so if the logical port is -1, check 100G and use core0 */ 1091 /* This could be a 100G port. so mapping is available for core0 only */ 1092 1093 monterey_pm_port_polarity_get(unit, logical_port, phy_port, lane, core_index, &tx_polarity, &rx_polarity); 1094 1095 polarity.rx_polarity |= rx_polarity; 1096 polarity.tx_polarity |= tx_polarity; 1097 } 1098 1099 /* Lane map */ 1100 rv = phymod_lane_map_t_init(&lane_map); 1101 if (PORTMOD_FAILURE(rv)) { 1102 break; 1103 } 1104 1105 phy_port = first_port + (core_index*4); 1106 logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 1107 1108 1109 monterey_pm_port_lanemap_get(unit, logical_port, phy_port, core_index, &txlane_map, &rxlane_map); 1110 /* Handle package level polarity flips and lane swaps */ 1111 if (!SAL_BOOT_SIMULATION) { 1112 _soc_monterey_portctrl_pkg_config_set(unit, phy_port, &rx_polarity, &tx_polarity, 1113 &rxlane_map, &txlane_map); 1114 } 1115 1116 polarity.rx_polarity |= rx_polarity; 1117 polarity.tx_polarity |= tx_polarity; 1118 1119 rxlane_map_l = rxlane_map ; 1120 /* For TSC-E/F family, both lane_map_rx and lane_map_tx are logic lane base */ 1121 /* TD2/TD2+ xgxs_rx_lane_map is phy-lane base */ 1122 if(SOC_IS_MONTEREY(unit)) { /* use TD2 legacy notion system */ 1123 rxlane_map_l = 0 ; 1124 for (i=0; i<SOC_PM4X10_NUM_LANES; i++) { 1125 rxlane_map_l |= i << SOC_PM4X10_NUM_LANES *((rxlane_map >> (i*SOC_PM4X10_NUM_LANES))& SOC_PM4X10_LANE_MASK) ; 1126 } 1127 } 1128 1129 if (type == portmodDispatchTypePm4x25) { 1130 lane_map.num_of_lanes = SOC_PM4X25_NUM_LANES; 1131 } else if (type == portmodDispatchTypeCpm4x25) { 1132 lane_map.num_of_lanes = SOC_PM4X25_NUM_LANES; 1133 } else { 1134 lane_map.num_of_lanes = SOC_PM4X10_NUM_LANES; 1135 } 1136 1137 for(lane = 0 ; lane < SOC_PM4X10_NUM_LANES; lane++) { 1138 lane_map.lane_map_tx[lane] = 1139 (txlane_map >> (lane * SOC_PM4X10_NUM_LANES)) & 1140 SOC_PM4X10_LANE_MASK; 1141 lane_map.lane_map_rx[lane] = 1142 (rxlane_map >> (lane * SOC_PM4X10_NUM_LANES)) & 1143 SOC_PM4X10_LANE_MASK; 1144 } 1145 1146 sal_memcpy(&port_config_info->fw_load_method[core_index], &fw_load_method, 1147 sizeof(phymod_firmware_load_method_t)); 1148 port_config_info->fw_load_method_overwrite = 1; 1149 sal_memcpy(&port_config_info->polarity[core_index], &polarity, 1150 sizeof(phymod_polarity_t)); 1151 port_config_info->polarity_overwrite = 1; 1152 sal_memcpy(&port_config_info->lane_map[core_index], &lane_map, 1153 sizeof(phymod_lane_map_t)); 1154 port_config_info->lane_map_overwrite = 1; 1155 } 1156 1157 /* Check CPM port mode */ 1158 first_port = 1 + (( phy - 1) & ~0x3); 1159 1160 for (lane = 0; lane < SOC_PM4X10_NUM_LANES; lane++) { 1161 phy_port = first_port + lane; 1162 logical_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 1163 1164 if ((logical_port == -1) || SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, logical_port)) { 1165 continue; 1166 } else { 1167 if (SOC_PBMP_MEMBER(SOC_INFO(unit).cpri.bitmap, logical_port)) { 1168 cpri_mode++; 1169 } else { 1170 eth_mode++; 1171 } 1172 } 1173 } 1174 if (cpri_mode && eth_mode) { 1175 port_config_info->cpm_core_mode = portmodCpmMixEthCpri; /* MixEthCPri */ 1176 } else if (cpri_mode && !eth_mode) { 1177 port_config_info->cpm_core_mode = portmodCpmAllCpri; /* AllCpri */ 1178 } else if (!cpri_mode && eth_mode) { 1179 port_config_info->cpm_core_mode = portmodCpmAllIEEE; /* AllIEEE */ 1180 } else { 1181 port_config_info->cpm_core_mode = portmodCpmCount; 1182 } 1183 1184 return rv; 1185 #else /* PORTMOD_PM4X10_SUPPORT */ 1186 return SOC_E_UNAVAIL; 1187 #endif /* PORTMOD_PM4X10_SUPPORT */ 1188 } 1189 1190 int 1191 soc_mn_portctrl_pm_port_phyaddr_get(int unit, soc_port_t port) 1192 { 1193 int phy, core_index; 1194 uint32 i, *pAddr = NULL, *pPort = NULL, *pCoreNum = NULL; 1195 int core_idx = 0 ; 1196 int pm4x25_count = 0; 1197 int cpm4x25_count = 0 ; 1198 uint16 dev_id; 1199 uint8 rev_id; 1200 soc_cm_get_id(unit, &dev_id, &rev_id); 1201 phy = SOC_INFO(unit).port_l2p_mapping[port]; 1202 1203 /* Find the port belong to which PM. The port has its own core id, using it to compare PM. */ 1204 core_index = (phy - 1) / SOC_PM4X10_NUM_LANES; 1205 #ifdef PORTMOD_PM4X10_SUPPORT 1206 for (i=0; i<SOC_MN_PM4X10_COUNT; i++) { 1207 if (core_index == _mn_pm4x10_core_num[i]) { 1208 SOC_IF_ERROR_RETURN 1209 (_soc_mn_portctrl_device_addr_port_get(unit, 1210 portmodDispatchTypePm4x10, 1211 &pAddr, &pPort, &pCoreNum)); 1212 return pAddr[i]; 1213 } 1214 } 1215 #endif /* PORTMOD_PM4X10_SUPPORT */ 1216 1217 #ifdef PORTMOD_PM4X25_SUPPORT 1218 /* When port dones't find PM4x10, find PM4x25 again. */ 1219 if (dev_id == BCM56671_DEVICE_ID) { 1220 pm4x25_count = SOC_MN_56671_PM4X25_COUNT; 1221 } else { 1222 pm4x25_count = SOC_MN_PM4X25_COUNT; 1223 } 1224 for (i=0; i<pm4x25_count; i++) { 1225 if (dev_id == BCM56671_DEVICE_ID) { 1226 core_idx = _mn_56671_pm4x25_core_num[i]; 1227 } else { 1228 core_idx = _mn_pm4x25_core_num[i]; 1229 } 1230 if (core_index == core_idx) { 1231 SOC_IF_ERROR_RETURN 1232 (_soc_mn_portctrl_device_addr_port_get(unit, 1233 portmodDispatchTypePm4x25, 1234 &pAddr, &pPort, &pCoreNum)); 1235 return pAddr[i]; 1236 } 1237 } 1238 #endif /* PORTMOD_PM4X25_SUPPORT */ 1239 #ifdef PORTMOD_CPM4X25_SUPPORT 1240 /* When port dones't find PM4x10, find PM4x25 again. */ 1241 if (dev_id == BCM56671_DEVICE_ID) { 1242 cpm4x25_count = SOC_MN_56671_CPM4X25_COUNT; 1243 } else { 1244 cpm4x25_count = SOC_MN_CPM4X25_COUNT; 1245 } 1246 for (i=0; i<cpm4x25_count; i++) { 1247 if (dev_id == BCM56671_DEVICE_ID) { 1248 core_idx = _mn_56671_cpm4x25_core_num[i]; 1249 } else { 1250 core_idx = _mn_cpm4x25_core_num[i]; 1251 } 1252 if (core_index == core_idx) { 1253 SOC_IF_ERROR_RETURN 1254 (_soc_mn_portctrl_device_addr_port_get(unit, 1255 portmodDispatchTypeCpm4x25, 1256 &pAddr, &pPort, &pCoreNum)); 1257 return pAddr[i]; 1258 } 1259 } 1260 #endif /* PORTMOD_CPM4X25_SUPPORT */ 1261 1262 1263 return -1; 1264 } 1265 1266 int 1267 soc_mn_portctrl_port_ability_update(int unit, soc_port_t port, soc_port_ability_t *ability) 1268 { 1269 int phy_port, tsc_id; 1270 uint32 force_hg; 1271 1272 if (!soc_feature(unit, soc_feature_untethered_otp)) { 1273 return SOC_E_NONE; 1274 } 1275 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1276 /* Each bit in FORCE_HG bond option represents one TSC/Port Macro 1277 * 1 - All ports in specified TSC are Higig only. 1278 * 0 - No restrictions 1279 */ 1280 force_hg = SOC_BOND_INFO(unit)->tsc_force_hg; 1281 tsc_id = (phy_port - 1) / SOC_MN_MAX_PORTS_PER_TSC; 1282 1283 if (force_hg & (1 << tsc_id)) { 1284 ability->encap &= ~SOC_PA_ENCAP_IEEE; 1285 } 1286 return SOC_E_NONE; 1287 } 1288 1289 int 1290 soc_mn_portctrl_pm_type_get(int unit, soc_port_t phy_port, 1291 int* pm_type) 1292 { 1293 uint16 dev_id; 1294 uint8 rev_id; 1295 soc_cm_get_id(unit, &dev_id, &rev_id); 1296 if ((phy_port < 0) || (phy_port > 64)) { 1297 return SOC_E_PARAM; 1298 } 1299 #if (defined (PORTMOD_PM4X10_SUPPORT) && defined (PORTMOD_PM4X25_SUPPORT) && defined (PORTMOD_CPM4X25_SUPPORT)) 1300 1301 if (MONTEREY_PORT_IS_PM4x25_PORT_PHY(unit, phy_port)) { 1302 *pm_type = portmodDispatchTypePm4x25; 1303 } 1304 else if (MONTEREY_PORT_IS_CPM4x25_PORT_PHY(unit, phy_port)) { 1305 if (dev_id == BCM56671_DEVICE_ID && ((phy_port >52) && (phy_port < 57))) { 1306 *pm_type = portmodDispatchTypePm4x25; 1307 } else { 1308 *pm_type = portmodDispatchTypeCpm4x25; 1309 1310 } 1311 } else { 1312 *pm_type = portmodDispatchTypePm4x10; 1313 } 1314 #else 1315 *pm_type = -1; 1316 #endif 1317 1318 return ((*pm_type == -1) ? SOC_E_UNAVAIL : SOC_E_NONE); 1319 } 1320 1321 #endif /* BCM_MONTEREY_SUPPORT */