falcon16.c (45453B)
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_acc.h> 14 #include <phymod/phymod_dispatch.h> 15 #include <phymod/chip/bcmi_tscf_16nm_xgxs_defs.h> 16 17 #include "../tier1/src/falcon16_cfg_seq.h" 18 #include "../tier1/include/falcon16_tsc_enum.h" 19 #include "../tier1/include/falcon16_tsc_common.h" 20 #include "../tier1/include/falcon16_tsc_interface.h" 21 #include "../tier1/include/falcon16_tsc_dependencies.h" 22 23 #define FALCON16_ID0 0 24 #define FALCON16_ID1 0 25 #define FALCON16_MODEL 0x1b 26 #define TSCF16_PHY_ALL_LANES 0xf 27 #define FALCON16_PMD_CRC_UCODE 1 28 29 30 #define TSCF16_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 31 do{\ 32 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access, sizeof((_phy_access)->access));\ 33 (_phy_access)->type = (_core_access)->type; \ 34 (_phy_access)->port_loc = (_core_access)->port_loc; \ 35 (_phy_access)->device_op_mode = (_core_access)->device_op_mode; \ 36 (_phy_access)->access.lane_mask = TSCF16_PHY_ALL_LANES; \ 37 }while(0) 38 39 40 #define TSCF16_NOF_DFES 9 41 #define TSCF16_NOF_LANES_IN_CORE 4 42 extern unsigned char falcon16_ucode[]; 43 extern unsigned short falcon16_ucode_len; 44 extern unsigned short falcon16_ucode_crc; 45 46 47 int falcon16_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified) 48 { 49 const phymod_access_t *pm_acc = &core->access; 50 falcon16_rev_id0_t rev_id0; 51 falcon16_rev_id1_t rev_id1; 52 *is_identified = 0; 53 54 PHYMOD_IF_ERR_RETURN(falcon16_tsc_identify(pm_acc, &rev_id0, &rev_id1) ); 55 if (rev_id0.revid_model == FALCON16_MODEL){ 56 *is_identified = 1; 57 } 58 59 return PHYMOD_E_NONE; 60 } 61 62 63 int falcon16_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info) 64 { 65 info->core_version = phymodCoreVersionFalconA0; 66 info->serdes_id = 0; 67 info->phy_id0 = 0; 68 info->phy_id1 = 0; 69 70 return PHYMOD_E_NONE; 71 72 } 73 74 75 int falcon16_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map) 76 { 77 78 79 return PHYMOD_E_NONE; 80 81 } 82 83 int falcon16_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map) 84 { 85 #if 0 86 int lane; 87 uint32_t pmd_swap = 0; 88 89 PHYMOD_IF_ERR_RETURN(falcon16_pmd_lane_swap_tx_get(&core->access, &pmd_swap)); 90 for (lane = 0; lane < TSCF16_NOF_LANES_IN_CORE; lane++){ 91 lane_map->lane_map_tx[lane] = (pmd_swap >> (lane*4)) & 0x3; 92 lane_map->lane_map_rx[lane] = lane; 93 } 94 lane_map->num_of_lanes = TSCF16_NOF_LANES_IN_CORE; 95 #endif 96 return PHYMOD_E_NONE; 97 98 } 99 100 101 int falcon16_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction) 102 { 103 104 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_core_reset_set)\n")); 105 106 return PHYMOD_E_NONE; 107 108 } 109 110 int falcon16_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction) 111 { 112 113 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_core_reset_get)\n")); 114 115 return PHYMOD_E_NONE; 116 117 } 118 119 120 int falcon16_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 121 { 122 123 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_core_firmware_info_get)\n")); 124 125 return PHYMOD_E_NONE; 126 127 } 128 129 130 /* load tscf fw. the fw_loader parameter is valid just for external fw load*/ 131 STATIC 132 int _falcon16_core_firmware_load(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config) 133 { 134 int wait; 135 136 switch(init_config->firmware_load_method){ 137 case phymodFirmwareLoadMethodInternal: 138 PHYMOD_IF_ERR_RETURN(falcon16_tsc_ucode_mdio_load(&core->access, falcon16_ucode, falcon16_ucode_len)); 139 break; 140 case phymodFirmwareLoadMethodExternal: 141 if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 142 PHYMOD_NULL_CHECK(init_config->firmware_loader); 143 PHYMOD_IF_ERR_RETURN(falcon16_tsc_ucode_init(&core->access)); 144 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 145 wait = 0; 146 } else { 147 wait = 1; 148 } 149 PHYMOD_IF_ERR_RETURN(falcon16_pram_firmware_enable(&core->access, 1, wait)); 150 151 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 152 return PHYMOD_E_NONE; 153 } 154 155 PHYMOD_IF_ERR_RETURN(init_config->firmware_loader(core, falcon16_ucode_len, falcon16_ucode)); 156 } 157 PHYMOD_IF_ERR_RETURN(falcon16_pram_firmware_enable(&core->access, 0, 0)); 158 break; 159 case phymodFirmwareLoadMethodNone: 160 break; 161 default: 162 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal fw load method %u"), init_config->firmware_load_method)); 163 } 164 165 if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone){ 166 /*PHYMOD_IF_ERR_RETURN(tscf16_core_firmware_info_get(core, &actual_fw)); 167 if((falcon16_ucode_crc != actual_fw.fw_crc) || (falcon16_ucode_ver != actual_fw.fw_version)){ 168 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("fw load validation was failed"))); 169 } */ 170 } 171 172 return PHYMOD_E_NONE; 173 } 174 175 176 int falcon16_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config) 177 { 178 struct falcon16_tsc_uc_core_config_st serdes_firmware_core_config; 179 uint32_t is_write_disabled; 180 181 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_write_disabled)); 182 if (is_write_disabled){ 183 return PHYMOD_E_NONE; 184 } 185 186 PHYMOD_MEMSET(&serdes_firmware_core_config, 0, sizeof(serdes_firmware_core_config)); 187 /* serdes_firmware_core_config.field.core_cfg_from_pcs = fw_core_config.CoreConfigFromPCS; 188 serdes_firmware_core_config.field.vco_rate = fw_core_config.VcoRate; 189 PHYMOD_IF_ERR_RETURN(falcon16_tsc_uc_core_config(&phy->access, serdes_firmware_core_config));*/ 190 PHYMOD_IF_ERR_RETURN(falcon16_tsc_set_core_config_from_pcs(&phy->access, fw_core_config.CoreConfigFromPCS)); 191 192 return PHYMOD_E_NONE; 193 194 } 195 196 int falcon16_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config) 197 { 198 struct falcon16_tsc_uc_core_config_st serdes_firmware_core_config; 199 PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_uc_core_config(&phy->access, &serdes_firmware_core_config)); 200 PHYMOD_MEMSET(fw_core_config, 0, sizeof(*fw_core_config)); 201 fw_core_config->CoreConfigFromPCS = serdes_firmware_core_config.field.core_cfg_from_pcs; 202 fw_core_config->VcoRate = serdes_firmware_core_config.field.vco_rate; 203 204 return PHYMOD_E_NONE; 205 206 } 207 208 209 int _falcon16_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 210 { 211 uint32_t is_warm_boot; 212 struct falcon16_tsc_uc_lane_config_st serdes_firmware_config; 213 214 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 215 serdes_firmware_config.field.lane_cfg_from_pcs = fw_config.LaneConfigFromPCS; 216 serdes_firmware_config.field.an_enabled = fw_config.AnEnabled; 217 serdes_firmware_config.field.dfe_on = fw_config.DfeOn; 218 serdes_firmware_config.field.force_brdfe_on = fw_config.ForceBrDfe; 219 /* serdes_firmware_config.field.cl72_emulation_en = fw_config.Cl72Enable; */ 220 serdes_firmware_config.field.scrambling_dis = fw_config.ScramblingDisable; 221 serdes_firmware_config.field.unreliable_los = fw_config.UnreliableLos; 222 serdes_firmware_config.field.media_type = fw_config.MediaType; 223 serdes_firmware_config.field.dfe_lp_mode = fw_config.LpDfeOn; 224 serdes_firmware_config.field.cl72_auto_polarity_en = fw_config.Cl72AutoPolEn; 225 serdes_firmware_config.field.cl72_restart_timeout_en = fw_config.Cl72RestTO; 226 227 PHYMOD_IF_ERR_RETURN(PHYMOD_IS_WRITE_DISABLED(&phy->access, &is_warm_boot)); 228 229 if(!is_warm_boot) { 230 PHYMOD_IF_ERR_RETURN(falcon16_tsc_set_uc_lane_cfg(&phy->access, serdes_firmware_config)); 231 } 232 return PHYMOD_E_NONE; 233 } 234 235 236 int falcon16_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config) 237 { 238 239 PHYMOD_IF_ERR_RETURN 240 (falcon16_lane_soft_reset_release(&phy->access, 0)); 241 242 PHYMOD_IF_ERR_RETURN 243 (_falcon16_phy_firmware_lane_config_set(phy, fw_lane_config)); 244 245 PHYMOD_IF_ERR_RETURN 246 (falcon16_lane_soft_reset_release(&phy->access, 1)); 247 248 return PHYMOD_E_NONE; 249 250 } 251 252 int falcon16_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config) 253 { 254 struct falcon16_tsc_uc_lane_config_st serdes_firmware_config; 255 256 PHYMOD_MEMSET(&serdes_firmware_config, 0x0, sizeof(serdes_firmware_config)); 257 PHYMOD_IF_ERR_RETURN(falcon16_tsc_get_uc_lane_cfg(&phy->access, &serdes_firmware_config)); 258 PHYMOD_MEMSET(fw_lane_config, 0, sizeof(*fw_lane_config)); 259 fw_lane_config->LaneConfigFromPCS = serdes_firmware_config.field.lane_cfg_from_pcs; 260 fw_lane_config->AnEnabled = serdes_firmware_config.field.an_enabled; 261 fw_lane_config->DfeOn = serdes_firmware_config.field.dfe_on; 262 fw_lane_config->LpDfeOn = serdes_firmware_config.field.dfe_lp_mode; 263 fw_lane_config->ForceBrDfe = serdes_firmware_config.field.force_brdfe_on; 264 /* fw_config->Cl72Enable = serdes_firmware_config.field.cl72_emulation_en; */ 265 fw_lane_config->ScramblingDisable = serdes_firmware_config.field.scrambling_dis; 266 fw_lane_config->UnreliableLos = serdes_firmware_config.field.unreliable_los; 267 fw_lane_config->MediaType = serdes_firmware_config.field.media_type; 268 fw_lane_config->Cl72AutoPolEn = serdes_firmware_config.field.cl72_auto_polarity_en; 269 fw_lane_config->Cl72RestTO = serdes_firmware_config.field.cl72_restart_timeout_en; 270 271 return PHYMOD_E_NONE; 272 273 } 274 275 276 int falcon16_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 277 { 278 279 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_core_pll_sequencer_restart)\n")); 280 281 return PHYMOD_E_NONE; 282 283 } 284 285 286 int falcon16_core_wait_event(const phymod_core_access_t* core, phymod_core_event_t event, uint32_t timeout) 287 { 288 289 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_core_wait_event)\n")); 290 291 return PHYMOD_E_NONE; 292 293 } 294 295 296 int falcon16_phy_rx_restart(const phymod_phy_access_t* phy) 297 { 298 299 PHYMOD_IF_ERR_RETURN(falcon16_tsc_rx_restart(&phy->access, 1)); 300 301 return PHYMOD_E_NONE; 302 303 } 304 305 306 int falcon16_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 307 { 308 309 PHYMOD_IF_ERR_RETURN 310 (falcon16_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity)); 311 312 return PHYMOD_E_NONE; 313 314 } 315 316 int falcon16_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 317 { 318 319 PHYMOD_IF_ERR_RETURN 320 (falcon16_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity)); 321 322 return PHYMOD_E_NONE; 323 324 } 325 326 327 int falcon16_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 328 { 329 330 PHYMOD_IF_ERR_RETURN 331 (falcon16_tsc_write_tx_afe(&phy->access, TX_AFE_PRE, (int8_t)tx->pre)); 332 PHYMOD_IF_ERR_RETURN 333 (falcon16_tsc_write_tx_afe(&phy->access, TX_AFE_MAIN, (int8_t)tx->main)); 334 PHYMOD_IF_ERR_RETURN 335 (falcon16_tsc_write_tx_afe(&phy->access, TX_AFE_POST1, (int8_t)tx->post)); 336 PHYMOD_IF_ERR_RETURN 337 (falcon16_tsc_write_tx_afe(&phy->access, TX_AFE_POST2, (int8_t)tx->post2)); 338 PHYMOD_IF_ERR_RETURN 339 (falcon16_tsc_write_tx_afe(&phy->access, TX_AFE_POST3, (int8_t)tx->post3)); 340 /* 341 PHYMOD_IF_ERR_RETURN 342 (falcon16_tsc_write_tx_afe(&phy->access, TX_AFE_RPARA, tx->amp)); */ 343 344 return PHYMOD_E_NONE; 345 346 } 347 348 int falcon16_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 349 { 350 int8_t value = 0; 351 352 PHYMOD_IF_ERR_RETURN 353 (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_PRE, &value)); 354 tx->pre = value; 355 PHYMOD_IF_ERR_RETURN 356 (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_MAIN, &value)); 357 tx->main = value; 358 PHYMOD_IF_ERR_RETURN 359 (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_POST1, &value)); 360 tx->post = value; 361 PHYMOD_IF_ERR_RETURN 362 (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_POST2, &value)); 363 tx->post2 = value; 364 PHYMOD_IF_ERR_RETURN 365 (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_POST3, &value)); 366 tx->post3 = value; 367 PHYMOD_IF_ERR_RETURN 368 (falcon16_tsc_read_tx_afe(&phy->access, TX_AFE_RPARA, &value)); 369 tx->rpara = value; 370 371 return PHYMOD_E_NONE; 372 373 } 374 375 376 int falcon16_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx) 377 { 378 switch (media) { 379 case phymodMediaTypeChipToChip: 380 tx->pre = 0xA; 381 tx->main = 0x41; 382 tx->post = 0x14; 383 tx->post2 = 0x0; 384 tx->post3 = 0x0; 385 break; 386 case phymodMediaTypeShort: 387 tx->pre = 0xA; 388 tx->main = 0x41; 389 tx->post = 0x14; 390 tx->post2 = 0x0; 391 tx->post3 = 0x0; 392 break; 393 case phymodMediaTypeMid: 394 tx->pre = 0xA; 395 tx->main = 0x41; 396 tx->post = 0x14; 397 tx->post2 = 0x0; 398 tx->post3 = 0x0; 399 break; 400 case phymodMediaTypeLong: 401 tx->pre = 0xA; 402 tx->main = 0x41; 403 tx->post = 0x14; 404 tx->post2 = 0x0; 405 tx->post3 = 0x0; 406 break; 407 default: 408 tx->pre = 0xA; 409 tx->main = 0x41; 410 tx->post = 0x14; 411 tx->post2 = 0x0; 412 tx->post3 = 0x0; 413 break; 414 } 415 416 return PHYMOD_E_NONE; 417 418 } 419 420 421 int falcon16_phy_tx_override_set(const phymod_phy_access_t* phy, const phymod_tx_override_t* tx_override) 422 { 423 PHYMOD_IF_ERR_RETURN 424 (falcon16_tsc_tx_pi_freq_override(&phy->access, 425 tx_override->phase_interpolator.enable, 426 tx_override->phase_interpolator.value)); 427 428 429 return PHYMOD_E_NONE; 430 431 } 432 433 int falcon16_phy_tx_override_get(const phymod_phy_access_t* phy, phymod_tx_override_t* tx_override) 434 { 435 436 /* Place your code here */ 437 438 439 return PHYMOD_E_NONE; 440 441 } 442 443 444 int falcon16_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 445 { 446 uint32_t i; 447 448 /*params check*/ 449 if((rx->num_of_dfe_taps == 0) || (rx->num_of_dfe_taps > TSCF16_NOF_DFES)){ 450 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set %u"), (unsigned int)rx->num_of_dfe_taps)); 451 } 452 453 /*vga set*/ 454 if (rx->vga.enable) { 455 /* first stop the rx adaption */ 456 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 1)); 457 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_VGA, rx->vga.value)); 458 } else { 459 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 0)); 460 } 461 462 /*dfe set*/ 463 for (i = 0 ; i < rx->num_of_dfe_taps ; i++){ 464 if(rx->dfe[i].enable){ 465 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 1)); 466 switch (i) { 467 case 0: 468 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_DFE1, rx->dfe[i].value)); 469 break; 470 case 1: 471 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_DFE2, rx->dfe[i].value)); 472 break; 473 case 2: 474 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_DFE3, rx->dfe[i].value)); 475 break; 476 case 3: 477 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_DFE4, rx->dfe[i].value)); 478 break; 479 case 4: 480 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_DFE5, rx->dfe[i].value)); 481 break; 482 default: 483 return PHYMOD_E_PARAM; 484 } 485 } else { 486 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 0)); 487 } 488 } 489 /*peaking filter set*/ 490 if(rx->peaking_filter.enable){ 491 /* first stop the rx adaption */ 492 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 1)); 493 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_PF, rx->peaking_filter.value)); 494 } else { 495 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 0)); 496 } 497 498 if(rx->low_freq_peaking_filter.enable){ 499 /* first stop the rx adaption */ 500 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 1)); 501 PHYMOD_IF_ERR_RETURN(falcon16_tsc_write_rx_afe(&phy->access, RX_AFE_PF2, rx->low_freq_peaking_filter.value)); 502 } else { 503 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 0)); 504 } 505 506 507 return PHYMOD_E_NONE; 508 509 } 510 511 512 int falcon16_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 513 { 514 int8_t val; 515 uint32_t rx_adaptation; 516 517 rx_adaptation = PHYMOD_RX_ADAPTATION_ON_GET(rx); 518 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 1)); 519 520 PHYMOD_IF_ERR_RETURN 521 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_PF, &val)); 522 rx->peaking_filter.value = val; 523 524 PHYMOD_IF_ERR_RETURN 525 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_PF2, &val)); 526 rx->low_freq_peaking_filter.value = val; 527 528 PHYMOD_IF_ERR_RETURN 529 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_VGA, &val)); 530 rx->vga.value = val; 531 532 PHYMOD_IF_ERR_RETURN 533 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE1, &val)); 534 rx->dfe[0].value = val; 535 536 PHYMOD_IF_ERR_RETURN 537 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE2, &val)); 538 rx->dfe[1].value = val; 539 540 PHYMOD_IF_ERR_RETURN 541 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE3, &val)); 542 rx->dfe[2].value = val; 543 544 PHYMOD_IF_ERR_RETURN 545 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE4, &val)); 546 rx->dfe[3].value = val; 547 548 PHYMOD_IF_ERR_RETURN 549 (falcon16_tsc_read_rx_afe(&phy->access, RX_AFE_DFE5, &val)); 550 rx->dfe[4].value = val; 551 552 rx->num_of_dfe_taps = 5; 553 rx->dfe[0].enable = 1; 554 rx->dfe[1].enable = 1; 555 rx->dfe[2].enable = 1; 556 rx->dfe[3].enable = 1; 557 rx->dfe[4].enable = 1; 558 rx->vga.enable = 1; 559 rx->low_freq_peaking_filter.enable = 1; 560 rx->peaking_filter.enable = 1; 561 562 if (rx_adaptation) { 563 PHYMOD_IF_ERR_RETURN(falcon16_tsc_stop_rx_adaptation(&phy->access, 0)); 564 } 565 566 return PHYMOD_E_NONE; 567 568 } 569 570 571 int falcon16_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset) 572 { 573 /*Reset per RX/TX is not supported*/ 574 if (reset->rx != reset->tx) 575 { 576 PHYMOD_DEBUG_ERROR(("Reset per RX/TX is NOT SUPPORTED!! (falcon_phy_reset_set) \n")); 577 } 578 579 switch (reset->tx) 580 { 581 case phymodResetDirectionIn: 582 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&phy->access, 0)); 583 break; 584 case phymodResetDirectionOut: 585 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&phy->access, 1)); 586 break; 587 case phymodResetDirectionInOut: 588 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&phy->access, 0)); 589 PHYMOD_USLEEP(10); 590 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&phy->access, 1)); 591 break; 592 default: 593 break; 594 } 595 596 597 return PHYMOD_E_NONE; 598 599 } 600 601 int falcon16_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset) 602 { 603 604 uint32_t rst; 605 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release_get(&phy->access, &rst)); 606 if(rst == 0) { 607 reset->tx = phymodResetDirectionIn; 608 reset->rx = phymodResetDirectionIn; 609 } else { 610 reset->tx = phymodResetDirectionOut; 611 reset->rx = phymodResetDirectionOut; 612 } 613 614 return PHYMOD_E_NONE; 615 616 } 617 618 619 int falcon16_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power) 620 { 621 enum srds_core_pwrdn_mode_enum mode; 622 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerNoChange)) { 623 /*disable tx on the PMD side */ 624 mode = PWRDN_TX; 625 PHYMOD_IF_ERR_RETURN(falcon16_tsc_lane_pwrdn(&phy->access, mode)); 626 } 627 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerNoChange)) { 628 /*enable tx on the PMD side */ 629 PHYMOD_IF_ERR_RETURN(falcon16_tsc_pwrdn_set(&phy->access, 1, 0)); 630 } 631 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOff)) { 632 /*disable rx on the PMD side */ 633 mode = PWRDN_RX; 634 PHYMOD_IF_ERR_RETURN(falcon16_tsc_lane_pwrdn(&phy->access, mode)); 635 } 636 if ((power->tx == phymodPowerNoChange) && (power->rx == phymodPowerOn)) { 637 PHYMOD_IF_ERR_RETURN(falcon16_tsc_pwrdn_set(&phy->access, 0, 0)); 638 /*enable rx on the PMD side */ 639 } 640 if ((power->tx == phymodPowerOn) && (power->rx == phymodPowerOn)) { 641 mode = PWR_ON; 642 PHYMOD_IF_ERR_RETURN(falcon16_tsc_lane_pwrdn(&phy->access, mode)); 643 } 644 if ((power->tx == phymodPowerOff) && (power->rx == phymodPowerOff)) { 645 /* Both Tx and Rx power down */ 646 mode = PWRDN; 647 PHYMOD_IF_ERR_RETURN(falcon16_tsc_lane_pwrdn(&phy->access, mode)); 648 } 649 650 651 return PHYMOD_E_NONE; 652 653 } 654 655 int falcon16_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 656 { 657 power_status_t pwrdn; 658 659 PHYMOD_IF_ERR_RETURN(falcon16_tsc_pwrdn_get(&phy->access, &pwrdn)); 660 power->rx = (pwrdn.rx_s_pwrdn == 0)? phymodPowerOn: phymodPowerOff; 661 power->tx = (pwrdn.tx_s_pwrdn == 0)? phymodPowerOn: phymodPowerOff; 662 663 664 return PHYMOD_E_NONE; 665 666 } 667 668 669 int falcon16_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control) 670 { 671 switch (tx_control) 672 { 673 case phymodTxElectricalIdleEnable: 674 PHYMOD_IF_ERR_RETURN(falcon16_electrical_idle_set(&phy->access, 1)); 675 break; 676 case phymodTxElectricalIdleDisable: 677 PHYMOD_IF_ERR_RETURN(falcon16_electrical_idle_set(&phy->access, 0)); 678 break; 679 case phymodTxSquelchOn: 680 PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_disable(&phy->access, 1)); 681 break; 682 case phymodTxSquelchOff: 683 PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_disable(&phy->access, 0)); 684 break; 685 default: 686 PHYMOD_DEBUG_ERROR(("This control is NOT SUPPORTED!! (falcon16_phy_tx_lane_control_set)\n")); 687 } 688 689 return PHYMOD_E_NONE; 690 691 } 692 693 int falcon16_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control) 694 { 695 uint8_t disable; 696 697 PHYMOD_IF_ERR_RETURN(falcon16_tsc_tx_disable_get(&phy->access, &disable)); 698 if(disable){ 699 *tx_control = phymodTxSquelchOn; 700 } else { 701 *tx_control = phymodTxSquelchOff; 702 703 } 704 705 return PHYMOD_E_NONE; 706 707 } 708 709 710 int falcon16_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control) 711 { 712 713 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_rx_lane_control_set)\n")); 714 715 return PHYMOD_E_NONE; 716 717 } 718 719 int falcon16_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control) 720 { 721 722 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_rx_lane_control_get)\n")); 723 724 return PHYMOD_E_NONE; 725 726 } 727 728 729 int falcon16_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config) 730 { 731 /* phymod_tx_t tx_params; */ 732 uint32_t current_pll_div=0; 733 uint32_t vco_rate; 734 uint32_t new_pll_div=0; 735 int16_t new_os_mode =0; 736 phymod_phy_access_t pm_phy_copy; 737 int start_lane, num_lane, i; 738 uint32_t enable[PHYMOD_MAX_LANES_PER_CORE]; 739 740 /* sc_table_entry exp_entry; RAVI */ 741 phymod_firmware_lane_config_t firmware_lane_config; 742 phymod_firmware_core_config_t firmware_core_config; 743 744 PHYMOD_MEMSET(&firmware_lane_config, 0x0, sizeof(firmware_lane_config)); 745 PHYMOD_MEMSET(&firmware_core_config, 0x0, sizeof(firmware_core_config)); 746 firmware_lane_config.MediaType = 0; 747 748 /*next program the tx fir taps and driver current based on the input*/ 749 PHYMOD_IF_ERR_RETURN 750 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 751 752 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 753 754 /*Get lane reset status*/ 755 for (i = 0; i < num_lane; i++) { 756 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 757 PHYMOD_IF_ERR_RETURN 758 (falcon16_lane_soft_reset_release_get(&pm_phy_copy.access, &enable[i])); 759 } 760 761 /*Hold the per lne soft reset bit*/ 762 for (i = 0; i < num_lane; i++) { 763 if (enable[i]) 764 { 765 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 766 PHYMOD_IF_ERR_RETURN 767 (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 0)); 768 } 769 } 770 771 pm_phy_copy.access.lane_mask = 0x1 << start_lane; 772 PHYMOD_IF_ERR_RETURN 773 (falcon16_phy_firmware_lane_config_get(&pm_phy_copy, &firmware_lane_config)); 774 775 /*make sure that an and config from pcs is off*/ 776 firmware_core_config.CoreConfigFromPCS = 0; 777 firmware_lane_config.AnEnabled = 0; 778 firmware_lane_config.LaneConfigFromPCS = 0; 779 firmware_lane_config.DfeOn = 1; 780 firmware_lane_config.LpDfeOn = 0; 781 firmware_lane_config.Cl72RestTO = 1; 782 if(config->data_rate == 1000) 783 firmware_lane_config.DfeOn = 0; 784 785 if (PHYMOD_INTF_MODES_FIBER_GET(config)) { 786 firmware_lane_config.MediaType = phymodFirmwareMediaTypeOptics; 787 } else if (PHYMOD_INTF_MODES_COPPER_GET(config)) { 788 firmware_lane_config.MediaType = phymodFirmwareMediaTypeCopperCable; 789 } else { 790 firmware_lane_config.MediaType = phymodFirmwareMediaTypePcbTraceBackPlane; 791 } 792 /* Check unreliable LOS */ 793 if(config->interface_modes & ~(0x200)) { 794 firmware_lane_config.UnreliableLos = 1; 795 } else { 796 firmware_lane_config.UnreliableLos = 0; 797 } 798 799 PHYMOD_IF_ERR_RETURN 800 (falcon16_tsc_get_pll_vco_osmode(config, &vco_rate, &new_pll_div, &new_os_mode)); 801 802 PHYMOD_IF_ERR_RETURN 803 (falcon16_pll_mode_get(&pm_phy_copy.access, ¤t_pll_div)); 804 805 806 /*if pll change is enabled*/ 807 if((current_pll_div != new_pll_div) && (PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)){ 808 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, 809 (_PHYMOD_MSG("pll has to change for speed_set from %u to %u but DONT_TURN_OFF_PLL flag is enabled"), 810 (unsigned int)current_pll_div, (unsigned int)new_pll_div)); 811 } 812 /*pll switch is required and expected */ 813 if((current_pll_div != new_pll_div) && !(PHYMOD_INTF_F_DONT_TURN_OFF_PLL & flags)) { 814 /* phymod_access_t tmp_phy_access; */ 815 PHYMOD_IF_ERR_RETURN 816 (falcon16_core_soft_reset_release(&pm_phy_copy.access, 0)); 817 818 /*release the uc reset */ 819 #if 0 820 PHYMOD_IF_ERR_RETURN 821 (falcon16_tsc_uc_reset(&pm_phy_copy.access ,0)); 822 #endif 823 /*set the PLL divider */ 824 PHYMOD_IF_ERR_RETURN 825 (falcon16_pll_mode_set(&pm_phy_copy.access, new_pll_div)); 826 827 firmware_core_config.VcoRate = (vco_rate * 16 + 500) / 1000 - 224; 828 829 /*change the master port num to the current caller port */ 830 831 /* 832 PHYMOD_IF_ERR_RETURN 833 (tefmod_master_port_num_set(&phy->access, start_lane)); */ 834 /* Do we need PLL reset */ 835 836 #if 0 837 PHYMOD_IF_ERR_RETURN 838 (falcon16_pll_reset_enable_set(&pm_phy_copy.access, 1)); 839 #endif 840 /*update the firmware config properly*/ 841 PHYMOD_IF_ERR_RETURN 842 (falcon16_phy_firmware_core_config_set(&pm_phy_copy, firmware_core_config)); 843 PHYMOD_IF_ERR_RETURN 844 (falcon16_core_soft_reset_release(&pm_phy_copy.access, 1)); 845 } 846 847 /* 848 PHYMOD_IF_ERR_RETURN 849 (tefmod_set_spd_intf(&phy->access, spd_intf)); 850 */ 851 852 /*change TX parameters if enabled*/ 853 /* 854 if((PHYMOD_IF_F_DONT_OVERIDE_TX_PARAMS & flags) == 0) { 855 PHYMOD_IF_ERR_RETURN 856 (tscf_phy_media_type_tx_get(phy, phymodMediaTypeMid, &tx_params)); 857 } 858 */ 859 for (i = 0; i < num_lane; i++) { 860 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 861 PHYMOD_IF_ERR_RETURN 862 (_falcon16_phy_firmware_lane_config_set(&pm_phy_copy, firmware_lane_config)); 863 } 864 for (i = 0; i < num_lane; i++) { 865 pm_phy_copy.access.lane_mask = 0x1 << (start_lane + i); 866 PHYMOD_IF_ERR_RETURN 867 (falcon16_osr_mode_set(&pm_phy_copy.access, new_os_mode)); 868 } 869 870 /*release the per lne soft reset bit*/ 871 for (i = 0; i < num_lane; i++) { 872 if (enable[i]) 873 { 874 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 875 PHYMOD_IF_ERR_RETURN 876 (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 1)); 877 } 878 } 879 880 return PHYMOD_E_NONE; 881 882 } 883 884 885 STATIC 886 int _falcon16_pll_multiplier_get(uint32_t pll_div, uint32_t *pll_multiplier) 887 { 888 switch (pll_div) { 889 case 0x0: 890 *pll_multiplier = 64; 891 break; 892 case 0x1: 893 *pll_multiplier = 66; 894 break; 895 case 0x2: 896 *pll_multiplier = 80; 897 break; 898 case 0x3: 899 *pll_multiplier = 128; 900 break; 901 case 0x4: 902 *pll_multiplier = 132; 903 break; 904 case 0x5: 905 *pll_multiplier = 140; 906 break; 907 case 0x6: 908 *pll_multiplier = 160; 909 break; 910 case 0x7: 911 *pll_multiplier = 165; 912 break; 913 case 0x8: 914 *pll_multiplier = 168; 915 break; 916 case 0x9: 917 *pll_multiplier = 170; 918 break; 919 case 0xa: 920 *pll_multiplier = 175; 921 break; 922 case 0xb: 923 *pll_multiplier = 180; 924 break; 925 case 0xc: 926 *pll_multiplier = 184; 927 break; 928 case 0xd: 929 *pll_multiplier = 200; 930 break; 931 case 0xe: 932 *pll_multiplier = 224; 933 break; 934 case 0xf: 935 *pll_multiplier = 264; 936 break; 937 default: 938 *pll_multiplier = 165; 939 break; 940 } 941 return PHYMOD_E_NONE; 942 } 943 944 945 STATIC 946 int _falcon16_actual_osr_get(int osr_mode, int* actual_os) 947 { 948 switch(osr_mode) { 949 case 0: *actual_os = 1; break; 950 case 1: *actual_os = 2; break; 951 case 2: *actual_os = 4; break; 952 default: 953 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("unsupported OS mode %d"), osr_mode)); 954 } 955 return PHYMOD_E_NONE; 956 } 957 958 959 int falcon16_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) 960 { 961 int osr_mode; 962 uint32_t pll_div; 963 uint32_t pll_multiplier, refclk; 964 phymod_phy_access_t phy_copy; 965 int actual_osr; 966 967 config->ref_clock = ref_clock; 968 969 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 970 phy_copy.access.lane_mask = 0x1; 971 972 PHYMOD_IF_ERR_RETURN 973 (falcon16_osr_mode_get(&phy->access, &osr_mode)); 974 PHYMOD_IF_ERR_RETURN 975 (falcon16_pll_mode_get(&phy_copy.access, &pll_div)); 976 PHYMOD_IF_ERR_RETURN 977 (_falcon16_pll_multiplier_get(pll_div, &pll_multiplier)); 978 979 if (ref_clock == phymodRefClk156Mhz) { 980 refclk = 15625; 981 } else if (ref_clock == phymodRefClk125Mhz) { 982 refclk = 12500; 983 } else { 984 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INTERNAL, (_PHYMOD_MSG("Unknown refclk"))); 985 } 986 987 PHYMOD_IF_ERR_RETURN(_falcon16_actual_osr_get(osr_mode, &actual_osr)); 988 989 config->data_rate = (refclk*pll_multiplier)/(100*actual_osr); 990 config->interface_type = phymodInterfaceBypass; 991 992 if(osr_mode == 1) { 993 PHYMOD_INTF_MODES_OS2_SET(config); 994 } 995 996 return PHYMOD_E_NONE; 997 998 } 999 1000 1001 int falcon16_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 1002 { 1003 PHYMOD_IF_ERR_RETURN 1004 (falcon16_clause72_control(&phy->access, cl72_en)); 1005 1006 return PHYMOD_E_NONE; 1007 1008 } 1009 1010 int falcon16_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 1011 { 1012 PHYMOD_IF_ERR_RETURN 1013 (falcon16_clause72_control_get(&phy->access, cl72_en)); 1014 1015 return PHYMOD_E_NONE; 1016 1017 } 1018 1019 1020 int falcon16_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 1021 { 1022 uint32_t local_status; 1023 1024 PHYMOD_IF_ERR_RETURN 1025 (falcon16_pmd_cl72_receiver_status(&phy->access, &local_status)); 1026 status->locked = local_status; 1027 1028 1029 return PHYMOD_E_NONE; 1030 1031 } 1032 1033 1034 int falcon16_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type) 1035 { 1036 1037 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_autoneg_ability_set)\n")); 1038 1039 return PHYMOD_E_NONE; 1040 1041 } 1042 1043 int falcon16_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 1044 { 1045 1046 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_autoneg_ability_get)\n")); 1047 1048 return PHYMOD_E_NONE; 1049 1050 } 1051 1052 1053 int falcon16_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 1054 { 1055 1056 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_autoneg_set)\n")); 1057 1058 return PHYMOD_E_NONE; 1059 1060 } 1061 1062 int falcon16_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 1063 { 1064 1065 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_autoneg_get)\n")); 1066 1067 return PHYMOD_E_NONE; 1068 1069 } 1070 1071 1072 int falcon16_phy_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 1073 { 1074 1075 PHYMOD_DEBUG_ERROR(("This function is NOT SUPPORTED!! (falcon16_phy_autoneg_status_get)\n")); 1076 1077 return PHYMOD_E_NONE; 1078 1079 } 1080 1081 1082 int falcon16_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status) 1083 { 1084 1085 int rv; 1086 phymod_phy_access_t phy_access, phy_access_copy; 1087 phymod_core_access_t core_copy; 1088 phymod_firmware_core_config_t firmware_core_config_tmp; 1089 1090 TSCF16_CORE_TO_PHY_ACCESS(&phy_access, core); 1091 phy_access_copy = phy_access; 1092 PHYMOD_MEMCPY(&core_copy, core, sizeof(core_copy)); 1093 core_copy.access.lane_mask = 0x1; 1094 phy_access_copy = phy_access; 1095 phy_access_copy.access = core->access; 1096 phy_access_copy.access.lane_mask = 0x1; 1097 phy_access_copy.type = core->type; 1098 1099 1100 1101 if(!PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) { 1102 PHYMOD_IF_ERR_RETURN 1103 (falcon16_pmd_reset_seq(&core_copy.access, core_status->pmd_active)); 1104 } 1105 1106 rv = _falcon16_core_firmware_load(&core_copy, init_config); 1107 if (rv != PHYMOD_E_NONE) { 1108 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC firmware-load failed\n", core->access.addr, core->access.lane_mask)); 1109 PHYMOD_IF_ERR_RETURN(rv); 1110 } 1111 1112 if(PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) { 1113 return PHYMOD_E_NONE; 1114 } 1115 1116 /*next we need to check if the load is correct or not */ 1117 if(init_config->firmware_load_method != phymodFirmwareLoadMethodNone) { 1118 1119 /*next we need to set the uc active and release uc */ 1120 PHYMOD_IF_ERR_RETURN 1121 (falcon16_uc_active_set(&core_copy.access ,1)); 1122 1123 /*release the uc reset */ 1124 PHYMOD_IF_ERR_RETURN 1125 (falcon16_tsc_uc_reset(&core_copy.access ,0)); 1126 1127 #ifndef FALCON_PMD_CRC_UCODE 1128 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 1129 rv = falcon16_tsc_ucode_load_verify(&core_copy.access, (uint8_t *) &falcon16_ucode, falcon16_ucode_len); 1130 1131 if (rv != PHYMOD_E_NONE) { 1132 PHYMOD_DEBUG_ERROR(("devad 0x%x lane 0x%x: UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 1133 PHYMOD_IF_ERR_RETURN(rv); 1134 } 1135 } 1136 #endif 1137 1138 PHYMOD_IF_ERR_RETURN 1139 (falcon16_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x1)); 1140 1141 /* we need to wait at least 10ms for the uc to settle */ 1142 PHYMOD_USLEEP(10000); 1143 1144 /* poll the ready bit in 10 ms */ 1145 #ifndef FALCON16_PMD_CRC_UCODE 1146 PHYMOD_IF_ERR_RETURN 1147 (serdes_INTERNAL_poll_uc_dsc_ready_for_cmd_equals_1(&phy_access_copy.access, 1, CMD_READ_DIAG_DATA_BYTE)); 1148 #else 1149 if(PHYMOD_CORE_INIT_F_FIRMWARE_LOAD_VERIFY_GET(init_config)) { 1150 rv = falcon16_tsc_ucode_crc_verify(&core_copy.access, falcon16_ucode_len, falcon16_ucode_crc); 1151 if (rv != PHYMOD_E_NONE) { 1152 PHYMOD_DEBUG_ERROR(("devad 0x%"PRIx32" lane 0x%"PRIx32": UC load-verify failed\n", core->access.addr, core->access.lane_mask)); 1153 PHYMOD_IF_ERR_RETURN(rv); 1154 } 1155 } 1156 #endif 1157 PHYMOD_IF_ERR_RETURN 1158 (falcon16_pmd_ln_h_rstb_pkill_override( &phy_access_copy.access, 0x0)); 1159 } 1160 1161 /* AFE/PLL config */ 1162 if(init_config->afe_pll.afe_pll_change_default) { 1163 PHYMOD_IF_ERR_RETURN 1164 (falcon16_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 1165 firmware_core_config_tmp.disable_write_pll_iqp = 1; 1166 } else { 1167 PHYMOD_IF_ERR_RETURN 1168 (falcon16_afe_pll_reg_set(&core_copy.access, &init_config->afe_pll)); 1169 firmware_core_config_tmp.disable_write_pll_iqp = 0; 1170 } 1171 /* plldiv CONFIG */ 1172 PHYMOD_IF_ERR_RETURN 1173 (falcon16_pll_mode_set(&core_copy.access, 0xa)); 1174 1175 /*now config the lane mapping and polarity */ 1176 PHYMOD_IF_ERR_RETURN 1177 (falcon16_core_lane_map_set(core, &init_config->lane_map)); 1178 /* 1179 PHYMOD_IF_ERR_RETURN 1180 (tscf16_core_lane_map_set(core, &init_config->lane_map)); 1181 PHYMOD_IF_ERR_RETURN 1182 (tefmod_autoneg_timer_init(&core->access)); 1183 PHYMOD_IF_ERR_RETURN 1184 (tefmod_master_port_num_set(&core->access, 0)); 1185 */ 1186 /*don't overide the fw that set in config set if not specified*/ 1187 firmware_core_config_tmp = init_config->firmware_core_config; 1188 firmware_core_config_tmp.CoreConfigFromPCS = 0; 1189 /*set the vco rate to be default at 10.3125G */ 1190 firmware_core_config_tmp.VcoRate = 0x13; 1191 1192 PHYMOD_IF_ERR_RETURN 1193 (falcon16_phy_firmware_core_config_set(&phy_access_copy, firmware_core_config_tmp)); 1194 1195 1196 /* release core soft reset */ 1197 PHYMOD_IF_ERR_RETURN 1198 (falcon16_core_soft_reset_release(&core_copy.access, 1)); 1199 1200 1201 return PHYMOD_E_NONE; 1202 1203 } 1204 1205 1206 int falcon16_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config) 1207 { 1208 const phymod_access_t *pm_acc = &phy->access; 1209 phymod_phy_access_t pm_phy_copy; 1210 int start_lane, num_lane, i; 1211 int lane_bkup; 1212 phymod_polarity_t tmp_pol; 1213 1214 PHYMOD_MEMSET(&tmp_pol, 0x0, sizeof(tmp_pol)); 1215 PHYMOD_MEMCPY(&pm_phy_copy, phy, sizeof(pm_phy_copy)); 1216 1217 /*next program the tx fir taps and driver current based on the input*/ 1218 PHYMOD_IF_ERR_RETURN 1219 (phymod_util_lane_config_get(pm_acc, &start_lane, &num_lane)); 1220 /*per lane based reset release */ 1221 /* PHYMOD_IF_ERR_RETURN 1222 (tefmod_pmd_x4_reset(pm_acc)); */ 1223 PHYMOD_IF_ERR_RETURN(falcon16_lane_hard_soft_reset_release(&pm_phy_copy.access, 0)); 1224 PHYMOD_IF_ERR_RETURN(falcon16_lane_hard_soft_reset_release(&pm_phy_copy.access, 1)); 1225 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1226 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1227 PHYMOD_IF_ERR_RETURN(falcon16_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1228 1229 lane_bkup = pm_phy_copy.access.lane_mask; 1230 for (i = 0; i < num_lane; i++) { 1231 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1232 PHYMOD_IF_ERR_RETURN 1233 (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 1)); 1234 } 1235 for (i = 0; i < num_lane; i++) { 1236 pm_phy_copy.access.lane_mask = 1 << (start_lane + i); 1237 PHYMOD_IF_ERR_RETURN 1238 (falcon16_lane_soft_reset_release(&pm_phy_copy.access, 0)); 1239 } 1240 pm_phy_copy.access.lane_mask = lane_bkup; 1241 1242 /* program the rx/tx polarity */ 1243 for (i = 0; i < num_lane; i++) { 1244 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1245 tmp_pol.tx_polarity = (init_config->polarity.tx_polarity) >> (i + start_lane) & 0x1; 1246 tmp_pol.rx_polarity = (init_config->polarity.rx_polarity) >> (i + start_lane) & 0x1; 1247 PHYMOD_IF_ERR_RETURN 1248 (falcon16_phy_polarity_set(&pm_phy_copy, &tmp_pol)); 1249 } 1250 1251 for (i = 0; i < num_lane; i++) { 1252 pm_phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1253 PHYMOD_IF_ERR_RETURN 1254 (falcon16_phy_tx_set(&pm_phy_copy, &init_config->tx[i])); 1255 } 1256 1257 PHYMOD_IF_ERR_RETURN 1258 (falcon16_phy_cl72_set(&pm_phy_copy, init_config->cl72_en)); 1259 1260 /* ONLY for PCS 1261 PHYMOD_IF_ERR_RETURN 1262 (tefmod_update_port_mode(pm_acc, &pll_restart)); 1263 1264 PHYMOD_IF_ERR_RETURN 1265 (tefmod_rx_lane_control_set(pm_acc, 1)); 1266 PHYMOD_IF_ERR_RETURN 1267 (tefmod_tx_lane_control_set(pm_acc, TEFMOD_TX_LANE_RESET_TRAFFIC_ENABLE)); 1268 */ 1269 1270 return PHYMOD_E_NONE; 1271 1272 } 1273 1274 1275 int falcon16_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable) 1276 { 1277 1278 int i; 1279 int start_lane, num_lane; 1280 int rv = PHYMOD_E_NONE; 1281 phymod_phy_access_t phy_copy; 1282 1283 PHYMOD_MEMCPY(&phy_copy, phy, sizeof(phy_copy)); 1284 1285 /* next figure out the lane num and start_lane based on the input */ 1286 PHYMOD_IF_ERR_RETURN 1287 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1288 1289 switch (loopback) { 1290 case phymodLoopbackGlobal : 1291 /* PHYMOD_IF_ERR_RETURN(tefmod_tx_loopback_control(&phy->access, enable, start_lane, num_lane)); */ 1292 break; 1293 case phymodLoopbackGlobalPMD : 1294 for (i = 0; i < num_lane; i++) { 1295 phy_copy.access.lane_mask = 0x1 << (i + start_lane); 1296 PHYMOD_IF_ERR_RETURN(falcon16_tsc_dig_lpbk(&phy_copy.access, (uint8_t) enable)); 1297 PHYMOD_IF_ERR_RETURN(falcon16_pmd_force_signal_detect(&phy_copy.access, (int) enable)); 1298 } 1299 break; 1300 case phymodLoopbackRemotePMD : 1301 PHYMOD_IF_ERR_RETURN(falcon16_tsc_rmt_lpbk(&phy->access, (uint8_t)enable)); 1302 break; 1303 case phymodLoopbackRemotePCS : 1304 /* PHYMOD_IF_ERR_RETURN(tefmod_rx_loopback_control(&phy->access, enable)); */ 1305 break; 1306 default : 1307 break; 1308 } 1309 1310 return rv; 1311 1312 } 1313 1314 int falcon16_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable) 1315 { 1316 1317 int start_lane, num_lane; 1318 1319 /*next figure out the lane num and start_lane based on the input*/ 1320 PHYMOD_IF_ERR_RETURN 1321 (phymod_util_lane_config_get(&phy->access, &start_lane, &num_lane)); 1322 1323 switch (loopback) { 1324 case phymodLoopbackGlobal : 1325 /* PHYMOD_IF_ERR_RETURN(temod_tx_loopback_get(&phy->access, &enable_core)); */ 1326 /* *enable = (enable_core >> start_lane) & 0x1; */ 1327 break; 1328 case phymodLoopbackGlobalPMD : 1329 PHYMOD_IF_ERR_RETURN(falcon16_tsc_dig_lpbk_get(&phy->access, enable)); 1330 break; 1331 case phymodLoopbackRemotePMD : 1332 PHYMOD_IF_ERR_RETURN(falcon16_tsc_rmt_lpbk_get(&phy->access, enable)); 1333 break; 1334 case phymodLoopbackRemotePCS : 1335 /* PHYMOD_IF_ERR_RETURN(temod_rx_loopback_control(&phy->access, enable, enable, enable)); */ 1336 break; 1337 default : 1338 break; 1339 } 1340 1341 1342 return PHYMOD_E_NONE; 1343 1344 } 1345 1346 1347 int falcon16_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status) 1348 { 1349 unsigned char rx_lock; 1350 1351 PHYMOD_IF_ERR_RETURN(falcon16_tsc_pmd_lock_status(&phy->access, &rx_lock)); 1352 *link_status = (uint32_t ) rx_lock; 1353 1354 return PHYMOD_E_NONE; 1355 1356 } 1357 1358 1359 int falcon16_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked) 1360 { 1361 1362 1363 PHYMOD_IF_ERR_RETURN(falcon16_phy_link_status_get(phy, rx_pmd_locked)); 1364 1365 return PHYMOD_E_NONE; 1366 1367 } 1368 1369 1370 int falcon16_phy_rx_signal_detect_get(const phymod_phy_access_t* phy, uint32_t* rx_signal_detect) 1371 { 1372 1373 PHYMOD_IF_ERR_RETURN(falcon16_tsc_signal_detect(&phy->access, rx_signal_detect)); 1374 1375 return PHYMOD_E_NONE; 1376 1377 } 1378 1379 1380 1381 int falcon16_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val) 1382 { 1383 1384 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_read(&phy->access, reg_addr, val)); 1385 1386 return PHYMOD_E_NONE; 1387 1388 } 1389 1390 1391 int falcon16_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val) 1392 { 1393 1394 PHYMOD_IF_ERR_RETURN(phymod_tsc_iblk_write(&phy->access, reg_addr, val)); 1395 1396 return PHYMOD_E_NONE; 1397 1398 }