tscf_gen3.c (121858B)
1 /* 2 * 3 * 4 * 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 6 * 7 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 8 */ 9 10 #include <phymod/phymod.h> 11 #include <phymod/phymod_system.h> 12 #include <phymod/phymod_util.h> 13 #include <phymod/phymod_dispatch.h> 14 #include <phymod/chip/falcon_dpll.h> 15 #include <phymod/chip/tscf_gen3.h> 16 #include <phymod/chip/bcmi_tscf_gen3_xgxs_defs.h> 17 #include "tscf_gen3/tier1/tefmod_gen3.h" 18 #include "tscf_gen3/tier1/tefmod_gen3_enum_defines.h" 19 #include "tscf_gen3/tier1/tefmod_gen3_sc_lkup_table.h" 20 #include "falcon_dpll/tier1/falcon2_monterey_interface.h" 21 #include "falcon_dpll/tier1/falcon2_monterey_debug_functions.h" 22 #include "falcon_dpll/tier1/falcon_api_uc_common.h" 23 #include "falcon_dpll/tier1/falcon_dpll_cfg_seq.h" 24 25 26 #define TSCF_GEN3_ID0 0x600d 27 #define TSCF_GEN3_ID1 0x8770 28 #define TSC4F_GEN3_MODEL 0x24 29 #define TSCF_GEN3_TECH_PROC 0x3 30 #define TSCF_GEN3_NOF_LANES_IN_CORE 4 31 #define TSCF_GEN3_LANE_SWAP_LANE_MASK 3 32 #define TSCF_GEN3_NOF_DFES 6 33 #define TSCF_GEN3_PHY_ALL_LANES 0xf 34 35 #define TSCF_GEN3_PMD_CRC_UCODE_VERIFY 1 36 37 /* uController's firmware */ 38 extern unsigned char falcon_dpll_ucode[]; 39 extern unsigned short falcon_dpll_ucode_ver; 40 extern unsigned short falcon_dpll_ucode_crc; 41 extern unsigned short falcon_dpll_ucode_len; 42 43 44 #define TSCF_GEN3_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 45 do{\ 46 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\ 47 (_phy_access)->type = (_core_access)->type; \ 48 (_phy_access)->port_loc = (_core_access)->port_loc; \ 49 (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \ 50 (_phy_access)->access.lane_mask = TSCF_GEN3_PHY_ALL_LANES; \ 51 }while(0) 52 53 STATIC 54 int _tscf_gen3_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 55 { 56 struct falcon2_monterey_uc_lane_config_st serdes_firmware_config; 57 phymod_phy_access_t phy_copy; 58 int start_lane, num_lane, i; 59 uint32_t is_warm_boot; 60 61 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 62 PHYMOD_IF_ERR_RETURN 63 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 64 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 65 66 for (i = 0; i < num_lane; i++) { 67 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 68 continue; 69 } 70 phy_copy.access.lane_mask = 1 << (start_lane + i); 71 serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 72 serdes_firmware_config.field.an_enabled = fw_config.AnEnabled; 73 serdes_firmware_config.field.dfe_on = fw_config.DfeOn; 74 serdes_firmware_config.field.dfe_lp_mode = fw_config.LpDfeOn; 75 serdes_firmware_config.field.force_brdfe_on = fw_config.ForceBrDfe; 76 serdes_firmware_config.field.media_type = fw_config.MediaType; 77 serdes_firmware_config.field.unreliable_los = fw_config.UnreliableLos; 78 serdes_firmware_config.field.scrambling_dis = fw_config.ScramblingDisable; 79 serdes_firmware_config.field.cl72_auto_polarity_en = fw_config.Cl72AutoPolEn; 80 serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO; 81 /*serdes_firmware_config.field.en_short_chn_osx1 = fw_config.short_chn;*/ 82 83 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy_copy.access, &is_warm_boot)); 84 85 if(!is_warm_boot) { 86 PHYMOD_IF_ERR_RETURN (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 0)); 87 PHYMOD_IF_ERR_RETURN(falcon2_monterey_set_uc_lane_cfg(&phy_copy.access, serdes_firmware_config)); 88 PHYMOD_IF_ERR_RETURN (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 1)); 89 90 } 91 } 92 93 return PHYMOD_E_NONE; 94 } 95 96 int tscf_gen3_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 97 { 98 int ioerr = 0; 99 const phymod_access_t *pm_acc = &core->access; 100 PHYID2r_t id2; 101 PHYID3r_t id3; 102 MAIN0_SERDESIDr_t serdes_id; 103 uint32_t model; 104 105 *is_identified = 0; 106 107 if (core_id == 0){ 108 ioerr += READ_PHYID2r(pm_acc, &id2); 109 ioerr += READ_PHYID3r(pm_acc, &id3); 110 } else { 111 PHYID2r_SET(id2, ((core_id >> 16) & 0xffff)); 112 PHYID3r_SET(id3, core_id & 0xffff); 113 } 114 115 if (PHYID2r_REGID1f_GET(id2) == TSCF_GEN3_ID0 && 116 (PHYID3r_REGID2f_GET(id3) == TSCF_GEN3_ID1)) { 117 /* PHY IDs match - now check SERDES ID model number */ 118 ioerr += READ_MAIN0_SERDESIDr(pm_acc, &serdes_id); 119 model = MAIN0_SERDESIDr_MODEL_NUMBERf_GET(serdes_id); 120 if (model == TSC4F_GEN3_MODEL) { 121 if (MAIN0_SERDESIDr_TECH_PROCf_GET(serdes_id) == TSCF_GEN3_TECH_PROC) { 122 *is_identified = 1; 123 } 124 } 125 } 126 127 return ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE; 128 } 129 130 int tscf_gen3_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info) 131 { 132 uint32_t serdes_id = TSC4F_GEN3_MODEL; 133 char core_name[15] = "TscfGen3"; 134 PHYID2r_t id2; 135 PHYID3r_t id3; 136 const phymod_access_t *pm_acc = &core->access; 137 138 PHYMOD_IF_ERR_RETURN 139 (tefmod_gen3_revid_read(&core->access, &serdes_id)); 140 PHYMOD_IF_ERR_RETURN 141 (phymod_core_name_get(core, serdes_id, core_name, info)); 142 info->serdes_id = serdes_id; 143 info->core_version = phymodCoreVersionTscfGen3; 144 145 PHYMOD_IF_ERR_RETURN(READ_PHYID2r(pm_acc, &id2)); 146 PHYMOD_IF_ERR_RETURN(READ_PHYID3r(pm_acc, &id3)); 147 148 info->phy_id0 = (uint16_t) id2.v[0]; 149 info->phy_id1 = (uint16_t) id3.v[0]; 150 151 return PHYMOD_E_NONE; 152 } 153 154 /* pcs_or_pmd = 1 => do the PCS lane swap 155 pcs_or_pmd = 0 => do the PMD lane swap */ 156 static int _tscf_gen3_core_lane_map_part_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map, int pcs_or_pmd) 157 { 158 uint32_t lane, pcs_tx_swap = 0, pcs_rx_swap = 0; 159 uint8_t pmd_tx_addr[4], pmd_rx_addr[4]; 160 161 if (lane_map->num_of_lanes != TSCF_GEN3_NOF_LANES_IN_CORE){ 162 return PHYMOD_E_CONFIG; 163 } 164 for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE; lane++){ 165 if ((lane_map->lane_map_tx[lane] >= TSCF_GEN3_NOF_LANES_IN_CORE)|| 166 (lane_map->lane_map_rx[lane] >= TSCF_GEN3_NOF_LANES_IN_CORE)){ 167 return PHYMOD_E_CONFIG; 168 } 169 /* Encode each lane as four bits */ 170 pcs_tx_swap += lane_map->lane_map_tx[lane]<<(lane*4); 171 pcs_rx_swap += lane_map->lane_map_rx[lane]<<(lane*4); 172 } 173 /* PMD lane addr is based on PCS logical to physical mapping */ 174 for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE; lane++){ 175 pmd_tx_addr[((pcs_tx_swap >> (lane*4)) & 0xf)] = lane; 176 pmd_rx_addr[((pcs_rx_swap >> (lane*4)) & 0xf)] = lane; 177 } 178 179 if(pcs_or_pmd) { 180 PHYMOD_IF_ERR_RETURN 181 (tefmod_gen3_pcs_tx_lane_swap(&core->access, pcs_tx_swap)); 182 PHYMOD_IF_ERR_RETURN 183 (tefmod_gen3_pcs_rx_lane_swap(&core->access, pcs_rx_swap)); 184 } else { 185 PHYMOD_IF_ERR_RETURN 186 (falcon2_monterey_map_lanes(&core->access, TSCF_GEN3_NOF_LANES_IN_CORE, pmd_tx_addr, pmd_rx_addr)); 187 } 188 189 return PHYMOD_E_NONE; 190 } 191 192 int tscf_gen3_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 193 { 194 PHYMOD_IF_ERR_RETURN 195 (_tscf_gen3_core_lane_map_part_set(core, lane_map, 1)); 196 PHYMOD_IF_ERR_RETURN 197 (_tscf_gen3_core_lane_map_part_set(core, lane_map, 0)); 198 199 return PHYMOD_E_NONE; 200 } 201 202 int tscf_gen3_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 203 { 204 uint32_t pcs_tx_swap = 0 , pcs_rx_swap = 0, lane; 205 206 PHYMOD_IF_ERR_RETURN(tefmod_gen3_pcs_tx_lane_swap_get(&core->access, &pcs_tx_swap)); 207 PHYMOD_IF_ERR_RETURN(tefmod_gen3_pcs_rx_lane_swap_get(&core->access, &pcs_rx_swap)); 208 209 for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE ; lane++){ 210 /* Decode each lane from four bits */ 211 lane_map->lane_map_tx[lane] = (pcs_tx_swap>>(lane*4)) & TSCF_GEN3_LANE_SWAP_LANE_MASK; 212 lane_map->lane_map_rx[lane] = (pcs_rx_swap>>(lane*4)) & TSCF_GEN3_LANE_SWAP_LANE_MASK; 213 } 214 lane_map->num_of_lanes = TSCF_GEN3_NOF_LANES_IN_CORE; 215 216 return PHYMOD_E_NONE; 217 } 218 219 220 int tscf_gen3_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 221 { 222 223 return PHYMOD_E_UNAVAIL; 224 225 } 226 227 int tscf_gen3_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 228 { 229 230 return PHYMOD_E_UNAVAIL; 231 232 } 233 234 int tscf_gen3_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 235 { 236 237 return PHYMOD_E_NONE; 238 239 } 240 241 STATIC 242 int _tscf_gen3_core_firmware_load(const phymod_core_access_t* core, phymod_firmware_load_method_t load_method, phymod_firmware_loader_f fw_loader) 243 { 244 /* coverity[assignment:FALSE] */ 245 load_method = phymodFirmwareLoadMethodInternal; 246 /* coverity[const:FALSE] */ 247 /* coverity[dead_error_condition:FALSE] */ 248 switch(load_method){ 249 case phymodFirmwareLoadMethodInternal: 250 PHYMOD_IF_ERR_RETURN(falcon2_monterey_ucode_mdio_load(&core->access, falcon_dpll_ucode, falcon_dpll_ucode_len)); 251 break; 252 case phymodFirmwareLoadMethodExternal: 253 PHYMOD_NULL_CHECK(fw_loader); 254 PHYMOD_IF_ERR_RETURN(falcon2_monterey_ucode_init(&core->access)); 255 PHYMOD_IF_ERR_RETURN 256 (falcon2_monterey_pram_firmware_enable(&core->access, 1, 0)); 257 PHYMOD_IF_ERR_RETURN(fw_loader(core, falcon_dpll_ucode_len, falcon_dpll_ucode)); 258 PHYMOD_IF_ERR_RETURN 259 (falcon2_monterey_pram_firmware_enable(&core->access, 0, 0)); 260 break; 261 /* coverity[DEADCODE:FALSE] */ 262 case phymodFirmwareLoadMethodNone: 263 break; 264 /* coverity[dead_event_begin:FALSE] */ 265 default: 266 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), load_method)); 267 } 268 269 return PHYMOD_E_NONE; 270 } 271 272 int tscf_gen3_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config) 273 { 274 struct falcon2_monterey_uc_core_config_st serdes_firmware_core_config; 275 276 PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config)); 277 serdes_firmware_core_config.field.core_cfg_from_pcs = fw_core_config.CoreConfigFromPCS; 278 serdes_firmware_core_config.field.vco_rate = fw_core_config.VcoRate; 279 serdes_firmware_core_config.field.disable_write_pll_iqp = fw_core_config.disable_write_pll_iqp; 280 PHYMOD_IF_ERR_RETURN(falcon2_monterey_set_uc_core_config(&phy->access, serdes_firmware_core_config)); 281 282 return PHYMOD_E_NONE; 283 } 284 285 int tscf_gen3_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config) 286 { 287 struct falcon2_monterey_uc_core_config_st serdes_firmware_core_config; 288 289 PHYMOD_MEMSET(fw_core_config, 0, sizeof(*fw_core_config)); 290 PHYMOD_IF_ERR_RETURN(falcon2_monterey_get_uc_core_config(&phy->access, &serdes_firmware_core_config)); 291 fw_core_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs; 292 fw_core_config->VcoRate = serdes_firmware_core_config.field.vco_rate; 293 fw_core_config->disable_write_pll_iqp = serdes_firmware_core_config.field.disable_write_pll_iqp; 294 295 return PHYMOD_E_NONE; 296 } 297 298 int tscf_gen3_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config) 299 { 300 phymod_phy_access_t phy_copy; 301 int start_lane, num_lane, i; 302 303 PHYMOD_IF_ERR_RETURN 304 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 305 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 306 307 /* Hold the per lane soft reset bit */ 308 for (i = 0; i < num_lane; i++) { 309 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 310 continue; 311 } 312 phy_copy.access.lane_mask = 1 << (start_lane + i); 313 PHYMOD_IF_ERR_RETURN 314 (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 0)); 315 } 316 317 PHYMOD_IF_ERR_RETURN 318 (_tscf_gen3_phy_firmware_lane_config_set(phy, fw_lane_config)); 319 320 /* Release the per lane soft reset bit */ 321 for (i = 0; i < num_lane; i++) { 322 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 323 continue; 324 } 325 phy_copy.access.lane_mask = 1 << (start_lane + i); 326 PHYMOD_IF_ERR_RETURN 327 (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 1)); 328 } 329 330 /* Toggle the pcs data path reset */ 331 PHYMOD_IF_ERR_RETURN 332 (tefmod_gen3_trigger_speed_change(&phy->access)); 333 334 return PHYMOD_E_NONE; 335 } 336 337 int tscf_gen3_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config) 338 { 339 struct falcon2_monterey_uc_lane_config_st serdes_firmware_config; 340 phymod_phy_access_t phy_copy; 341 int start_lane, num_lane; 342 343 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 344 PHYMOD_IF_ERR_RETURN 345 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 346 347 phy_copy.access.lane_mask = 1 << start_lane ; 348 349 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 350 PHYMOD_IF_ERR_RETURN(falcon2_monterey_get_uc_lane_cfg(&phy_copy.access, &serdes_firmware_config)); 351 PHYMOD_MEMSET(fw_lane_config, 0, sizeof(*fw_lane_config)); 352 fw_lane_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs; 353 fw_lane_config->AnEnabled = serdes_firmware_config.field.an_enabled; 354 fw_lane_config->DfeOn = serdes_firmware_config.field.dfe_on; 355 fw_lane_config->LpDfeOn = serdes_firmware_config.field.dfe_lp_mode; 356 fw_lane_config->ForceBrDfe = serdes_firmware_config.field.force_brdfe_on; 357 fw_lane_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis; 358 fw_lane_config->UnreliableLos = serdes_firmware_config.field.unreliable_los; 359 fw_lane_config->MediaType = serdes_firmware_config.field.media_type; 360 fw_lane_config->Cl72AutoPolEn = serdes_firmware_config.field.cl72_auto_polarity_en; 361 fw_lane_config->Cl72RestTO = serdes_firmware_config.field.cl72_restart_timeout_en; 362 363 return PHYMOD_E_NONE; 364 } 365 366 int tscf_gen3_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 367 { 368 369 return PHYMOD_E_UNAVAIL; 370 371 } 372 373 int tscf_gen3_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout) 374 { 375 376 return PHYMOD_E_NONE; 377 378 } 379 380 int tscf_gen3_phy_rx_restart(const phymod_phy_access_t* phy) 381 { 382 383 PHYMOD_IF_ERR_RETURN(falcon2_monterey_rx_restart(&phy->access, 1)); 384 385 return PHYMOD_E_NONE; 386 } 387 388 int tscf_gen3_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 389 { 390 PHYMOD_IF_ERR_RETURN 391 (tefmod_gen3_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity)); 392 393 return PHYMOD_E_NONE; 394 } 395 396 int tscf_gen3_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 397 { 398 PHYMOD_IF_ERR_RETURN 399 (tefmod_gen3_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity)); 400 401 return PHYMOD_E_NONE; 402 } 403 404 int tscf_gen3_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 405 { 406 PHYMOD_IF_ERR_RETURN 407 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre)); 408 PHYMOD_IF_ERR_RETURN 409 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main)); 410 PHYMOD_IF_ERR_RETURN 411 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post)); 412 PHYMOD_IF_ERR_RETURN 413 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2)); 414 PHYMOD_IF_ERR_RETURN 415 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3)); 416 PHYMOD_IF_ERR_RETURN 417 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_AMP, (int8_t)tx->amp)); 418 if((tx->drivermode != -1) && 419 (phy->device_op_mode & PHYMOD_INTF_CONFIG_TX_FIR_DRIVERMODE_ENABLE)) { 420 PHYMOD_IF_ERR_RETURN 421 (falcon2_monterey_write_tx_afe(&phy->access, TX_AFE_DRIVERMODE, (int8_t)tx->drivermode)); 422 } 423 424 return PHYMOD_E_NONE; 425 426 } 427 428 int tscf_gen3_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 429 { 430 int8_t value = 0; 431 432 PHYMOD_IF_ERR_RETURN 433 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_PRE, &value)); 434 tx->pre = value; 435 PHYMOD_IF_ERR_RETURN 436 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_MAIN, &value)); 437 tx->main = value; 438 PHYMOD_IF_ERR_RETURN 439 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_POST1, &value)); 440 tx->post = value; 441 PHYMOD_IF_ERR_RETURN 442 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_POST2, &value)); 443 tx->post2 = value; 444 PHYMOD_IF_ERR_RETURN 445 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_POST3, &value)); 446 tx->post3 = value; 447 PHYMOD_IF_ERR_RETURN 448 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_AMP, &value)); 449 tx->amp = value; 450 PHYMOD_IF_ERR_RETURN 451 (falcon2_monterey_read_tx_afe(&phy->access, TX_AFE_DRIVERMODE, &value)); 452 tx->drivermode = value; 453 454 return PHYMOD_E_NONE; 455 } 456 457 458 int tscf_gen3_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 459 { 460 PHYMOD_IF_ERR_RETURN 461 (falcon2_monterey_tx_pi_freq_override(&phy->access, 462 tx_override->phase_interpolator.enable, 463 tx_override->phase_interpolator.value)); 464 465 return PHYMOD_E_NONE; 466 467 } 468 469 int tscf_gen3_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 470 { 471 int16_t pi_value; 472 473 PHYMOD_IF_ERR_RETURN 474 (falcon2_monterey_tx_pi_control_get(&phy->access, &pi_value)); 475 tx_override->phase_interpolator.value = (int32_t) pi_value; 476 477 return PHYMOD_E_NONE; 478 479 } 480 481 int tscf_gen3_phy_txpi_config_set(const phymod_phy_access_t* phy, const phymod_txpi_config_t* config) 482 { 483 phymod_phy_access_t phy_copy; 484 485 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 486 487 PHYMOD_IF_ERR_RETURN 488 (falcon2_monterey_tx_pi_enable_set(&phy_copy.access, config->enable)); 489 490 PHYMOD_IF_ERR_RETURN 491 (falcon2_monterey_tx_pi_ext_pd_select_set(&phy_copy.access, config->mode == PHYMOD_TXPI_EXT_PD_MODE ? 1 : 0)); 492 493 return PHYMOD_E_NONE; 494 } 495 496 int tscf_gen3_phy_txpi_config_get(const phymod_phy_access_t* phy, phymod_txpi_config_t* config) 497 { 498 phymod_phy_access_t phy_copy; 499 uint32_t ext_pd; 500 501 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 502 503 PHYMOD_IF_ERR_RETURN 504 (falcon2_monterey_tx_pi_enable_get(&phy_copy.access, &config->enable)); 505 506 PHYMOD_IF_ERR_RETURN 507 (falcon2_monterey_tx_pi_ext_pd_select_get(&phy_copy.access, &ext_pd)); 508 509 config->mode = ext_pd ? PHYMOD_TXPI_EXT_PD_MODE : PHYMOD_TXPI_NORMAL_MODE; 510 511 return PHYMOD_E_NONE; 512 } 513 514 int tscf_gen3_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 515 { 516 uint32_t i; 517 uint8_t uc_lane_stopped; 518 phymod_phy_access_t pm_phy_copy; 519 int start_lane, num_lane, k; 520 521 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 522 /* Program the tx fir taps and driver current based on the input */ 523 PHYMOD_IF_ERR_RETURN 524 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 525 526 /* Check params */ 527 if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF_GEN3_NOF_DFES)){ 528 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps)); 529 } 530 531 for (k = 0; k < num_lane; k++) { 532 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + k)) { 533 continue; 534 } 535 pm_phy_copy.access.lane_mask = 1 << (start_lane + k); 536 537 /* Check if Micro is stopped on a lane */ 538 PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_uc_lane_status(&pm_phy_copy.access, &uc_lane_stopped)); 539 if (!uc_lane_stopped) { 540 PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_rx_adaptation(&pm_phy_copy.access, 1)); 541 } 542 /* vga set */ 543 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_VGA, rx->vga.value)); 544 /* dfe set */ 545 for (i = 0 ; i < rx->num_of_dfe_taps ; i++){ 546 switch (i) { 547 case 0: 548 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE1, rx->dfe[i].value)); 549 break; 550 case 1: 551 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE2, rx->dfe[i].value)); 552 break; 553 case 2: 554 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE3, rx->dfe[i].value)); 555 break; 556 case 3: 557 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE4, rx->dfe[i].value)); 558 break; 559 case 4: 560 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE5, rx->dfe[i].value)); 561 break; 562 case 5: 563 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_DFE6, rx->dfe[i].value)); 564 break; 565 default: 566 return PHYMOD_E_PARAM; 567 } 568 } 569 570 /*peaking filter set*/ 571 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF, rx->peaking_filter.value)); 572 573 /* low freq peak filter */ 574 PHYMOD_IF_ERR_RETURN(falcon2_monterey_write_rx_afe(&pm_phy_copy.access, RX_AFE_PF2, (int8_t)rx->low_freq_peaking_filter.value)); 575 } 576 577 return PHYMOD_E_NONE; 578 } 579 580 int tscf_gen3_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 581 { 582 int8_t tmpData; 583 584 PHYMOD_IF_ERR_RETURN 585 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_VGA, &tmpData)); 586 rx->vga.value = tmpData; 587 PHYMOD_IF_ERR_RETURN 588 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE1, &tmpData)); 589 rx->dfe[0].value = tmpData; 590 PHYMOD_IF_ERR_RETURN 591 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE2, &tmpData)); 592 rx->dfe[1].value = tmpData; 593 PHYMOD_IF_ERR_RETURN 594 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE3, &tmpData)); 595 rx->dfe[2].value = tmpData; 596 PHYMOD_IF_ERR_RETURN 597 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE4, &tmpData)); 598 rx->dfe[3].value = tmpData; 599 PHYMOD_IF_ERR_RETURN 600 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE5, &tmpData)); 601 rx->dfe[4].value = tmpData; 602 PHYMOD_IF_ERR_RETURN 603 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_DFE6, &tmpData)); 604 rx->dfe[5].value = tmpData; 605 PHYMOD_IF_ERR_RETURN 606 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_PF, &tmpData)); 607 rx->peaking_filter.value = tmpData; 608 PHYMOD_IF_ERR_RETURN 609 (falcon2_monterey_read_rx_afe(&phy->access, RX_AFE_PF2, &tmpData)); 610 rx->low_freq_peaking_filter.value = tmpData; 611 612 rx->num_of_dfe_taps = 6; 613 rx->dfe[0].enable = 1; 614 rx->dfe[1].enable = 1; 615 rx->dfe[2].enable = 1; 616 rx->dfe[3].enable = 1; 617 rx->dfe[4].enable = 1; 618 rx->dfe[5].enable = 1; 619 rx->vga.enable = 1; 620 rx->low_freq_peaking_filter.enable = 1; 621 rx->peaking_filter.enable = 1; 622 623 return PHYMOD_E_NONE; 624 } 625 626 627 int tscf_gen3_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 628 { 629 uint8_t uc_lane_stopped; 630 631 PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_uc_lane_status(&phy->access, &uc_lane_stopped)); 632 if (uc_lane_stopped) { 633 PHYMOD_IF_ERR_RETURN(falcon2_monterey_stop_rx_adaptation(&phy->access, 0)); 634 } 635 636 return PHYMOD_E_NONE; 637 } 638 639 int tscf_gen3_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 640 { 641 642 return PHYMOD_E_NONE; 643 644 } 645 646 int tscf_gen3_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 647 { 648 649 return PHYMOD_E_NONE; 650 651 } 652 653 654 int tscf_gen3_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 655 { 656 phymod_phy_access_t pm_phy_copy; 657 int start_lane, num_lane, i; 658 659 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 660 PHYMOD_IF_ERR_RETURN 661 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 662 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) { 663 for (i = 0; i < num_lane; i++) { 664 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 665 continue; 666 } 667 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 668 PHYMOD_IF_ERR_RETURN(tefmod_gen3_port_enable_set(&pm_phy_copy.access, 0)); 669 } 670 } 671 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) { 672 for (i = 0; i < num_lane; i++) { 673 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 674 continue; 675 } 676 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 677 PHYMOD_IF_ERR_RETURN(tefmod_gen3_port_enable_set(&pm_phy_copy.access, 1)); 678 PHYMOD_IF_ERR_RETURN(tefmod_gen3_power_control(&phy->access, 0, 0)); 679 } 680 } 681 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) { 682 /* Disable tx on the PMD side */ 683 PHYMOD_IF_ERR_RETURN(falcon2_monterey_tx_disable(&phy->access, 1)); 684 } 685 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) { 686 /* Enable tx on the PMD side */ 687 PHYMOD_IF_ERR_RETURN(falcon2_monterey_tx_disable(&phy->access, 0)); 688 } 689 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) { 690 /* Force PMD signal detect value */ 691 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&phy->access, 1)); 692 } 693 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) { 694 /* Remove PMD signal detect value */ 695 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&phy->access, 0)); 696 } 697 698 return PHYMOD_E_NONE; 699 } 700 701 int tscf_gen3_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 702 { 703 int enable; 704 uint32_t lb_enable; 705 phymod_phy_access_t pm_phy_copy; 706 int start_lane, num_lane; 707 708 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 709 PHYMOD_IF_ERR_RETURN 710 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 711 712 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 713 714 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_get(&pm_phy_copy.access, &enable)); 715 716 /* Check if PMD loopback is on */ 717 if (enable) { 718 PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 719 if (lb_enable) enable = 0; 720 } 721 722 power->rx = (enable == 1)? phymodPowerOff: phymodPowerOn; 723 /* Commented the following line. Because if in PMD loopback mode, we squelch the 724 xmit, and we should still see the correct port status */ 725 /* PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_get(&pm_phy_copy.access, &enable)); */ 726 power->tx = (enable == 1)? phymodPowerOff: phymodPowerOn; 727 728 729 return PHYMOD_E_NONE; 730 731 } 732 733 int tscf_gen3_phy_hg2_codec_control_set(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t hg2_codec) 734 { 735 tefmod_gen3_hg2_codec_t local_copy; 736 737 switch (hg2_codec) { 738 case phymodBcmHG2CodecOff: 739 local_copy = TEFMOD_HG2_CODEC_OFF; 740 break; 741 case phymodBcmHG2CodecOnWith8ByteIPG: 742 local_copy = TEFMOD_HG2_CODEC_ON_8BYTE_IPG; 743 break; 744 case phymodBcmHG2CodecOnWith9ByteIPG: 745 local_copy = TEFMOD_HG2_CODEC_ON_9BYTE_IPG; 746 break; 747 default: 748 local_copy = TEFMOD_HG2_CODEC_OFF; 749 break; 750 } 751 PHYMOD_IF_ERR_RETURN(tefmod_gen3_hg2_codec_set(&phy->access, local_copy)); 752 753 return PHYMOD_E_NONE; 754 } 755 756 int tscf_gen3_phy_hg2_codec_control_get(const phymod_phy_access_t* phy, phymod_phy_hg2_codec_t* hg2_codec) 757 { 758 tefmod_gen3_hg2_codec_t local_copy; 759 760 PHYMOD_IF_ERR_RETURN(tefmod_gen3_hg2_codec_get(&phy->access, &local_copy)); 761 762 switch (local_copy) { 763 case TEFMOD_HG2_CODEC_OFF: 764 *hg2_codec = phymodBcmHG2CodecOff; 765 break; 766 case TEFMOD_HG2_CODEC_ON_8BYTE_IPG: 767 *hg2_codec = phymodBcmHG2CodecOnWith8ByteIPG; 768 break; 769 case TEFMOD_HG2_CODEC_ON_9BYTE_IPG: 770 *hg2_codec = phymodBcmHG2CodecOnWith9ByteIPG; 771 break; 772 default: 773 *hg2_codec = phymodBcmHG2CodecOff; 774 break; 775 } 776 777 return PHYMOD_E_NONE; 778 } 779 780 int tscf_gen3_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 781 { 782 phymod_firmware_lane_config_t fw_lane_config; 783 784 PHYMOD_IF_ERR_RETURN (tscf_gen3_phy_firmware_lane_config_get(phy, &fw_lane_config)); 785 786 switch (tx_control) { 787 case phymodTxTrafficDisable: 788 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_TRAFFIC_DISABLE)); 789 break; 790 case phymodTxTrafficEnable: 791 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_TRAFFIC_ENABLE)); 792 break; 793 case phymodTxReset: 794 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_set(&phy->access, TEFMOD_TX_LANE_RESET)); 795 break; 796 case phymodTxSquelchOn: 797 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_set(&phy->access, 1)); 798 break; 799 case phymodTxSquelchOff: 800 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_set(&phy->access, 0)); 801 break; 802 case phymodTxElectricalIdleEnable: 803 if (fw_lane_config.LaneConfigFromPCS == 0) { 804 PHYMOD_IF_ERR_RETURN(falcon2_monterey_electrical_idle_set(&phy->access, 1)); 805 }else{ 806 return PHYMOD_E_UNAVAIL; 807 } 808 break; 809 case phymodTxElectricalIdleDisable: 810 if (fw_lane_config.LaneConfigFromPCS == 0) { 811 PHYMOD_IF_ERR_RETURN(falcon2_monterey_electrical_idle_set(&phy->access, 0)); 812 }else{ 813 return PHYMOD_E_UNAVAIL; 814 } 815 break; 816 default: 817 break; 818 } 819 820 return PHYMOD_E_NONE; 821 } 822 823 int tscf_gen3_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 824 { 825 int enable, reset, tx_lane; 826 uint32_t lb_enable; 827 phymod_phy_access_t pm_phy_copy; 828 int start_lane, num_lane; 829 830 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 831 PHYMOD_IF_ERR_RETURN 832 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 833 834 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 835 836 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_squelch_get(&pm_phy_copy.access, &enable)); 837 838 /* Check if PMD loopback is on */ 839 if (enable) { 840 PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 841 if (lb_enable) enable = 0; 842 } 843 if (enable) { 844 *tx_control = phymodTxSquelchOn; 845 } else { 846 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_lane_control_get(&pm_phy_copy.access, &reset, &tx_lane)); 847 if (!reset) { 848 *tx_control = phymodTxReset; 849 } else if (!tx_lane) { 850 *tx_control = phymodTxTrafficDisable; 851 } else { 852 *tx_control = phymodTxTrafficEnable; 853 } 854 } 855 856 return PHYMOD_E_NONE; 857 } 858 859 860 int tscf_gen3_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 861 { 862 phymod_phy_access_t pm_phy_copy; 863 int start_lane, num_lane, i; 864 865 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 866 PHYMOD_IF_ERR_RETURN 867 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 868 869 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 870 871 switch (rx_control) { 872 case phymodRxReset: 873 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_lane_control_set(&phy->access, 1)); 874 break; 875 case phymodRxSquelchOn: 876 for (i = 0; i < num_lane; i++) { 877 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 878 continue; 879 } 880 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 881 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&pm_phy_copy.access, 1)); 882 } 883 break; 884 case phymodRxSquelchOff: 885 for (i = 0; i < num_lane; i++) { 886 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 887 continue; 888 } 889 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 890 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_set(&pm_phy_copy.access, 0)); 891 } 892 break; 893 default: 894 break; 895 } 896 897 return PHYMOD_E_NONE; 898 } 899 900 int tscf_gen3_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 901 { 902 int enable, reset; 903 uint32_t lb_enable; 904 phymod_phy_access_t pm_phy_copy; 905 int start_lane, num_lane; 906 907 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 908 PHYMOD_IF_ERR_RETURN 909 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 910 911 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 912 913 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_squelch_get(&pm_phy_copy.access, &enable)); 914 /* Check if PMD loopback is on */ 915 if (enable) { 916 PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_loopback_get(&pm_phy_copy.access, &lb_enable)); 917 if (lb_enable) enable = 0; 918 } 919 if (enable) { 920 *rx_control = phymodRxSquelchOn; 921 } else { 922 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_lane_control_get(&pm_phy_copy.access, &reset)); 923 if (reset == 0) { 924 *rx_control = phymodRxReset; 925 } else { 926 *rx_control = phymodRxSquelchOff; 927 } 928 } 929 930 return PHYMOD_E_NONE; 931 } 932 933 934 int tscf_gen3_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 935 { 936 int fec_en; 937 tefmod_gen3_fec_type_t fec_type; 938 939 /* first check FEC type */ 940 if (PHYMOD_FEC_CL91_GET(enable)) { 941 fec_type = TEFMOD_CL91; 942 } else if (PHYMOD_FEC_CL108_GET(enable)) { 943 fec_type = TEFMOD_CL108; 944 } else { 945 fec_type = TEFMOD_CL74; 946 } 947 948 /* check FEC on/off */ 949 fec_en = enable & TEFMOD_PHY_CONTROL_FEC_MASK; 950 PHYMOD_IF_ERR_RETURN( 951 tefmod_gen3_FEC_control(&phy->access, fec_type, fec_en, 0)); 952 953 return PHYMOD_E_NONE; 954 } 955 956 int tscf_gen3_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 957 { 958 int fec_en; 959 tefmod_gen3_fec_type_t fec_type; 960 961 /* first check FEC type */ 962 if (PHYMOD_FEC_CL91_GET(*enable)) { 963 fec_type = TEFMOD_CL91; 964 } else if (PHYMOD_FEC_CL108_GET(*enable)) { 965 fec_type = TEFMOD_CL108; 966 } else { 967 fec_type = TEFMOD_CL74; 968 } 969 970 PHYMOD_IF_ERR_RETURN( 971 tefmod_gen3_FEC_get(&phy->access, fec_type, &fec_en)); 972 PHYMOD_DEBUG_VERBOSE(("FEC enable state :: %x :: fec_type :: %x\n", fec_en, fec_type)); 973 *enable = (uint32_t) fec_en; 974 975 return PHYMOD_E_NONE; 976 } 977 978 int tscf_gen3_phy_autoneg_oui_set(const phymod_phy_access_t* phy, phymod_autoneg_oui_t an_oui) 979 { 980 tefmod_gen3_an_oui_t oui; 981 982 oui.oui = an_oui.oui; 983 oui.oui_override_hpam_adv = an_oui.oui_override_hpam_adv; 984 oui.oui_override_hpam_det = an_oui.oui_override_hpam_det; 985 oui.oui_override_bam73_adv = an_oui.oui_override_bam73_adv; 986 oui.oui_override_bam73_det = an_oui.oui_override_bam73_det; 987 988 PHYMOD_IF_ERR_RETURN(tefmod_gen3_an_oui_set(&phy->access, oui)); 989 990 return PHYMOD_E_NONE; 991 } 992 993 int tscf_gen3_phy_autoneg_oui_get(const phymod_phy_access_t* phy, phymod_autoneg_oui_t* an_oui) 994 { 995 tefmod_gen3_an_oui_t oui; 996 997 PHYMOD_IF_ERR_RETURN(tefmod_gen3_an_oui_get(&phy->access, &oui)); 998 an_oui->oui_override_hpam_adv = oui.oui_override_hpam_adv; 999 an_oui->oui_override_hpam_det = oui.oui_override_hpam_det; 1000 an_oui->oui_override_bam73_adv = oui.oui_override_bam73_adv; 1001 an_oui->oui_override_bam73_det = oui.oui_override_bam73_det; 1002 1003 return PHYMOD_E_NONE; 1004 } 1005 1006 int tscf_gen3_phy_eee_set(const phymod_phy_access_t* phy, uint32_t enable) 1007 { 1008 uint32_t lpi_bypass; 1009 int rv = PHYMOD_E_NONE; 1010 lpi_bypass = PHYMOD_LPI_BYPASS_GET(enable); 1011 enable &= 0x1; 1012 if (lpi_bypass) { 1013 rv = tefmod_gen3_eee_control_set(&phy->access,enable); 1014 } else { 1015 return PHYMOD_E_UNAVAIL; 1016 } 1017 1018 return rv; 1019 } 1020 1021 int tscf_gen3_phy_eee_get(const phymod_phy_access_t* phy, uint32_t* enable) 1022 { 1023 if (PHYMOD_LPI_BYPASS_GET(*enable)) { 1024 PHYMOD_IF_ERR_RETURN(tefmod_gen3_eee_control_get(&phy->access, enable)); 1025 PHYMOD_LPI_BYPASS_SET(*enable); 1026 } else { 1027 return PHYMOD_E_UNAVAIL; 1028 } 1029 1030 return PHYMOD_E_NONE; 1031 } 1032 1033 int tscf_gen3_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config) 1034 { 1035 int16_t new_os_mode = -1; 1036 int16_t os_mode; 1037 int start_lane, num_lane, lane; 1038 uint32_t vco_rate; 1039 uint32_t new_pll_div; 1040 uint32_t cur_pll0_div = 0; 1041 uint32_t cur_pll1_div = 0; 1042 uint8_t cur_pll_select = 0; 1043 int new_pll_set = 0; 1044 int pll_index_update = 0; 1045 int pll_index = 0; 1046 phymod_phy_access_t pm_phy_copy; 1047 tefmod_gen3_spd_intfc_type_t spd_intf = TEFMOD_SPD_ILLEGAL; 1048 phymod_firmware_lane_config_t firmware_lane_config; 1049 phymod_firmware_core_config_t firmware_core_config; 1050 1051 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1052 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 1053 PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config)); 1054 PHYMOD_IF_ERR_RETURN 1055 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1056 1057 /* Hold PCS lane reset */ 1058 tefmod_gen3_disable_set(&phy->access); 1059 1060 /* Assert the ln dp reset */ 1061 for (lane = 0; lane < num_lane; lane++) { 1062 if(!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane+lane)) { 1063 continue; 1064 } 1065 pm_phy_copy.access.lane_mask = (1 << (start_lane + lane)); 1066 PHYMOD_IF_ERR_RETURN 1067 (falcon2_monterey_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1068 } 1069 1070 /* Remove pmd_tx_disable_pin_dis, it may be asserted because of ILKN*/ 1071 if (config->interface_type != phymodInterfaceBypass) { 1072 for (lane = 0; lane < num_lane; lane++) { 1073 if(!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane+lane)) { 1074 continue; 1075 } 1076 pm_phy_copy.access.lane_mask = (1 << (start_lane + lane)); 1077 PHYMOD_IF_ERR_RETURN 1078 (falcon2_monterey_pmd_tx_disable_pin_dis_set(&pm_phy_copy.access, 0)); 1079 } 1080 } 1081 1082 pm_phy_copy.access.lane_mask = 0x1; 1083 PHYMOD_IF_ERR_RETURN 1084 (tscf_gen3_phy_firmware_core_config_get(&pm_phy_copy, &firmware_core_config)); 1085 1086 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1087 PHYMOD_IF_ERR_RETURN 1088 (tscf_gen3_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 1089 1090 /* AutoNeg and core config from pcs are off */ 1091 firmware_core_config.CoreConfigFromPCS = 0; 1092 firmware_lane_config.AnEnabled = 0; 1093 firmware_lane_config.LaneConfigFromPCS = 0; 1094 firmware_lane_config.DfeOn = 1; 1095 firmware_lane_config.LpDfeOn = 0; 1096 firmware_lane_config.Cl72RestTO = 1; 1097 firmware_lane_config.Cl72AutoPolEn = 0; 1098 firmware_lane_config.ScramblingDisable = 0; 1099 1100 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1101 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1102 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1103 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1104 } else { 1105 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1106 } 1107 1108 if ((config->data_rate == 1000)||(config->data_rate == 2500)) { 1109 firmware_lane_config.DfeOn = 0; 1110 } 1111 1112 /* Select port configuration mode */ 1113 PHYMOD_IF_ERR_RETURN 1114 (tefmod_gen3_port_mode_select(&phy->access)); 1115 1116 /* Lookup speed ID table */ 1117 if (config->interface_type == phymodInterface1000X) { 1118 if (config->data_rate == 2500){ 1119 spd_intf = TEFMOD_SPD_2P5G_KX1; 1120 } else { 1121 if (config->pll_divider_req == 165) { 1122 spd_intf = TEFMOD_SPD_1G_25G; 1123 } else { 1124 spd_intf = TEFMOD_SPD_1G_20G; 1125 } 1126 } 1127 } else if (config->interface_type == phymodInterfaceSGMII) { 1128 if (config->data_rate == 2500){ 1129 spd_intf = TEFMOD_SPD_2P5G_KX1; 1130 } else { 1131 if (config->pll_divider_req == 165) { 1132 spd_intf = TEFMOD_SPD_1G_25G; 1133 } else { 1134 spd_intf = TEFMOD_SPD_1G_20G; 1135 } 1136 } 1137 } else if ((config->interface_type == phymodInterfaceBypass) || 1138 (num_lane == 1)) { 1139 switch (config->data_rate) { 1140 case 5000: 1141 spd_intf = TEFMOD_SPD_5G_KR1; 1142 firmware_lane_config.DfeOn = 0; 1143 break; 1144 case 10000: 1145 case 12000: 1146 spd_intf = TEFMOD_SPD_10000_XFI; 1147 if (config->interface_type != phymodInterfaceBypass) { 1148 if (!PHYMOD_INTF_MODES_COPPER_GET(config)) { 1149 firmware_lane_config.DfeOn = 0; 1150 } 1151 } 1152 break; 1153 case 11000: 1154 spd_intf = TEFMOD_SPD_10600_XFI_HG; 1155 if (config->interface_type != phymodInterfaceBypass) { 1156 if (!PHYMOD_INTF_MODES_COPPER_GET(config)) { 1157 firmware_lane_config.DfeOn = 0; 1158 } 1159 } 1160 break; 1161 case 20000: 1162 spd_intf = TEFMOD_SPD_20000_XFI; 1163 break; 1164 case 21000: 1165 case 21200: 1166 spd_intf = TEFMOD_SPD_21200_XFI_HG; 1167 break; 1168 case 25000: 1169 spd_intf = TEFMOD_SPD_25000_XFI; 1170 break; 1171 case 27000: 1172 spd_intf = TEFMOD_SPD_26500_XFI_HG; 1173 firmware_lane_config.DfeOn = 1; 1174 firmware_lane_config.LpDfeOn = 0; 1175 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1176 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1177 } else { 1178 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1179 } 1180 break; 1181 default: 1182 /* If the interface is pcs bypass mode and check the speed */ 1183 if (config->interface_type == phymodInterfaceBypass) { 1184 /* Disable DFE for lower speed */ 1185 if (config->data_rate < 10000) { 1186 firmware_lane_config.DfeOn = 0; 1187 } 1188 } else { 1189 spd_intf = TEFMOD_SPD_10000_XFI; 1190 firmware_lane_config.DfeOn = 0; 1191 } 1192 break; 1193 } 1194 } else if ((config->interface_type == phymodInterfaceKR2) || 1195 (config->interface_type == phymodInterfaceCR2) || 1196 (config->interface_type == phymodInterfaceXLAUI2) || 1197 (config->interface_type == phymodInterfaceRXAUI) || 1198 (config->interface_type == phymodInterfaceX2) || 1199 (num_lane == 2)) { 1200 switch (config->data_rate) { 1201 case 20000: 1202 spd_intf = TEFMOD_SPD_20G_MLD_X2; 1203 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1204 firmware_lane_config.DfeOn = 0; 1205 firmware_lane_config.LpDfeOn = 0; 1206 } 1207 if (PHYMOD_INTF_MODES_FIBER_GET(config) && !(PHYMOD_INTF_MODES_HIGIG_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 break; 1215 case 21000: 1216 case 21200: 1217 firmware_lane_config.DfeOn = 0; 1218 firmware_lane_config.LpDfeOn = 0; 1219 spd_intf = TEFMOD_SPD_21G_MLD_HG_X2; 1220 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1221 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1222 } else { 1223 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1224 } 1225 break; 1226 case 40000: 1227 spd_intf = TEFMOD_SPD_40G_MLD_X2; 1228 if (config->interface_type == phymodInterfaceXLAUI2) { 1229 firmware_lane_config.DfeOn = 0; 1230 firmware_lane_config.LpDfeOn = 0; 1231 } else { 1232 firmware_lane_config.DfeOn = 1; 1233 firmware_lane_config.LpDfeOn = 1; 1234 } 1235 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1236 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1237 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1238 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1239 } else { 1240 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1241 } 1242 break; 1243 case 42000: 1244 spd_intf = TEFMOD_SPD_42G_MLD_HG_X2; 1245 firmware_lane_config.DfeOn = 1; 1246 firmware_lane_config.LpDfeOn = 1; 1247 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1248 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1249 } else { 1250 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1251 } 1252 break; 1253 case 50000: 1254 spd_intf = TEFMOD_SPD_50G_MLD_X2; 1255 break; 1256 case 53000: 1257 spd_intf = TEFMOD_SPD_53G_MLD_HG_X2; 1258 break; 1259 default: 1260 spd_intf = TEFMOD_SPD_20G_MLD_X2; 1261 break; 1262 } 1263 } else if (num_lane == 4) { 1264 switch (config->data_rate) { 1265 case 10000: 1266 spd_intf = TEFMOD_SPD_2P5G_KX1; 1267 firmware_lane_config.DfeOn = 0; 1268 firmware_lane_config.LpDfeOn = 0; 1269 firmware_lane_config.ScramblingDisable = 1; 1270 break; 1271 case 40000: 1272 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1273 spd_intf = TEFMOD_SPD_42G_MLD_HG_X4; 1274 firmware_lane_config.DfeOn = 1; 1275 firmware_lane_config.LpDfeOn = 1; 1276 } else if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1277 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1278 firmware_lane_config.DfeOn = 0; 1279 firmware_lane_config.LpDfeOn = 0; 1280 } else { 1281 if (config->interface_type == phymodInterfaceXLAUI) { 1282 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1283 firmware_lane_config.DfeOn = 0; 1284 firmware_lane_config.LpDfeOn = 0; 1285 } else { 1286 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1287 firmware_lane_config.DfeOn = 1; 1288 firmware_lane_config.LpDfeOn = 1; 1289 } 1290 } 1291 break; 1292 case 42000: 1293 spd_intf = TEFMOD_SPD_42G_MLD_HG_X4; 1294 firmware_lane_config.DfeOn = 1; 1295 firmware_lane_config.LpDfeOn = 1; 1296 break; 1297 case 48000: 1298 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1299 firmware_lane_config.DfeOn = 0; 1300 firmware_lane_config.LpDfeOn = 0; 1301 break; 1302 case 50000: 1303 spd_intf = TEFMOD_SPD_50G_MLD_X4; 1304 break; 1305 case 53000: 1306 spd_intf = TEFMOD_SPD_53G_MLD_HG_X4; 1307 break; 1308 case 100000: 1309 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) { 1310 spd_intf = TEFMOD_SPD_106G_MLD_HG_X4; 1311 firmware_lane_config.DfeOn = 1; 1312 firmware_lane_config.LpDfeOn = 0; 1313 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1314 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1315 } else { 1316 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1317 } 1318 } else { 1319 spd_intf = TEFMOD_SPD_100G_MLD_X4; 1320 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1321 firmware_lane_config.DfeOn = 0; 1322 firmware_lane_config.LpDfeOn = 0; 1323 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 1324 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1325 firmware_lane_config.DfeOn = 1; 1326 firmware_lane_config.LpDfeOn = 0; 1327 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1328 } else { 1329 firmware_lane_config.DfeOn = 1; 1330 firmware_lane_config.LpDfeOn = 0; 1331 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1332 } 1333 if (config->interface_type == phymodInterfaceCAUI4 || config->interface_type == phymodInterfaceCAUI) { 1334 firmware_lane_config.DfeOn = 1; 1335 firmware_lane_config.LpDfeOn = 1; 1336 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1337 } 1338 } 1339 break; 1340 case 106000: 1341 spd_intf = TEFMOD_SPD_106G_MLD_HG_X4; 1342 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1343 firmware_lane_config.DfeOn = 1; 1344 firmware_lane_config.LpDfeOn = 0; 1345 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 1346 } else { 1347 firmware_lane_config.DfeOn = 1; 1348 firmware_lane_config.LpDfeOn = 0; 1349 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 1350 } 1351 break; 1352 default: 1353 spd_intf = TEFMOD_SPD_40G_MLD_X4; 1354 firmware_lane_config.DfeOn = 0; 1355 break; 1356 } 1357 } else { 1358 PHYMOD_DEBUG_ERROR(("Incorrect speed config\n" )); 1359 return PHYMOD_E_CONFIG; 1360 } 1361 1362 /* Get current PLL0 and PLL1 */ 1363 PHYMOD_IF_ERR_RETURN 1364 (tefmod_gen3_pll_div_get(&pm_phy_copy.access, &cur_pll0_div, &cur_pll1_div)); 1365 1366 /* Get PLL_select */ 1367 PHYMOD_IF_ERR_RETURN 1368 (falcon2_monterey_pll_select_get(&pm_phy_copy.access, &cur_pll_select)); 1369 1370 /* Get required PLL_DIV */ 1371 if (config->interface_type == phymodInterfaceBypass){ 1372 PHYMOD_IF_ERR_RETURN 1373 (falcon2_monterey_get_vco(config, &vco_rate, &new_pll_div, &new_os_mode)); 1374 } else { 1375 PHYMOD_IF_ERR_RETURN 1376 (tefmod_gen3_pll_div_lkup_get(&phy->access, spd_intf, config->ref_clock, &new_pll_div)); 1377 } 1378 1379 /* If flag SINGLE_PLL_ONLY set 1380 * One PLL: PLL1_DIV = 132(20G)/165(25G) 1381 * Otherwise, 1382 * Dual PLL: 1383 * - IEEE mode: PLL0_DIV = 132(20G), PLL1_DIV = 165(25G) 1384 * - HIGIG mode: PLL0_DIV = 140(21G)/ 175(27G), PLL1_DIV = 165(25G) 1385 */ 1386 /* Only PLL1 is used for ETH port of mixed mode */ 1387 if (flags == PHYMOD_INTF_F_SINGLE_PLL_ONLY) { 1388 if ((new_pll_div == phymod_TSCF_PLL_DIV132) || (new_pll_div == phymod_TSCF_PLL_DIV165)){ 1389 if (new_pll_div != cur_pll1_div) { 1390 if (!(flags & PHYMOD_INTF_F_DONT_TURN_OFF_PLL)){ 1391 new_pll_set = 1; 1392 } else { 1393 PHYMOD_DEBUG_ERROR(("DONT TURN OFF PLL flag is set\n" )); 1394 return PHYMOD_E_CONFIG; 1395 } 1396 } 1397 pll_index_update = 1; 1398 pll_index = 1; 1399 } else { 1400 PHYMOD_DEBUG_ERROR(("Pll %d One PLL mode doesn't support \n", new_pll_div)); 1401 return PHYMOD_E_CONFIG; 1402 } 1403 } else { /* HIGIG MODE */ 1404 if (PHYMOD_INTF_MODES_HIGIG_GET(config)){ 1405 /* For 10G, 20G, 40G(4 lanes) Higig2, pll_div is phymod_TSCF_PLL_DIV132 */ 1406 if ((config->data_rate == 10000) && (num_lane == 1)) { 1407 new_pll_set = 0; 1408 pll_index_update = 1; 1409 pll_index = 0; 1410 } else if ((config->data_rate == 20000) && (num_lane == 2)) { 1411 new_pll_set = 0; 1412 pll_index_update = 1; 1413 pll_index = 0; 1414 } else if ((config->data_rate == 40000) && (num_lane == 4)) { 1415 new_pll_set = 0; 1416 pll_index_update = 1; 1417 pll_index = 0; 1418 new_pll_div = phymod_TSCF_PLL_DIV132; 1419 } 1420 if ((pll_index_update == 1) && (new_pll_div != cur_pll0_div)) { 1421 new_pll_set = 1; 1422 } 1423 if ((new_pll_div == phymod_TSCF_PLL_DIV140) || (new_pll_div == phymod_TSCF_PLL_DIV175)) { 1424 if (new_pll_div != cur_pll0_div){ 1425 if (!(flags & PHYMOD_INTF_F_DONT_TURN_OFF_PLL)){ 1426 new_pll_set = 1; 1427 pll_index_update = 1; 1428 pll_index = 0; 1429 } else { 1430 PHYMOD_DEBUG_ERROR(("DONT TURN OFF PLL flag is set\n" )); 1431 return PHYMOD_E_CONFIG; 1432 } 1433 } 1434 pll_index_update = 1; 1435 pll_index = 0; 1436 } 1437 } else { /* IEEE MODE */ 1438 if ((new_pll_div == phymod_TSCF_PLL_DIV132) || (new_pll_div == phymod_TSCF_PLL_DIV165)){ 1439 if ((new_pll_div == cur_pll0_div) && (cur_pll_select != 0)){ 1440 pll_index_update = 1; 1441 pll_index = 0; 1442 } 1443 if ((new_pll_div == cur_pll1_div) && (cur_pll_select != 1)){ 1444 pll_index_update = 1; 1445 pll_index = 1; 1446 } 1447 /* Set PLL select as 1 when speed 1G with VCO 25.78125 */ 1448 if ((config->data_rate == 1000) && (config->pll_divider_req == 165)) { 1449 pll_index_update = 1; 1450 pll_index = 1; 1451 } 1452 } 1453 } 1454 } 1455 1456 1457 /* Set os mode */ 1458 if (new_os_mode >=0){ 1459 os_mode = new_os_mode | 0x80000000; 1460 } else { 1461 os_mode = 0; 1462 } 1463 PHYMOD_IF_ERR_RETURN 1464 (tefmod_gen3_pmd_os_mode_set(&phy->access, spd_intf, config->ref_clock, os_mode)); 1465 1466 if (new_pll_set) { 1467 /* Only PLL1 is used for ETH port of mixed mode */ 1468 if (flags != PHYMOD_INTF_F_SINGLE_PLL_ONLY) { 1469 pm_phy_copy.access.pll_idx = 0; 1470 PHYMOD_IF_ERR_RETURN 1471 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 0)); 1472 } 1473 1474 /* Update PLL1 for ETH port of mixed mode, otherwise leave PLL1 at 25G */ 1475 if (flags == PHYMOD_INTF_F_SINGLE_PLL_ONLY) { 1476 pm_phy_copy.access.pll_idx = 1; 1477 PHYMOD_IF_ERR_RETURN 1478 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 0)); 1479 } 1480 /* PLL0 config */ 1481 if (flags != PHYMOD_INTF_F_SINGLE_PLL_ONLY) { 1482 pm_phy_copy.access.pll_idx = 0; 1483 PHYMOD_IF_ERR_RETURN 1484 (tefmod_gen3_configure_pll(&pm_phy_copy.access, new_pll_div, config->ref_clock)); 1485 PHYMOD_IF_ERR_RETURN 1486 (tefmod_gen3_pll_to_vco_rate(&pm_phy_copy.access, new_pll_div, config->ref_clock, &vco_rate)); 1487 firmware_core_config.VcoRate = MHZ_TO_VCO_RATE(vco_rate); 1488 1489 /* Update firmware core config */ 1490 PHYMOD_IF_ERR_RETURN 1491 (tscf_gen3_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config)); 1492 PHYMOD_IF_ERR_RETURN 1493 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 1)); 1494 } 1495 1496 if (flags == PHYMOD_INTF_F_SINGLE_PLL_ONLY) { 1497 pm_phy_copy.access.pll_idx = 1; 1498 PHYMOD_IF_ERR_RETURN 1499 (tefmod_gen3_configure_pll(&pm_phy_copy.access, new_pll_div, config->ref_clock)); 1500 PHYMOD_IF_ERR_RETURN 1501 (tefmod_gen3_pll_to_vco_rate(&pm_phy_copy.access, new_pll_div, config->ref_clock, &vco_rate)); 1502 firmware_core_config.VcoRate = MHZ_TO_VCO_RATE(vco_rate); 1503 1504 /* Update firmware core config */ 1505 PHYMOD_IF_ERR_RETURN 1506 (tscf_gen3_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config)); 1507 PHYMOD_IF_ERR_RETURN 1508 (falcon2_monterey_core_soft_reset_release(&pm_phy_copy.access, 1)); 1509 } 1510 1511 PHYMOD_IF_ERR_RETURN 1512 (tefmod_gen3_master_port_num_set(&phy->access, start_lane)); 1513 PHYMOD_IF_ERR_RETURN 1514 (tefmod_gen3_pll_reset_enable_set(&phy->access, 1)); 1515 } 1516 1517 /* Select pll index for the port */ 1518 if (pll_index_update) { 1519 for (lane = 0; lane < num_lane; lane++) { 1520 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + lane)) { 1521 continue; 1522 } 1523 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + lane); 1524 PHYMOD_IF_ERR_RETURN 1525 (tefmod_gen3_pll_select_set(&pm_phy_copy.access, pll_index)); 1526 } 1527 } 1528 if(config->interface_type != phymodInterfaceBypass) { 1529 PHYMOD_IF_ERR_RETURN 1530 (tefmod_gen3_set_spd_intf(&phy->access, spd_intf)); 1531 } 1532 1533 /* Update firmware lane config */ 1534 for (lane = 0; lane < num_lane; lane++) { 1535 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + lane)) { 1536 continue; 1537 } 1538 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + lane); 1539 PHYMOD_IF_ERR_RETURN 1540 (_tscf_gen3_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 1541 } 1542 1543 /* Release the ln dp reset */ 1544 for (lane = 0; lane < num_lane; lane++) { 1545 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + lane)) { 1546 continue; 1547 } 1548 pm_phy_copy.access.lane_mask = 1 << (start_lane + lane); 1549 PHYMOD_IF_ERR_RETURN 1550 (falcon2_monterey_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1551 } 1552 1553 return PHYMOD_E_NONE; 1554 } 1555 1556 STATIC 1557 int _tscf_gen3_speed_id_interface_config_get(const phymod_phy_access_t* phy, int speed_id, phymod_phy_inf_config_t* config) 1558 { 1559 int ilkn_set = 0; 1560 uint32_t pll_div, pll0_div, pll1_div; 1561 uint8_t pll_select; 1562 int osr_mode; 1563 int div_osr_value; 1564 uint32_t vco_rate; 1565 1566 PHYMOD_IF_ERR_RETURN(tefmod_gen3_pcs_ilkn_chk(&phy->access, &ilkn_set)); 1567 PHYMOD_IF_ERR_RETURN 1568 (tefmod_gen3_pll_div_get(&phy->access, &pll0_div, &pll1_div)); 1569 PHYMOD_IF_ERR_RETURN 1570 (falcon2_monterey_pll_select_get(&phy->access, &pll_select)); 1571 pll_div = (pll_select == 1)? pll1_div : pll0_div; 1572 1573 if(ilkn_set) { 1574 config->interface_type = phymodInterfaceBypass; 1575 PHYMOD_IF_ERR_RETURN 1576 (falcon2_monterey_osr_mode_get(&phy->access, &osr_mode)); 1577 PHYMOD_IF_ERR_RETURN 1578 (tefmod_gen3_pll_to_vco_rate(&phy->access, pll_div, config->ref_clock, &vco_rate)); 1579 1580 div_osr_value = 1 << osr_mode; 1581 config->data_rate = vco_rate/div_osr_value; 1582 } else { 1583 switch (speed_id) { 1584 case 0x0: 1585 config->data_rate = 10000; 1586 config->interface_type = phymodInterfaceCR; 1587 break; 1588 case 0x1: 1589 config->data_rate = 10000; 1590 config->interface_type = phymodInterfaceKR; 1591 break; 1592 case 0x2: 1593 config->data_rate = 10000; 1594 config->interface_type = phymodInterfaceKR; 1595 break; 1596 case 0x4: 1597 config->data_rate = 11000; 1598 config->interface_type = phymodInterfaceCR; 1599 break; 1600 case 0x5: 1601 config->data_rate = 11000; 1602 config->interface_type = phymodInterfaceKR; 1603 break; 1604 case 0x6: 1605 config->data_rate = 11000; 1606 config->interface_type = phymodInterfaceKR; 1607 break; 1608 case 0x8: 1609 config->data_rate = 20000; 1610 config->interface_type = phymodInterfaceCR; 1611 break; 1612 case 0x9: 1613 config->data_rate = 20000; 1614 config->interface_type = phymodInterfaceKR; 1615 break; 1616 case 0xa: 1617 config->data_rate = 20000; 1618 config->interface_type = phymodInterfaceKR; 1619 break; 1620 case 0xc: 1621 config->data_rate = 21000; 1622 config->interface_type = phymodInterfaceCR; 1623 break; 1624 case 0xd: 1625 config->data_rate = 21000; 1626 config->interface_type = phymodInterfaceKR; 1627 break; 1628 case 0xe: 1629 config->data_rate = 21000; 1630 config->interface_type = phymodInterfaceKR; 1631 break; 1632 case 0x10: 1633 config->data_rate = 25000; 1634 config->interface_type = phymodInterfaceCR; 1635 break; 1636 case 0x11: 1637 config->data_rate = 25000; 1638 config->interface_type = phymodInterfaceKR; 1639 break; 1640 case 0x12: 1641 config->data_rate = 25000; 1642 config->interface_type = phymodInterfaceKR; 1643 break; 1644 case 0x15: 1645 config->data_rate = 27000; 1646 config->interface_type = phymodInterfaceKR; 1647 break; 1648 case 0x16: 1649 config->data_rate = 27000; 1650 config->interface_type = phymodInterfaceKR; 1651 break; 1652 case 0x18: 1653 config->data_rate = 20000; 1654 config->interface_type = phymodInterfaceCR2; 1655 break; 1656 case 0x19: 1657 config->data_rate = 20000; 1658 config->interface_type = phymodInterfaceKR2; 1659 break; 1660 case 0x1a: 1661 config->data_rate = 20000; 1662 config->interface_type = phymodInterfaceKR2; 1663 break; 1664 case 0x1c: 1665 config->data_rate = 21000; 1666 config->interface_type = phymodInterfaceCR2; 1667 break; 1668 case 0x1d: 1669 config->data_rate = 21000; 1670 config->interface_type = phymodInterfaceKR2; 1671 break; 1672 case 0x1e: 1673 config->data_rate = 21000; 1674 config->interface_type = phymodInterfaceKR2; 1675 break; 1676 case 0x20: 1677 config->data_rate = 40000; 1678 config->interface_type = phymodInterfaceCR2; 1679 break; 1680 case 0x21: 1681 config->data_rate = 40000; 1682 config->interface_type = phymodInterfaceKR2; 1683 break; 1684 case 0x22: 1685 config->data_rate = 40000; 1686 config->interface_type = phymodInterfaceKR2; 1687 break; 1688 case 0x24: 1689 config->data_rate = 42000; 1690 config->interface_type = phymodInterfaceCR2; 1691 break; 1692 case 0x25: 1693 config->data_rate = 42000; 1694 config->interface_type = phymodInterfaceKR2; 1695 break; 1696 case 0x26: 1697 config->data_rate = 42000; 1698 config->interface_type = phymodInterfaceKR2; 1699 break; 1700 case 0x28: 1701 config->data_rate = 40000; 1702 if ((config->ref_clock == phymodRefClk156Mhz) && 1703 (pll_div == phymod_TSCF_PLL_DIV140)) { 1704 config->data_rate =42000; 1705 } 1706 config->interface_type = phymodInterfaceCR4; 1707 break; 1708 case 0x29: 1709 config->data_rate = 40000; 1710 if ((config->ref_clock == phymodRefClk156Mhz) && 1711 (pll_div == phymod_TSCF_PLL_DIV140)) { 1712 config->data_rate =42000; 1713 } 1714 config->interface_type = phymodInterfaceKR4; 1715 break; 1716 case 0x2a: 1717 config->data_rate = 40000; 1718 if ((config->ref_clock == phymodRefClk156Mhz) && 1719 (pll_div == phymod_TSCF_PLL_DIV140)) { 1720 config->data_rate =42000; 1721 } 1722 config->interface_type = phymodInterfaceKR4; 1723 break; 1724 case 0x2c: 1725 config->data_rate = 42000; 1726 config->interface_type = phymodInterfaceCR4; 1727 break; 1728 case 0x2d: 1729 config->data_rate = 42000; 1730 config->interface_type = phymodInterfaceKR4; 1731 break; 1732 case 0x2e: 1733 config->data_rate = 42000; 1734 if ((config->ref_clock == phymodRefClk156Mhz) && 1735 (pll_div == phymod_TSCF_PLL_DIV132)) { 1736 config->data_rate =40000; 1737 } 1738 if ((config->ref_clock == phymodRefClk125Mhz) && 1739 (pll_div == phymod_TSCF_PLL_DIV165)) { 1740 config->data_rate =40000; 1741 } 1742 config->interface_type = phymodInterfaceKR4; 1743 break; 1744 case 0x30: 1745 config->data_rate = 50000; 1746 config->interface_type = phymodInterfaceCR2; 1747 break; 1748 case 0x31: 1749 config->data_rate = 50000; 1750 config->interface_type = phymodInterfaceKR2; 1751 break; 1752 case 0x32: 1753 config->data_rate = 50000; 1754 config->interface_type = phymodInterfaceKR2; 1755 break; 1756 case 0x34: 1757 config->data_rate = 53000; 1758 config->interface_type = phymodInterfaceCR2; 1759 break; 1760 case 0x35: 1761 config->data_rate = 53000; 1762 config->interface_type = phymodInterfaceKR2; 1763 break; 1764 case 0x36: 1765 config->data_rate = 53000; 1766 config->interface_type = phymodInterfaceKR2; 1767 break; 1768 case 0x38: 1769 config->data_rate = 50000; 1770 config->interface_type = phymodInterfaceCR4; 1771 break; 1772 case 0x39: 1773 config->data_rate = 50000; 1774 config->interface_type = phymodInterfaceKR4; 1775 break; 1776 case 0x3a: 1777 config->data_rate = 50000; 1778 config->interface_type = phymodInterfaceKR4; 1779 break; 1780 case 0x3c: 1781 config->data_rate = 53000; 1782 config->interface_type = phymodInterfaceCR4; 1783 break; 1784 case 0x3d: 1785 config->data_rate = 53000; 1786 config->interface_type = phymodInterfaceKR4; 1787 break; 1788 case 0x3e: 1789 config->data_rate = 53000; 1790 config->interface_type = phymodInterfaceKR4; 1791 break; 1792 case 0x40: 1793 config->data_rate = 100000; 1794 config->interface_type = phymodInterfaceCR4; 1795 break; 1796 case 0x41: 1797 config->data_rate = 100000; 1798 config->interface_type = phymodInterfaceKR4; 1799 break; 1800 case 0x42: 1801 config->data_rate = 100000; 1802 config->interface_type = phymodInterfaceKR4; 1803 break; 1804 case 0x44: 1805 config->data_rate = 106000; 1806 if (pll_div == phymod_TSCF_PLL_DIV165) { 1807 config->data_rate = 100000; 1808 } 1809 config->interface_type = phymodInterfaceCR4; 1810 break; 1811 case 0x45: 1812 config->data_rate = 106000; 1813 if (pll_div == phymod_TSCF_PLL_DIV165) { 1814 config->data_rate = 100000; 1815 } 1816 config->interface_type = phymodInterfaceKR4; 1817 break; 1818 case 0x46: 1819 config->data_rate = 106000; 1820 if (pll_div == phymod_TSCF_PLL_DIV165) { 1821 config->data_rate = 100000; 1822 } 1823 config->interface_type = phymodInterfaceKR4; 1824 break; 1825 case 0x48: 1826 config->data_rate = 20000; 1827 config->interface_type = phymodInterfaceKR2; 1828 break; 1829 case 0x50: 1830 config->data_rate = 25000; 1831 config->interface_type = phymodInterfaceKR2; 1832 break; 1833 case 0x58: 1834 config->data_rate = 1000; 1835 config->interface_type = phymodInterfaceSGMII; 1836 break; 1837 case 0x60: 1838 config->data_rate = 1000; 1839 config->interface_type = phymodInterfaceSGMII; 1840 break; 1841 case 0x62: 1842 config->data_rate = 2500; 1843 config->interface_type = phymodInterfaceSGMII; 1844 break; 1845 case 0x63: 1846 config->data_rate = 5000; 1847 config->interface_type = phymodInterfaceKR; 1848 break; 1849 case 0x70: 1850 config->data_rate = 25000; 1851 config->interface_type = phymodInterfaceCR; 1852 break; 1853 case 0x71: 1854 config->data_rate = 25000; 1855 config->interface_type = phymodInterfaceCR; 1856 break; 1857 case 0x72: 1858 config->data_rate = 25000; 1859 config->interface_type = phymodInterfaceKR; 1860 break; 1861 case 0x73: 1862 config->data_rate = 25000; 1863 config->interface_type = phymodInterfaceKR; 1864 break; 1865 default: 1866 config->data_rate = 10000; 1867 config->interface_type = phymodInterfaceKR; 1868 break; 1869 } 1870 } 1871 1872 return PHYMOD_E_NONE; 1873 } 1874 1875 int tscf_gen3_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) 1876 { 1877 int speed_id; 1878 phymod_firmware_lane_config_t firmware_lane_config; 1879 phymod_phy_access_t pm_phy_copy; 1880 int start_lane, num_lane; 1881 phymod_autoneg_control_t an_control; 1882 int an_done = 0; 1883 an_control.flags = 0; 1884 1885 config->ref_clock = ref_clock; 1886 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1887 1888 PHYMOD_IF_ERR_RETURN 1889 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1890 PHYMOD_IF_ERR_RETURN 1891 (tefmod_gen3_speed_id_get(&phy->access, &speed_id)); 1892 PHYMOD_IF_ERR_RETURN 1893 (_tscf_gen3_speed_id_interface_config_get(phy, speed_id, config)); 1894 /* Read the current media type */ 1895 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 1896 PHYMOD_IF_ERR_RETURN 1897 (tscf_gen3_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 1898 if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeOptics) { 1899 PHYMOD_INTF_MODES_FIBER_SET(config); 1900 } else if (firmware_lane_config.MediaType == phymodFirmwareMediaTypeCopperCable) { 1901 PHYMOD_INTF_MODES_FIBER_CLR(config); 1902 PHYMOD_INTF_MODES_COPPER_SET(config); 1903 } else { 1904 PHYMOD_INTF_MODES_FIBER_CLR(config); 1905 PHYMOD_INTF_MODES_BACKPLANE_SET(config); 1906 } 1907 /* Next need to check for 40G 4 lanes mode, it's for XLAUI or KR4 */ 1908 if ((config->data_rate == 40000) && (!(firmware_lane_config.DfeOn)) && 1909 (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) { 1910 if (num_lane == 2) { 1911 config->interface_type = phymodInterfaceXLAUI2; 1912 } else { 1913 config->interface_type = phymodInterfaceXLAUI; 1914 } 1915 } 1916 PHYMOD_IF_ERR_RETURN 1917 (tscf_gen3_phy_autoneg_get(phy, &an_control, (uint32_t *) &an_done)); 1918 1919 /* Next need to check if we are CAUI4 100G mode */ 1920 if (!(an_control.enable && an_done)) { 1921 if ((config->data_rate == 100000) && (firmware_lane_config.LpDfeOn) && 1922 (firmware_lane_config.MediaType == phymodFirmwareMediaTypePcbTraceBackPlane)) { 1923 config->interface_type = phymodInterfaceCAUI4; 1924 } 1925 } 1926 1927 switch (config->interface_type) { 1928 case phymodInterfaceSGMII: 1929 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1930 config->interface_type = phymodInterface1000X; 1931 } else { 1932 config->interface_type = phymodInterfaceSGMII; 1933 } 1934 1935 /* 1936 * Speed ID 0x58 and 0x60 are interpreted as phymodInterfaceSGMII 1937 * by _tscf_gen3_speed_id_interface_config_get(). This is correct when 1938 * the port is in forced speed mode. However, when AN is enabled 1939 * and completed the interface type cannot be SGMII because TSCF 1940 * does not support CL37 & CL37bam. The correct interface type in 1941 * this scenario should be phymodInterfaceKX. 1942 */ 1943 if (an_control.enable && an_done) { 1944 config->interface_type = phymodInterfaceKX; 1945 } 1946 break; 1947 case phymodInterfaceXFI: 1948 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1949 config->interface_type = phymodInterfaceCR; 1950 } else { 1951 config->interface_type = phymodInterfaceXFI; 1952 } 1953 break; 1954 case phymodInterfaceKR2: 1955 if (!an_control.enable) { 1956 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1957 config->interface_type = phymodInterfaceSR2; 1958 } else { 1959 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1960 config->interface_type = phymodInterfaceCR2; 1961 } else { 1962 config->interface_type = phymodInterfaceKR2; 1963 } 1964 } 1965 } 1966 break; 1967 case phymodInterfaceKR4: 1968 if (!an_control.enable) { 1969 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1970 config->interface_type = phymodInterfaceSR4; 1971 /*if (pCfg->speed_config.line_interface == TSCF_IF_LR4) { 1972 config->interface_type = phymodInterfaceLR4; 1973 }*/ 1974 } else { 1975 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1976 config->interface_type = phymodInterfaceCR4; 1977 } else { 1978 config->interface_type = phymodInterfaceKR4; 1979 } 1980 } 1981 } 1982 break; 1983 case phymodInterfaceKR: 1984 { 1985 if (!an_control.enable) { 1986 if(config->data_rate == 10000) { 1987 if (/*PHY_EXTERNAL_MODE(unit, port) ||*/ !PHYMOD_INTF_MODES_FIBER_GET(config)) { 1988 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 1989 config->interface_type = phymodInterfaceCR; 1990 } else { 1991 config->interface_type = phymodInterfaceXFI; 1992 } 1993 } else { 1994 config->interface_type = phymodInterfaceSFI; 1995 } 1996 } else{ 1997 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 1998 config->interface_type = phymodInterfaceSR; 1999 } else { 2000 if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 2001 config->interface_type = phymodInterfaceCR; 2002 } else { 2003 config->interface_type = phymodInterfaceKR; 2004 } 2005 } 2006 } 2007 } else { 2008 config->interface_type = phymodInterfaceKR; 2009 } 2010 break; 2011 } 2012 2013 default: 2014 break; 2015 } 2016 2017 return PHYMOD_E_NONE; 2018 } 2019 2020 int tscf_gen3_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 2021 { 2022 struct falcon2_monterey_uc_lane_config_st serdes_firmware_config; 2023 PHYMOD_IF_ERR_RETURN(falcon2_monterey_get_uc_lane_cfg(&phy->access, &serdes_firmware_config)); 2024 2025 if(serdes_firmware_config.field.dfe_on == 0) { 2026 PHYMOD_DEBUG_ERROR(("ERROR :: DFE is off : Can not start CL72/CL93 with no DFE\n")); 2027 return PHYMOD_E_CONFIG; 2028 } 2029 2030 PHYMOD_IF_ERR_RETURN 2031 (tefmod_gen3_clause72_control(&phy->access, cl72_en)); 2032 2033 return PHYMOD_E_NONE; 2034 2035 } 2036 2037 int tscf_gen3_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 2038 { 2039 PHYMOD_IF_ERR_RETURN 2040 (falcon2_monterey_clause72_control_get(&phy->access, cl72_en)); 2041 2042 return PHYMOD_E_NONE; 2043 2044 } 2045 2046 2047 int tscf_gen3_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 2048 { 2049 uint32_t local_status; 2050 PHYMOD_IF_ERR_RETURN 2051 (falcon2_monterey_pmd_cl72_receiver_status(&phy->access, &local_status)); 2052 status->locked = local_status; 2053 2054 return PHYMOD_E_NONE; 2055 } 2056 2057 2058 int tscf_gen3_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability) 2059 { 2060 tefmod_gen3_an_adv_ability_t value; 2061 int start_lane, num_lane; 2062 phymod_phy_access_t phy_copy; 2063 2064 PHYMOD_IF_ERR_RETURN 2065 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2066 2067 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2068 phy_copy.access.lane_mask = 0x1 << start_lane; 2069 2070 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2071 2072 value.an_cl72 = an_ability->an_cl72; 2073 if (PHYMOD_AN_FEC_OFF_GET(an_ability->an_fec)) { 2074 value.an_fec = TEFMOD_FEC_SUPRTD_NOT_REQSTD; 2075 } else { 2076 if (PHYMOD_AN_FEC_CL74_GET(an_ability->an_fec)){ 2077 value.an_fec = TEFMOD_FEC_CL74_SUPRTD_REQSTD; 2078 } 2079 if (PHYMOD_AN_FEC_CL91_GET(an_ability->an_fec)){ 2080 value.an_fec |= TEFMOD_FEC_CL91_SUPRTD_REQSTD; 2081 } 2082 } 2083 2084 /* value.an_fec = an_ability->an_fec; */ 2085 value.an_hg2 = an_ability->an_hg2; 2086 2087 /* next check pause */ 2088 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) { 2089 value.an_pause = TEFMOD_SYMM_PAUSE; 2090 } 2091 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && !PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 2092 value.an_pause = TEFMOD_ASYM_PAUSE; 2093 } 2094 if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability) && PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 2095 value.an_pause = TEFMOD_ASYM_SYMM_PAUSE; 2096 } 2097 /* check cl73 ability */ 2098 if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)){ 2099 value.an_base_speed |= 1 << TEFMOD_CL73_1GBASE_KX; 2100 } 2101 if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)){ 2102 value.an_base_speed |= 1 << TEFMOD_CL73_10GBASE_KR1; 2103 } 2104 if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)){ 2105 value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_KR4; 2106 } 2107 if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)){ 2108 value.an_base_speed |= 1 << TEFMOD_CL73_40GBASE_CR4; 2109 } 2110 if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) { 2111 value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_KR4; 2112 } 2113 if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) { 2114 value.an_base_speed |= 1 << TEFMOD_CL73_100GBASE_CR4; 2115 } 2116 if (PHYMOD_AN_CAP_25G_CR1_GET(an_ability->an_cap)){ 2117 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CR1; 2118 } 2119 if (PHYMOD_AN_CAP_25G_KR1_GET(an_ability->an_cap)){ 2120 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KR1; 2121 } 2122 if (PHYMOD_AN_CAP_25G_CRS1_GET(an_ability->an_cap)){ 2123 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_CRS1; 2124 } 2125 if (PHYMOD_AN_CAP_25G_KRS1_GET(an_ability->an_cap)){ 2126 value.an_base_speed |= 1 << TEFMOD_CL73_25GBASE_KRS1; 2127 } 2128 if (PHYMOD_AN_CAP_2P5G_X_GET(an_ability->an_cap)){ 2129 value.an_base_speed |= 1 << TEFMOD_CL73_2P5GBASE_KX1; 2130 } 2131 if (PHYMOD_AN_CAP_5G_KR1_GET(an_ability->an_cap)){ 2132 value.an_base_speed |= 1 << TEFMOD_CL73_5GBASE_KR1; 2133 } 2134 2135 /* check cl73 bam ability */ 2136 if (PHYMOD_BAM_CL73_CAP_20G_KR2_GET(an_ability->cl73bam_cap)){ 2137 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_KR2; 2138 } 2139 if (PHYMOD_BAM_CL73_CAP_20G_CR2_GET(an_ability->cl73bam_cap)){ 2140 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_20GBASE_CR2; 2141 } 2142 if (PHYMOD_BAM_CL73_CAP_40G_KR2_GET(an_ability->cl73bam_cap)){ 2143 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_KR2; 2144 } 2145 if (PHYMOD_BAM_CL73_CAP_40G_CR2_GET(an_ability->cl73bam_cap)){ 2146 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_40GBASE_CR2; 2147 } 2148 if (PHYMOD_BAM_CL73_CAP_50G_KR2_GET(an_ability->cl73bam_cap)){ 2149 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR2; 2150 } 2151 if (PHYMOD_BAM_CL73_CAP_50G_CR2_GET(an_ability->cl73bam_cap)){ 2152 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR2; 2153 } 2154 if (PHYMOD_BAM_CL73_CAP_50G_KR4_GET(an_ability->cl73bam_cap)){ 2155 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_KR4; 2156 } 2157 if (PHYMOD_BAM_CL73_CAP_50G_CR4_GET(an_ability->cl73bam_cap)){ 2158 value.an_bam_speed |= 1 << TEFMOD_CL73_BAM_50GBASE_CR4; 2159 } 2160 if (PHYMOD_BAM_CL73_CAP_20G_KR1_GET(an_ability->cl73bam_cap)){ 2161 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_KR1; 2162 } 2163 if (PHYMOD_BAM_CL73_CAP_20G_CR1_GET(an_ability->cl73bam_cap)){ 2164 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_20GBASE_CR1; 2165 } 2166 if (PHYMOD_BAM_CL73_CAP_25G_KR1_GET(an_ability->cl73bam_cap)){ 2167 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_KR1; 2168 } 2169 if (PHYMOD_BAM_CL73_CAP_25G_CR1_GET(an_ability->cl73bam_cap)){ 2170 value.an_bam_speed1 |= 1 << TEFMOD_CL73_BAM_25GBASE_CR1; 2171 } 2172 PHYMOD_IF_ERR_RETURN 2173 (tefmod_gen3_autoneg_ability_set(&phy_copy.access, &value)); 2174 2175 return PHYMOD_E_NONE; 2176 } 2177 2178 int tscf_gen3_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 2179 { 2180 tefmod_gen3_an_adv_ability_t value; 2181 phymod_phy_access_t phy_copy; 2182 int start_lane, num_lane; 2183 2184 PHYMOD_IF_ERR_RETURN 2185 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2186 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2187 phy_copy.access.lane_mask = 0x1 << start_lane; 2188 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2189 2190 /* Place your code here */ 2191 2192 PHYMOD_IF_ERR_RETURN 2193 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2194 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2195 phy_copy.access.lane_mask = 0x1 << start_lane; 2196 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2197 2198 PHYMOD_IF_ERR_RETURN 2199 (tefmod_gen3_autoneg_ability_get(&phy_copy.access, &value)); 2200 an_ability_get_type->an_cl72 = value.an_cl72; 2201 2202 an_ability_get_type->an_fec = 0; 2203 if (value.an_fec == TEFMOD_FEC_NOT_SUPRTD) { 2204 2205 } else if (value.an_fec == TEFMOD_FEC_SUPRTD_NOT_REQSTD) { 2206 PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec); 2207 } else { 2208 if (value.an_fec & TEFMOD_FEC_CL74_SUPRTD_REQSTD) { 2209 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2210 } 2211 if (value.an_fec & TEFMOD_FEC_CL91_SUPRTD_REQSTD) { 2212 PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec); 2213 } 2214 } 2215 2216 if (value.an_pause == TEFMOD_ASYM_PAUSE) { 2217 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2218 } else if (value.an_pause == TEFMOD_SYMM_PAUSE) { 2219 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2220 } else if (value.an_pause == TEFMOD_ASYM_SYMM_PAUSE) { 2221 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2222 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2223 } 2224 2225 /* first check cl73 base ability */ 2226 if (value.an_base_speed & 1 << TEFMOD_CL73_100GBASE_CR4) { 2227 PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap); 2228 } 2229 if (value.an_base_speed & 1 << TEFMOD_CL73_100GBASE_KR4) { 2230 PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap); 2231 } 2232 if (value.an_base_speed & 1 << TEFMOD_CL73_40GBASE_CR4) { 2233 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 2234 } 2235 if (value.an_base_speed & 1 << TEFMOD_CL73_40GBASE_KR4) { 2236 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 2237 } 2238 if (value.an_base_speed & 1 << TEFMOD_CL73_10GBASE_KR1) { 2239 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 2240 } 2241 if (value.an_base_speed & 1 << TEFMOD_CL73_1GBASE_KX) { 2242 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 2243 } 2244 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_KR1) { 2245 PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap); 2246 } 2247 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_CR1) { 2248 PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap); 2249 } 2250 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_KRS1) { 2251 PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap); 2252 } 2253 if (value.an_base_speed & 1 << TEFMOD_CL73_25GBASE_CRS1) { 2254 PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap); 2255 } 2256 if (value.an_base_speed & 1 << TEFMOD_CL73_2P5GBASE_KX1) { 2257 PHYMOD_AN_CAP_2P5G_X_SET(an_ability_get_type->an_cap); 2258 } 2259 if (value.an_base_speed & 1 << TEFMOD_CL73_5GBASE_KR1) { 2260 PHYMOD_AN_CAP_5G_KR1_SET(an_ability_get_type->an_cap); 2261 } 2262 2263 /* next check cl73 bam ability */ 2264 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_20GBASE_KR2){ 2265 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap); 2266 } 2267 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_20GBASE_CR2){ 2268 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap); 2269 } 2270 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_40GBASE_KR2){ 2271 PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap); 2272 } 2273 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_40GBASE_CR2){ 2274 PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap); 2275 } 2276 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_KR2){ 2277 PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap); 2278 } 2279 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_CR2){ 2280 PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap); 2281 } 2282 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_KR4){ 2283 PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap); 2284 } 2285 if (value.an_bam_speed & 1 << TEFMOD_CL73_BAM_50GBASE_CR4){ 2286 PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap); 2287 } 2288 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_20GBASE_KR1){ 2289 PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap); 2290 } 2291 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_20GBASE_CR1){ 2292 PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap); 2293 } 2294 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_25GBASE_KR1){ 2295 PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap); 2296 } 2297 if (value.an_bam_speed1 & 1 << TEFMOD_CL73_BAM_25GBASE_CR1) { 2298 PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap); 2299 } 2300 2301 return PHYMOD_E_NONE; 2302 } 2303 2304 int tscf_gen3_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 2305 { 2306 2307 uint16_t baseP0, baseP1, baseP2, nextP3, nextP4; 2308 int an_fec; 2309 2310 PHYMOD_IF_ERR_RETURN 2311 (tefmod_gen3_autoneg_lp_status_get(&phy->access, &baseP0, &baseP1, &baseP2, &nextP3, &nextP4)); 2312 2313 if((baseP1 >> 5) & 1) { /* D0 */ 2314 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 2315 } 2316 if((baseP1 >> 7) & 1) { /* D2 */ 2317 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 2318 } 2319 if((baseP1 >> 8) & 1) { /* D3 */ 2320 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 2321 } 2322 if((baseP1 >> 9) & 1) { /* D4 */ 2323 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 2324 } 2325 if((baseP1 >> 12) & 1) { /* D7 */ 2326 PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap); 2327 } 2328 if((baseP1 >> 13) & 1) { /* D8 */ 2329 PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap); 2330 } 2331 2332 if((baseP1 >> 14) & 1) { 2333 PHYMOD_AN_CAP_25G_KRS1_SET(an_ability_get_type->an_cap); 2334 PHYMOD_AN_CAP_25G_CRS1_SET(an_ability_get_type->an_cap); 2335 } 2336 if((baseP1 >> 15) & 1) { 2337 PHYMOD_AN_CAP_25G_KR1_SET(an_ability_get_type->an_cap); 2338 PHYMOD_AN_CAP_25G_CR1_SET(an_ability_get_type->an_cap); 2339 } 2340 2341 an_fec = (baseP2 >> 14) & 3; /* D47:D46 */ 2342 2343 an_ability_get_type->an_fec = 0; 2344 if (an_fec == 0x0) { 2345 2346 } else if (an_fec == 0x1) { 2347 PHYMOD_AN_FEC_OFF_SET(an_ability_get_type->an_fec); 2348 } else { 2349 if (an_fec == 0x3) { 2350 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2351 } 2352 } 2353 2354 an_fec = (baseP2 >> 12) & 3; /* D45:D44 */ 2355 if (an_fec & 0x1) { 2356 PHYMOD_AN_FEC_CL91_SET(an_ability_get_type->an_fec); 2357 } 2358 if (an_fec & 0x2) { 2359 PHYMOD_AN_FEC_CL74_SET(an_ability_get_type->an_fec); 2360 } 2361 2362 if((baseP0 >> 10) & 1) { /* C0 */ 2363 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 2364 } 2365 if((baseP0 >> 11) & 1) { /* C1 */ 2366 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 2367 } 2368 2369 if((nextP3 >> 0) & 1) { 2370 PHYMOD_BAM_CL73_CAP_20G_KR2_SET(an_ability_get_type->cl73bam_cap); 2371 } 2372 if((nextP3 >> 1) & 1) { 2373 PHYMOD_BAM_CL73_CAP_20G_CR2_SET(an_ability_get_type->cl73bam_cap); 2374 } 2375 if((nextP3 >> 2) & 1) { 2376 PHYMOD_BAM_CL73_CAP_20G_KR1_SET(an_ability_get_type->cl73bam_cap); 2377 } 2378 if((nextP3 >> 3) & 1) { 2379 PHYMOD_BAM_CL73_CAP_20G_CR1_SET(an_ability_get_type->cl73bam_cap); 2380 } 2381 if((nextP3 >> 4) & 1) { 2382 PHYMOD_BAM_CL73_CAP_25G_KR1_SET(an_ability_get_type->cl73bam_cap); 2383 } 2384 if((nextP3 >> 5) & 1) { 2385 PHYMOD_BAM_CL73_CAP_25G_CR1_SET(an_ability_get_type->cl73bam_cap); 2386 } 2387 if((nextP3 >> 6) & 1) { 2388 PHYMOD_BAM_CL73_CAP_40G_KR2_SET(an_ability_get_type->cl73bam_cap); 2389 } 2390 if((nextP3 >> 7) & 1) { 2391 PHYMOD_BAM_CL73_CAP_40G_CR2_SET(an_ability_get_type->cl73bam_cap); 2392 } 2393 if((nextP3 >> 8) & 1) { 2394 PHYMOD_BAM_CL73_CAP_50G_KR2_SET(an_ability_get_type->cl73bam_cap); 2395 } 2396 if((nextP3 >> 9) & 1) { 2397 PHYMOD_BAM_CL73_CAP_50G_CR2_SET(an_ability_get_type->cl73bam_cap); 2398 } 2399 if((nextP4 >> 0) & 1) { 2400 PHYMOD_BAM_CL73_CAP_50G_KR4_SET(an_ability_get_type->cl73bam_cap); 2401 } 2402 if((nextP4 >> 1) & 1) { 2403 PHYMOD_BAM_CL73_CAP_50G_CR4_SET(an_ability_get_type->cl73bam_cap); 2404 } 2405 2406 return PHYMOD_E_NONE; 2407 } 2408 2409 int tscf_gen3_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 2410 { 2411 int num_lane_adv_encoded; 2412 int start_lane, num_lane; 2413 int i, an_enable_bitmap, single_port_mode = 0; 2414 int do_lane_config_set, do_core_config_set; 2415 phymod_firmware_lane_config_t firmware_lane_config; 2416 phymod_firmware_core_config_t firmware_core_config_tmp; 2417 tefmod_gen3_an_control_t an_control; 2418 phymod_phy_access_t phy_copy; 2419 tefmod_gen3_an_adv_ability_t value; 2420 2421 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 2422 PHYMOD_MEMSET(&firmware_core_config_tmp, 0x0, sizeof(firmware_core_config_tmp)); 2423 2424 PHYMOD_MEMSET(&an_control, 0x0, sizeof(an_control)); 2425 PHYMOD_MEMSET(&value, 0x0, sizeof(value)); 2426 2427 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2428 PHYMOD_IF_ERR_RETURN 2429 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2430 PHYMOD_IF_ERR_RETURN 2431 (tefmod_gen3_autoneg_ability_get(&phy->access, &value)); 2432 2433 if (value.an_hg2){ 2434 single_port_mode = 1; 2435 } 2436 2437 switch (an->num_lane_adv) { 2438 case 1: 2439 num_lane_adv_encoded = 0; 2440 break; 2441 case 2: 2442 num_lane_adv_encoded = 1; 2443 break; 2444 case 4: 2445 num_lane_adv_encoded = 2; 2446 break; 2447 case 10: 2448 num_lane_adv_encoded = 3; 2449 break; 2450 default: 2451 return PHYMOD_E_PARAM; 2452 } 2453 2454 /* Check if cl72 is allowed to change */ 2455 if (PHYMOD_AN_F_ALLOW_CL72_CONFIG_CHANGE_GET(an)) { 2456 an_control.cl72_config_allowed = 1; 2457 } else { 2458 an_control.cl72_config_allowed = 0; 2459 } 2460 2461 if(PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_GET(an)) { 2462 an_control.pd_kx_en = 1; 2463 } else { 2464 an_control.pd_kx_en = 0; 2465 } 2466 if(PHYMOD_AN_F_SET_CL73_PDET_2P5G_KX_ENABLE_GET(an)) { 2467 an_control.pd_2P5G_kx_en = 1; 2468 } else { 2469 an_control.pd_2P5G_kx_en = 0; 2470 } 2471 2472 an_control.num_lane_adv = num_lane_adv_encoded; 2473 an_control.enable = an->enable; 2474 an_control.an_property_type = 0x0; /* for now disable */ 2475 switch (an->an_mode) { 2476 case phymod_AN_MODE_CL73: 2477 an_control.an_type = TEFMOD_AN_MODE_CL73; 2478 break; 2479 case phymod_AN_MODE_CL73BAM: 2480 an_control.an_type = TEFMOD_AN_MODE_CL73BAM; 2481 break; 2482 case phymod_AN_MODE_MSA: 2483 an_control.an_type = TEFMOD_AN_MODE_MSA; 2484 break; 2485 case phymod_AN_MODE_CL73_MSA: 2486 an_control.an_type = TEFMOD_AN_MODE_CL73_MSA; 2487 break; 2488 case phymod_AN_MODE_HPAM: 2489 an_control.an_type = TEFMOD_AN_MODE_HPAM; 2490 break; 2491 default: 2492 an_control.an_type = TEFMOD_AN_MODE_CL73; 2493 break; 2494 } 2495 2496 PHYMOD_IF_ERR_RETURN(tefmod_gen3_disable_set(&phy->access)); 2497 2498 if (single_port_mode) { 2499 PHYMOD_IF_ERR_RETURN 2500 (tefmod_gen3_set_an_single_port_mode(&phy->access, an->enable)); 2501 } 2502 2503 if(an->enable) { 2504 PHYMOD_IF_ERR_RETURN(tefmod_gen3_set_an_port_mode(&phy->access, num_lane, start_lane)); 2505 } 2506 2507 /* Check if any other lane has An on */ 2508 an_enable_bitmap = 0; 2509 phy_copy.access.lane_mask = 0x1 << start_lane; 2510 if (!an->enable) { 2511 for (i = 0; i < 4; i++ ) { 2512 phy_copy.access.lane_mask = 0x1 << i; 2513 if (phy_copy.access.lane_mask & phy->access.lane_mask) continue; 2514 PHYMOD_IF_ERR_RETURN 2515 (tscf_gen3_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 2516 if (firmware_lane_config.AnEnabled) { 2517 an_enable_bitmap |= 1 << i; 2518 } 2519 } 2520 2521 } 2522 2523 phy_copy.access.lane_mask = 0x1 << start_lane; 2524 2525 /* make sure the firmware config is set to an eenabled */ 2526 PHYMOD_IF_ERR_RETURN 2527 (tscf_gen3_phy_firmware_lane_config_get(&phy_copy, &firmware_lane_config)); 2528 /* make sure the firmware config is set to an eenabled */ 2529 PHYMOD_IF_ERR_RETURN 2530 (tscf_gen3_phy_firmware_core_config_get(&phy_copy, &firmware_core_config_tmp)); 2531 do_lane_config_set = 0; 2532 do_core_config_set = 0; 2533 2534 if (an->enable) { 2535 if(firmware_lane_config.AnEnabled != 1) { 2536 firmware_lane_config.AnEnabled = 1; 2537 do_lane_config_set = 1; 2538 } 2539 if(firmware_lane_config.LaneConfigFromPCS != 1) { 2540 firmware_lane_config.LaneConfigFromPCS = 1; 2541 do_lane_config_set = 1; 2542 } 2543 if(firmware_core_config_tmp.CoreConfigFromPCS != 1) { 2544 firmware_core_config_tmp.CoreConfigFromPCS = 1; 2545 do_core_config_set = 1; 2546 } 2547 firmware_lane_config.Cl72RestTO = 0; 2548 } else { 2549 if(firmware_lane_config.AnEnabled != 0) { 2550 firmware_lane_config.AnEnabled = 0; 2551 do_lane_config_set = 1; 2552 } 2553 if(firmware_lane_config.LaneConfigFromPCS != 0) { 2554 firmware_lane_config.LaneConfigFromPCS = 0; 2555 do_lane_config_set = 1; 2556 } 2557 if(firmware_core_config_tmp.CoreConfigFromPCS != 0) { 2558 if (!an_enable_bitmap) { 2559 firmware_core_config_tmp.CoreConfigFromPCS = 0; 2560 do_core_config_set = 1; 2561 } 2562 } 2563 firmware_lane_config.Cl72RestTO = 1; 2564 } 2565 2566 if(do_core_config_set && single_port_mode) { 2567 PHYMOD_IF_ERR_RETURN 2568 (falcon2_monterey_core_soft_reset_release(&phy_copy.access, 0)); 2569 PHYMOD_USLEEP(1000); 2570 2571 PHYMOD_IF_ERR_RETURN 2572 (tscf_gen3_phy_firmware_core_config_set(&phy_copy, firmware_core_config_tmp)); 2573 2574 PHYMOD_IF_ERR_RETURN 2575 (falcon2_monterey_core_soft_reset_release(&phy_copy.access, 1)); 2576 } 2577 2578 if(do_lane_config_set) { 2579 for (i = 0; i < num_lane; i++) { 2580 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2581 continue; 2582 } 2583 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2584 PHYMOD_IF_ERR_RETURN 2585 (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 0)); 2586 } 2587 2588 PHYMOD_USLEEP(1000); 2589 for (i = 0; i < num_lane; i++) { 2590 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2591 continue; 2592 } 2593 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2594 PHYMOD_IF_ERR_RETURN 2595 (_tscf_gen3_phy_firmware_lane_config_set(&phy_copy, firmware_lane_config)); 2596 } 2597 for (i = 0; i < num_lane; i++) { 2598 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 2599 continue; 2600 } 2601 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2602 PHYMOD_IF_ERR_RETURN 2603 (falcon2_monterey_lane_soft_reset_release(&phy_copy.access, 1)); 2604 } 2605 } 2606 2607 phy_copy.access.lane_mask = 0x1 << start_lane; 2608 if(an->enable && single_port_mode) { 2609 PHYMOD_IF_ERR_RETURN 2610 (tefmod_gen3_master_port_num_set(&phy_copy.access, start_lane)); 2611 } 2612 PHYMOD_IF_ERR_RETURN 2613 (tefmod_gen3_autoneg_control(&phy_copy.access, &an_control)); 2614 2615 if (!an->enable) { 2616 PHYMOD_IF_ERR_RETURN(tefmod_gen3_enable_set(&phy->access)); 2617 } 2618 2619 return PHYMOD_E_NONE; 2620 } 2621 2622 int tscf_gen3_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 2623 { 2624 tefmod_gen3_an_control_t an_control; 2625 phymod_phy_access_t phy_copy; 2626 int start_lane, num_lane; 2627 int an_complete = 0; 2628 2629 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 2630 PHYMOD_IF_ERR_RETURN 2631 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 2632 phy_copy.access.lane_mask = 0x1 << start_lane; 2633 2634 PHYMOD_MEMSET(&an_control, 0x0, sizeof(tefmod_gen3_an_control_t)); 2635 PHYMOD_IF_ERR_RETURN 2636 (tefmod_gen3_autoneg_control_get(&phy_copy.access, &an_control, &an_complete)); 2637 2638 if (an_control.enable) { 2639 an->enable = 1; 2640 *an_done = an_complete; 2641 } else { 2642 an->enable = 0; 2643 } 2644 2645 if(an_control.pd_kx_en) { 2646 PHYMOD_AN_F_SET_CL73_PDET_KX_ENABLE_SET(an) ; 2647 } 2648 if(an_control.pd_2P5G_kx_en) { 2649 PHYMOD_AN_F_SET_CL73_PDET_2P5G_KX_ENABLE_SET(an) ; 2650 } 2651 2652 switch (an_control.an_type) { 2653 case TEFMOD_AN_MODE_CL73: 2654 an->an_mode = phymod_AN_MODE_CL73; 2655 break; 2656 case TEFMOD_AN_MODE_CL73BAM: 2657 an->an_mode = phymod_AN_MODE_CL73BAM; 2658 break; 2659 case TEFMOD_AN_MODE_MSA: 2660 an->an_mode = phymod_AN_MODE_MSA; 2661 break; 2662 case TEFMOD_AN_MODE_CL73_MSA: 2663 an->an_mode = phymod_AN_MODE_CL73_MSA; 2664 break; 2665 case TEFMOD_AN_MODE_HPAM: 2666 an->an_mode = phymod_AN_MODE_HPAM; 2667 break; 2668 default: 2669 an->an_mode = phymod_AN_MODE_NONE; 2670 break; 2671 } 2672 2673 return PHYMOD_E_NONE; 2674 } 2675 2676 int tscf_gen3_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 2677 { 2678 2679 int speed_id, an_en, an_done; 2680 phymod_phy_inf_config_t config; 2681 phymod_ref_clk_t ref_clock; 2682 const phymod_access_t *pm_acc = &phy->access; 2683 2684 PHYMOD_IF_ERR_RETURN 2685 (tefmod_gen3_autoneg_status_get(&phy->access, &an_en, &an_done)); 2686 2687 PHYMOD_IF_ERR_RETURN 2688 (tefmod_gen3_speed_id_get(&phy->access, &speed_id)); 2689 2690 PHYMOD_IF_ERR_RETURN 2691 (tefmod_gen3_refclk_get(pm_acc, &ref_clock)); 2692 2693 config.ref_clock = ref_clock; 2694 PHYMOD_IF_ERR_RETURN 2695 (_tscf_gen3_speed_id_interface_config_get(phy, speed_id, &config)); 2696 2697 status->enabled = an_en; 2698 status->locked = an_done; 2699 status->data_rate = config.data_rate; 2700 status->interface = config.interface_type; 2701 2702 return PHYMOD_E_NONE; 2703 } 2704 2705 /* Core initialization 2706 * 1. De-assert PMD core and PMD lane reset 2707 * 2. Set heartbeat for comclk 2708 * 3. Configure lane mapping 2709 * 4. Micro code load and verify 2710 * 4.1. Set uc_active = 1 2711 * 4.2. De-assert micro reset 2712 * 4.3. Poll for us_dsc_ready_for_cmd = 1 2713 * 5. Configure registers for each PLL core and power up each PLL 2714 * 6. Configure Core level micro RAM variables for each PLL core 2715 * 7. Release core DP soft (core_dp_s_rstb) reset for each PLL core 2716 */ 2717 STATIC 2718 int _tscf_gen3_core_init_pass1(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 2719 { 2720 int rv; 2721 int lane; 2722 phymod_phy_access_t phy_access; 2723 phymod_core_access_t core_copy; 2724 uint32_t uc_enable = 0; 2725 2726 TSCF_GEN3_CORE_TO_PHY_ACCESS(&phy_access, core); 2727 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 2728 core_copy.access.lane_mask = 0x1; 2729 2730 /* De-assert PMD core power and core data path reset */ 2731 PHYMOD_IF_ERR_RETURN 2732 (tefmod_gen3_pmd_reset_seq(&core_copy.access, core_status->pmd_active)); 2733 2734 /* Release lane reset */ 2735 for (lane = 0; lane < TSCF_GEN3_NOF_LANES_IN_CORE; lane++) { 2736 phy_access.access.lane_mask = 1 << lane; 2737 PHYMOD_IF_ERR_RETURN 2738 (tefmod_gen3_pmd_x4_reset(&phy_access.access)); 2739 } 2740 2741 PHYMOD_IF_ERR_RETURN 2742 (falcon2_monterey_uc_active_get(&phy_access.access, &uc_enable)); 2743 if (uc_enable) return PHYMOD_E_NONE; 2744 2745 /* Set the heart beat, based on clock src. */ 2746 PHYMOD_IF_ERR_RETURN 2747 (tefmod_gen3_refclk_set(&core_copy.access, init_config->interface.ref_clock)); 2748 2749 /* Configure lane mapping */ 2750 /* doing PMD lane swap */ 2751 PHYMOD_IF_ERR_RETURN 2752 (_tscf_gen3_core_lane_map_part_set(&core_copy, &init_config->lane_map, 0)); 2753 2754 /* Micro code load */ 2755 rv = _tscf_gen3_core_firmware_load(&core_copy, init_config->firmware_load_method, init_config->firmware_loader); 2756 if (rv != PHYMOD_E_NONE) { 2757 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask)); 2758 PHYMOD_IF_ERR_RETURN(rv); 2759 } 2760 2761 #ifndef TSCF_GEN3_PMD_CRC_UCODE_VERIFY 2762 if (init_config->firmware_load_method != phymodFirmwareLoadMethodNone) { 2763 int rv; 2764 /* Read-back uCode from Program RAM and verify against ucode_image */ 2765 rv = falcon2_monterey_ucode_load_verify(&core_copy.access, (uint8_t *) &falcon_dpll_ucode, falcon_dpll_ucode_len); 2766 if (rv != PHYMOD_E_NONE) { 2767 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 2768 PHYMOD_IF_ERR_RETURN(rv); 2769 } 2770 } 2771 #endif 2772 /* pmd lane hard reset */ 2773 PHYMOD_IF_ERR_RETURN 2774 (falcon2_monterey_pmd_ln_h_rstb_pkill_override(&core_copy.access, 0x1)); 2775 2776 /* Set uc_active = 1 */ 2777 PHYMOD_IF_ERR_RETURN 2778 (falcon2_monterey_uc_active_set(&core_copy.access, 1)); 2779 2780 /* De-assert micro reset */ 2781 PHYMOD_IF_ERR_RETURN 2782 (falcon2_monterey_uc_reset(&core_copy.access, 0)); 2783 2784 if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 2785 #ifdef TSCF_GEN3_PMD_CRC_UCODE_VERIFY 2786 PHYMOD_IF_ERR_RETURN( 2787 falcon2_monterey_start_ucode_crc_calc(&core_copy.access, falcon_dpll_ucode_len)); 2788 #endif 2789 } 2790 2791 return PHYMOD_E_NONE; 2792 } 2793 2794 STATIC 2795 int _tscf_gen3_core_init_pass2(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 2796 { 2797 phymod_phy_access_t phy_access, phy_access_copy; 2798 phymod_core_access_t core_copy; 2799 phymod_firmware_core_config_t firmware_core_config_tmp; 2800 uint32_t vco_rate; 2801 2802 TSCF_GEN3_CORE_TO_PHY_ACCESS(&phy_access, core); 2803 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 2804 core_copy.access.lane_mask = 0x1; 2805 2806 phy_access_copy = phy_access; 2807 phy_access_copy.access = core->access; 2808 phy_access_copy.access.lane_mask = 0x1; 2809 phy_access_copy.type = core->type; 2810 2811 /* doing PCS lane swap */ 2812 PHYMOD_IF_ERR_RETURN 2813 (_tscf_gen3_core_lane_map_part_set(&core_copy, &init_config->lane_map, 1)); 2814 if (PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 2815 #ifndef TSCF_GEN3_PMD_CRC_UCODE_VERIFY 2816 /* poll the ready bit */ 2817 PHYMOD_IF_ERR_RETURN( 2818 falcon2_monterey_poll_uc_dsc_ready_for_cmd_equals_1(&core_copy.access, 100)); 2819 #else 2820 PHYMOD_IF_ERR_RETURN( 2821 falcon2_monterey_check_ucode_crc(&core_copy.access, falcon_dpll_ucode_crc, 200)); 2822 #endif 2823 } 2824 2825 /* release pmd lane hard reset */ 2826 PHYMOD_IF_ERR_RETURN 2827 (falcon2_monterey_pmd_ln_h_rstb_pkill_override(&phy_access_copy.access, 0x0)); 2828 2829 PHYMOD_IF_ERR_RETURN 2830 (tefmod_gen3_autoneg_timer_init(&core_copy.access)); 2831 2832 PHYMOD_IF_ERR_RETURN 2833 (tefmod_gen3_master_port_num_set(&core_copy.access, 0)); 2834 2835 phy_access_copy.access.lane_mask = 0x1; 2836 /* Configure Core level RAM variables */ 2837 firmware_core_config_tmp = init_config->firmware_core_config; 2838 firmware_core_config_tmp.CoreConfigFromPCS = 0; 2839 /* set charge pump current */ 2840 if (init_config->afe_pll.afe_pll_change_default){ 2841 firmware_core_config_tmp.disable_write_pll_iqp = 1; 2842 } else { 2843 firmware_core_config_tmp.disable_write_pll_iqp = 0; 2844 } 2845 2846 /* reset core DP */ 2847 /* Only PLL1 is used for Eth port in mixed mode */ 2848 if (init_config->pll0_div_init_value){ 2849 core_copy.access.pll_idx = 0; 2850 PHYMOD_IF_ERR_RETURN 2851 (falcon2_monterey_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 2852 PHYMOD_IF_ERR_RETURN 2853 (falcon2_monterey_core_soft_reset_release(&core_copy.access, 0)); 2854 } 2855 2856 core_copy.access.pll_idx = 1; 2857 PHYMOD_IF_ERR_RETURN 2858 (falcon2_monterey_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 2859 PHYMOD_IF_ERR_RETURN 2860 (falcon2_monterey_core_soft_reset_release(&core_copy.access, 0)); 2861 2862 /* PLL0 config */ 2863 /* Skip to program PLL0, Only PLL1 is used for Eth port in mixed mode */ 2864 if (init_config->pll0_div_init_value){ 2865 phy_access_copy.access.pll_idx = 0; 2866 PHYMOD_IF_ERR_RETURN 2867 (tefmod_gen3_configure_pll(&phy_access_copy.access, init_config->pll0_div_init_value, init_config->interface.ref_clock)); 2868 /* Get Core config variable VcoRate */ 2869 PHYMOD_IF_ERR_RETURN 2870 (tefmod_gen3_pll_to_vco_rate(&phy_access_copy.access, init_config->pll0_div_init_value, init_config->interface.ref_clock, &vco_rate)); 2871 firmware_core_config_tmp.VcoRate = MHZ_TO_VCO_RATE(vco_rate); 2872 /* Configure Core level RAM variables */ 2873 PHYMOD_IF_ERR_RETURN 2874 (tscf_gen3_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 2875 } 2876 2877 /* PLL1 config */ 2878 phy_access_copy.access.pll_idx = 1; 2879 PHYMOD_IF_ERR_RETURN 2880 (tefmod_gen3_configure_pll(&phy_access_copy.access, init_config->pll1_div_init_value, init_config->interface.ref_clock)); 2881 /* Get Core config variable VcoRate */ 2882 PHYMOD_IF_ERR_RETURN 2883 (tefmod_gen3_pll_to_vco_rate(&phy_access_copy.access, init_config->pll1_div_init_value, init_config->interface.ref_clock, &vco_rate)); 2884 firmware_core_config_tmp.VcoRate = MHZ_TO_VCO_RATE(vco_rate); 2885 /* Configure Core level RAM variables */ 2886 PHYMOD_IF_ERR_RETURN 2887 (tscf_gen3_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 2888 2889 PHYMOD_IF_ERR_RETURN 2890 (tefmod_gen3_cl74_chng_default (&core_copy.access)); 2891 2892 PHYMOD_IF_ERR_RETURN 2893 (tefmod_gen3_cl91_ecc_clear(&core_copy.access)); 2894 2895 /* Release core DP soft reset */ 2896 if (init_config->pll0_div_init_value){ 2897 core_copy.access.pll_idx = 0; 2898 PHYMOD_IF_ERR_RETURN 2899 (falcon2_monterey_core_soft_reset_release(&core_copy.access, 1)); 2900 } 2901 2902 core_copy.access.pll_idx = 1; 2903 PHYMOD_IF_ERR_RETURN 2904 (falcon2_monterey_core_soft_reset_release(&core_copy.access, 1)); 2905 2906 return PHYMOD_E_NONE; 2907 } 2908 2909 2910 int tscf_gen3_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 2911 { 2912 2913 if ((!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) && 2914 !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) || 2915 PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) { 2916 PHYMOD_IF_ERR_RETURN 2917 (_tscf_gen3_core_init_pass1(core, init_config, core_status)); 2918 2919 if (PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) { 2920 return PHYMOD_E_NONE; 2921 } 2922 } 2923 2924 if ( (!PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config) && 2925 !PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) || 2926 PHYMOD_CORE_INIT_F_EXECUTE_PASS2_GET(init_config)) { 2927 PHYMOD_IF_ERR_RETURN 2928 (_tscf_gen3_core_init_pass2(core, init_config, core_status)); 2929 } 2930 2931 return PHYMOD_E_NONE; 2932 } 2933 2934 2935 int tscf_gen3_phy_pll_multiplier_get(const phymod_phy_access_t* phy, uint32_t* pll_multiplier) 2936 { 2937 return PHYMOD_E_NONE; 2938 } 2939 2940 int tscf_gen3_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 2941 { 2942 const phymod_access_t *pm_acc = &phy->access; 2943 phymod_phy_access_t pm_phy_copy; 2944 int start_lane, num_lane, i; 2945 /*int lane_bkup; */ 2946 phymod_polarity_t tmp_pol; 2947 phymod_firmware_lane_config_t firmware_lane_config; 2948 2949 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 2950 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 2951 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 2952 2953 PHYMOD_IF_ERR_RETURN 2954 (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane)); 2955 2956 /* De-assert PMD lane reset */ 2957 PHYMOD_IF_ERR_RETURN 2958 (tefmod_gen3_pmd_x4_reset(pm_acc)); 2959 #if 0 2960 lane_bkup = pm_phy_copy.access.lane_mask; 2961 for (i = 0; i < num_lane; i++) { 2962 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 2963 PHYMOD_IF_ERR_RETURN 2964 (falcon2_monterey_lane_soft_reset_release(&pm_phy_copy.access, 1)); 2965 } 2966 pm_phy_copy.access.lane_mask = lane_bkup; 2967 #endif 2968 /* Clear all the lane config */ 2969 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 2970 2971 /* Program the rx/tx polarity */ 2972 for (i = 0; i < num_lane; i++) { 2973 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2974 tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> i & 0x1; 2975 tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> i & 0x1; 2976 PHYMOD_IF_ERR_RETURN 2977 (tscf_gen3_phy_polarity_set(&pm_phy_copy, &tmp_pol)); 2978 } 2979 for (i = 0; i < num_lane; i++) { 2980 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2981 /* set tx parameters */ 2982 PHYMOD_IF_ERR_RETURN 2983 (tscf_gen3_phy_tx_set(&pm_phy_copy, &init_config->tx[i])); 2984 } 2985 2986 for (i = 0; i < num_lane; i++) { 2987 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 2988 PHYMOD_IF_ERR_RETURN 2989 (_tscf_gen3_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 2990 } 2991 #if 0 2992 /* Next check if pcs-bypass mode */ 2993 if (PHYMOD_DEVICE_OP_MODE_PCS_BYPASS_GET(phy->device_op_mode)) { 2994 PHYMOD_IF_ERR_RETURN 2995 (falcon2_monterey_pmd_tx_disable_pin_dis_set(&phy->access, 1)); 2996 PHYMOD_IF_ERR_RETURN 2997 (tefmod_gen3_init_pcs_ilkn(&phy->access)); 2998 } 2999 #endif 3000 3001 PHYMOD_IF_ERR_RETURN 3002 (tefmod_gen3_port_mode_select(pm_acc)); 3003 3004 PHYMOD_IF_ERR_RETURN 3005 (tefmod_gen3_rx_lane_control_set(pm_acc, 1)); 3006 PHYMOD_IF_ERR_RETURN 3007 (tefmod_gen3_tx_lane_control_set(pm_acc, TEFMOD_TX_LANE_RESET_TRAFFIC_ENABLE)); 3008 3009 PHYMOD_IF_ERR_RETURN 3010 (tefmod_gen3_25g_rsfec_am_init(pm_acc)); 3011 3012 return PHYMOD_E_NONE; 3013 } 3014 3015 3016 int tscf_gen3_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 3017 { 3018 int i; 3019 int start_lane, num_lane; 3020 uint32_t cl72_en = 0; 3021 phymod_phy_access_t phy_copy; 3022 3023 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3024 3025 /* Next figure out the lane num and start_lane based on the input */ 3026 PHYMOD_IF_ERR_RETURN 3027 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3028 3029 switch (loopback) { 3030 case phymodLoopbackGlobal : 3031 PHYMOD_IF_ERR_RETURN 3032 (tscf_gen3_phy_cl72_get(phy, &cl72_en)); 3033 if (cl72_en == 1) { 3034 PHYMOD_DEBUG_ERROR(("adr=%0x,lane 0x%x: Error! pcs gloop not supported with cl72 enabled\n", phy_copy.access.addr, start_lane)); 3035 break; 3036 } 3037 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_loopback_control(&phy->access, enable, start_lane, num_lane)); 3038 break; 3039 3040 case phymodLoopbackGlobalPMD : 3041 PHYMOD_IF_ERR_RETURN 3042 (tscf_gen3_phy_cl72_get(phy, &cl72_en)); 3043 if (cl72_en == 1) { 3044 PHYMOD_DEBUG_ERROR(("adr=%0x,lane 0x%x: Error! pmd gloop not supported with cl72 enabled\n", phy_copy.access.addr, start_lane)); 3045 break; 3046 } 3047 for (i = 0; i < num_lane; i++) { 3048 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 3049 PHYMOD_IF_ERR_RETURN(falcon2_monterey_dig_lpbk(&phy_copy.access, (uint8_t) enable)); 3050 PHYMOD_IF_ERR_RETURN(falcon2_monterey_pmd_force_signal_detect(&phy_copy.access, (int) enable)); 3051 PHYMOD_IF_ERR_RETURN(tefmod_gen3_rx_lane_control_set(&phy->access, 1)); 3052 } 3053 break; 3054 case phymodLoopbackRemotePMD : 3055 PHYMOD_IF_ERR_RETURN(falcon2_monterey_rmt_lpbk(&phy->access, (uint8_t)enable)); 3056 break; 3057 3058 case phymodLoopbackRemotePCS : 3059 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 3060 (_PHYMOD_MSG("PCS Remote LoopBack not supported"))); 3061 break; 3062 default : 3063 break; 3064 } 3065 3066 return PHYMOD_E_NONE; 3067 } 3068 3069 int tscf_gen3_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 3070 { 3071 uint32_t enable_core; 3072 int start_lane, num_lane; 3073 3074 *enable = 0; 3075 3076 /* next figure out the lane num and start_lane based on the input */ 3077 PHYMOD_IF_ERR_RETURN 3078 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3079 3080 switch (loopback) { 3081 case phymodLoopbackGlobal : 3082 PHYMOD_IF_ERR_RETURN(tefmod_gen3_tx_loopback_get(&phy->access, &enable_core)); 3083 *enable = (enable_core >> start_lane) & 0x1; 3084 break; 3085 3086 case phymodLoopbackGlobalPMD : 3087 PHYMOD_IF_ERR_RETURN(falcon2_monterey_tsc_dig_lpbk_get(&phy->access, enable)); 3088 break; 3089 case phymodLoopbackRemotePMD : 3090 PHYMOD_IF_ERR_RETURN(falcon2_monterey_tsc_rmt_lpbk_get(&phy->access, enable)); 3091 break; 3092 3093 case phymodLoopbackRemotePCS : 3094 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 3095 (_PHYMOD_MSG("PCS Remote LoopBack not supported"))); 3096 break; 3097 default : 3098 break; 3099 } 3100 3101 return PHYMOD_E_NONE; 3102 } 3103 3104 3105 int tscf_gen3_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked) 3106 { 3107 PHYMOD_IF_ERR_RETURN(tefmod_gen3_pmd_lock_get(&phy->access, rx_pmd_locked)); 3108 3109 return PHYMOD_E_NONE; 3110 } 3111 3112 int tscf_gen3_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* value) 3113 { 3114 uint32_t local_rx_signal_det; 3115 int start_lane, num_lane, i; 3116 *value = 1; 3117 3118 PHYMOD_IF_ERR_RETURN 3119 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3120 3121 for (i = 0; i < num_lane; i++) { 3122 if (!PHYMOD_LANEPBMP_MEMBER(phy->access.lane_mask, start_lane + i)) { 3123 continue; 3124 } 3125 PHYMOD_IF_ERR_RETURN 3126 (falcon2_monterey_tsc_signal_detect(&phy->access, &local_rx_signal_det)); 3127 *value = *value & local_rx_signal_det; 3128 } 3129 3130 return PHYMOD_E_NONE; 3131 } 3132 3133 int tscf_gen3_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 3134 { 3135 PHYMOD_IF_ERR_RETURN(tefmod_gen3_get_pcs_latched_link_status(&phy->access, link_status)); 3136 3137 return PHYMOD_E_NONE; 3138 } 3139 3140 3141 int tscf_gen3_phy_pcs_userspeed_set(const phymod_phy_access_t* phy, const phymod_pcs_userspeed_config_t* config) 3142 { 3143 return PHYMOD_E_UNAVAIL; 3144 } 3145 3146 int tscf_gen3_phy_pcs_userspeed_get(const phymod_phy_access_t* phy, phymod_pcs_userspeed_config_t* config) 3147 { 3148 return PHYMOD_E_UNAVAIL; 3149 } 3150 3151 3152 int tscf_gen3_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val) 3153 { 3154 phymod_phy_access_t phy_copy; 3155 3156 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3157 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val)); 3158 3159 return PHYMOD_E_NONE; 3160 } 3161 3162 3163 int tscf_gen3_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 3164 { 3165 phymod_phy_access_t phy_copy; 3166 3167 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3168 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val)); 3169 3170 return PHYMOD_E_NONE; 3171 } 3172 3173 3174 int tscf_gen3_phy_eye_margin_est_get(const phymod_phy_access_t* phy, phymod_eye_margin_mode_t eye_margin_mode, uint32_t* value) 3175 { 3176 3177 return PHYMOD_E_NONE; 3178 3179 } 3180 3181 3182 int tscf_gen3_phy_rescal_set(const phymod_phy_access_t* phy, uint32_t enable, uint32_t value) 3183 { 3184 PHYMOD_IF_ERR_RETURN(falcon2_monterey_rescal_val_set(&phy->access, enable, value)); 3185 3186 return PHYMOD_E_NONE; 3187 } 3188 3189 int tscf_gen3_phy_rescal_get(const phymod_phy_access_t* phy, uint32_t* value) 3190 { 3191 PHYMOD_IF_ERR_RETURN(falcon2_monterey_rescal_val_get(&phy->access, value)); 3192 3193 return PHYMOD_E_NONE; 3194 } 3195 3196 /* Enable 1588 timestamping of packets within the TXP and RXP pipelines */ 3197 int tscf_gen3_timesync_enable_set(const phymod_phy_access_t* phy, uint32_t flags, uint32_t enable) 3198 { 3199 phymod_phy_access_t phy_copy; 3200 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3201 3202 PHYMOD_IF_ERR_RETURN 3203 (tefmod_gen3_1588_ts_enable_set(&phy_copy.access, enable)); 3204 3205 return PHYMOD_E_NONE; 3206 3207 } 3208 3209 int tscf_gen3_timesync_enable_get(const phymod_phy_access_t* phy, uint32_t flags, uint32_t* enable) 3210 { 3211 phymod_phy_access_t phy_copy; 3212 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3213 3214 PHYMOD_IF_ERR_RETURN 3215 (tefmod_gen3_1588_ts_enable_get(&phy_copy.access, enable)); 3216 3217 return PHYMOD_E_NONE; 3218 } 3219 3220 /* Set timesync offset */ 3221 int tscf_gen3_timesync_offset_set(const phymod_core_access_t* core, uint32_t ts_offset) 3222 { 3223 phymod_core_access_t core_copy; 3224 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 3225 3226 PHYMOD_IF_ERR_RETURN 3227 (tefmod_gen3_1588_ts_offset_set(&core_copy.access, ts_offset)); 3228 3229 3230 return PHYMOD_E_NONE; 3231 } 3232 3233 3234 int tscf_gen3_timesync_adjust_set(const phymod_phy_access_t* phy, uint32_t ts_am_norm_mode) 3235 { 3236 phymod_phy_access_t phy_copy; 3237 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3238 3239 /* Set sfd_ts_en, crc_calc_mode, cl36_sop_adjust*/ 3240 PHYMOD_IF_ERR_RETURN 3241 (tefmod_gen3_1588_pcs_control_set(&phy_copy.access)); 3242 3243 /* Set 1588 FCLK period */ 3244 PHYMOD_IF_ERR_RETURN 3245 (tefmod_gen3_1588_fclk_set(&phy_copy.access)); 3246 3247 /* Set ui values */ 3248 PHYMOD_IF_ERR_RETURN 3249 (tefmod_gen3_1588_ui_values_set(&phy_copy.access)); 3250 3251 /*Set RX/TX pmd fixed latency */ 3252 PHYMOD_IF_ERR_RETURN 3253 (tefmod_gen3_1588_txrx_fixed_latency_set(&phy_copy.access)); 3254 3255 /* Program deskew adjustment for multi-lane ports */ 3256 if (ts_am_norm_mode != phymodTimesyncCompensationModeNone) { 3257 PHYMOD_IF_ERR_RETURN 3258 (tefmod_gen3_1588_rx_deskew_set(&phy_copy.access, ts_am_norm_mode)); 3259 } 3260 3261 return PHYMOD_E_NONE; 3262 } 3263 3264 int tscf_gen3_timesync_tx_info_get(const phymod_phy_access_t* phy, phymod_ts_fifo_status_t* ts_tx_info) 3265 { 3266 phymod_phy_access_t phy_copy; 3267 tefmod_gen3_ts_tx_info_t local_ts_tx_info; 3268 3269 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3270 PHYMOD_MEMSET(&local_ts_tx_info, 0, sizeof(tefmod_gen3_ts_tx_info_t)); 3271 3272 PHYMOD_IF_ERR_RETURN(tefmod_gen3_1588_tx_info_get(&phy_copy.access, &local_ts_tx_info)); 3273 3274 ts_tx_info->ts_in_fifo_lo = ((uint32_t)(local_ts_tx_info.ts_val_hi << 16)) | ((uint32_t)local_ts_tx_info.ts_val_lo); 3275 ts_tx_info->ts_in_fifo_hi = 0; 3276 ts_tx_info->ts_seq_id = (uint32_t)local_ts_tx_info.ts_seq_id; 3277 ts_tx_info->ts_sub_nanosec = (uint32_t)local_ts_tx_info.ts_sub_nanosec; 3278 3279 return PHYMOD_E_NONE; 3280 } 3281 3282 int tscf_gen3_phy_rx_ppm_get(const phymod_phy_access_t* phy, int16_t* rx_ppm) 3283 { 3284 int start_lane, num_lane; 3285 phymod_phy_access_t pm_phy_copy; 3286 3287 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 3288 3289 PHYMOD_IF_ERR_RETURN 3290 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3291 3292 pm_phy_copy.access.lane_mask = 1 << start_lane; 3293 PHYMOD_IF_ERR_RETURN 3294 (falcon2_monterey_tsc_rx_ppm(&pm_phy_copy.access, rx_ppm)); 3295 3296 return PHYMOD_E_NONE; 3297 } 3298 3299 int tscf_gen3_phy_synce_clk_ctrl_set(const phymod_phy_access_t* phy, 3300 phymod_synce_clk_ctrl_t cfg) 3301 { 3302 phymod_phy_access_t phy_copy; 3303 int start_lane, num_lane; 3304 3305 PHYMOD_IF_ERR_RETURN 3306 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 3307 3308 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 3309 phy_copy.access.lane_mask = 0x1 << start_lane; 3310 3311 PHYMOD_IF_ERR_RETURN 3312 (tefmod_gen3_synce_stg0_mode_set(&phy_copy.access, cfg.stg0_mode)); 3313 3314 PHYMOD_IF_ERR_RETURN 3315 (tefmod_gen3_synce_stg1_mode_set(&phy_copy.access, cfg.stg1_mode)); 3316 3317 PHYMOD_IF_ERR_RETURN 3318 (tefmod_gen3_synce_clk_ctrl_set(&phy_copy.access, cfg.sdm_val)); 3319 3320 return PHYMOD_E_NONE; 3321 } 3322 3323 int tscf_gen3_phy_synce_clk_ctrl_get(const phymod_phy_access_t* phy, 3324 phymod_synce_clk_ctrl_t *cfg) 3325 { 3326 PHYMOD_IF_ERR_RETURN 3327 (tefmod_gen3_synce_stg0_mode_get(&phy->access, &(cfg->stg0_mode))); 3328 3329 PHYMOD_IF_ERR_RETURN 3330 (tefmod_gen3_synce_stg1_mode_get(&phy->access, &(cfg->stg1_mode))); 3331 3332 PHYMOD_IF_ERR_RETURN 3333 (tefmod_gen3_synce_clk_ctrl_get(&phy->access, &(cfg->sdm_val))); 3334 3335 return PHYMOD_E_NONE; 3336 } 3337