tsce.c (149256B)
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 <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_debug.h> 13 #include <phymod/phymod_util.h> 14 #include <phymod/chip/bcmi_tsce_xgxs_defs.h> 15 #include <phymod/chip/tsce.h> 16 #include <phymod/chip/eagle_common.h> 17 #include "../../tsce/tier1/temod_enum_defines.h" 18 #include "../../tsce/tier1/temod.h" 19 #include "../../tsce/tier1/temod_device.h" 20 #include "../../tsce/tier1/temod_sc_lkup_table.h" 21 #include "../../tsce/tier1/tePCSRegEnums.h" 22 #include "../../eagle/tier1/eagle_cfg_seq.h" 23 #include "../../eagle/tier1/eagle_tsc_common.h" 24 #include "../../eagle/tier1/eagle_tsc_interface.h" 25 #include "../../eagle/tier1/eagle_tsc_debug_functions.h" 26 #include "../../eagle/tier1/eagle_tsc_dependencies.h" 27 28 29 30 #define TSCE_ID0 0x600d 31 #define TSCE_ID1 0x8770 32 #define TSCE_REV_MASK 0x0 33 34 #define TSCE4_MODEL 0x12 35 #define TSCE12_MODEL 0x13 36 #define EAGLE_MODEL 0x1a 37 #define TSCE_TECH_PROC 0x3 /* 28nm */ 38 39 #define TSCE_NOF_DFES (5) 40 #define TSCE_NOF_LANES_IN_CORE (4) 41 #define TSCE_LANE_SWAP_LANE_MASK (0x3) 42 #define TSCE_PHY_ALL_LANES (0xf) 43 #define TSCE_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 44 do{\ 45 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\ 46 (_phy_access)->type = (_core_access)->type; \ 47 (_phy_access)->port_loc = (_core_access)->port_loc; \ 48 (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \ 49 (_phy_access)->access.lane_mask = TSCE_PHY_ALL_LANES; \ 50 }while(0) 51 52 #define TSCE_MAX_FIRMWARES (5) 53 54 #define TSCE_USERSPEED_SELECT(_phy, _config, _type) \ 55 ((_config)->mode==phymodPcsUserSpeedModeST) ? \ 56 temod_st_control_field_set(&(_phy)->access, (_config)->current_entry, _type, (_config)->value) : \ 57 temod_override_set(&(_phy)->access, _type, (_config)->value) 58 59 #define TSCE_USERSPEED_CREDIT_SELECT(_phy, _config, _type) \ 60 ((_config)->mode==phymodPcsUserSpeedModeST) ? \ 61 temod_st_credit_field_set(&(_phy)->access, (_config)->current_entry, _type, (_config)->value) : \ 62 temod_credit_override_set(&(_phy)->access, _type, (_config)->value) 63 64 #define TSCE_PMD_CRC_UCODE 1 65 /* uController's firmware */ 66 extern unsigned char tsce_ucode[]; 67 extern unsigned short tsce_ucode_ver; 68 extern unsigned short tsce_ucode_crc; 69 extern unsigned short tsce_ucode_len; 70 71 typedef int (*sequncer_control_f)(const phymod_access_t* core, uint32_t enable); 72 typedef int (*rx_DFE_tap_control_set_f)(const phymod_access_t* phy, uint32_t val); 73 extern int tsce_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config); 74 75 STATIC 76 int _tsce_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 77 { 78 struct eagle_tsc_uc_lane_config_st serdes_firmware_config; 79 phymod_phy_access_t phy_copy; 80 int start_lane, num_lane, i; 81 /* uint32_t rst_status; */ 82 uint32_t is_warm_boot; 83 84 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 85 PHYMOD_IF_ERR_RETURN 86 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 87 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 88 89 for (i = 0; i < num_lane; i++) { 90 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 91 continue; 92 } 93 phy_copy.access.lane_mask = 1 << (start_lane + i); 94 serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 95 serdes_firmware_config.field.an_enabled = fw_config.AnEnabled; 96 serdes_firmware_config.field.dfe_on = fw_config.DfeOn; 97 serdes_firmware_config.field.force_brdfe_on = fw_config.ForceBrDfe; 98 /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */ 99 serdes_firmware_config.field.scrambling_dis = fw_config.ScramblingDisable; 100 serdes_firmware_config.field.unreliable_los = fw_config.UnreliableLos; 101 serdes_firmware_config.field.media_type = fw_config.MediaType; 102 serdes_firmware_config.field.cl72_auto_polarity_en = fw_config.Cl72AutoPolEn; 103 serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO; 104 105 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy_copy.access, &is_warm_boot)); 106 107 108 if(!is_warm_boot) { 109 /* PHYMOD_IF_ERR_RETURN(eagle_lane_soft_reset_read(&phy_copy.access, &rst_status)); */ 110 /* if(rst_status) */ PHYMOD_IF_ERR_RETURN (eagle_lane_soft_reset_release(&phy_copy.access, 0)); 111 PHYMOD_IF_ERR_RETURN(eagle_tsc_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config)); 112 /* if(rst_status) */ PHYMOD_IF_ERR_RETURN (eagle_lane_soft_reset_release(&phy_copy.access, 1)); 113 } 114 } 115 return PHYMOD_E_NONE; 116 } 117 118 int tsce_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 119 { 120 int ioerr = 0; 121 const phymod_access_t *pm_acc = &core->access; 122 PHYID2r_t id2; 123 PHYID3r_t id3; 124 MAIN0_SERDESIDr_t serdesid; 125 /* DIG_REVID0r_t revid; */ 126 uint32_t model; 127 int rv ; 128 *is_identified = 0; 129 130 if(core_id == 0){ 131 ioerr += READ_PHYID2r(pm_acc, &id2); 132 ioerr += READ_PHYID3r(pm_acc, &id3); 133 } 134 else{ 135 PHYID2r_SET(id2, ((core_id >> 16) & 0xffff)); 136 PHYID3r_SET(id3, core_id & 0xffff); 137 } 138 139 if (PHYID2r_GET(id2) == TSCE_ID0 && 140 (PHYID3r_GET(id3) &= ~TSCE_REV_MASK) == TSCE_ID1) { 141 /* PHY IDs match - now check PCS model */ 142 ioerr += READ_MAIN0_SERDESIDr(pm_acc, &serdesid); 143 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 144 if (model == TSCE4_MODEL || model == TSCE12_MODEL) { 145 /* PCS model matches - now check PMD model */ 146 /* for now Bypass the pmd register rev check */ 147 /* ioerr += READ_DIG_REVID0r(pm_acc, &revid); 148 if (DIG_REVID0r_REVID_MODELf_GET(revid) == EAGLE_MODEL) */ { 149 if(MAIN0_SERDESIDr_TECH_PROCf_GET(serdesid) == TSCE_TECH_PROC) { 150 *is_identified = 1; 151 } 152 } 153 } 154 } 155 rv = ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE; 156 return rv ; 157 } 158 159 160 int tsce_core_info_get(const phymod_core_access_t* phy, phymod_core_info_t* info) 161 { 162 uint32_t serdes_id; 163 PHYID2r_t id2; 164 PHYID3r_t id3; 165 char core_name[15]; 166 const phymod_access_t *pm_acc = &phy->access; 167 168 PHYMOD_IF_ERR_RETURN 169 (temod_revid_read(&phy->access, &serdes_id)); 170 171 info->serdes_id = serdes_id; 172 if ((serdes_id & 0x3f) == TSCE4_MODEL) { 173 info->core_version = phymodCoreVersionTsce4A0; 174 PHYMOD_STRNCPY(core_name, "tsce4", PHYMOD_STRLEN("tsce4")+1); 175 } else { 176 info->core_version = phymodCoreVersionTsce12A0; 177 PHYMOD_STRNCPY(core_name, "tsce12", PHYMOD_STRLEN("tsce12")+1); 178 } 179 PHYMOD_IF_ERR_RETURN 180 (phymod_core_name_get(phy, serdes_id, core_name, info)); 181 182 PHYMOD_IF_ERR_RETURN(READ_PHYID2r(pm_acc, &id2)); 183 PHYMOD_IF_ERR_RETURN(READ_PHYID3r(pm_acc, &id3)); 184 185 info->phy_id0 = (uint16_t) id2.v[0]; 186 info->phy_id1 = (uint16_t) id3.v[0]; 187 188 return PHYMOD_E_NONE; 189 } 190 191 192 /* 193 * set lane swapping for core 194 * The tx swap is composed of PCS swap and after that the PMD swap. 195 * The rx swap is composed just by PCS swap 196 * 197 * lane_map_tx and lane_map_rx[lane=logic_lane] are logic-lane base. 198 * pcs_swap and register is logic_lane base. 199 * but pmd_tx_map and addr_index_swap (and registers) are physical lane base 200 */ 201 202 int tsce_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 203 { 204 uint32_t pcs_swap = 0 , pmd_swap = 0, lane; 205 uint32_t addr_index_swap = 0, pmd_tx_map =0; 206 207 if(lane_map->num_of_lanes != TSCE_NOF_LANES_IN_CORE){ 208 return PHYMOD_E_CONFIG; 209 } 210 for( lane = 0 ; lane < TSCE_NOF_LANES_IN_CORE ; lane++){ 211 if(lane_map->lane_map_rx[lane] >= TSCE_NOF_LANES_IN_CORE){ 212 return PHYMOD_E_CONFIG; 213 } 214 /* encode each lane as four bits */ 215 /* pcs_map[lane] = rx_map[lane] */ 216 pcs_swap += lane_map->lane_map_rx[lane]<<(lane*4); 217 } 218 219 for( lane = 0 ; lane < TSCE_NOF_LANES_IN_CORE ; lane++){ 220 if(lane_map->lane_map_tx[lane] >= TSCE_NOF_LANES_IN_CORE){ 221 return PHYMOD_E_CONFIG; 222 } 223 /* encode each lane as four bits. pmd_swap is logic base */ 224 /* considering the pcs lane swap: pmd_map[pcs_map[lane]] = tx_map[lane] */ 225 pmd_swap += lane_map->lane_map_tx[lane]<<(lane_map->lane_map_rx[lane]*4); 226 } 227 228 for( lane = 0 ; lane < TSCE_NOF_LANES_IN_CORE ; lane++){ 229 addr_index_swap |= (lane << 4*((pcs_swap >> lane*4) & 0xf)) ; 230 pmd_tx_map |= (lane << 4*((pmd_swap >> lane*4) & 0xf)) ; 231 } 232 if (!PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(core->device_op_mode)) { 233 PHYMOD_IF_ERR_RETURN(temod_pcs_lane_swap(&core->access, pcs_swap)); 234 235 PHYMOD_IF_ERR_RETURN 236 (temod_pmd_addr_lane_swap(&core->access, addr_index_swap)); 237 } 238 PHYMOD_IF_ERR_RETURN 239 (temod_pmd_lane_swap_tx(&core->access, pmd_tx_map)); 240 return PHYMOD_E_NONE; 241 } 242 243 244 int tsce_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 245 { 246 uint32_t pmd_swap = 0 , pcs_swap = 0, lane; 247 PHYMOD_IF_ERR_RETURN(temod_pcs_lane_swap_get(&core->access, &pcs_swap)); 248 PHYMOD_IF_ERR_RETURN(temod_pmd_lane_swap_tx_get(&core->access, &pmd_swap)); 249 for( lane = 0 ; lane < TSCE_NOF_LANES_IN_CORE ; lane++){ 250 /* deccode each lane from four bits */ 251 lane_map->lane_map_rx[lane] = (pcs_swap>>(lane*4)) & TSCE_LANE_SWAP_LANE_MASK; 252 /* considering the pcs lane swap: tx_map[lane] = pmd_map[pcs_map[lane]] */ 253 lane_map->lane_map_tx[lane] = (pmd_swap>>(lane_map->lane_map_rx[lane]*4)) & TSCE_LANE_SWAP_LANE_MASK; 254 } 255 lane_map->num_of_lanes = TSCE_NOF_LANES_IN_CORE; 256 return PHYMOD_E_NONE; 257 } 258 259 260 int tsce_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 261 { 262 263 /* Place your code here */ 264 265 266 return PHYMOD_E_NONE; 267 } 268 269 270 int tsce_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 271 { 272 return PHYMOD_E_UNAVAIL; 273 } 274 275 int tsce_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 276 { 277 278 /* 279 * It's O.K to use this code as is since the firmware CRC is already checked at 280 * at the time we load it. 281 */ 282 fw_info->fw_crc = tsce_ucode_crc; 283 fw_info->fw_version = tsce_ucode_ver; 284 return PHYMOD_E_NONE; 285 } 286 287 /* load tsce fw. the fw_loader parameter is valid just for external fw load */ 288 STATIC 289 int _tsce_core_firmware_load(const phymod_core_access_t* core, phymod_firmware_load_method_t load_method, phymod_firmware_loader_f fw_loader) 290 { 291 #ifndef TSCE_PMD_CRC_UCODE 292 phymod_core_firmware_info_t actual_fw; 293 #endif 294 295 296 switch(load_method){ 297 case phymodFirmwareLoadMethodInternal: 298 PHYMOD_IF_ERR_RETURN(eagle_tsc_ucode_mdio_load(&core->access, tsce_ucode, tsce_ucode_len)); 299 break; 300 case phymodFirmwareLoadMethodExternal: 301 PHYMOD_NULL_CHECK(fw_loader); 302 303 eagle_pram_flop_set(&core->access, 0x0); 304 305 PHYMOD_IF_ERR_RETURN(eagle_tsc_ucode_init(&core->access)); 306 307 PHYMOD_IF_ERR_RETURN 308 (temod_pram_abl_enable_set(&core->access,1)); 309 PHYMOD_IF_ERR_RETURN 310 (eagle_pram_firmware_enable(&core->access, 1)); 311 312 PHYMOD_IF_ERR_RETURN(fw_loader(core, tsce_ucode_len, tsce_ucode)); 313 314 PHYMOD_IF_ERR_RETURN 315 (eagle_pram_firmware_enable(&core->access, 0)); 316 PHYMOD_IF_ERR_RETURN 317 (temod_pram_abl_enable_set(&core->access,0)); 318 break; 319 case phymodFirmwareLoadMethodNone: 320 break; 321 default: 322 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), load_method)); 323 } 324 return PHYMOD_E_NONE; 325 } 326 327 int tsce_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config) 328 { 329 struct eagle_tsc_uc_core_config_st serdes_firmware_core_config; 330 PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config)); 331 serdes_firmware_core_config.field.core_cfg_from_pcs = fw_config.CoreConfigFromPCS; 332 serdes_firmware_core_config.field.vco_rate = fw_config.VcoRate; 333 PHYMOD_IF_ERR_RETURN(eagle_tsc_set_uc_core_config(&phy->access, serdes_firmware_core_config)); 334 return PHYMOD_E_NONE; 335 } 336 337 338 int tsce_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config) 339 { 340 struct eagle_tsc_uc_core_config_st serdes_firmware_core_config; 341 PHYMOD_IF_ERR_RETURN(eagle_tsc_get_uc_core_config(&phy->access, &serdes_firmware_core_config)); 342 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 343 fw_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs; 344 fw_config->VcoRate = serdes_firmware_core_config.field.vco_rate; 345 return PHYMOD_E_NONE; 346 } 347 348 349 int tsce_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 350 { 351 phymod_phy_access_t phy_copy; 352 int start_lane, num_lane, i; 353 354 PHYMOD_IF_ERR_RETURN 355 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 356 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 357 358 /*Hold the per lne soft reset bit*/ 359 for (i = 0; i < num_lane; i++) { 360 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 361 continue; 362 } 363 phy_copy.access.lane_mask = 1 << (start_lane + i); 364 PHYMOD_IF_ERR_RETURN 365 (eagle_lane_soft_reset_release(&phy_copy.access, 0)); 366 } 367 368 PHYMOD_IF_ERR_RETURN 369 (_tsce_phy_firmware_lane_config_set(phy, fw_config)); 370 /*Hold the per lne soft reset bit*/ 371 for (i = 0; i < num_lane; i++) { 372 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 373 continue; 374 } 375 phy_copy.access.lane_mask = 1 << (start_lane + i); 376 PHYMOD_IF_ERR_RETURN 377 (eagle_lane_soft_reset_release(&phy_copy.access, 1)); 378 } 379 380 PHYMOD_IF_ERR_RETURN 381 (temod_trigger_speed_change(&phy->access)); 382 383 return PHYMOD_E_NONE; 384 } 385 386 387 int tsce_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 388 { 389 struct eagle_tsc_uc_lane_config_st serdes_firmware_config; 390 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 391 392 PHYMOD_IF_ERR_RETURN(eagle_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config)); 393 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 394 fw_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs; 395 fw_config->AnEnabled = serdes_firmware_config.field.an_enabled; 396 fw_config->DfeOn = serdes_firmware_config.field.dfe_on; 397 fw_config->ForceBrDfe = serdes_firmware_config.field.force_brdfe_on; 398 fw_config->Cl72AutoPolEn = serdes_firmware_config.field.cl72_auto_polarity_en; 399 fw_config->Cl72RestTO = serdes_firmware_config.field.cl72_restart_timeout_en; 400 fw_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis; 401 fw_config->UnreliableLos = serdes_firmware_config.field.unreliable_los; 402 fw_config->MediaType = serdes_firmware_config.field.media_type; 403 fw_config->Cl72AutoPolEn = serdes_firmware_config.field.cl72_auto_polarity_en; 404 fw_config->Cl72RestTO = serdes_firmware_config.field.cl72_restart_timeout_en; 405 406 return PHYMOD_E_NONE; 407 } 408 409 /* reset pll sequencer 410 * flags - unused parameter 411 */ 412 int tsce_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 413 { 414 switch (operation) { 415 case phymodSeqOpStop: 416 PHYMOD_IF_ERR_RETURN 417 (temod_pll_sequencer_control(&core->access, 0)); 418 break; 419 case phymodSeqOpStart: 420 PHYMOD_IF_ERR_RETURN 421 (temod_pll_sequencer_control(&core->access, 1)); 422 423 /* PHYMOD_IF_ERR_RETURN 424 (temod_pll_lock_wait(&core->access, 250000)); */ 425 break; 426 case phymodSeqOpRestart: 427 PHYMOD_IF_ERR_RETURN 428 (temod_pll_sequencer_control(&core->access, 0)); 429 430 PHYMOD_IF_ERR_RETURN 431 (temod_pll_sequencer_control(&core->access, 1)); 432 433 /* PHYMOD_IF_ERR_RETURN 434 (temod_pll_lock_wait(&core->access, 250000)); */ 435 break; 436 default: 437 return PHYMOD_E_UNAVAIL; 438 break; 439 } 440 return PHYMOD_E_NONE; 441 } 442 443 int tsce_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout) 444 { 445 switch(event){ 446 case phymodCoreEventPllLock: 447 /* PHYMOD_IF_ERR_RETURN(temod_pll_lock_wait(&core->access, timeout)); */ 448 break; 449 default: 450 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal wait event %u"), event)); 451 } 452 return PHYMOD_E_NONE; 453 } 454 455 int tsce_phy_pll_multiplier_get(const phymod_phy_access_t* core, uint32_t* pll_multiplier) 456 { 457 return PHYMOD_E_NONE; 458 } 459 460 461 /* reset rx sequencer 462 * flags - unused parameter 463 */ 464 int tsce_phy_rx_restart(const phymod_phy_access_t* phy) 465 { 466 PHYMOD_IF_ERR_RETURN(eagle_tsc_rx_restart(&phy->access, 1)); 467 return PHYMOD_E_NONE; 468 } 469 470 471 int tsce_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 472 { 473 PHYMOD_IF_ERR_RETURN 474 (temod_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity)); 475 return PHYMOD_E_NONE; 476 } 477 478 479 int tsce_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 480 { 481 PHYMOD_IF_ERR_RETURN 482 (temod_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity)); 483 return PHYMOD_E_NONE; 484 } 485 486 STATIC 487 int _tsce_phy_drivermode_phymod_to_tier1(int8_t phymod_drivermode, int8_t* drivermode) 488 { 489 switch (phymod_drivermode) { 490 case phymodTxDriverModeDefault: 491 *drivermode = DM_DEFAULT; 492 break; 493 case phymodTxDriverModeHalfAmpHiImped: 494 *drivermode = DM_HALF_AMPLITUDE_HI_IMPED; 495 break; 496 case phymodTxDriverModeHalfAmp: 497 *drivermode = DM_HALF_AMPLITUDE; 498 break; 499 case phymodTxDriverModeNotSupported: 500 *drivermode = DM_NOT_SUPPORTED; 501 break; 502 default: 503 return PHYMOD_E_PARAM; 504 } 505 return PHYMOD_E_NONE; 506 507 } 508 509 STATIC 510 int _tsce_phy_drivermode_tier1_to_phymod(int8_t drivermode, int8_t* phymod_drivermode) 511 { 512 switch (drivermode) { 513 case DM_DEFAULT: 514 *phymod_drivermode = phymodTxDriverModeDefault; 515 break; 516 case DM_HALF_AMPLITUDE_HI_IMPED: 517 *phymod_drivermode = phymodTxDriverModeHalfAmpHiImped; 518 break; 519 case DM_HALF_AMPLITUDE: 520 *phymod_drivermode = phymodTxDriverModeHalfAmp; 521 break; 522 case DM_NOT_SUPPORTED: 523 *phymod_drivermode = phymodTxDriverModeNotSupported; 524 break; 525 default: 526 return PHYMOD_E_INTERNAL; 527 } 528 return PHYMOD_E_NONE; 529 530 } 531 532 int tsce_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 533 { 534 int8_t drivermode; 535 536 537 PHYMOD_IF_ERR_RETURN 538 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre)); 539 PHYMOD_IF_ERR_RETURN 540 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main)); 541 PHYMOD_IF_ERR_RETURN 542 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post)); 543 PHYMOD_IF_ERR_RETURN 544 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2)); 545 PHYMOD_IF_ERR_RETURN 546 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3)); 547 PHYMOD_IF_ERR_RETURN 548 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_AMP, (int8_t)tx->amp)); 549 if((tx->drivermode != -1) && 550 (phy->device_op_mode & PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE)) { 551 PHYMOD_IF_ERR_RETURN 552 (_tsce_phy_drivermode_phymod_to_tier1(tx->drivermode, &drivermode)); 553 PHYMOD_IF_ERR_RETURN 554 (eagle_tsc_write_tx_afe(&phy->access, TX_AFE_DRIVERMODE, drivermode)); 555 } 556 return PHYMOD_E_NONE; 557 } 558 559 int tsce_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 560 { 561 int8_t drivermode = 0; 562 int8_t value = 0; 563 564 PHYMOD_IF_ERR_RETURN 565 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_PRE, &value)); 566 tx->pre = value; 567 PHYMOD_IF_ERR_RETURN 568 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_MAIN, &value)); 569 tx->main = value; 570 PHYMOD_IF_ERR_RETURN 571 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_POST1, &value)); 572 tx->post = value; 573 PHYMOD_IF_ERR_RETURN 574 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_POST2, &value)); 575 tx->post2 = value; 576 PHYMOD_IF_ERR_RETURN 577 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_POST3, &value)); 578 tx->post2 = value; 579 PHYMOD_IF_ERR_RETURN 580 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_AMP, &value)); 581 tx->amp = value; 582 PHYMOD_IF_ERR_RETURN 583 (eagle_tsc_read_tx_afe(&phy->access, TX_AFE_DRIVERMODE, &drivermode)); 584 PHYMOD_IF_ERR_RETURN 585 (_tsce_phy_drivermode_tier1_to_phymod(drivermode, &value)); 586 tx->drivermode = value; 587 588 return PHYMOD_E_NONE; 589 } 590 591 int tsce_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 592 { 593 PHYMOD_IF_ERR_RETURN 594 (eagle_tsc_tx_pi_freq_override(&phy->access, 595 tx_override->phase_interpolator.enable, 596 tx_override->phase_interpolator.value)); 597 return PHYMOD_E_NONE; 598 } 599 600 int tsce_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 601 { 602 int16_t pi_value; 603 604 PHYMOD_IF_ERR_RETURN 605 (eagle_tx_pi_control_get(&phy->access, &pi_value)); 606 607 tx_override->phase_interpolator.value = (int32_t) pi_value; 608 609 return PHYMOD_E_NONE; 610 } 611 612 613 int tsce_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 614 { 615 uint32_t i; 616 uint8_t uc_lane_stopped; 617 phymod_phy_access_t pm_phy_copy; 618 int start_lane, num_lane, k; 619 620 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 621 /* next program the tx fir taps and driver current based on the input */ 622 PHYMOD_IF_ERR_RETURN 623 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 624 625 /* params check */ 626 if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCE_NOF_DFES)){ 627 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps)); 628 } 629 630 for (k = 0; k < num_lane; k++) { 631 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + k)) { 632 continue; 633 } 634 pm_phy_copy.access.lane_mask = 1 << (start_lane + k); 635 636 /*vga set*/ 637 /* first check if uc lane is stopped already */ 638 PHYMOD_IF_ERR_RETURN(eagle_tsc_stop_uc_lane_status(&pm_phy_copy.access, (uint8_t *) &uc_lane_stopped)); 639 if (!uc_lane_stopped) { 640 PHYMOD_IF_ERR_RETURN(eagle_tsc_stop_rx_adaptation(&pm_phy_copy.access, 1)); 641 } 642 PHYMOD_IF_ERR_RETURN(eagle_tsc_stop_rx_adaptation(&pm_phy_copy.access, 1)); 643 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_VGA, rx->vga.value)); 644 /* dfe set */ 645 for (i = 0 ; i < rx->num_of_dfe_taps ; i++){ 646 switch (i) { 647 case 0: 648 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&phy->access, RX_AFE_DFE1, rx->dfe[i].value)); 649 break; 650 case 1: 651 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&phy->access, RX_AFE_DFE2, rx->dfe[i].value)); 652 break; 653 case 2: 654 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&phy->access, RX_AFE_DFE3, rx->dfe[i].value)); 655 break; 656 case 3: 657 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&phy->access, RX_AFE_DFE4, rx->dfe[i].value)); 658 break; 659 case 4: 660 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&phy->access, RX_AFE_DFE5, rx->dfe[i].value)); 661 break; 662 default: 663 return PHYMOD_E_PARAM; 664 } 665 } 666 /*peaking filter set*/ 667 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF, rx->peaking_filter.value)); 668 669 /* low freq peak filter */ 670 PHYMOD_IF_ERR_RETURN(eagle_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF2, (int8_t)rx->low_freq_peaking_filter.value)); 671 672 } 673 return PHYMOD_E_NONE; 674 } 675 676 677 int tsce_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 678 { 679 int8_t tmpData; 680 681 PHYMOD_IF_ERR_RETURN 682 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_PF, &tmpData)); 683 rx->peaking_filter.value = tmpData; 684 PHYMOD_IF_ERR_RETURN 685 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_PF2, &tmpData)); 686 rx->low_freq_peaking_filter.value = tmpData; 687 PHYMOD_IF_ERR_RETURN 688 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_VGA,&tmpData)); 689 rx->vga.value = tmpData; 690 PHYMOD_IF_ERR_RETURN 691 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_DFE1,&tmpData)); 692 rx->dfe[0].value = tmpData; 693 PHYMOD_IF_ERR_RETURN 694 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_DFE2,&tmpData)); 695 rx->dfe[1].value = tmpData; 696 PHYMOD_IF_ERR_RETURN 697 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_DFE3, &tmpData)); 698 rx->dfe[2].value = tmpData; 699 PHYMOD_IF_ERR_RETURN 700 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_DFE4,&tmpData)); 701 rx->dfe[3].value = tmpData; 702 PHYMOD_IF_ERR_RETURN 703 (eagle_tsc_read_rx_afe(&phy->access, RX_AFE_DFE5,&tmpData)); 704 rx->dfe[4].value = tmpData; 705 706 rx->num_of_dfe_taps = 5; 707 rx->dfe[0].enable = 1; 708 rx->dfe[1].enable = 1; 709 rx->dfe[2].enable = 1; 710 rx->dfe[3].enable = 1; 711 rx->dfe[4].enable = 1; 712 rx->vga.enable = 1; 713 rx->low_freq_peaking_filter.enable = 1; 714 rx->peaking_filter.enable = 1; 715 716 return PHYMOD_E_NONE; 717 } 718 719 720 int tsce_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 721 { 722 723 724 725 /* Place your code here */ 726 727 728 return PHYMOD_E_NONE; 729 730 731 } 732 733 734 int tsce_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 735 { 736 737 738 739 /* Place your code here */ 740 741 742 return PHYMOD_E_NONE; 743 744 745 } 746 747 748 int tsce_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 749 { 750 phymod_phy_access_t pm_phy_copy; 751 int start_lane, num_lane, i; 752 753 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 754 /* next program the tx fir taps and driver current based on the input */ 755 PHYMOD_IF_ERR_RETURN 756 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 757 758 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) { 759 for (i = 0; i < num_lane; i++) { 760 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 761 continue; 762 } 763 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 764 PHYMOD_IF_ERR_RETURN(temod_port_enable_set(&pm_phy_copy.access, 0)); 765 } 766 } 767 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) { 768 for (i = 0; i < num_lane; i++) { 769 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 770 continue; 771 } 772 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 773 PHYMOD_IF_ERR_RETURN(temod_port_enable_set(&pm_phy_copy.access, 1)); 774 } 775 } 776 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) { 777 /* disable tx on the PMD side */ 778 PHYMOD_IF_ERR_RETURN(eagle_tsc_tx_disable(&phy->access, 1)); 779 } 780 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) { 781 /* enable tx on the PMD side */ 782 PHYMOD_IF_ERR_RETURN(eagle_tsc_tx_disable(&phy->access, 0)); 783 } 784 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) { 785 /* disable rx on the PMD side */ 786 PHYMOD_IF_ERR_RETURN(temod_rx_squelch_set(&phy->access, 1)); 787 } 788 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) { 789 /* enable rx on the PMD side */ 790 PHYMOD_IF_ERR_RETURN(temod_rx_squelch_set(&phy->access, 0)); 791 } 792 return PHYMOD_E_NONE; 793 } 794 795 int tsce_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 796 { 797 int enable; 798 uint32_t lb_enable; 799 phymod_phy_access_t pm_phy_copy; 800 int start_lane, num_lane; 801 802 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 803 /* next program the tx fir taps and driver current based on the input */ 804 PHYMOD_IF_ERR_RETURN 805 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 806 807 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 808 809 PHYMOD_IF_ERR_RETURN(temod_rx_squelch_get(&pm_phy_copy.access, &enable)); 810 811 /* next check if PMD loopback is on */ 812 if (enable) { 813 PHYMOD_IF_ERR_RETURN(eagle_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 814 if (lb_enable) enable = 0; 815 } 816 817 power->rx = (enable == 1)? phymodPowerOff: phymodPowerOn; 818 /* Commented the following line. Because if in PMD loopback mode, we squelch the 819 xmit, and we should still see the correct port status */ 820 /* PHYMOD_IF_ERR_RETURN(temod_tx_squelch_get(&pm_phy_copy.access, &enable)); */ 821 power->tx = (enable == 1)? phymodPowerOff: phymodPowerOn; 822 return PHYMOD_E_NONE; 823 } 824 825 int tsce_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 826 { 827 switch (tx_control) { 828 case phymodTxTrafficDisable: 829 PHYMOD_IF_ERR_RETURN(temod_tx_lane_control_set(&phy->access, TEMOD_TX_LANE_TRAFFIC_DISABLE)); 830 break; 831 case phymodTxTrafficEnable: 832 PHYMOD_IF_ERR_RETURN(temod_tx_lane_control_set(&phy->access, TEMOD_TX_LANE_TRAFFIC_ENABLE)); 833 break; 834 case phymodTxReset: 835 PHYMOD_IF_ERR_RETURN(temod_tx_lane_control_set(&phy->access, TEMOD_TX_LANE_RESET)); 836 break; 837 case phymodTxSquelchOn: 838 PHYMOD_IF_ERR_RETURN(temod_tx_squelch_set(&phy->access, 1)); 839 break; 840 case phymodTxSquelchOff: 841 PHYMOD_IF_ERR_RETURN(temod_tx_squelch_set(&phy->access, 0)); 842 break; 843 default: 844 break; 845 } 846 return PHYMOD_E_NONE; 847 } 848 849 int tsce_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 850 { 851 int enable, reset, tx_lane; 852 uint32_t lb_enable; 853 phymod_phy_access_t pm_phy_copy; 854 int start_lane, num_lane; 855 856 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 857 /* next program the tx fir taps and driver current based on the input */ 858 PHYMOD_IF_ERR_RETURN 859 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 860 861 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 862 863 PHYMOD_IF_ERR_RETURN(temod_tx_squelch_get(&pm_phy_copy.access, &enable)); 864 865 /* next check if PMD loopback is on */ 866 if (enable) { 867 PHYMOD_IF_ERR_RETURN(eagle_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 868 if (lb_enable) enable = 0; 869 } 870 871 if(enable) { 872 *tx_control = phymodTxSquelchOn; 873 } else { 874 PHYMOD_IF_ERR_RETURN(temod_tx_lane_control_get(&pm_phy_copy.access, &reset, &tx_lane)); 875 if (!reset) { 876 *tx_control = phymodTxReset; 877 } else if (!tx_lane) { 878 *tx_control = phymodTxTrafficDisable; 879 } else { 880 *tx_control = phymodTxTrafficEnable; 881 } 882 } 883 return PHYMOD_E_NONE; 884 } 885 886 887 int tsce_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 888 { 889 phymod_phy_access_t pm_phy_copy; 890 int start_lane, num_lane, i; 891 892 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 893 /* next program the tx fir taps and driver current based on the input */ 894 PHYMOD_IF_ERR_RETURN 895 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 896 897 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 898 899 switch (rx_control) { 900 case phymodRxReset: 901 PHYMOD_IF_ERR_RETURN(temod_rx_lane_control_set(&phy->access, 1)); 902 break; 903 case phymodRxDisable: 904 PHYMOD_IF_ERR_RETURN(temod_rx_lane_control_set(&phy->access, 0)); 905 break; 906 case phymodRxSquelchOn: 907 for (i = 0; i < num_lane; i++) { 908 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 909 continue; 910 } 911 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 912 PHYMOD_IF_ERR_RETURN(temod_rx_squelch_set(&pm_phy_copy.access, 1)); 913 } 914 break; 915 case phymodRxSquelchOff: 916 for (i = 0; i < num_lane; i++) { 917 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 918 continue; 919 } 920 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 921 PHYMOD_IF_ERR_RETURN(temod_rx_squelch_set(&pm_phy_copy.access, 0)); 922 } 923 break; 924 default: 925 break; 926 } 927 return PHYMOD_E_NONE; 928 } 929 930 int tsce_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 931 { 932 int enable, reset; 933 uint32_t lb_enable; 934 phymod_phy_access_t pm_phy_copy; 935 int start_lane, num_lane; 936 937 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 938 /* next program the tx fir taps and driver current based on the input */ 939 PHYMOD_IF_ERR_RETURN 940 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 941 942 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 943 944 PHYMOD_IF_ERR_RETURN(temod_rx_squelch_get(&pm_phy_copy.access, &enable)); 945 /* next check if PMD loopback is on */ 946 if (enable) { 947 PHYMOD_IF_ERR_RETURN(eagle_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 948 if (lb_enable) enable = 0; 949 } 950 if(enable) { 951 *rx_control = phymodRxSquelchOn; 952 } else { 953 PHYMOD_IF_ERR_RETURN(temod_rx_lane_control_get(&pm_phy_copy.access, &reset)); 954 if (reset == 0) { 955 *rx_control = phymodRxReset; 956 } else { 957 *rx_control = phymodRxSquelchOff; 958 } 959 } 960 return PHYMOD_E_NONE; 961 } 962 963 int tsce_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 964 { 965 int i, start_lane, num_lane; 966 phymod_phy_access_t phy_copy; 967 if ((phy->access.lane_mask == 0xf) || 968 (phy->access.lane_mask == 0xc) || 969 (phy->access.lane_mask == 0x3)) { 970 PHYMOD_IF_ERR_RETURN(temod_fecmode_set(&phy->access, enable)); 971 } else { 972 PHYMOD_IF_ERR_RETURN 973 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 974 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 975 976 for (i = 0; i < num_lane; i++) { 977 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 978 continue; 979 } 980 phy_copy.access.lane_mask = 1 << (start_lane + i); 981 PHYMOD_IF_ERR_RETURN(temod_fecmode_set(&phy_copy.access, enable)); 982 } 983 } 984 return PHYMOD_E_NONE; 985 986 } 987 988 int tsce_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 989 { 990 PHYMOD_IF_ERR_RETURN(temod_fecmode_get(&phy->access, enable)); 991 return PHYMOD_E_NONE; 992 993 } 994 995 STATIC 996 int _tsce_pll_multiplier_get(uint32_t pll_div, uint32_t *pll_multiplier) 997 { 998 switch (pll_div) { 999 case 0x0: 1000 *pll_multiplier = 46; 1001 break; 1002 case 0x1: 1003 *pll_multiplier = 72; 1004 break; 1005 case TEMOD_PLL_MODE_DIV_40: 1006 *pll_multiplier = 40; 1007 break; 1008 case TEMOD_PLL_MODE_DIV_42: 1009 *pll_multiplier = 42; 1010 break; 1011 case TEMOD_PLL_MODE_DIV_48: 1012 *pll_multiplier = 48; 1013 break; 1014 case 0x5: 1015 *pll_multiplier = 50; 1016 break; 1017 case TEMOD_PLL_MODE_DIV_52: 1018 *pll_multiplier = 52; 1019 break; 1020 case TEMOD_PLL_MODE_DIV_54: 1021 *pll_multiplier = 54; 1022 break; 1023 case TEMOD_PLL_MODE_DIV_60: 1024 *pll_multiplier = 60; 1025 break; 1026 case TEMOD_PLL_MODE_DIV_64: 1027 *pll_multiplier = 64; 1028 break; 1029 case TEMOD_PLL_MODE_DIV_66: 1030 *pll_multiplier = 66; 1031 break; 1032 case 0xb: 1033 *pll_multiplier = 68; 1034 break; 1035 case TEMOD_PLL_MODE_DIV_70: 1036 *pll_multiplier = 70; 1037 break; 1038 case TEMOD_PLL_MODE_DIV_80: 1039 *pll_multiplier = 80; 1040 break; 1041 case TEMOD_PLL_MODE_DIV_92: 1042 *pll_multiplier = 92; 1043 break; 1044 case 0xf: 1045 *pll_multiplier = 100; 1046 break; 1047 case TEMOD_PLL_MODE_DIV_82P5: 1048 *pll_multiplier = 82; 1049 break; 1050 case TEMOD_PLL_MODE_DIV_87P5: 1051 *pll_multiplier = 87; 1052 break; 1053 default: 1054 *pll_multiplier = 66; 1055 break; 1056 } 1057 return PHYMOD_E_NONE; 1058 } 1059 1060 STATIC 1061 int _tsce_st_hto_interface_config_set(const temod_device_aux_modes_t *device, int lane_num, int speed_vec, uint32_t *new_pll_div, int16_t *os_mode) 1062 { 1063 int i, max_lane=4 ; 1064 *os_mode = -1 ; 1065 /* ST */ 1066 for(i=0;i<max_lane; i++) { 1067 if(device->st_hcd[i]==speed_vec){ 1068 *new_pll_div = device->st_pll_div[i]; 1069 *os_mode = device->st_os[i] ; 1070 break ; 1071 } 1072 } 1073 /* HTO */ 1074 if(device->hto_enable[lane_num]){ 1075 *new_pll_div = device->hto_pll_div[lane_num]; 1076 *os_mode = device->hto_os[lane_num] ; 1077 } 1078 return PHYMOD_E_NONE; 1079 } 1080 1081 1082 int tsce_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config) 1083 { 1084 uint32_t current_pll_div=0; 1085 uint32_t new_pll_div=0; 1086 uint16_t new_speed_vec=0; 1087 int16_t new_os_mode =-1; 1088 temod_spd_intfc_type spd_intf = TEMOD_SPD_ILLEGAL; 1089 phymod_phy_access_t pm_phy_copy; 1090 int start_lane=0, num_lane, i, pll_switch = 0; 1091 uint32_t os_dfeon=0; 1092 uint32_t scrambling_dis=0; 1093 uint32_t u_os_mode = 0; 1094 int dfe_adjust = -1 ; 1095 int lane_bkup; 1096 uint32_t pll_multiplier, vco_rate; 1097 enum eagle_tsc_pll_enum new_pll_div_enum; 1098 int cl72_allowed=0, cl72_req=0, high_vco_1G = 1; 1099 uint32_t mode_flip=0; 1100 phymod_phy_inf_config_t temp_config; 1101 temod_pll_mode_type pll_mode; 1102 uint16_t or_val=0; 1103 int rv = PHYMOD_E_NONE; 1104 1105 /* sc_table_entry exp_entry; RAVI */ 1106 phymod_firmware_lane_config_t firmware_lane_config; 1107 phymod_firmware_core_config_t firmware_core_config; 1108 1109 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1110 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 1111 PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config)); 1112 PHYMOD_MEMSET(&temp_config, 0x0, sizeof(temp_config)); 1113 1114 /* special mode */ 1115 if(flags&PHYMOD_INTF_F_SET_CORE_MAP_MODE) { 1116 int pmode = -1; 1117 /* 100g/120g port */ 1118 1119 /* mode flip, in TSC12 odd number ports are reverse. 1120 So it need to be swapped between 244 and 442 mode. 1121 343 is fine as those are symmertic. */ 1122 if( flags & PHYMOD_INTF_F_CORE_MAP_MODE_FLIP) { 1123 mode_flip = 1; 1124 } 1125 1126 if(PHYMOD_INTF_MODES_TRIPLE_CORE_GET(config)) { 1127 1128 if (PHYMOD_INTF_MODES_TC_442_GET(config)) { 1129 if(mode_flip){ 1130 pmode = 1; 1131 } else { 1132 pmode = 2 ; 1133 } 1134 } 1135 else if (PHYMOD_INTF_MODES_TC_244_GET(config)){ 1136 if(mode_flip) { 1137 pmode = 2 ; 1138 } else { 1139 pmode = 1 ; 1140 } 1141 } 1142 else if (PHYMOD_INTF_MODES_TC_343_GET(config)) 1143 pmode=0; 1144 1145 if(config->data_rate>=120000) { 1146 PHYMOD_IF_ERR_RETURN 1147 (temod_tsc12_control(&pm_phy_copy.access, 2, pmode)); 1148 } else if(config->data_rate>=100000) { 1149 PHYMOD_IF_ERR_RETURN 1150 (temod_tsc12_control(&pm_phy_copy.access, 1, pmode)); 1151 } else { 1152 PHYMOD_IF_ERR_RETURN 1153 (temod_tsc12_control(&pm_phy_copy.access, 0, pmode)); 1154 } 1155 } else { 1156 (temod_tsc12_control(&pm_phy_copy.access, 0, 0)); 1157 } 1158 return PHYMOD_E_NONE; 1159 } 1160 if (flags & PHYMOD_INTF_F_SET_SPD_TRIGGER) { 1161 if (config->data_rate >= 100000) { 1162 switch(config->data_rate) { 1163 case 100000: spd_intf = TEMOD_SPD_100G_CR10; break ; 1164 case 106000: 1165 case 107000: spd_intf = TEMOD_SPD_107G_HG_CR10; break ; 1166 case 120000: spd_intf = TEMOD_SPD_120G_CR12; break ; 1167 case 127000: spd_intf = TEMOD_SPD_127G_HG_CR12; break ; 1168 } 1169 PHYMOD_IF_ERR_RETURN 1170 (temod_set_spd_intf(&phy->access, spd_intf, 0)); 1171 } 1172 return PHYMOD_E_NONE; 1173 } 1174 if (flags & PHYMOD_INTF_F_SET_SPD_DISABLE) { 1175 if (config->data_rate >= 100000) { 1176 pm_phy_copy.access.lane_mask =0xf; 1177 num_lane = 0x4; 1178 start_lane = 0; 1179 PHYMOD_IF_ERR_RETURN 1180 (temod_disable_set(&pm_phy_copy.access)); 1181 /* next set the firmware lane config properly */ 1182 /* Hold the per lne soft reset bit */ 1183 for (i = 0; i < num_lane; i++) { 1184 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1185 PHYMOD_IF_ERR_RETURN 1186 (eagle_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1187 } 1188 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1189 PHYMOD_IF_ERR_RETURN 1190 (tsce_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 1191 1192 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1193 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1194 } else { 1195 if (config->interface_type == phymodInterfaceCR10) { 1196 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1197 } else { 1198 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1199 } 1200 } 1201 1202 for (i = 0; i < num_lane; i++) { 1203 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 1204 PHYMOD_IF_ERR_RETURN 1205 (_tsce_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1206 } 1207 1208 /* release the per lne soft reset bit */ 1209 for (i = 0; i < num_lane; i++) { 1210 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1211 PHYMOD_IF_ERR_RETURN 1212 (eagle_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1213 } 1214 } 1215 return PHYMOD_E_NONE; 1216 } 1217 /* end of special mode */ 1218 1219 if (flags & PHYMOD_INTF_F_SPEED_CONFIG_CLEAR) { 1220 1221 /* disable speed change trigger. */ 1222 PHYMOD_IF_ERR_RETURN 1223 (temod_disable_set(&phy->access)); 1224 1225 /* disable cl82_multi_pipe_mode, cl82_mld_phys_map to 1226 HW default 343 mode. */ 1227 PHYMOD_IF_ERR_RETURN 1228 (temod_tsc12_control(&phy->access, 0, 0)); 1229 1230 return PHYMOD_E_NONE; 1231 } 1232 1233 /* end of special mode */ 1234 firmware_lane_config.MediaType = 0; 1235 1236 /* next program the tx fir taps and driver current based on the input */ 1237 PHYMOD_IF_ERR_RETURN 1238 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1239 1240 /* reset pcs */ 1241 temod_disable_set(&phy->access); 1242 1243 /* Hold the per lne soft reset bit */ 1244 for (i = 0; i < num_lane; i++) { 1245 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1246 continue; 1247 } 1248 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1249 PHYMOD_IF_ERR_RETURN 1250 (eagle_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1251 } 1252 /* deassert pmd_tx_disable_pin_dis if it is set by ILKn */ 1253 /* remove pmd_tx_disable_pin_dis it may be asserted because of ILKn */ 1254 if(config->interface_type != phymodInterfaceBypass) { 1255 for (i = 0; i < num_lane; i++) { 1256 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1257 continue; 1258 } 1259 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1260 PHYMOD_IF_ERR_RETURN 1261 (eagle_pmd_tx_disable_pin_dis_set(&phy->access, 0)); 1262 } 1263 } 1264 /* disable CL72 */ 1265 for (i = 0; i < num_lane; i++) { 1266 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1267 continue; 1268 } 1269 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1270 PHYMOD_IF_ERR_RETURN 1271 (temod_clause72_control(&pm_phy_copy.access, 0|TEMOD_CL72_CONTROL_NO_TRIGER)) ; 1272 } 1273 1274 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1275 PHYMOD_IF_ERR_RETURN 1276 (tsce_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 1277 1278 /* make sure that an and config from pcs is off */ 1279 firmware_core_config.CoreConfigFromPCS = 0; 1280 firmware_lane_config.AnEnabled = 0; 1281 firmware_lane_config.LaneConfigFromPCS = 0; 1282 1283 /* and also make sure the cl72 restart timeout is enabled */ 1284 firmware_lane_config.Cl72RestTO = 1; 1285 firmware_lane_config.Cl72AutoPolEn = 0; 1286 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1287 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1288 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1289 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1290 } else { 1291 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1292 } 1293 1294 PHYMOD_IF_ERR_RETURN 1295 (temod_update_port_mode(&phy->access, (int *) &pll_switch)); 1296 1297 spd_intf = TEMOD_SPD_10_X1_SGMII; /* to prevent undefinded TEMOD_SPD_ILLEGAL accessing tables */ 1298 1299 /* find the speed */ 1300 if (config->interface_type == phymodInterfaceXFI) { 1301 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1302 } else if(config->interface_type == phymodInterfaceSFI) { 1303 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1304 } else if(config->interface_type == phymodInterfaceSFPDAC) { 1305 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1306 } else if(config->interface_type == phymodInterface1000X) { 1307 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1308 } else if(config->interface_type == phymodInterfaceSGMII) { 1309 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1310 } else if(config->interface_type == phymodInterfaceLR) { 1311 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1312 } else if(config->interface_type == phymodInterfaceSR) { 1313 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1314 } 1315 1316 cl72_req = (flags & (PHYMOD_INTF_F_CL72_REQUESTED_BY_CNFG|PHYMOD_INTF_F_CL72_REQUESTED_BY_API))?1:0; 1317 switch(config->data_rate) { 1318 case 10: 1319 if(config->pll_divider_req==40) { 1320 spd_intf = TEMOD_SPD_10_SGMII; 1321 high_vco_1G = 0; 1322 } else { 1323 spd_intf = TEMOD_SPD_10_X1_SGMII; 1324 } 1325 break; 1326 case 100: 1327 if(config->pll_divider_req==40) { 1328 spd_intf = TEMOD_SPD_100_SGMII; 1329 high_vco_1G = 0; 1330 } else { 1331 spd_intf = TEMOD_SPD_100_X1_SGMII; 1332 } 1333 break; 1334 case 1000: 1335 if(config->pll_divider_req==40) { 1336 spd_intf = TEMOD_SPD_1000_SGMII; 1337 high_vco_1G = 0; 1338 } else { 1339 spd_intf = TEMOD_SPD_1000_X1_SGMII; 1340 } 1341 break; 1342 case 2500: 1343 if(config->pll_divider_req==40) { 1344 spd_intf = TEMOD_SPD_2500; 1345 high_vco_1G = 0; 1346 } else { 1347 spd_intf = TEMOD_SPD_2500_X1; 1348 } 1349 break; 1350 case 5000: 1351 if (config->interface_type == phymodInterfaceRXAUI) { 1352 temod_credit_override_set(&phy->access, TEMOD_CREDIT_MAC, 0x4); 1353 new_os_mode = TEMOD_PMA_OS_MODE_2; 1354 if (PHYMOD_INTF_MODES_SCR_GET(config)) { 1355 spd_intf = TEMOD_SPD_10000_DXGXS_SCR; 1356 } else { 1357 spd_intf = TEMOD_SPD_10000_DXGXS; 1358 } 1359 } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1360 if(config->pll_divider_req==40) { 1361 spd_intf = TEMOD_SPD_5000; 1362 } else { 1363 spd_intf = TEMOD_SPD_5000_XFI; 1364 } 1365 } else { 1366 if(config->pll_divider_req==40) { 1367 spd_intf = TEMOD_SPD_5000; 1368 } else { 1369 spd_intf = TEMOD_SPD_5000_XFI; 1370 } 1371 } 1372 break; 1373 case 10000: 1374 if (config->interface_type == phymodInterfaceXAUI) { 1375 spd_intf = TEMOD_SPD_10000; 1376 } else if (config->interface_type == phymodInterfaceRXAUI) { 1377 /* There is no seperate speed Id defined for dual lane 10G 1378 * in HG mode. both HG/IEEE uses the same speed Id 1379 */ 1380 if (PHYMOD_INTF_MODES_SCR_GET(config)) { 1381 spd_intf = TEMOD_SPD_10000_DXGXS_SCR; 1382 } else { 1383 spd_intf = TEMOD_SPD_10000_DXGXS; 1384 } 1385 1386 } else if(config->interface_type == phymodInterfaceX2) { 1387 spd_intf = TEMOD_SPD_10000_X2; 1388 } else { 1389 cl72_allowed = 1 ; 1390 if (config->interface_type == phymodInterfaceSFI) { 1391 spd_intf = TEMOD_SPD_10000_XFI; 1392 dfe_adjust = 0 ; 1393 } else if(config->interface_type == phymodInterfaceXFI) { 1394 spd_intf = TEMOD_SPD_10000_XFI; 1395 dfe_adjust = 0 ; 1396 } else if(config->interface_type == phymodInterfaceXGMII) { 1397 spd_intf = TEMOD_SPD_10000; 1398 } else if(config->interface_type == phymodInterfaceKR) { 1399 spd_intf = TEMOD_SPD_10000_XFI; 1400 dfe_adjust = 1; 1401 } else { 1402 spd_intf = TEMOD_SPD_10000_XFI; 1403 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1404 dfe_adjust = 0 ; 1405 } 1406 } 1407 } 1408 break; 1409 case 10500: 1410 /* TEMOD_SPD_10500_HI is 4-lane port */ 1411 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1412 spd_intf = TEMOD_SPD_10500_HI; 1413 } else { 1414 spd_intf = TEMOD_SPD_10500_HI; 1415 } 1416 break; 1417 case 11000: 1418 cl72_allowed = 1 ; 1419 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1420 spd_intf = TEMOD_SPD_10600_XFI_HG; 1421 } else { 1422 spd_intf = TEMOD_SPD_10000_XFI; 1423 } 1424 break; 1425 case 12000: 1426 if(config->interface_type == phymodInterfaceRXAUI) { 1427 spd_intf = TEMOD_SPD_12773_HI_DXGXS; 1428 } else { 1429 cl72_allowed = 1 ; 1430 spd_intf = TEMOD_SPD_10000_XFI; 1431 if ((config->interface_type == phymodInterfaceSFI) || 1432 (config->interface_type == phymodInterfaceXFI)) { 1433 dfe_adjust = 0 ; 1434 } 1435 } 1436 break; 1437 case 13000: 1438 if(config->interface_type == phymodInterfaceRXAUI) { 1439 spd_intf = TEMOD_SPD_12773_DXGXS; 1440 /* 1441 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1442 spd_intf = TEMOD_SPD_12773_DXGXS; 1443 } else { 1444 spd_intf = TEMOD_SPD_12773_DXGXS; 1445 } 1446 */ 1447 } else { 1448 spd_intf = TEMOD_SPD_13000; 1449 } 1450 break; 1451 case 15000: 1452 spd_intf = TEMOD_SPD_15000; 1453 break; 1454 case 15750: 1455 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1456 spd_intf = TEMOD_SPD_15750_HI_DXGXS; 1457 } 1458 break; 1459 case 16000: 1460 spd_intf = TEMOD_SPD_16000; 1461 break; 1462 case 20000: 1463 if(config->interface_type == phymodInterfaceKR2 || 1464 config->interface_type == phymodInterfaceCR2) { 1465 cl72_allowed = 1 ; 1466 spd_intf = TEMOD_SPD_20G_MLD_DXGXS ; 1467 } else if(config->interface_type == phymodInterfaceRXAUI) { 1468 cl72_allowed = 1 ; 1469 spd_intf = TEMOD_SPD_20G_DXGXS; 1470 } else { 1471 if (PHYMOD_INTF_MODES_SCR_GET(config)) { 1472 spd_intf = TEMOD_SPD_20000_SCR; 1473 } else { 1474 spd_intf = TEMOD_SPD_20000; 1475 } 1476 } 1477 break; 1478 case 21000: 1479 if(config->interface_type == phymodInterfaceRXAUI) { 1480 spd_intf = TEMOD_SPD_20G_DXGXS; 1481 } else if(config->interface_type == phymodInterfaceKR2 || 1482 config->interface_type == phymodInterfaceCR2) { 1483 spd_intf = TEMOD_SPD_21G_HI_MLD_DXGXS; 1484 } else { 1485 spd_intf = TEMOD_SPD_21000; 1486 } 1487 break; 1488 case 25000: 1489 if (num_lane == 2) { 1490 cl72_allowed = 1 ; 1491 spd_intf = TEMOD_SPD_20G_MLD_DXGXS ; 1492 } else { 1493 spd_intf = TEMOD_SPD_25455 ; 1494 } 1495 break; 1496 case 25450: 1497 spd_intf = TEMOD_SPD_25455 ; 1498 break; 1499 case 30000: 1500 case 32000: 1501 spd_intf = TEMOD_SPD_31500; 1502 break; 1503 case 40000: 1504 cl72_allowed = 1 ; 1505 spd_intf = TEMOD_SPD_40G_XLAUI; 1506 if (config->interface_type == phymodInterfaceXLAUI) { 1507 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1508 dfe_adjust = 0 ; 1509 } else if(PHYMOD_INTF_MODES_FIBER_GET(config)) { 1510 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics ; 1511 dfe_adjust = 0 ; 1512 } else if(config->interface_type == phymodInterfaceCR4) { 1513 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable ; 1514 } else if (config->interface_type == phymodInterfaceKR4) { 1515 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1516 } else if((config->interface_type == phymodInterfaceXGMII) || PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1517 spd_intf = TEMOD_SPD_40G_X4; 1518 } else { 1519 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane ; 1520 } 1521 break; 1522 case 42000: 1523 cl72_allowed = 1 ; 1524 if ((config->interface_type == phymodInterfaceKR4) && 1525 PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1526 spd_intf = TEMOD_SPD_42G_XLAUI; 1527 }else if((config->interface_type == phymodInterfaceCR4) && 1528 PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1529 spd_intf = TEMOD_SPD_42G_XLAUI; 1530 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1531 }else if((config->interface_type == phymodInterfaceXGMII) || PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1532 spd_intf = TEMOD_SPD_40G_X4; 1533 } else { 1534 spd_intf = TEMOD_SPD_42G_XLAUI; 1535 } 1536 break; 1537 case 48000: 1538 cl72_allowed = 1 ; 1539 spd_intf = TEMOD_SPD_40G_XLAUI; 1540 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1541 dfe_adjust = 0 ; 1542 break; 1543 case 100000: 1544 cl72_allowed = 1 ; 1545 spd_intf = TEMOD_SPD_100G_CR10; 1546 break; 1547 case 106000: 1548 case 107000: 1549 cl72_allowed = 1 ; 1550 spd_intf = TEMOD_SPD_107G_HG_CR10; 1551 break; 1552 case 120000: 1553 cl72_allowed = 1 ; 1554 spd_intf = TEMOD_SPD_120G_CR12; 1555 break; 1556 case 127000: 1557 cl72_allowed = 1 ; 1558 spd_intf = TEMOD_SPD_127G_HG_CR12; 1559 break; 1560 default: 1561 break; 1562 } 1563 1564 /* need to decide if we need to set low VCO for 2.5G,1G or below */ 1565 if (!high_vco_1G) { 1566 PHYMOD_IF_ERR_RETURN 1567 (temod_cl37_high_vco_set(&pm_phy_copy.access, 0)); 1568 } 1569 1570 if(PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1571 PHYMOD_IF_ERR_RETURN 1572 (temod_encode_set(&phy->access, spd_intf, 1)); 1573 PHYMOD_IF_ERR_RETURN 1574 (temod_decode_set(&phy->access, spd_intf, 1)); 1575 } else { 1576 PHYMOD_IF_ERR_RETURN 1577 (temod_encode_set(&phy->access, spd_intf, 0)); 1578 PHYMOD_IF_ERR_RETURN 1579 (temod_decode_set(&phy->access, spd_intf, 0)); 1580 } 1581 1582 if(config->data_rate==10||config->data_rate==100|| 1583 config->data_rate==1000) { 1584 if (config->interface_type == phymodInterfaceSGMII) { 1585 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1586 } 1587 if (config->interface_type == phymodInterface1000X) { 1588 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1589 } 1590 } 1591 /* get the current PLL setting */ 1592 pm_phy_copy.access.lane_mask = 1 << start_lane; 1593 PHYMOD_IF_ERR_RETURN 1594 (temod_pll_config_get(&pm_phy_copy.access, &pll_mode)); 1595 current_pll_div = (uint32_t) pll_mode; 1596 1597 if(config->interface_type == phymodInterfaceBypass) { 1598 1599 rv = eagle_tsc_get_vco(config, &vco_rate, &new_pll_div_enum, &new_os_mode); 1600 /* eagle tier1 error codes are not compatible with SDK error codes 1601 * convert the eagle tier1 err code to PHYMOD error code 1602 */ 1603 if (rv != PHYMOD_E_NONE) { 1604 return PHYMOD_E_CONFIG; 1605 } 1606 1607 rv = eagle_tsc_get_pll_div_from_enum(new_pll_div_enum, &new_pll_div); 1608 if (rv != PHYMOD_E_NONE) { 1609 return PHYMOD_E_CONFIG; 1610 } 1611 1612 } else { 1613 1614 PHYMOD_IF_ERR_RETURN 1615 (temod_plldiv_lkup_get(&phy->access, spd_intf, config->ref_clock, &new_pll_div, &new_speed_vec)); 1616 1617 /* For 12.12G, data rate specified is 12000, and pll_div is set pll_mode_div_80 */ 1618 if (config->ref_clock == phymodRefClk156Mhz) { 1619 switch(config->data_rate) { 1620 case 11000: new_pll_div = TEMOD_PLL_MODE_DIV_70; break ; 1621 case 12000: new_pll_div = TEMOD_PLL_MODE_DIV_80; break ; 1622 case 21000: 1623 if (num_lane == 2) { 1624 new_pll_div = TEMOD_PLL_MODE_DIV_70; 1625 } 1626 break ; 1627 case 25000: 1628 if (num_lane == 2) { 1629 new_pll_div = TEMOD_PLL_MODE_DIV_80; 1630 } 1631 break ; 1632 case 42000: new_pll_div = TEMOD_PLL_MODE_DIV_70; break ; 1633 case 48000: new_pll_div = TEMOD_PLL_MODE_DIV_80; break ; 1634 case 106000: new_pll_div = TEMOD_PLL_MODE_DIV_70; break ; 1635 case 127000: new_pll_div = TEMOD_PLL_MODE_DIV_70; break ; 1636 default: break ; 1637 } 1638 } 1639 if (config->ref_clock == phymodRefClk125Mhz) { 1640 switch(config->data_rate) { 1641 case 11000: new_pll_div = TEMOD_PLL_MODE_DIV_87P5; break ; 1642 case 12000: new_pll_div = TEMOD_PLL_MODE_DIV_100; break ; 1643 case 21000: 1644 if (num_lane == 2) { 1645 new_pll_div = TEMOD_PLL_MODE_DIV_87P5; 1646 } 1647 break ; 1648 case 25000: 1649 if (num_lane == 2) { 1650 new_pll_div = TEMOD_PLL_MODE_DIV_100; 1651 } 1652 break ; 1653 case 42000: new_pll_div = TEMOD_PLL_MODE_DIV_87P5; break ; 1654 case 48000: new_pll_div = TEMOD_PLL_MODE_DIV_100; break ; 1655 case 106000: new_pll_div = TEMOD_PLL_MODE_DIV_87P5; break ; 1656 case 127000: new_pll_div = TEMOD_PLL_MODE_DIV_87P5; break ; 1657 default: break ; 1658 } 1659 } 1660 } 1661 1662 if(config->device_aux_modes !=NULL){ 1663 PHYMOD_IF_ERR_RETURN 1664 (_tsce_st_hto_interface_config_set(config->device_aux_modes, start_lane, new_speed_vec, &new_pll_div, &new_os_mode)) ; 1665 } 1666 1667 if(new_os_mode>=0) { 1668 u_os_mode = new_os_mode | TEMOD_OVERRIDE_CFG ; 1669 } else { 1670 u_os_mode = 0 ; 1671 } 1672 1673 1674 PHYMOD_IF_ERR_RETURN 1675 (temod_pmd_osmode_set(&phy->access, spd_intf, u_os_mode)); 1676 PHYMOD_IF_ERR_RETURN(temod_osdfe_on_lkup_get(&phy->access, spd_intf, &os_dfeon)); 1677 PHYMOD_IF_ERR_RETURN(temod_scrambling_dis_lkup_get(&phy->access, spd_intf, &scrambling_dis)); 1678 firmware_lane_config.DfeOn = 0; 1679 firmware_lane_config.ScramblingDisable = scrambling_dis; 1680 1681 if(PHYMOD_INTF_F_SCRAMBLE_FORCED_ON & flags) { 1682 firmware_lane_config.ScramblingDisable = 0 ; 1683 1684 or_val = 1; 1685 PHYMOD_IF_ERR_RETURN 1686 (temod_override_set(&phy->access, TEMOD_OVERRIDE_SCR_MODE , or_val)); 1687 PHYMOD_IF_ERR_RETURN 1688 (temod_override_set(&phy->access, TEMOD_OVERRIDE_DESCR_MODE, or_val)); 1689 } else if (PHYMOD_INTF_F_SCRAMBLE_FORCED_OFF & flags) { 1690 firmware_lane_config.ScramblingDisable = 1 ; 1691 1692 or_val = 0; 1693 PHYMOD_IF_ERR_RETURN 1694 (temod_override_set(&phy->access, TEMOD_OVERRIDE_SCR_MODE , or_val)); 1695 PHYMOD_IF_ERR_RETURN 1696 (temod_override_set(&phy->access, TEMOD_OVERRIDE_DESCR_MODE, or_val)); 1697 } else { 1698 /* Override scrambler settings in PCS when disable scrambler is needed*/ 1699 if (scrambling_dis){ 1700 or_val = 0; 1701 PHYMOD_IF_ERR_RETURN 1702 (temod_override_set(&phy->access, TEMOD_OVERRIDE_SCR_MODE , or_val)); 1703 PHYMOD_IF_ERR_RETURN 1704 (temod_override_set(&phy->access, TEMOD_OVERRIDE_DESCR_MODE, or_val)); 1705 } 1706 else { 1707 PHYMOD_IF_ERR_RETURN 1708 (temod_override_clear(&phy->access, TEMOD_OVERRIDE_SCR_MODE)); 1709 PHYMOD_IF_ERR_RETURN 1710 (temod_override_clear(&phy->access, TEMOD_OVERRIDE_DESCR_MODE)); 1711 } 1712 } 1713 1714 if(os_dfeon == 0x1) 1715 firmware_lane_config.DfeOn = 1; 1716 1717 if(dfe_adjust >=0) 1718 firmware_lane_config.DfeOn = dfe_adjust ; 1719 1720 /* the speed is not supported */ 1721 if (new_pll_div == TEMOD_PLL_MODE_DIV_ILLEGAL) { 1722 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 1723 (_PHYMOD_MSG("this speed %d is not supported at this ref clock %d"), 1724 config->data_rate, config->ref_clock)); 1725 } 1726 1727 /* if pll change is enabled. new_pll_div is the reg vector value */ 1728 if((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)){ 1729 /*Terminate the execution of the function*/ 1730 PHYMOD_DEBUG_WARN(("PLL has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled \n", 1731 (unsigned int)current_pll_div, (unsigned int)new_pll_div)); 1732 return PHYMOD_E_NONE; 1733 } 1734 1735 1736 /* pll switch is required and expected */ 1737 if((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) { 1738 /* phymod_access_t tmp_phy_access; */ 1739 1740 /* Change in PLL, so reset all the ports first. Check for TSC12 */ 1741 lane_bkup = pm_phy_copy.access.lane_mask; 1742 pm_phy_copy.access.lane_mask = 0xf; 1743 temod_disable_set(&pm_phy_copy.access); 1744 pm_phy_copy.access.lane_mask = lane_bkup; 1745 1746 /* tmp_phy_access = phy->access; */ 1747 1748 PHYMOD_IF_ERR_RETURN 1749 (eagle_core_soft_reset_release(&pm_phy_copy.access, 0)); 1750 1751 /* release the uc reset */ 1752 PHYMOD_IF_ERR_RETURN 1753 (eagle_uc_reset(&pm_phy_copy.access ,1)); 1754 1755 /* set the PLL divider */ 1756 PHYMOD_IF_ERR_RETURN 1757 (temod_pll_config_set(&pm_phy_copy.access, new_pll_div, config->ref_clock)); 1758 1759 PHYMOD_IF_ERR_RETURN 1760 (_tsce_pll_multiplier_get(new_pll_div, &pll_multiplier)); 1761 /* update the VCO rate properly */ 1762 switch (config->ref_clock) { 1763 case phymodRefClk156Mhz: 1764 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1765 break; 1766 case phymodRefClk125Mhz: 1767 vco_rate = pll_multiplier * 125; 1768 if ((pll_multiplier == 82) || (pll_multiplier == 87)) { 1769 vco_rate = pll_multiplier * 125 + 62; 1770 } 1771 break; 1772 default: 1773 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1774 break; 1775 } 1776 firmware_core_config.VcoRate = (vco_rate - 5750) / 250 + 1; 1777 1778 /* change the master port num to the current caller port */ 1779 PHYMOD_IF_ERR_RETURN 1780 (temod_master_port_num_set(&pm_phy_copy.access, start_lane)); 1781 1782 PHYMOD_IF_ERR_RETURN 1783 (temod_pll_reset_enable_set(&pm_phy_copy.access, 1)); 1784 1785 /* update the firmware config properly */ 1786 PHYMOD_IF_ERR_RETURN 1787 (tsce_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config)); 1788 PHYMOD_IF_ERR_RETURN 1789 (eagle_core_soft_reset_release(&pm_phy_copy.access, 1)); 1790 } 1791 1792 if(cl72_req&cl72_allowed){ 1793 for (i = 0; i < num_lane; i++) { 1794 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1795 continue; 1796 } 1797 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1798 PHYMOD_IF_ERR_RETURN 1799 (temod_clause72_control(&pm_phy_copy.access, 1|TEMOD_CL72_CONTROL_NO_TRIGER)) ; 1800 } 1801 } 1802 1803 if(config->interface_type != phymodInterfaceBypass) { 1804 if(flags & PHYMOD_INTF_F_SET_SPD_NO_TRIGGER) { 1805 (temod_set_spd_intf(&phy->access, spd_intf, 1)); 1806 } else { 1807 PHYMOD_IF_ERR_RETURN 1808 (temod_set_spd_intf(&phy->access, spd_intf, 0)); 1809 } 1810 } 1811 1812 /* TX Params are set outside this func */ 1813 /* change TX parameters if enabled */ 1814 /* if((PHYMOD_IF_F_DONT_OVERIDE_TX_PARAMS & flags) == 0) 1815 PHYMOD_IF_ERR_RETURN 1816 (tsce_phy_media_type_tx_get(phy, phymodMediaTypeMid, &tx_params)); 1817 PHYMOD_IF_ERR_RETURN 1818 (tsce_phy_tx_set(phy, &tx_params)); 1819 */ 1820 1821 for (i = 0; i < num_lane; i++) { 1822 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1823 continue; 1824 } 1825 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 1826 PHYMOD_IF_ERR_RETURN 1827 (_tsce_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1828 } 1829 1830 /* release the per lne soft reset bit */ 1831 for (i = 0; i < num_lane; i++) { 1832 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1833 continue; 1834 } 1835 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1836 PHYMOD_IF_ERR_RETURN 1837 (eagle_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1838 } 1839 1840 return PHYMOD_E_NONE; 1841 } 1842 1843 STATIC 1844 int _tsce_speed_id_interface_config_get(const phymod_phy_access_t* phy, int speed_id, 1845 phymod_phy_inf_config_t* config, uint16_t an_enable, 1846 phymod_firmware_lane_config_t *lane_config) 1847 { 1848 int ilkn_set; 1849 int osr_mode; 1850 int hg_enable = 0; 1851 uint32_t vco_rate; 1852 uint32_t pll_multiplier; 1853 uint32_t current_pll_div=0; 1854 int u_os_mode = 0xff; 1855 uint32_t actual_osr, actual_osr_rem; 1856 phymod_osr_mode_t osr_mode_enum; 1857 temod_pll_mode_type pll_mode; 1858 1859 if (config->ref_clock == phymodRefClk125Mhz) { 1860 PHYMOD_IF_ERR_RETURN 1861 (temod_pll_config_get(&phy->access, &pll_mode)); 1862 current_pll_div = (uint32_t) pll_mode; 1863 } else { 1864 PHYMOD_IF_ERR_RETURN 1865 (temod_get_plldiv(&phy->access, ¤t_pll_div)); 1866 } 1867 1868 PHYMOD_IF_ERR_RETURN 1869 (temod_hg_enable_get(&phy->access, &hg_enable)); 1870 1871 PHYMOD_IF_ERR_RETURN(temod_pcs_ilkn_chk(&phy->access, &ilkn_set)); 1872 if(ilkn_set) { 1873 config->interface_type = phymodInterfaceBypass; 1874 PHYMOD_IF_ERR_RETURN 1875 (_tsce_pll_multiplier_get(current_pll_div, &pll_multiplier)); 1876 PHYMOD_IF_ERR_RETURN 1877 (eagle_osr_mode_get(&phy->access, &osr_mode)); 1878 1879 switch (config->ref_clock) { 1880 case phymodRefClk156Mhz: 1881 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1882 break; 1883 case phymodRefClk125Mhz: 1884 vco_rate = pll_multiplier * 125; 1885 break; 1886 default: 1887 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1888 break; 1889 } 1890 1891 PHYMOD_IF_ERR_RETURN(eagle_osr_mode_to_enum(osr_mode, &osr_mode_enum)); 1892 PHYMOD_IF_ERR_RETURN(phymod_osr_mode_to_actual_os(osr_mode_enum, &actual_osr, &actual_osr_rem)); 1893 config->data_rate = vco_rate/actual_osr; 1894 } else { 1895 1896 switch (speed_id) { 1897 case 0x1: 1898 config->data_rate = 10; 1899 config->interface_type = phymodInterfaceSGMII; 1900 break; 1901 case 0x2: 1902 config->data_rate = 100; 1903 config->interface_type = phymodInterfaceSGMII; 1904 break; 1905 case 0x3: 1906 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 1907 config->interface_type = phymodInterface1000X; 1908 } else { 1909 config->interface_type = phymodInterfaceSGMII; 1910 } 1911 config->data_rate = 1000; 1912 break; 1913 case 0x4: 1914 config->data_rate = 1000; 1915 config->interface_type = phymodInterfaceCX; 1916 break; 1917 case 0x5: 1918 config->data_rate = 1000; 1919 config->interface_type = phymodInterfaceKX; 1920 break; 1921 case 0x6: 1922 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 1923 config->interface_type = phymodInterfaceSR; 1924 } else { 1925 config->interface_type = phymodInterfaceSGMII; 1926 } 1927 config->data_rate = 2500; 1928 break; 1929 case 0x7: 1930 config->data_rate = 5000; 1931 config->interface_type = phymodInterfaceSR; 1932 break; 1933 case 0x8: 1934 config->data_rate = 10000; 1935 config->interface_type = phymodInterfaceCX4; 1936 break; 1937 case 0x9: 1938 config->data_rate = 10000; 1939 config->interface_type = phymodInterfaceKX4; 1940 break; 1941 case 0xa: 1942 config->data_rate = 10000; 1943 config->interface_type = phymodInterfaceXGMII; 1944 break; 1945 case 0xb: 1946 config->data_rate = 13000; 1947 config->interface_type = phymodInterfaceXGMII; 1948 break; 1949 case 0xc: 1950 config->data_rate = 15000; 1951 config->interface_type = phymodInterfaceXGMII; 1952 break; 1953 case 0xd: 1954 config->data_rate = 16000; 1955 config->interface_type = phymodInterfaceXGMII; 1956 break; 1957 case 0xe: 1958 config->data_rate = 20000; 1959 config->interface_type = phymodInterfaceCX4; 1960 break; 1961 case 0xf: 1962 PHYMOD_IF_ERR_RETURN 1963 (temod_pmd_osmode_get(&phy->access, &u_os_mode)); 1964 if(u_os_mode == TEMOD_PMA_OS_MODE_2) { 1965 config->data_rate = 5000; 1966 config->interface_type = phymodInterfaceRXAUI; 1967 } else { 1968 config->data_rate = 10000; 1969 config->interface_type = phymodInterfaceRXAUI; 1970 } 1971 break; 1972 case 0x10: 1973 PHYMOD_IF_ERR_RETURN 1974 (temod_pmd_osmode_get(&phy->access, &u_os_mode)); 1975 if(u_os_mode == TEMOD_PMA_OS_MODE_2) { 1976 config->data_rate = 5000; 1977 config->interface_type = phymodInterfaceRXAUI; 1978 } else { 1979 config->data_rate = 10000; 1980 config->interface_type = phymodInterfaceX2; 1981 } 1982 break; 1983 case 0x11: 1984 config->data_rate = 20000; 1985 config->interface_type = phymodInterfaceXGMII; 1986 break; 1987 case 0x12: 1988 config->data_rate = 10500; 1989 config->interface_type = phymodInterfaceX2; 1990 break; 1991 case 0x13: 1992 config->data_rate = 21000; 1993 config->interface_type = phymodInterfaceCX4; 1994 break; 1995 case 0x14: 1996 config->data_rate = 13000; /* round up from 12700 */ 1997 config->interface_type = phymodInterfaceX2; 1998 break; 1999 case 0x15: 2000 config->data_rate = 25450; 2001 config->interface_type = phymodInterfaceKR4; 2002 break; 2003 case 0x16: 2004 config->data_rate = 15750; 2005 config->interface_type = phymodInterfaceX2; 2006 break; 2007 case 0x17: 2008 config->data_rate = 31500; 2009 config->interface_type = phymodInterfaceXGMII; 2010 break; 2011 case 0x18: 2012 config->data_rate = 31500; 2013 config->interface_type = phymodInterfaceKR4; 2014 break; 2015 case 0x19: 2016 config->data_rate = 20000; 2017 config->interface_type = phymodInterfaceCX2; 2018 break; 2019 case 0x1a: 2020 if (config->ref_clock == phymodRefClk125Mhz) { 2021 if(current_pll_div==TEMOD_PLL_MODE_DIV_87P5) { 2022 config->data_rate = 21000; 2023 } else { 2024 config->data_rate = 20000; 2025 } 2026 } else { 2027 if(current_pll_div==TEMOD_PLL_MODE_DIV_70) { 2028 config->data_rate = 21000; 2029 } else { 2030 config->data_rate = 20000; 2031 } 2032 } 2033 config->interface_type = phymodInterfaceX2; 2034 break; 2035 case 0x1b: /* digital_operationSpeeds_SPEED_40G_X4; BRCM */ 2036 if (config->ref_clock == phymodRefClk125Mhz) { 2037 if(current_pll_div==TEMOD_PLL_MODE_DIV_87P5) { 2038 config->data_rate = 42000; 2039 } else { 2040 config->data_rate = 40000; 2041 } 2042 } else { 2043 if(current_pll_div==TEMOD_PLL_MODE_DIV_70) { 2044 config->data_rate = 42000; 2045 } else { 2046 config->data_rate = 40000; 2047 } 2048 } 2049 config->interface_type = phymodInterfaceXGMII; 2050 break; 2051 case 0x1c: 2052 if (config->ref_clock == phymodRefClk125Mhz) { 2053 if(current_pll_div==TEMOD_PLL_MODE_DIV_100) { 2054 config->data_rate = 12000; 2055 } else if(current_pll_div==TEMOD_PLL_MODE_DIV_87P5) { 2056 config->data_rate = 11000; 2057 } else { 2058 config->data_rate = 10000; 2059 } 2060 } else { 2061 if(current_pll_div==TEMOD_PLL_MODE_DIV_80) { 2062 config->data_rate = 12000; 2063 } else if(current_pll_div==TEMOD_PLL_MODE_DIV_70) { 2064 config->data_rate = 11000; 2065 } else { 2066 config->data_rate = 10000; 2067 } 2068 } 2069 config->interface_type = phymodInterfaceKR; 2070 if(!an_enable) { 2071 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 2072 if(config->interface_type == phymodInterfaceSR) { 2073 config->interface_type = phymodInterfaceSR ; 2074 } else { 2075 config->interface_type = phymodInterfaceSFI ; 2076 } 2077 } else if (lane_config->MediaType == phymodFirmwareMediaTypeCopperCable) { 2078 config->interface_type = phymodInterfaceCR ; 2079 } else if (lane_config->DfeOn == 1) { 2080 config->interface_type = phymodInterfaceKR; 2081 } else { 2082 config->interface_type = phymodInterfaceXFI ; 2083 } 2084 } 2085 break; 2086 case 0x1d: 2087 config->data_rate = 11000; 2088 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 2089 if(config->interface_type == phymodInterfaceSR) { 2090 config->interface_type = phymodInterfaceSR ; 2091 } else { 2092 config->interface_type = phymodInterfaceSFI ; 2093 } 2094 } else { 2095 config->interface_type = phymodInterfaceXFI ; 2096 } 2097 break; 2098 case 0x1e: 2099 if (config->ref_clock == phymodRefClk125Mhz) { 2100 if(current_pll_div == TEMOD_PLL_MODE_DIV_100) { 2101 config->data_rate = 25000; 2102 } else if(current_pll_div == TEMOD_PLL_MODE_DIV_87P5) { 2103 config->data_rate = 21000; 2104 } else { 2105 config->data_rate = 20000; 2106 } 2107 } else { 2108 if(current_pll_div == TEMOD_PLL_MODE_DIV_80) { 2109 config->data_rate = 25000; 2110 } else if(current_pll_div == TEMOD_PLL_MODE_DIV_70) { 2111 config->data_rate = 21000; 2112 } else { 2113 config->data_rate = 20000; 2114 } 2115 } 2116 if (lane_config->MediaType == phymodFirmwareMediaTypeCopperCable) { 2117 config->interface_type = phymodInterfaceCR2; 2118 } else { 2119 config->interface_type = phymodInterfaceKR2; 2120 } 2121 break; 2122 case 0x1f: 2123 if (config->ref_clock == phymodRefClk125Mhz) { 2124 if(current_pll_div == TEMOD_PLL_MODE_DIV_100) { 2125 config->data_rate = 25000; 2126 } else if(current_pll_div == TEMOD_PLL_MODE_DIV_87P5) { 2127 config->data_rate = 21000; 2128 } else { 2129 config->data_rate = 20000; 2130 } 2131 } else { 2132 if(current_pll_div == TEMOD_PLL_MODE_DIV_80) { 2133 config->data_rate = 25000; 2134 } else if(current_pll_div == TEMOD_PLL_MODE_DIV_70) { 2135 config->data_rate = 21000; 2136 } else { 2137 config->data_rate = 20000; 2138 } 2139 } 2140 config->interface_type = phymodInterfaceCR2; 2141 break; 2142 case 0x20: 2143 config->data_rate = 21000; 2144 config->interface_type = phymodInterfaceKR2; 2145 break; 2146 case 0x21: /* digital_operationSpeeds_SPEED_40G_KR4 */ 2147 if (config->ref_clock == phymodRefClk125Mhz) { 2148 if (current_pll_div == TEMOD_PLL_MODE_DIV_100) { 2149 config->data_rate = 48000; 2150 } else if (current_pll_div == TEMOD_PLL_MODE_DIV_87P5) { 2151 config->data_rate = 42000; 2152 } else { 2153 config->data_rate = 40000; 2154 } 2155 2156 } else { 2157 if (current_pll_div == TEMOD_PLL_MODE_DIV_80) { 2158 config->data_rate = 48000; 2159 } else if (current_pll_div == TEMOD_PLL_MODE_DIV_70) { 2160 config->data_rate = 42000; 2161 } else { 2162 config->data_rate = 40000; 2163 } 2164 } 2165 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 2166 config->interface_type = phymodInterfaceSR4; 2167 } else if (lane_config->MediaType == phymodFirmwareMediaTypeCopperCable) { 2168 config->interface_type = phymodInterfaceCR4; 2169 } else if ((lane_config->MediaType == phymodFirmwareMediaTypePcbTraceBackPlane) && hg_enable) { 2170 config->interface_type = phymodInterfaceKR4; 2171 } else if(lane_config->DfeOn) { 2172 config->interface_type = phymodInterfaceKR4; 2173 } else { 2174 config->interface_type = phymodInterfaceXLAUI; 2175 } 2176 break; 2177 case 0x22: 2178 config->data_rate = 40000; 2179 config->interface_type = phymodInterfaceCR4; 2180 break; 2181 case 0x23: /* digital_operationSpeeds_SPEED_42G_X4; atcually MLD */ 2182 config->data_rate = 42000; 2183 if(lane_config->MediaType == phymodFirmwareMediaTypeCopperCable){ 2184 config->interface_type = phymodInterfaceCR4; 2185 }else if(lane_config->DfeOn) { 2186 config->interface_type = phymodInterfaceKR4; 2187 } else { 2188 config->interface_type = phymodInterfaceXLAUI; 2189 } 2190 break; 2191 case 0x24: 2192 config->data_rate = 100000; 2193 config->interface_type = phymodInterfaceCR10; 2194 break; 2195 case 0x25: 2196 config->data_rate = 106000; 2197 config->interface_type = phymodInterfaceCAUI; 2198 break; 2199 case 0x26: 2200 config->data_rate = 120000; 2201 /* config->interface_type = phymodInterfaceXGMII; */ 2202 config->interface_type = phymodInterfaceCAUI; 2203 break; 2204 case 0x27: 2205 config->data_rate = 127000; 2206 config->interface_type = phymodInterfaceCAUI; 2207 break; 2208 case 0x31: 2209 config->data_rate = 5000; 2210 config->interface_type = phymodInterface1000X; 2211 break; 2212 case 0x32: 2213 config->data_rate = 10500; 2214 config->interface_type = phymodInterfaceXGMII; 2215 break; 2216 case 0x35: 2217 config->data_rate = 10; 2218 config->interface_type = phymodInterfaceSGMII; 2219 break; 2220 case 0x36: 2221 config->data_rate = 100; 2222 config->interface_type = phymodInterfaceSGMII; 2223 break; 2224 case 0x37: 2225 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 2226 config->interface_type = phymodInterface1000X; 2227 } else { 2228 config->interface_type = phymodInterfaceSGMII; 2229 } 2230 config->data_rate = 1000; 2231 break; 2232 case 0x38: 2233 if (lane_config->MediaType == phymodFirmwareMediaTypeOptics) { 2234 config->interface_type = phymodInterface1000X; 2235 } else { 2236 config->interface_type = phymodInterfaceSGMII; 2237 } 2238 config->data_rate = 2500; 2239 break; 2240 default: 2241 config->data_rate = 0; 2242 config->interface_type = phymodInterfaceSGMII; 2243 break; 2244 } 2245 } 2246 return PHYMOD_E_NONE; 2247 } 2248 2249 2250 /* flags- unused parameter */ 2251 int tsce_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config) 2252 { 2253 int speed_id; 2254 phymod_firmware_lane_config_t firmware_lane_config; 2255 phymod_phy_access_t pm_phy_copy; 2256 int start_lane, num_lane; 2257 temod_an_control_t an_control; 2258 int an_complete = 0; 2259 int hg_enable = 0; 2260 2261 config->ref_clock = ref_clock; 2262 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 2263 PHYMOD_IF_ERR_RETURN 2264 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2265 2266 PHYMOD_IF_ERR_RETURN 2267 (temod_speed_id_get(&phy->access, &speed_id)); 2268 2269 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 2270 2271 PHYMOD_MEMSET(&an_control, 0x0, sizeof(temod_an_control_t)); 2272 PHYMOD_IF_ERR_RETURN 2273 (temod_autoneg_control_get(&pm_phy_copy.access, &an_control, &an_complete)); 2274 2275 PHYMOD_IF_ERR_RETURN 2276 (tsce_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 2277 2278 PHYMOD_IF_ERR_RETURN 2279 (_tsce_speed_id_interface_config_get(phy, speed_id, config, an_control.enable, &firmware_lane_config)); 2280 2281 if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) { 2282 PHYMOD_INTF_MODES_FIBER_SET(config); 2283 } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) { 2284 PHYMOD_INTF_MODES_FIBER_CLR(config); 2285 PHYMOD_INTF_MODES_COPPER_SET(config); 2286 } else { 2287 PHYMOD_INTF_MODES_FIBER_CLR(config); 2288 PHYMOD_INTF_MODES_BACKPLANE_SET(config); 2289 } 2290 2291 if (config->data_rate >= 100000) { 2292 switch(firmware_lane_config.MediaType) { 2293 case phymodFirmwareMediaTypePcbTraceBackPlane: 2294 /* no difference between CAUI and KR10. upper layer willhandle the conversion */ 2295 config->interface_type = phymodInterfaceCAUI; 2296 break; 2297 case phymodFirmwareMediaTypeCopperCable: 2298 config->interface_type = phymodInterfaceCR10; 2299 break; 2300 case phymodFirmwareMediaTypeOptics: 2301 /* 2302 * There is no difference between SR10 and LR10. tsce will return SR10 and let 2303 * the upper layers hand 2304 */ 2305 config->interface_type = phymodInterfaceSR10; 2306 break; 2307 default: 2308 config->interface_type = phymodInterfaceCAUI; 2309 break; 2310 } 2311 } 2312 2313 switch (config->interface_type) { 2314 case phymodInterfaceSGMII: 2315 { 2316 if(config->data_rate == 1000) { 2317 if (!PHYMOD_INTF_MODES_FIBER_GET(config)) { 2318 config->interface_type = phymodInterfaceSGMII; 2319 } else { 2320 config->interface_type = phymodInterface1000X; 2321 } 2322 } else { 2323 config->interface_type = phymodInterfaceSGMII; 2324 } 2325 break; 2326 } 2327 case phymodInterfaceKR: 2328 { 2329 phymod_autoneg_control_t an_control; 2330 int an_complete; 2331 /* first check if an is enable or not */ 2332 PHYMOD_IF_ERR_RETURN 2333 (tsce_phy_autoneg_get(phy, &an_control, (uint32_t *) &an_complete)); 2334 if (!an_control.enable) { 2335 if(config->data_rate == 10000) { 2336 if (!PHYMOD_INTF_MODES_FIBER_GET(config)) { 2337 if (firmware_lane_config.DfeOn == 1) { 2338 config->interface_type = phymodInterfaceKR; 2339 } else { 2340 config->interface_type = phymodInterfaceXFI; 2341 } 2342 } else { 2343 config->interface_type = phymodInterfaceSFI; 2344 } 2345 } else { 2346 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 2347 config->interface_type = phymodInterfaceSR; 2348 } else { 2349 config->interface_type = phymodInterfaceKR; 2350 } 2351 } 2352 } else { 2353 config->interface_type = phymodInterfaceKR; 2354 } 2355 break; 2356 } 2357 default: 2358 break; 2359 } 2360 2361 PHYMOD_IF_ERR_RETURN 2362 (temod_hg_enable_get(&phy->access, &hg_enable)); 2363 2364 if (hg_enable) { 2365 PHYMOD_INTF_MODES_HIGIG_SET(config); 2366 } else { 2367 PHYMOD_INTF_MODES_HIGIG_CLR(config); 2368 } 2369 2370 return PHYMOD_E_NONE; 2371 } 2372 2373 2374 int tsce_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 2375 { 2376 struct eagle_tsc_uc_lane_config_st serdes_firmware_config; 2377 2378 PHYMOD_IF_ERR_RETURN(eagle_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config)); 2379 2380 if(serdes_firmware_config.field.dfe_on == 0) { 2381 PHYMOD_DEBUG_ERROR(("ERROR :: DFE is off : Can not start CL72 with no DFE\n")); 2382 return PHYMOD_E_CONFIG; 2383 } 2384 2385 PHYMOD_IF_ERR_RETURN 2386 (temod_clause72_control(&phy->access, cl72_en)); 2387 return PHYMOD_E_NONE; 2388 } 2389 2390 int tsce_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 2391 { 2392 uint32_t local_en;; 2393 PHYMOD_IF_ERR_RETURN 2394 (eagle_pmd_cl72_enable_get(&phy->access, &local_en)); 2395 *cl72_en = local_en; 2396 return PHYMOD_E_NONE; 2397 } 2398 2399 2400 int tsce_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 2401 { 2402 uint32_t local_status; 2403 PHYMOD_IF_ERR_RETURN 2404 (eagle_pmd_cl72_receiver_status(&phy->access, &local_status)); 2405 status->locked = local_status; 2406 return PHYMOD_E_NONE; 2407 } 2408 2409 int tsce_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability) 2410 { 2411 temod_an_ability_t value; 2412 int start_lane, num_lane; 2413 phymod_phy_access_t phy_copy; 2414 /* next program the tx fir taps and driver current based on the input */ 2415 PHYMOD_IF_ERR_RETURN 2416 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2417 2418 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2419 phy_copy.access.lane_mask = 0x1 << start_lane; 2420 2421 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2422 2423 value.cl37_adv.an_cl72 = an_ability->an_cl72; 2424 value.cl73_adv.an_cl72 = an_ability->an_cl72; 2425 value.cl37_adv.an_hg2 = an_ability->an_hg2; 2426 2427 if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)) { 2428 value.cl37_adv.an_fec = TEMOD_FEC_CL74_SUPRTD_REQSTD; 2429 value.cl73_adv.an_fec = TEMOD_FEC_CL74_SUPRTD_REQSTD; 2430 } else if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) { 2431 value.cl37_adv.an_fec = TEMOD_FEC_SUPRTD_NOT_REQSTD; 2432 value.cl73_adv.an_fec = TEMOD_FEC_SUPRTD_NOT_REQSTD; 2433 } 2434 2435 /* check if sgmii or not */ 2436 if (PHYMOD_AN_CAP_SGMII_GET(an_ability)) { 2437 switch (an_ability->sgmii_speed) { 2438 case phymod_CL37_SGMII_10M: 2439 value.cl37_adv.cl37_sgmii_speed = TEMOD_CL37_SGMII_10M; 2440 break; 2441 case phymod_CL37_SGMII_100M: 2442 value.cl37_adv.cl37_sgmii_speed = TEMOD_CL37_SGMII_100M; 2443 break; 2444 case phymod_CL37_SGMII_1000M: 2445 value.cl37_adv.cl37_sgmii_speed = TEMOD_CL37_SGMII_1000M; 2446 break; 2447 default: 2448 value.cl37_adv.cl37_sgmii_speed = TEMOD_CL37_SGMII_1000M; 2449 break; 2450 } 2451 } 2452 /* next check pause */ 2453 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) { 2454 value.cl37_adv.an_pause = TEMOD_SYMM_PAUSE; 2455 value.cl73_adv.an_pause = TEMOD_SYMM_PAUSE; 2456 } 2457 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 2458 value.cl37_adv.an_pause = TEMOD_ASYM_PAUSE; 2459 value.cl73_adv.an_pause = TEMOD_ASYM_PAUSE; 2460 } 2461 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 2462 value.cl37_adv.an_pause = TEMOD_ASYM_SYMM_PAUSE; 2463 value.cl73_adv.an_pause = TEMOD_ASYM_SYMM_PAUSE; 2464 } 2465 2466 /* check cl73 and cl73 bam ability */ 2467 if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)) 2468 value.cl73_adv.an_base_speed |= 1 << TEMOD_CL73_1000BASE_KX; 2469 if (PHYMOD_AN_CAP_10G_KX4_GET(an_ability->an_cap)) 2470 value.cl73_adv.an_base_speed |= 1 << TEMOD_CL73_10GBASE_KX4; 2471 if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)) 2472 value.cl73_adv.an_base_speed |= 1 << TEMOD_CL73_10GBASE_KR; 2473 if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)) 2474 value.cl73_adv.an_base_speed |= 1 << TEMOD_CL73_40GBASE_KR4; 2475 if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)) 2476 value.cl73_adv.an_base_speed |= 1 << TEMOD_CL73_40GBASE_CR4; 2477 if (PHYMOD_AN_CAP_100G_CR10_GET(an_ability->an_cap)) 2478 value.cl73_adv.an_base_speed |= 1 << TEMOD_CL73_100GBASE_CR10; 2479 2480 /* next check cl73 bam ability */ 2481 if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap)) 2482 value.cl73_adv.an_bam_speed |= 1 << TEMOD_CL73_BAM_20GBASE_KR2; 2483 if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap)) 2484 value.cl73_adv.an_bam_speed |= 1 << TEMOD_CL73_BAM_20GBASE_CR2; 2485 2486 /* check cl37 and cl37 bam ability */ 2487 if (PHYMOD_BAM_CL37_CAP_2P5G_GET(an_ability->cl37bam_cap)) 2488 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_2p5GBASE_X; 2489 if (PHYMOD_BAM_CL37_CAP_5G_X4_GET(an_ability->cl37bam_cap)) 2490 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_5GBASE_X4; 2491 if (PHYMOD_BAM_CL37_CAP_6G_X4_GET(an_ability->cl37bam_cap)) 2492 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_6GBASE_X4; 2493 if (PHYMOD_BAM_CL37_CAP_10G_HIGIG_GET(an_ability->cl37bam_cap)) 2494 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_10GBASE_X4; 2495 if (PHYMOD_BAM_CL37_CAP_10G_CX4_GET(an_ability->cl37bam_cap)) 2496 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_10GBASE_X4_CX4; 2497 if (PHYMOD_BAM_CL37_CAP_12G_X4_GET(an_ability->cl37bam_cap)) 2498 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_12GBASE_X4; 2499 if (PHYMOD_BAM_CL37_CAP_12P5_X4_GET(an_ability->cl37bam_cap)) 2500 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_12p5GBASE_X4; 2501 if (PHYMOD_BAM_CL37_CAP_10G_X2_CX4_GET(an_ability->cl37bam_cap)) 2502 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_10GBASE_X2_CX4; 2503 if (PHYMOD_BAM_CL37_CAP_10G_DXGXS_GET(an_ability->cl37bam_cap)) 2504 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_10GBASE_X2; 2505 if (PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_GET(an_ability->cl37bam_cap)) 2506 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_BAM_10p5GBASE_X2; 2507 if (PHYMOD_BAM_CL37_CAP_12P7_DXGXS_GET(an_ability->cl37bam_cap)) 2508 value.cl37_adv.an_bam_speed |= 1 << TEMOD_CL37_BAM_12p7GBASE_X2; 2509 if (PHYMOD_BAM_CL37_CAP_20G_X2_CX4_GET(an_ability->cl37bam_cap)) 2510 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_20GBASE_X2_CX4; 2511 if (PHYMOD_BAM_CL37_CAP_20G_X2_GET(an_ability->cl37bam_cap)) 2512 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_20GBASE_X2; 2513 if (PHYMOD_BAM_CL37_CAP_13G_X4_GET(an_ability->cl37bam_cap)) 2514 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_13GBASE_X4; 2515 if (PHYMOD_BAM_CL37_CAP_15G_X4_GET(an_ability->cl37bam_cap)) 2516 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_15GBASE_X4; 2517 if (PHYMOD_BAM_CL37_CAP_16G_X4_GET(an_ability->cl37bam_cap)) 2518 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_16GBASE_X4; 2519 if (PHYMOD_BAM_CL37_CAP_20G_X4_CX4_GET(an_ability->cl37bam_cap)) 2520 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_20GBASE_X4_CX4; 2521 if (PHYMOD_BAM_CL37_CAP_20G_X4_GET(an_ability->cl37bam_cap)) 2522 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_20GBASE_X4; 2523 if (PHYMOD_BAM_CL37_CAP_21G_X4_GET(an_ability->cl37bam_cap)) 2524 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_21GBASE_X4; 2525 if (PHYMOD_BAM_CL37_CAP_25P455G_GET(an_ability->cl37bam_cap)) 2526 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_25p455GBASE_X4; 2527 if (PHYMOD_BAM_CL37_CAP_31P5G_GET(an_ability->cl37bam_cap)) 2528 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_31p5GBASE_X4; 2529 if (PHYMOD_BAM_CL37_CAP_32P7G_GET(an_ability->cl37bam_cap)) 2530 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_32p7GBASE_X4; 2531 if (PHYMOD_BAM_CL37_CAP_40G_GET(an_ability->cl37bam_cap)) 2532 value.cl37_adv.an_bam_speed1 |= 1 << TEMOD_CL37_BAM_40GBASE_X4; 2533 2534 PHYMOD_IF_ERR_RETURN 2535 (temod_autoneg_set(&phy_copy.access, &value)); 2536 return PHYMOD_E_NONE; 2537 2538 } 2539 2540 int tsce_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type){ 2541 temod_an_ability_t value; 2542 phymod_phy_access_t phy_copy; 2543 int start_lane, num_lane; 2544 temod_an_control_t an_control; 2545 int an_complete = 0; 2546 int an_fec = 0; 2547 2548 2549 PHYMOD_IF_ERR_RETURN 2550 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2551 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2552 phy_copy.access.lane_mask = 0x1 << start_lane; 2553 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2554 PHYMOD_MEMSET(&an_control, 0x0, sizeof(temod_an_control_t)); 2555 2556 PHYMOD_IF_ERR_RETURN 2557 (temod_autoneg_local_ability_get(&phy_copy.access, &value)); 2558 PHYMOD_IF_ERR_RETURN 2559 (temod_autoneg_control_get(&phy_copy.access, &an_control, &an_complete)); 2560 2561 an_ability_get_type->an_cl72 = value.cl37_adv.an_cl72 | value.cl73_adv.an_cl72; 2562 an_ability_get_type->an_hg2 = value.cl37_adv.an_hg2; 2563 2564 2565 an_fec = value.cl37_adv.an_fec | value.cl73_adv.an_fec; 2566 an_ability_get_type->an_fec = 0; 2567 if (an_fec == TEMOD_FEC_CL74_SUPRTD_REQSTD) { 2568 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2569 } else { 2570 PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec); 2571 } 2572 2573 if ((value.cl37_adv.an_pause == TEMOD_ASYM_PAUSE)||(value.cl73_adv.an_pause == TEMOD_ASYM_PAUSE)) { 2574 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2575 } else if ((value.cl37_adv.an_pause == TEMOD_SYMM_PAUSE)||(value.cl73_adv.an_pause == TEMOD_SYMM_PAUSE)) { 2576 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2577 } else if ((value.cl37_adv.an_pause == TEMOD_ASYM_SYMM_PAUSE)||(value.cl73_adv.an_pause == TEMOD_ASYM_SYMM_PAUSE)) { 2578 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2579 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2580 } 2581 2582 /* get AN Clause */ 2583 switch (an_control.an_type) { 2584 case TEMOD_AN_MODE_CL73: 2585 PHYMOD_AN_CAP_CL73_SET(an_ability_get_type); 2586 break; 2587 case TEMOD_AN_MODE_CL37: 2588 PHYMOD_AN_CAP_CL37_SET(an_ability_get_type); 2589 break; 2590 case TEMOD_AN_MODE_CL73BAM: 2591 PHYMOD_AN_CAP_CL73BAM_SET(an_ability_get_type); 2592 break; 2593 case TEMOD_AN_MODE_CL37BAM: 2594 PHYMOD_AN_CAP_CL37BAM_SET(an_ability_get_type); 2595 break; 2596 case TEMOD_AN_MODE_HPAM: 2597 PHYMOD_AN_CAP_HPAM_SET(an_ability_get_type); 2598 break; 2599 case TEMOD_AN_MODE_SGMII: 2600 PHYMOD_AN_CAP_SGMII_SET(an_ability_get_type); 2601 break; 2602 case TEMOD_AN_MODE_CL37_SGMII: 2603 PHYMOD_AN_CAP_SGMII_SET(an_ability_get_type); 2604 break; 2605 default: 2606 2607 break; 2608 } 2609 2610 /* get the cl37 sgmii speed */ 2611 if (PHYMOD_AN_CAP_SGMII_GET(an_ability_get_type)){ 2612 switch (value.cl37_adv.cl37_sgmii_speed) { 2613 case TEMOD_CL37_SGMII_10M: 2614 an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_10M; 2615 break; 2616 case TEMOD_CL37_SGMII_100M: 2617 an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_100M; 2618 break; 2619 case TEMOD_CL37_SGMII_1000M: 2620 an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_1000M; 2621 break; 2622 default: 2623 break; 2624 } 2625 } 2626 /* first check cl73 ability */ 2627 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_100GBASE_CR10) 2628 PHYMOD_AN_CAP_100G_CR10_SET(an_ability_get_type->an_cap); 2629 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_40GBASE_CR4) 2630 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 2631 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_40GBASE_KR4) 2632 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 2633 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_10GBASE_KR) 2634 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 2635 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_10GBASE_KX4) 2636 PHYMOD_AN_CAP_10G_KX4_SET(an_ability_get_type->an_cap); 2637 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_1000BASE_KX) 2638 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 2639 2640 /* next check cl73 bam ability */ 2641 if (value.cl73_adv.an_bam_speed & 1 << TEMOD_CL73_BAM_20GBASE_KR2) 2642 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap); 2643 if (value.cl73_adv.an_bam_speed & 1 << TEMOD_CL73_BAM_20GBASE_CR2) 2644 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap); 2645 2646 /* check cl37 bam ability */ 2647 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_2p5GBASE_X) 2648 PHYMOD_BAM_CL37_CAP_2P5G_SET(an_ability_get_type->cl37bam_cap); 2649 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_5GBASE_X4) 2650 PHYMOD_BAM_CL37_CAP_5G_X4_SET(an_ability_get_type->cl37bam_cap); 2651 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_6GBASE_X4) 2652 PHYMOD_BAM_CL37_CAP_6G_X4_SET(an_ability_get_type->cl37bam_cap); 2653 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X4) 2654 PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_ability_get_type->cl37bam_cap); 2655 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X4_CX4) 2656 PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_ability_get_type->cl37bam_cap); 2657 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X2) 2658 PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2659 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X2_CX4) 2660 PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_ability_get_type->cl37bam_cap); 2661 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_BAM_10p5GBASE_X2) 2662 PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2663 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_12GBASE_X4) 2664 PHYMOD_BAM_CL37_CAP_12G_X4_SET(an_ability_get_type->cl37bam_cap); 2665 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_12p5GBASE_X4) 2666 PHYMOD_BAM_CL37_CAP_12P5_X4_SET(an_ability_get_type->cl37bam_cap); 2667 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_12p7GBASE_X2) 2668 PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2669 2670 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_13GBASE_X4) 2671 PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_ability_get_type->cl37bam_cap); 2672 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_15GBASE_X4) 2673 PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_ability_get_type->cl37bam_cap); 2674 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_15p75GBASE_X2) 2675 PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2676 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_16GBASE_X4) 2677 PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_ability_get_type->cl37bam_cap); 2678 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X4_CX4) 2679 PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_ability_get_type->cl37bam_cap); 2680 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X4) 2681 PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_ability_get_type->cl37bam_cap); 2682 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X2) 2683 PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_ability_get_type->cl37bam_cap); 2684 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X2_CX4) 2685 PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_ability_get_type->cl37bam_cap); 2686 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_21GBASE_X4) 2687 PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_ability_get_type->cl37bam_cap); 2688 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_25p455GBASE_X4) 2689 PHYMOD_BAM_CL37_CAP_25P455G_SET(an_ability_get_type->cl37bam_cap); 2690 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_31p5GBASE_X4) 2691 PHYMOD_BAM_CL37_CAP_31P5G_SET(an_ability_get_type->cl37bam_cap); 2692 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_32p7GBASE_X4) 2693 PHYMOD_BAM_CL37_CAP_32P7G_SET(an_ability_get_type->cl37bam_cap); 2694 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_40GBASE_X4) 2695 PHYMOD_BAM_CL37_CAP_40G_SET(an_ability_get_type->cl37bam_cap); 2696 2697 return PHYMOD_E_NONE; 2698 } 2699 2700 int tsce_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 2701 { 2702 2703 temod_an_ability_t value; 2704 temod_an_control_t an_control; 2705 phymod_phy_access_t phy_copy; 2706 int an_complete = 0; 2707 int start_lane, num_lane; 2708 int an_fec = 0; 2709 2710 PHYMOD_IF_ERR_RETURN 2711 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2712 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2713 phy_copy.access.lane_mask = 0x1 << start_lane; 2714 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2715 PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control)); 2716 2717 PHYMOD_IF_ERR_RETURN 2718 (temod_autoneg_remote_ability_get(&phy_copy.access, &value)); 2719 an_ability_get_type->an_cl72 = value.cl37_adv.an_cl72 | value.cl73_adv.an_cl72; 2720 an_ability_get_type->an_hg2 = value.cl37_adv.an_hg2; 2721 2722 an_fec = value.cl37_adv.an_fec | value.cl73_adv.an_fec; 2723 if (an_fec == TEMOD_FEC_CL74_SUPRTD_REQSTD) { 2724 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2725 } else { 2726 PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec); 2727 } 2728 2729 PHYMOD_IF_ERR_RETURN 2730 (temod_autoneg_control_get(&phy_copy.access, &an_control, &an_complete)); 2731 2732 /* get AN Clause */ 2733 switch (an_control.an_type) { 2734 case TEMOD_AN_MODE_CL73: 2735 PHYMOD_AN_CAP_CL73_SET(an_ability_get_type); 2736 break; 2737 case TEMOD_AN_MODE_CL37: 2738 PHYMOD_AN_CAP_CL37_SET(an_ability_get_type); 2739 break; 2740 case TEMOD_AN_MODE_CL73BAM: 2741 PHYMOD_AN_CAP_CL73BAM_SET(an_ability_get_type); 2742 break; 2743 case TEMOD_AN_MODE_CL37BAM: 2744 PHYMOD_AN_CAP_CL37BAM_SET(an_ability_get_type); 2745 break; 2746 case TEMOD_AN_MODE_HPAM: 2747 PHYMOD_AN_CAP_HPAM_SET(an_ability_get_type); 2748 break; 2749 case TEMOD_AN_MODE_SGMII: 2750 PHYMOD_AN_CAP_SGMII_SET(an_ability_get_type); 2751 break; 2752 case TEMOD_AN_MODE_CL37_SGMII: 2753 PHYMOD_AN_CAP_SGMII_SET(an_ability_get_type); 2754 break; 2755 default: 2756 break; 2757 } 2758 2759 if (an_control.an_type == TEMOD_AN_MODE_CL73 || an_control.an_type == TEMOD_AN_MODE_CL73BAM) { 2760 if (value.cl73_adv.an_pause == TEMOD_ASYM_PAUSE) { 2761 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2762 } else if (value.cl73_adv.an_pause == TEMOD_SYMM_PAUSE) { 2763 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2764 } else if (value.cl73_adv.an_pause == TEMOD_ASYM_SYMM_PAUSE) { 2765 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2766 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2767 } 2768 } else { 2769 if (value.cl37_adv.an_pause == TEMOD_ASYM_PAUSE) { 2770 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2771 } else if (value.cl37_adv.an_pause == TEMOD_SYMM_PAUSE) { 2772 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2773 } else if (value.cl37_adv.an_pause == TEMOD_ASYM_SYMM_PAUSE) { 2774 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2775 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2776 } 2777 } 2778 2779 if (an_control.an_type == TEMOD_AN_MODE_CL37) { 2780 PHYMOD_AN_CAP_CL37_SET(an_ability_get_type); 2781 } 2782 2783 /* get the cl37 sgmii speed */ 2784 if (PHYMOD_AN_CAP_SGMII_GET(an_ability_get_type)) { 2785 switch (value.cl37_adv.cl37_sgmii_speed) { 2786 case TEMOD_CL37_SGMII_10M: 2787 an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_10M; 2788 break; 2789 case TEMOD_CL37_SGMII_100M: 2790 an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_100M; 2791 break; 2792 case TEMOD_CL37_SGMII_1000M: 2793 an_ability_get_type->sgmii_speed = phymod_CL37_SGMII_1000M; 2794 break; 2795 default: 2796 break; 2797 } 2798 } 2799 2800 /* first check cl73 ability */ 2801 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_100GBASE_CR10) 2802 PHYMOD_AN_CAP_100G_CR10_SET(an_ability_get_type->an_cap); 2803 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_40GBASE_CR4) 2804 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 2805 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_40GBASE_KR4) 2806 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 2807 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_10GBASE_KR) 2808 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 2809 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_10GBASE_KX4) 2810 PHYMOD_AN_CAP_10G_KX4_SET(an_ability_get_type->an_cap); 2811 if (value.cl73_adv.an_base_speed & 1 << TEMOD_CL73_1000BASE_KX) 2812 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 2813 2814 /* next check cl73 bam ability */ 2815 /*UD0 in UP4 indicates Over 1G ability when an mode is cl37 bam*/ 2816 if (PHYMOD_AN_CAP_CL73BAM_GET(an_ability_get_type)) { 2817 if (value.cl73_adv.an_bam_speed & 1 << TEMOD_CL73_BAM_20GBASE_KR2) 2818 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap); 2819 if (value.cl73_adv.an_bam_speed & 1 << TEMOD_CL73_BAM_20GBASE_CR2) 2820 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap); 2821 } 2822 2823 /* check cl37 bam ability */ 2824 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_2p5GBASE_X) 2825 PHYMOD_BAM_CL37_CAP_2P5G_SET(an_ability_get_type->cl37bam_cap); 2826 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_5GBASE_X4) 2827 PHYMOD_BAM_CL37_CAP_5G_X4_SET(an_ability_get_type->cl37bam_cap); 2828 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_6GBASE_X4) 2829 PHYMOD_BAM_CL37_CAP_6G_X4_SET(an_ability_get_type->cl37bam_cap); 2830 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X4) 2831 PHYMOD_BAM_CL37_CAP_10G_HIGIG_SET(an_ability_get_type->cl37bam_cap); 2832 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X4_CX4) 2833 PHYMOD_BAM_CL37_CAP_10G_CX4_SET(an_ability_get_type->cl37bam_cap); 2834 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X2) 2835 PHYMOD_BAM_CL37_CAP_10G_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2836 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_10GBASE_X2_CX4) 2837 PHYMOD_BAM_CL37_CAP_10G_X2_CX4_SET(an_ability_get_type->cl37bam_cap); 2838 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_BAM_10p5GBASE_X2) 2839 PHYMOD_BAM_CL37_CAP_10P5G_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2840 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_12GBASE_X4) 2841 PHYMOD_BAM_CL37_CAP_12G_X4_SET(an_ability_get_type->cl37bam_cap); 2842 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_12p5GBASE_X4) 2843 PHYMOD_BAM_CL37_CAP_12P5_X4_SET(an_ability_get_type->cl37bam_cap); 2844 if (value.cl37_adv.an_bam_speed & 1 << TEMOD_CL37_BAM_12p7GBASE_X2) 2845 PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2846 2847 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_13GBASE_X4) 2848 PHYMOD_BAM_CL37_CAP_13G_X4_SET(an_ability_get_type->cl37bam_cap); 2849 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_15GBASE_X4) 2850 PHYMOD_BAM_CL37_CAP_15G_X4_SET(an_ability_get_type->cl37bam_cap); 2851 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_15p75GBASE_X2) 2852 PHYMOD_BAM_CL37_CAP_12P7_DXGXS_SET(an_ability_get_type->cl37bam_cap); 2853 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_16GBASE_X4) 2854 PHYMOD_BAM_CL37_CAP_16G_X4_SET(an_ability_get_type->cl37bam_cap); 2855 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X4_CX4) 2856 PHYMOD_BAM_CL37_CAP_20G_X4_CX4_SET(an_ability_get_type->cl37bam_cap); 2857 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X4) 2858 PHYMOD_BAM_CL37_CAP_20G_X4_SET(an_ability_get_type->cl37bam_cap); 2859 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X2) 2860 PHYMOD_BAM_CL37_CAP_20G_X2_SET(an_ability_get_type->cl37bam_cap); 2861 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_20GBASE_X2_CX4) 2862 PHYMOD_BAM_CL37_CAP_20G_X2_CX4_SET(an_ability_get_type->cl37bam_cap); 2863 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_21GBASE_X4) 2864 PHYMOD_BAM_CL37_CAP_21G_X4_SET(an_ability_get_type->cl37bam_cap); 2865 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_25p455GBASE_X4) 2866 PHYMOD_BAM_CL37_CAP_25P455G_SET(an_ability_get_type->cl37bam_cap); 2867 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_31p5GBASE_X4) 2868 PHYMOD_BAM_CL37_CAP_31P5G_SET(an_ability_get_type->cl37bam_cap); 2869 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_32p7GBASE_X4) 2870 PHYMOD_BAM_CL37_CAP_32P7G_SET(an_ability_get_type->cl37bam_cap); 2871 if (value.cl37_adv.an_bam_speed1 & 1 << TEMOD_CL37_BAM_40GBASE_X4) 2872 PHYMOD_BAM_CL37_CAP_40G_SET(an_ability_get_type->cl37bam_cap); 2873 2874 return PHYMOD_E_NONE; 2875 } 2876 2877 int tsce_phy_autoneg_restart_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 2878 { 2879 int start_lane, num_lane ; 2880 phymod_phy_access_t phy_copy; 2881 temod_an_control_t an_control; 2882 2883 PHYMOD_IF_ERR_RETURN 2884 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2885 2886 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2887 phy_copy.access.lane_mask = 0x1 << start_lane; 2888 2889 if(an->an_mode == phymod_AN_MODE_CL37_SGMII) { 2890 an_control.enable = an->enable; 2891 an_control.an_type = TEMOD_AN_MODE_CL37_SGMII; 2892 PHYMOD_IF_ERR_RETURN 2893 (temod_autoneg_restart(&phy_copy.access, &an_control)); 2894 } 2895 return PHYMOD_E_NONE; 2896 } 2897 2898 2899 int tsce_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 2900 { 2901 int num_lane_adv_encoded; 2902 phymod_firmware_lane_config_t firmware_lane_config; 2903 phymod_firmware_core_config_t firmware_core_config_tmp; 2904 int start_lane, num_lane, i ; 2905 phymod_phy_access_t phy_copy; 2906 temod_an_control_t an_control; 2907 int ctrl_port = 0 ; 2908 int no_pll_switch = 0; 2909 uint32_t current_pll_div=0; 2910 2911 /* next program the tx fir taps and driver current based on the input */ 2912 PHYMOD_IF_ERR_RETURN 2913 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2914 2915 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 2916 PHYMOD_MEMSET(&firmware_core_config_tmp, 0x0, sizeof(firmware_core_config_tmp)); 2917 2918 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2919 phy_copy.access.lane_mask = 0x1 << start_lane; 2920 2921 if((an->flags & PHYMOD_AN_F_SET_PRIOR_ENABLE)&& an->enable) { 2922 PHYMOD_IF_ERR_RETURN 2923 (temod_tsc12_control(&phy_copy.access, 0, -1)); 2924 2925 2926 temod_disable_set(&phy->access); 2927 PHYMOD_IF_ERR_RETURN 2928 (tsce_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 2929 2930 for (i = 0; i < num_lane; i++) { 2931 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2932 continue; 2933 } 2934 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2935 PHYMOD_IF_ERR_RETURN 2936 (eagle_lane_soft_reset_release(&phy_copy.access, 0)); 2937 } 2938 2939 if (an->enable) { 2940 firmware_lane_config.AnEnabled = 1; 2941 firmware_lane_config.LaneConfigFromPCS = 1; 2942 } else { 2943 firmware_lane_config.AnEnabled = 0; 2944 firmware_lane_config.LaneConfigFromPCS = 0; 2945 } 2946 for (i = 0; i < num_lane; i++) { 2947 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2948 continue; 2949 } 2950 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2951 PHYMOD_IF_ERR_RETURN 2952 (_tsce_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config)); 2953 } 2954 2955 for (i = 0; i < num_lane; i++) { 2956 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2957 continue; 2958 } 2959 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2960 PHYMOD_IF_ERR_RETURN 2961 (eagle_lane_soft_reset_release(&phy_copy.access, 1)); 2962 } 2963 2964 2965 return PHYMOD_E_NONE ; 2966 } 2967 2968 /* make sure the firmware config is set to an eenabled */ 2969 PHYMOD_IF_ERR_RETURN 2970 (tsce_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp)); 2971 2972 2973 switch (an->num_lane_adv) { 2974 case 1: 2975 num_lane_adv_encoded = 0; 2976 break; 2977 case 2: 2978 num_lane_adv_encoded = 1; 2979 break; 2980 case 4: 2981 num_lane_adv_encoded = 2; 2982 break; 2983 case 10: 2984 num_lane_adv_encoded = 3; 2985 break; 2986 default: 2987 return PHYMOD_E_PARAM; 2988 } 2989 2990 if(PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) { 2991 an_control.pd_kx_en = 1; 2992 } else { 2993 an_control.pd_kx_en = 0; 2994 } 2995 if(PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_GET(an)) { 2996 an_control.pd_kx4_en = 1; 2997 } else { 2998 an_control.pd_kx4_en = 0; 2999 } 3000 3001 an_control.num_lane_adv = num_lane_adv_encoded; 3002 an_control.enable = an->enable; 3003 if (PHYMOD_AN_F_SGMII_MASTER_MODE_GET(an)) { 3004 an_control.an_property_type = TEMOD_AN_PROPERTY_ENABLE_SGMII_MASTER_MODE; 3005 } else { 3006 an_control.an_property_type = 0x0; /* for now disable */ 3007 } 3008 switch (an->an_mode) { 3009 case phymod_AN_MODE_CL73: 3010 an_control.an_type = TEMOD_AN_MODE_CL73; 3011 break; 3012 case phymod_AN_MODE_CL37: 3013 an_control.an_type = TEMOD_AN_MODE_CL37; 3014 break; 3015 case phymod_AN_MODE_CL73BAM: 3016 an_control.an_type = TEMOD_AN_MODE_CL73BAM; 3017 break; 3018 case phymod_AN_MODE_CL37BAM: 3019 an_control.an_type = TEMOD_AN_MODE_CL37BAM; 3020 break; 3021 case phymod_AN_MODE_HPAM: 3022 an_control.an_type = TEMOD_AN_MODE_HPAM; 3023 break; 3024 case phymod_AN_MODE_SGMII: 3025 an_control.an_type = TEMOD_AN_MODE_SGMII; 3026 break; 3027 case phymod_AN_MODE_CL37BAM_10P9375G_VCO: 3028 an_control.an_type = TEMOD_AN_MODE_CL37BAM; 3029 no_pll_switch = 1; 3030 break; 3031 default: 3032 if(an->an_mode ==(phymod_AN_MODE_CL37_SGMII)) { 3033 an_control.an_type = TEMOD_AN_MODE_CL37_SGMII ; 3034 } else { 3035 an_control.an_type = TEMOD_AN_MODE_CL73; 3036 } 3037 break; 3038 } 3039 3040 /* make sure the firmware config is set to an eenabled */ 3041 PHYMOD_IF_ERR_RETURN 3042 (tsce_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp)); 3043 3044 /* Hold core soft reset */ 3045 if ((an->num_lane_adv == 4) && !no_pll_switch) { 3046 PHYMOD_IF_ERR_RETURN 3047 (eagle_core_soft_reset_release(&phy_copy.access, 0)); 3048 } 3049 3050 temod_disable_set(&phy->access); 3051 3052 for (i = 0; i < num_lane; i++) { 3053 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3054 continue; 3055 } 3056 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3057 PHYMOD_IF_ERR_RETURN 3058 (eagle_lane_soft_reset_release(&phy_copy.access, 0)); 3059 } 3060 3061 if (no_pll_switch) { 3062 /*check VCO rate first */ 3063 PHYMOD_IF_ERR_RETURN 3064 (temod_get_plldiv(&phy_copy.access, ¤t_pll_div)); 3065 /* need to switch to 10.9375GVCO if not */ 3066 if (current_pll_div != 0xc) { 3067 temod_disable_set(&phy->access); 3068 PHYMOD_IF_ERR_RETURN 3069 (eagle_core_soft_reset_release(&phy_copy.access, 0)); 3070 PHYMOD_USLEEP(500); 3071 /* set the PLL divider */ 3072 PHYMOD_IF_ERR_RETURN 3073 (eagle_pll_mode_set(&phy_copy.access, 0xc)); 3074 3075 PHYMOD_IF_ERR_RETURN 3076 (temod_pll_reset_enable_set(&phy_copy.access, 1)); 3077 3078 PHYMOD_IF_ERR_RETURN 3079 (eagle_core_soft_reset_release(&phy_copy.access, 1)); 3080 PHYMOD_USLEEP(500); 3081 PHYMOD_IF_ERR_RETURN 3082 (temod_trigger_speed_change(&phy->access)); 3083 } 3084 } 3085 3086 /* make sure the firmware config is set to an eenabled */ 3087 PHYMOD_IF_ERR_RETURN 3088 (tsce_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 3089 3090 if (!PHYMOD_AN_F_IGNORE_MEDIUM_CHECK_GET(an)) { 3091 if(an_control.an_type == TEMOD_AN_MODE_SGMII) { 3092 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 3093 } 3094 if(an_control.an_type == TEMOD_AN_MODE_CL37) { 3095 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 3096 } 3097 } 3098 3099 if (an->enable) { 3100 firmware_lane_config.AnEnabled = 1; 3101 firmware_lane_config.LaneConfigFromPCS = 1; 3102 firmware_core_config_tmp.CoreConfigFromPCS = 1; 3103 firmware_lane_config.Cl72RestTO = 0; 3104 } else { 3105 firmware_lane_config.AnEnabled = 0; 3106 firmware_lane_config.LaneConfigFromPCS = 0; 3107 firmware_core_config_tmp.CoreConfigFromPCS = 0; 3108 firmware_lane_config.Cl72RestTO = 1; 3109 } 3110 3111 if ((an->num_lane_adv == 4) && !no_pll_switch) { 3112 phy_copy.access.lane_mask = 0x1 << start_lane; 3113 PHYMOD_IF_ERR_RETURN 3114 (tsce_phy_firmware_core_config_set(&phy_copy, firmware_core_config_tmp)); 3115 } 3116 3117 for (i = 0; i < num_lane; i++) { 3118 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3119 continue; 3120 } 3121 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3122 PHYMOD_IF_ERR_RETURN 3123 (_tsce_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config)); 3124 } 3125 /* Release core soft reset */ 3126 if ((an->num_lane_adv == 4) && !no_pll_switch) { 3127 phy_copy.access.lane_mask = 0x1 << start_lane; 3128 PHYMOD_IF_ERR_RETURN 3129 (eagle_core_soft_reset_release(&phy_copy.access, 1)); 3130 } 3131 3132 for (i = 0; i < num_lane; i++) { 3133 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3134 continue; 3135 } 3136 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3137 PHYMOD_IF_ERR_RETURN 3138 (eagle_lane_soft_reset_release(&phy_copy.access, 1)); 3139 } 3140 3141 phy_copy.access.lane_mask = 0x1 << start_lane; 3142 PHYMOD_IF_ERR_RETURN 3143 (temod_trigger_speed_change(&phy_copy.access)); 3144 3145 if (!no_pll_switch) { 3146 if (an->enable) { 3147 if(an->num_lane_adv == 4) { 3148 ctrl_port = 1 ; 3149 } else { 3150 ctrl_port = 0 ; 3151 } 3152 PHYMOD_IF_ERR_RETURN 3153 (temod_set_an_port_mode(&phy->access, an->enable, num_lane_adv_encoded, start_lane, ctrl_port)); 3154 } else { 3155 ctrl_port =0 ; 3156 PHYMOD_IF_ERR_RETURN 3157 (temod_set_an_port_mode(&phy->access, an->enable, num_lane_adv_encoded, start_lane, ctrl_port)); 3158 } 3159 } 3160 /* temod_autoneg_control invokes disabling CL72 and spd_trigger when en=0 */ 3161 3162 PHYMOD_IF_ERR_RETURN 3163 (temod_autoneg_control(&phy_copy.access, &an_control)); 3164 3165 3166 return PHYMOD_E_NONE; 3167 3168 } 3169 3170 int tsce_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 3171 { 3172 temod_an_control_t an_control; 3173 phymod_phy_access_t phy_copy; 3174 int start_lane, num_lane; 3175 int an_complete = 0; 3176 3177 /* next program the tx fir taps and driver current based on the input */ 3178 PHYMOD_IF_ERR_RETURN 3179 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3180 3181 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3182 phy_copy.access.lane_mask = 0x1 << start_lane; 3183 3184 PHYMOD_MEMSET(&an_control, 0x0, sizeof(temod_an_control_t)); 3185 PHYMOD_IF_ERR_RETURN 3186 (temod_autoneg_control_get(&phy_copy.access, &an_control, &an_complete)); 3187 3188 if (an_control.enable) { 3189 an->enable = 1; 3190 *an_done = an_complete; 3191 } else { 3192 an->enable = 0; 3193 *an_done = 0; 3194 } 3195 3196 if(an_control.pd_kx_en) { 3197 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(an); 3198 } else { 3199 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_CLR(an); 3200 } 3201 if(an_control.pd_kx4_en) { 3202 PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_SET(an); 3203 } else { 3204 PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_CLR(an); 3205 } 3206 3207 if (an_control.an_property_type == TEMOD_AN_PROPERTY_ENABLE_SGMII_MASTER_MODE) { 3208 PHYMOD_AN_F_SGMII_MASTER_MODE_SET(an); 3209 } else { 3210 PHYMOD_AN_F_SGMII_MASTER_MODE_CLR(an); 3211 } 3212 3213 switch (an_control.an_type) { 3214 case TEMOD_AN_MODE_CL73: 3215 an->an_mode = phymod_AN_MODE_CL73; 3216 break; 3217 case TEMOD_AN_MODE_CL37: 3218 an->an_mode = phymod_AN_MODE_CL37; 3219 break; 3220 case TEMOD_AN_MODE_CL73BAM: 3221 an->an_mode = phymod_AN_MODE_CL73BAM; 3222 break; 3223 case TEMOD_AN_MODE_CL37BAM: 3224 an->an_mode = phymod_AN_MODE_CL37BAM; 3225 break; 3226 case TEMOD_AN_MODE_HPAM: 3227 an->an_mode = phymod_AN_MODE_HPAM; 3228 break; 3229 case TEMOD_AN_MODE_SGMII: 3230 an->an_mode = phymod_AN_MODE_SGMII; 3231 break; 3232 default: 3233 if(an_control.an_type == TEMOD_AN_MODE_CL37_SGMII) { 3234 an->an_mode = phymod_AN_MODE_CL37_SGMII ; 3235 } else { 3236 an->an_mode = phymod_AN_MODE_NONE; 3237 } 3238 break; 3239 } 3240 3241 return PHYMOD_E_NONE; 3242 } 3243 3244 3245 int tsce_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 3246 { 3247 /* Place your code here */ 3248 3249 3250 return PHYMOD_E_NONE; 3251 } 3252 3253 3254 STATIC 3255 int _tsce_core_init_pass1(const phymod_core_access_t* core, 3256 const phymod_core_init_config_t* init_config, 3257 const phymod_core_status_t* core_status) 3258 { 3259 phymod_phy_access_t phy_access; 3260 phymod_core_access_t core_copy; 3261 uint32_t uc_active = 0 ; 3262 3263 TSCE_CORE_TO_PHY_ACCESS(&phy_access, core); 3264 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 3265 core_copy.access.lane_mask = 0x1; 3266 3267 PHYMOD_IF_ERR_RETURN(eagle_uc_active_get(&core_copy.access, &uc_active)) ; 3268 if(uc_active) { 3269 return(PHYMOD_E_NONE); 3270 } 3271 3272 PHYMOD_IF_ERR_RETURN 3273 (temod_pmd_reset_seq(&core_copy.access, core_status->pmd_active)); 3274 3275 /* need to set the heart beat default is for 156.25M */ 3276 PHYMOD_IF_ERR_RETURN (temod_refclk_set(&core_copy.access, 3277 init_config->interface.ref_clock)); 3278 3279 if (_tsce_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader)) { 3280 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask)); 3281 PHYMOD_IF_ERR_RETURN (PHYMOD_E_INIT); 3282 } 3283 return (PHYMOD_E_NONE); 3284 } 3285 3286 STATIC 3287 int _tsce_core_init_pass2(const phymod_core_access_t* core, 3288 const phymod_core_init_config_t* init_config, 3289 const phymod_core_status_t* core_status) 3290 { 3291 phymod_phy_access_t phy_access, phy_access_copy; 3292 phymod_core_access_t core_copy; 3293 phymod_firmware_core_config_t firmware_core_config_tmp; 3294 3295 TSCE_CORE_TO_PHY_ACCESS(&phy_access, core); 3296 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 3297 core_copy.access.lane_mask = 0x1; 3298 3299 phy_access_copy = phy_access; 3300 phy_access_copy.access = core->access; 3301 phy_access_copy.access.lane_mask = 0x1; 3302 phy_access_copy.type = core->type; 3303 3304 #ifndef TSCE_PMD_CRC_UCODE 3305 /* next we need to check if the load is correct or not */ 3306 if (eagle_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) &tsce_ucode, tsce_ucode_len)) { 3307 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 3308 PHYMOD_IF_ERR_RETURN (PHYMOD_E_INIT); 3309 } 3310 #endif /* TSCE_PMD_CRC_UCODE */ 3311 3312 PHYMOD_IF_ERR_RETURN 3313 (eagle_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1)); 3314 3315 /* next we need to set the uc active and release uc */ 3316 PHYMOD_IF_ERR_RETURN 3317 (eagle_uc_active_set(&core_copy.access ,1)); 3318 3319 /* release the uc reset */ 3320 PHYMOD_IF_ERR_RETURN 3321 (eagle_uc_reset(&core_copy.access ,1)); 3322 /* we need to wait at least 10ms for the uc to settle */ 3323 /* PHYMOD_USLEEP(10000); */ 3324 3325 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 3326 #ifndef TSCE_PMD_CRC_UCODE 3327 /* poll the ready bit in 10 ms */ 3328 eagle_tsc_poll_uc_dsc_ready_for_cmd_equals_1(&phy_access_copy.access, 1); 3329 #else 3330 PHYMOD_IF_ERR_RETURN( 3331 eagle_tsc_ucode_crc_verify( &core_copy.access, tsce_ucode_len,tsce_ucode_crc)); 3332 #endif /* TSCE_PMD_CRC_UCODE */ 3333 } 3334 3335 PHYMOD_IF_ERR_RETURN( 3336 eagle_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0)); 3337 3338 /* next check if in pcs-bypass mode */ 3339 if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(core->device_op_mode)) { 3340 phy_access_copy.access.lane_mask = 0xf; 3341 PHYMOD_IF_ERR_RETURN( 3342 temod_pcs_ilkn_mode_set(&phy_access_copy.access)); 3343 phy_access_copy.access.lane_mask = 0x1; 3344 } 3345 3346 /* now config the lane mapping and polarity */ 3347 PHYMOD_IF_ERR_RETURN 3348 (tsce_core_lane_map_set(core, &init_config->lane_map)); 3349 3350 /* if TSC12, set the mld phys map mode */ 3351 if(PHYMOD_INTF_MODES_TRIPLE_CORE_GET(&init_config->interface)) { 3352 if(PHYMOD_INTF_MODES_TC_343_GET(&init_config->interface)) { 3353 PHYMOD_IF_ERR_RETURN 3354 (temod_tsc12_control(&core->access, -1, 0)); 3355 } else if(PHYMOD_INTF_MODES_TC_343_GET(&init_config->interface)) { 3356 PHYMOD_IF_ERR_RETURN 3357 (temod_tsc12_control(&core->access, -1, 1)); 3358 } else if(PHYMOD_INTF_MODES_TC_343_GET(&init_config->interface)) { 3359 PHYMOD_IF_ERR_RETURN 3360 (temod_tsc12_control(&core->access, -1, 2)); 3361 } 3362 } 3363 3364 #if 0 3365 /* NEED TO REVISIT */ 3366 PHYMOD_IF_ERR_RETURN 3367 (temod_autoneg_set_init(&core->access, &an)); 3368 #endif 3369 PHYMOD_IF_ERR_RETURN 3370 (temod_autoneg_timer_init(&core->access)); 3371 3372 /* mld has 2 reg copies */ 3373 phy_access_copy.access.lane_mask = 0xf; 3374 PHYMOD_IF_ERR_RETURN 3375 (temod_mld_am_timers_set(&phy_access_copy.access)); 3376 3377 phy_access_copy.access.lane_mask = 0x1; 3378 3379 PHYMOD_IF_ERR_RETURN 3380 (temod_master_port_num_set(&core->access, 0)); 3381 PHYMOD_IF_ERR_RETURN 3382 (temod_cl48_lfrfli_init(&core->access)); 3383 3384 PHYMOD_IF_ERR_RETURN 3385 (eagle_core_soft_reset_release(&core_copy.access, 0)); 3386 3387 /* plldiv CONFIG */ 3388 PHYMOD_IF_ERR_RETURN 3389 (temod_pll_config_set(&phy_access_copy.access, TEMOD_PLL_MODE_DIV_66, init_config->interface.ref_clock)); 3390 3391 /* don't overide the fw that set in config set if not specified */ 3392 firmware_core_config_tmp = init_config->firmware_core_config; 3393 firmware_core_config_tmp.CoreConfigFromPCS = 0; 3394 /* set the vco rate to be default at 10.3125G */ 3395 firmware_core_config_tmp.VcoRate = 0x13; 3396 3397 PHYMOD_IF_ERR_RETURN 3398 (tsce_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 3399 3400 3401 PHYMOD_IF_ERR_RETURN 3402 (temod_cl74_chng_default (&core_copy.access)); 3403 3404 /* release core soft reset */ 3405 PHYMOD_IF_ERR_RETURN 3406 (eagle_core_soft_reset_release(&core_copy.access, 1)); 3407 3408 return PHYMOD_E_NONE; 3409 } 3410 3411 int tsce_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 3412 { 3413 if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) && 3414 !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) || 3415 PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) { 3416 PHYMOD_IF_ERR_RETURN 3417 (_tsce_core_init_pass1(core, init_config, core_status)); 3418 3419 if (PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) { 3420 return PHYMOD_E_NONE; 3421 } 3422 } 3423 3424 if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) && 3425 !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) || 3426 PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) { 3427 PHYMOD_IF_ERR_RETURN 3428 (_tsce_core_init_pass2(core, init_config, core_status)); 3429 } 3430 3431 return PHYMOD_E_NONE; 3432 3433 } 3434 3435 int tsce_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 3436 { 3437 int pll_restart = 0; 3438 const phymod_access_t *pm_acc = &phy->access; 3439 phymod_phy_access_t pm_phy_copy; 3440 int start_lane, num_lane, i; 3441 int lane_bkup; 3442 phymod_polarity_t tmp_pol; 3443 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 3444 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 3445 3446 /* next program the tx fir taps and driver current based on the input */ 3447 PHYMOD_IF_ERR_RETURN 3448 (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane)); 3449 /* per lane based reset release */ 3450 PHYMOD_IF_ERR_RETURN 3451 (temod_pmd_x4_reset(pm_acc)); 3452 3453 /* poll for per lane uc_dsc_ready */ 3454 lane_bkup = pm_phy_copy.access.lane_mask; 3455 for (i = 0; i < num_lane; i++) { 3456 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3457 continue; 3458 } 3459 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 3460 PHYMOD_IF_ERR_RETURN 3461 (eagle_lane_soft_reset_release(&pm_phy_copy.access, 1)); 3462 } 3463 pm_phy_copy.access.lane_mask = lane_bkup; 3464 3465 /* program the rx/tx polarity */ 3466 for (i = 0; i < num_lane; i++) { 3467 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3468 continue; 3469 } 3470 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3471 tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1; 3472 tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1; 3473 PHYMOD_IF_ERR_RETURN 3474 (tsce_phy_polarity_set(&pm_phy_copy, &tmp_pol)); 3475 } 3476 3477 for (i = 0; i < num_lane; i++) { 3478 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3479 continue; 3480 } 3481 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3482 PHYMOD_IF_ERR_RETURN 3483 (tsce_phy_tx_set(&pm_phy_copy, &init_config->tx[i])); 3484 } 3485 3486 /* next check if pcs-bypass mode */ 3487 if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy->device_op_mode)) { 3488 PHYMOD_IF_ERR_RETURN 3489 (eagle_pmd_tx_disable_pin_dis_set(&phy->access, 1)); 3490 PHYMOD_IF_ERR_RETURN 3491 (temod_init_pcs_ilkn(&phy->access)); 3492 } 3493 3494 3495 pm_phy_copy.access.lane_mask = 0x1; 3496 3497 PHYMOD_IF_ERR_RETURN 3498 (temod_update_port_mode(pm_acc, &pll_restart)); 3499 3500 PHYMOD_IF_ERR_RETURN 3501 (temod_rx_lane_control_set(pm_acc, 1)); 3502 PHYMOD_IF_ERR_RETURN 3503 (temod_tx_lane_control_set(pm_acc, TEMOD_TX_LANE_RESET_TRAFFIC_ENABLE)); /* TX_LANE_CONTROL */ 3504 3505 return PHYMOD_E_NONE; 3506 } 3507 3508 3509 int tsce_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 3510 { 3511 int start_lane, num_lane; 3512 int rv = PHYMOD_E_NONE; 3513 int i = 0; 3514 uint32_t cl72_en; 3515 phymod_phy_access_t phy_copy; 3516 3517 const phymod_access_t *pm_acc; 3518 pm_acc = &phy->access; 3519 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3520 3521 /* next figure out the lane num and start_lane based on the input */ 3522 PHYMOD_IF_ERR_RETURN 3523 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3524 3525 switch (loopback) { 3526 case phymodLoopbackGlobal : 3527 PHYMOD_IF_ERR_RETURN 3528 (tsce_phy_cl72_get(phy, &cl72_en)); 3529 if((cl72_en == 1) && (enable == 1)) { 3530 PHYMOD_DEBUG_ERROR(("adr=%0"PRIx32",lane 0x%x: Error! pcs gloop not supported with cl72 enabled\n", pm_acc->addr, start_lane)); 3531 break; 3532 } 3533 PHYMOD_IF_ERR_RETURN(temod_tx_loopback_control(&phy->access, enable, start_lane, num_lane)); 3534 break; 3535 case phymodLoopbackGlobalPMD : 3536 PHYMOD_IF_ERR_RETURN 3537 (tsce_phy_cl72_get(phy, &cl72_en)); 3538 if((cl72_en == 1) && (enable == 1)) { 3539 PHYMOD_DEBUG_ERROR(("adr=%0"PRIx32",lane 0x%x: Error! pmd gloop not supported with cl72 enabled\n", pm_acc->addr, start_lane)); 3540 break; 3541 } 3542 for (i = 0; i < num_lane; i++) { 3543 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3544 continue; 3545 } 3546 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3547 PHYMOD_IF_ERR_RETURN(temod_tx_squelch_set(&phy_copy.access, enable)); 3548 PHYMOD_IF_ERR_RETURN(eagle_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable)); 3549 PHYMOD_IF_ERR_RETURN(eagle_pmd_force_signal_detect(&phy_copy.access, (int) enable)); 3550 PHYMOD_IF_ERR_RETURN(temod_rx_lane_control_set(&phy_copy.access, 1)); 3551 } 3552 break; 3553 case phymodLoopbackRemotePMD : 3554 PHYMOD_IF_ERR_RETURN(eagle_tsc_rmt_lpbk(&phy->access, (uint8_t)enable)); 3555 break; 3556 case phymodLoopbackRemotePCS : 3557 /* PHYMOD_IF_ERR_RETURN(temod_rx_loopback_control(&phy->access, enable, enable, enable)); */ /* RAVI */ 3558 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 3559 (_PHYMOD_MSG("PCS Remote LoopBack not supported"))); 3560 break; 3561 default : 3562 break; 3563 } 3564 return rv; 3565 } 3566 3567 int tsce_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 3568 { 3569 uint32_t enable_core; 3570 int start_lane, num_lane; 3571 3572 *enable = 0; 3573 3574 /* next figure out the lane num and start_lane based on the input */ 3575 PHYMOD_IF_ERR_RETURN 3576 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3577 3578 switch (loopback) { 3579 case phymodLoopbackGlobal : 3580 PHYMOD_IF_ERR_RETURN(temod_tx_loopback_get(&phy->access, &enable_core)); 3581 *enable = (enable_core >> start_lane) & 0x1; 3582 break; 3583 case phymodLoopbackGlobalPMD : 3584 PHYMOD_IF_ERR_RETURN(eagle_pmd_loopback_get(&phy->access, enable)); 3585 break; 3586 case phymodLoopbackRemotePMD : 3587 PHYMOD_IF_ERR_RETURN(eagle_tsc_rmt_lpbk_get(&phy->access, enable)); 3588 break; 3589 case phymodLoopbackRemotePCS : 3590 /* PHYMOD_IF_ERR_RETURN(temod_rx_loopback_control(&phy->access, enable, enable, enable)); */ /* RAVI */ 3591 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 3592 (_PHYMOD_MSG("PCS Remote LoopBack not supported"))); 3593 break; 3594 default : 3595 break; 3596 } 3597 return PHYMOD_E_NONE; 3598 } 3599 3600 3601 int tsce_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_seq_done){ 3602 PHYMOD_IF_ERR_RETURN(temod_pmd_lock_get(&phy->access, rx_seq_done)); 3603 return PHYMOD_E_NONE; 3604 } 3605 3606 3607 int tsce_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 3608 { 3609 PHYMOD_IF_ERR_RETURN(temod_get_pcs_latched_link_status(&phy->access, link_status)); 3610 return PHYMOD_E_NONE; 3611 } 3612 3613 3614 int tsce_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config) 3615 { 3616 int rv ; 3617 rv = PHYMOD_E_UNAVAIL ; 3618 3619 switch(config->param){ 3620 case phymodPcsUserSpeedParamEntry: 3621 /* no need */ 3622 break ; 3623 case phymodPcsUserSpeedParamHCD: 3624 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_SPDID) ; 3625 break ; 3626 case phymodPcsUserSpeedParamClear: 3627 if(config->mode==phymodPcsUserSpeedModeST) { 3628 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_SPDID) ; 3629 } 3630 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_RESET) ; 3631 break ; 3632 case phymodPcsUserSpeedParamPllDiv: 3633 /* not required */ 3634 break ; 3635 case phymodPcsUserSpeedParamPmaOS: 3636 /* not required */ 3637 break ; 3638 case phymodPcsUserSpeedParamScramble: 3639 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_SCR_MODE) ; 3640 break ; 3641 case phymodPcsUserSpeedParamEncode: 3642 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_ENCODE_MODE) ; 3643 break ; 3644 case phymodPcsUserSpeedParamCl48CheckEnd: 3645 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_CHKEND_EN) ; 3646 break ; 3647 case phymodPcsUserSpeedParamBlkSync: 3648 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_BLKSYNC_MODE) ; 3649 break ; 3650 case phymodPcsUserSpeedParamReorder: 3651 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_REORDER_EN) ; 3652 break ; 3653 case phymodPcsUserSpeedParamCl36Enable: 3654 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_CL36_EN) ; 3655 break ; 3656 case phymodPcsUserSpeedParamDescr1: 3657 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_DESCR_MODE) ; 3658 break ; 3659 case phymodPcsUserSpeedParamDecode1: 3660 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_DECODE_MODE) ; 3661 break ; 3662 case phymodPcsUserSpeedParamDeskew: 3663 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_DESKEW_MODE) ; 3664 break ; 3665 case phymodPcsUserSpeedParamDescr2: 3666 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_DESC2_MODE) ; 3667 break ; 3668 case phymodPcsUserSpeedParamDescr2ByteDel: 3669 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_CL36BYTEDEL_MODE) ; 3670 break ; 3671 case phymodPcsUserSpeedParamBrcm64B66: 3672 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_BRCM64B66_DESCR_MODE) ; 3673 break ; 3674 case phymodPcsUserSpeedParamSgmii: 3675 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_SGMII_SPD) ; 3676 break ; 3677 case phymodPcsUserSpeedParamClkcnt0: 3678 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_CLOCK_COUNT_0); 3679 break ; 3680 case phymodPcsUserSpeedParamClkcnt1: 3681 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_CLOCK_COUNT_1); 3682 break ; 3683 case phymodPcsUserSpeedParamLpcnt0: 3684 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_LOOP_COUNT_0); 3685 break ; 3686 case phymodPcsUserSpeedParamLpcnt1: 3687 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_LOOP_COUNT_1); 3688 break ; 3689 case phymodPcsUserSpeedParamMacCGC: 3690 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_MAC); 3691 break ; 3692 case phymodPcsUserSpeedParamRepcnt: 3693 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_PCS_REPCNT); 3694 break ; 3695 case phymodPcsUserSpeedParamCrdtEn: 3696 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_EN) ; 3697 break ; 3698 case phymodPcsUserSpeedParamPcsClkcnt: 3699 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_PCS_CLOCK_COUNT_0); 3700 break ; 3701 case phymodPcsUserSpeedParamPcsCGC: 3702 rv = TSCE_USERSPEED_CREDIT_SELECT(phy, config, TEMOD_CREDIT_PCS_GEN_COUNT); 3703 break ; 3704 case phymodPcsUserSpeedParamCl72En: 3705 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_CL72) ; 3706 break ; 3707 case phymodPcsUserSpeedParamNumOfLanes: 3708 rv = TSCE_USERSPEED_SELECT(phy, config, TEMOD_OVERRIDE_NUM_LANES) ; 3709 break ; 3710 default: 3711 break ; 3712 } 3713 return rv; 3714 } 3715 3716 int tsce_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, phymod_pcs_userspeed_config_t* config) 3717 { 3718 return PHYMOD_E_UNAVAIL; 3719 } 3720 3721 int tsce_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t *val) 3722 { 3723 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val)); 3724 return PHYMOD_E_NONE; 3725 } 3726 3727 3728 int tsce_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 3729 { 3730 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val)); 3731 return PHYMOD_E_NONE; 3732 } 3733 3734 /* pass through LPI or convert LPI to IDEL*/ 3735 int tsce_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable) 3736 { 3737 uint32_t lpi_bypass; 3738 int rv = PHYMOD_E_NONE ; 3739 lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable); 3740 enable &= 0x1; 3741 if (lpi_bypass) { 3742 rv = temod_eee_control_set(&phy->access,enable); 3743 } else { 3744 return PHYMOD_E_UNAVAIL; 3745 } 3746 return rv; 3747 } 3748 3749 int tsce_phy_eee_get(const phymod_phy_access_t* phy, uint32_t *enable) 3750 { 3751 if (PHYMOD_LPI_BYPASS_GET(*enable)) { 3752 PHYMOD_IF_ERR_RETURN(temod_eee_control_get(&phy->access, enable)); 3753 PHYMOD_LPI_BYPASS_SET(*enable); 3754 } else { 3755 return PHYMOD_E_UNAVAIL; 3756 } 3757 return PHYMOD_E_NONE; 3758 } 3759 3760 int tsce_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 3761 { 3762 uint8_t uc_lane_stopped; 3763 PHYMOD_IF_ERR_RETURN(eagle_tsc_stop_uc_lane_status(&phy->access, &uc_lane_stopped)); 3764 if (uc_lane_stopped) { 3765 PHYMOD_IF_ERR_RETURN(eagle_tsc_stop_rx_adaptation(&phy->access, 0)); 3766 } 3767 return PHYMOD_E_NONE; 3768 } 3769 3770 int tsce_phy_autoneg_oui_set(const phymod_phy_access_t* phy, phymod_autoneg_oui_t an_oui) { 3771 temod_an_oui_t oui; 3772 3773 oui.oui = an_oui.oui; 3774 oui.oui_override_hpam_adv = an_oui.oui_override_hpam_adv; 3775 oui.oui_override_hpam_det = an_oui.oui_override_hpam_det; 3776 oui.oui_override_bam73_adv = an_oui.oui_override_bam73_adv; 3777 oui.oui_override_bam73_det = an_oui.oui_override_bam73_det; 3778 oui.oui_override_bam37_adv = an_oui.oui_override_bam37_adv; 3779 oui.oui_override_bam37_det = an_oui.oui_override_bam37_det; 3780 3781 PHYMOD_IF_ERR_RETURN(temod_an_oui_set(&phy->access, oui)); 3782 3783 return PHYMOD_E_NONE; 3784 } 3785 3786 int tsce_phy_autoneg_oui_get(const phymod_phy_access_t* phy, phymod_autoneg_oui_t* an_oui) { 3787 temod_an_oui_t oui; 3788 3789 PHYMOD_IF_ERR_RETURN(temod_an_oui_get(&phy->access, &oui)); 3790 3791 an_oui->oui_override_hpam_adv = oui.oui_override_hpam_adv; 3792 an_oui->oui_override_hpam_det = oui.oui_override_hpam_det; 3793 an_oui->oui_override_bam73_adv = oui.oui_override_bam73_adv; 3794 an_oui->oui_override_bam73_det = oui.oui_override_bam73_det; 3795 an_oui->oui_override_bam37_adv = oui.oui_override_bam37_adv; 3796 an_oui->oui_override_bam37_det = oui.oui_override_bam37_det; 3797 3798 return PHYMOD_E_NONE; 3799 } 3800 3801 int tsce_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* value) 3802 { 3803 uint32_t local_rx_signal_det; 3804 int start_lane, num_lane, i; 3805 3806 *value = 1; 3807 3808 PHYMOD_IF_ERR_RETURN 3809 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3810 3811 for (i = 0; i < num_lane; i++) { 3812 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3813 continue; 3814 } 3815 PHYMOD_IF_ERR_RETURN 3816 (eagle_tsc_signal_detect(&phy->access, &local_rx_signal_det)); 3817 *value = *value & local_rx_signal_det; 3818 } 3819 3820 return PHYMOD_E_NONE; 3821 } 3822 3823 int tsce_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value) 3824 { 3825 int start_lane, num_lane; 3826 phymod_phy_access_t phy_copy; 3827 int hz_l, hz_r, vt_u, vt_d; 3828 3829 3830 /* first get the start_lane */ 3831 PHYMOD_IF_ERR_RETURN 3832 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3833 3834 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3835 phy_copy.access.lane_mask = 0x1 << start_lane; 3836 3837 PHYMOD_IF_ERR_RETURN 3838 (eagle_tsc_get_eye_margin_est(&phy_copy.access, &hz_l, &hz_r, &vt_u, &vt_d)); 3839 3840 switch (eye_margin_mode) { 3841 case phymod_eye_marign_HZ_L: 3842 *value = hz_l; 3843 break; 3844 case phymod_eye_marign_HZ_R: 3845 *value = hz_r; 3846 break; 3847 case phymod_eye_marign_VT_U: 3848 *value = vt_u; 3849 break; 3850 case phymod_eye_marign_VT_D: 3851 *value = vt_d; 3852 break; 3853 default: 3854 *value = 0; 3855 break; 3856 } 3857 3858 return PHYMOD_E_NONE; 3859 } 3860 3861 int tsce_phy_hg2_codec_control_set(const phymod_phy_access_t* phy, 3862 phymod_phy_hg2_codec_t hg2_codec) 3863 { 3864 temod_hg2_codec_t local_copy; 3865 switch (hg2_codec) { 3866 case phymodBcmHG2CodecOff: 3867 local_copy = TEMOD_HG2_CODEC_OFF; 3868 break; 3869 case phymodBcmHG2CodecOnWith8ByteIPG: 3870 local_copy = TEMOD_HG2_CODEC_ON_8BYTE_IPG; 3871 break; 3872 case phymodBcmHG2CodecOnWith9ByteIPG: 3873 local_copy = TEMOD_HG2_CODEC_ON_9BYTE_IPG; 3874 break; 3875 default: 3876 local_copy = TEMOD_HG2_CODEC_OFF; 3877 break; 3878 } 3879 PHYMOD_IF_ERR_RETURN(temod_hg2_codec_set(&phy->access, local_copy)); 3880 return PHYMOD_E_NONE; 3881 } 3882 3883 int tsce_phy_hg2_codec_control_get(const phymod_phy_access_t* phy, 3884 phymod_phy_hg2_codec_t* hg2_codec) 3885 { 3886 temod_hg2_codec_t local_copy; 3887 3888 PHYMOD_IF_ERR_RETURN(temod_hg2_codec_get(&phy->access, &local_copy)); 3889 3890 switch (local_copy) { 3891 case TEMOD_HG2_CODEC_OFF: 3892 *hg2_codec = phymodBcmHG2CodecOff; 3893 break; 3894 case TEMOD_HG2_CODEC_ON_8BYTE_IPG: 3895 *hg2_codec = phymodBcmHG2CodecOnWith8ByteIPG; 3896 break; 3897 case TEMOD_HG2_CODEC_ON_9BYTE_IPG: 3898 *hg2_codec = phymodBcmHG2CodecOnWith9ByteIPG; 3899 break; 3900 default: 3901 *hg2_codec = phymodBcmHG2CodecOff; 3902 break; 3903 } 3904 return PHYMOD_E_NONE; 3905 } 3906 3907 int tsce_phy_rx_ppm_get(const phymod_phy_access_t* phy, int16_t* rx_ppm) 3908 { 3909 int start_lane, num_lane; 3910 phymod_phy_access_t pm_phy_copy; 3911 3912 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 3913 3914 PHYMOD_IF_ERR_RETURN 3915 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3916 3917 pm_phy_copy.access.lane_mask = 1 << start_lane; 3918 PHYMOD_IF_ERR_RETURN 3919 (eagle_tsc_rx_ppm(&pm_phy_copy.access, rx_ppm)); 3920 3921 return PHYMOD_E_NONE; 3922 } 3923 3924 int tsce_phy_master_set(const phymod_phy_access_t* phy, phymod_master_mode_t master_mode) 3925 { 3926 int start_lane, num_lane; 3927 phymod_phy_access_t phy_copy; 3928 int ms_mode = TEMOD_SGMII_SLAVE; 3929 3930 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3931 3932 PHYMOD_IF_ERR_RETURN 3933 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3934 3935 phy_copy.access.lane_mask = 1 << start_lane; 3936 switch (master_mode) { 3937 case phymodMSSlave: 3938 ms_mode = TEMOD_SGMII_SLAVE; 3939 break; 3940 case phymodMSMaster: 3941 ms_mode = TEMOD_SGMII_MASTER; 3942 break; 3943 default: 3944 return PHYMOD_E_PARAM; 3945 } 3946 PHYMOD_IF_ERR_RETURN 3947 (temod_sgmii_master_set(&phy_copy.access, ms_mode)); 3948 3949 return PHYMOD_E_NONE; 3950 3951 } 3952 3953 int tsce_phy_master_get(const phymod_phy_access_t* phy, phymod_master_mode_t *master_mode) 3954 { 3955 int start_lane, num_lane; 3956 phymod_phy_access_t phy_copy; 3957 int ms_mode; 3958 3959 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3960 3961 PHYMOD_IF_ERR_RETURN 3962 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3963 3964 phy_copy.access.lane_mask = 1 << start_lane; 3965 PHYMOD_IF_ERR_RETURN 3966 (temod_sgmii_master_get(&phy_copy.access, &ms_mode)); 3967 switch (ms_mode) { 3968 case TEMOD_SGMII_SLAVE: 3969 *master_mode = phymodMSSlave; 3970 break; 3971 case TEMOD_SGMII_MASTER: 3972 *master_mode = phymodMSMaster; 3973 break; 3974 default: 3975 *master_mode = phymodMSNone; 3976 break; 3977 } 3978 3979 return PHYMOD_E_NONE; 3980 3981 } 3982 3983 int tsce_phy_synce_clk_ctrl_set(const phymod_phy_access_t* phy, 3984 phymod_synce_clk_ctrl_t cfg) 3985 { 3986 phymod_phy_access_t phy_copy; 3987 int start_lane, num_lane; 3988 3989 /* TSCE only supports stage1 divider mode */ 3990 if (cfg.stg0_mode != -1 || cfg.sdm_val != 0) { 3991 return PHYMOD_E_UNAVAIL; 3992 } 3993 3994 PHYMOD_IF_ERR_RETURN 3995 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3996 3997 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3998 phy_copy.access.lane_mask = 0x1 << start_lane; 3999 4000 PHYMOD_IF_ERR_RETURN 4001 (temod_synce_mode_set(&phy_copy.access, cfg.stg1_mode)); 4002 4003 return PHYMOD_E_NONE; 4004 } 4005 4006 int tsce_phy_synce_clk_ctrl_get(const phymod_phy_access_t* phy, 4007 phymod_synce_clk_ctrl_t *cfg) 4008 { 4009 PHYMOD_IF_ERR_RETURN 4010 (temod_synce_mode_get(&phy->access, &(cfg->stg1_mode))); 4011 4012 return PHYMOD_E_NONE; 4013 }