pm4x10Q.c (63604B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <soc/types.h> 11 #include <soc/error.h> 12 #include <soc/drv.h> 13 #include <soc/wb_engine.h> 14 #include <soc/portmod/portmod_internal.h> 15 #include <soc/portmod/portmod_common.h> 16 #include <soc/portmod/portmod.h> 17 #include <soc/portmod/portmod_dispatch.h> 18 #include <soc/portmod/portmod_chain.h> 19 20 #include <soc/portmod/unimac.h> 21 #include <soc/portmod/pm4x10Q.h> 22 #include <soc/portmod/pm4x10.h> 23 24 25 26 #ifdef _ERR_MSG_MODULE_NAME 27 #error "_ERR_MSG_MODULE_NAME redefined" 28 #endif 29 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT 30 31 #ifdef PORTMOD_PM4x10Q_SUPPORT 32 33 #define PM_4x10_INFO(pm_info) ((pm_info)->pm_data.pm4x10_db) 34 #define PM_4x10Q_INFO(pm_info) ((pm_info)->pm_data.pm4x10q_db) 35 #define PM_4x10Q_PM_4x10_INFO(pm_info) (PM_4x10Q_INFO(pm_info)->pm4x10->pm_data.pm4x10_db) 36 37 38 #define PHY_REG_ADDR_DEVAD(_phy_reg) (((_phy_reg) >> 27) & 0x1f) 39 #define QSGMII_REG_ADDR_LANE(_phy_reg) (((_phy_reg) >> 16) & 0x7ff) 40 #define QSGMII_REG_ADDR_LANE_SET(_phy_reg_new, _phy_reg) ((_phy_reg_new) |= ((_phy_reg) & 0x7ff0000)) 41 #define QSGMII_REG_ADDR_REG(_phy_reg) ((((_phy_reg) & 0x8000) >> 11) | ((_phy_reg) & 0xf)) 42 #define IS_QSGMII_REGISTER(_phy_reg) (((_phy_reg) & 0xf800f000) == 0x8000) 43 44 #define PM4X10Q_LANES_PER_CORE (4) 45 #define PM4X10Q_MAX_PORTS_PER_PM4X10Q (16) 46 #define PM4X10Q_MAX_PORTS_PER_LANE (4) 47 48 #define PM4X10Q_EGR_1588_TIMESTAMP_MODE_48BIT (0) 49 #define PM4X10Q_EGR_1588_TIMESTAMP_MODE_32BIT (1) 50 51 extern phymod_bus_t pm4x10_default_bus; 52 53 extern int pm4x10_default_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data); 54 55 typedef enum pm4x10q_wb_vars{ 56 isInitialized, 57 isActive, 58 ports, 59 phyAccPorts, 60 numPortsPerLane 61 }pm4x10q_wb_vars_t; 62 63 struct pm4x10q_s{ 64 portmod_pbmp_t phys; 65 int is_initialized; 66 uint32 blk_id; 67 void* qsgmii_user_acc; 68 void* pm4x10_user_acc; 69 int auto_cfg[PM4X10Q_MAX_PORTS_PER_PM4X10Q]; 70 int is_bypass; 71 phymod_ref_clk_t ref_clk; 72 pm_info_t pm4x10; 73 uint32 core_clock_khz; 74 }; 75 76 STATIC int 77 _pm4x10q_fw_loader(const phymod_core_access_t* core, uint32_t length, const uint8_t* data) 78 { 79 phymod_core_access_t temp_core; 80 portmod_pm4x10q_user_data_t *user_data; 81 82 user_data = (portmod_pm4x10q_user_data_t*)core->access.user_acc; 83 84 temp_core.access = user_data->pm4x10_access; 85 86 SOC_IF_ERROR_RETURN(pm4x10_default_fw_loader(&temp_core, length, data)); 87 88 return SOC_E_NONE; 89 } 90 91 STATIC int 92 _pm4x10q_indacc_wait(int unit, int blk_id, soc_field_t fwait) 93 { 94 uint32 ctlsts; 95 int poll = 1000; 96 97 do { 98 SOC_IF_ERROR_RETURN(READ_CHIP_INDACC_CTLSTSr(unit, blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, &ctlsts)); 99 if (soc_reg_field_get(unit, CHIP_INDACC_CTLSTSr, ctlsts, fwait)) { 100 break; 101 } 102 } while (--poll > 0); 103 104 if (poll <= 0) { 105 return SOC_E_TIMEOUT; 106 } 107 return SOC_E_NONE; 108 } 109 110 111 STATIC int 112 _pm4x10q_indacc_gport_get(uint32 phy_reg, int *target_select) 113 { 114 if (QSGMII_REG_ADDR_LANE(phy_reg) <= 15) { 115 *target_select = (QSGMII_REG_ADDR_LANE(phy_reg) < 8) ? 0 : 1; 116 return SOC_E_NONE; 117 } 118 119 return SOC_E_INTERNAL; 120 } 121 122 123 STATIC 124 int 125 _pm4x10q_indacc_write(portmod_default_user_access_t *user_data, uint32_t reg_addr, uint32_t val) 126 { 127 int unit = user_data->unit; 128 int gport = 0; 129 uint32 ctlsts; 130 131 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_gport_get(reg_addr, &gport)); 132 SOC_IF_ERROR_RETURN(WRITE_CHIP_INDACC_WDATAr(unit, user_data->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, val)); 133 ctlsts = 0; 134 soc_reg_field_set(unit, CHIP_INDACC_CTLSTSr, &ctlsts, TARGET_SELECTf, gport); 135 soc_reg_field_set(unit, CHIP_INDACC_CTLSTSr, &ctlsts, WR_REQf, 1); 136 /*CL22 style*/ 137 reg_addr = reg_addr & 0x1f; 138 soc_reg_field_set(unit, CHIP_INDACC_CTLSTSr, &ctlsts, ADDRESSf, reg_addr); 139 SOC_IF_ERROR_RETURN(WRITE_CHIP_INDACC_CTLSTSr(unit, user_data->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, ctlsts)); 140 141 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_wait(unit, user_data->blk_id , WR_RDYf)); 142 SOC_IF_ERROR_RETURN(WRITE_CHIP_INDACC_CTLSTSr(unit,user_data->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, 0)); 143 144 return SOC_E_NONE; 145 } 146 147 148 STATIC 149 int 150 _pm4x10q_indacc_read(portmod_default_user_access_t *user_data, uint32_t reg_addr, uint32_t *val) 151 { 152 int unit = user_data->unit; 153 int gport = 0; 154 uint32 ctlsts; 155 156 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_gport_get(reg_addr, &gport)); 157 ctlsts = 0; 158 soc_reg_field_set(unit, CHIP_INDACC_CTLSTSr, &ctlsts, TARGET_SELECTf, gport); 159 soc_reg_field_set(unit, CHIP_INDACC_CTLSTSr, &ctlsts, RD_REQf, 1); 160 /*CL22 style*/ 161 reg_addr = reg_addr & 0x1f; 162 soc_reg_field_set(unit, CHIP_INDACC_CTLSTSr, &ctlsts, ADDRESSf, reg_addr); 163 SOC_IF_ERROR_RETURN(WRITE_CHIP_INDACC_CTLSTSr(unit, user_data->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, ctlsts)); 164 165 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_wait(unit, user_data->blk_id , RD_RDYf)); 166 SOC_IF_ERROR_RETURN(READ_CHIP_INDACC_RDATAr(unit, user_data->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, val)); 167 SOC_IF_ERROR_RETURN(WRITE_CHIP_INDACC_CTLSTSr(unit,user_data->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK, 0)); 168 169 return SOC_E_NONE; 170 } 171 172 173 STATIC int 174 _pm4x10q_sbus_qsgmii_write(portmod_default_user_access_t *user_data, uint32_t phy_reg, uint32_t val) 175 { 176 uint32 reg_addr, reg_data; 177 178 /* The "phy_reg" in Sbus MDIO access is expected in 32 bits PHY address 179 * format with AER information included. Since this interface allows 180 * MDIO access in Claue22 only, the AER process must be applied. 181 */ 182 183 /* AER process : AER block selection */ 184 reg_addr = 0x1f; 185 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 186 reg_data = 0xffd0; 187 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, reg_data)); 188 189 /* AER process : lane control */ 190 reg_addr = 0x1e; 191 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 192 /* lane control to indicated lane 0~7 for each QSGMIMI core */ 193 reg_data = QSGMII_REG_ADDR_LANE(phy_reg) & 0x7; 194 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, reg_data)); 195 196 /* target register block selection */ 197 reg_addr = 0x1f; 198 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 199 reg_data = phy_reg & 0xfff0; 200 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, reg_data)); 201 202 /* read data */ 203 reg_addr = QSGMII_REG_ADDR_REG(phy_reg); 204 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 205 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, val)); 206 return SOC_E_NONE; 207 } 208 209 210 STATIC int 211 _pm4x10q_sbus_qsgmii_read(portmod_default_user_access_t *user_data, uint32_t phy_reg, uint32_t *val) 212 { 213 uint32 reg_addr, reg_data; 214 215 /* The "phy_reg" in Sbus MDIO access is expected in 32 bits PHY address 216 * format with AER information included. Since this interface allows 217 * MDIO access in Claue22 only, the AER process must be applied. 218 */ 219 220 /* AER process : AER block selection */ 221 reg_addr = 0x1f; 222 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 223 reg_data = 0xffd0; 224 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, reg_data)); 225 226 /* AER process : lane control */ 227 reg_addr = 0x1e; 228 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 229 /* lane control to indicated lane 0~7 for each QSGMIMI core */ 230 reg_data = QSGMII_REG_ADDR_LANE(phy_reg) & 0x7; 231 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, reg_data)); 232 233 /* target register block selection */ 234 reg_addr = 0x1f; 235 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 236 reg_data = phy_reg & 0xfff0; 237 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_write(user_data, reg_addr, reg_data)); 238 239 /* read data */ 240 reg_addr = QSGMII_REG_ADDR_REG(phy_reg); 241 QSGMII_REG_ADDR_LANE_SET(reg_addr, phy_reg); 242 SOC_IF_ERROR_RETURN(_pm4x10q_indacc_read(user_data, reg_addr, val)); 243 return SOC_E_NONE; 244 } 245 246 STATIC int 247 _pm4x10q_is_pcs_reg(uint32_t reg_addr, int *is_pcs) 248 { 249 *is_pcs = (PHY_REG_ADDR_DEVAD(reg_addr) == 0) && ((IS_QSGMII_REGISTER(reg_addr)) || (QSGMII_REG_ADDR_REG(reg_addr) < 0x10)); 250 return SOC_E_NONE; 251 } 252 253 STATIC int 254 _pm4x10q_sbus_pm4x10_sbus_set(void *user_acc, phymod_bus_t* pm4x10_bus) 255 { 256 portmod_pm4x10q_user_data_t *user_data = user_acc; 257 258 user_data->pm4x10_access.bus = pm4x10_bus; 259 return SOC_E_NONE; 260 } 261 262 STATIC int 263 _pm4x10q_sbus_reg_write(void *user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t val) 264 { 265 portmod_pm4x10q_user_data_t *user_data = user_acc; 266 int is_pcs = 0; 267 268 if (user_data->pm4x10_access.bus == NULL) { 269 SOC_IF_ERROR_RETURN(_pm4x10q_sbus_pm4x10_sbus_set(user_acc, &pm4x10_default_bus)); 270 } 271 272 SOC_IF_ERROR_RETURN(_pm4x10q_is_pcs_reg(reg_addr, &is_pcs)); 273 if(is_pcs){ 274 SOC_IF_ERROR_RETURN(portmod_common_mutex_take((void*)&user_data->qsgmiie_user_data)); 275 SOC_IF_ERROR_RETURN(_pm4x10q_sbus_qsgmii_write(&user_data->qsgmiie_user_data, reg_addr, val)); 276 SOC_IF_ERROR_RETURN(portmod_common_mutex_give((void*)&user_data->qsgmiie_user_data)); 277 return SOC_E_NONE; 278 } 279 /* coverity[var_deref_op:FALSE] */ 280 return user_data->pm4x10_access.bus->write(user_data->pm4x10_access.user_acc, user_data->pm4x10_access.addr, reg_addr, val); 281 } 282 283 284 STATIC int 285 _pm4x10q_sbus_reg_read(void *user_acc, uint32_t core_addr, uint32_t reg_addr, uint32_t *val) 286 { 287 portmod_pm4x10q_user_data_t *user_data = user_acc; 288 int is_pcs = 0; 289 290 if (user_data->pm4x10_access.bus == NULL) { 291 SOC_IF_ERROR_RETURN(_pm4x10q_sbus_pm4x10_sbus_set(user_acc, &pm4x10_default_bus)); 292 } 293 294 SOC_IF_ERROR_RETURN(_pm4x10q_is_pcs_reg(reg_addr, &is_pcs)); 295 if(is_pcs){ 296 SOC_IF_ERROR_RETURN(portmod_common_mutex_take((void*)&user_data->qsgmiie_user_data)); 297 SOC_IF_ERROR_RETURN(_pm4x10q_sbus_qsgmii_read(&user_data->qsgmiie_user_data, reg_addr, val)); 298 SOC_IF_ERROR_RETURN(portmod_common_mutex_give((void*)&user_data->qsgmiie_user_data)); 299 return SOC_E_NONE; 300 } 301 /* coverity[var_deref_op:FALSE] */ 302 return user_data->pm4x10_access.bus->read(user_data->pm4x10_access.user_acc, user_data->pm4x10_access.addr, reg_addr, val); 303 } 304 305 STATIC int 306 _pm4x10q_sbus_mutex_take(void *user_acc) 307 { 308 portmod_pm4x10q_user_data_t *user_data; 309 310 user_data = (portmod_pm4x10q_user_data_t*)user_acc; 311 312 return portmod_common_mutex_take(&(user_data->qsgmiie_user_data)); 313 } 314 315 STATIC int 316 _pm4x10q_sbus_mutex_give(void *user_acc) 317 { 318 portmod_pm4x10q_user_data_t *user_data; 319 320 user_data = (portmod_pm4x10q_user_data_t*)user_acc; 321 322 return portmod_common_mutex_give(&(user_data->qsgmiie_user_data)); 323 } 324 325 326 phymod_bus_t pm4x10q_default_bus = { 327 "PM4X10Q PCS Bus", 328 _pm4x10q_sbus_reg_read, 329 _pm4x10q_sbus_reg_write, 330 NULL, 331 _pm4x10q_sbus_mutex_take, 332 _pm4x10q_sbus_mutex_give, 333 NULL, 334 NULL, 335 PHYMOD_BUS_CAP_WR_MODIFY| PHYMOD_BUS_CAP_LANE_CTRL 336 }; 337 338 STATIC 339 int pm4x10q_wb_buffer_init(int unit, int wb_buffer_index, pm_info_t pm_info) 340 { 341 /* Declare the common variables needed for warmboot */ 342 WB_ENGINE_INIT_TABLES_DEFS; 343 int wb_var_id, rv, i, j, invalid_port = -1; 344 int buffer_id = wb_buffer_index; /*required by SOC_WB_ENGINE_ADD_ Macros*/ 345 SOC_INIT_FUNC_DEFS; 346 347 COMPILER_REFERENCE(buffer_is_dynamic); 348 349 SOC_WB_ENGINE_ADD_BUFF(SOC_WB_ENGINE_PORTMOD, wb_buffer_index, "pm4x10Q", NULL, NULL, VERSION(1), 1, SOC_WB_ENGINE_PRE_RELEASE); 350 _SOC_IF_ERR_EXIT(rv); 351 352 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 353 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_initialized", wb_buffer_index, sizeof(uint32), NULL, VERSION(1)); 354 _SOC_IF_ERR_EXIT(rv); 355 pm_info->wb_vars_ids[isInitialized] = wb_var_id; 356 357 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 358 SOC_WB_ENGINE_ADD_2D_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "ports", wb_buffer_index, sizeof(int), NULL, PM4X10Q_MAX_PORTS_PER_LANE, PM4X10Q_LANES_PER_CORE, VERSION(1)); 359 _SOC_IF_ERR_EXIT(rv); 360 pm_info->wb_vars_ids[ports] = wb_var_id; 361 362 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 363 SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "phy_acc_ports", wb_buffer_index, sizeof(int), NULL, PM4X10Q_LANES_PER_CORE, VERSION(1)); 364 _SOC_IF_ERR_EXIT(rv); 365 pm_info->wb_vars_ids[phyAccPorts] = wb_var_id; 366 367 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 368 SOC_WB_ENGINE_ADD_ARR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "num_ports_per_lane", wb_buffer_index, sizeof(int), NULL, PM4X10Q_LANES_PER_CORE, VERSION(1)); 369 _SOC_IF_ERR_EXIT(rv); 370 pm_info->wb_vars_ids[numPortsPerLane] = wb_var_id; 371 372 _SOC_IF_ERR_EXIT(portmod_next_wb_var_id_get(unit, &wb_var_id)); 373 SOC_WB_ENGINE_ADD_VAR(SOC_WB_ENGINE_PORTMOD, wb_var_id, "is_active", wb_buffer_index, sizeof(uint32), NULL, VERSION(1)); 374 _SOC_IF_ERR_EXIT(rv); 375 pm_info->wb_vars_ids[isActive] = wb_var_id; 376 377 _SOC_IF_ERR_EXIT(soc_wb_engine_init_buffer(unit, SOC_WB_ENGINE_PORTMOD, wb_buffer_index, FALSE)); 378 if(!SOC_WARM_BOOT(unit)){ 379 for (i = 0; i < PM4X10Q_MAX_PORTS_PER_LANE; ++i) { 380 for (j = 0; j < PM4X10Q_LANES_PER_CORE; ++j) { 381 rv = SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[ports], &invalid_port, i, j); 382 _SOC_IF_ERR_EXIT(rv); 383 } 384 } 385 386 rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], -1); 387 _SOC_IF_ERR_EXIT(rv); 388 389 rv = SOC_WB_ENGINE_MEMSET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], 0); 390 _SOC_IF_ERR_EXIT(rv); 391 } 392 exit: 393 SOC_FUNC_RETURN; 394 } 395 396 397 STATIC 398 int _pm4x10q_sub_phy_get(int unit, soc_port_t port, pm_info_t pm_info, int *phy_index, int* sub_phy_index) 399 { 400 uint32 phy_num_ports; 401 int i, j, found = 0, rv, temp_port; 402 SOC_INIT_FUNC_DEFS; 403 404 *phy_index = -1; 405 *sub_phy_index = -1; 406 407 for (i = 0; i < PM4X10Q_LANES_PER_CORE && !found; ++i) { 408 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, i); 409 _SOC_IF_ERR_EXIT(rv); 410 for (j = 0; j < phy_num_ports; ++j) { 411 rv = SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[ports], &temp_port, i, j); 412 _SOC_IF_ERR_EXIT(rv); 413 if (temp_port == port) { 414 *phy_index = i; 415 *sub_phy_index = j; 416 found = 1; 417 break; 418 } 419 } 420 } 421 422 exit: 423 SOC_FUNC_RETURN; 424 } 425 426 int pm4x10Q_pm_interface_type_is_supported(int unit, soc_port_if_t interface, int* is_supported) 427 { 428 SOC_INIT_FUNC_DEFS; 429 430 switch(interface){ 431 case SOC_PORT_IF_QSGMII: 432 *is_supported = TRUE; 433 break; 434 default: 435 *is_supported = FALSE; 436 } 437 438 SOC_FUNC_RETURN; 439 } 440 441 442 int pm4x10Q_pm_init(int unit, const portmod_pm_create_info_internal_t* pm_add_info, int wb_buffer_index, pm_info_t pm_info) 443 { 444 const portmod_pm4x10q_create_info_internal_t *info = &pm_add_info->pm_specific_info.pm4x10q; 445 pm4x10q_t pm4x10q_data = NULL; 446 int rv; 447 uint32 pm_is_active, pm_is_initialized; 448 SOC_INIT_FUNC_DEFS; 449 450 pm_info->unit = unit; 451 pm_info->type = portmodDispatchTypePm4x10Q; 452 pm_info->wb_buffer_id = wb_buffer_index; 453 454 pm4x10q_data = sal_alloc(sizeof(struct pm4x10q_s), "pm4x10q_specific_db"); 455 SOC_NULL_CHECK(pm4x10q_data); 456 pm_info->pm_data.pm4x10q_db = pm4x10q_data; 457 458 /*init wb buffer*/ 459 _SOC_IF_ERR_EXIT(pm4x10q_wb_buffer_init(unit, wb_buffer_index, pm_info)); 460 461 PORTMOD_PBMP_ASSIGN(pm4x10q_data->phys, pm_add_info->phys); 462 pm4x10q_data->pm4x10 = info->pm4x10; 463 pm4x10q_data->is_initialized = 0; 464 465 pm4x10q_data->is_bypass = 0; 466 pm4x10q_data->blk_id = pm_add_info->pm_specific_info.pm4x10q.blk_id; 467 pm4x10q_data->qsgmii_user_acc = info->qsgmii_user_acc; 468 pm4x10q_data->pm4x10_user_acc = info->pm4x10_user_acc; 469 pm4x10q_data->ref_clk = pm_add_info->pm_specific_info.pm4x10.ref_clk; 470 pm4x10q_data->core_clock_khz = pm_add_info->pm_specific_info.pm4x10q.core_clock_khz; 471 472 if(!SOC_WARM_BOOT(unit)){ 473 pm_is_active = 0; 474 rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active); 475 _SOC_IF_ERR_EXIT(rv); 476 477 pm_is_initialized = 0; 478 rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isInitialized], &pm_is_initialized); 479 _SOC_IF_ERR_EXIT(rv); 480 } 481 482 exit: 483 if(SOC_FUNC_ERROR){ 484 pm4x10Q_pm_destroy(unit, pm_info); 485 } 486 SOC_FUNC_RETURN; 487 } 488 489 490 int pm4x10Q_pm_destroy(int unit, pm_info_t pm_info) 491 { 492 493 SOC_INIT_FUNC_DEFS; 494 495 if(pm_info->pm_data.pm4x10q_db != NULL) { 496 SOC_IF_ERROR_RETURN(pm4x10Q_pm_destroy(unit, pm_info->pm_data.pm4x10q_db->pm4x10)); 497 sal_free(pm_info->pm_data.pm4x10q_db); 498 pm_info->pm_data.pm4x10q_db = NULL; 499 } 500 501 SOC_FUNC_RETURN; 502 503 } 504 505 int pm4x10Q_pm_core_info_get(int unit, pm_info_t pm_info, int phyn, portmod_pm_core_info_t* core_info) 506 { 507 SOC_INIT_FUNC_DEFS; 508 509 /* Place your code here */ 510 511 SOC_FUNC_RETURN; 512 } 513 514 515 int pm4x10Q_port_attach(int unit, int port, pm_info_t pm_info, const portmod_port_add_info_t* add_info) 516 { 517 int phy, index, phy_num_ports, reg_port, rv, pm_is_active; 518 uint32 reg_val, ilkn_rst = 0, phy_acc_port; 519 portmod_bus_update_t pm_update; 520 int flags; 521 SOC_INIT_FUNC_DEFS; 522 523 PORTMOD_PBMP_ITER(add_info->phys, phy){ 524 break; 525 } 526 index = (phy - 1) % 4; 527 528 reg_port = PM_4x10Q_INFO(pm_info)->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK; 529 530 if (!PORTMOD_PORT_ADD_F_INIT_PASS1_GET(add_info)) { 531 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, index); 532 _SOC_IF_ERR_EXIT(rv); 533 if (phy_acc_port == -1) { 534 rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &port, index); 535 _SOC_IF_ERR_EXIT(rv); 536 phy_acc_port = port; 537 } 538 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, index); 539 _SOC_IF_ERR_EXIT(rv); 540 if (phy_num_ports < 0) { 541 phy_num_ports = 0; 542 } 543 rv = SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[ports], &port, index, phy_num_ports); 544 _SOC_IF_ERR_EXIT(rv); 545 phy_num_ports += 1; 546 rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, index); 547 _SOC_IF_ERR_EXIT(rv); 548 549 pm_update.default_bus = &pm4x10q_default_bus; 550 pm_update.user_acc = PM_4x10Q_INFO(pm_info)->qsgmii_user_acc; 551 pm_update.blk_id = -1; /*dont change the default blk_id*/ 552 pm_update.external_fw_loader = _pm4x10q_fw_loader; 553 554 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_4x10Q_INFO(pm_info)->pm4x10, &pm_update)); 555 556 rv = SOC_WB_ENGINE_GET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active); 557 _SOC_IF_ERR_EXIT(rv); 558 if (pm_is_active == 0) { 559 /* special init process for PMQ(PM4x10Q in QSGMII mode) - to release PMQ's QSGMII reset state after QSGMII-PCS and UniMAC init. */ 560 SOC_IF_ERROR_RETURN(READ_CHIP_CONFIGr(unit, reg_port, ®_val)); 561 soc_reg_field_set(unit, CHIP_CONFIGr, ®_val, QMODEf, 1); 562 if ((PM_4x10Q_INFO(pm_info)->core_clock_khz > 325000) || (PM_4x10Q_INFO(pm_info)->core_clock_khz == 0)) { 563 soc_reg_field_set(unit, CHIP_CONFIGr, ®_val, IP_TDMf, 0x3); 564 } else { 565 /* According to PORTMACRO-210, when clk=300M or less, ip_tdm should be 2 or less */ 566 soc_reg_field_set(unit, CHIP_CONFIGr, ®_val, IP_TDMf, 0x1); 567 } 568 SOC_IF_ERROR_RETURN(WRITE_CHIP_CONFIGr(unit, reg_port, reg_val)); 569 /* reset ILKN FIFO */ 570 _SOC_IF_ERR_EXIT(READ_CHIP_SWRSTr(unit, reg_port, ®_val)); 571 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, FLUSHf, 0x1); 572 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, ILKN_BYPASS_RSTNf, 0); 573 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_QSGMII_PCSf, 0x1); 574 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_GPORT1f, 0x1); 575 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_GPORT0f, 0x1); 576 _SOC_IF_ERR_EXIT(WRITE_CHIP_SWRSTr(unit, reg_port, reg_val)); 577 578 _SOC_IF_ERR_EXIT(READ_CHIP_SWRSTr(unit, reg_port, ®_val)); 579 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, FLUSHf, 0x0); 580 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_QSGMII_PCSf, 0); 581 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_GPORT1f, 0); 582 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_GPORT0f, 0); 583 _SOC_IF_ERR_EXIT(WRITE_CHIP_SWRSTr(unit, reg_port, reg_val)); 584 585 pm_is_active = 1; 586 rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active); 587 _SOC_IF_ERR_EXIT(rv); 588 } 589 590 if (add_info->flags & PORTMOD_PORT_ADD_F_EGR_1588_TIMESTAMP_MODE_48BIT) { 591 SOC_IF_ERROR_RETURN(READ_GPORT_MODE_REGr(unit, port, ®_val)); 592 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EGR_1588_TIMESTAMPING_MODEf, PM4X10Q_EGR_1588_TIMESTAMP_MODE_48BIT); 593 SOC_IF_ERROR_RETURN(WRITE_GPORT_MODE_REGr(unit, port, reg_val)); 594 } 595 596 /* Initialize mask for purging packet data received from the MAC */ 597 _SOC_IF_ERR_EXIT(WRITE_GPORT_RSV_MASKr(unit, port, 0x78)); 598 _SOC_IF_ERR_EXIT(WRITE_GPORT_STAT_UPDATE_MASKr(unit, port, 0x78)); 599 600 _SOC_IF_ERR_EXIT(READ_GPORT_CONFIGr(unit, port, ®_val)); 601 soc_reg_field_set(unit, GPORT_CONFIGr, ®_val, CLR_CNTf, 1); 602 _SOC_IF_ERR_EXIT(WRITE_GPORT_CONFIGr(unit, port, reg_val)); 603 604 /* Reset the clear-count bit after 64 clocks */ 605 soc_reg_field_set(unit, GPORT_CONFIGr, ®_val, CLR_CNTf, 0); 606 _SOC_IF_ERR_EXIT(WRITE_GPORT_CONFIGr(unit, port, reg_val)); 607 608 _SOC_IF_ERR_EXIT(READ_GPORT_CONFIGr(unit, port, ®_val)); 609 soc_reg_field_set(unit, GPORT_CONFIGr, ®_val, GPORT_ENf, 1); 610 _SOC_IF_ERR_EXIT(WRITE_GPORT_CONFIGr(unit, port, reg_val)); 611 612 _SOC_IF_ERR_EXIT(READ_GPORT_MODE_REGr(unit, port, ®_val)); 613 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EP_TO_GP_CRC_MODES_SELf, 0x1); 614 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EP_TO_GP_CRC_FWDf, 0); 615 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EP_TO_GP_CRC_OWRTf, 0); 616 _SOC_IF_ERR_EXIT(WRITE_GPORT_MODE_REGr(unit, port, reg_val)); 617 618 /* init MAC */ 619 flags = 0; 620 if(PORTMOD_PORT_ADD_F_RX_SRIP_CRC_GET(add_info)) { 621 flags |= UNIMAC_INIT_F_RX_STRIP_CRC; 622 } 623 _SOC_IF_ERR_EXIT(unimac_init(unit, port, flags)); 624 625 if (phy_acc_port == port) { /* only done once per phy lane */ 626 if (PM_4x10Q_INFO(pm_info)->is_bypass == 0) { 627 _SOC_IF_ERR_EXIT(pm4x10_pm_bypass_set(unit, PM_4x10Q_INFO(pm_info)->pm4x10, 1)); 628 PM_4x10Q_INFO(pm_info)->is_bypass = 1; 629 } 630 _SOC_IF_ERR_EXIT(pm4x10_port_attach(unit, port, PM_4x10Q_INFO(pm_info)->pm4x10, add_info)); 631 } 632 }else { 633 SOC_IF_ERROR_RETURN(READ_CHIP_SWRSTr(unit, reg_port, ®_val)); 634 ilkn_rst = soc_reg_field_get(unit, CHIP_SWRSTr, reg_val, ILKN_BYPASS_RSTNf); 635 /* coverity[negative_shift:FALSE] */ 636 ilkn_rst |= 0x1 << index; 637 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, ILKN_BYPASS_RSTNf, ilkn_rst); 638 _SOC_IF_ERR_EXIT(WRITE_CHIP_SWRSTr(unit, reg_port, reg_val)); 639 } 640 exit: 641 SOC_FUNC_RETURN; 642 } 643 644 645 int pm4x10Q_port_detach(int unit, int port, pm_info_t pm_info) 646 { 647 int enable, phy_index, sub_phy, total_ports_left, i, reg_port, invalid_port = -1, temp_port, rv, pm_is_active; 648 uint32 reg_val, phy_num_ports, phy_acc_port, ilkn_rst = 0; 649 portmod_bus_update_t pm_update; 650 SOC_INIT_FUNC_DEFS; 651 652 _SOC_IF_ERR_EXIT(pm4x10Q_port_enable_get(unit, port, pm_info, 0, &enable)); 653 if (enable) { 654 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("can't detach active port %d"), port)); 655 } 656 657 _SOC_IF_ERR_EXIT(_pm4x10q_sub_phy_get(unit, port, pm_info, &phy_index, &sub_phy)); 658 659 if (phy_index == -1) { 660 _SOC_EXIT_WITH_ERR(SOC_E_INTERNAL, (_SOC_MSG("port %d was not found in internal DB"), port)); 661 } 662 663 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, phy_index); 664 _SOC_IF_ERR_EXIT(rv); 665 666 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, phy_index); 667 _SOC_IF_ERR_EXIT(rv); 668 phy_num_ports -= 1; 669 670 reg_port = PM_4x10Q_INFO(pm_info)->blk_id | SOC_REG_ADDR_BLOCK_ID_MASK; 671 672 if (phy_num_ports == 0) { 673 674 _SOC_IF_ERR_EXIT(READ_CHIP_SWRSTr(unit, reg_port, ®_val)); 675 ilkn_rst = soc_reg_field_get(unit, CHIP_SWRSTr, reg_val, ILKN_BYPASS_RSTNf); 676 /* coverity[negative_shift:FALSE] */ 677 ilkn_rst &= (~(0x1 << phy_index)); 678 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, ILKN_BYPASS_RSTNf, ilkn_rst); 679 _SOC_IF_ERR_EXIT(WRITE_CHIP_SWRSTr(unit, reg_port, reg_val)); 680 681 _SOC_IF_ERR_EXIT(pm4x10_port_detach(unit, phy_acc_port, PM_4x10Q_INFO(pm_info)->pm4x10)); 682 683 PM_4x10Q_INFO(pm_info)->is_bypass = 0; 684 685 rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &invalid_port, phy_index); 686 _SOC_IF_ERR_EXIT(rv); 687 } 688 689 /* deinit MAC */ 690 _SOC_IF_ERR_EXIT(unimac_deinit(unit, port)); 691 692 _SOC_IF_ERR_EXIT(READ_GPORT_MODE_REGr(unit, port, ®_val)); 693 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EP_TO_GP_CRC_MODES_SELf, 0); 694 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EP_TO_GP_CRC_FWDf, 0); 695 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EP_TO_GP_CRC_OWRTf, 0); 696 _SOC_IF_ERR_EXIT(WRITE_GPORT_MODE_REGr(unit, port, reg_val)); 697 698 _SOC_IF_ERR_EXIT(READ_GPORT_CONFIGr(unit, port, ®_val)); 699 soc_reg_field_set(unit, GPORT_CONFIGr, ®_val, GPORT_ENf, 0); 700 _SOC_IF_ERR_EXIT(WRITE_GPORT_CONFIGr(unit, port, reg_val)); 701 702 /* Initialize mask for purging packet data received from the MAC */ 703 _SOC_IF_ERR_EXIT(WRITE_GPORT_RSV_MASKr(unit, port, 0x70)); 704 _SOC_IF_ERR_EXIT(WRITE_GPORT_STAT_UPDATE_MASKr(unit, port, 0x70)); 705 706 /* Disable - clean db */ 707 total_ports_left = 0; 708 for (i = 0; i < PM4X10Q_LANES_PER_CORE; ++i) { 709 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, i); 710 _SOC_IF_ERR_EXIT(rv); 711 total_ports_left += phy_num_ports; 712 } 713 if (total_ports_left == 1) { /*last one*/ 714 715 pm_is_active = 0; 716 rv = SOC_WB_ENGINE_SET_VAR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[isActive], &pm_is_active); 717 _SOC_IF_ERR_EXIT(rv); 718 719 /* reset ILKN FIFO */ 720 721 _SOC_IF_ERR_EXIT(READ_CHIP_SWRSTr(unit, reg_port, ®_val)); 722 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, ILKN_BYPASS_RSTNf, 0); 723 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, FLUSHf, 0x1); 724 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_QSGMII_PCSf, 0x0); 725 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_GPORT1f, 0x0); 726 soc_reg_field_set(unit, CHIP_SWRSTr, ®_val, SOFT_RESET_GPORT0f, 0x0); 727 _SOC_IF_ERR_EXIT(WRITE_CHIP_SWRSTr(unit, reg_port, reg_val)); 728 729 _SOC_IF_ERR_EXIT(READ_CHIP_CONFIGr(unit, reg_port, ®_val)); 730 soc_reg_field_set(unit, CHIP_CONFIGr, ®_val, QMODEf, 0); 731 soc_reg_field_set(unit, CHIP_CONFIGr, ®_val, IP_TDMf, 0); 732 _SOC_IF_ERR_EXIT(WRITE_CHIP_CONFIGr(unit, reg_port, reg_val)); 733 734 PM_4x10Q_INFO(pm_info)->is_initialized = 0; 735 736 /*restore bus and fw_loader*/ 737 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_4x10Q_INFO(pm_info)->pm4x10, NULL)); 738 739 /*restore user access*/ 740 pm_update.default_bus = NULL; 741 pm_update.user_acc = PM_4x10Q_INFO(pm_info)->pm4x10_user_acc; 742 pm_update.blk_id = -1; /*dont change the default blk_id*/ 743 pm_update.external_fw_loader = NULL; 744 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_4x10Q_INFO(pm_info)->pm4x10, &pm_update)); 745 746 _SOC_IF_ERR_EXIT(pm4x10_pm_bypass_set(unit, PM_4x10Q_INFO(pm_info)->pm4x10, 0)); 747 } 748 749 _SOC_IF_ERR_EXIT(READ_GPORT_MODE_REGr(unit, port, ®_val)); 750 soc_reg_field_set(unit, GPORT_MODE_REGr, ®_val, EGR_1588_TIMESTAMPING_MODEf, 0x1); 751 _SOC_IF_ERR_EXIT(WRITE_GPORT_MODE_REGr(unit, port, reg_val)); 752 753 754 755 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, phy_index); 756 _SOC_IF_ERR_EXIT(rv); 757 phy_num_ports -= 1; 758 759 rv = SOC_WB_ENGINE_SET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[numPortsPerLane], &phy_num_ports, phy_index); 760 _SOC_IF_ERR_EXIT(rv); 761 rv = SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[ports], &invalid_port, phy_index, sub_phy); 762 _SOC_IF_ERR_EXIT(rv); 763 while (sub_phy < phy_num_ports) { 764 rv = SOC_WB_ENGINE_GET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[ports], &temp_port, phy_index, sub_phy + 1); 765 _SOC_IF_ERR_EXIT(rv); 766 rv = SOC_WB_ENGINE_SET_DBL_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[ports], &temp_port, phy_index, sub_phy); 767 _SOC_IF_ERR_EXIT(rv); 768 ++sub_phy; 769 } 770 771 exit: 772 SOC_FUNC_RETURN; 773 } 774 775 int pm4x10Q_port_replace(int unit, int port, pm_info_t pm_info, int new_port) 776 { 777 778 SOC_INIT_FUNC_DEFS; 779 780 /* Place your code here */ 781 782 783 SOC_FUNC_RETURN; 784 785 } 786 787 int pm4x10Q_port_enable_set(int unit, int port, pm_info_t pm_info, int flags, int enable) 788 { 789 int actual_flags = flags, nof_phys = 0; 790 phymod_phy_power_t phy_power; 791 phymod_phy_access_t phy_access[1+MAX_PHYN]; 792 uint32 phychain_flag; 793 phymod_phy_tx_lane_control_t tx_control = phymodTxSquelchOn; 794 phymod_phy_rx_lane_control_t rx_control = phymodRxSquelchOn; 795 SOC_INIT_FUNC_DEFS; 796 797 /* If no Rx/Tx flags - set both */ 798 if ((!PORTMOD_PORT_ENABLE_TX_GET(flags)) && (!PORTMOD_PORT_ENABLE_RX_GET(flags))) { 799 PORTMOD_PORT_ENABLE_RX_SET(actual_flags); 800 PORTMOD_PORT_ENABLE_TX_SET(actual_flags); 801 } 802 803 /* If no Mac/Phy flags - set both */ 804 if ((!PORTMOD_PORT_ENABLE_PHY_GET(flags)) && (!PORTMOD_PORT_ENABLE_MAC_GET(flags))) { 805 PORTMOD_PORT_ENABLE_PHY_SET(actual_flags); 806 PORTMOD_PORT_ENABLE_MAC_SET(actual_flags); 807 } 808 809 /* if MAC is set and either RX or TX set is invalid combination */ 810 if( (PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) && (!PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) ) { 811 if((!PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) || (!PORTMOD_PORT_ENABLE_RX_GET(actual_flags))){ 812 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("MAC RX and TX can't be enabled separately"))); 813 } 814 } 815 816 /* phychain_flag is meant to be used if we want only part of the phychin to be affected*/ 817 phychain_flag = PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_GET(flags) ? 818 PORTMOD_INIT_F_INTERNAL_SERDES_ONLY : 819 PORTMOD_INIT_F_EXTERNAL_MOST_ONLY ; 820 821 _SOC_IF_ERR_EXIT(phymod_phy_power_t_init(&phy_power)); 822 phy_power.rx = phymodPowerNoChange; 823 phy_power.tx = phymodPowerNoChange; 824 825 if(PORTMOD_PORT_ENABLE_RX_GET(actual_flags)){ 826 phy_power.rx = (enable) ? phymodPowerOn : phymodPowerOff; 827 rx_control = (enable) ? phymodRxSquelchOff : phymodRxSquelchOn; 828 } 829 if(PORTMOD_PORT_ENABLE_TX_GET(actual_flags)){ 830 phy_power.tx = (enable) ? phymodPowerOn : phymodPowerOff; 831 tx_control = (enable) ? phymodTxSquelchOff : phymodTxSquelchOn; 832 } 833 834 if (PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)){ 835 _SOC_IF_ERR_EXIT(unimac_enable_set(unit, port, 0, enable)); 836 837 } 838 if (PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) { 839 _SOC_IF_ERR_EXIT 840 (portmod_port_chain_phy_access_get(unit, port, pm_info, 841 phy_access ,(1+MAX_PHYN), 842 &nof_phys)); 843 844 if (enable) { 845 _SOC_IF_ERR_EXIT 846 (portmod_port_phychain_power_set(unit, port, phy_access, nof_phys, phychain_flag, &phy_power)); 847 _SOC_IF_ERR_EXIT 848 (portmod_port_phychain_tx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag, tx_control)); 849 _SOC_IF_ERR_EXIT 850 (portmod_port_phychain_rx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag, rx_control)); 851 } else { 852 _SOC_IF_ERR_EXIT 853 (portmod_port_phychain_tx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag, tx_control)); 854 _SOC_IF_ERR_EXIT 855 (portmod_port_phychain_rx_lane_control_set(unit, port, phy_access, nof_phys, phychain_flag, rx_control)); 856 _SOC_IF_ERR_EXIT 857 (portmod_port_phychain_power_set(unit, port, phy_access, nof_phys, phychain_flag, &phy_power)); 858 } 859 } 860 861 exit: 862 SOC_FUNC_RETURN; 863 } 864 865 int pm4x10Q_port_enable_get(int unit, int port, pm_info_t pm_info, int flags, int* enable) 866 { 867 phymod_phy_access_t phy_access[1+MAX_PHYN]; 868 int nof_phys = 0; 869 phymod_phy_tx_lane_control_t tx_control = phymodTxSquelchOn; 870 phymod_phy_rx_lane_control_t rx_control = phymodRxSquelchOn; 871 int phy_enable = 1, mac_enable = 1, mac_rx_enable, mac_tx_enable; 872 int actual_flags = flags; 873 uint32 phychain_flag; 874 SOC_INIT_FUNC_DEFS; 875 SOC_NULL_CHECK(pm_info); 876 877 /* If no RX\TX flags - set both*/ 878 if((!PORTMOD_PORT_ENABLE_TX_GET(flags)) && (!PORTMOD_PORT_ENABLE_RX_GET(flags))){ 879 PORTMOD_PORT_ENABLE_RX_SET(actual_flags); 880 PORTMOD_PORT_ENABLE_TX_SET(actual_flags); 881 } 882 883 /* if no MAC\Phy flags - set both*/ 884 if((!PORTMOD_PORT_ENABLE_PHY_GET(flags)) && (!PORTMOD_PORT_ENABLE_MAC_GET(flags))){ 885 PORTMOD_PORT_ENABLE_PHY_SET(actual_flags); 886 PORTMOD_PORT_ENABLE_MAC_SET(actual_flags); 887 } 888 889 /* phychain_flag is meant to be used if we want only part of the phychin to be affected*/ 890 phychain_flag = PORTMOD_PORT_ENABLE_INTERNAL_PHY_ONLY_GET(flags) ? 891 PORTMOD_INIT_F_INTERNAL_SERDES_ONLY : 892 PORTMOD_INIT_F_EXTERNAL_MOST_ONLY ; 893 894 if (PORTMOD_PORT_ENABLE_MAC_GET(actual_flags)) { 895 mac_enable = 0; 896 897 if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) { 898 _SOC_IF_ERR_EXIT(unimac_enable_get(unit, port, UNIMAC_ENABLE_SET_FLAGS_RX_EN, &mac_rx_enable)); 899 mac_enable |= (mac_rx_enable) ? 1 : 0; 900 } 901 if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) { 902 _SOC_IF_ERR_EXIT(unimac_enable_get(unit, port, UNIMAC_ENABLE_SET_FLAGS_TX_EN, &mac_tx_enable)); 903 mac_enable |= (mac_tx_enable) ? 1 : 0; 904 } 905 906 } 907 908 if (PORTMOD_PORT_ENABLE_PHY_GET(actual_flags)) { 909 910 _SOC_IF_ERR_EXIT 911 (portmod_port_chain_phy_access_get(unit, port, pm_info, 912 phy_access ,(1+MAX_PHYN), 913 &nof_phys)); 914 915 _SOC_IF_ERR_EXIT 916 (portmod_port_phychain_tx_lane_control_get(unit, port, phy_access, nof_phys, phychain_flag, &tx_control)); 917 _SOC_IF_ERR_EXIT 918 (portmod_port_phychain_rx_lane_control_get(unit, port, phy_access, nof_phys, phychain_flag, &rx_control)); 919 920 phy_enable = 0; 921 922 if (PORTMOD_PORT_ENABLE_RX_GET(actual_flags)) { 923 phy_enable |= (rx_control == phymodRxSquelchOn) ? 0 : 1; 924 } 925 if (PORTMOD_PORT_ENABLE_TX_GET(actual_flags)) { 926 phy_enable |= (tx_control == phymodTxSquelchOn) ? 0 : 1; 927 } 928 } 929 930 *enable = (mac_enable && phy_enable); 931 932 exit: 933 SOC_FUNC_RETURN; 934 } 935 936 937 int pm4x10Q_port_interface_config_set(int unit, int port, pm_info_t pm_info, const portmod_port_interface_config_t* config, int phy_init_flags) 938 { 939 int nof_phys; 940 portmod_access_get_params_t params; 941 phymod_phy_access_t phy_access; 942 phymod_phy_inf_config_t phy_interface_config; 943 soc_port_if_t interface = SOC_PORT_IF_NULL; 944 SOC_INIT_FUNC_DEFS; 945 946 _SOC_IF_ERR_EXIT(portmod_access_get_params_t_init(unit, ¶ms)); 947 params.phyn = 0; 948 params.lane = -1; 949 params.sys_side = PORTMOD_SIDE_LINE; 950 951 _SOC_IF_ERR_EXIT(pm4x10Q_port_phy_lane_access_get(unit, port, pm_info, ¶ms, 1, &phy_access, &nof_phys, NULL)); 952 953 _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init (&phy_interface_config)); 954 _SOC_IF_ERR_EXIT(portmod_line_intf_from_config_get(config, &interface)); 955 _SOC_IF_ERR_EXIT(portmod_intf_to_phymod_intf(unit, config->speed, 956 interface, &phy_interface_config.interface_type)); 957 958 phy_interface_config.data_rate = config->speed; 959 phy_interface_config.interface_modes = config->interface_modes; 960 phy_interface_config.ref_clock = PM_4x10Q_INFO(pm_info)->ref_clk; 961 _SOC_IF_ERR_EXIT(phymod_phy_interface_config_set(&phy_access, 0, &phy_interface_config)); 962 963 _SOC_IF_ERR_EXIT(unimac_speed_set(unit, port, phy_interface_config.data_rate)); 964 965 exit: 966 SOC_FUNC_RETURN; 967 } 968 969 int pm4x10Q_port_interface_config_get(int unit, int port, pm_info_t pm_info, portmod_port_interface_config_t* config, int phy_init_flags) 970 { 971 int nof_phys; 972 phymod_phy_inf_config_t phy_interface_config; 973 phymod_phy_access_t phy_access[1+MAX_PHYN]; 974 SOC_INIT_FUNC_DEFS; 975 976 _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access ,(1+MAX_PHYN), &nof_phys)); 977 978 _SOC_IF_ERR_EXIT(phymod_phy_inf_config_t_init (&phy_interface_config)); 979 _SOC_IF_ERR_EXIT(phymod_phy_interface_config_get(phy_access, 0, PM_4x10Q_INFO(pm_info)->ref_clk, &phy_interface_config)); 980 981 config->speed = phy_interface_config.data_rate; 982 983 _SOC_IF_ERR_EXIT(portmod_intf_from_phymod_intf(unit, phy_interface_config.interface_type, &config->interface)); 984 985 exit: 986 SOC_FUNC_RETURN; 987 } 988 989 int pm4x10Q_port_default_interface_get(int unit, int port, pm_info_t pm_info, const portmod_port_interface_config_t* config, soc_port_if_t* interface) 990 { 991 *interface = SOC_PORT_IF_NULL; 992 return SOC_E_NONE; 993 } 994 995 int pm4x10Q_port_loopback_set(int unit, int port, pm_info_t pm_info, portmod_loopback_mode_t loopback_type, int enable) 996 { 997 phymod_phy_access_t phy_access[1+MAX_PHYN]; 998 int nof_phys; 999 phymod_loopback_mode_t phymod_lb_type; 1000 SOC_INIT_FUNC_DEFS; 1001 1002 switch (loopback_type) { 1003 case portmodLoopbackMacOuter: 1004 _SOC_IF_ERR_EXIT(unimac_loopback_set(unit, port, enable)); 1005 break; 1006 case portmodLoopbackPhyGloopPCS: 1007 case portmodLoopbackPhyGloopPMD: 1008 case portmodLoopbackPhyRloopPMD: 1009 _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit, 1010 loopback_type, &phymod_lb_type)); 1011 1012 _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, 1013 phy_access ,(1+MAX_PHYN), 1014 &nof_phys)); 1015 1016 _SOC_IF_ERR_EXIT(portmod_port_phychain_loopback_set(unit, port, phy_access, 1017 nof_phys, 1018 phymod_lb_type, 1019 enable)); 1020 break; 1021 default: 1022 _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("unsupported loopback type %d"), loopback_type)); 1023 } 1024 1025 exit: 1026 SOC_FUNC_RETURN; 1027 } 1028 1029 int pm4x10Q_port_loopback_get(int unit, int port, pm_info_t pm_info, portmod_loopback_mode_t loopback_type, int* enable) 1030 { 1031 int rv, nof_phys; 1032 phymod_phy_access_t phy_access[1+MAX_PHYN]; 1033 uint32_t tmp_enable=0; 1034 phymod_loopback_mode_t phymod_lb_type; 1035 SOC_INIT_FUNC_DEFS; 1036 1037 switch (loopback_type) { 1038 case portmodLoopbackMacOuter: 1039 _SOC_IF_ERR_EXIT(unimac_loopback_get(unit, port, enable)); 1040 break; 1041 case portmodLoopbackPhyGloopPCS: 1042 case portmodLoopbackPhyGloopPMD: 1043 case portmodLoopbackPhyRloopPMD: 1044 _SOC_IF_ERR_EXIT(portmod_commmon_portmod_to_phymod_loopback_type(unit, 1045 loopback_type, &phymod_lb_type)); 1046 _SOC_IF_ERR_EXIT 1047 (portmod_port_chain_phy_access_get(unit, port, pm_info, 1048 phy_access ,(1+MAX_PHYN), 1049 &nof_phys)); 1050 1051 rv = portmod_port_phychain_loopback_get(unit, port, phy_access, 1052 nof_phys, 1053 phymod_lb_type, 1054 &tmp_enable); 1055 if (rv == PHYMOD_E_UNAVAIL) { 1056 rv = PHYMOD_E_NONE; 1057 tmp_enable = 0; 1058 } 1059 1060 _SOC_IF_ERR_EXIT(rv); 1061 *enable = tmp_enable; 1062 1063 break; 1064 default: 1065 (*enable) = 0; 1066 } 1067 1068 exit: 1069 SOC_FUNC_RETURN; 1070 } 1071 1072 1073 int pm4x10Q_port_core_access_get(int unit, int port, pm_info_t pm_info, int phyn, int max_cores, phymod_core_access_t* core_access_arr, int* nof_cores, int* is_most_ext) 1074 { 1075 int rv; 1076 int phy_index, sub_phy; 1077 soc_port_t phy_acc_port; 1078 SOC_INIT_FUNC_DEFS; 1079 1080 _SOC_IF_ERR_EXIT(_pm4x10q_sub_phy_get(unit, port, pm_info, &phy_index, &sub_phy)); 1081 1082 /* call pm4x10 below only for phys*/ 1083 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, phy_index); 1084 _SOC_IF_ERR_EXIT(rv); 1085 1086 rv = pm4x10_port_core_access_get(unit, phy_acc_port, PM_4x10Q_INFO(pm_info)->pm4x10, phyn, max_cores, core_access_arr, nof_cores, is_most_ext); 1087 _SOC_IF_ERR_EXIT(rv); 1088 1089 exit: 1090 SOC_FUNC_RETURN; 1091 } 1092 1093 1094 int pm4x10Q_port_phy_lane_access_get(int unit, int port, pm_info_t pm_info, const portmod_access_get_params_t* params, int max_phys, phymod_phy_access_t* access, int* nof_phys, int* is_most_ext) 1095 { 1096 int rv; 1097 int phy_index, sub_phy; 1098 soc_port_t phy_acc_port; 1099 SOC_INIT_FUNC_DEFS; 1100 1101 _SOC_IF_ERR_EXIT(_pm4x10q_sub_phy_get(unit, port, pm_info, &phy_index, &sub_phy)); 1102 1103 /* call pm4x10 below only for phys*/ 1104 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, phy_index); 1105 _SOC_IF_ERR_EXIT(rv); 1106 1107 rv = pm4x10_port_phy_lane_access_get(unit, phy_acc_port, PM_4x10Q_INFO(pm_info)->pm4x10, params, max_phys, access, nof_phys, is_most_ext); 1108 _SOC_IF_ERR_EXIT(rv); 1109 1110 access[0].access.lane_mask = 1 << ((phy_index * 4) + sub_phy); 1111 1112 exit: 1113 SOC_FUNC_RETURN; 1114 } 1115 1116 1117 int pm4x10Q_port_tx_average_ipg_set(int unit, int port, pm_info_t pm_info, int value) 1118 { 1119 SOC_INIT_FUNC_DEFS; 1120 1121 _SOC_IF_ERR_EXIT(unimac_tx_average_ipg_set(unit, port, value)); 1122 1123 exit: 1124 SOC_FUNC_RETURN; 1125 } 1126 1127 1128 int pm4x10Q_port_tx_average_ipg_get(int unit, int port, pm_info_t pm_info, int* value) 1129 { 1130 SOC_INIT_FUNC_DEFS; 1131 1132 _SOC_IF_ERR_EXIT(unimac_tx_average_ipg_get(unit, port, value)); 1133 1134 exit: 1135 SOC_FUNC_RETURN; 1136 } 1137 1138 int pm4x10Q_port_encap_set(int unit, int port, pm_info_t pm_info, int flags, portmod_encap_t encap) 1139 { 1140 SOC_INIT_FUNC_DEFS; 1141 1142 _SOC_IF_ERR_EXIT(unimac_encap_set(unit, port, encap)); 1143 1144 exit: 1145 SOC_FUNC_RETURN; 1146 } 1147 1148 1149 int pm4x10Q_port_encap_get(int unit, int port, pm_info_t pm_info, int *flags, portmod_encap_t *encap) 1150 { 1151 SOC_INIT_FUNC_DEFS; 1152 1153 _SOC_IF_ERR_EXIT(unimac_encap_get(unit, port, encap)); 1154 1155 exit: 1156 SOC_FUNC_RETURN; 1157 } 1158 1159 1160 int pm4x10Q_port_eee_set(int unit, int port, pm_info_t pm_info,const portmod_eee_t* eee) 1161 { 1162 SOC_INIT_FUNC_DEFS; 1163 1164 _SOC_IF_ERR_EXIT(unimac_eee_set(unit, port, eee)); 1165 1166 exit: 1167 SOC_FUNC_RETURN; 1168 } 1169 1170 1171 int pm4x10Q_port_eee_get(int unit, int port, pm_info_t pm_info, portmod_eee_t* eee) 1172 { 1173 SOC_INIT_FUNC_DEFS; 1174 1175 _SOC_IF_ERR_EXIT(unimac_eee_get(unit, port, eee)); 1176 1177 exit: 1178 SOC_FUNC_RETURN; 1179 } 1180 1181 1182 int pm4x10Q_port_speed_get(int unit, int port, pm_info_t pm_info, int* speed) 1183 { 1184 SOC_INIT_FUNC_DEFS; 1185 1186 _SOC_IF_ERR_EXIT(unimac_speed_get(unit, port, speed)); 1187 1188 exit: 1189 SOC_FUNC_RETURN; 1190 } 1191 1192 1193 int pm4x10Q_port_pfc_config_set(int unit, int port,pm_info_t pm_info, const portmod_pfc_config_t* pfc_cfg) 1194 { 1195 SOC_INIT_FUNC_DEFS; 1196 1197 _SOC_IF_ERR_EXIT(unimac_pfc_config_set(unit, port, pfc_cfg)); 1198 1199 exit: 1200 SOC_FUNC_RETURN; 1201 } 1202 1203 1204 int pm4x10Q_port_pfc_config_get(int unit, int port,pm_info_t pm_info, portmod_pfc_config_t* pfc_cfg) 1205 { 1206 SOC_INIT_FUNC_DEFS; 1207 1208 _SOC_IF_ERR_EXIT(unimac_pfc_config_get(unit, port, pfc_cfg)); 1209 1210 exit: 1211 SOC_FUNC_RETURN; 1212 } 1213 1214 int pm4x10Q_port_pause_control_set(int unit, int port, pm_info_t pm_info, const portmod_pause_control_t* control) 1215 { 1216 SOC_INIT_FUNC_DEFS; 1217 1218 _SOC_IF_ERR_EXIT(unimac_pause_control_set(unit, port, control)); 1219 1220 exit: 1221 SOC_FUNC_RETURN; 1222 } 1223 1224 1225 int pm4x10Q_port_pause_control_get(int unit, int port, pm_info_t pm_info, portmod_pause_control_t* control) 1226 { 1227 SOC_INIT_FUNC_DEFS; 1228 1229 _SOC_IF_ERR_EXIT(unimac_pause_control_get(unit, port, control)); 1230 1231 exit: 1232 SOC_FUNC_RETURN; 1233 } 1234 1235 1236 int pm4x10Q_port_duplex_set(int unit, int port, pm_info_t pm_info,int enable) 1237 { 1238 SOC_INIT_FUNC_DEFS; 1239 1240 _SOC_IF_ERR_EXIT(unimac_duplex_set(unit, port, enable)); 1241 1242 exit: 1243 SOC_FUNC_RETURN; 1244 } 1245 1246 int pm4x10Q_port_duplex_get(int unit, int port, pm_info_t pm_info, int* enable) 1247 { 1248 SOC_INIT_FUNC_DEFS; 1249 1250 _SOC_IF_ERR_EXIT(unimac_duplex_get(unit, port, enable)); 1251 1252 exit: 1253 SOC_FUNC_RETURN; 1254 } 1255 1256 1257 int pm4x10Q_port_cntmaxsize_get(int unit, int port, pm_info_t pm_info, int *val) 1258 { 1259 SOC_INIT_FUNC_DEFS; 1260 1261 _SOC_IF_ERR_EXIT(READ_GPORT_CNTMAXSIZEr(unit, port, (uint32_t *)val)); 1262 1263 exit: 1264 SOC_FUNC_RETURN; 1265 } 1266 1267 int pm4x10Q_port_cntmaxsize_set(int unit, int port, pm_info_t pm_info, int val) 1268 { 1269 SOC_INIT_FUNC_DEFS; 1270 1271 _SOC_IF_ERR_EXIT(WRITE_GPORT_CNTMAXSIZEr(unit, port, (uint32_t)val)); 1272 1273 exit: 1274 SOC_FUNC_RETURN; 1275 } 1276 1277 1278 int 1279 pm4x10Q_default_bus_update(int unit, pm_info_t pm_info, const portmod_bus_update_t* update) 1280 { 1281 SOC_INIT_FUNC_DEFS; 1282 1283 _SOC_IF_ERR_EXIT(pm4x10_default_bus_update(unit, PM_4x10Q_INFO(pm_info)->pm4x10, update)); 1284 exit: 1285 SOC_FUNC_RETURN; 1286 } 1287 1288 int 1289 pm4x10Q_port_local_fault_control_set(int unit, int port, pm_info_t pm_info, const portmod_local_fault_control_t* control) 1290 { 1291 SOC_INIT_FUNC_DEFS; 1292 1293 SOC_FUNC_RETURN; 1294 } 1295 1296 int 1297 pm4x10Q_port_local_fault_control_get(int unit, int port, pm_info_t pm_info, portmod_local_fault_control_t* control) 1298 { 1299 SOC_INIT_FUNC_DEFS; 1300 1301 SOC_FUNC_RETURN; 1302 } 1303 1304 int pm4x10Q_port_local_fault_status_clear(int unit, int port, pm_info_t pm_info) 1305 { 1306 SOC_INIT_FUNC_DEFS; 1307 1308 _SOC_IF_ERR_EXIT(pm4x10_port_local_fault_status_clear(unit, port, PM_4x10Q_INFO(pm_info)->pm4x10)); 1309 exit: 1310 SOC_FUNC_RETURN; 1311 } 1312 1313 int 1314 pm4x10Q_port_remote_fault_control_set(int unit, int port, pm_info_t pm_info, const portmod_remote_fault_control_t* control) 1315 { 1316 SOC_INIT_FUNC_DEFS; 1317 1318 SOC_FUNC_RETURN; 1319 } 1320 1321 int 1322 pm4x10Q_port_remote_fault_control_get(int unit, int port, pm_info_t pm_info, portmod_remote_fault_control_t* control) 1323 { 1324 SOC_INIT_FUNC_DEFS; 1325 1326 SOC_FUNC_RETURN; 1327 } 1328 1329 int pm4x10Q_port_remote_fault_status_clear(int unit, int port, pm_info_t pm_info) 1330 { 1331 SOC_INIT_FUNC_DEFS; 1332 1333 _SOC_IF_ERR_EXIT(pm4x10_port_remote_fault_status_clear(unit, port, PM_4x10Q_INFO(pm_info)->pm4x10)); 1334 exit: 1335 SOC_FUNC_RETURN; 1336 } 1337 1338 int pm4x10Q_port_rx_control_set(int unit, int port, pm_info_t pm_info,const portmod_rx_control_t* rx_ctrl) 1339 { 1340 SOC_INIT_FUNC_DEFS; 1341 1342 _SOC_IF_ERR_EXIT(unimac_pass_control_frame_set(unit, port, rx_ctrl->pass_control_frames)); 1343 1344 exit: 1345 SOC_FUNC_RETURN; 1346 } 1347 1348 int pm4x10Q_xphy_lane_attach_to_pm(int unit, pm_info_t pm_info, int iphy, int phyn, const portmod_xphy_lane_connection_t* lane_connection) 1349 { 1350 SOC_INIT_FUNC_DEFS; 1351 1352 SOC_FUNC_RETURN; 1353 } 1354 1355 int pm4x10Q_xphy_lane_detach_from_pm(int unit, pm_info_t pm_info, int iphy, int phyn, portmod_xphy_lane_connection_t* lane_connection) 1356 { 1357 SOC_INIT_FUNC_DEFS; 1358 1359 SOC_FUNC_RETURN; 1360 } 1361 1362 int pm4x10Q_port_diag_fifo_status_get (int unit, int port,pm_info_t pm_info, const portmod_fifo_status_t* diag_info) 1363 { 1364 SOC_INIT_FUNC_DEFS; 1365 1366 _SOC_IF_ERR_EXIT(unimac_diag_fifo_status_get(unit, port, diag_info)); 1367 exit: 1368 SOC_FUNC_RETURN; 1369 } 1370 1371 1372 int pm4x10Q_port_drv_name_get(int unit, int port, pm_info_t pm_info, char* buf, int len) 1373 { 1374 strncpy(buf, "PM4X10Q Driver", len); 1375 return (SOC_E_NONE); 1376 } 1377 1378 int pm4x10Q_port_max_packet_size_set (int unit, int port, pm_info_t pm_info, int value) 1379 { 1380 SOC_INIT_FUNC_DEFS; 1381 1382 _SOC_IF_ERR_EXIT(unimac_rx_max_size_set(unit, port, value)); 1383 1384 exit: 1385 SOC_FUNC_RETURN; 1386 } 1387 1388 int pm4x10Q_port_max_packet_size_get (int unit, int port, pm_info_t pm_info, int* value) 1389 { 1390 SOC_INIT_FUNC_DEFS; 1391 1392 _SOC_IF_ERR_EXIT(unimac_rx_max_size_get(unit, port, value)); 1393 1394 exit: 1395 SOC_FUNC_RETURN; 1396 } 1397 1398 1399 int pm4x10Q_port_rx_mac_enable_set(int unit, int port, pm_info_t pm_info, int enable) 1400 { 1401 SOC_INIT_FUNC_DEFS; 1402 1403 _SOC_IF_ERR_EXIT(unimac_rx_enable_set(unit, port, enable)); 1404 1405 exit: 1406 SOC_FUNC_RETURN; 1407 1408 } 1409 1410 int pm4x10Q_port_rx_mac_enable_get(int unit, int port, pm_info_t pm_info, int* enable) 1411 { 1412 SOC_INIT_FUNC_DEFS; 1413 1414 _SOC_IF_ERR_EXIT(unimac_rx_enable_get(unit, port, enable)); 1415 1416 exit: 1417 SOC_FUNC_RETURN; 1418 1419 } 1420 1421 int pm4x10Q_port_vlan_tag_set(int unit, int port, pm_info_t pm_info,const portmod_vlan_tag_t* vlan_tag) 1422 { 1423 SOC_INIT_FUNC_DEFS; 1424 1425 _SOC_IF_ERR_EXIT(unimac_rx_vlan_tag_set(unit, port, vlan_tag->outer_vlan_tag, vlan_tag->inner_vlan_tag)); 1426 1427 exit: 1428 SOC_FUNC_RETURN; 1429 } 1430 1431 1432 int pm4x10Q_port_vlan_tag_get(int unit, int port, pm_info_t pm_info, portmod_vlan_tag_t* vlan_tag) 1433 { 1434 SOC_INIT_FUNC_DEFS; 1435 1436 _SOC_IF_ERR_EXIT(unimac_rx_vlan_tag_get(unit, port, (int*)&vlan_tag->outer_vlan_tag, (int*)&vlan_tag->inner_vlan_tag)); 1437 1438 exit: 1439 SOC_FUNC_RETURN; 1440 1441 } 1442 1443 int pm4x10Q_port_pfc_control_set(int unit, int port, pm_info_t pm_info, const portmod_pfc_control_t* control) 1444 { 1445 1446 SOC_INIT_FUNC_DEFS; 1447 _SOC_IF_ERR_EXIT(unimac_pfc_control_set(unit, port, control)); 1448 exit: 1449 SOC_FUNC_RETURN; 1450 1451 } 1452 1453 int pm4x10Q_port_pfc_control_get(int unit, int port, pm_info_t pm_info, portmod_pfc_control_t* control) 1454 { 1455 1456 SOC_INIT_FUNC_DEFS; 1457 _SOC_IF_ERR_EXIT(unimac_pfc_control_get(unit, port, control)); 1458 exit: 1459 SOC_FUNC_RETURN; 1460 1461 } 1462 1463 int pm4x10Q_port_llfc_control_set(int unit, int port, pm_info_t pm_info, const portmod_llfc_control_t* control) 1464 { 1465 SOC_INIT_FUNC_DEFS; 1466 1467 SOC_FUNC_RETURN; 1468 } 1469 1470 int pm4x10Q_port_llfc_control_get(int unit, int port, pm_info_t pm_info, portmod_llfc_control_t* control) 1471 { 1472 SOC_INIT_FUNC_DEFS; 1473 1474 SOC_FUNC_RETURN; 1475 } 1476 1477 int pm4x10Q_port_link_get(int unit, int port, pm_info_t pm_info, int flags, int* link) 1478 { 1479 int rv; 1480 int phy_index, sub_phy; 1481 soc_port_t phy_acc_port; 1482 1483 phymod_phy_access_t phy_access[1+MAX_PHYN]; 1484 int nof_phys; 1485 SOC_INIT_FUNC_DEFS; 1486 1487 _SOC_IF_ERR_EXIT(_pm4x10q_sub_phy_get(unit, port, pm_info, &phy_index, &sub_phy)); 1488 1489 /* call pm4x10 below only for phys*/ 1490 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, phy_index); 1491 _SOC_IF_ERR_EXIT(rv); 1492 1493 _SOC_IF_ERR_EXIT(portmod_port_chain_phy_access_get(unit, port, pm_info, phy_access ,(1+MAX_PHYN), &nof_phys)); 1494 1495 _SOC_IF_ERR_EXIT(portmod_port_phychain_link_status_get(unit, port, phy_access, nof_phys, flags, (uint32_t*) link)); 1496 1497 exit: 1498 SOC_FUNC_RETURN; 1499 } 1500 1501 int pm4x10Q_port_autoneg_set(int unit, int port, pm_info_t pm_info, uint32 phy_flags, const phymod_autoneg_control_t* an) 1502 { 1503 int rv; 1504 int phy_index, sub_phy; 1505 soc_port_t phy_acc_port; 1506 SOC_INIT_FUNC_DEFS; 1507 1508 _SOC_IF_ERR_EXIT(_pm4x10q_sub_phy_get(unit, port, pm_info, &phy_index, &sub_phy)); 1509 1510 /* call pm4x10 below only for phys*/ 1511 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, phy_index); 1512 _SOC_IF_ERR_EXIT(rv); 1513 1514 rv = pm4x10_port_autoneg_set(unit, phy_acc_port, PM_4x10Q_INFO(pm_info)->pm4x10, phy_flags, an); 1515 _SOC_IF_ERR_EXIT(rv); 1516 1517 exit: 1518 SOC_FUNC_RETURN; 1519 } 1520 1521 int pm4x10Q_port_autoneg_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags, phymod_autoneg_control_t* an) 1522 { 1523 int rv; 1524 int phy_index, sub_phy; 1525 soc_port_t phy_acc_port; 1526 SOC_INIT_FUNC_DEFS; 1527 1528 _SOC_IF_ERR_EXIT(_pm4x10q_sub_phy_get(unit, port, pm_info, &phy_index, &sub_phy)); 1529 1530 /* call pm4x10 below only for phys*/ 1531 rv = SOC_WB_ENGINE_GET_ARR(unit, SOC_WB_ENGINE_PORTMOD, pm_info->wb_vars_ids[phyAccPorts], &phy_acc_port, phy_index); 1532 _SOC_IF_ERR_EXIT(rv); 1533 1534 rv = pm4x10_port_autoneg_get(unit, phy_acc_port, PM_4x10Q_INFO(pm_info)->pm4x10, phy_flags, an); 1535 _SOC_IF_ERR_EXIT(rv); 1536 1537 exit: 1538 SOC_FUNC_RETURN; 1539 } 1540 1541 int pm4x10Q_port_tx_mac_sa_set(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr) 1542 { 1543 return (unimac_mac_sa_set(unit, port, mac_addr)); 1544 } 1545 1546 1547 int pm4x10Q_port_tx_mac_sa_get(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr) 1548 { 1549 return (unimac_mac_sa_get(unit, port, mac_addr)); 1550 } 1551 1552 int pm4x10Q_port_rx_mac_sa_set(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr) 1553 { 1554 return (unimac_mac_sa_set(unit, port, mac_addr)); 1555 } 1556 1557 1558 int pm4x10Q_port_rx_mac_sa_get(int unit, int port, pm_info_t pm_info, sal_mac_addr_t mac_addr) 1559 { 1560 return (unimac_mac_sa_get(unit, port, mac_addr)); 1561 } 1562 1563 int pm4x10Q_port_pad_size_set(int unit, int port, pm_info_t pm_info, int value) 1564 { 1565 SOC_INIT_FUNC_DEFS; 1566 1567 /*Unimac tx padding is always enabled*/ 1568 SOC_FUNC_RETURN; 1569 1570 } 1571 1572 int pm4x10Q_port_pad_size_get(int unit, int port, pm_info_t pm_info, int* value) 1573 { 1574 SOC_INIT_FUNC_DEFS; 1575 SOC_NULL_CHECK(pm_info); 1576 1577 /*Unimac tx padding is always enabled and min frame size is 64*/ 1578 *value = 64; 1579 1580 exit: 1581 SOC_FUNC_RETURN; 1582 } 1583 1584 int pm4x10Q_port_update(int unit, int port, pm_info_t pm_info, 1585 const portmod_port_update_control_t* update_control) 1586 { 1587 SOC_INIT_FUNC_DEFS; 1588 1589 SOC_FUNC_RETURN; 1590 } 1591 1592 int pm4x10Q_port_nof_lanes_get(int unit, int port, pm_info_t pm_info, int *nof_lanes) 1593 { 1594 SOC_INIT_FUNC_DEFS; 1595 1596 /*QSGMII ports always occupy only one lane*/ 1597 *nof_lanes = 1; 1598 1599 SOC_FUNC_RETURN; 1600 } 1601 1602 int pm4x10Q_port_diag_ctrl(int unit, soc_port_t port, pm_info_t pm_info, 1603 uint32 inst, int op_type, int op_cmd, const void *arg) 1604 { 1605 phymod_phy_access_t phy_access[1+MAX_PHYN]; 1606 phymod_tx_t ln_txparam[PM4X10Q_LANES_PER_CORE]; 1607 int nof_phys, i; 1608 uint32 lane_map; 1609 portmod_access_get_params_t params; 1610 1611 SOC_IF_ERROR_RETURN(portmod_access_get_params_t_init(unit, ¶ms)); 1612 1613 for (i = 0; i < PM4X10Q_LANES_PER_CORE; i++) { 1614 SOC_IF_ERROR_RETURN(phymod_tx_t_init(&ln_txparam[i])); 1615 } 1616 1617 if( PHY_DIAG_INST_DEV(inst) == PHY_DIAG_DEV_INT ) { 1618 params.phyn = 0 ; 1619 } else { 1620 /* most external PHY_DIAG_DEV_DFLT and PHY_DIAG_DEV_EXT */ 1621 params.phyn = -1 ; 1622 } 1623 1624 if(PHY_DIAG_INST_INTF(inst) == PHY_DIAG_INTF_SYS ){ 1625 params.sys_side = PORTMOD_SIDE_SYSTEM; 1626 } else { /* line side is default */ 1627 params.sys_side = PORTMOD_SIDE_LINE; 1628 } 1629 1630 params.apply_lane_mask = 1; 1631 1632 SOC_IF_ERROR_RETURN(pm4x10Q_port_phy_lane_access_get(unit, port, pm_info, 1633 ¶ms, 1, phy_access, &nof_phys, NULL)); 1634 1635 lane_map = phy_access[0].access.lane_mask; 1636 1637 switch(op_cmd) { 1638 case PHY_DIAG_CTRL_DSC: 1639 LOG_INFO(BSL_LS_SOC_PHY, 1640 (BSL_META_U(unit, 1641 "pm4x10_port_diag_ctrl: " 1642 "u=%d p=%d PHY_DIAG_CTRL_DSC 0x%x\n"), 1643 unit, port, PHY_DIAG_CTRL_DSC)); 1644 1645 SOC_IF_ERROR_RETURN 1646 (portmod_port_phychain_pmd_info_dump(unit, phy_access, nof_phys, 1647 (void*)arg)); 1648 break; 1649 1650 default: 1651 if(op_type == PHY_DIAG_CTRL_SET) { 1652 LOG_INFO(BSL_LS_SOC_PHY, 1653 (BSL_META_U(unit, 1654 "pm4x10_port_diag_ctrl: " 1655 "u=%d p=%d PHY_DIAG_CTRL_SET 0x%x\n"), 1656 unit, port, PHY_DIAG_CTRL_SET)); 1657 if (!SAL_BOOT_SIMULATION) { 1658 if( !(phy_access->access.lane_mask == 0)){ 1659 SOC_IF_ERROR_RETURN(portmod_pm_phy_control_set(phy_access, nof_phys, op_cmd, ln_txparam, lane_map, PTR_TO_INT(arg))); 1660 } 1661 } 1662 } else if(op_type == PHY_DIAG_CTRL_GET) { 1663 LOG_INFO(BSL_LS_SOC_PHY, 1664 (BSL_META_U(unit, 1665 "pm4x10_port_diag_ctrl: " 1666 "u=%d p=%d PHY_DIAG_CTRL_GET 0x%x\n"), 1667 unit, port, PHY_DIAG_CTRL_GET)); 1668 if (!SAL_BOOT_SIMULATION) { 1669 if( !(phy_access->access.lane_mask == 0)){ 1670 SOC_IF_ERROR_RETURN(portmod_pm_phy_control_get(phy_access,nof_phys,op_cmd, ln_txparam, lane_map, (uint32 *)arg)); 1671 } else { 1672 *(uint32 *)arg = 0; 1673 } 1674 } 1675 } else { 1676 return (SOC_E_UNAVAIL); 1677 } 1678 break ; 1679 } 1680 return (SOC_E_NONE); 1681 } 1682 1683 int pm4x10Q_port_autoneg_status_get (int unit, int port, pm_info_t pm_info, 1684 phymod_autoneg_status_t* an_status) 1685 { 1686 phymod_phy_access_t phy_access[1+MAX_PHYN]; 1687 int nof_phys; 1688 1689 SOC_INIT_FUNC_DEFS; 1690 1691 _SOC_IF_ERR_EXIT 1692 (portmod_port_chain_phy_access_get(unit, port, pm_info, 1693 phy_access ,(1+MAX_PHYN), 1694 &nof_phys)); 1695 if(nof_phys == 0) { 1696 _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL, (_SOC_MSG("Autoneg isn't supported"))); 1697 } 1698 1699 _SOC_IF_ERR_EXIT 1700 (portmod_port_phychain_autoneg_status_get(unit, port, phy_access, nof_phys, an_status)); 1701 1702 exit: 1703 SOC_FUNC_RETURN; 1704 1705 } 1706 1707 int pm4x10Q_port_phy_link_up_event(int unit, int port, pm_info_t pm_info) 1708 { 1709 phymod_phy_access_t phy_access[1+MAX_PHYN]; 1710 int nof_phys; 1711 1712 SOC_INIT_FUNC_DEFS; 1713 1714 _SOC_IF_ERR_EXIT 1715 (portmod_port_chain_phy_access_get(unit, port, pm_info, 1716 phy_access ,(1+MAX_PHYN), 1717 &nof_phys)); 1718 _SOC_IF_ERR_EXIT 1719 (portmod_port_phychain_phy_link_up_event(unit, port, phy_access, nof_phys)); 1720 exit: 1721 SOC_FUNC_RETURN; 1722 } 1723 1724 int pm4x10Q_port_phy_link_down_event(int unit, int port, pm_info_t pm_info) 1725 { 1726 phymod_phy_access_t phy_access[1+MAX_PHYN]; 1727 int nof_phys; 1728 1729 SOC_INIT_FUNC_DEFS; 1730 1731 _SOC_IF_ERR_EXIT 1732 (portmod_port_chain_phy_access_get(unit, port, pm_info, 1733 phy_access ,(1+MAX_PHYN), 1734 &nof_phys)); 1735 _SOC_IF_ERR_EXIT 1736 (portmod_port_phychain_phy_link_down_event(unit, port, phy_access, nof_phys)); 1737 exit: 1738 SOC_FUNC_RETURN; 1739 } 1740 1741 int 1742 pm4x10Q_port_ability_local_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags, portmod_port_ability_t* ability) 1743 { 1744 SOC_INIT_FUNC_DEFS; 1745 1746 ability->speed_full_duplex = SOC_PA_SPEED_2500MB | SOC_PA_SPEED_1000MB | SOC_PA_SPEED_100MB | SOC_PA_SPEED_10MB; 1747 ability->speed_half_duplex = SOC_PA_ABILITY_NONE; 1748 ability->medium = SOC_PA_MEDIUM_FIBER | SOC_PA_MEDIUM_COPPER; 1749 ability->interface = SOC_PA_INTF_QSGMII; 1750 ability->loopback = SOC_PA_LB_PHY | SOC_PA_LB_MAC; 1751 ability->fec = SOC_PA_FEC_NONE; 1752 ability->encap = SOC_PA_ENCAP_IEEE; 1753 ability->channel = SOC_PA_CHANNEL_LONG; 1754 1755 SOC_FUNC_RETURN; 1756 } 1757 1758 int 1759 pm4x10Q_port_ability_advert_set(int unit, int port, pm_info_t pm_info, uint32 phy_flags, portmod_port_ability_t* ability) 1760 { 1761 /* Autoneg not supported for QSGMII ports */ 1762 SOC_INIT_FUNC_DEFS; 1763 1764 SOC_FUNC_RETURN; 1765 } 1766 1767 int 1768 pm4x10Q_port_ability_advert_get(int unit, int port, pm_info_t pm_info, uint32 phy_flags, portmod_port_ability_t* ability) 1769 { 1770 /* Autoneg not supported for QSGMII ports */ 1771 SOC_INIT_FUNC_DEFS; 1772 1773 SOC_FUNC_RETURN; 1774 } 1775 1776 int 1777 pm4x10Q_port_mode_set(int unit, int port, pm_info_t pm_info, const portmod_port_mode_info_t* mode) 1778 { 1779 SOC_INIT_FUNC_DEFS; 1780 1781 SOC_FUNC_RETURN; 1782 } 1783 1784 int 1785 pm4x10Q_port_mode_get(int unit, int port, pm_info_t pm_info, portmod_port_mode_info_t* mode) 1786 { 1787 SOC_INIT_FUNC_DEFS; 1788 1789 SOC_FUNC_RETURN; 1790 } 1791 1792 int 1793 pm4x10Q_port_mac_reset_check(int unit, int port, pm_info_t pm_info, int enable, int* reset) 1794 { 1795 SOC_INIT_FUNC_DEFS; 1796 1797 _SOC_IF_ERR_EXIT(unimac_soft_reset_get(unit, port, reset)); 1798 1799 *reset = (enable == *reset) ? (enable ? 0 : 1) : 1; 1800 1801 exit: 1802 SOC_FUNC_RETURN; 1803 } 1804 1805 int 1806 pm4x10Q_port_check_legacy_phy(int unit, int port, pm_info_t pm_info, int* legacy_phy) 1807 { 1808 SOC_INIT_FUNC_DEFS; 1809 1810 *legacy_phy = 0; 1811 1812 SOC_FUNC_RETURN; 1813 } 1814 1815 int 1816 pm4x10Q_port_discard_set(int unit, int port, pm_info_t pm_info, int discard) 1817 { 1818 SOC_INIT_FUNC_DEFS; 1819 1820 SOC_FUNC_RETURN; 1821 } 1822 1823 int 1824 pm4x10Q_port_core_num_get(int unit, int port, pm_info_t pm_info, int* core_num) 1825 { 1826 SOC_INIT_FUNC_DEFS; 1827 1828 _SOC_IF_ERR_EXIT(pm4x10_port_core_num_get(unit, port, PM_4x10Q_INFO(pm_info)->pm4x10, core_num)); 1829 1830 exit: 1831 SOC_FUNC_RETURN; 1832 } 1833 1834 int 1835 pm4x10Q_port_ref_clk_get(int unit, int port, pm_info_t pm_info, int* ref_clk) 1836 { 1837 SOC_INIT_FUNC_DEFS; 1838 1839 _SOC_IF_ERR_EXIT(pm4x10_port_ref_clk_get(unit, port, PM_4x10Q_INFO(pm_info)->pm4x10, ref_clk)); 1840 1841 exit: 1842 SOC_FUNC_RETURN; 1843 } 1844 1845 int 1846 pm4x10Q_port_soft_reset_set(int unit, int port, pm_info_t pm_info, int idx, int val, int flags) 1847 { 1848 SOC_INIT_FUNC_DEFS; 1849 1850 _SOC_IF_ERR_EXIT(unimac_soft_reset_set(unit, port, val)); 1851 1852 exit: 1853 SOC_FUNC_RETURN; 1854 } 1855 1856 int 1857 pm4x10Q_port_drain_cells_rx_enable(int unit, int port, pm_info_t pm_info, int enable) 1858 { 1859 int flags; 1860 SOC_INIT_FUNC_DEFS; 1861 1862 flags = UNIMAC_ENABLE_SET_FLAGS_RX_EN | UNIMAC_ENABLE_SET_FLAGS_TX_EN; 1863 1864 _SOC_IF_ERR_EXIT(unimac_enable_set(unit, port, flags, enable)); 1865 1866 exit: 1867 SOC_FUNC_RETURN; 1868 } 1869 1870 int 1871 pm4x10Q_port_tx_down(int unit, int port, pm_info_t pm_info) 1872 { 1873 int flags; 1874 SOC_INIT_FUNC_DEFS; 1875 1876 flags = UNIMAC_ENABLE_SET_FLAGS_TX_EN; 1877 1878 _SOC_IF_ERR_EXIT(unimac_enable_set(unit, port, flags, 0)); 1879 1880 exit: 1881 SOC_FUNC_RETURN; 1882 } 1883 1884 int 1885 pm4x10Q_port_txfifo_cell_cnt_get(int unit, int port, pm_info_t pm_info, uint32* cnt) 1886 { 1887 SOC_INIT_FUNC_DEFS; 1888 1889 *cnt = 0; 1890 1891 SOC_FUNC_RETURN; 1892 } 1893 1894 int 1895 pm4x10Q_port_drain_cell_get(int unit, int port, pm_info_t pm_info, portmod_drain_cells_t* drain_cells) 1896 { 1897 SOC_INIT_FUNC_DEFS; 1898 1899 _SOC_IF_ERR_EXIT(unimac_drain_cell_get(unit, port, drain_cells)); 1900 1901 exit: 1902 SOC_FUNC_RETURN; 1903 } 1904 1905 int 1906 pm4x10Q_port_drain_cell_start(int unit, int port, pm_info_t pm_info) 1907 { 1908 1909 SOC_INIT_FUNC_DEFS; 1910 1911 SOC_FUNC_RETURN; 1912 } 1913 1914 int 1915 pm4x10Q_port_drain_cell_stop(int unit, int port, pm_info_t pm_info, const portmod_drain_cells_t* drain_cells) 1916 { 1917 1918 SOC_INIT_FUNC_DEFS; 1919 1920 SOC_FUNC_RETURN; 1921 } 1922 1923 int 1924 pm4x10Q_port_lag_failover_status_toggle(int unit, int port, pm_info_t pm_info) 1925 { 1926 /* Lag failover not supported */ 1927 SOC_INIT_FUNC_DEFS; 1928 1929 SOC_FUNC_RETURN; 1930 } 1931 1932 #endif /* PORTMOD_PM4x10Q_SUPPORT */ 1933 1934 #undef _ERR_MSG_MODULE_NAME