openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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