furia.c (56624B)
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 11 #include <phymod/phymod.h> 12 #include <phymod/phymod_system.h> 13 #include <phymod/phymod_dispatch.h> 14 #include <phymod/phymod_acc.h> 15 16 #include <phymod/chip/furia.h> 17 18 #include "../tier1/furia_regs_structs.h" 19 #include "../tier1/furia_reg_access.h" 20 #include "../tier1/furia_address_defines.h" 21 #include "../tier1/furia_micro_seq.h" 22 #include "../tier1/furia_types.h" 23 #include "../tier1/furia_cfg_seq.h" 24 #include "../tier1/furia_pkg_cfg.h" 25 26 #define FURIA_ID0 0xae02 27 #define FURIA_ID1 0x5230 28 #define FURIA_IF_SIDE_SHIFT (31) 29 #define FURIA_NOF_LANES_IN_CORE (4) 30 #define FURIA_PHY_ALL_LANES (0xf) 31 #define FURIA_CORE_TO_PHY_ACCESS(_phy_access, _core_access) \ 32 do{\ 33 PHYMOD_MEMCPY(&(_phy_access)->access, &(_core_access)->access,\ 34 sizeof((_phy_access)->access));\ 35 (_phy_access)->type = (_core_access)->type; \ 36 (_phy_access)->access.lane = FURIA_PHY_ALL_LANES; \ 37 }while(0) 38 39 /* uController's firmware */ 40 extern unsigned char furia_ucode_Furia[]; 41 extern unsigned short furia_ucode_Furia_len; 42 43 int _furia_tx_rx_power_set(const phymod_access_t *pa, 44 phymod_power_t tx_rx_power, 45 uint8_t tx_rx); 46 /** Core identify 47 * This function reads device ID2 & ID3 registers and confirm whether furia 48 * device presents or not. 49 * 50 * @param core Pointer to phymod core access structure 51 * @param core_id Core ID which is supplied by interface layer 52 * @param is_identified Flag variable to return device 53 * identification status 54 * 55 * @return PHYMOD_E_NONE successful function execution 56 */ 57 int furia_core_identify(const phymod_core_access_t* core, uint32_t core_id, 58 uint32_t* is_identified) 59 { 60 int ioerr = 0; 61 const phymod_access_t *pm_acc = &core->access; 62 IEEE_PMA_PMD_BLK0_PMD_IDENTIFIER_REGISTER_0_t id2; 63 IEEE_PMA_PMD_BLK0_PMD_IDENTIFIER_REGISTER_1_t id3; 64 uint32_t chip_id = 0; 65 chip_id = _furia_get_chip_id(pm_acc); 66 67 *is_identified = 0; 68 69 if(core_id == 0){ 70 ioerr += 71 READ_FURIA_PMA_PMD_REG(pm_acc, 72 IEEE_PMA_PMD_BLK0_pmd_identifier_register_0_Adr, 73 &id2.data); 74 ioerr += 75 READ_FURIA_PMA_PMD_REG(pm_acc, 76 IEEE_PMA_PMD_BLK0_pmd_identifier_register_1_Adr, 77 &id3.data); 78 } else { 79 id2.data = (uint16_t) ((core_id >> 16) & 0xffff); 80 id3.data = (uint16_t) core_id & 0xffff; 81 } 82 83 if (((id2.data) == FURIA_ID0 && 84 (id3.data) == FURIA_ID1) && (FURIA_IS_SIMPLEX(chip_id) || FURIA_IS_DUPLEX(chip_id))) { 85 if (chip_id == FURIA_ID_82212) { 86 /* PHY IDs match */ 87 *is_identified = 0; 88 } else { 89 /* PHY IDs match */ 90 *is_identified = 1; 91 } 92 } 93 94 return ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE; 95 } 96 97 /** Core firmware download 98 * This function downloads the firmware using either internal or external 99 * method as specified by the user. Firmware loader function supplied by user 100 * will be used for external download method. 101 * 102 * @param core Pointer to phymod core access structure 103 * @param load_method Load method will be specified by user 104 * @param fw_loader Loader function specified by user and will be 105 * used for external download method 106 * 107 * @return PHYMOD_E_NONE successful function execution 108 */ 109 STATIC 110 int _furia_core_firmware_load(const phymod_core_access_t* core, 111 phymod_firmware_load_method_t load_method, 112 phymod_firmware_loader_f fw_loader) 113 { 114 phymod_access_t pa; 115 FUR_PAD_CTRL_EXT_UC_RSTB_CONTROL_t ext_uc_rstb_ctrl; 116 FUR_MICRO_BOOT_BOOT_POR_t boot_por; 117 int ret_val = 0; 118 uint32_t chip_id = 0; 119 uint32_t data = 0; 120 phymod_tx_t tx_params; 121 const phymod_access_t *pm_acc = &core->access; 122 PHYMOD_MEMSET(&ext_uc_rstb_ctrl, 0 , sizeof(FUR_PAD_CTRL_EXT_UC_RSTB_CONTROL_t)); 123 PHYMOD_MEMSET(&boot_por, 0 , sizeof(FUR_MICRO_BOOT_BOOT_POR_t)); 124 PHYMOD_MEMSET(&tx_params, 0 , sizeof(phymod_tx_t)); 125 switch(load_method) 126 { 127 case phymodFirmwareLoadMethodInternal: 128 PHYMOD_DEBUG_VERBOSE((" Starting Firmware download through MDIO, it takes few seconds...\n")); 129 /* In case of FW Download is only for second die i.e for odd address of the die 130 * To get the micro out of reset on even die(previous die); for MDIO only 131 * Applicable for only duel die chips; 132 */ 133 chip_id = _furia_get_chip_id(pm_acc); 134 if (FURIA_IS_DUAL_DIE_DUPLEX(chip_id)) { 135 if ((pm_acc->addr & 0x1) == 0x1) { 136 PHYMOD_MEMCPY(&pa, pm_acc, sizeof(phymod_access_t)); 137 /* modify the mdio address to be even */ 138 pa.addr &= ~(0x1); 139 /* Set the 11th and 9th bit of even die to get the micro out of reset */ 140 PHYMOD_IF_ERR_RETURN 141 (READ_FURIA_PMA_PMD_REG(&pa,\ 142 FUR_PAD_CTRL_ext_uc_rstb_control_Adr,\ 143 &ext_uc_rstb_ctrl.data)); 144 ext_uc_rstb_ctrl.fields.out_frcval = 1; 145 ext_uc_rstb_ctrl.fields.ibof = 1; 146 PHYMOD_IF_ERR_RETURN 147 (WRITE_FURIA_PMA_PMD_REG(&pa,\ 148 FUR_PAD_CTRL_ext_uc_rstb_control_Adr,\ 149 ext_uc_rstb_ctrl.data)); 150 } 151 } 152 ret_val = furia_download_prog_eeprom(pm_acc, 153 furia_ucode_Furia, 154 furia_ucode_Furia_len, 155 0); 156 if ((ret_val != PHYMOD_E_NONE) && 157 (ret_val != FURIA_FW_ALREADY_DOWNLOADED) && 158 (ret_val != furia_ucode_Furia_len)) { 159 PHYMOD_RETURN_WITH_ERR 160 (PHYMOD_E_CONFIG, 161 (_PHYMOD_MSG("firmware download failed"))); 162 } else { 163 PHYMOD_DEBUG_VERBOSE(("Firmware download through MDIO success \n")); 164 } 165 166 break; 167 case phymodFirmwareLoadMethodExternal: 168 return PHYMOD_E_UNAVAIL; 169 break; 170 case phymodFirmwareLoadMethodNone: 171 /* Expected to download firmware from Flashed EEPROM */ 172 /* Firmware download works only when serboot pin is set on the chip */ 173 PHYMOD_IF_ERR_RETURN 174 (READ_FURIA_PMA_PMD_REG(pm_acc,\ 175 FUR_MICRO_BOOT_boot_por_Adr,\ 176 &boot_por.data)); 177 if (boot_por.fields.serboot) { 178 PHYMOD_IF_ERR_RETURN 179 (READ_FURIA_PMA_PMD_REG(pm_acc,\ 180 FUR_MICRO_BOOT_boot_por_Adr,\ 181 &boot_por.data)); 182 /* check download_done flags again */ 183 if (boot_por.fields.mst_dwld_done != 1 || boot_por.fields.slv_dwld_done != 1) { 184 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 185 (_PHYMOD_MSG("ERR:Firmware Download Done got cleared"))); 186 } 187 PHYMOD_IF_ERR_RETURN 188 (READ_FURIA_PMA_PMD_REG(pm_acc,\ 189 FUR_GEN_CNTRLS_firmware_version_Adr,\ 190 &data)); 191 if (data == 0x1) { 192 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 193 (_PHYMOD_MSG("ERR:Invalid Firmware version Downloaded"))); 194 } 195 PHYMOD_IF_ERR_RETURN 196 (READ_FURIA_PMA_PMD_REG(pm_acc,\ 197 FUR_GEN_CNTRLS_mst_running_chksum_Adr,\ 198 &data)); 199 if (0x600D != data) { 200 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 201 (_PHYMOD_MSG("Master Dload chksum Fail"))); 202 } 203 PHYMOD_IF_ERR_RETURN 204 (READ_FURIA_PMA_PMD_REG(pm_acc,\ 205 FUR_GEN_CNTRLS_slv_running_chksum_Adr,\ 206 &data)); 207 if (0x600D != data) { 208 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 209 (_PHYMOD_MSG("Slave Dload chksum Fail"))); 210 } 211 /* Set Tx driver current, FIR main/pre/post default values 212 * Default values are 213 * driver current = 0xf 214 * TX FIR main = 0x3c 215 * TX FIR pre = 0x0 216 * TX FIR post = 0x0 217 */ 218 219 PHYMOD_IF_ERR_RETURN 220 (furia_tx_get(pm_acc, &tx_params)); 221 tx_params.amp = 0xf; 222 tx_params.pre = 0x0; 223 tx_params.post = 0x0; 224 tx_params.main = 0x3c; 225 PHYMOD_IF_ERR_RETURN 226 (furia_tx_set(pm_acc, &tx_params)); 227 228 } 229 break; 230 case phymodFirmwareLoadMethodProgEEPROM: 231 PHYMOD_DIAG_OUT(("Firmware will be downloaded first, and flashed on to EEPROM \n")); 232 PHYMOD_DIAG_OUT(("This process will take few minutes.....\n")); 233 ret_val = furia_download_prog_eeprom(pm_acc, 234 furia_ucode_Furia, 235 furia_ucode_Furia_len, 236 1); 237 if ((ret_val != PHYMOD_E_NONE) && 238 (ret_val != FURIA_FW_ALREADY_DOWNLOADED) && 239 (ret_val != furia_ucode_Furia_len)) { 240 PHYMOD_RETURN_WITH_ERR 241 (PHYMOD_E_FAIL, 242 (_PHYMOD_MSG("Flasing Firmware to EEPROM faliled failed"))); 243 } else { 244 PHYMOD_DIAG_OUT(("Firmware is flashed to EEPROM successfully\n")); 245 } 246 break; 247 default: 248 PHYMOD_RETURN_WITH_ERR 249 (PHYMOD_E_CONFIG, 250 (_PHYMOD_MSG("illegal fw load method"))); 251 } 252 return PHYMOD_E_NONE; 253 } 254 255 /** Set Interface config 256 * This function sets interface configuration (interface, speed, frequency of 257 * operation). This is requried to put the furia into specific mode specified 258 * by the user. 259 * 260 * @param phy Pointer to phymod phy access structure 261 * @param flags Currently unused and reserved for future use 262 * @param config Interface config structure where user specifies 263 * interface, speed and the frequency of operation. 264 * 265 * @return PHYMOD_E_NONE successful function execution 266 */ 267 int furia_phy_interface_config_set(const phymod_phy_access_t* phy, 268 uint32_t flags, 269 const phymod_phy_inf_config_t* config) 270 { 271 return furia_set_config_mode(&phy->access, 272 config); 273 274 } 275 276 /** Get Interface config 277 * This function retrieves interface configuration(interface, speed and 278 * frequency of operation) from the device. 279 * 280 * @param phy Pointer to phymod phy access structure 281 * @param flags Currently unused and reserved for future use 282 * @param config Interface config structure where 283 * interface, speed and the frequency of operation 284 * will be populated from device . 285 * 286 * @return PHYMOD_E_NONE successful function execution 287 */ 288 int furia_phy_interface_config_get(const phymod_phy_access_t* phy, 289 uint32_t flags, 290 phymod_ref_clk_t ref_clock, 291 phymod_phy_inf_config_t* config) 292 { 293 return furia_get_config_mode(&phy->access, 294 &config->interface_type, 295 &config->data_rate, 296 &config->ref_clock, 297 &config->interface_modes, config, (uint16_t)(*(&phy->access.lane_mask))); 298 } 299 300 /** Core Init 301 * This function initializes the furia core and 302 * download the firmware and setting the PHY into 303 * default mode. 304 * 305 * @param phy Pointer to phymod core access structure 306 * @param init_config Init configuration specified by user 307 * @param core_status Core status read from PHY chip 308 * 309 * @return PHYMOD_E_NONE successful function execution 310 */ 311 int furia_core_init(const phymod_core_access_t* core, 312 const phymod_core_init_config_t* init_config, 313 const phymod_core_status_t* core_status) 314 { 315 uint32_t chip_id = 0; 316 int num_lanes = 0; 317 int rv = -1; 318 int lane_index = 0; 319 uint32_t phy_id_idx = 0; 320 uint32_t exist_phy = 0; 321 uint32_t is_write_disabled=0; 322 phymod_phy_inf_config_t interface; 323 phymod_access_t l_access; 324 FUR_GEN_CNTRLS_micro_sync_7_t gen_ctrls_intf_type; 325 FUR_GEN_CNTRLS_micro_sync_6_t gen_ctrls6_intf_type; 326 FURIA_DEVICE_AUX_MODE_T aux_mode; 327 FURIA_DEVICE_AUX_MODE_T *an_aux_mode = (FURIA_DEVICE_AUX_MODE_T*)init_config->interface.device_aux_modes; 328 uint32_t *tx_source_array=NULL; 329 phymod_phy_access_t l_phy_access; 330 PHYMOD_MEMSET(&gen_ctrls_intf_type, 0 , sizeof(FUR_GEN_CNTRLS_micro_sync_7_t)); 331 PHYMOD_MEMSET(&gen_ctrls6_intf_type, 0 , sizeof(FUR_GEN_CNTRLS_micro_sync_6_t)); 332 333 PHYMOD_MEMSET(&aux_mode, 0 , sizeof(FURIA_DEVICE_AUX_MODE_T)); 334 PHYMOD_MEMSET(&aux_mode, 0 , sizeof(FURIA_DEVICE_AUX_MODE_T)); 335 PHYMOD_MEMCPY(&l_access, &core->access, sizeof(phymod_access_t)); 336 PHYMOD_MEMSET(&l_phy_access, 0 , sizeof(phymod_phy_access_t)); 337 PHYMOD_MEMCPY(&(l_phy_access.access), &l_access, sizeof(phymod_access_t)); 338 /* Write is disabled in warm boot, get the status of of write disable flag */ 339 PHYMOD_IF_ERR_RETURN( 340 phymod_is_write_disabled(&core->access, &is_write_disabled)); 341 342 aux_mode.avdd_txdrv = init_config->tx_input_voltage; 343 aux_mode.ull_dp = init_config->op_datapath; 344 345 interface.data_rate = init_config->interface.data_rate; 346 interface.ref_clock = init_config->interface.ref_clock; 347 interface.interface_type = init_config->interface.interface_type; 348 interface.pll_divider_req = init_config->interface.pll_divider_req; 349 interface.interface_modes = init_config->interface.interface_modes; 350 num_lanes = FURIA_IS_SIMPLEX(chip_id) ? 8 : 4; 351 _furia_get_phy_id_idx(core->access.addr, &phy_id_idx, &exist_phy); 352 chip_id = _furia_get_chip_id(&core->access); 353 if(!is_write_disabled){ 354 PHYMOD_IF_ERR_RETURN 355 (_furia_core_firmware_load(core, 356 init_config->firmware_load_method, 357 init_config->firmware_loader)); 358 /* enable/disable ULL Datapath based on static configuration specified by the user */ 359 PHYMOD_IF_ERR_RETURN 360 (_furia_cfg_fw_ull_dp(core, aux_mode.ull_dp)); 361 /* Select AVDD TXDRV voltage based on static configuration specified by the user */ 362 PHYMOD_IF_ERR_RETURN 363 (_furia_core_avddtxdrv_config_set(core, aux_mode.avdd_txdrv)); 364 if(an_aux_mode){ 365 PHYMOD_IF_ERR_RETURN 366 (_furia_cfg_an_master_lane(core, an_aux_mode->an_master_lane)); 367 } 368 PHYMOD_IF_ERR_RETURN ( 369 _furia_core_cfg_pfifo_4_max_ieee_input_skew(&core->access, 370 init_config->tx_fifo_sync_offset, init_config->rx_fifo_sync_offset)); 371 PHYMOD_IF_ERR_RETURN 372 (_furia_pcs_monitor_enable_set(core, 0)); 373 374 PHYMOD_IF_ERR_RETURN 375 (READ_FURIA_PMA_PMD_REG(&core->access,\ 376 FUR_GEN_CNTRLS_micro_sync_7_Adr,\ 377 &gen_ctrls_intf_type.data)); 378 PHYMOD_IF_ERR_RETURN 379 (READ_FURIA_PMA_PMD_REG(&core->access,\ 380 FUR_GEN_CNTRLS_micro_sync_6_Adr,\ 381 &gen_ctrls6_intf_type.data)); 382 383 384 if (FURIA_IS_DUPLEX(chip_id)) { 385 PHYMOD_IF_ERR_RETURN 386 (furia_fec_enable_set(&core->access, 0)); 387 /*clear sync7 register in hard reboot*/ 388 gen_ctrls_intf_type.fields.intf_type_ln0 = 0; 389 gen_ctrls_intf_type.fields.intf_type_ln1 = 0; 390 gen_ctrls_intf_type.fields.intf_type_ln2 = 0; 391 gen_ctrls_intf_type.fields.intf_type_ln3 = 0; 392 PHYMOD_IF_ERR_RETURN 393 (WRITE_FURIA_PMA_PMD_REG(&core->access,\ 394 FUR_GEN_CNTRLS_micro_sync_7_Adr,\ 395 gen_ctrls_intf_type.data)); 396 } 397 398 if (!exist_phy) { 399 if (FURIA_IS_SIMPLEX(chip_id)) { 400 if (chip_id == FURIA_ID_82212) { 401 if ((core->access.addr & 1) == 1) { 402 glb_phy_list[phy_id_idx].tx_lanes = 0xba5432; 403 } else { 404 glb_phy_list[phy_id_idx].tx_lanes = 0x987610; 405 } 406 } 407 } 408 } 409 if (FURIA_IS_SIMPLEX(chip_id)) { 410 interface.data_rate = 25000; 411 interface.interface_type = phymodInterfaceKR; 412 l_access.lane_mask = 0xFF; 413 l_access.flags &= (~(1 << 31)); 414 rv = furia_set_config_mode(&l_access, &interface); 415 if(!rv) { 416 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 417 gen_ctrls_intf_type.fields.intf_type_ln0 = 3; 418 gen_ctrls_intf_type.fields.intf_type_ln1 = 3; 419 gen_ctrls_intf_type.fields.intf_type_ln2 = 3; 420 gen_ctrls_intf_type.fields.intf_type_ln3 = 3; 421 gen_ctrls_intf_type.fields.intf_type_ln4 = 3; 422 gen_ctrls_intf_type.fields.intf_type_ln5 = 3; 423 gen_ctrls_intf_type.fields.intf_type_ln6 = 3; 424 gen_ctrls_intf_type.fields.intf_type_ln7 = 3; 425 } 426 PHYMOD_IF_ERR_RETURN 427 (WRITE_FURIA_PMA_PMD_REG(&core->access,\ 428 FUR_GEN_CNTRLS_micro_sync_7_Adr,\ 429 gen_ctrls_intf_type.data)); 430 } else { 431 for(lane_index = 0; lane_index < num_lanes; lane_index++) { 432 gen_ctrls_intf_type.fields.intf_type_ln0 = 0; 433 gen_ctrls_intf_type.fields.intf_type_ln1 = 0; 434 gen_ctrls_intf_type.fields.intf_type_ln2 = 0; 435 gen_ctrls_intf_type.fields.intf_type_ln3 = 0; 436 gen_ctrls_intf_type.fields.intf_type_ln4 = 0; 437 gen_ctrls_intf_type.fields.intf_type_ln5 = 0; 438 gen_ctrls_intf_type.fields.intf_type_ln6 = 0; 439 gen_ctrls_intf_type.fields.intf_type_ln7 = 0; 440 } 441 PHYMOD_IF_ERR_RETURN 442 (WRITE_FURIA_PMA_PMD_REG(&core->access, 443 FUR_GEN_CNTRLS_micro_sync_7_Adr, 444 gen_ctrls_intf_type.data)); 445 } 446 } 447 gen_ctrls6_intf_type.fields.ref_clk = 1; 448 } 449 if (!exist_phy) { 450 if (FURIA_IS_SIMPLEX(chip_id)) { 451 if(is_write_disabled){/* warmboot enabled */ 452 tx_source_array = (uint32_t *)PHYMOD_MALLOC( num_lanes * sizeof(uint32_t),"tx_source_array" ); 453 if(tx_source_array == NULL){ 454 return PHYMOD_E_MEMORY; 455 } 456 rv = furia_phy_lane_cross_switch_map_get(&l_phy_access,tx_source_array); 457 if (rv != PHYMOD_E_NONE){ 458 PHYMOD_FREE(tx_source_array); 459 return rv; 460 } 461 for (lane_index = 0; lane_index < 8; lane_index ++) { 462 glb_phy_list[phy_id_idx].tx_lanes |= (tx_source_array[lane_index] << (4 * lane_index)); 463 } 464 PHYMOD_FREE(tx_source_array); 465 }else{ /* cold boot */ 466 for (lane_index = 0; lane_index < 8; lane_index ++) { 467 glb_phy_list[phy_id_idx].tx_lanes |= (lane_index << (4 * lane_index)); 468 } 469 if (chip_id == FURIA_ID_82212) { 470 if ((core->access.addr & 1) == 1) { 471 glb_phy_list[phy_id_idx].tx_lanes = 0xba5432; 472 } else { 473 glb_phy_list[phy_id_idx].tx_lanes = 0x987610; 474 } 475 } 476 } 477 } else { 478 if(is_write_disabled){ /* warmboot enabled */ 479 tx_source_array = (uint32_t *)PHYMOD_MALLOC( num_lanes * sizeof(uint32_t),"tx_source_array" ); 480 if(tx_source_array == NULL){ 481 return PHYMOD_E_MEMORY; 482 } 483 rv = furia_phy_lane_cross_switch_map_get(&l_phy_access,tx_source_array); 484 if (rv != PHYMOD_E_NONE){ 485 PHYMOD_FREE(tx_source_array); 486 return rv; 487 } 488 for (lane_index = 0; lane_index < 4; lane_index ++) { 489 glb_phy_list[phy_id_idx].tx_lanes |= (tx_source_array[lane_index] << (4 * lane_index)); 490 } 491 l_phy_access.access.flags = SIDE_B << FURIA_IF_SIDE_SHIFT;/*get array for the system side*/ 492 rv = furia_phy_lane_cross_switch_map_get(&l_phy_access,tx_source_array); 493 if (rv != PHYMOD_E_NONE){ 494 PHYMOD_FREE(tx_source_array); 495 return rv; 496 } 497 for (lane_index = 0; lane_index < 4; lane_index ++) { 498 glb_phy_list[phy_id_idx].tx_lanes |= (tx_source_array[lane_index] << (4 * (lane_index + 4))); 499 } 500 PHYMOD_FREE(tx_source_array); 501 }else{ /* cold boot */ 502 for (lane_index = 0; lane_index < 4; lane_index ++) { 503 glb_phy_list[phy_id_idx].tx_lanes |= (lane_index << (4 * lane_index)); 504 } 505 for (lane_index = 0; lane_index < 4; lane_index ++) { 506 glb_phy_list[phy_id_idx].tx_lanes |= (lane_index << (4 * (lane_index + 4))); 507 } 508 } 509 } 510 } 511 return PHYMOD_E_NONE; 512 } 513 514 /** PHY init 515 * This function initializes PHY 516 * 517 * @param phy Pointer to phymod phy access structure 518 * @param init_config User specified phy init configuration 519 * 520 * @return PHYMOD_E_NONE successful function execution 521 */ 522 int furia_phy_init(const phymod_phy_access_t* phy, 523 const phymod_phy_init_config_t* init_config) 524 { 525 /* int pll_restart = 0; 526 const phymod_access_t *pm_acc = &phy->access; 527 */ 528 529 PHYMOD_IF_ERR_RETURN 530 (_furia_core_rptr_rtmr_mode_set(&phy->access, init_config->op_mode)); 531 532 PHYMOD_IF_ERR_RETURN 533 (_furia_core_cfg_hcd_link_status_criteria(&phy->access, init_config->an_link_qualifier)); 534 535 PHYMOD_IF_ERR_RETURN 536 (_furia_core_cfg_polarity_set(&phy->access, init_config->polarity.rx_polarity, init_config->polarity.tx_polarity)); 537 538 PHYMOD_IF_ERR_RETURN 539 (_furia_core_cfg_tx_set(&phy->access, init_config->tx)); 540 return PHYMOD_E_NONE; 541 } 542 543 /** Get PHY link status 544 * This function retrieves PHY link status from device 545 * 546 * @param phy Pointer to phymod phy access structure 547 * @param link_status Link status retrieved from the device 548 * 549 * @return PHYMOD_E_NONE successful function execution 550 */ 551 int furia_phy_link_status_get(const phymod_phy_access_t* phy, 552 uint32_t* link_status) 553 { 554 return furia_link_status(&phy->access, link_status); 555 } 556 557 /** PHY register read 558 * This function reads the PHY register 559 * 560 * @param phy Pointer to phymod phy access structure 561 * @param reg_addr PHY Register Address to Read 562 * @param val PHY Register content of the specified 563 * register Address to Read 564 * 565 * @return PHYMOD_E_NONE successful function execution 566 */ 567 int furia_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, 568 uint32_t *val) 569 { 570 /*check if this is a slice reg read*/ 571 int rv = PHYMOD_E_NONE, rv1 = PHYMOD_E_NONE; 572 if (phy->access.devad & FURIA_BIT(SLICE_REG_SET_BIT)) { 573 rv1 = furia_slice_reg_set(&phy->access); 574 } 575 576 rv = furia_reg_read(&phy->access,\ 577 FURIA_CLAUSE45_ADDR((phy->access.devad), (reg_addr)),\ 578 val); 579 if (phy->access.devad & FURIA_BIT(SLICE_REG_SET_BIT)) { 580 if (rv1 == 0) { 581 rv1 = furia_slice_reg_unset(&phy->access); 582 } 583 584 } 585 return rv; 586 } 587 588 589 /** PHY register write 590 * This function is used to write content to PHY register 591 * 592 * @param phy Pointer to phymod phy access structure 593 * @param reg_addr PHY Register Address to Write 594 * @param val Content/Value to Write to the PHY Register 595 * 596 * @return PHYMOD_E_NONE successful function execution 597 */ 598 int furia_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, 599 uint32_t val) 600 { 601 /*check if this is a slice reg read*/ 602 int rv = PHYMOD_E_NONE, rv1 = PHYMOD_E_NONE; 603 if (phy->access.devad & FURIA_BIT(SLICE_REG_SET_BIT)) { 604 rv1 = furia_slice_reg_set(&phy->access); 605 } 606 rv = furia_reg_write(&phy->access,\ 607 FURIA_CLAUSE45_ADDR((phy->access.devad), (reg_addr)),\ 608 val); 609 if (phy->access.devad & FURIA_BIT(SLICE_REG_SET_BIT)) { 610 if (rv1 == 0) { 611 rv1 = furia_slice_reg_unset(&phy->access); 612 } 613 614 } 615 return rv; 616 617 } 618 619 /** PHY core info get 620 * This function is used to write content to PHY register 621 * 622 * @param phy Pointer to phymod phy access structure 623 * @param info Pointer to core info structure 624 * 625 * @return PHYMOD_E_NONE successful function execution 626 */ 627 int furia_core_info_get(const phymod_core_access_t* phy, phymod_core_info_t* info) 628 { 629 uint32_t chip_id; 630 chip_id = _furia_get_chip_id(&phy->access); 631 info->serdes_id = chip_id; 632 info->core_version = phymodCoreVersionFuriaA2; 633 PHYMOD_STRNCPY(info->name, "FuriaA2", PHYMOD_STRLEN("FuriaA2")+1); 634 info->phy_id0 = FURIA_ID0; 635 info->phy_id1 = FURIA_ID1; 636 return PHYMOD_E_NONE; 637 } 638 /** PHY polarity set 639 * This function is used to set the lane polarity 640 * 641 * @param phy Pointer to phymod phy access structure 642 * @param polarity Pointer to phymod_polarity_t for rx and tx 643 * 644 * @return PHYMOD_E_NONE successful function execution 645 */ 646 int furia_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity) 647 { 648 return furia_tx_rx_polarity_set(&phy->access, polarity->tx_polarity, polarity->rx_polarity); 649 } 650 651 652 /** PHY polarity get 653 * This function is used to get the lane polarity 654 * 655 * @param phy Pointer to phymod phy access structure 656 * @param polarity Pointer to phymod_polarity_t for rx and tx 657 * 658 * @return PHYMOD_E_NONE successful function execution 659 */ 660 int furia_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity) 661 { 662 return furia_tx_rx_polarity_get(&phy->access, &polarity->tx_polarity, &polarity->rx_polarity); 663 } 664 665 /** PHY Rx PMD lock 666 * PHY Rx PMD lock This function is used to get the rx PMD lock status 667 * 668 * @param phy Pointer to phymod phy access structure 669 * @param rx_seq_done Pointer to rx sequence 670 * 671 * @return PHYMOD_E_NONE successful function execution 672 */ 673 int furia_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_seq_done){ 674 return furia_pmd_lock_get(&phy->access, rx_seq_done); 675 } 676 677 /** PHY power set 678 * PHY power set This function is used to set the power 679 * 680 * @param phy Pointer to phymod phy access structure 681 * @param power Pointer to phymod phy power structure 682 * 683 * @return PHYMOD_E_NONE successful function execution 684 */ 685 int furia_phy_power_set(const phymod_phy_access_t* phy, 686 const phymod_phy_power_t* power) 687 { 688 /* Set Tx power */ 689 _furia_tx_rx_power_set(&phy->access, power->tx, 0); 690 /* Set Rx Power */ 691 _furia_tx_rx_power_set(&phy->access, power->rx, 1); 692 return PHYMOD_E_NONE; 693 } 694 695 int _furia_tx_rx_power_set(const phymod_access_t *pa, 696 phymod_power_t tx_rx_power, 697 uint8_t tx_rx) 698 { 699 switch(tx_rx_power) { 700 case phymodPowerOff: 701 PHYMOD_IF_ERR_RETURN 702 (furia_tx_rx_power_set(pa, tx_rx, 0)); 703 break; 704 case phymodPowerOn: 705 PHYMOD_IF_ERR_RETURN 706 (furia_tx_rx_power_set(pa, tx_rx, 1)); 707 break; 708 case phymodPowerOffOn: 709 break; 710 case phymodPowerNoChange: 711 break; 712 default: 713 break; 714 } 715 return PHYMOD_E_NONE; 716 } 717 718 /** PHY power get 719 * PHY power get This function is used to get the power 720 * 721 * @param phy Pointer to phymod phy access structure 722 * @param power Pointer to phymod phy power structure 723 * 724 * @return PHYMOD_E_NONE successful function execution 725 */ 726 int furia_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power) 727 { 728 phymod_power_t power_tx = 0, power_rx = 0; 729 PHYMOD_IF_ERR_RETURN 730 (furia_tx_rx_power_get(&phy->access, &power_tx, &power_rx)); 731 power->tx = power_tx; 732 power->rx = power_rx; 733 return PHYMOD_E_NONE; 734 } 735 736 /** PHY CL73 ability Set 737 * This function is used to set the CL73 ability of a lane 738 * 739 * @param phy Pointer to phymod phy access structure 740 * @param an_ability Pointer to the ability of cl73 741 * 742 * @return PHYMOD_E_NONE successful function execution 743 */ 744 int furia_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability) 745 { 746 furia_an_ability_t value; 747 PHYMOD_MEMSET(&value, 0, sizeof(value)); 748 749 value.cl73_adv.an_fec = an_ability->an_fec; 750 value.cl73_adv.an_cl72 = an_ability->an_cl72; 751 /*check if sgmii or not */ 752 if (PHYMOD_AN_CAP_SGMII_GET(an_ability)){ 753 return PHYMOD_E_PARAM; 754 } 755 756 /* Configure the user specified master lane */ 757 PHYMOD_IF_ERR_RETURN 758 (_furia_cfg_an_master_lane((phymod_core_access_t*)phy, an_ability->an_master_lane)); 759 /*next check pause */ 760 if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability)) { 761 value.cl73_adv.an_pause = FURIA_SYMM_PAUSE; 762 } else if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability)) { 763 value.cl73_adv.an_pause = FURIA_ASYM_PAUSE; 764 } else { 765 value.cl73_adv.an_pause = FURIA_NO_PAUSE; 766 } 767 768 /*check cl73 and cl73 bam ability */ 769 if (PHYMOD_AN_CAP_1G_KX_GET(an_ability->an_cap)) { 770 value.cl73_adv.an_base_speed = FURIA_CL73_1000BASE_KX; 771 } else if (PHYMOD_AN_CAP_10G_KR_GET(an_ability->an_cap)) { 772 value.cl73_adv.an_base_speed = FURIA_CL73_10GBASE_KR; 773 } else if (PHYMOD_AN_CAP_40G_KR4_GET(an_ability->an_cap)) { 774 value.cl73_adv.an_base_speed = FURIA_CL73_40GBASE_KR4; 775 } else if (PHYMOD_AN_CAP_40G_CR4_GET(an_ability->an_cap)) { 776 value.cl73_adv.an_base_speed = FURIA_CL73_40GBASE_CR4; 777 } else if (PHYMOD_AN_CAP_100G_CR10_GET(an_ability->an_cap)) { 778 return PHYMOD_E_UNAVAIL; 779 } else if (PHYMOD_AN_CAP_100G_CR4_GET(an_ability->an_cap)) { 780 value.cl73_adv.an_base_speed = FURIA_CL73_100GBASE_CR4; 781 } else if (PHYMOD_AN_CAP_100G_KR4_GET(an_ability->an_cap)) { 782 value.cl73_adv.an_base_speed = FURIA_CL73_100GBASE_KR4; 783 } else if (an_ability->an_cap == 0) { 784 return PHYMOD_E_NONE; 785 } else { 786 return PHYMOD_E_PARAM; 787 } 788 789 PHYMOD_IF_ERR_RETURN 790 (_furia_autoneg_ability_set(&phy->access, &value)); 791 return PHYMOD_E_NONE; 792 793 } 794 795 /** PHY CL73 ability get 796 * This function is used to get the CL73 ability of a lane 797 * 798 * @param phy Pointer to phymod phy access structure 799 * @param an_ability Pointer to the ability of cl73 800 * 801 * @return PHYMOD_E_NONE successful function execution 802 */ 803 int furia_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type) 804 { 805 furia_an_ability_t value; 806 807 PHYMOD_IF_ERR_RETURN( 808 _furia_autoneg_ability_get (&phy->access, &value)); 809 810 an_ability_get_type->an_fec = value.cl73_adv.an_fec; 811 an_ability_get_type->an_master_lane = value.an_master_lane; 812 switch (value.cl73_adv.an_pause) { 813 case FURIA_ASYM_PAUSE: 814 PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get_type); 815 break; 816 case FURIA_SYMM_PAUSE: 817 PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get_type); 818 break; 819 default: 820 break; 821 } 822 823 /*first check cl73 ability*/ 824 switch (value.cl73_adv.an_base_speed) { 825 case FURIA_CL73_100GBASE_CR10: 826 PHYMOD_AN_CAP_100G_CR10_SET(an_ability_get_type->an_cap); 827 break; 828 case FURIA_CL73_40GBASE_CR4: 829 PHYMOD_AN_CAP_40G_CR4_SET(an_ability_get_type->an_cap); 830 break; 831 case FURIA_CL73_40GBASE_KR4: 832 PHYMOD_AN_CAP_40G_KR4_SET(an_ability_get_type->an_cap); 833 break; 834 case FURIA_CL73_10GBASE_KR: 835 PHYMOD_AN_CAP_10G_KR_SET(an_ability_get_type->an_cap); 836 break; 837 case FURIA_CL73_1000BASE_KX: 838 PHYMOD_AN_CAP_1G_KX_SET(an_ability_get_type->an_cap); 839 break; 840 case FURIA_CL73_100GBASE_CR4: 841 PHYMOD_AN_CAP_100G_CR4_SET(an_ability_get_type->an_cap); 842 break; 843 case FURIA_CL73_100GBASE_KR4: 844 PHYMOD_AN_CAP_100G_KR4_SET(an_ability_get_type->an_cap); 845 break; 846 default: 847 break; 848 } 849 return PHYMOD_E_NONE; 850 } 851 852 /** PHY enable/Disable CL73 853 * This function is used to enable/disable CL73 of a lane 854 * 855 * @param phy Pointer to phymod phy access structure 856 * @param an Pointer to the AN control 857 * 858 * @return PHYMOD_E_NONE successful function execution 859 */ 860 int furia_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an) 861 { 862 return (_furia_autoneg_set(&phy->access, an)); 863 } 864 865 /** Get CL73 completion state 866 * This function is used get CL73 completion state of a lane 867 * 868 * @param phy Pointer to phymod phy access structure 869 * @param an Pointer to the AN control 870 * @param an_done Pointer to the AN completion state 871 * 872 * @return PHYMOD_E_NONE successful function execution 873 */ 874 int furia_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done) 875 { 876 return (_furia_autoneg_get(&phy->access, an, an_done)); 877 } 878 879 /** PHY CL73 remote ability get 880 * This function is used to get the CL73 remote ability of a lane 881 * 882 * @param phy Pointer to phymod phy access structure 883 * @param an_ability Pointer to the ability of cl73 884 * 885 * @return PHYMOD_E_NONE successful function execution 886 */ 887 int furia_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get) 888 { 889 return (_furia_autoneg_remote_ability_get(&phy->access, an_ability_get)); 890 } 891 892 /** Get CL73 status 893 * This function is used get CL73 resolved status 894 * 895 * @param phy Pointer to phymod phy access structure 896 * @param status Pointer to AN resolved status 897 * 898 * @return PHYMOD_E_NONE successful function execution 899 */ 900 int furia_autoneg_status_get(const phymod_phy_access_t* phy, phymod_autoneg_status_t* status) 901 { 902 /* Place your code here */ 903 904 905 return PHYMOD_E_NONE; 906 } 907 908 /** Set Core reset 909 * This function is used to reset the core 910 * 911 * @param core Pointer to phymod core access structure 912 * @param reset_mode Type of reset 913 * 0 - Hard reset 914 * 1 - Soft reset 915 * @param direction Reset direction 916 * 0 - In 917 * 1 - Out 918 * 2 - In Out (toggle) 919 * @return PHYMOD_E_NONE successful function execution 920 */ 921 int furia_core_reset_set(const phymod_core_access_t* core, 922 phymod_reset_mode_t reset_mode, 923 phymod_reset_direction_t direction) 924 { 925 return furia_reset_set(&core->access, reset_mode, direction); 926 } 927 /** Get Core reset 928 * This function is used to get the status of core reset 929 * 930 * @param core Pointer to phymod core access structure 931 * @param reset_mode Type of reset 932 * 0 - Hard reset 933 * 1 - Soft reset 934 * @param direction Reset direction 935 * 0 - In 936 * 1 - Out 937 * 2 - In Out (toggle) 938 * @return PHYMOD_E_NONE successful function execution 939 */ 940 int furia_core_reset_get(const phymod_core_access_t* core, 941 phymod_reset_mode_t reset_mode, 942 phymod_reset_direction_t* direction) 943 { 944 return PHYMOD_E_UNAVAIL; 945 } 946 947 /** Tx set 948 * This function is used to set transmitter analog parameters 949 * 950 * @param phy Pointer to phymod phy access structure 951 * @param tx Pointer to tx param structure 952 * 953 * @return PHYMOD_E_NONE successful function execution 954 */ 955 int furia_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx) 956 { 957 return furia_tx_set(&phy->access, tx); 958 } 959 960 /** Tx get 961 * This function is used to get transmitter analog parameters 962 * 963 * @param phy Pointer to phymod phy access structure 964 * @param tx Pointer to tx param structure 965 * 966 * @return PHYMOD_E_NONE successful function execution 967 */ 968 int furia_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 969 { 970 return furia_tx_get(&phy->access, tx); 971 } 972 973 /** Rx set 974 * This function is used to set receiver analog parameters 975 * 976 * @param phy Pointer to phymod phy access structure 977 * @param rx Pointer to rx param structure 978 * 979 * @return PHYMOD_E_NONE successful function execution 980 */ 981 int furia_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx) 982 { 983 return furia_rx_set(&phy->access, rx); 984 } 985 986 /** Rx get 987 * This function is used to get receiver analog parameters 988 * 989 * @param phy Pointer to phymod phy access structure 990 * @param rx Pointer to rx param structure 991 * 992 * @return PHYMOD_E_NONE successful function execution 993 */ 994 int furia_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx) 995 { 996 return furia_rx_get(&phy->access, rx); 997 } 998 999 /** PHY Rx adaptation resume 1000 * This function is used to perform PHY reset 1001 * 1002 * @param phy Pointer to phymod phy access structure 1003 * 1004 * @return PHYMOD_E_NONE successful function execution 1005 */ 1006 int furia_phy_rx_adaptation_resume(const phymod_phy_access_t* phy) 1007 { 1008 return furia_rx_adaptation_resume(&phy->access); 1009 } 1010 /** Set PHY reset 1011 * This function is used to perform PHY reset 1012 * 1013 * @param phy Pointer to phymod phy access structure 1014 * @param reset Pointer to phy reset structure 1015 * 1016 * @return PHYMOD_E_NONE successful function execution 1017 */ 1018 int furia_phy_reset_set(const phymod_phy_access_t* phy, 1019 const phymod_phy_reset_t* reset) 1020 { 1021 return _furia_phy_reset_set(&phy->access, reset); 1022 } 1023 1024 /** Get PHY reset 1025 * This function is used to get status of PHY reset 1026 * 1027 * @param phy Pointer to phymod phy access structure 1028 * @param reset Pointer to phy reset structure 1029 * 1030 * @return PHYMOD_E_NONE successful function execution 1031 */ 1032 int furia_phy_reset_get(const phymod_phy_access_t* phy, 1033 phymod_phy_reset_t* reset) 1034 { 1035 return _furia_phy_reset_get(&phy->access, reset); 1036 } 1037 1038 /** Tx lane control set 1039 * This function is used to set the lane control for example 1040 * resetting the traffic 1041 * 1042 * @param phy Pointer to phymod phy access structure 1043 * @param tx_control Tx lane control 1044 * 1045 * @return PHYMOD_E_NONE successful function execution 1046 */ 1047 int furia_phy_tx_lane_control_set(const phymod_phy_access_t* phy, 1048 phymod_phy_tx_lane_control_t tx_control) 1049 { 1050 return furia_tx_lane_control_set(&phy->access, tx_control); 1051 } 1052 1053 /** Tx lane control get 1054 * This function is used to get the lane control status for 1055 * a particular lane control 1056 * 1057 * 1058 * @param phy Pointer to phymod phy access structure 1059 * @param tx_control Tx lane control 1060 * 1061 * @return PHYMOD_E_NONE successful function execution 1062 */ 1063 int furia_phy_tx_lane_control_get(const phymod_phy_access_t* phy, 1064 phymod_phy_tx_lane_control_t* tx_control) 1065 { 1066 return furia_tx_lane_control_get(&phy->access, tx_control);; 1067 } 1068 1069 1070 /** Rx lane control set 1071 * This function is used to set the lane control for example 1072 * resetting the traffic 1073 * 1074 * @param phy Pointer to phymod phy access structure 1075 * @param tx_control Tx lane control 1076 * 1077 * @return PHYMOD_E_NONE successful function execution 1078 */ 1079 int furia_phy_rx_lane_control_set(const phymod_phy_access_t* phy, 1080 phymod_phy_rx_lane_control_t rx_control) 1081 { 1082 return furia_rx_lane_control_set(&phy->access, rx_control); 1083 } 1084 1085 1086 /** Rx lane control get 1087 * This function is used to get the lane control status for 1088 * a particular lane control 1089 * 1090 * 1091 * @param phy Pointer to phymod phy access structure 1092 * @param tx_control Tx lane control 1093 * 1094 * @return PHYMOD_E_NONE successful function execution 1095 */ 1096 int furia_phy_rx_lane_control_get(const phymod_phy_access_t* phy, 1097 phymod_phy_rx_lane_control_t* rx_control) 1098 { 1099 return furia_rx_lane_control_get(&phy->access, rx_control); 1100 } 1101 /** Set loopback 1102 * This function is used to set a particular loopback mode 1103 * 1104 * @param phy Pointer to phymod phy access structure 1105 * @param loopback Type of loopback 1106 * 0 - Global loopback 1107 * 1 - Global PMD loopback 1108 * 2 - Remote PMD loopback 1109 * 3 - Remote PCS loopback 1110 * 4 - Digital PMD loopback 1111 * @enable Enable or disable 1112 * 0 - disable 1113 * 1 - enable 1114 * 1115 * @return PHYMOD_E_NONE successful function execution 1116 */ 1117 int furia_phy_loopback_set(const phymod_phy_access_t* phy, 1118 phymod_loopback_mode_t loopback, 1119 uint32_t enable) 1120 { 1121 uint32_t ena_dis = 0; 1122 PHYMOD_IF_ERR_RETURN(furia_loopback_get(&phy->access, loopback, &ena_dis)); 1123 if (ena_dis || enable) { 1124 return furia_loopback_set(&phy->access, loopback, enable); 1125 } 1126 return PHYMOD_E_NONE; 1127 } 1128 1129 /** Get loopback 1130 * This function is used to get the status of a particular loopback mode 1131 * whether or not enabled 1132 * 1133 * @param phy Pointer to phymod phy access structure 1134 * @param loopback Type of loopback 1135 * 0 - Global loopback 1136 * 1 - Global PMD loopback 1137 * 2 - Remote PMD loopback 1138 * 3 - Remote PCS loopback 1139 * 4 - Digital PMD loopback 1140 * @enable Enable or disable 1141 * 0 - disable 1142 * 1 - enable 1143 * 1144 * @return PHYMOD_E_NONE successful function execution 1145 */ 1146 int furia_phy_loopback_get(const phymod_phy_access_t* phy, 1147 phymod_loopback_mode_t loopback, 1148 uint32_t* enable) 1149 { 1150 return furia_loopback_get(&phy->access, loopback, enable); 1151 } 1152 1153 /** Set Force Tx training 1154 * This function is used to enable/disable forced Tx training 1155 * 1156 * @param phy Pointer to phymod phy access structure 1157 * @param enable enable / disable force Tx training 1158 * 1 - enable 1159 * 0 - disable 1160 * 1161 * @return PHYMOD_E_NONE successful function execution 1162 */ 1163 int furia_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en) 1164 { 1165 return furia_force_tx_training_set(&phy->access, cl72_en); 1166 } 1167 1168 1169 /** Get force Tx training 1170 * This function is used to get the status whether Tx training is enabled or disabled 1171 * 1172 * @param phy Pointer to phymod phy access structure 1173 * @param enable enable or disable 1174 * 1 - enable 1175 * 0 - disable 1176 * 1177 * @return PHYMOD_E_NONE successful function execution 1178 */ 1179 int furia_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en) 1180 { 1181 return furia_force_tx_training_get(&phy->access, cl72_en); 1182 } 1183 1184 /** Get force Tx training status 1185 * This function is used to get the status of Tx training 1186 * 1187 * @param phy Pointer to phymod phy access structure 1188 * @param enable enable or disable 1189 * 1 - enable 1190 * 0 - disable 1191 * @param training_failure training failure status 1192 * 1 - failure detected 1193 * 0 - no failure detected 1194 * @trained Receiver training status 1195 * 1 - receiver trained 1196 * 0 - receiver not trained 1197 * 1198 * @return PHYMOD_E_NONE successful function execution 1199 */ 1200 int furia_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status) 1201 { 1202 return furia_force_tx_training_status_get(&phy->access, status); 1203 } 1204 1205 /** Get core firmware info 1206 * This function is used to get core firmware version and CRC 1207 * 1208 * 1209 * @param core Pointer to phymod core access structure 1210 * @param fw_info Firmware information such as version and CRC 1211 * 1212 * @return PHYMOD_E_NONE successful function execution 1213 */ 1214 int furia_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info) 1215 { 1216 return furia_firmware_info_get(&core->access, fw_info); 1217 } 1218 1219 int furia_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_config) 1220 { 1221 return furia_firmware_core_config_set(&phy->access, fw_config); 1222 } 1223 1224 1225 int furia_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_config) 1226 { 1227 return furia_firmware_core_config_get(&phy->access, fw_config); 1228 } 1229 1230 1231 int furia_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config) 1232 { 1233 return furia_firmware_lane_config_set(&phy->access, fw_config); 1234 } 1235 1236 1237 int furia_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config) 1238 { 1239 return furia_firmware_lane_config_get(&phy->access, fw_config); 1240 } 1241 /** Restart PLL Sequecer 1242 * This function is used to get restart the PLL sequencer 1243 * 1244 * 1245 * @param core Pointer to phymod core access structure 1246 * @param flags Reserved for Furtuer use 1247 * @param operation Operation to perform on PLL sequencer 1248 * 1249 * @return PHYMOD_E_NONE successful function execution 1250 */ 1251 int furia_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation) 1252 { 1253 return furia_pll_sequencer_restart(&core->access, operation); 1254 } 1255 /** FEC enable set 1256 * This function is used to enable the FEC 1257 * 1258 * @param phy Pointer to phymod phy access structure 1259 * @param enable enable or disable 1260 * 1 - enable 1261 * 0 - disable 1262 * 1263 * @return PHYMOD_E_NONE successful function execution 1264 */ 1265 int furia_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 1266 { 1267 return furia_fec_enable_set(&phy->access, enable); 1268 } 1269 /** FEC enable get 1270 * This function is used to check whether or not FEC is enabled 1271 * 1272 * @param phy Pointer to phymod phy access structure 1273 * @param enable enable or disable 1274 * 1 - enable 1275 * 0 - disable 1276 * 1277 * @return PHYMOD_E_NONE successful function execution 1278 */ 1279 int furia_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable) 1280 { 1281 return furia_fec_enable_get(&phy->access, enable); 1282 } 1283 /** PHY status dump 1284 * This function is used to display status dump of a core and for given lane 1285 * 1286 * @param phy Pointer to phymod phy access structure 1287 * 1288 * @return PHYMOD_E_NONE successful function execution 1289 */ 1290 int furia_phy_status_dump(const phymod_phy_access_t* phy) 1291 { 1292 return _furia_phy_status_dump(&phy->access); 1293 } 1294 /** Interrupt status get 1295 * This function is used to check whether or not particualr interrupt is pending 1296 * 1297 * @param phy Pointer to phymod phy access structure 1298 * @param status Pending status mask 1299 * 1300 * @return PHYMOD_E_NONE successful function execution 1301 */ 1302 int furia_phy_intr_status_get(const phymod_phy_access_t *phy, uint32_t* intr_status) 1303 { 1304 uint32_t intr_index = 0; 1305 uint32_t value = 0; 1306 1307 for (intr_index = 0; intr_index < FURIA_MAX_INTRS_SUPPORT; intr_index ++) { 1308 PHYMOD_IF_ERR_RETURN( 1309 furia_ext_intr_status_get(phy,(0x1 << intr_index), &value)); 1310 if (value) { 1311 *intr_status |= (0x1 << intr_index); 1312 } 1313 } 1314 return PHYMOD_E_NONE; 1315 } 1316 /** Interrupt enable set 1317 * This function is used to enable or disable particular interrupt 1318 * 1319 * @param phy Pointer to phymod phy access structure 1320 * @param intr_type Interrupt type 1321 * @param enable Enable or disable 1322 * 1 - enable 1323 * 0 - disable 1324 * 1325 * @return PHYMOD_E_NONE successful function execution 1326 */ 1327 int furia_phy_intr_enable_set(const phymod_phy_access_t *phy, uint32_t enable) 1328 { 1329 uint32_t intr_index = 0; 1330 for (intr_index = 0; intr_index < FURIA_MAX_INTRS_SUPPORT; intr_index ++) { 1331 if (enable & (0x1 << intr_index)) { 1332 PHYMOD_IF_ERR_RETURN(furia_ext_intr_enable_set(phy, (0x1 << intr_index), 1)); 1333 } else { 1334 PHYMOD_IF_ERR_RETURN(furia_ext_intr_enable_set(phy, (0x1 << intr_index), 0)); 1335 } 1336 } 1337 return PHYMOD_E_NONE; 1338 } 1339 /** Interrupt enable get 1340 * This function is used to check whether or not particular interrupt is enabled 1341 * 1342 * @param phy Pointer to phymod phy access structure 1343 * @param intr_type Interrupt type 1344 * @param enable Enable or disable 1345 * 1 - enable 1346 * 0 - disable 1347 * 1348 * @return PHYMOD_E_NONE successful function execution 1349 */ 1350 int furia_phy_intr_enable_get(const phymod_phy_access_t *phy, uint32_t* enable) 1351 { 1352 uint32_t intr_index = 0; 1353 uint32_t value = 0; 1354 1355 *enable = 0; 1356 for (intr_index = 0; intr_index < FURIA_MAX_INTRS_SUPPORT; intr_index ++) { 1357 PHYMOD_IF_ERR_RETURN( 1358 furia_ext_intr_enable_get(phy, (0x1 << intr_index), &value)); 1359 if (value) { 1360 *enable |= (0x1 << intr_index); 1361 } 1362 } 1363 return PHYMOD_E_NONE; 1364 } 1365 /** Interrupt status clear 1366 * This function is used for clearing interrupt status 1367 * 1368 * @param phy Pointer to phymod phy access structure 1369 * @param intr_type Interrupt type 1370 * 1371 * @return PHYMOD_E_NONE successful function execution 1372 */ 1373 int furia_phy_intr_status_clear(const phymod_phy_access_t *phy, uint32_t intr_clear) 1374 { 1375 uint32_t intr_index = 0; 1376 1377 for (intr_index = 0; intr_index < FURIA_MAX_INTRS_SUPPORT; intr_index ++) { 1378 if (intr_clear & (0x1 << intr_index)) { 1379 PHYMOD_IF_ERR_RETURN( 1380 furia_ext_intr_status_clear(phy, (0x1 << intr_index))); 1381 } 1382 } 1383 return PHYMOD_E_NONE; 1384 } 1385 1386 int furia_phy_lane_cross_switch_map_set(const phymod_phy_access_t* phy, const uint32_t* tx_array) 1387 { 1388 return furia_lane_cross_switch_map_set(&phy->access, tx_array); 1389 } 1390 1391 int furia_phy_lane_cross_switch_map_get(const phymod_phy_access_t* phy, uint32_t* tx_array) 1392 { 1393 return furia_lane_cross_switch_map_get(&phy->access, tx_array); 1394 } 1395 /*Read data from I2C device attached to PHY*/ 1396 int furia_phy_i2c_read(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint8_t* data) 1397 { 1398 return furia_module_read(&phy->access, addr, offset, size, data); 1399 } 1400 1401 /*Write data to I2C device attached to PHY*/ 1402 int furia_phy_i2c_write(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, const uint8_t* data) 1403 { 1404 return furia_module_write(&phy->access, addr, offset, size, data); 1405 } 1406 1407 /*Set/Get the output/input value of a PHY GPIO pin*/ 1408 int furia_phy_gpio_pin_value_set(const phymod_phy_access_t* phy, int pin_no, int value) 1409 { 1410 return furia_gpio_pin_value_set(&phy->access, pin_no, value); 1411 } 1412 int furia_phy_gpio_pin_value_get(const phymod_phy_access_t* phy, int pin_no, int* value) 1413 { 1414 return furia_gpio_pin_value_get(&phy->access, pin_no, value); 1415 } 1416 1417 /*Set/Get the configuration of a PHY GPIO pin*/ 1418 int furia_phy_gpio_config_set(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t gpio_mode) 1419 { 1420 return furia_gpio_config_set(&phy->access, pin_no, gpio_mode); 1421 } 1422 int furia_phy_gpio_config_get(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t* gpio_mode) 1423 { 1424 return furia_gpio_config_get(&phy->access, pin_no, gpio_mode); 1425 } 1426 1427 int furia_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx) 1428 { 1429 switch (media) { 1430 case phymodMediaTypeChipToChip: 1431 tx->pre = 0xc; 1432 tx->main = 0x66; 1433 tx->post = 0x0; 1434 tx->post2 = 0x0; 1435 tx->post3 = 0x0; 1436 tx->amp = 0xc; 1437 break; 1438 case phymodMediaTypeShort: 1439 tx->pre = 0xc; 1440 tx->main = 0x66; 1441 tx->post = 0x0; 1442 tx->post2 = 0x0; 1443 tx->post3 = 0x0; 1444 tx->amp = 0xc; 1445 break; 1446 case phymodMediaTypeMid: 1447 tx->pre = 0xc; 1448 tx->main = 0x66; 1449 tx->post = 0x0; 1450 tx->post2 = 0x0; 1451 tx->post3 = 0x0; 1452 tx->amp = 0xc; 1453 break; 1454 case phymodMediaTypeLong: 1455 tx->pre = 0xc; 1456 tx->main = 0x66; 1457 tx->post = 0x0; 1458 tx->post2 = 0x0; 1459 tx->post3 = 0x0; 1460 tx->amp = 0xc; 1461 break; 1462 default: 1463 tx->pre = 0xc; 1464 tx->main = 0x66; 1465 tx->post = 0x0; 1466 tx->post2 = 0x0; 1467 tx->post3 = 0x0; 1468 tx->amp = 0xc; 1469 break; 1470 } 1471 1472 return PHYMOD_E_NONE; 1473 } 1474 1475 1476 /** Short channel mode set 1477 * This function is used set the enable or diable the short channel mode 1478 * 1479 * @param phy Pointer to phymod phy access structure 1480 * @param enable enable or disable 1481 * 1 - enable 1482 * 0 - disable 1483 * 1484 * @return PHYMOD_E_NONE successful function execution 1485 */ 1486 int furia_phy_short_chn_mode_enable_set(const phymod_phy_access_t* phy, uint32_t enable) 1487 { 1488 return _furia_phy_short_channel_mode_set(&phy->access, enable); 1489 } 1490 /** Short channel mode get 1491 * This function is used get the enable or diable the short channel mode 1492 * 1493 * @param phy Pointer to phymod phy access structure 1494 * @param enable enable or disable 1495 * 0 - enable 1496 * 1 - disable 1497 * @param status enable or disable 1498 * 0 - enable 1499 * 1 - disable 1500 * 1501 * @return PHYMOD_E_NONE successful function execution 1502 */ 1503 1504 1505 int furia_phy_short_chn_mode_enable_get(const phymod_phy_access_t* phy, uint32_t* enable, uint32_t* status) 1506 { 1507 return _furia_phy_short_channel_mode_get(&phy->access, enable, status); 1508 } 1509 1510 int furia_phy_op_mode_get(const phymod_phy_access_t* phy, phymod_operation_mode_t* op_mode) 1511 { 1512 return PHYMOD_E_UNAVAIL; 1513 } 1514