tscf.c (149518B)
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 #ifndef _DV_TB_ 11 #define _SDK_TEFMOD_ 1 12 #endif 13 14 #include <phymod/phymod.h> 15 #include <phymod/phymod_system.h> 16 #include <phymod/phymod_util.h> 17 #include <phymod/chip/bcmi_tscf_xgxs_defs.h> 18 #include <phymod/chip/falcon.h> 19 #include <phymod/chip/tscf.h> 20 #include "../../tscf/tier1/tefmod_enum_defines.h" 21 #include "../../tscf/tier1/tefmod.h" 22 #include "../../tscf/tier1/tefmod_device.h" 23 #include "../../tscf/tier1/tefmod_sc_lkup_table.h" 24 #include "../../tscf/tier1/tfPCSRegEnums.h" 25 #include "../../falcon/tier1/falcon_cfg_seq.h" 26 #include "../../falcon/tier1/falcon_tsc_common.h" 27 #include "../../falcon/tier1/falcon_tsc_interface.h" 28 #include "../../falcon/tier1/falcon_tsc_debug_functions.h" 29 #include "../../falcon/tier1/falcon_tsc_dependencies.h" 30 31 #define TSCF_ID0 0x600d 32 #define TSCF_ID1 0x8770 33 #define TSCF_MODEL 0x14 34 #define TSCF_GEN2_MODEL 0x15 35 #define TSCF_TECH_PROC 0x3 36 #define FALCON_MODEL 0x1b 37 #define TSCF_NOF_LANES_IN_CORE 4 38 #define TSCF_LANE_SWAP_LANE_MASK 3 39 #define TSCF_NOF_DFES 5 40 #define TSCF_PHY_ALL_LANES 0xf 41 #define TSCF_REV_LETTER_A 0x0 42 #define TSCF_REV_LETTER_B 0x1 43 #define TSCF_REV_LETTER_C 0x2 44 #define TSCF_REV_NUM_0 0x0 45 #define TSCF_REV_NUM_1 0x1 46 47 #define TSCF_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 48 do{\ 49 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\ 50 (_phy_access)->type = (_core_access)->type; \ 51 (_phy_access)->port_loc = (_core_access)->port_loc; \ 52 (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \ 53 (_phy_access)->access.lane_mask = TSCF_PHY_ALL_LANES; \ 54 }while(0) 55 56 #define TSCF_MAX_FIRMWARES (5) 57 58 #define TSCF_PMD_CRC_UCODE 1 59 60 /* uController's firmware */ 61 extern unsigned char tscf_ucode[]; 62 extern unsigned short tscf_ucode_ver; 63 extern unsigned short tscf_ucode_crc; 64 extern unsigned short tscf_ucode_len; 65 66 67 typedef int (*sequncer_control_f)(const phymod_access_t* core, uint32_t enable); 68 typedef int (*rx_DFE_tap_control_set_f)(const phymod_access_t* phy, uint32_t val); 69 70 STATIC 71 int _tscf_pll_multiplier_get(uint32_t pll_div, uint32_t *pll_multiplier) 72 { 73 switch (pll_div) { 74 case 0x0: 75 *pll_multiplier = 64; 76 break; 77 case 0x1: 78 *pll_multiplier = 66; 79 break; 80 case 0x2: 81 *pll_multiplier = 80; 82 break; 83 case 0x3: 84 *pll_multiplier = 128; 85 break; 86 case 0x4: 87 *pll_multiplier = 132; 88 break; 89 case 0x5: 90 *pll_multiplier = 140; 91 break; 92 case 0x6: 93 *pll_multiplier = 160; 94 break; 95 case 0x7: 96 *pll_multiplier = 165; 97 break; 98 case 0x8: 99 *pll_multiplier = 168; 100 break; 101 case 0x9: 102 *pll_multiplier = 170; 103 break; 104 case 0xa: 105 *pll_multiplier = 175; 106 break; 107 case 0xb: 108 *pll_multiplier = 180; 109 break; 110 case 0xc: 111 *pll_multiplier = 184; 112 break; 113 case 0xd: 114 *pll_multiplier = 200; 115 break; 116 case 0xe: 117 *pll_multiplier = 224; 118 break; 119 case 0xf: 120 *pll_multiplier = 264; 121 break; 122 default: 123 *pll_multiplier = 165; 124 break; 125 } 126 return PHYMOD_E_NONE; 127 } 128 129 STATIC 130 int _tscf_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 131 { 132 struct falcon_tsc_uc_lane_config_st serdes_firmware_config; 133 phymod_phy_access_t phy_copy; 134 int start_lane, num_lane, i; 135 uint32_t rst_status; 136 uint32_t is_warm_boot; 137 138 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 139 PHYMOD_IF_ERR_RETURN 140 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 141 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 142 143 for (i = 0; i < num_lane; i++) { 144 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 145 continue; 146 } 147 phy_copy.access.lane_mask = 1 << (start_lane + i); 148 serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 149 serdes_firmware_config.field.an_enabled = fw_config.AnEnabled; 150 serdes_firmware_config.field.dfe_on = fw_config.DfeOn; 151 serdes_firmware_config.field.force_brdfe_on = fw_config.ForceBrDfe; 152 /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */ 153 serdes_firmware_config.field.scrambling_dis = fw_config.ScramblingDisable; 154 serdes_firmware_config.field.unreliable_los = fw_config.UnreliableLos; 155 serdes_firmware_config.field.media_type = fw_config.MediaType; 156 serdes_firmware_config.field.dfe_lp_mode = fw_config.LpDfeOn; 157 serdes_firmware_config.field.cl72_auto_polarity_en = fw_config.Cl72AutoPolEn; 158 serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO; 159 160 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy_copy.access, &is_warm_boot)); 161 162 if(!is_warm_boot) { 163 PHYMOD_IF_ERR_RETURN(falcon_lane_soft_reset_read(&phy_copy.access, &rst_status)); 164 if(rst_status) PHYMOD_IF_ERR_RETURN (falcon_lane_soft_reset_release(&phy_copy.access, 0)); 165 PHYMOD_IF_ERR_RETURN(falcon_tsc_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config)); 166 if(rst_status) PHYMOD_IF_ERR_RETURN (falcon_lane_soft_reset_release(&phy_copy.access, 1)); 167 } 168 } 169 return PHYMOD_E_NONE; 170 } 171 172 173 int tscf_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 174 { 175 int ioerr = 0; 176 const phymod_access_t *pm_acc = &core->access; 177 PHYID2r_t id2; 178 PHYID3r_t id3; 179 MAIN0_SERDESIDr_t serdesid; 180 /* DIG_REVID0r_t revid; */ 181 uint32_t model; 182 183 *is_identified = 0; 184 185 if(core_id == 0){ 186 ioerr += READ_PHYID2r(pm_acc, &id2); 187 ioerr += READ_PHYID3r(pm_acc, &id3); 188 } 189 else{ 190 PHYID2r_SET(id2, ((core_id >> 16) & 0xffff)); 191 PHYID3r_SET(id3, core_id & 0xffff); 192 } 193 194 if (PHYID2r_REGID1f_GET(id2) == TSCF_ID0 && 195 (PHYID3r_REGID2f_GET(id3) == TSCF_ID1)) { 196 /* PHY IDs match - now check PCS model */ 197 ioerr += READ_MAIN0_SERDESIDr(pm_acc, &serdesid); 198 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 199 if ((model == TSCF_MODEL) || (model == TSCF_GEN2_MODEL)) { 200 if (MAIN0_SERDESIDr_TECH_PROCf_GET(serdesid) == TSCF_TECH_PROC) { 201 *is_identified = 1; 202 } 203 } 204 } 205 206 return ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE; 207 208 } 209 210 211 int tscf_core_info_get(const phymod_core_access_t* phy, phymod_core_info_t* info) 212 { 213 uint32_t serdes_id; 214 PHYID2r_t id2; 215 PHYID3r_t id3; 216 const phymod_access_t *pm_acc = &phy->access; 217 uint32_t rev_number; 218 uint32_t rev_letter; 219 char core_name[15] = "Tscf"; 220 221 PHYMOD_IF_ERR_RETURN 222 (tefmod_revid_read(&phy->access, &serdes_id)); 223 info->serdes_id = serdes_id; 224 rev_letter = (serdes_id & 0xc000) >> 14; 225 rev_number = (serdes_id & 0x3800) >> 11; 226 if ((serdes_id & 0x3f) == TSCF_MODEL) { 227 /* for rev A*/ 228 if (rev_letter == 0) 229 info->core_version = phymodCoreVersionTscfA0; 230 /* for rev B*/ 231 if (rev_letter == 1) { 232 switch(rev_number) { 233 case 0: 234 info->core_version = phymodCoreVersionTscfB0; 235 break; 236 case 1: 237 info->core_version = phymodCoreVersionTscfB1; 238 break; 239 } 240 } 241 } 242 PHYMOD_IF_ERR_RETURN 243 (phymod_core_name_get(phy, serdes_id, core_name, info)); 244 245 PHYMOD_IF_ERR_RETURN(READ_PHYID2r(pm_acc, &id2)); 246 PHYMOD_IF_ERR_RETURN(READ_PHYID3r(pm_acc, &id3)); 247 248 info->phy_id0 = (uint16_t) id2.v[0]; 249 info->phy_id1 = (uint16_t) id3.v[0]; 250 251 return PHYMOD_E_NONE; 252 } 253 254 255 /* 256 * set lane swapping for core 257 * The tx swap is composed of PCS swap and after that the PMD swap. 258 * The rx swap is composed just by PCS swap 259 * 260 * lane_map_tx and lane_map_rx[lane=logic_lane] are logic-lane base. 261 * pmd_swap and register is logic_lane base. 262 * but pmd_tx_map and addr_index_swap (and registers) are physical lane base 263 */ 264 265 int tscf_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 266 { 267 uint32_t pcs_swap = 0 , pmd_swap = 0, lane; 268 uint32_t addr_index_swap = 0, pmd_tx_map =0; 269 270 if(lane_map->num_of_lanes != TSCF_NOF_LANES_IN_CORE){ 271 return PHYMOD_E_CONFIG; 272 } 273 for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){ 274 if(lane_map->lane_map_rx[lane] >= TSCF_NOF_LANES_IN_CORE){ 275 return PHYMOD_E_CONFIG; 276 } 277 /*encode each lane as four bits*/ 278 /*pcs_map[lane] = rx_map[lane]*/ 279 pcs_swap += lane_map->lane_map_rx[lane]<<(lane*4); 280 } 281 282 for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){ 283 if(lane_map->lane_map_tx[lane] >= TSCF_NOF_LANES_IN_CORE){ 284 return PHYMOD_E_CONFIG; 285 } 286 /*encode each lane as four bits*/ 287 /*considering the pcs lane swap: pmd_map[pcs_map[lane]] = tx_map[lane]*/ 288 pmd_swap += lane_map->lane_map_tx[lane]<<(lane_map->lane_map_rx[lane]*4); 289 } 290 291 for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){ 292 addr_index_swap |= (lane << 4*((pcs_swap >> lane*4) & 0xf)) ; 293 pmd_tx_map |= (lane << 4*((pmd_swap >> lane*4) & 0xf)) ; 294 } 295 if (!PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(core->device_op_mode)) { 296 PHYMOD_IF_ERR_RETURN(tefmod_pcs_lane_swap(&core->access, pcs_swap)); 297 298 PHYMOD_IF_ERR_RETURN 299 (tefmod_pmd_addr_lane_swap(&core->access, addr_index_swap)); 300 } 301 PHYMOD_IF_ERR_RETURN 302 (tefmod_pmd_lane_swap_tx(&core->access, 303 pmd_tx_map)); 304 return PHYMOD_E_NONE; 305 } 306 307 308 int tscf_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 309 { 310 uint32_t pmd_swap = 0 , pcs_swap = 0, lane; 311 PHYMOD_IF_ERR_RETURN(tefmod_pcs_lane_swap_get(&core->access, &pcs_swap)); 312 PHYMOD_IF_ERR_RETURN(tefmod_pmd_lane_swap_tx_get(&core->access, &pmd_swap)); 313 for( lane = 0 ; lane < TSCF_NOF_LANES_IN_CORE ; lane++){ 314 /*deccode each lane from four bits*/ 315 lane_map->lane_map_rx[lane] = (pcs_swap>>(lane*4)) & TSCF_LANE_SWAP_LANE_MASK; 316 /*considering the pcs lane swap: tx_map[lane] = pmd_map[pcs_map[lane]]*/ 317 lane_map->lane_map_tx[lane] = (pmd_swap>>(lane_map->lane_map_rx[lane]*4)) & TSCF_LANE_SWAP_LANE_MASK; 318 } 319 lane_map->num_of_lanes = TSCF_NOF_LANES_IN_CORE; 320 return PHYMOD_E_NONE; 321 } 322 323 324 int tscf_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 325 { 326 327 return PHYMOD_E_UNAVAIL; /*Not implemented, yet*/ 328 329 } 330 331 332 int tscf_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 333 { 334 335 return PHYMOD_E_UNAVAIL; /*Not implemented, yet*/ 336 337 } 338 339 340 int tscf_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 341 { 342 /* fw_info->fw_crc = tscf_ucode_crc; 343 fw_info->fw_version = tscf_ucode_ver; */ 344 return PHYMOD_E_NONE; 345 } 346 347 348 /* load tscf fw. the fw_loader parameter is valid just for external fw load*/ 349 STATIC 350 int _tscf_core_firmware_load(const phymod_core_access_t* core, phymod_firmware_load_method_t load_method, phymod_firmware_loader_f fw_loader) 351 { 352 switch(load_method){ 353 case phymodFirmwareLoadMethodInternal: 354 PHYMOD_IF_ERR_RETURN(falcon_tsc_ucode_mdio_load(&core->access, tscf_ucode, tscf_ucode_len)); 355 break; 356 case phymodFirmwareLoadMethodExternal: 357 PHYMOD_NULL_CHECK(fw_loader); 358 PHYMOD_IF_ERR_RETURN(falcon_tsc_ucode_init(&core->access)); 359 PHYMOD_IF_ERR_RETURN 360 (falcon_pram_firmware_enable(&core->access, 1, 0)); 361 PHYMOD_IF_ERR_RETURN(fw_loader(core, tscf_ucode_len, tscf_ucode)); 362 PHYMOD_IF_ERR_RETURN 363 (falcon_pram_firmware_enable(&core->access, 0, 0)); 364 break; 365 case phymodFirmwareLoadMethodNone: 366 break; 367 default: 368 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), load_method)); 369 } 370 if(load_method != phymodFirmwareLoadMethodNone){ 371 /* PHYMOD_IF_ERR_RETURN(tscf_core_firmware_info_get(core, &actual_fw)); 372 if((tscf_ucode_crc != actual_fw.fw_crc) || (tscf_ucode_ver != actual_fw.fw_version)){ 373 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("fw load validation was failed"))); 374 } */ 375 } 376 return PHYMOD_E_NONE; 377 } 378 379 int tscf_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config) 380 { 381 struct falcon_tsc_uc_core_config_st serdes_firmware_core_config; 382 uint32_t rst_status; 383 PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config)); 384 serdes_firmware_core_config.field.core_cfg_from_pcs = fw_config.CoreConfigFromPCS; 385 serdes_firmware_core_config.field.vco_rate = fw_config.VcoRate; 386 serdes_firmware_core_config.field.disable_write_pll_iqp = fw_config.disable_write_pll_iqp; 387 PHYMOD_IF_ERR_RETURN(falcon_core_soft_reset_read(&phy->access, &rst_status)); 388 if(rst_status) PHYMOD_IF_ERR_RETURN (falcon_core_soft_reset_release(&phy->access, 0)); 389 PHYMOD_IF_ERR_RETURN(falcon_tsc_set_uc_core_config(&phy->access, serdes_firmware_core_config)); 390 if(rst_status) PHYMOD_IF_ERR_RETURN (falcon_core_soft_reset_release(&phy->access, 1)); 391 return PHYMOD_E_NONE; 392 } 393 394 395 int tscf_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config) 396 { 397 struct falcon_tsc_uc_core_config_st serdes_firmware_core_config; 398 PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_core_config(&phy->access, &serdes_firmware_core_config)); 399 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 400 fw_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs; 401 fw_config->VcoRate = serdes_firmware_core_config.field.vco_rate; 402 fw_config->disable_write_pll_iqp = serdes_firmware_core_config.field.disable_write_pll_iqp; 403 return PHYMOD_E_NONE; 404 } 405 406 407 int tscf_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 408 { 409 phymod_phy_access_t phy_copy; 410 int start_lane, num_lane, i; 411 412 PHYMOD_IF_ERR_RETURN 413 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 414 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 415 416 /*Hold the per lne soft reset bit*/ 417 for (i = 0; i < num_lane; i++) { 418 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 419 continue; 420 } 421 phy_copy.access.lane_mask = 1 << (start_lane + i); 422 PHYMOD_IF_ERR_RETURN 423 (falcon_lane_soft_reset_release(&phy_copy.access, 0)); 424 } 425 426 PHYMOD_IF_ERR_RETURN 427 (_tscf_phy_firmware_lane_config_set(phy, fw_config)); 428 /*Hold the per lne soft reset bit*/ 429 for (i = 0; i < num_lane; i++) { 430 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 431 continue; 432 } 433 phy_copy.access.lane_mask = 1 << (start_lane + i); 434 PHYMOD_IF_ERR_RETURN 435 (falcon_lane_soft_reset_release(&phy_copy.access, 1)); 436 } 437 438 /* next we need to toggle the pcs data path reset */ 439 PHYMOD_IF_ERR_RETURN 440 (tefmod_trigger_speed_change(&phy->access)); 441 442 return PHYMOD_E_NONE; 443 } 444 445 446 int tscf_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 447 { 448 struct falcon_tsc_uc_lane_config_st serdes_firmware_config; 449 phymod_phy_access_t phy_copy; 450 int start_lane, num_lane; 451 452 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 453 PHYMOD_IF_ERR_RETURN 454 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 455 456 phy_copy.access.lane_mask = 1 << start_lane ; 457 458 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 459 PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_lane_cfg(&phy_copy.access, &serdes_firmware_config)); 460 PHYMOD_MEMSET(fw_config, 0, sizeof(*fw_config)); 461 fw_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs; 462 fw_config->AnEnabled = serdes_firmware_config.field.an_enabled; 463 fw_config->DfeOn = serdes_firmware_config.field.dfe_on; 464 fw_config->LpDfeOn = serdes_firmware_config.field.dfe_lp_mode; 465 fw_config->ForceBrDfe = serdes_firmware_config.field.force_brdfe_on; 466 /* fw_config->Cl72Enable = serdes_firmware_config.field.cl72_emulation_en; */ 467 fw_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis; 468 fw_config->UnreliableLos = serdes_firmware_config.field.unreliable_los; 469 fw_config->MediaType = serdes_firmware_config.field.media_type; 470 fw_config->Cl72AutoPolEn = serdes_firmware_config.field.cl72_auto_polarity_en; 471 fw_config->Cl72RestTO = serdes_firmware_config.field.cl72_restart_timeout_en; 472 473 return PHYMOD_E_NONE; 474 } 475 476 /* reset pll sequencer 477 * flags - unused parameter 478 */ 479 int tscf_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 480 { 481 return PHYMOD_E_UNAVAIL; 482 } 483 484 int tscf_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout) 485 { 486 switch(event){ 487 case phymodCoreEventPllLock: 488 /* PHYMOD_IF_ERR_RETURN(tefmod_pll_lock_wait(&core->access, timeout)); */ 489 break; 490 default: 491 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal wait event %u"), event)); 492 } 493 return PHYMOD_E_NONE; 494 } 495 496 int tscf_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* pll_multiplier) 497 { 498 phymod_phy_access_t pm_phy_copy; 499 uint32_t pll_mode = 0; 500 501 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 502 pm_phy_copy.access.lane_mask = 0x1; 503 504 PHYMOD_IF_ERR_RETURN 505 (falcon_pll_mode_get(&pm_phy_copy.access, &pll_mode)); 506 _tscf_pll_multiplier_get(pll_mode, pll_multiplier); 507 508 return PHYMOD_E_NONE; 509 } 510 511 /* reset rx sequencer 512 * flags - unused parameter 513 */ 514 int tscf_phy_rx_restart(const phymod_phy_access_t* phy) 515 { 516 PHYMOD_IF_ERR_RETURN(falcon_tsc_rx_restart(&phy->access, 1)); 517 return PHYMOD_E_NONE; 518 } 519 520 521 int tscf_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 522 { 523 PHYMOD_IF_ERR_RETURN 524 (tefmod_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity)); 525 return PHYMOD_E_NONE; 526 } 527 528 529 int tscf_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 530 { 531 PHYMOD_IF_ERR_RETURN 532 (tefmod_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity)); 533 return PHYMOD_E_NONE; 534 } 535 536 STATIC 537 int _tscf_phy_drivermode_phymod_to_tier1(int8_t phymod_drivermode, int8_t* drivermode) 538 { 539 switch (phymod_drivermode) { 540 case phymodTxDriverModeDefault: 541 *drivermode = DM_DEFAULT; 542 break; 543 case phymodTxDriverModeHalfAmpHiImped: 544 *drivermode = DM_HALF_AMPLITUDE_HI_IMPED; 545 break; 546 case phymodTxDriverModeHalfAmp: 547 *drivermode = DM_HALF_AMPLITUDE; 548 break; 549 case phymodTxDriverModeNotSupported: 550 *drivermode = DM_NOT_SUPPORTED; 551 break; 552 default: 553 return PHYMOD_E_PARAM; 554 } 555 return PHYMOD_E_NONE; 556 557 } 558 559 STATIC 560 int _tscf_phy_drivermode_tier1_to_phymod(int8_t drivermode, int8_t* phymod_drivermode) 561 { 562 switch (drivermode) { 563 case DM_DEFAULT: 564 *phymod_drivermode = phymodTxDriverModeDefault; 565 break; 566 case DM_HALF_AMPLITUDE_HI_IMPED: 567 *phymod_drivermode = phymodTxDriverModeHalfAmpHiImped; 568 break; 569 case DM_HALF_AMPLITUDE: 570 *phymod_drivermode = phymodTxDriverModeHalfAmp; 571 break; 572 case DM_NOT_SUPPORTED: 573 *phymod_drivermode = phymodTxDriverModeNotSupported; 574 break; 575 default: 576 return PHYMOD_E_INTERNAL; 577 } 578 return PHYMOD_E_NONE; 579 580 } 581 582 int tscf_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 583 { 584 int8_t drivermode; 585 586 PHYMOD_IF_ERR_RETURN 587 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre)); 588 PHYMOD_IF_ERR_RETURN 589 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main)); 590 PHYMOD_IF_ERR_RETURN 591 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post)); 592 PHYMOD_IF_ERR_RETURN 593 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2)); 594 PHYMOD_IF_ERR_RETURN 595 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3)); 596 PHYMOD_IF_ERR_RETURN 597 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_AMP, (int8_t)tx->amp)); 598 if((tx->drivermode != -1) && 599 (phy->device_op_mode & PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE)) { 600 PHYMOD_IF_ERR_RETURN 601 (_tscf_phy_drivermode_phymod_to_tier1(tx->drivermode, &drivermode)); 602 PHYMOD_IF_ERR_RETURN 603 (falcon_tsc_write_tx_afe(&phy->access, TX_AFE_DRIVERMODE, drivermode)); 604 } 605 return PHYMOD_E_NONE; 606 } 607 608 int tscf_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 609 { 610 int8_t drivermode = 0; 611 int8_t value = 0; 612 613 PHYMOD_IF_ERR_RETURN 614 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_PRE, &value)); 615 tx->pre = value; 616 PHYMOD_IF_ERR_RETURN 617 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_MAIN, &value)); 618 tx->main = value; 619 PHYMOD_IF_ERR_RETURN 620 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST1, &value)); 621 tx->post = value; 622 PHYMOD_IF_ERR_RETURN 623 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST2, &value)); 624 tx->post2 = value; 625 PHYMOD_IF_ERR_RETURN 626 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_POST3, &value)); 627 tx->post3 = value; 628 PHYMOD_IF_ERR_RETURN 629 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_AMP, &value)); 630 tx->amp = value; 631 PHYMOD_IF_ERR_RETURN 632 (falcon_tsc_read_tx_afe(&phy->access, TX_AFE_DRIVERMODE, &drivermode)); 633 PHYMOD_IF_ERR_RETURN 634 (_tscf_phy_drivermode_tier1_to_phymod(drivermode, &value)); 635 tx->drivermode = value; 636 637 return PHYMOD_E_NONE; 638 } 639 640 int tscf_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 641 { 642 PHYMOD_IF_ERR_RETURN 643 (falcon_tsc_tx_pi_freq_override(&phy->access, 644 tx_override->phase_interpolator.enable, 645 tx_override->phase_interpolator.value)); 646 return PHYMOD_E_NONE; 647 } 648 649 int tscf_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 650 { 651 int16_t pi_value; 652 653 PHYMOD_IF_ERR_RETURN 654 (falcon_tx_pi_control_get(&phy->access, &pi_value)); 655 656 tx_override->phase_interpolator.value = (int32_t) pi_value; 657 658 return PHYMOD_E_NONE; 659 } 660 661 662 int tscf_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 663 { 664 uint32_t i; 665 uint8_t uc_lane_stopped; 666 phymod_phy_access_t pm_phy_copy; 667 int start_lane, num_lane, k; 668 669 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 670 /* next program the tx fir taps and driver current based on the input */ 671 PHYMOD_IF_ERR_RETURN 672 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 673 674 /*params check*/ 675 if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF_NOF_DFES)){ 676 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps)); 677 } 678 679 for (k = 0; k < num_lane; k++) { 680 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + k)) { 681 continue; 682 } 683 pm_phy_copy.access.lane_mask = 1 << (start_lane + k); 684 685 /*vga set*/ 686 /* first check if uc lane is stopped already */ 687 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_uc_lane_status(&pm_phy_copy.access, &uc_lane_stopped)); 688 if (!uc_lane_stopped) { 689 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&pm_phy_copy.access, 1)); 690 } 691 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_VGA, rx->vga.value)); 692 /*dfe set*/ 693 for (i = 0 ; i < rx->num_of_dfe_taps ; i++){ 694 switch (i) { 695 case 0: 696 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE1, rx->dfe[i].value)); 697 break; 698 case 1: 699 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE2, rx->dfe[i].value)); 700 break; 701 case 2: 702 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE3, rx->dfe[i].value)); 703 break; 704 case 3: 705 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE4, rx->dfe[i].value)); 706 break; 707 case 4: 708 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE5, rx->dfe[i].value)); 709 break; 710 default: 711 return PHYMOD_E_PARAM; 712 } 713 } 714 715 /*peaking filter set*/ 716 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF, rx->peaking_filter.value)); 717 718 /* low freq peak filter */ 719 PHYMOD_IF_ERR_RETURN(falcon_tsc_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF2, (int8_t)rx->low_freq_peaking_filter.value)); 720 } 721 return PHYMOD_E_NONE; 722 } 723 724 725 int tscf_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 726 { 727 int8_t tmpData; 728 729 PHYMOD_IF_ERR_RETURN 730 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_VGA, &tmpData)); 731 rx->vga.value = tmpData; 732 PHYMOD_IF_ERR_RETURN 733 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE1, &tmpData)); 734 rx->dfe[0].value = tmpData; 735 PHYMOD_IF_ERR_RETURN 736 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE2, &tmpData)); 737 rx->dfe[1].value = tmpData; 738 PHYMOD_IF_ERR_RETURN 739 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE3, &tmpData)); 740 rx->dfe[2].value = tmpData; 741 PHYMOD_IF_ERR_RETURN 742 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE4, &tmpData)); 743 rx->dfe[3].value = tmpData; 744 PHYMOD_IF_ERR_RETURN 745 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_DFE5, &tmpData)); 746 rx->dfe[4].value = tmpData; 747 PHYMOD_IF_ERR_RETURN 748 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_PF, &tmpData)); 749 rx->peaking_filter.value = tmpData; 750 PHYMOD_IF_ERR_RETURN 751 (falcon_tsc_read_rx_afe(&phy->access, RX_AFE_PF2, &tmpData)); 752 rx->low_freq_peaking_filter.value = tmpData; 753 754 rx->num_of_dfe_taps = 5; 755 rx->dfe[0].enable = 1; 756 rx->dfe[1].enable = 1; 757 rx->dfe[2].enable = 1; 758 rx->dfe[3].enable = 1; 759 rx->dfe[4].enable = 1; 760 rx->vga.enable = 1; 761 rx->low_freq_peaking_filter.enable = 1; 762 rx->peaking_filter.enable = 1; 763 764 return PHYMOD_E_NONE; 765 } 766 767 768 int tscf_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 769 { 770 771 phymod_firmware_lane_config_t fw_lane_config; 772 773 PHYMOD_IF_ERR_RETURN (tscf_phy_firmware_lane_config_get(phy, &fw_lane_config)); 774 775 if(fw_lane_config.LaneConfigFromPCS == 0) { 776 PHYMOD_IF_ERR_RETURN (falcon_phy_reset_set(phy, reset)); 777 }else{ 778 return PHYMOD_E_UNAVAIL; /*Not implemented, yet*/ 779 } 780 781 return PHYMOD_E_NONE; 782 } 783 784 785 int tscf_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 786 { 787 788 phymod_firmware_lane_config_t fw_lane_config; 789 790 PHYMOD_IF_ERR_RETURN (tscf_phy_firmware_lane_config_get(phy, &fw_lane_config)); 791 792 if(fw_lane_config.LaneConfigFromPCS == 0) { 793 PHYMOD_IF_ERR_RETURN (falcon_phy_reset_get(phy, reset)); 794 }else{ 795 return PHYMOD_E_UNAVAIL; /*Not implemented, yet*/ 796 } 797 return PHYMOD_E_NONE; 798 } 799 800 801 int tscf_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 802 { 803 phymod_phy_access_t pm_phy_copy; 804 int start_lane, num_lane, i; 805 806 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 807 /* next program the tx fir taps and driver current based on the input */ 808 PHYMOD_IF_ERR_RETURN 809 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 810 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) { 811 for (i = 0; i < num_lane; i++) { 812 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 813 continue; 814 } 815 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 816 PHYMOD_IF_ERR_RETURN(tefmod_port_enable_set(&pm_phy_copy.access, 0)); 817 } 818 } 819 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) { 820 for (i = 0; i < num_lane; i++) { 821 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 822 continue; 823 } 824 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 825 PHYMOD_IF_ERR_RETURN(tefmod_port_enable_set(&pm_phy_copy.access, 1)); 826 PHYMOD_IF_ERR_RETURN(tefmod_power_control(&phy->access, 0, 0)); 827 } 828 } 829 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) { 830 /*disable tx on the PMD side */ 831 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable(&phy->access, 1)); 832 } 833 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) { 834 /*enable tx on the PMD side */ 835 PHYMOD_IF_ERR_RETURN(falcon_tsc_tx_disable(&phy->access, 0)); 836 } 837 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) { 838 /* disable rx on the PMD side */ 839 PHYMOD_IF_ERR_RETURN(tefmod_rx_squelch_set(&phy->access, 1)); 840 } 841 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) { 842 /*enable rx on the PMD side */ 843 /* disable rx on the PMD side */ 844 PHYMOD_IF_ERR_RETURN(tefmod_rx_squelch_set(&phy->access, 0)); 845 } 846 return PHYMOD_E_NONE; 847 } 848 849 int tscf_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 850 { 851 int enable; 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(tefmod_rx_squelch_get(&pm_phy_copy.access, &enable)); 864 865 /* next check if PMD loopback is on */ 866 if (enable) { 867 PHYMOD_IF_ERR_RETURN(falcon_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 868 if (lb_enable) enable = 0; 869 } 870 871 power->rx = (enable == 1)? phymodPowerOff: phymodPowerOn; 872 /* Commented the following line. Because if in PMD loopback mode, we squelch the 873 xmit, and we should still see the correct port status */ 874 /* PHYMOD_IF_ERR_RETURN(tefmod_tx_squelch_get(&pm_phy_copy.access, &enable)); */ 875 power->tx = (enable == 1)? phymodPowerOff: phymodPowerOn; 876 return PHYMOD_E_NONE; 877 } 878 879 int tscf_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 880 { 881 phymod_firmware_lane_config_t fw_lane_config; 882 PHYMOD_IF_ERR_RETURN (tscf_phy_firmware_lane_config_get(phy, &fw_lane_config)); 883 884 switch (tx_control) { 885 case phymodTxTrafficDisable: 886 PHYMOD_IF_ERR_RETURN(tefmod_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_TRAFFIC_DISABLE)); 887 break; 888 case phymodTxTrafficEnable: 889 PHYMOD_IF_ERR_RETURN(tefmod_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_TRAFFIC_ENABLE)); 890 break; 891 case phymodTxReset: 892 PHYMOD_IF_ERR_RETURN(tefmod_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_RESET)); 893 break; 894 case phymodTxSquelchOn: 895 PHYMOD_IF_ERR_RETURN(tefmod_tx_squelch_set(&phy->access, 1)); 896 break; 897 case phymodTxSquelchOff: 898 PHYMOD_IF_ERR_RETURN(tefmod_tx_squelch_set(&phy->access, 0)); 899 break; 900 case phymodTxElectricalIdleEnable: 901 if(fw_lane_config.LaneConfigFromPCS == 0) { 902 PHYMOD_IF_ERR_RETURN(falcon_electrical_idle_set(&phy->access, 1)); 903 }else{ 904 return PHYMOD_E_UNAVAIL; /*Not implemented, yet*/ 905 } 906 break; 907 case phymodTxElectricalIdleDisable: 908 if(fw_lane_config.LaneConfigFromPCS == 0) { 909 PHYMOD_IF_ERR_RETURN(falcon_electrical_idle_set(&phy->access, 0)); 910 }else{ 911 return PHYMOD_E_UNAVAIL; /*Not implemented, yet*/ 912 } 913 break; 914 default: 915 break; 916 } 917 return PHYMOD_E_NONE; 918 919 } 920 921 int tscf_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 922 { 923 int enable, reset, tx_lane; 924 uint32_t lb_enable; 925 phymod_phy_access_t pm_phy_copy; 926 int start_lane, num_lane; 927 928 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 929 /* next program the tx fir taps and driver current based on the input */ 930 PHYMOD_IF_ERR_RETURN 931 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 932 933 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 934 935 PHYMOD_IF_ERR_RETURN(tefmod_tx_squelch_get(&pm_phy_copy.access, &enable)); 936 937 /* next check if PMD loopback is on */ 938 if (enable) { 939 PHYMOD_IF_ERR_RETURN(falcon_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 940 if (lb_enable) enable = 0; 941 } 942 943 if(enable) { 944 *tx_control = phymodTxSquelchOn; 945 } else { 946 PHYMOD_IF_ERR_RETURN(tefmod_tx_lane_control_get(&pm_phy_copy.access, &reset, &tx_lane)); 947 if (!reset) { 948 *tx_control = phymodTxReset; 949 } else if (!tx_lane) { 950 *tx_control = phymodTxTrafficDisable; 951 } else { 952 *tx_control = phymodTxTrafficEnable; 953 } 954 } 955 return PHYMOD_E_NONE; 956 } 957 958 959 int tscf_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 960 { 961 phymod_phy_access_t pm_phy_copy; 962 int start_lane, num_lane, i; 963 964 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 965 /* next program the tx fir taps and driver current based on the input */ 966 PHYMOD_IF_ERR_RETURN 967 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 968 969 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 970 971 switch (rx_control) { 972 case phymodRxReset: 973 PHYMOD_IF_ERR_RETURN(tefmod_rx_lane_control_set(&phy->access, 1)); 974 break; 975 case phymodRxDisable: 976 PHYMOD_IF_ERR_RETURN(tefmod_rx_lane_control_set(&phy->access, 0)); 977 break; 978 case phymodRxSquelchOn: 979 for (i = 0; i < num_lane; i++) { 980 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 981 continue; 982 } 983 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 984 PHYMOD_IF_ERR_RETURN(tefmod_rx_squelch_set(&pm_phy_copy.access, 1)); 985 } 986 break; 987 case phymodRxSquelchOff: 988 for (i = 0; i < num_lane; i++) { 989 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 990 continue; 991 } 992 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 993 PHYMOD_IF_ERR_RETURN(tefmod_rx_squelch_set(&pm_phy_copy.access, 0)); 994 } 995 break; 996 default: 997 break; 998 } 999 return PHYMOD_E_NONE; 1000 } 1001 1002 int tscf_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 1003 { 1004 int enable, reset; 1005 uint32_t lb_enable; 1006 phymod_phy_access_t pm_phy_copy; 1007 int start_lane, num_lane; 1008 1009 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1010 /* next program the tx fir taps and driver current based on the input */ 1011 PHYMOD_IF_ERR_RETURN 1012 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1013 1014 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1015 1016 PHYMOD_IF_ERR_RETURN(tefmod_rx_squelch_get(&pm_phy_copy.access, &enable)); 1017 /* next check if PMD loopback is on */ 1018 if (enable) { 1019 PHYMOD_IF_ERR_RETURN(falcon_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 1020 if (lb_enable) enable = 0; 1021 } 1022 if(enable) { 1023 *rx_control = phymodRxSquelchOn; 1024 } else { 1025 PHYMOD_IF_ERR_RETURN(tefmod_rx_lane_control_get(&pm_phy_copy.access, &reset)); 1026 if (reset == 0) { 1027 *rx_control = phymodRxReset; 1028 } else { 1029 *rx_control = phymodRxSquelchOff; 1030 } 1031 } 1032 return PHYMOD_E_NONE; 1033 } 1034 1035 /* 1036 * enables/disables FEC function. 1037 * enable[6:0] = Enable for fec 1038 * 0x1 Enable FEC (speed 100G CL91 or CL74) 1039 */ 1040 int tscf_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 1041 { 1042 int fec_en; 1043 tefmod_fec_type_t fec_type; 1044 1045 /* first check FEC type */ 1046 if (PHYMOD_FEC_CL91_GET(enable)) { 1047 /* enable/disable FEC CL91 */ 1048 fec_type = TEFMOD_CL91; 1049 } else if (PHYMOD_FEC_CL108_GET(enable)) { 1050 fec_type = TEFMOD_CL108; 1051 } else { 1052 fec_type = TEFMOD_CL74; 1053 } 1054 /* SOC_PHY_CONTROL_FEC_OFF(0), SOC_PHY_CONTROL_FEC_ON(1), 1055 * SOC_PHY_CONTROL_FEC_AUTO(2) are supported now. 1056 */ 1057 fec_en = enable & 0x3; 1058 PHYMOD_IF_ERR_RETURN( 1059 tefmod_FEC_control(&phy->access, fec_type, fec_en, 0)); 1060 1061 return PHYMOD_E_NONE; 1062 } 1063 1064 int tscf_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 1065 { 1066 tefmod_fec_type_t fec_type; 1067 int fec_en; 1068 1069 /* first check FEC type */ 1070 if (PHYMOD_FEC_CL91_GET(*enable)) { 1071 /* enable/disable FEC CL91 */ 1072 fec_type = TEFMOD_CL91; 1073 } else if (PHYMOD_FEC_CL108_GET(*enable)) { 1074 fec_type = TEFMOD_CL108; 1075 } else { 1076 fec_type = TEFMOD_CL74; 1077 } 1078 1079 PHYMOD_IF_ERR_RETURN( 1080 tefmod_FEC_get(&phy->access, fec_type, &fec_en)); 1081 PHYMOD_DEBUG_VERBOSE(("FEC enable state :: %x :: fec_type :: %x\n", fec_en, fec_type)); 1082 *enable = (uint32_t) fec_en; 1083 return PHYMOD_E_NONE; 1084 1085 } 1086 1087 /* 1088 * Enables/Disables FEC override bit. 1089 * 0xc055 field[4:3] 1090 * 0x1 Enable for NOFEC 100G AN 1091 */ 1092 int tscf_phy_fec_override_set(const phymod_phy_access_t* phy, uint32_t enable) 1093 { 1094 if ((enable == 0) || (enable == 1)) { 1095 PHYMOD_IF_ERR_RETURN(tefmod_fec_override_set(&phy->access, enable)); 1096 } else { 1097 PHYMOD_DEBUG_ERROR(("ERROR :: Supported input values: 1 to set FEC override, 0 to disable FEC override\n")); 1098 } 1099 1100 return PHYMOD_E_NONE; 1101 } 1102 1103 int tscf_phy_fec_override_get(const phymod_phy_access_t* phy, uint32_t* enable) 1104 { 1105 1106 PHYMOD_IF_ERR_RETURN(tefmod_fec_override_get(&phy->access, enable)); 1107 1108 return PHYMOD_E_NONE; 1109 1110 } 1111 1112 1113 STATIC 1114 int _tscf_st_hto_interface_config_set(const tefmod_device_aux_modes_t *device, int lane_num, int speed_vec, uint32_t *new_pll_div, int16_t *os_mode) 1115 { 1116 int i, max_lane=4 ; 1117 *os_mode = -1 ; 1118 /* ST */ 1119 for(i=0;i<max_lane; i++) { 1120 if(device->st_hcd[i]==speed_vec){ 1121 *new_pll_div = device->st_pll_div[i]; 1122 *os_mode = device->st_os[i] ; 1123 break ; 1124 } 1125 } 1126 /* HTO */ 1127 if(device->hto_enable[lane_num]){ 1128 *new_pll_div = device->hto_pll_div[lane_num]; 1129 *os_mode = device->hto_os[lane_num] ; 1130 } 1131 return PHYMOD_E_NONE; 1132 } 1133 1134 1135 int tscf_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config) 1136 { 1137 uint32_t current_pll_div=0; 1138 uint32_t new_pll_div=0; 1139 uint16_t new_speed_vec=0; 1140 int16_t new_os_mode =-1; 1141 tefmod_spd_intfc_type_t spd_intf = TEFMOD_SPD_ILLEGAL; 1142 phymod_phy_access_t pm_phy_copy; 1143 int start_lane, num_lane, i, pll_switch=0; 1144 int lane_bkup, os_mode; 1145 int rv = PHYMOD_E_NONE; 1146 1147 /* phymod_access_t tmp_phy_access; */ 1148 uint32_t pll_multiplier, vco_rate; 1149 1150 /* sc_table_entry exp_entry; RAVI */ 1151 phymod_firmware_lane_config_t firmware_lane_config; 1152 phymod_firmware_core_config_t firmware_core_config; 1153 1154 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 1155 PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config)); 1156 1157 firmware_lane_config.MediaType = 0; 1158 1159 /*next program the tx fir taps and driver current based on the input*/ 1160 PHYMOD_IF_ERR_RETURN 1161 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1162 1163 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1164 1165 /* first hold the pcs lane reset */ 1166 tefmod_disable_set(&phy->access); 1167 1168 /*Hold the per lane PMD soft reset bit*/ 1169 for (i = 0; i < num_lane; i++) { 1170 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1171 continue; 1172 } 1173 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1174 PHYMOD_IF_ERR_RETURN 1175 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1176 } 1177 /* remove pmd_tx_disable_pin_dis it may be asserted because of ILKn */ 1178 if(config->interface_type != phymodInterfaceBypass) { 1179 1180 for (i = 0; i < num_lane; i++) { 1181 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1182 continue; 1183 } 1184 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1185 PHYMOD_IF_ERR_RETURN 1186 (falcon_pmd_tx_disable_pin_dis_set(&pm_phy_copy.access, 0)); 1187 } 1188 } 1189 pm_phy_copy.access.lane_mask = 0x1; 1190 PHYMOD_IF_ERR_RETURN 1191 (tscf_phy_firmware_core_config_get(&pm_phy_copy, &firmware_core_config)); 1192 1193 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1194 PHYMOD_IF_ERR_RETURN 1195 (tscf_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 1196 1197 /*make sure that an and config from pcs is off*/ 1198 firmware_core_config.CoreConfigFromPCS = 0; 1199 firmware_lane_config.AnEnabled = 0; 1200 firmware_lane_config.LaneConfigFromPCS = 0; 1201 firmware_lane_config.DfeOn = 1; 1202 firmware_lane_config.LpDfeOn = 0; 1203 firmware_lane_config.Cl72RestTO = 1; 1204 firmware_lane_config.Cl72AutoPolEn = 0; 1205 firmware_lane_config.ScramblingDisable = 0; 1206 1207 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1208 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1209 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1210 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1211 } else { 1212 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1213 } 1214 if(config->data_rate == 1000) 1215 firmware_lane_config.DfeOn = 0; 1216 1217 PHYMOD_IF_ERR_RETURN 1218 (tefmod_update_port_mode(&phy->access, (int *) &pll_switch)); 1219 1220 if (config->interface_type == phymodInterface1000X) { 1221 if (config->pll_divider_req == 165) { 1222 spd_intf = TEFMOD_SPD_1G_25G; 1223 } else { 1224 spd_intf = TEFMOD_SPD_1G_20G; 1225 } 1226 } else if (config->interface_type == phymodInterfaceSGMII) { 1227 if (config->pll_divider_req == 165) { 1228 spd_intf = TEFMOD_SPD_1G_25G; 1229 } else { 1230 spd_intf = TEFMOD_SPD_1G_20G; 1231 } 1232 } else if ((config->interface_type == phymodInterfaceBypass) || 1233 (num_lane == 1)) { 1234 switch (config->data_rate) { 1235 case 10000: 1236 case 12000: 1237 spd_intf = TEFMOD_SPD_10000_XFI; 1238 if (config->interface_type != phymodInterfaceBypass) { 1239 if (!PHYMOD_INTF_MODES_COPPER_GET(config)) { 1240 firmware_lane_config.DfeOn = 0; 1241 } 1242 } 1243 break; 1244 case 11000: 1245 spd_intf = TEFMOD_SPD_10600_XFI_HG; 1246 if (config->interface_type != phymodInterfaceBypass) { 1247 if (!PHYMOD_INTF_MODES_COPPER_GET(config)) { 1248 firmware_lane_config.DfeOn = 0; 1249 } 1250 } 1251 break; 1252 case 20000: 1253 spd_intf = TEFMOD_SPD_20000_XFI; 1254 break; 1255 case 21200: 1256 spd_intf = TEFMOD_SPD_21200_XFI_HG; 1257 break; 1258 case 25000: 1259 spd_intf = TEFMOD_SPD_25000_XFI; 1260 break; 1261 case 27000: 1262 spd_intf = TEFMOD_SPD_26500_XFI_HG; 1263 firmware_lane_config.DfeOn = 1; 1264 firmware_lane_config.LpDfeOn = 0; 1265 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1266 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1267 } else { 1268 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1269 } 1270 break; 1271 default: 1272 /* if the interface is pcs bypass mode and check the speed */ 1273 if (config->interface_type == phymodInterfaceBypass) { 1274 /* disable DFE for lower speed */ 1275 if (config->data_rate < 10000) { 1276 firmware_lane_config.DfeOn = 0; 1277 } 1278 } else { 1279 spd_intf = TEFMOD_SPD_10000_XFI; 1280 firmware_lane_config.DfeOn = 0; 1281 } 1282 break; 1283 } 1284 } else if ((config->interface_type == phymodInterfaceKR2) || 1285 (config->interface_type == phymodInterfaceCR2) || 1286 (config->interface_type == phymodInterfaceXLAUI2) || 1287 (config->interface_type == phymodInterfaceRXAUI) || 1288 (config->interface_type == phymodInterfaceX2) || 1289 (num_lane == 2)) { 1290 switch (config->data_rate) { 1291 case 20000: 1292 spd_intf = TEFMOD_SPD_20G_MLD_X2; 1293 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1294 firmware_lane_config.DfeOn = 0; 1295 firmware_lane_config.LpDfeOn = 0; 1296 } 1297 if (PHYMOD_INTF_MODES_FIBER_GET(config) && !(PHYMOD_INTF_MODES_HIGIG_GET(config))) { 1298 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1299 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1300 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1301 } else { 1302 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1303 } 1304 break; 1305 case 21000: 1306 case 21200: 1307 firmware_lane_config.DfeOn = 0; 1308 firmware_lane_config.LpDfeOn = 0; 1309 spd_intf = TEFMOD_SPD_21G_MLD_HG_X2; 1310 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1311 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1312 } else { 1313 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1314 } 1315 break; 1316 case 40000: 1317 spd_intf = TEFMOD_SPD_40G_MLD_X2; 1318 if (config->interface_type == phymodInterfaceXLAUI2) { 1319 firmware_lane_config.DfeOn = 0; 1320 firmware_lane_config.LpDfeOn = 0; 1321 } else { 1322 firmware_lane_config.DfeOn = 1; 1323 firmware_lane_config.LpDfeOn = 1; 1324 } 1325 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1326 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1327 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1328 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1329 } else { 1330 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1331 } 1332 break; 1333 case 42000: 1334 spd_intf = TEFMOD_SPD_42G_MLD_HG_X2; 1335 firmware_lane_config.DfeOn = 1; 1336 firmware_lane_config.LpDfeOn = 1; 1337 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1338 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1339 } else { 1340 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1341 } 1342 break; 1343 case 50000: 1344 spd_intf = TEFMOD_SPD_50G_MLD_X2; 1345 break; 1346 case 53000: 1347 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1348 spd_intf = TEFMOD_SPD_53G_MLD_HG_X2; 1349 } else { 1350 spd_intf = TEFMOD_SPD_50G_MLD_X2; 1351 } 1352 break; 1353 default: 1354 spd_intf = TEFMOD_SPD_20G_MLD_X2; 1355 break; 1356 } 1357 } else { 1358 switch (config->data_rate) { 1359 case 10000: 1360 { 1361 /* first need to check model number and version */ 1362 MAIN0_SERDESIDr_t serdesid; 1363 uint32_t model, rev_letter; 1364 int rv; 1365 /* read the serdes_id, if not revB, bypass the uc_active checking */ 1366 rv = READ_MAIN0_SERDESIDr(&phy->access, &serdesid); 1367 if (rv != PHYMOD_E_NONE) { 1368 return PHYMOD_E_CONFIG; 1369 } 1370 rev_letter = MAIN0_SERDESIDr_REV_LETTERf_GET(serdesid); 1371 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 1372 if ( (rev_letter == TSCF_REV_LETTER_C) && 1373 (model == TSCF_MODEL)) { 1374 spd_intf = TEFMOD_SPD_10G_25G; 1375 firmware_lane_config.DfeOn = 0; 1376 firmware_lane_config.LpDfeOn = 0; 1377 firmware_lane_config.ScramblingDisable = 1; 1378 } else { 1379 PHYMOD_DEBUG_ERROR(("ERROR :: 10G XAUI speed is not supported \n")); 1380 return PHYMOD_E_CONFIG; 1381 } 1382 break; 1383 } 1384 1385 case 40000: 1386 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1387 spd_intf = TEFMOD_SPD_42G_MLD_HG_X4; 1388 firmware_lane_config.DfeOn = 1; 1389 firmware_lane_config.LpDfeOn = 1; 1390 } else if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1391 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1392 firmware_lane_config.DfeOn = 0; 1393 firmware_lane_config.LpDfeOn = 0; 1394 } else { 1395 if (config->interface_type == phymodInterfaceXLAUI) { 1396 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1397 firmware_lane_config.DfeOn = 0; 1398 firmware_lane_config.LpDfeOn = 0; 1399 } else { 1400 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1401 firmware_lane_config.DfeOn = 1; 1402 firmware_lane_config.LpDfeOn = 1; 1403 } 1404 } 1405 break; 1406 case 42000: 1407 spd_intf = TEFMOD_SPD_42G_MLD_HG_X4; 1408 firmware_lane_config.DfeOn = 1; 1409 firmware_lane_config.LpDfeOn = 1; 1410 break; 1411 case 48000: 1412 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1413 firmware_lane_config.DfeOn = 0; 1414 firmware_lane_config.LpDfeOn = 0; 1415 break; 1416 case 50000: 1417 spd_intf = TEFMOD_SPD_50G_MLD_X4; 1418 break; 1419 case 53000: 1420 spd_intf = TEFMOD_SPD_53G_MLD_HG_X4; 1421 break; 1422 case 100000: 1423 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1424 spd_intf = TEFMOD_SPD_106G_MLD_HG_X4; 1425 firmware_lane_config.DfeOn = 1; 1426 firmware_lane_config.LpDfeOn = 0; 1427 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1428 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1429 } else { 1430 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1431 } 1432 } else { 1433 spd_intf = TEFMOD_SPD_100G_MLD_X4; 1434 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1435 firmware_lane_config.DfeOn = 0; 1436 firmware_lane_config.LpDfeOn = 0; 1437 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1438 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1439 firmware_lane_config.DfeOn = 1; 1440 firmware_lane_config.LpDfeOn = 0; 1441 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1442 } else { 1443 firmware_lane_config.DfeOn = 1; 1444 firmware_lane_config.LpDfeOn = 0; 1445 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1446 } 1447 if (config->interface_type == phymodInterfaceCAUI4 || config->interface_type == phymodInterfaceCAUI) { 1448 firmware_lane_config.DfeOn = 1; 1449 firmware_lane_config.LpDfeOn = 1; 1450 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1451 } 1452 } 1453 break; 1454 case 106000: 1455 spd_intf = TEFMOD_SPD_106G_MLD_HG_X4; 1456 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1457 firmware_lane_config.DfeOn = 1; 1458 firmware_lane_config.LpDfeOn = 0; 1459 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1460 } else { 1461 firmware_lane_config.DfeOn = 1; 1462 firmware_lane_config.LpDfeOn = 0; 1463 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1464 } 1465 break; 1466 default: 1467 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1468 firmware_lane_config.DfeOn = 0; 1469 break; 1470 } 1471 } 1472 1473 PHYMOD_IF_ERR_RETURN 1474 (tefmod_get_plldiv(&phy->access, ¤t_pll_div)); 1475 1476 if(config->interface_type == phymodInterfaceBypass) { 1477 /* falcon tier1 error codes are not compatible with SDK error codes 1478 * convert the falcon tier1 err code to PHYMOD error code 1479 */ 1480 rv = falcon_tsc_get_vco(config, &vco_rate, &new_pll_div, &new_os_mode); 1481 1482 if (rv != PHYMOD_E_NONE) { 1483 return PHYMOD_E_CONFIG; 1484 } 1485 1486 } else { 1487 1488 PHYMOD_IF_ERR_RETURN 1489 (tefmod_plldiv_lkup_get(&phy->access, spd_intf, config->ref_clock, &new_pll_div)); 1490 1491 /* For 12GG XFI , data rate specified is 12000, and pll_div is set to 160 ( 6 ) */ 1492 if ((config->data_rate == 12000) && (num_lane == 1)) { 1493 if (config->ref_clock == phymodRefClk125Mhz) { 1494 new_pll_div = 0xd; 1495 } else { 1496 new_pll_div = 6; 1497 } 1498 } 1499 if ((config->data_rate == 40000) && 1500 PHYMOD_INTF_MODES_HIGIG_GET(config) && 1501 (num_lane == 4)) { 1502 if (config->ref_clock == phymodRefClk125Mhz) { 1503 new_pll_div = 0x7; 1504 } else { 1505 new_pll_div = 4; 1506 } 1507 } 1508 if ((config->data_rate == 48000) && (num_lane == 4)) { 1509 if (config->ref_clock == phymodRefClk125Mhz) { 1510 new_pll_div = 0xd; 1511 } else { 1512 new_pll_div = 6; 1513 } 1514 } 1515 if ((config->data_rate == 100000) && 1516 PHYMOD_INTF_MODES_HIGIG_GET(config) && 1517 (num_lane == 4)) { 1518 new_pll_div = 7; 1519 } 1520 if ((config->data_rate == 53000) && 1521 !PHYMOD_INTF_MODES_HIGIG_GET(config) && 1522 (num_lane == 2)) { 1523 if (config->ref_clock == phymodRefClk156Mhz) { 1524 new_pll_div = 0xa; 1525 } 1526 } 1527 1528 if(config->device_aux_modes !=NULL){ 1529 PHYMOD_IF_ERR_RETURN 1530 (_tscf_st_hto_interface_config_set(config->device_aux_modes, start_lane, new_speed_vec, &new_pll_div, &new_os_mode)) ; 1531 } 1532 } 1533 1534 PHYMOD_IF_ERR_RETURN(tefmod_disable_set(&phy->access)); 1535 1536 if(new_os_mode>=0) { 1537 os_mode = new_os_mode | 0x80000000 ; 1538 } else { 1539 os_mode = 0 ; 1540 } 1541 PHYMOD_IF_ERR_RETURN 1542 (tefmod_pmd_osmode_set(&phy->access, spd_intf, config->ref_clock,os_mode)); 1543 1544 /*if pll change is disabled*/ 1545 if((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)){ 1546 /*Terminate the execution of the function*/ 1547 PHYMOD_DEBUG_WARN(("PLL has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled \n", 1548 (unsigned int)current_pll_div, (unsigned int)new_pll_div)); 1549 return PHYMOD_E_NONE; 1550 } 1551 1552 1553 /*pll switch is required and expected */ 1554 if((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) { 1555 1556 /* Change in PLL, so reset all the ports first. */ 1557 lane_bkup = pm_phy_copy.access.lane_mask; 1558 pm_phy_copy.access.lane_mask = 0xf; 1559 PHYMOD_IF_ERR_RETURN(tefmod_disable_set(&pm_phy_copy.access)); 1560 pm_phy_copy.access.lane_mask = lane_bkup; 1561 1562 PHYMOD_IF_ERR_RETURN 1563 (falcon_core_soft_reset_release(&pm_phy_copy.access, 0)); 1564 1565 /*release the uc reset */ 1566 PHYMOD_IF_ERR_RETURN 1567 (falcon_tsc_uc_reset(&pm_phy_copy.access ,0)); 1568 1569 /*set the PLL divider */ 1570 PHYMOD_IF_ERR_RETURN 1571 (falcon_pll_mode_set(&phy->access, new_pll_div)); 1572 PHYMOD_IF_ERR_RETURN 1573 (_tscf_pll_multiplier_get(new_pll_div, &pll_multiplier)); 1574 /* update the VCO rate properly */ 1575 switch (config->ref_clock) { 1576 case phymodRefClk156Mhz: 1577 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1578 break; 1579 case phymodRefClk125Mhz: 1580 vco_rate = pll_multiplier * 125; 1581 break; 1582 default: 1583 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1584 break; 1585 } 1586 firmware_core_config.VcoRate = (vco_rate * 16 + 500) / 1000 - 224; 1587 1588 /*change the master port num to the current caller port */ 1589 PHYMOD_IF_ERR_RETURN 1590 (tefmod_master_port_num_set(&phy->access, start_lane)); 1591 PHYMOD_IF_ERR_RETURN 1592 (tefmod_pll_reset_enable_set(&phy->access, 1)); 1593 /*update the firmware config properly*/ 1594 PHYMOD_IF_ERR_RETURN 1595 (tscf_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config)); 1596 PHYMOD_IF_ERR_RETURN 1597 (falcon_core_soft_reset_release(&pm_phy_copy.access, 1)); 1598 } 1599 1600 if(config->interface_type != phymodInterfaceBypass) { 1601 PHYMOD_IF_ERR_RETURN 1602 (tefmod_set_spd_intf(&phy->access, spd_intf)); 1603 } 1604 1605 for (i = 0; i < num_lane; i++) { 1606 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1607 continue; 1608 } 1609 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 1610 PHYMOD_IF_ERR_RETURN 1611 (_tscf_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1612 } 1613 1614 /*release the per lne soft reset bit*/ 1615 for (i = 0; i < num_lane; i++) { 1616 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 1617 continue; 1618 } 1619 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1620 PHYMOD_IF_ERR_RETURN 1621 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1622 } 1623 1624 return PHYMOD_E_NONE; 1625 } 1626 1627 /* Yet to fix the interface_type */ 1628 STATIC 1629 int _tscf_speed_id_interface_config_get(const phymod_phy_access_t* phy, int speed_id, phymod_phy_inf_config_t* config) 1630 { 1631 int ilkn_set; 1632 int osr_mode; 1633 int div_osr_value; 1634 uint32_t vco_rate; 1635 uint32_t pll_multiplier; 1636 uint32_t plldiv_r_val; 1637 1638 PHYMOD_IF_ERR_RETURN(tefmod_pcs_ilkn_chk(&phy->access, &ilkn_set)); 1639 PHYMOD_IF_ERR_RETURN(tefmod_get_plldiv(&phy->access, &plldiv_r_val)); 1640 if(ilkn_set) { 1641 config->interface_type = phymodInterfaceBypass; 1642 PHYMOD_IF_ERR_RETURN(tefmod_get_plldiv(&phy->access, &plldiv_r_val)); 1643 PHYMOD_IF_ERR_RETURN 1644 (_tscf_pll_multiplier_get(plldiv_r_val, &pll_multiplier)); 1645 PHYMOD_IF_ERR_RETURN 1646 (falcon_osr_mode_get(&phy->access, &osr_mode)); 1647 1648 switch (config->ref_clock) { 1649 case phymodRefClk156Mhz: 1650 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1651 break; 1652 case phymodRefClk125Mhz: 1653 vco_rate = pll_multiplier * 125; 1654 break; 1655 default: 1656 vco_rate = pll_multiplier * 156 + pll_multiplier * 25 / 100; 1657 break; 1658 } 1659 div_osr_value = 1 << osr_mode; 1660 config->data_rate = vco_rate/div_osr_value; 1661 } else { 1662 switch (speed_id) { 1663 case 0x0: 1664 config->data_rate = 10000; 1665 config->interface_type = phymodInterfaceCR; 1666 break; 1667 case 0x1: 1668 config->data_rate = 10000; 1669 config->interface_type = phymodInterfaceKR; 1670 break; 1671 case 0x2: 1672 config->data_rate = 10000; 1673 config->interface_type = phymodInterfaceKR; 1674 /*next check the PLL divider to see if 10G or 12G */ 1675 PHYMOD_IF_ERR_RETURN(tefmod_get_plldiv(&phy->access, &plldiv_r_val)); 1676 if ((config->ref_clock == phymodRefClk125Mhz) && 1677 (plldiv_r_val == 0xd)) { 1678 config->data_rate = 12000; 1679 } 1680 1681 if ((config->ref_clock == phymodRefClk156Mhz) && 1682 (plldiv_r_val == 0x6)) { 1683 config->data_rate = 12000; 1684 } 1685 break; 1686 case 0x4: 1687 config->data_rate = 11000; 1688 config->interface_type = phymodInterfaceCR; 1689 break; 1690 case 0x5: 1691 config->data_rate = 11000; 1692 config->interface_type = phymodInterfaceKR; 1693 break; 1694 case 0x6: 1695 config->data_rate = 11000; 1696 config->interface_type = phymodInterfaceKR; 1697 break; 1698 case 0x8: 1699 config->data_rate = 20000; 1700 config->interface_type = phymodInterfaceCR; 1701 break; 1702 case 0x9: 1703 config->data_rate = 20000; 1704 config->interface_type = phymodInterfaceKR; 1705 break; 1706 case 0xa: 1707 config->data_rate = 20000; 1708 config->interface_type = phymodInterfaceKR; 1709 break; 1710 case 0xc: 1711 config->data_rate = 21000; 1712 config->interface_type = phymodInterfaceCR; 1713 break; 1714 case 0xd: 1715 config->data_rate = 21000; 1716 config->interface_type = phymodInterfaceKR; 1717 break; 1718 case 0xe: 1719 config->data_rate = 21000; 1720 config->interface_type = phymodInterfaceKR; 1721 break; 1722 case 0x10: 1723 config->data_rate = 25000; 1724 config->interface_type = phymodInterfaceCR; 1725 break; 1726 case 0x11: 1727 config->data_rate = 25000; 1728 config->interface_type = phymodInterfaceKR; 1729 break; 1730 case 0x12: 1731 config->data_rate = 25000; 1732 config->interface_type = phymodInterfaceKR; 1733 break; 1734 case 0x14: 1735 config->data_rate = 27000; 1736 config->interface_type = phymodInterfaceCR; 1737 break; 1738 case 0x15: 1739 config->data_rate = 27000; 1740 config->interface_type = phymodInterfaceKR; 1741 break; 1742 case 0x16: 1743 config->data_rate = 27000; 1744 config->interface_type = phymodInterfaceKR; 1745 break; 1746 case 0x18: 1747 config->data_rate = 20000; 1748 config->interface_type = phymodInterfaceCR2; 1749 break; 1750 case 0x19: 1751 config->data_rate = 20000; 1752 config->interface_type = phymodInterfaceKR2; 1753 break; 1754 case 0x1a: 1755 config->data_rate = 20000; 1756 config->interface_type = phymodInterfaceKR2; 1757 break; 1758 case 0x1c: 1759 config->data_rate = 21000; 1760 config->interface_type = phymodInterfaceCR2; 1761 break; 1762 case 0x1d: 1763 config->data_rate = 21000; 1764 config->interface_type = phymodInterfaceKR2; 1765 break; 1766 case 0x1e: 1767 config->data_rate = 21000; 1768 config->interface_type = phymodInterfaceKR2; 1769 break; 1770 case 0x20: 1771 config->data_rate = 40000; 1772 config->interface_type = phymodInterfaceCR2; 1773 break; 1774 case 0x21: 1775 config->data_rate = 40000; 1776 config->interface_type = phymodInterfaceKR2; 1777 break; 1778 case 0x22: 1779 config->data_rate = 40000; 1780 config->interface_type = phymodInterfaceKR2; 1781 break; 1782 case 0x24: 1783 config->data_rate = 42000; 1784 config->interface_type = phymodInterfaceCR2; 1785 break; 1786 case 0x25: 1787 config->data_rate = 42000; 1788 config->interface_type = phymodInterfaceKR2; 1789 break; 1790 case 0x26: 1791 config->data_rate = 42000; 1792 config->interface_type = phymodInterfaceKR2; 1793 break; 1794 case 0x28: 1795 config->data_rate = 40000; 1796 if ((config->ref_clock == phymodRefClk156Mhz) && 1797 (plldiv_r_val == 0x5)) { 1798 config->data_rate =42000; 1799 } 1800 if ((config->ref_clock == phymodRefClk156Mhz) && 1801 (plldiv_r_val == 0x6)) { 1802 config->data_rate =48000; 1803 } 1804 if ((config->ref_clock == phymodRefClk125Mhz) && 1805 (plldiv_r_val == 0xa)) { 1806 config->data_rate =42000; 1807 } 1808 if ((config->ref_clock == phymodRefClk125Mhz) && 1809 (plldiv_r_val == 0xd)) { 1810 config->data_rate =48000; 1811 } 1812 1813 config->interface_type = phymodInterfaceCR4; 1814 break; 1815 case 0x29: 1816 config->data_rate = 40000; 1817 if ((config->ref_clock == phymodRefClk156Mhz) && 1818 (plldiv_r_val == 0x5)) { 1819 config->data_rate =42000; 1820 } 1821 if ((config->ref_clock == phymodRefClk156Mhz) && 1822 (plldiv_r_val == 0x6)) { 1823 config->data_rate =48000; 1824 } 1825 if ((config->ref_clock == phymodRefClk125Mhz) && 1826 (plldiv_r_val == 0xa)) { 1827 config->data_rate =42000; 1828 } 1829 if ((config->ref_clock == phymodRefClk125Mhz) && 1830 (plldiv_r_val == 0xd)) { 1831 config->data_rate =48000; 1832 } 1833 config->interface_type = phymodInterfaceKR4; 1834 break; 1835 case 0x2a: 1836 config->data_rate = 40000; 1837 if ((config->ref_clock == phymodRefClk156Mhz) && 1838 (plldiv_r_val == 0x5)) { 1839 config->data_rate =42000; 1840 } 1841 if ((config->ref_clock == phymodRefClk156Mhz) && 1842 (plldiv_r_val == 0x6)) { 1843 config->data_rate =48000; 1844 } 1845 if ((config->ref_clock == phymodRefClk125Mhz) && 1846 (plldiv_r_val == 0xa)) { 1847 config->data_rate =42000; 1848 } 1849 if ((config->ref_clock == phymodRefClk125Mhz) && 1850 (plldiv_r_val == 0xd)) { 1851 config->data_rate =48000; 1852 } 1853 config->interface_type = phymodInterfaceKR4; 1854 break; 1855 case 0x2c: 1856 config->data_rate = 42000; 1857 config->interface_type = phymodInterfaceCR4; 1858 break; 1859 case 0x2d: 1860 config->data_rate = 42000; 1861 config->interface_type = phymodInterfaceKR4; 1862 break; 1863 case 0x2e: 1864 config->data_rate = 42000; 1865 if ((config->ref_clock == phymodRefClk156Mhz) && 1866 (plldiv_r_val == 0x4)) { 1867 config->data_rate =40000; 1868 } 1869 if ((config->ref_clock == phymodRefClk125Mhz) && 1870 (plldiv_r_val == 0x7)) { 1871 config->data_rate =40000; 1872 } 1873 config->interface_type = phymodInterfaceKR4; 1874 break; 1875 case 0x30: 1876 config->data_rate = 50000; 1877 config->interface_type = phymodInterfaceCR2; 1878 break; 1879 case 0x31: 1880 config->data_rate = 50000; 1881 config->interface_type = phymodInterfaceKR2; 1882 break; 1883 case 0x32: 1884 config->data_rate = 50000; 1885 if ((config->ref_clock == phymodRefClk156Mhz) && 1886 (plldiv_r_val == 0xa)) { 1887 config->data_rate =53000; 1888 } 1889 config->interface_type = phymodInterfaceKR2; 1890 break; 1891 case 0x34: 1892 config->data_rate = 53000; 1893 config->interface_type = phymodInterfaceCR2; 1894 break; 1895 case 0x35: 1896 config->data_rate = 53000; 1897 config->interface_type = phymodInterfaceKR2; 1898 break; 1899 case 0x36: 1900 config->data_rate = 53000; 1901 config->interface_type = phymodInterfaceKR2; 1902 break; 1903 case 0x38: 1904 config->data_rate = 50000; 1905 config->interface_type = phymodInterfaceCR4; 1906 break; 1907 case 0x39: 1908 config->data_rate = 50000; 1909 config->interface_type = phymodInterfaceKR4; 1910 break; 1911 case 0x3a: 1912 config->data_rate = 50000; 1913 config->interface_type = phymodInterfaceKR4; 1914 break; 1915 case 0x3c: 1916 config->data_rate = 53000; 1917 config->interface_type = phymodInterfaceCR4; 1918 break; 1919 case 0x3d: 1920 config->data_rate = 53000; 1921 config->interface_type = phymodInterfaceKR4; 1922 break; 1923 case 0x3e: 1924 config->data_rate = 53000; 1925 config->interface_type = phymodInterfaceKR4; 1926 break; 1927 case 0x40: 1928 config->data_rate = 100000; 1929 config->interface_type = phymodInterfaceCR4; 1930 break; 1931 case 0x41: 1932 config->data_rate = 100000; 1933 config->interface_type = phymodInterfaceKR4; 1934 break; 1935 case 0x42: 1936 config->data_rate = 100000; 1937 config->interface_type = phymodInterfaceKR4; 1938 break; 1939 case 0x44: 1940 config->data_rate = 106000; 1941 if (plldiv_r_val == 7) { 1942 config->data_rate = 100000; 1943 } 1944 config->interface_type = phymodInterfaceCR4; 1945 break; 1946 case 0x45: 1947 config->data_rate = 106000; 1948 if (plldiv_r_val == 7) { 1949 config->data_rate = 100000; 1950 } 1951 config->interface_type = phymodInterfaceKR4; 1952 break; 1953 case 0x46: 1954 if (plldiv_r_val == 10) { 1955 config->data_rate = 106000; 1956 } else if (plldiv_r_val == 7) { 1957 config->data_rate = 100000; 1958 } else { 1959 /* 1960 * before SDK 6.5.6, plldiv_r_val = 6 when the 1961 * speed of a HG2 port is 100G. 1962 */ 1963 config->data_rate = 100000; 1964 } 1965 config->interface_type = phymodInterfaceKR4; 1966 break; 1967 case 0x48: 1968 config->data_rate = 20000; 1969 config->interface_type = phymodInterfaceKR2; 1970 break; 1971 case 0x50: 1972 config->data_rate = 25000; 1973 config->interface_type = phymodInterfaceKR2; 1974 break; 1975 case 0x58: 1976 config->data_rate = 1000; 1977 config->interface_type = phymodInterfaceSGMII; 1978 break; 1979 case 0x60: 1980 config->data_rate = 1000; 1981 config->interface_type = phymodInterfaceSGMII; 1982 break; 1983 case 0x62: 1984 config->data_rate = 10000; 1985 config->interface_type = phymodInterfaceXAUI; 1986 break; 1987 case 0x70: 1988 config->data_rate = 25000; 1989 config->interface_type = phymodInterfaceCR; 1990 break; 1991 case 0x71: 1992 config->data_rate = 25000; 1993 config->interface_type = phymodInterfaceCR; 1994 break; 1995 case 0x72: 1996 config->data_rate = 25000; 1997 config->interface_type = phymodInterfaceKR; 1998 break; 1999 case 0x73: 2000 config->data_rate = 25000; 2001 config->interface_type = phymodInterfaceKR; 2002 break; 2003 default: 2004 config->data_rate = 10000; 2005 config->interface_type = phymodInterfaceKR; 2006 break; 2007 } 2008 } 2009 return PHYMOD_E_NONE; 2010 } 2011 2012 2013 /*flags- unused parameter*/ 2014 int tscf_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) 2015 { 2016 int speed_id; 2017 phymod_firmware_lane_config_t firmware_lane_config; 2018 phymod_phy_access_t pm_phy_copy; 2019 int start_lane, num_lane; 2020 phymod_autoneg_control_t an_control; 2021 int an_done = 0; 2022 an_control.flags = 0; 2023 2024 config->ref_clock = ref_clock; 2025 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 2026 2027 PHYMOD_IF_ERR_RETURN 2028 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2029 PHYMOD_IF_ERR_RETURN 2030 (tefmod_speed_id_get(&phy->access, &speed_id)); 2031 PHYMOD_IF_ERR_RETURN 2032 (_tscf_speed_id_interface_config_get(phy, speed_id, config)); 2033 /* read the current media type */ 2034 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 2035 PHYMOD_IF_ERR_RETURN 2036 (tscf_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 2037 if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) { 2038 PHYMOD_INTF_MODES_FIBER_SET(config); 2039 } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) { 2040 PHYMOD_INTF_MODES_FIBER_CLR(config); 2041 PHYMOD_INTF_MODES_COPPER_SET(config); 2042 } else { 2043 PHYMOD_INTF_MODES_FIBER_CLR(config); 2044 PHYMOD_INTF_MODES_BACKPLANE_SET(config); 2045 } 2046 /* next need to check for 40G 4 lanes mode, it's for XLAUI or KR4 */ 2047 if ((config->data_rate == 40000) && (!(firmware_lane_config.DfeOn)) && 2048 (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) { 2049 if (num_lane == 2) { 2050 config->interface_type = phymodInterfaceXLAUI2; 2051 } else { 2052 config->interface_type = phymodInterfaceXLAUI; 2053 } 2054 } 2055 2056 PHYMOD_IF_ERR_RETURN 2057 (tscf_phy_autoneg_get(phy, &an_control, (uint32_t *) &an_done)); 2058 2059 /* next need to check if we are CAUI4 100G mode */ 2060 if (!(an_control.enable && an_done)) { 2061 if ((config->data_rate == 100000) && (firmware_lane_config.LpDfeOn) && 2062 (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) { 2063 config->interface_type = phymodInterfaceCAUI4; 2064 } 2065 } 2066 2067 switch (config->interface_type) { 2068 case phymodInterfaceSGMII: 2069 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 2070 config->interface_type = phymodInterface1000X; 2071 } else { 2072 config->interface_type = phymodInterfaceSGMII; 2073 } 2074 2075 /* 2076 * Speed ID 0x58 and 0x60 are interpreted as phymodInterfaceSGMII 2077 * by _tscf_speed_id_interface_config_get(). This is correct when 2078 * the port is in forced speed mode. However, when AN is enabled 2079 * and completed the interface type cannot be SGMII because TSCF 2080 * does not support CL37 & CL37bam. The correct interface type in 2081 * this scenario should be phymodInterfaceKX. 2082 */ 2083 if (an_control.enable && an_done) { 2084 config->interface_type = phymodInterfaceKX; 2085 } 2086 2087 break; 2088 case phymodInterfaceXFI: 2089 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 2090 config->interface_type = phymodInterfaceCR; 2091 } else { 2092 config->interface_type = phymodInterfaceXFI; 2093 } 2094 break; 2095 case phymodInterfaceKR2: 2096 if (!an_control.enable) { 2097 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 2098 config->interface_type = phymodInterfaceSR2; 2099 } else { 2100 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 2101 config->interface_type = phymodInterfaceCR2; 2102 } else { 2103 config->interface_type = phymodInterfaceKR2; 2104 } 2105 } 2106 } 2107 break; 2108 case phymodInterfaceKR4: 2109 if (!an_control.enable) { 2110 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 2111 config->interface_type = phymodInterfaceSR4; 2112 /*if (pCfg->speed_config.line_interface == TSCF_IF_LR4) { 2113 config->interface_type = phymodInterfaceLR4; 2114 }*/ 2115 } else { 2116 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 2117 config->interface_type = phymodInterfaceCR4; 2118 } else { 2119 config->interface_type = phymodInterfaceKR4; 2120 } 2121 } 2122 } 2123 break; 2124 case phymodInterfaceKR: 2125 { 2126 if (!an_control.enable) { 2127 if(config->data_rate == 10000) { 2128 if (/*PHY_EXTERNAL_MODE(unit, port) ||*/ !PHYMOD_INTF_MODES_FIBER_GET(config)) { 2129 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 2130 config->interface_type = phymodInterfaceCR; 2131 } else { 2132 config->interface_type = phymodInterfaceXFI; 2133 } 2134 } else { 2135 config->interface_type = phymodInterfaceSFI; 2136 } 2137 } else{ 2138 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 2139 config->interface_type = phymodInterfaceSR; 2140 } else { 2141 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 2142 config->interface_type = phymodInterfaceCR; 2143 } else { 2144 config->interface_type = phymodInterfaceKR; 2145 } 2146 } 2147 } 2148 } else { 2149 config->interface_type = phymodInterfaceKR; 2150 } 2151 break; 2152 } 2153 2154 default: 2155 break; 2156 } 2157 2158 return PHYMOD_E_NONE; 2159 } 2160 2161 int tscf_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 2162 { 2163 struct falcon_tsc_uc_lane_config_st serdes_firmware_config; 2164 PHYMOD_IF_ERR_RETURN(falcon_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config)); 2165 2166 2167 if(serdes_firmware_config.field.dfe_on == 0) { 2168 PHYMOD_DEBUG_ERROR(("ERROR :: DFE is off : Can not start CL72/CL93 with no DFE\n")); 2169 return PHYMOD_E_CONFIG; 2170 } 2171 2172 2173 PHYMOD_IF_ERR_RETURN 2174 (tefmod_clause72_control(&phy->access, cl72_en)); 2175 return PHYMOD_E_NONE; 2176 } 2177 2178 int tscf_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 2179 { 2180 /* PHYMOD_IF_ERR_RETURN 2181 (falcon_tsc_display_cl93n72_status(&phy->access)); */ 2182 PHYMOD_IF_ERR_RETURN 2183 (falcon_clause72_control_get(&phy->access, cl72_en)); 2184 return PHYMOD_E_NONE; 2185 } 2186 2187 2188 int tscf_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 2189 { 2190 uint32_t local_status; 2191 /* PHYMOD_IF_ERR_RETURN 2192 (falcon_tsc_display_cl93n72_status(&phy->access)); */ 2193 PHYMOD_IF_ERR_RETURN 2194 (falcon_pmd_cl72_receiver_status(&phy->access, &local_status)); 2195 status->locked = local_status; 2196 return PHYMOD_E_NONE; 2197 } 2198 2199 int tscf_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability) 2200 { 2201 tefmod_an_adv_ability_t value; 2202 int start_lane, num_lane; 2203 phymod_phy_access_t phy_copy; 2204 phymod_core_info_t core_info; 2205 MAIN0_SERDESIDr_t serdesid; 2206 /* DIG_REVID0r_t revid; */ 2207 uint32_t model; 2208 2209 2210 /* next program the tx fir taps and driver current based on the input */ 2211 PHYMOD_IF_ERR_RETURN 2212 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2213 2214 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2215 phy_copy.access.lane_mask = 0x1 << start_lane; 2216 2217 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2218 PHYMOD_MEMSET(&core_info, 0x0, sizeof(core_info)); 2219 2220 PHYMOD_IF_ERR_RETURN 2221 (tscf_core_info_get((phymod_core_access_t *)phy, &core_info)); 2222 2223 2224 /*first check if tscf gen2 or not */ 2225 PHYMOD_IF_ERR_RETURN(READ_MAIN0_SERDESIDr(&phy_copy.access, &serdesid)); 2226 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 2227 2228 value.an_cl72 = an_ability->an_cl72; 2229 2230 if (model == TSCF_MODEL) { 2231 if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) { 2232 value.an_fec = TEFMOD_FEC_SUPRTD_NOT_REQSTD; 2233 } else if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)) { 2234 value.an_fec = TEFMOD_FEC_CL74_SUPRTD_REQSTD; 2235 } 2236 } else { 2237 /* this is new CL91 support on gen2 version */ 2238 if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) { 2239 value.an_fec = TEFMOD_FEC_SUPRTD_NOT_REQSTD; 2240 } else { 2241 if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)) 2242 value.an_fec = TEFMOD_FEC_CL74_SUPRTD_REQSTD; 2243 if (PHYMOD_AN_FEC_CL91_GET(an_ability->an_fec)) 2244 value.an_fec |= TEFMOD_FEC_CL91_SUPRTD_REQSTD; 2245 } 2246 } 2247 2248 /* value.an_fec = an_ability->an_fec; */ 2249 value.an_hg2 = an_ability->an_hg2; 2250 2251 /* tscf a0 does not support cl91 */ 2252 /* next check pause */ 2253 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) { 2254 value.an_pause = TEFMOD_SYMM_PAUSE; 2255 } 2256 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 2257 value.an_pause = TEFMOD_ASYM_PAUSE; 2258 } 2259 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 2260 value.an_pause = TEFMOD_ASYM_SYMM_PAUSE; 2261 } 2262 2263 /* check cl73 and cl73 bam ability */ 2264 if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)) 2265 value.an_base_speed |= 1 << TEFMOD_CL73_1GBASE_KX; 2266 if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)) 2267 value.an_base_speed |= 1 << TEFMOD_CL73_10GBASE_KR1; 2268 if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)) 2269 value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_KR4; 2270 if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)) 2271 value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_CR4; 2272 if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) { 2273 if (core_info.core_version == phymodCoreVersionTscfA0) { 2274 value.an_fec = TEFMOD_FEC_NOT_SUPRTD; 2275 } 2276 value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_KR4; 2277 } 2278 if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) { 2279 if (core_info.core_version == phymodCoreVersionTscfA0) { 2280 value.an_fec = TEFMOD_FEC_NOT_SUPRTD; 2281 } 2282 value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_CR4; 2283 } 2284 /* tscf gen2 added 25G as the IEEE base cl73 speed */ 2285 if (model == TSCF_GEN2_MODEL) { 2286 if (PHYMOD_AN_CAP_25G_CR1_GET(an_ability->an_cap)) 2287 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CR1; 2288 if (PHYMOD_AN_CAP_25G_KR1_GET(an_ability->an_cap)) 2289 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KR1; 2290 if (PHYMOD_AN_CAP_25G_CRS1_GET(an_ability->an_cap)) 2291 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CRS1; 2292 if (PHYMOD_AN_CAP_25G_KRS1_GET(an_ability->an_cap)) 2293 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KRS1; 2294 } 2295 2296 /* check cl73 bam ability */ 2297 if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap)) 2298 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_KR2; 2299 if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap)) 2300 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_CR2; 2301 if (PHYMOD_BAM_CL73_CAP_40G_KR2_GET(an_ability->cl73bam_cap)) 2302 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_KR2; 2303 if (PHYMOD_BAM_CL73_CAP_40G_CR2_GET(an_ability->cl73bam_cap)) 2304 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_CR2; 2305 if (PHYMOD_BAM_CL73_CAP_50G_KR2_GET(an_ability->cl73bam_cap)) 2306 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR2; 2307 if (PHYMOD_BAM_CL73_CAP_50G_CR2_GET(an_ability->cl73bam_cap)) 2308 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR2; 2309 if (PHYMOD_BAM_CL73_CAP_50G_KR4_GET(an_ability->cl73bam_cap)) 2310 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR4; 2311 if (PHYMOD_BAM_CL73_CAP_50G_CR4_GET(an_ability->cl73bam_cap)) 2312 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR4; 2313 2314 if (PHYMOD_BAM_CL73_CAP_20G_KR1_GET(an_ability->cl73bam_cap)) 2315 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_KR1; 2316 if (PHYMOD_BAM_CL73_CAP_20G_CR1_GET(an_ability->cl73bam_cap)) 2317 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_CR1; 2318 if (PHYMOD_BAM_CL73_CAP_25G_KR1_GET(an_ability->cl73bam_cap)) 2319 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_KR1; 2320 if (PHYMOD_BAM_CL73_CAP_25G_CR1_GET(an_ability->cl73bam_cap)) 2321 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_CR1; 2322 2323 PHYMOD_IF_ERR_RETURN 2324 (tefmod_autoneg_ability_set(&phy_copy.access, &value)); 2325 return PHYMOD_E_NONE; 2326 2327 } 2328 2329 int tscf_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type){ 2330 tefmod_an_adv_ability_t value; 2331 phymod_phy_access_t phy_copy; 2332 int start_lane, num_lane; 2333 2334 PHYMOD_IF_ERR_RETURN 2335 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2336 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2337 phy_copy.access.lane_mask = 0x1 << start_lane; 2338 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2339 2340 PHYMOD_IF_ERR_RETURN 2341 (tefmod_autoneg_ability_get(&phy_copy.access, &value)); 2342 an_ability_get_type->an_cl72 = value.an_cl72; 2343 2344 an_ability_get_type->an_fec = 0; 2345 if (value.an_fec == TEFMOD_FEC_NOT_SUPRTD) { 2346 2347 } else if (value.an_fec == TEFMOD_FEC_SUPRTD_NOT_REQSTD) { 2348 PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec); 2349 } else { 2350 if (value.an_fec & TEFMOD_FEC_CL74_SUPRTD_REQSTD) { 2351 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2352 } 2353 if (value.an_fec & TEFMOD_FEC_CL91_SUPRTD_REQSTD) { 2354 PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec); 2355 } 2356 } 2357 2358 if (value.an_pause == TEFMOD_ASYM_PAUSE) { 2359 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2360 } else if (value.an_pause == TEFMOD_SYMM_PAUSE) { 2361 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2362 } else if (value.an_pause == TEFMOD_ASYM_SYMM_PAUSE) { 2363 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2364 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2365 } 2366 2367 /* first check cl73 base ability */ 2368 if (value.an_base_speed & 1 << TEFMOD_CL73_100GBASE_CR4) { 2369 PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap); 2370 } 2371 if (value.an_base_speed & 1 << TEFMOD_CL73_100GBASE_KR4) { 2372 PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap); 2373 } 2374 if (value.an_base_speed & 1 << TEFMOD_CL73_40GBASE_CR4) { 2375 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 2376 } 2377 if (value.an_base_speed & 1 << TEFMOD_CL73_40GBASE_KR4) { 2378 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 2379 } 2380 if (value.an_base_speed & 1 << TEFMOD_CL73_10GBASE_KR1) { 2381 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 2382 } 2383 if (value.an_base_speed & 1 << TEFMOD_CL73_1GBASE_KX) { 2384 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 2385 } 2386 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_KR1) { 2387 PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap); 2388 } 2389 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_CR1) { 2390 PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap); 2391 } 2392 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_KRS1) { 2393 PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap); 2394 } 2395 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_CRS1) { 2396 PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap); 2397 } 2398 2399 /* next check cl73 bam ability */ 2400 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_20GBASE_KR2) 2401 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap); 2402 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_20GBASE_CR2) 2403 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap); 2404 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_40GBASE_KR2) 2405 PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap); 2406 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_40GBASE_CR2) 2407 PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap); 2408 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_KR2) 2409 PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap); 2410 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_CR2) 2411 PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap); 2412 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_KR4) 2413 PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap); 2414 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_CR4) 2415 PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap); 2416 2417 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_20GBASE_KR1) 2418 PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap); 2419 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_20GBASE_CR1) 2420 PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap); 2421 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_25GBASE_KR1) 2422 PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap); 2423 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_25GBASE_CR1) 2424 PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap); 2425 2426 return PHYMOD_E_NONE; 2427 } 2428 2429 int tscf_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 2430 { 2431 uint16_t baseP0, baseP1, baseP2, nextP3, nextP4; 2432 int an_fec; 2433 2434 PHYMOD_IF_ERR_RETURN 2435 (tefmod_autoneg_lp_status_get(&phy->access, &baseP0, &baseP1, &baseP2, &nextP3, &nextP4)); 2436 2437 if((baseP1 >> 5) & 1) { /* D0 */ 2438 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 2439 } 2440 if((baseP1 >> 7) & 1) { /* D2 */ 2441 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 2442 } 2443 if((baseP1 >> 8) & 1) { /* D3 */ 2444 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 2445 } 2446 if((baseP1 >> 9) & 1) { /* D4 */ 2447 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 2448 } 2449 if((baseP1 >> 12) & 1) { /* D7 */ 2450 PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap); 2451 } 2452 if((baseP1 >> 13) & 1) { /* D8 */ 2453 PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap); 2454 } 2455 2456 if((baseP1 >> 14) & 1) { 2457 PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap); 2458 PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap); 2459 } 2460 if((baseP1 >> 15) & 1) { 2461 PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap); 2462 PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap); 2463 } 2464 2465 an_fec = (baseP2 >> 14) & 3; /* D47:D46 */ 2466 2467 an_ability_get_type->an_fec = 0; 2468 if (an_fec == 0x0) { 2469 2470 } else if (an_fec == 0x1) { 2471 PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec); 2472 } else { 2473 if (an_fec == 0x3) { 2474 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2475 } 2476 } 2477 2478 an_fec = (baseP2 >> 12) & 3; /* D45:D44 */ 2479 if (an_fec & 0x1) { 2480 PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec); 2481 } 2482 if (an_fec & 0x2) { 2483 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2484 } 2485 2486 if((baseP0 >> 10) & 1) { /* C0 */ 2487 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2488 } 2489 if((baseP0 >> 11) & 1) { /* C1 */ 2490 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2491 } 2492 2493 if((nextP3 >> 0) & 1) { 2494 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap); 2495 } 2496 if((nextP3 >> 1) & 1) { 2497 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap); 2498 } 2499 if((nextP3 >> 2) & 1) { 2500 PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap); 2501 } 2502 if((nextP3 >> 3) & 1) { 2503 PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap); 2504 } 2505 if((nextP3 >> 4) & 1) { 2506 PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap); 2507 } 2508 if((nextP3 >> 5) & 1) { 2509 PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap); 2510 } 2511 if((nextP3 >> 6) & 1) { 2512 PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap); 2513 } 2514 if((nextP3 >> 7) & 1) { 2515 PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap); 2516 } 2517 if((nextP3 >> 8) & 1) { 2518 PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap); 2519 } 2520 if((nextP3 >> 9) & 1) { 2521 PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap); 2522 } 2523 if((nextP4 >> 0) & 1) { 2524 PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap); 2525 } 2526 if((nextP4 >> 1) & 1) { 2527 PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap); 2528 } 2529 2530 return PHYMOD_E_NONE; 2531 } 2532 2533 2534 int tscf_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 2535 { 2536 int num_lane_adv_encoded; 2537 int start_lane, num_lane; 2538 int i, an_enable_bitmap, single_port_mode = 0; 2539 int do_lane_config_set, do_core_config_set; 2540 phymod_firmware_lane_config_t firmware_lane_config; 2541 phymod_firmware_core_config_t firmware_core_config_tmp; 2542 tefmod_an_control_t an_control; 2543 phymod_phy_access_t phy_copy; 2544 2545 /* TSCF doesn't support 10G KX4 and 1G KX parallel detection*/ 2546 if (PHYMOD_AN_F_SET_CL73_PDET_KX4_ENABLE_GET(an) || 2547 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) { 2548 return PHYMOD_E_UNAVAIL; 2549 } 2550 2551 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 2552 PHYMOD_MEMSET(&firmware_core_config_tmp, 0x0, sizeof(firmware_core_config_tmp)); 2553 2554 PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control)); 2555 PHYMOD_IF_ERR_RETURN 2556 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2557 2558 if (PHYMOD_AN_F_ALLOW_PLL_CHANGE_GET(an) || (num_lane == 0x4)){ 2559 single_port_mode = 1; 2560 } 2561 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2562 phy_copy.access.lane_mask = 0x1 << start_lane; 2563 2564 switch (an->num_lane_adv) { 2565 case 1: 2566 num_lane_adv_encoded = 0; 2567 break; 2568 case 2: 2569 num_lane_adv_encoded = 1; 2570 break; 2571 case 4: 2572 num_lane_adv_encoded = 2; 2573 break; 2574 case 10: 2575 num_lane_adv_encoded = 3; 2576 break; 2577 default: 2578 return PHYMOD_E_PARAM; 2579 } 2580 2581 /* first heck if cl72 is allowed to change */ 2582 if (PHYMOD_AN_F_ALLOW_CL72_CONFIG_CHANGE_GET(an)) { 2583 an_control.cl72_config_allowed = 1; 2584 } else { 2585 an_control.cl72_config_allowed = 0; 2586 } 2587 2588 if(PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) { 2589 an_control.pd_kx_en = 1 ; 2590 } 2591 2592 an_control.num_lane_adv = num_lane_adv_encoded; 2593 an_control.enable = an->enable; 2594 an_control.an_property_type = 0x0; /* for now disable */ 2595 switch (an->an_mode) { 2596 case phymod_AN_MODE_CL73: 2597 an_control.an_type = TEFMOD_AN_MODE_CL73; 2598 break; 2599 case phymod_AN_MODE_CL73BAM: 2600 an_control.an_type = TEFMOD_AN_MODE_CL73BAM; 2601 break; 2602 case phymod_AN_MODE_MSA: 2603 an_control.an_type = TEFMOD_AN_MODE_MSA; 2604 break; 2605 case phymod_AN_MODE_CL73_MSA: 2606 an_control.an_type = TEFMOD_AN_MODE_CL73_MSA; 2607 break; 2608 case phymod_AN_MODE_HPAM: 2609 an_control.an_type = TEFMOD_AN_MODE_HPAM; 2610 break; 2611 default: 2612 an_control.an_type = TEFMOD_AN_MODE_CL73; 2613 break; 2614 } 2615 2616 PHYMOD_IF_ERR_RETURN(tefmod_disable_set(&phy->access)); 2617 2618 if (single_port_mode) { 2619 PHYMOD_IF_ERR_RETURN 2620 (tefmod_set_an_single_port_mode(&phy->access, an->enable)); 2621 } 2622 2623 if(an->enable) { 2624 PHYMOD_IF_ERR_RETURN(tefmod_set_an_port_mode(&phy->access, num_lane, start_lane)); 2625 } 2626 2627 /* first check if any other lane has An on */ 2628 an_enable_bitmap = 0; 2629 if (!an->enable) { 2630 for (i = 0; i < 4; i++ ) { 2631 phy_copy.access.lane_mask = 0x1 << i; 2632 if (phy_copy.access.lane_mask & phy->access.lane_mask) continue; 2633 PHYMOD_IF_ERR_RETURN 2634 (tscf_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 2635 if (firmware_lane_config.AnEnabled) { 2636 an_enable_bitmap |= 1 << i; 2637 } 2638 } 2639 2640 } 2641 2642 phy_copy.access.lane_mask = 0x1 << start_lane; 2643 2644 /* make sure the firmware config is set to an eenabled */ 2645 PHYMOD_IF_ERR_RETURN 2646 (tscf_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 2647 /* make sure the firmware config is set to an eenabled */ 2648 PHYMOD_IF_ERR_RETURN 2649 (tscf_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp)); 2650 do_lane_config_set = 0; 2651 do_core_config_set = 0; 2652 2653 if (an->enable) { 2654 if(firmware_lane_config.AnEnabled != 1) { 2655 firmware_lane_config.AnEnabled = 1; 2656 do_lane_config_set = 1; 2657 } 2658 if(firmware_lane_config.LaneConfigFromPCS != 1) { 2659 firmware_lane_config.LaneConfigFromPCS = 1; 2660 do_lane_config_set = 1; 2661 } 2662 if(firmware_core_config_tmp.CoreConfigFromPCS != 1) { 2663 firmware_core_config_tmp.CoreConfigFromPCS = 1; 2664 do_core_config_set = 1; 2665 } 2666 firmware_lane_config.Cl72RestTO = 0; 2667 } else { 2668 if(firmware_lane_config.AnEnabled != 0) { 2669 firmware_lane_config.AnEnabled = 0; 2670 do_lane_config_set = 1; 2671 } 2672 if(firmware_lane_config.LaneConfigFromPCS != 0) { 2673 firmware_lane_config.LaneConfigFromPCS = 0; 2674 do_lane_config_set = 1; 2675 } 2676 if(firmware_core_config_tmp.CoreConfigFromPCS != 0) { 2677 if (!an_enable_bitmap) { 2678 firmware_core_config_tmp.CoreConfigFromPCS = 0; 2679 do_core_config_set = 1; 2680 } 2681 } 2682 firmware_lane_config.Cl72RestTO = 1; 2683 } 2684 2685 if(do_core_config_set && single_port_mode) { 2686 PHYMOD_IF_ERR_RETURN 2687 (falcon_core_soft_reset_release(&phy_copy.access, 0)); 2688 PHYMOD_USLEEP(1000); 2689 2690 PHYMOD_IF_ERR_RETURN 2691 (tscf_phy_firmware_core_config_set(&phy_copy, firmware_core_config_tmp)); 2692 2693 PHYMOD_IF_ERR_RETURN 2694 (falcon_core_soft_reset_release(&phy_copy.access, 1)); 2695 } 2696 2697 if(do_lane_config_set) { 2698 for (i = 0; i < num_lane; i++) { 2699 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2700 continue; 2701 } 2702 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2703 PHYMOD_IF_ERR_RETURN 2704 (falcon_lane_soft_reset_release(&phy_copy.access, 0)); 2705 } 2706 2707 PHYMOD_USLEEP(1000); 2708 for (i = 0; i < num_lane; i++) { 2709 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2710 continue; 2711 } 2712 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2713 PHYMOD_IF_ERR_RETURN 2714 (_tscf_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config)); 2715 } 2716 2717 for (i = 0; i < num_lane; i++) { 2718 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2719 continue; 2720 } 2721 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2722 PHYMOD_IF_ERR_RETURN 2723 (falcon_lane_soft_reset_release(&phy_copy.access, 1)); 2724 } 2725 } 2726 2727 phy_copy.access.lane_mask = 0x1 << start_lane; 2728 2729 if (!an->enable) { 2730 PHYMOD_IF_ERR_RETURN(tefmod_enable_set(&phy_copy.access)); 2731 } 2732 2733 if(an->enable && single_port_mode) { 2734 PHYMOD_IF_ERR_RETURN 2735 (tefmod_master_port_num_set(&phy_copy.access, start_lane)); 2736 } 2737 2738 PHYMOD_IF_ERR_RETURN 2739 (tefmod_autoneg_control(&phy_copy.access, &an_control)); 2740 return PHYMOD_E_NONE; 2741 } 2742 2743 int tscf_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 2744 { 2745 tefmod_an_control_t an_control; 2746 phymod_phy_access_t phy_copy; 2747 int start_lane, num_lane; 2748 int an_complete = 0; 2749 2750 /* next program the tx fir taps and driver current based on the input */ 2751 PHYMOD_IF_ERR_RETURN 2752 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2753 2754 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2755 phy_copy.access.lane_mask = 0x1 << start_lane; 2756 2757 PHYMOD_MEMSET(&an_control, 0x0, sizeof(tefmod_an_control_t)); 2758 PHYMOD_IF_ERR_RETURN 2759 (tefmod_autoneg_control_get(&phy_copy.access, &an_control, &an_complete)); 2760 2761 if (an_control.enable) { 2762 an->enable = 1; 2763 *an_done = an_complete; 2764 } else { 2765 an->enable = 0; 2766 } 2767 2768 if(an_control.pd_kx_en) { 2769 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(an) ; 2770 } 2771 2772 switch (an_control.an_type) { 2773 case TEFMOD_AN_MODE_CL73: 2774 an->an_mode = phymod_AN_MODE_CL73; 2775 break; 2776 case TEFMOD_AN_MODE_CL73BAM: 2777 an->an_mode = phymod_AN_MODE_CL73BAM; 2778 break; 2779 case TEFMOD_AN_MODE_MSA: 2780 an->an_mode = phymod_AN_MODE_MSA; 2781 break; 2782 case TEFMOD_AN_MODE_CL73_MSA: 2783 an->an_mode = phymod_AN_MODE_CL73_MSA; 2784 break; 2785 case TEFMOD_AN_MODE_HPAM: 2786 an->an_mode = phymod_AN_MODE_HPAM; 2787 break; 2788 default: 2789 an->an_mode = phymod_AN_MODE_NONE; 2790 break; 2791 } 2792 return PHYMOD_E_NONE; 2793 } 2794 2795 2796 int tscf_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 2797 { 2798 int speed_id, an_en, an_done; 2799 phymod_phy_inf_config_t config; 2800 phymod_ref_clk_t ref_clock; 2801 const phymod_access_t *pm_acc = &phy->access; 2802 2803 PHYMOD_IF_ERR_RETURN 2804 (tefmod_autoneg_status_get(&phy->access, &an_en, &an_done)); 2805 2806 PHYMOD_IF_ERR_RETURN 2807 (tefmod_speed_id_get(&phy->access, &speed_id)); 2808 2809 PHYMOD_IF_ERR_RETURN 2810 (tefmod_refclk_get(pm_acc, &ref_clock)); 2811 2812 config.ref_clock = ref_clock; 2813 PHYMOD_IF_ERR_RETURN 2814 (_tscf_speed_id_interface_config_get(phy, speed_id, &config)); 2815 2816 status->enabled = an_en; 2817 status->locked = an_done; 2818 status->data_rate = config.data_rate; 2819 status->interface = config.interface_type; 2820 2821 return PHYMOD_E_NONE; 2822 } 2823 2824 STATIC 2825 int _tscf_core_init_pass1(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 2826 { 2827 int rv; 2828 uint32_t uc_enable = 0, rev_letter; 2829 phymod_phy_access_t phy_access; 2830 phymod_core_access_t core_copy; 2831 MAIN0_SERDESIDr_t serdesid; 2832 uint32_t model; 2833 2834 TSCF_CORE_TO_PHY_ACCESS(&phy_access, core); 2835 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 2836 core_copy.access.lane_mask = 0x1; 2837 2838 /* read the serdes_id, if not revB, bypass the uc_active checking */ 2839 rv = READ_MAIN0_SERDESIDr(&core_copy.access, &serdesid); 2840 rev_letter = MAIN0_SERDESIDr_REV_LETTERf_GET(serdesid); 2841 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 2842 2843 PHYMOD_IF_ERR_RETURN 2844 (tefmod_pmd_reset_seq(&core_copy.access, core_status->pmd_active)); 2845 2846 /* added the support for both tscf gen1 and gen2 support*/ 2847 if ((rev_letter == TSCF_REV_LETTER_B) || (model == TSCF_GEN2_MODEL)) { 2848 PHYMOD_IF_ERR_RETURN(falcon_uc_active_get(&phy_access.access, &uc_enable)); 2849 if (uc_enable) { 2850 return PHYMOD_E_NONE; 2851 } 2852 } 2853 2854 /*need to set the heart beat default is for 156.25M*/ 2855 if (init_config->interface.ref_clock == phymodRefClk125Mhz) { 2856 /* we need to set the ref clock config differently */ 2857 PHYMOD_IF_ERR_RETURN 2858 (tefmod_refclk_set(&core_copy.access, phymodRefClk125Mhz)); 2859 } 2860 2861 rv = _tscf_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader); 2862 if (rv != PHYMOD_E_NONE) { 2863 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask)); 2864 PHYMOD_IF_ERR_RETURN(rv); 2865 } 2866 return PHYMOD_E_NONE; 2867 } 2868 2869 2870 STATIC 2871 int _tscf_core_init_pass2(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 2872 { 2873 phymod_phy_access_t phy_access, phy_access_copy; 2874 phymod_core_access_t core_copy; 2875 phymod_firmware_core_config_t firmware_core_config_tmp; 2876 MAIN0_SERDESIDr_t serdesid; 2877 uint32_t model; 2878 int rv; 2879 2880 2881 TSCF_CORE_TO_PHY_ACCESS(&phy_access, core); 2882 phy_access_copy = phy_access; 2883 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 2884 core_copy.access.lane_mask = 0x1; 2885 phy_access_copy = phy_access; 2886 phy_access_copy.access = core->access; 2887 phy_access_copy.access.lane_mask = 0x1; 2888 phy_access_copy.type = core->type; 2889 2890 /* read the serdes_id*/ 2891 rv = READ_MAIN0_SERDESIDr(&core_copy.access, &serdesid); 2892 if (rv != PHYMOD_E_NONE) { 2893 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: serdes ID read failed\n", core->access.addr, core->access.lane_mask)); 2894 PHYMOD_IF_ERR_RETURN(rv); 2895 } 2896 2897 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 2898 2899 /*next we need to check if the load is correct or not */ 2900 #ifndef TSCF_PMD_CRC_UCODE 2901 if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone) { 2902 rv = falcon_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) &tscf_ucode, tscf_ucode_len); 2903 if(rv != PHYMOD_E_NONE) { 2904 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 2905 PHYMOD_IF_ERR_RETURN(rv); 2906 } 2907 } 2908 #endif 2909 2910 PHYMOD_IF_ERR_RETURN 2911 (falcon_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1)); 2912 2913 /*next we need to set the uc active and release uc */ 2914 PHYMOD_IF_ERR_RETURN 2915 (falcon_uc_active_set(&core_copy.access ,1)); 2916 /*release the uc reset */ 2917 PHYMOD_IF_ERR_RETURN 2918 (falcon_tsc_uc_reset(&core_copy.access ,0)); 2919 /* we need to wait at least 10ms for the uc to settle */ 2920 /* PHYMOD_USLEEP(10000); */ 2921 2922 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 2923 #ifndef TSCF_PMD_CRC_UCODE 2924 /* poll the ready bit in 10 ms */ 2925 /* Coverity fix: checking the return value with PHYMOD_IF_ERR_RETURN */ 2926 PHYMOD_IF_ERR_RETURN 2927 (falcon_tsc_poll_uc_dsc_ready_for_cmd_equals_1(&phy_access_copy.access, 100)); 2928 #else 2929 PHYMOD_IF_ERR_RETURN( 2930 falcon_tsc_ucode_crc_verify( &core_copy.access, tscf_ucode_len, tscf_ucode_crc)); 2931 #endif 2932 } 2933 PHYMOD_IF_ERR_RETURN( 2934 falcon_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0)); 2935 2936 /* next check if in pcs-bypass mode */ 2937 if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(core->device_op_mode)) { 2938 phy_access_copy.access.lane_mask = 0xf; 2939 PHYMOD_IF_ERR_RETURN( 2940 tefmod_pcs_ilkn_mode_set(&phy_access_copy.access)); 2941 phy_access_copy.access.lane_mask = 0x1; 2942 } 2943 2944 /* plldiv CONFIG */ 2945 PHYMOD_IF_ERR_RETURN 2946 (falcon_pll_mode_set(&core_copy.access, 0xa)); 2947 2948 /*now config the lane mapping and polarity */ 2949 PHYMOD_IF_ERR_RETURN 2950 (tscf_core_lane_map_set(core, &init_config->lane_map)); 2951 2952 /* check if tscf gen2 version need to set the credit to 1 */ 2953 if (model == TSCF_GEN2_MODEL) { 2954 PHYMOD_IF_ERR_RETURN 2955 (tefmod_default_init(&core->access)); 2956 } 2957 2958 PHYMOD_IF_ERR_RETURN 2959 (tefmod_autoneg_timer_init(&core->access)); 2960 PHYMOD_IF_ERR_RETURN 2961 (tefmod_master_port_num_set(&core->access, 0)); 2962 /*don't overide the fw that set in config set if not specified*/ 2963 firmware_core_config_tmp = init_config->firmware_core_config; 2964 firmware_core_config_tmp.CoreConfigFromPCS = 0; 2965 /*set the vco rate to be default at 27.34G */ 2966 firmware_core_config_tmp.VcoRate = 214; 2967 2968 /* AFE/PLL config */ 2969 if(init_config->afe_pll.afe_pll_change_default) { 2970 PHYMOD_IF_ERR_RETURN 2971 (falcon_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 2972 firmware_core_config_tmp.disable_write_pll_iqp = 1; 2973 } else { 2974 PHYMOD_IF_ERR_RETURN 2975 (falcon_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 2976 firmware_core_config_tmp.disable_write_pll_iqp = 0; 2977 } 2978 2979 PHYMOD_IF_ERR_RETURN 2980 (tscf_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 2981 2982 PHYMOD_IF_ERR_RETURN 2983 (tefmod_cl74_chng_default (&core_copy.access)); 2984 2985 PHYMOD_IF_ERR_RETURN 2986 (tefmod_cl91_ecc_clear (&core_copy.access, model)); 2987 2988 /* release core soft reset */ 2989 PHYMOD_IF_ERR_RETURN 2990 (falcon_core_soft_reset_release(&core_copy.access, 1)); 2991 2992 return PHYMOD_E_NONE; 2993 } 2994 2995 int tscf_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 2996 { 2997 2998 if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) && 2999 !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) || 3000 PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) { 3001 PHYMOD_IF_ERR_RETURN 3002 (_tscf_core_init_pass1(core, init_config, core_status)); 3003 3004 if (PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) { 3005 return PHYMOD_E_NONE; 3006 } 3007 } 3008 3009 if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) && 3010 !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) || 3011 PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) { 3012 PHYMOD_IF_ERR_RETURN 3013 (_tscf_core_init_pass2(core, init_config, core_status)); 3014 } 3015 3016 return PHYMOD_E_NONE; 3017 } 3018 3019 3020 int tscf_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 3021 { 3022 int pll_restart = 0; 3023 const phymod_access_t *pm_acc = &phy->access; 3024 phymod_phy_access_t pm_phy_copy; 3025 int start_lane, num_lane, i; 3026 int lane_bkup; 3027 phymod_polarity_t tmp_pol; 3028 phymod_firmware_lane_config_t firmware_lane_config; 3029 uint32_t model = 0; 3030 3031 3032 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 3033 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 3034 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 3035 3036 /*next program the tx fir taps and driver current based on the input*/ 3037 PHYMOD_IF_ERR_RETURN 3038 (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane)); 3039 /*per lane based reset release */ 3040 PHYMOD_IF_ERR_RETURN 3041 (tefmod_pmd_x4_reset(pm_acc)); 3042 3043 lane_bkup = pm_phy_copy.access.lane_mask; 3044 for (i = 0; i < num_lane; i++) { 3045 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3046 continue; 3047 } 3048 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 3049 PHYMOD_IF_ERR_RETURN 3050 (falcon_lane_soft_reset_release(&pm_phy_copy.access, 1)); 3051 } 3052 pm_phy_copy.access.lane_mask = lane_bkup; 3053 3054 /* clearing all the lane config */ 3055 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 3056 3057 /* program the rx/tx polarity */ 3058 for (i = 0; i < num_lane; i++) { 3059 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3060 continue; 3061 } 3062 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3063 tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1; 3064 tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1; 3065 PHYMOD_IF_ERR_RETURN 3066 (tscf_phy_polarity_set(&pm_phy_copy, &tmp_pol)); 3067 } 3068 3069 for (i = 0; i < num_lane; i++) { 3070 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3071 continue; 3072 } 3073 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3074 PHYMOD_IF_ERR_RETURN 3075 (tscf_phy_tx_set(&pm_phy_copy, &init_config->tx[i])); 3076 } 3077 3078 for (i = 0; i < num_lane; i++) { 3079 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3080 continue; 3081 } 3082 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3083 PHYMOD_IF_ERR_RETURN 3084 (_tscf_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 3085 } 3086 /* next check if pcs-bypass mode */ 3087 if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy->device_op_mode)) { 3088 PHYMOD_IF_ERR_RETURN 3089 (falcon_pmd_tx_disable_pin_dis_set(&phy->access, 1)); 3090 PHYMOD_IF_ERR_RETURN 3091 (tefmod_init_pcs_ilkn(&phy->access)); 3092 } 3093 3094 PHYMOD_IF_ERR_RETURN 3095 (tefmod_update_port_mode(pm_acc, &pll_restart)); 3096 3097 PHYMOD_IF_ERR_RETURN 3098 (tefmod_rx_lane_control_set(pm_acc, 1)); 3099 PHYMOD_IF_ERR_RETURN 3100 (tefmod_tx_lane_control_set(pm_acc, TEFMOD_TX_LANE_RESET_TRAFFIC_ENABLE)); /* TX_LANE_CONTROL */ 3101 3102 /* Initialize the default AM values. This values will be used only when the port s running at 25G */ 3103 3104 PHYMOD_IF_ERR_RETURN 3105 (tefmod_serdes_model_get(pm_acc, &model)); 3106 3107 /* Init the default AM values for single ane RS FEC 3108 * these values are only used at 25G 3109 */ 3110 if (model == TSCF_GEN2_MODEL) { 3111 PHYMOD_IF_ERR_RETURN( 3112 tefmod_25g_rsfec_am_init(pm_acc)); 3113 } 3114 3115 return PHYMOD_E_NONE; 3116 } 3117 3118 3119 int tscf_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 3120 { 3121 int i; 3122 int start_lane, num_lane; 3123 int rv = PHYMOD_E_NONE; 3124 uint32_t cl72_en; 3125 phymod_phy_access_t phy_copy; 3126 3127 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3128 3129 /* next figure out the lane num and start_lane based on the input */ 3130 PHYMOD_IF_ERR_RETURN 3131 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3132 3133 switch (loopback) { 3134 case phymodLoopbackGlobal : 3135 PHYMOD_IF_ERR_RETURN 3136 (tscf_phy_cl72_get(phy, &cl72_en)); 3137 if((cl72_en == 1) && (enable == 1)) { 3138 PHYMOD_DEBUG_ERROR(("adr=%0"PRIx32",lane 0x%x: Error! pcs gloop not supported with cl72 enabled\n", phy_copy.access.addr, start_lane)); 3139 break; 3140 } 3141 PHYMOD_IF_ERR_RETURN(tefmod_tx_loopback_control(&phy->access, enable, start_lane, num_lane)); 3142 break; 3143 case phymodLoopbackGlobalPMD : 3144 PHYMOD_IF_ERR_RETURN 3145 (tscf_phy_cl72_get(phy, &cl72_en)); 3146 if((cl72_en == 1) && (enable == 1)) { 3147 PHYMOD_DEBUG_ERROR(("adr=%0"PRIx32",lane 0x%x: Error! pmd gloop not supported with cl72 enabled\n", phy_copy.access.addr, start_lane)); 3148 break; 3149 } 3150 for (i = 0; i < num_lane; i++) { 3151 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3152 continue; 3153 } 3154 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3155 PHYMOD_IF_ERR_RETURN(tefmod_tx_squelch_set(&phy_copy.access, enable)); 3156 PHYMOD_IF_ERR_RETURN(falcon_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable)); 3157 PHYMOD_IF_ERR_RETURN(falcon_pmd_force_signal_detect(&phy_copy.access, (int) enable)); 3158 PHYMOD_IF_ERR_RETURN(tefmod_rx_lane_control_set(&phy->access, 1)); 3159 } 3160 break; 3161 case phymodLoopbackRemotePMD : 3162 PHYMOD_IF_ERR_RETURN(falcon_tsc_rmt_lpbk(&phy->access, (uint8_t)enable)); 3163 break; 3164 case phymodLoopbackRemotePCS : 3165 /* PHYMOD_IF_ERR_RETURN(tefmod_rx_loopback_control(&phy->access, enable, enable, enable)); */ /* RAVI */ 3166 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 3167 (_PHYMOD_MSG("PCS Remote LoopBack not supported"))); 3168 break; 3169 default : 3170 break; 3171 } 3172 return rv; 3173 } 3174 3175 int tscf_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 3176 { 3177 uint32_t enable_core; 3178 int start_lane, num_lane; 3179 3180 *enable = 0; 3181 3182 /* next figure out the lane num and start_lane based on the input */ 3183 PHYMOD_IF_ERR_RETURN 3184 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3185 3186 switch (loopback) { 3187 case phymodLoopbackGlobal : 3188 PHYMOD_IF_ERR_RETURN(tefmod_tx_loopback_get(&phy->access, &enable_core)); 3189 *enable = (enable_core >> start_lane) & 0x1; 3190 break; 3191 case phymodLoopbackGlobalPMD : 3192 PHYMOD_IF_ERR_RETURN(falcon_tsc_dig_lpbk_get(&phy->access, enable)); 3193 break; 3194 case phymodLoopbackRemotePMD : 3195 PHYMOD_IF_ERR_RETURN(falcon_tsc_rmt_lpbk_get(&phy->access, enable)); 3196 break; 3197 case phymodLoopbackRemotePCS : 3198 /* PHYMOD_IF_ERR_RETURN(tefmod_rx_loopback_control(&phy->access, enable, enable, enable)); */ /* RAVI */ 3199 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 3200 (_PHYMOD_MSG("PCS Remote LoopBack not supported"))); 3201 break; 3202 default : 3203 break; 3204 } 3205 return PHYMOD_E_NONE; 3206 } 3207 3208 3209 int tscf_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_seq_done){ 3210 PHYMOD_IF_ERR_RETURN(tefmod_pmd_lock_get(&phy->access, rx_seq_done)); 3211 return PHYMOD_E_NONE; 3212 } 3213 3214 3215 int tscf_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 3216 { 3217 PHYMOD_IF_ERR_RETURN(tefmod_get_pcs_latched_link_status(&phy->access, link_status)); 3218 3219 return PHYMOD_E_NONE; 3220 } 3221 3222 int tscf_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config) 3223 { 3224 return PHYMOD_E_UNAVAIL; 3225 } 3226 3227 int tscf_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, phymod_pcs_userspeed_config_t* config) 3228 { 3229 return PHYMOD_E_UNAVAIL; 3230 } 3231 3232 int tscf_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t *val) 3233 { 3234 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val)); 3235 return PHYMOD_E_NONE; 3236 } 3237 3238 3239 int tscf_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 3240 { 3241 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val)); 3242 return PHYMOD_E_NONE; 3243 } 3244 3245 int tscf_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable) 3246 { 3247 uint32_t lpi_bypass; 3248 int rv = PHYMOD_E_NONE; 3249 lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable); 3250 enable &= 0x1; 3251 if (lpi_bypass) { 3252 rv = tefmod_eee_control_set(&phy->access,enable); 3253 } else { 3254 return PHYMOD_E_UNAVAIL; 3255 } 3256 return rv; 3257 } 3258 3259 int tscf_phy_eee_get(const phymod_phy_access_t* phy, uint32_t *enable) 3260 { 3261 if (PHYMOD_LPI_BYPASS_GET(*enable)) { 3262 PHYMOD_IF_ERR_RETURN(tefmod_eee_control_get(&phy->access, enable)); 3263 PHYMOD_LPI_BYPASS_SET(*enable); 3264 } else { 3265 return PHYMOD_E_UNAVAIL; 3266 } 3267 return PHYMOD_E_NONE; 3268 } 3269 3270 int tscf_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 3271 { 3272 uint8_t uc_lane_stopped; 3273 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_uc_lane_status(&phy->access, &uc_lane_stopped)); 3274 if (uc_lane_stopped) { 3275 PHYMOD_IF_ERR_RETURN(falcon_tsc_stop_rx_adaptation(&phy->access, 0)); 3276 } 3277 return PHYMOD_E_NONE; 3278 } 3279 3280 int tscf_phy_autoneg_oui_set(const phymod_phy_access_t* phy, phymod_autoneg_oui_t an_oui) { 3281 tefmod_an_oui_t oui; 3282 3283 oui.oui = an_oui.oui; 3284 oui.oui_override_hpam_adv = an_oui.oui_override_hpam_adv; 3285 oui.oui_override_hpam_det = an_oui.oui_override_hpam_det; 3286 oui.oui_override_bam73_adv = an_oui.oui_override_bam73_adv; 3287 oui.oui_override_bam73_det = an_oui.oui_override_bam73_det; 3288 3289 PHYMOD_IF_ERR_RETURN(tefmod_an_oui_set(&phy->access, oui)); 3290 3291 return PHYMOD_E_NONE; 3292 } 3293 3294 int tscf_phy_autoneg_oui_get(const phymod_phy_access_t* phy, phymod_autoneg_oui_t* an_oui) { 3295 tefmod_an_oui_t oui; 3296 3297 PHYMOD_IF_ERR_RETURN(tefmod_an_oui_get(&phy->access, &oui)); 3298 3299 an_oui->oui = oui.oui; 3300 an_oui->oui_override_hpam_adv = oui.oui_override_hpam_adv; 3301 an_oui->oui_override_hpam_det = oui.oui_override_hpam_det; 3302 an_oui->oui_override_bam73_adv = oui.oui_override_bam73_adv; 3303 an_oui->oui_override_bam73_det = oui.oui_override_bam73_det; 3304 3305 return PHYMOD_E_NONE; 3306 } 3307 3308 int tscf_phy_hg2_codec_control_set(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t hg2_codec) { 3309 tefmod_hg2_codec_t local_copy; 3310 switch (hg2_codec) { 3311 case phymodBcmHG2CodecOff: local_copy = TEFMOD_HG2_CODEC_OFF; 3312 break; 3313 case phymodBcmHG2CodecOnWith8ByteIPG: local_copy = TEFMOD_HG2_CODEC_ON_8BYTE_IPG; 3314 break; 3315 case phymodBcmHG2CodecOnWith9ByteIPG: local_copy = TEFMOD_HG2_CODEC_ON_9BYTE_IPG; 3316 break; 3317 default: local_copy = TEFMOD_HG2_CODEC_OFF; 3318 break; 3319 } 3320 PHYMOD_IF_ERR_RETURN(tefmod_hg2_codec_set(&phy->access, local_copy)); 3321 return PHYMOD_E_NONE; 3322 } 3323 3324 int tscf_phy_hg2_codec_control_get(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t* hg2_codec) { 3325 tefmod_hg2_codec_t local_copy; 3326 3327 PHYMOD_IF_ERR_RETURN(tefmod_hg2_codec_get(&phy->access, &local_copy)); 3328 3329 switch (local_copy) { 3330 case TEFMOD_HG2_CODEC_OFF: *hg2_codec = phymodBcmHG2CodecOff; 3331 break; 3332 case TEFMOD_HG2_CODEC_ON_8BYTE_IPG: *hg2_codec = phymodBcmHG2CodecOnWith8ByteIPG; 3333 break; 3334 case TEFMOD_HG2_CODEC_ON_9BYTE_IPG: *hg2_codec = phymodBcmHG2CodecOnWith9ByteIPG; 3335 break; 3336 default: *hg2_codec = phymodBcmHG2CodecOff; 3337 break; 3338 } 3339 return PHYMOD_E_NONE; 3340 } 3341 3342 int tscf_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value) 3343 { 3344 int start_lane, num_lane; 3345 phymod_phy_access_t phy_copy; 3346 int hz_l, hz_r, vt_u, vt_d; 3347 3348 3349 /* first get the start_lane */ 3350 PHYMOD_IF_ERR_RETURN 3351 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3352 3353 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3354 phy_copy.access.lane_mask = 0x1 << start_lane; 3355 3356 PHYMOD_IF_ERR_RETURN 3357 (falcon_tsc_get_eye_margin_est(&phy_copy.access, &hz_l, &hz_r, &vt_u, &vt_d)); 3358 3359 switch (eye_margin_mode) { 3360 case phymod_eye_marign_HZ_L: 3361 *value = hz_l; 3362 break; 3363 case phymod_eye_marign_HZ_R: 3364 *value = hz_r; 3365 break; 3366 case phymod_eye_marign_VT_U: 3367 *value = vt_u; 3368 break; 3369 case phymod_eye_marign_VT_D: 3370 *value = vt_d; 3371 break; 3372 default: 3373 *value = 0; 3374 break; 3375 } 3376 3377 return PHYMOD_E_NONE; 3378 } 3379 3380 int 3381 tscf_phy_sw_an_advert_set(const phymod_phy_access_t* phy, 3382 const phymod_autoneg_ability_t* an_ability, 3383 phymod_sw_an_ctxt_t* an_ctxt) 3384 { 3385 tefmod_an_adv_ability_t value; 3386 int start_lane, num_lane; 3387 phymod_phy_access_t phy_copy; 3388 phymod_core_info_t core_info; 3389 MAIN0_SERDESIDr_t serdesid; 3390 /* DIG_REVID0r_t revid; */ 3391 uint32_t model = 0; 3392 3393 3394 PHYMOD_IF_ERR_RETURN 3395 (tefmod_serdes_model_get(&phy->access, &model)); 3396 3397 if (model != TSCF_GEN2_MODEL) { 3398 return PHYMOD_E_UNAVAIL; 3399 } 3400 3401 3402 /* next program the tx fir taps and driver current based on the input */ 3403 PHYMOD_IF_ERR_RETURN 3404 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3405 3406 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3407 phy_copy.access.lane_mask = 0x1 << start_lane; 3408 3409 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 3410 PHYMOD_MEMSET(&core_info, 0x0, sizeof(core_info)); 3411 3412 PHYMOD_IF_ERR_RETURN 3413 (tscf_core_info_get((phymod_core_access_t *)phy, &core_info)); 3414 3415 3416 /*first check if tscf gen2 or not */ 3417 READ_MAIN0_SERDESIDr(&phy_copy.access, &serdesid); 3418 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdesid); 3419 3420 value.an_cl72 = an_ability->an_cl72; 3421 3422 if (model == TSCF_MODEL) { 3423 if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) { 3424 value.an_fec = TEFMOD_FEC_SUPRTD_NOT_REQSTD; 3425 } else if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)) { 3426 value.an_fec = TEFMOD_FEC_CL74_SUPRTD_REQSTD; 3427 } 3428 } else { 3429 /* this is new CL91 support on gen2 version */ 3430 if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) { 3431 value.an_fec = TEFMOD_FEC_SUPRTD_NOT_REQSTD; 3432 } else { 3433 if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)) 3434 value.an_fec = TEFMOD_FEC_CL74_SUPRTD_REQSTD; 3435 if (PHYMOD_AN_FEC_CL91_GET(an_ability->an_fec)) 3436 value.an_fec |= TEFMOD_FEC_CL91_SUPRTD_REQSTD; 3437 } 3438 } 3439 3440 /* value.an_fec = an_ability->an_fec; */ 3441 value.an_hg2 = an_ability->an_hg2; 3442 3443 /* tscf a0 does not support cl91 */ 3444 /* next check pause */ 3445 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) { 3446 value.an_pause = TEFMOD_SYMM_PAUSE; 3447 } 3448 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 3449 value.an_pause = TEFMOD_ASYM_PAUSE; 3450 } 3451 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 3452 value.an_pause = TEFMOD_ASYM_SYMM_PAUSE; 3453 } 3454 3455 /* check cl73 and cl73 bam ability */ 3456 if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)) 3457 value.an_base_speed |= 1 << TEFMOD_CL73_1GBASE_KX; 3458 if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)) 3459 value.an_base_speed |= 1 << TEFMOD_CL73_10GBASE_KR1; 3460 if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)) 3461 value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_KR4; 3462 if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)) 3463 value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_CR4; 3464 if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) { 3465 if (core_info.core_version == phymodCoreVersionTscfA0) { 3466 value.an_fec = TEFMOD_FEC_NOT_SUPRTD; 3467 } 3468 value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_KR4; 3469 } 3470 if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) { 3471 if (core_info.core_version == phymodCoreVersionTscfA0) { 3472 value.an_fec = TEFMOD_FEC_NOT_SUPRTD; 3473 } 3474 value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_CR4; 3475 } 3476 /* tscf gen2 added 25G as the IEEE base cl73 speed */ 3477 if (model == TSCF_GEN2_MODEL) { 3478 if (PHYMOD_AN_CAP_25G_CR1_GET(an_ability->an_cap)) 3479 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CR1; 3480 if (PHYMOD_AN_CAP_25G_KR1_GET(an_ability->an_cap)) 3481 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KR1; 3482 if (PHYMOD_AN_CAP_25G_CRS1_GET(an_ability->an_cap)) 3483 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CRS1; 3484 if (PHYMOD_AN_CAP_25G_KRS1_GET(an_ability->an_cap)) 3485 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KRS1; 3486 } 3487 3488 /* check cl73 bam ability */ 3489 if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap)) 3490 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_KR2; 3491 if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap)) 3492 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_CR2; 3493 if (PHYMOD_BAM_CL73_CAP_40G_KR2_GET(an_ability->cl73bam_cap)) 3494 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_KR2; 3495 if (PHYMOD_BAM_CL73_CAP_40G_CR2_GET(an_ability->cl73bam_cap)) 3496 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_CR2; 3497 if (PHYMOD_BAM_CL73_CAP_50G_KR2_GET(an_ability->cl73bam_cap)) 3498 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR2; 3499 if (PHYMOD_BAM_CL73_CAP_50G_CR2_GET(an_ability->cl73bam_cap)) 3500 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR2; 3501 if (PHYMOD_BAM_CL73_CAP_50G_KR4_GET(an_ability->cl73bam_cap)) 3502 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR4; 3503 if (PHYMOD_BAM_CL73_CAP_50G_CR4_GET(an_ability->cl73bam_cap)) 3504 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR4; 3505 3506 if (PHYMOD_BAM_CL73_CAP_20G_KR1_GET(an_ability->cl73bam_cap)) 3507 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_KR1; 3508 if (PHYMOD_BAM_CL73_CAP_20G_CR1_GET(an_ability->cl73bam_cap)) 3509 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_CR1; 3510 if (PHYMOD_BAM_CL73_CAP_25G_KR1_GET(an_ability->cl73bam_cap)) 3511 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_KR1; 3512 if (PHYMOD_BAM_CL73_CAP_25G_CR1_GET(an_ability->cl73bam_cap)) 3513 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_CR1; 3514 3515 3516 PHYMOD_IF_ERR_RETURN 3517 (tefmod_sw_an_advert_set(&phy_copy.access, &value, an_ctxt)); 3518 return PHYMOD_E_NONE; 3519 3520 } 3521 3522 static int 3523 _tscf_sw_an_pmd_lane_cfg_set(phymod_phy_access_t* phy, int enable) 3524 { 3525 int start_lane, num_lane, i=0; 3526 phymod_phy_access_t phy_copy; 3527 phymod_firmware_lane_config_t firmware_lane_config; 3528 3529 3530 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 3531 3532 PHYMOD_IF_ERR_RETURN 3533 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3534 3535 3536 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3537 phy_copy.access.lane_mask = 0x1 << start_lane; 3538 3539 /* make sure the firmware config is set to an eenabled */ 3540 PHYMOD_IF_ERR_RETURN 3541 (tscf_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 3542 if (enable) { 3543 firmware_lane_config.AnEnabled = 1; 3544 firmware_lane_config.LaneConfigFromPCS = 1; 3545 } else { 3546 firmware_lane_config.AnEnabled = 0; 3547 firmware_lane_config.LaneConfigFromPCS = 0; 3548 } 3549 3550 for (i = 0; i < num_lane; i++) { 3551 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3552 continue; 3553 } 3554 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3555 PHYMOD_IF_ERR_RETURN 3556 (falcon_lane_soft_reset_release(&phy_copy.access, 0)); 3557 } 3558 3559 PHYMOD_USLEEP(1000); 3560 for (i = 0; i < num_lane; i++) { 3561 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3562 continue; 3563 } 3564 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3565 PHYMOD_IF_ERR_RETURN 3566 (_tscf_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config)); 3567 } 3568 3569 for (i = 0; i < num_lane; i++) { 3570 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3571 continue; 3572 } 3573 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3574 PHYMOD_IF_ERR_RETURN 3575 (falcon_lane_soft_reset_release(&phy_copy.access, 1)); 3576 } 3577 3578 return PHYMOD_E_NONE; 3579 } 3580 3581 3582 static int 3583 _resolve_speed(const phymod_phy_access_t* phy, phymod_sw_an_ctxt_t *an_ctxt) 3584 { 3585 uint16_t common_tech_ability = 0; 3586 uint16_t hcd_speed = HCD_SPEED_ID_UNDEFINED; 3587 uint8_t is_krs = 0; 3588 uint8_t cl74_fec = 0, cl91_fec = 0, cl74_25gkrs_fec = 0; 3589 uint32_t msa_code_13_23 = 0, msa_code_2_12 = 0, msa_code_0_1 =0; 3590 uint8_t ld_cl91_sup, ld_cl91_req, rd_cl91_sup, rd_cl91_req; 3591 uint8_t ld_cl74_sup, ld_cl74_req, rd_cl74_sup, rd_cl74_req; 3592 uint8_t rd_base_cl74_fec_req, rd_base_cl74_fec_sup, ld_base_cl74_fec_req, ld_base_cl74_fec_sup; 3593 tefmod_fec_type_t fec_type; 3594 3595 /* Resolve base page tech ability */ 3596 if ((an_ctxt->rx_pages.base_page.page_1 >> AN_BASE1_PAGE_ABILITY_OFFSET) & 3597 AN_BASE1_PAGE_ABILITY_MASK) { 3598 common_tech_ability = (((an_ctxt->rx_pages.base_page.page_1) & 3599 (an_ctxt->tx_pages.base_page.page_1)) & 3600 (AN_BASE1_PAGE_ABILITY_MASK << AN_BASE1_PAGE_ABILITY_OFFSET)); 3601 if ((common_tech_ability >> AN_BASE_TECH_ABILITY_100GKR4_OFFSET) & AN_BASE_TECH_ABILITY_100GKR4_MASK) { 3602 hcd_speed = TEFMOD_100G_KR4_SPD_IF; 3603 } else if ((common_tech_ability >> AN_BASE_TECH_ABILITY_100GCR4_OFFSET) & AN_BASE_TECH_ABILITY_100GCR4_MASK) { 3604 hcd_speed = TEFMOD_100G_CR4_SPD_IF; 3605 } else if ((common_tech_ability >> AN_BASE_TECH_ABILITY_25GKR_OFFSET) & AN_BASE_TECH_ABILITY_25GKR_MASK) { 3606 /* speed is 25G KR */ 3607 hcd_speed = TEFMOD_25G_KR_SPD_IF; /* speed ID for 25G KR */ 3608 } else if ((common_tech_ability >> AN_BASE_TECH_ABILITY_25GKRS_OFFSET) & AN_BASE_TECH_ABILITY_25GKRS_MASK) { 3609 hcd_speed = TEFMOD_25G_KR_SPD_IF; /* tSCf does not differntiate between KR and KRS */ 3610 is_krs = 1; 3611 } else { 3612 /* TH SW AN will be used only for IEEE 100/25G and MSA 3613 * NO need to look for 10G and 40G 3614 */ 3615 hcd_speed = HCD_SPEED_ID_UNDEFINED; 3616 } 3617 3618 /* Resolve base page FEC ability */ 3619 if (an_ctxt->rx_pages.base_page.page_2) { 3620 /* always advertise cl91/74 supported mask */ 3621 cl91_fec = (((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL91_ABILITY_REQ_OFFSET) & 3622 AN_BASE_CL91_ABILITY_REQ_MASK) | 3623 ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL91_ABILITY_REQ_OFFSET) & 3624 AN_BASE_CL91_ABILITY_REQ_MASK)); 3625 3626 cl74_25gkrs_fec = (((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_25GKRS_REQ_OFFSET) & 3627 AN_BASE_CL74_25GKRS_REQ_MASK) | 3628 ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_25GKRS_REQ_OFFSET) & 3629 AN_BASE_CL74_25GKRS_REQ_MASK)); 3630 3631 cl74_fec = (((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) & 3632 AN_BASE_CL74_ABILITY_REQ_MASK) | 3633 ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) & 3634 AN_BASE_CL74_ABILITY_REQ_MASK)); 3635 } 3636 3637 } 3638 3639 if (hcd_speed == HCD_SPEED_ID_UNDEFINED) { 3640 /* NO IEEE Common speed found look for MSA Speeds */ 3641 msa_code_13_23 = ((an_ctxt->rx_pages.msg_page.page_1 >> AN_MSG_PAGE1_OUI_13to23_OFFSET) & 3642 AN_MSG_PAGE1_OUI_13to23_MASK); 3643 msa_code_2_12 = ((an_ctxt->rx_pages.msg_page.page_2 >> AN_MSG_PAGE2_OUI_2to12_OFFSET) & 3644 AN_MSG_PAGE2_OUI_2to12_MASK); 3645 msa_code_0_1 = ((an_ctxt->tx_pages.ufmt_page.page_0 >> AN_UF_PAGE0_OUI_OFFSET) & 3646 AN_UF_PAGE0_OUI_MASK); 3647 3648 if ((msa_code_13_23 == MSA_OUI_13to23) && 3649 (msa_code_2_12 == MSA_OUT_2to12) && 3650 (msa_code_0_1 == MSA_OUI_0to1)) { 3651 3652 /* MSA PAGE FOUND. Now parse the MSA pages */ 3653 common_tech_ability = (an_ctxt->tx_pages.ufmt_page.page_1 & an_ctxt->rx_pages.ufmt_page.page_1); 3654 3655 if ((common_tech_ability >> AN_UF_PAGE1_50G_KR2_ABILITY_OFFSET) & 3656 AN_UF_PAGE1_50G_KR2_ABILITY_MASK) { 3657 hcd_speed = TEFMOD_50G_KR2_SPD_IF; 3658 } else if ((common_tech_ability >> AN_UF_PAGE1_50G_CR2_ABILITY_OFFSET) & 3659 AN_UF_PAGE1_50G_CR2_ABILITY_MASK) { 3660 hcd_speed = TEFMOD_50G_CR2_SPD_IF; 3661 } else if ((common_tech_ability >> AN_UF_PAGE1_25G_KR1_ABILITY_OFFSET) & 3662 AN_UF_PAGE1_25G_KR1_ABILITY_MASK) { 3663 hcd_speed = TEFMOD_25G_KR_SPD_IF; 3664 } else if ((common_tech_ability >> AN_UF_PAGE1_25G_CR1_ABILITY_OFFSET) & 3665 AN_UF_PAGE1_25G_CR1_ABILITY_MASK) { 3666 hcd_speed = TEFMOD_25G_KR_SPD_IF; 3667 } else { 3668 /* Resolution error */ 3669 return PHYMOD_E_CONFIG; 3670 } 3671 3672 /* resolve FEC */ 3673 if (an_ctxt->tx_pages.ufmt_page.page_2 & an_ctxt->rx_pages.ufmt_page.page_2) { 3674 ld_cl91_sup = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_SUPPORT_OFFSET) & 3675 AN_UF_PAGE2_CL91_SUPPORT_MASK); 3676 ld_cl91_req = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_REQ_OFFSET) & 3677 AN_UF_PAGE2_CL91_REQ_MASK); 3678 ld_cl74_sup = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_SUPPORT_OFFSET) & 3679 AN_UF_PAGE2_CL74_SUPPORT_MASK); 3680 ld_cl74_req = ((an_ctxt->tx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_REQ_OFFSET) & 3681 AN_UF_PAGE2_CL74_REQ_MASK); 3682 3683 rd_cl91_sup = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_SUPPORT_OFFSET) & 3684 AN_UF_PAGE2_CL91_SUPPORT_MASK); 3685 rd_cl91_req = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL91_REQ_OFFSET) & 3686 AN_UF_PAGE2_CL91_REQ_MASK); 3687 rd_cl74_sup = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_SUPPORT_OFFSET) & 3688 AN_UF_PAGE2_CL74_SUPPORT_MASK); 3689 rd_cl74_req = ((an_ctxt->rx_pages.ufmt_page.page_2 >> AN_UF_PAGE2_CL74_REQ_OFFSET) & 3690 AN_UF_PAGE2_CL74_REQ_MASK); 3691 3692 rd_base_cl74_fec_req = ((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) & 3693 AN_BASE_CL74_ABILITY_REQ_MASK); 3694 ld_base_cl74_fec_req = ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_REQ_OFFSET) & 3695 AN_BASE_CL74_ABILITY_REQ_MASK); 3696 rd_base_cl74_fec_sup = ((an_ctxt->rx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_SUP_OFFSET) & 3697 AN_BASE_CL74_ABILITY_SUP_MASK); 3698 ld_base_cl74_fec_sup = ((an_ctxt->tx_pages.base_page.page_2 >> AN_BASE_CL74_ABILITY_SUP_OFFSET) & 3699 AN_BASE_CL74_ABILITY_SUP_MASK); 3700 3701 if ((ld_cl91_req || rd_cl91_req) && 3702 (ld_cl91_sup && rd_cl91_sup)) { 3703 cl91_fec = 1; 3704 } else if ((ld_cl74_req || rd_cl74_req) && 3705 (ld_cl74_sup && rd_cl74_sup)) { 3706 cl74_fec = 1; 3707 } else if ((rd_base_cl74_fec_req || ld_base_cl74_fec_req) && 3708 (rd_base_cl74_fec_sup && ld_base_cl74_fec_sup)) { 3709 cl74_fec =1; 3710 } 3711 3712 } 3713 3714 } 3715 } 3716 3717 if (is_krs) { 3718 /* For 25GBASE-KR-S and 25GBASE-CR-S PHYs if either PHY requests RS-FEC or BASE-R FEC then 3719 * BASE-R operation is enabled. This is because 25GBASE-KR-S and 25GBASE-CR-S PHYs do not support 3720 * RS-FEC operation 3721 */ 3722 if (cl91_fec) { 3723 cl74_25gkrs_fec = 1; 3724 } 3725 cl91_fec = 0; 3726 } 3727 3728 if (cl91_fec) { 3729 /* enable cl91 FEC */ 3730 fec_type = TEFMOD_CL91; 3731 } else if (cl74_fec || cl74_25gkrs_fec) { 3732 /* enable cl74 FEC */ 3733 fec_type = TEFMOD_CL74; 3734 } else { 3735 /* NO FEC enable */ 3736 fec_type = 0x0; 3737 } 3738 3739 if (fec_type) { 3740 PHYMOD_IF_ERR_RETURN 3741 (tefmod_FEC_control(&phy->access, fec_type, 1, 0)); 3742 /* HW AN logic does not drive the FEC control in SW AN mode 3743 * Need to override fec control 3744 */ 3745 PHYMOD_IF_ERR_RETURN 3746 (tefmod_sw_an_fec_override(&phy->access, fec_type, 1)); 3747 } 3748 /* Program the resolved speed Id to speed control */ 3749 PHYMOD_IF_ERR_RETURN 3750 (tefmod_set_speed_id(&phy->access, hcd_speed)); 3751 3752 return PHYMOD_E_NONE; 3753 } 3754 3755 static int _is_send_ack(phymod_sw_an_ctxt_t *an_ctxt) 3756 { 3757 3758 phymod_an_page_t *tx_page = 0; 3759 phymod_an_page_t *rx_page = 0; 3760 int send_ack = 0; 3761 int is_valid_tx_page =1, is_valid_rx_page = 1; 3762 3763 3764 3765 /** 3766 * check the current Tx page and Current Rx page and if the NP bit is set then send the ack 3767 */ 3768 switch (an_ctxt->tx_pages_cnt) { 3769 case TEFMOD_AN_PAGE_ID_BASE_PAGE: 3770 /* check the base page NP bit */ 3771 tx_page = &an_ctxt->tx_pages.base_page; 3772 break; 3773 case TEFMOD_AN_PAGE_ID_MSG_PAGE: 3774 /* check the message page NP bit */ 3775 tx_page = &an_ctxt->tx_pages.msg_page; 3776 break; 3777 case TEFMOD_AN_PAGE_ID_UP_PAGE: 3778 /* check the UF page NP bit */ 3779 tx_page = &an_ctxt->tx_pages.ufmt_page; 3780 break; 3781 default: 3782 tx_page = &an_ctxt->tx_pages.null_page; 3783 is_valid_tx_page = 0; 3784 break; 3785 } 3786 3787 switch (an_ctxt->rx_pages_cnt) { 3788 case TEFMOD_AN_PAGE_ID_NONE: 3789 /* No page has been rcvd yet */ 3790 is_valid_rx_page = 0; 3791 break; 3792 case TEFMOD_AN_PAGE_ID_BASE_PAGE: 3793 /* Rcvd base page NP bit */ 3794 rx_page = &an_ctxt->rx_pages.base_page; 3795 break; 3796 case TEFMOD_AN_PAGE_ID_MSG_PAGE: 3797 /* Rcvd msg page NP bit */ 3798 rx_page = &an_ctxt->rx_pages.msg_page; 3799 break; 3800 case TEFMOD_AN_PAGE_ID_UP_PAGE: 3801 /* Rcvd ufmt page NP bit */ 3802 rx_page = &an_ctxt->rx_pages.ufmt_page; 3803 break; 3804 default: 3805 /* check the cahed page at null page location*/ 3806 rx_page = &an_ctxt->rx_pages.null_page; 3807 break; 3808 } 3809 3810 if ( is_valid_tx_page && tx_page->page_0) { 3811 if ((tx_page->page_0 >> AN_BASE0_PAGE_NP_OFFSET) & 0x1) { 3812 send_ack = 1; 3813 } 3814 } 3815 if (is_valid_rx_page && rx_page->page_0) { 3816 if ((rx_page->page_0 >> AN_BASE0_PAGE_NP_OFFSET) & 0x1) { 3817 send_ack = 1; 3818 } 3819 } 3820 3821 return send_ack; 3822 } 3823 3824 int 3825 tscf_phy_sw_an_control_status_get(const phymod_phy_access_t* phy, phymod_sw_an_ctrl_status_t* an_ctrl_status) 3826 { 3827 uint32_t model = 0; 3828 3829 3830 PHYMOD_IF_ERR_RETURN 3831 (tefmod_serdes_model_get(&phy->access, &model)); 3832 3833 if (model != TSCF_GEN2_MODEL) { 3834 return PHYMOD_E_UNAVAIL; 3835 } 3836 3837 PHYMOD_MEMSET(an_ctrl_status, 0, sizeof(phymod_sw_an_ctrl_status_t)); 3838 3839 PHYMOD_IF_ERR_RETURN 3840 (tefmod_sw_an_ctl_sts_get(&phy->access, an_ctrl_status)); 3841 3842 return PHYMOD_E_NONE; 3843 } 3844 3845 int 3846 tscf_phy_sw_an_base_page_exchange_handler(const phymod_phy_access_t* phy, phymod_sw_an_ctxt_t* an_ctxt) 3847 { 3848 phymod_phy_access_t phy_copy; 3849 int start_lane, num_lane; 3850 uint32_t model = 0; 3851 3852 3853 PHYMOD_IF_ERR_RETURN 3854 (tefmod_serdes_model_get(&phy->access, &model)); 3855 3856 if (model != TSCF_GEN2_MODEL) { 3857 return PHYMOD_E_UNAVAIL; 3858 } 3859 3860 PHYMOD_IF_ERR_RETURN 3861 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3862 3863 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3864 phy_copy.access.lane_mask = 0x1 << start_lane; 3865 3866 PHYMOD_IF_ERR_RETURN 3867 (tefmod_setup_for_sw_an(&phy_copy.access, num_lane)); 3868 PHYMOD_IF_ERR_RETURN 3869 (tefmod_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.base_page, 1)); 3870 an_ctxt->tx_pages_cnt++; 3871 3872 PHYMOD_IF_ERR_RETURN 3873 (_tscf_sw_an_pmd_lane_cfg_set((phymod_phy_access_t*)phy, 1)); 3874 PHYMOD_USLEEP(1); 3875 PHYMOD_IF_ERR_RETURN 3876 (tefmod_sw_an_control(&phy_copy.access, 1)); 3877 3878 return PHYMOD_E_NONE; 3879 3880 } 3881 int 3882 tscf_phy_sw_an_lp_page_rdy_handler(const phymod_phy_access_t* phy, phymod_sw_an_ctxt_t* an_ctxt) 3883 { 3884 phymod_phy_access_t phy_copy; 3885 int start_lane, num_lane; 3886 uint32_t model = 0; 3887 3888 3889 PHYMOD_IF_ERR_RETURN 3890 (tefmod_serdes_model_get(&phy->access, &model)); 3891 3892 if (model != TSCF_GEN2_MODEL) { 3893 return PHYMOD_E_UNAVAIL; 3894 } 3895 3896 PHYMOD_IF_ERR_RETURN 3897 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3898 3899 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3900 phy_copy.access.lane_mask = 0x1 << start_lane; 3901 /* 1. Incerement the Rx page count 3902 * 2. read the lp page and cache it in the rx page buffer 3903 * 3. if the current tx page NP bit is 1 or rcvd page NP bit is 1 3904 * send the ack 3905 * 4. else 3906 * a. parse the received pages 3907 * b. resolve speed 3908 * c. program the speed control based on resolved speed 3909 * d. set the ack 3910 */ 3911 3912 an_ctxt->rx_pages_cnt++; 3913 switch(an_ctxt->rx_pages_cnt) { 3914 case TEFMOD_AN_PAGE_ID_BASE_PAGE: 3915 /* recevied LP base page */ 3916 PHYMOD_IF_ERR_RETURN 3917 (tefmod_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.base_page)); 3918 break; 3919 case TEFMOD_AN_PAGE_ID_MSG_PAGE: 3920 /* rcvd LP message page */ 3921 PHYMOD_IF_ERR_RETURN 3922 (tefmod_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.msg_page)); 3923 break; 3924 case TEFMOD_AN_PAGE_ID_UP_PAGE: 3925 /* rcvd LP UF page */ 3926 PHYMOD_IF_ERR_RETURN 3927 (tefmod_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.ufmt_page)); 3928 break; 3929 default: 3930 /* we are only interested in first 3 pages rest of the pages won't be parsed 3931 * use the null page entry as a scratch buffer to look for NP bit 3932 */ 3933 PHYMOD_IF_ERR_RETURN 3934 (tefmod_sw_an_lp_page_read(&phy_copy.access, &an_ctxt->rx_pages.null_page)); 3935 break; 3936 } 3937 3938 if (_is_send_ack(an_ctxt)) { 3939 /* Load the next page while the state IEEE SM is in ack det state */ 3940 switch(an_ctxt->tx_pages_cnt) { 3941 case 0: 3942 /* Invalid. Atleast base page shoould have beem txed before 3943 * receving ld_page event 3944 */ 3945 break; 3946 case TEFMOD_AN_PAGE_ID_BASE_PAGE: 3947 /* Tx Message Page */ 3948 PHYMOD_IF_ERR_RETURN 3949 (tefmod_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.msg_page, 0)); 3950 an_ctxt->tx_pages_cnt++; 3951 break; 3952 case TEFMOD_AN_PAGE_ID_MSG_PAGE: 3953 /* Tx unformatted Page for BAM abilities */ 3954 PHYMOD_IF_ERR_RETURN 3955 (tefmod_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.ufmt_page, 0)); 3956 an_ctxt->tx_pages_cnt++; 3957 break; 3958 default: 3959 /* request for page when no more valid pages are available to Tx 3960 * Tx NULL pages 3961 */ 3962 PHYMOD_IF_ERR_RETURN 3963 (tefmod_sw_an_ld_page_load(&phy_copy.access, &an_ctxt->tx_pages.null_page, 0)); 3964 an_ctxt->tx_pages_cnt++; 3965 break; 3966 } 3967 3968 } else { 3969 PHYMOD_IF_ERR_RETURN 3970 (_resolve_speed(phy, an_ctxt)); 3971 } 3972 PHYMOD_IF_ERR_RETURN 3973 (tefmod_sw_an_set_ack(&phy_copy.access)); 3974 3975 return PHYMOD_E_NONE; 3976 } 3977 3978 3979 int 3980 tscf_phy_sw_autoneg_enable(const phymod_phy_access_t* phy, int enable) 3981 { 3982 phymod_phy_access_t phy_copy; 3983 int start_lane, num_lane; 3984 uint32_t model = 0; 3985 3986 3987 PHYMOD_IF_ERR_RETURN 3988 (tefmod_serdes_model_get(&phy->access, &model)); 3989 3990 if (model != TSCF_GEN2_MODEL) { 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 4001 PHYMOD_IF_ERR_RETURN 4002 (_tscf_sw_an_pmd_lane_cfg_set((phymod_phy_access_t*)phy, enable)); 4003 PHYMOD_USLEEP(10); 4004 4005 PHYMOD_IF_ERR_RETURN 4006 (tefmod_sw_an_control(&phy_copy.access, enable)); 4007 4008 /* When disable SW AN, remove AN FEC override */ 4009 if (!enable) { 4010 PHYMOD_IF_ERR_RETURN 4011 (tefmod_sw_an_fec_override(&phy->access, 0, 0)); 4012 } 4013 return PHYMOD_E_NONE; 4014 4015 } 4016 4017 int tscf_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* value) 4018 { 4019 uint32_t local_rx_signal_det; 4020 int start_lane, num_lane, i; 4021 4022 *value = 1; 4023 4024 PHYMOD_IF_ERR_RETURN 4025 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 4026 4027 for (i = 0; i < num_lane; i++) { 4028 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 4029 continue; 4030 } 4031 PHYMOD_IF_ERR_RETURN 4032 (falcon_tsc_signal_detect(&phy->access, &local_rx_signal_det)); 4033 *value = *value & local_rx_signal_det; 4034 } 4035 4036 return PHYMOD_E_NONE; 4037 } 4038 4039 int tscf_phy_rx_ppm_get(const phymod_phy_access_t* phy, int16_t* rx_ppm) 4040 { 4041 int start_lane, num_lane; 4042 phymod_phy_access_t pm_phy_copy; 4043 4044 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 4045 4046 PHYMOD_IF_ERR_RETURN 4047 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 4048 4049 pm_phy_copy.access.lane_mask = 1 << start_lane; 4050 PHYMOD_IF_ERR_RETURN 4051 (falcon_tsc_rx_ppm(&pm_phy_copy.access, rx_ppm)); 4052 4053 return PHYMOD_E_NONE; 4054 } 4055 4056 int tscf_phy_synce_clk_ctrl_set(const phymod_phy_access_t* phy, 4057 phymod_synce_clk_ctrl_t cfg) 4058 { 4059 phymod_phy_access_t phy_copy; 4060 int start_lane, num_lane; 4061 4062 PHYMOD_IF_ERR_RETURN 4063 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 4064 4065 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 4066 phy_copy.access.lane_mask = 0x1 << start_lane; 4067 4068 PHYMOD_IF_ERR_RETURN 4069 (tefmod_synce_stg0_mode_set(&phy_copy.access, cfg.stg0_mode)); 4070 4071 PHYMOD_IF_ERR_RETURN 4072 (tefmod_synce_stg1_mode_set(&phy_copy.access, cfg.stg1_mode)); 4073 4074 PHYMOD_IF_ERR_RETURN 4075 (tefmod_synce_clk_ctrl_set(&phy_copy.access, cfg.sdm_val)); 4076 4077 return PHYMOD_E_NONE; 4078 } 4079 4080 int tscf_phy_synce_clk_ctrl_get(const phymod_phy_access_t* phy, 4081 phymod_synce_clk_ctrl_t *cfg) 4082 { 4083 PHYMOD_IF_ERR_RETURN 4084 (tefmod_synce_stg0_mode_get(&phy->access, &(cfg->stg0_mode))); 4085 4086 PHYMOD_IF_ERR_RETURN 4087 (tefmod_synce_stg1_mode_get(&phy->access, &(cfg->stg1_mode))); 4088 4089 PHYMOD_IF_ERR_RETURN 4090 (tefmod_synce_clk_ctrl_get(&phy->access, &(cfg->sdm_val))); 4091 4092 return PHYMOD_E_NONE; 4093 }