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

quadra28.c (33827B)


      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  *
     12  * 
     13  *
     14  * $Copyright:
     15  * All Rights Reserved.$
     16  *
     17  * File: quadra28.c
     18  * Purpose: tier2 phymod support for Broadcom 40G Quadra28 phy
     19  * note:
     20  * Specifications:
     21 
     22  * Repeater, retimer operation.
     23 
     24  * Supports the following data speeds:
     25  * 1.25 Gbps line rate (1 GbE data rate, 8x oversampled over 10 Gbps line rate)
     26  * 10.3125 Gbps line rate (10 GbE data rate)
     27  * 11.5 Gpbs line rate (for backplane application, proprietary data rate)
     28  * 410.3125 Gbps line rate (40 GbE data rate)
     29  *
     30  * Supports the following line-side connections:
     31  * 1 GbE and 10 GbE SFP+ SR and LR optical modules
     32  * 40 GbE QSFP SR4 and LR4 optical modules
     33  * 1 GbE and 10 GbE SFP+ CR (CX1) copper cable
     34  * 40 GbE QSFP CR4 copper cable
     35  * 10 GbE KR, 11.5 Gbps line rate and 40 GbE KR4 backplanes
     36  *
     37  * Operates with the following reference clocks:
     38  * Single 156.25 MHz differential clock for 1.25 Gbps, 10.3125 Gpbs and 11.5 Gbps
     39  * line rates
     40  *
     41  * Supports autonegotiation as follows:
     42  * Clause 73 only for starting Clause 72 and requesting FEC
     43  * No speed resolution performed
     44  * No Clause 73 in 11.5 Gbps line rate, only Clause 72 supported
     45  * Clause 72 may be enabled standalone for close systems
     46  * Clause 37 is supported
     47      
     48   */
     49 
     50 #include <phymod/phymod.h>
     51 #include <phymod/phymod_system.h>
     52 #include <phymod/phymod_dispatch.h>
     53 
     54 
     55 #ifdef PHYMOD_QUADRA28_SUPPORT
     56 #include <phymod/chip/quadra28.h>
     57 
     58 /* To be defined */
     59 #include "../tier1/quadra28_types.h"
     60 #include "../tier1/quadra28_cfg_seq.h"
     61 #include "../tier1/quadra28_reg_access.h"
     62 #include "../tier1/bcmi_quadra28_defs.h"
     63 
     64 /* Microcontroller Firmware */
     65 extern unsigned char quadra28_ucode_bin[];
     66 extern uint32_t quadra28_ucode_len;
     67 
     68 int _quadra28_core_firmware_load (const phymod_core_access_t* core,
     69                                   const phymod_core_init_config_t *init_config);
     70 
     71 
     72 /*
     73  *    Set Interface config
     74  *    This function sets interface configuration (interface, speed, frequency of
     75  *    operation). This is requried to put the quadra28 into specific mode specified
     76  *    by the user.
     77  *
     78  *    @param phy                Pointer to phymod phy access structure
     79  *    @param flags              Currently unused and reserved for future use
     80  *    @param config             Interface config structure where user specifies
     81  *                              interface, speed and the frequency of operation.
     82  *
     83  *    @return PHYMOD_E_NONE     successful function execution
     84  */
     85 int quadra28_phy_interface_config_set(const phymod_phy_access_t* phy,
     86                                    uint32_t flags,
     87                                    const phymod_phy_inf_config_t* config)
     88 {
     89     if (config->data_rate == 100 || config->data_rate == 10) {
     90         uint32_t enable = 0;
     91         PHYMOD_IF_ERR_RETURN(
     92             _quadra28_phy_retimer_enable_get(&phy->access, &enable));
     93         if (!enable) {
     94             return PHYMOD_E_NONE;
     95         }
     96     }
     97     return quadra28_set_config_mode(phy,
     98                        config->interface_type,
     99                        config->data_rate,
    100                        config->ref_clock, 0xFFFF, 0xFFFF);
    101 }
    102 
    103 /**   Get Interface config
    104  *    This function retrieves interface configuration(interface, speed and
    105  *    frequency of operation) from the device.
    106  *
    107  *    @param phy                Pointer to phymod phy access structure
    108  *    @param flags              Currently unused and reserved for future use
    109  *    @param config             Interface config structure where
    110  *                              interface, speed and the frequency of operation
    111  *                              will be populated from device .
    112  *
    113  *    @return PHYMOD_E_NONE     successful function execution
    114  */
    115 int quadra28_phy_interface_config_get(const phymod_phy_access_t* phy,
    116                                    uint32_t flags,
    117                                    phymod_ref_clk_t ref_clock,
    118                                    phymod_phy_inf_config_t* config)
    119 {
    120     return quadra28_get_config_mode(&phy->access,
    121                        &config->interface_type,
    122                        &config->data_rate,
    123                        &config->ref_clock,
    124                        &config->interface_modes);
    125 }
    126 
    127 
    128 /**   Core Init
    129  *    This function initializes the quadra core and
    130  *    downloads the firmware. It sets the PHY in
    131  *    default mode.
    132  *
    133  *    @param phy                Pointer to phymod core access structure
    134  *    @param init_config        Init configuration specified by user
    135  *    @param core_status        Core status read from PHY chip
    136  *
    137  *    @return PHYMOD_E_NONE     successful function execution
    138  */
    139 int quadra28_core_init(const phymod_core_access_t *core,
    140                        const phymod_core_init_config_t *init_config,
    141                        const phymod_core_status_t *core_status) 
    142 {
    143 
    144     PHYMOD_IF_ERR_RETURN(
    145         _quadra28_core_firmware_load (core, init_config));
    146 
    147 
    148     return PHYMOD_E_NONE;
    149 
    150 }
    151 
    152 /**   Core firmware download
    153  *    This function downloads the firmware using either internal or external
    154  *    method as specified by the user. Firmware loader function supplied by user
    155  *    will be used for external download method.
    156  *
    157  *    @param core               Pointer to phymod core access structure
    158  *    @param load_method        Load method will be specified by user
    159  *    @param fw_loader          Loader function specified by user and will be
    160  *                              used for external download method
    161  *
    162  *    @return PHYMOD_E_NONE     successful function execution
    163  */
    164 int _quadra28_core_firmware_load (const phymod_core_access_t* core,
    165                                   const phymod_core_init_config_t *init_config)
    166 {
    167     int ret_val = 0, dload_method = init_config->firmware_load_method;
    168     const phymod_access_t *pm_acc = &core->access;
    169     uint32_t chip_id;
    170     uint32_t new_firmware_version=0;
    171     phymod_core_firmware_info_t fw_info;
    172 
    173     PHYMOD_MEMSET(&fw_info, 0, sizeof(phymod_core_firmware_info_t));
    174     PHYMOD_IF_ERR_RETURN(
    175         quadra28_core_firmware_info_get(core, &fw_info));
    176     new_firmware_version = quadra28_ucode_bin[quadra28_ucode_len-3];
    177     chip_id =  _quadra28_get_chip_id(&core->access);
    178 
    179     switch(dload_method)
    180     {
    181         case phymodFirmwareLoadMethodInternal:
    182             if(PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_GET(init_config)){
    183                 if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
    184                     return quadra28_before_fw_load(core, init_config, chip_id);
    185                 } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) {
    186                     return quadra28_bcast_fw_load(core, init_config,
    187                                                   quadra28_ucode_bin, quadra28_ucode_len);
    188                 } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
    189                        ret_val = quadra28_bcast_after_fw_load(core, chip_id);
    190                        if(ret_val != 0){
    191                            PHYMOD_DEBUG_ERROR(("Firmware Verification failed %d\n",ret_val)); 
    192 
    193                            /* Doing Softreset to clear Broadcast*/
    194                            PHYMOD_IF_ERR_RETURN(
    195                                quadra28_bcast_disable(core, chip_id));
    196       
    197                        }
    198                        return ret_val; 
    199                 } else if(PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)){
    200                       PHYMOD_DIAG_OUT(("Firmware download success\n"));
    201                       /* Using sratch Reg to store and retrevie later*/
    202                       PHYMOD_IF_ERR_RETURN(
    203                           phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath));
    204                       PHYMOD_IF_ERR_RETURN(
    205                           phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath));
    206 
    207                       /* Doing Softreset to clear Broadcast*/
    208                       PHYMOD_IF_ERR_RETURN(
    209                            quadra28_bcast_disable(core, chip_id));
    210 
    211                 }
    212             } else if(PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_GET(init_config) && new_firmware_version != fw_info.fw_version){
    213                 if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
    214                     return quadra28_before_fw_load(core, init_config, chip_id);
    215                 } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) {
    216                     return quadra28_bcast_fw_load(core, init_config,
    217                                                   quadra28_ucode_bin, quadra28_ucode_len);
    218                 } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
    219                        ret_val = quadra28_bcast_after_fw_load(core, chip_id);
    220                        if(ret_val != 0){
    221                            PHYMOD_DEBUG_ERROR(("Firmware Verification failed %d\n",ret_val)); 
    222 
    223                            /* Doing Softreset to clear Broadcast*/
    224                            PHYMOD_IF_ERR_RETURN(
    225                                quadra28_bcast_disable(core, chip_id));
    226       
    227                        }
    228                        return ret_val; 
    229                 } else if(PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)){
    230                       PHYMOD_DIAG_OUT(("Firmware download success\n"));
    231                       /* Using sratch Reg to store and retrevie later*/
    232                       PHYMOD_IF_ERR_RETURN(
    233                           phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath));
    234                       PHYMOD_IF_ERR_RETURN(
    235                           phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath));
    236 
    237                       /* Doing Softreset to clear Broadcast*/
    238                       PHYMOD_IF_ERR_RETURN(
    239                            quadra28_bcast_disable(core, chip_id));
    240                 }
    241             } else if(fw_info.fw_version == 0){
    242                 if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
    243                     return quadra28_before_fw_load(core, init_config, chip_id);
    244                 } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) {
    245                     return quadra28_bcast_fw_load(core, init_config,
    246                                                   quadra28_ucode_bin, quadra28_ucode_len);
    247                 } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
    248                        ret_val = quadra28_bcast_after_fw_load(core, chip_id);
    249                        if(ret_val != 0){
    250                            PHYMOD_DEBUG_ERROR(("Firmware Verification failed %d\n",ret_val)); 
    251 
    252                            /* Doing Softreset to clear Broadcast*/
    253                            PHYMOD_IF_ERR_RETURN(
    254                                quadra28_bcast_disable(core, chip_id));
    255       
    256                        }
    257                        return ret_val; 
    258                 } else if(PHYMOD_CORE_INIT_F_FW_LOAD_END_GET(init_config)){
    259                       PHYMOD_DIAG_OUT(("Firmware download success\n"));
    260                       /* Using sratch Reg to store and retrevie later*/
    261                       PHYMOD_IF_ERR_RETURN(
    262                           phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath));
    263                       PHYMOD_IF_ERR_RETURN(
    264                           phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath));
    265 
    266                       /* Doing Softreset to clear Broadcast*/
    267                       PHYMOD_IF_ERR_RETURN(
    268                            quadra28_bcast_disable(core,chip_id));
    269                 }
    270             } else {
    271                 if (fw_info.fw_version != 0) {
    272                     MDIO_BROADCAST_CONTROLr_t mdio_broadcast_ctrl_reg;
    273                     PHYMOD_IF_ERR_RETURN
    274                         (READ_MDIO_BROADCAST_CONTROLr(&core->access, &mdio_broadcast_ctrl_reg));
    275                     if (BCMI_QUADRA28_MDIO_BROADCAST_CONTROLr_MDIO_BCAST_ENf_GET(mdio_broadcast_ctrl_reg)) {
    276                         /* Using sratch Reg to store and retrevie later*/
    277                         PHYMOD_IF_ERR_RETURN(
    278                            phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath));
    279                         PHYMOD_IF_ERR_RETURN(
    280                            phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath));
    281                         /* Doing Softreset to clear Broadcast*/
    282                         PHYMOD_IF_ERR_RETURN(
    283                             quadra28_bcast_disable(core,chip_id));
    284                      }
    285                 }
    286             }
    287         break;
    288         case phymodFirmwareLoadMethodExternal:
    289             return PHYMOD_E_UNAVAIL;
    290         break;
    291         case phymodFirmwareLoadMethodNone:
    292         break;
    293         case phymodFirmwareLoadMethodProgEEPROM:
    294             PHYMOD_DIAG_OUT(("Firmware will be downloaded first, and flashed on to EEPROM \n"));
    295             PHYMOD_DIAG_OUT(("This process will take few minutes.....\n"));
    296             ret_val = quadra28_rom_dload(pm_acc, quadra28_ucode_bin,
    297                                          quadra28_ucode_len);
    298             if (ret_val != PHYMOD_E_NONE) {
    299                 PHYMOD_RETURN_WITH_ERR
    300                 (PHYMOD_E_FAIL,
    301                  (_PHYMOD_MSG("Flashing Firmware to EEPROM failed")));
    302             } else {
    303                 PHYMOD_DEBUG_VERBOSE(("Firmware is flashed to EEPROM successfully\n"));
    304             }
    305             /* Using sratch Reg to store and retrevie later*/
    306             PHYMOD_IF_ERR_RETURN(
    307                  phymod_raw_iblk_write(&core->access, 0x1c91A,init_config->op_datapath));
    308             PHYMOD_IF_ERR_RETURN(
    309                  phymod_raw_iblk_write(&core->access, 0x1c91B,init_config->op_datapath));
    310         break;
    311         default:
    312             PHYMOD_RETURN_WITH_ERR
    313                 (PHYMOD_E_CONFIG,
    314                  (_PHYMOD_MSG("illegal fw load method")));
    315     }
    316     return PHYMOD_E_NONE;
    317 }
    318 
    319  
    320 /**   Get PHY link status
    321  *    This function retrieves PHY link status from device
    322  *
    323  *    @param phy                Pointer to phymod phy access structure
    324  *    @param link_status        Link status retrieved from the device
    325  *
    326  *    @return PHYMOD_E_NONE     successful function execution
    327  */
    328 
    329 
    330 int quadra28_phy_link_status_get(const phymod_phy_access_t* phy,
    331                               uint32_t* link_status)
    332 {
    333     return quadra28_link_status(phy, link_status);
    334 }
    335                    
    336 /**   PHY register read
    337  *    This function reads the PHY register
    338  *
    339  *    @param phy                Pointer to phymod phy access structure
    340  *    @param reg_addr           PHY Register Address to Read
    341  *    @param val                PHY Register content of the specified
    342  *                              register Address to Read
    343  *
    344  *    @return PHYMOD_E_NONE     successful function execution
    345  */
    346 int quadra28_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr,
    347                        uint32_t *val)
    348 {
    349     return phymod_raw_iblk_read(&phy->access,\
    350                         QUADRA28_CLAUSE45_ADDR((phy->access.devad), (reg_addr)),\
    351                         val);
    352 }
    353 
    354 
    355 /**   PHY register write
    356  *    This function is used to write content to PHY register
    357  *
    358  *    @param phy                Pointer to phymod phy access structure
    359  *    @param reg_addr           PHY Register Address to Write
    360  *    @param val                Content/Value to Write to the PHY Register
    361  *
    362  *    @return PHYMOD_E_NONE     successful function execution
    363  */
    364 int quadra28_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr,
    365                         uint32_t val)
    366 {
    367 
    368     return phymod_raw_iblk_write(&phy->access,\
    369                          QUADRA28_CLAUSE45_ADDR((phy->access.devad), (reg_addr)),\
    370                          val);
    371 }
    372 
    373 /**   PHY core info get
    374  *    This function is used to write content to PHY register
    375  *
    376  *    @param phy                Pointer to phymod phy access structure
    377  *    @param info               Pointer to core info structure
    378  *
    379  *    @return PHYMOD_E_NONE     successful function execution
    380  */
    381 int quadra28_core_info_get(const phymod_core_access_t* phy, phymod_core_info_t* info)
    382 {
    383     uint32_t chip_id;
    384     PMD_IDENTIFIER_0r_t id0;
    385     PMD_IDENTIFIER_1r_t id1;
    386 
    387     chip_id =  _quadra28_get_chip_id(&phy->access);
    388     info->serdes_id = chip_id;
    389     info->core_version = phymodCoreVersionQuadra28;
    390     PHYMOD_STRNCPY(info->name, "Quadra28", PHYMOD_STRLEN("Quadra28")+1);
    391 
    392     PHYMOD_IF_ERR_RETURN (
    393            READ_PMD_IDENTIFIER_1r(&phy->access, &id1));
    394     info->phy_id1 = id1.v[0];
    395     PHYMOD_IF_ERR_RETURN (
    396            READ_PMD_IDENTIFIER_0r(&phy->access, &id0));
    397     info->phy_id0 = id0.v[0];
    398 
    399     return PHYMOD_E_NONE;
    400 }
    401 /**  PHY polarity set
    402  *   This function is used to set the lane polarity
    403  *
    404  *    @param phy                Pointer to phymod phy access structure
    405  *    @param polarity           Pointer to phymod_polarity_t for rx and tx
    406  *
    407  *    @return PHYMOD_E_NONE     successful function execution
    408  */
    409 int quadra28_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    410 {
    411     return quadra28_tx_rx_polarity_set(phy, polarity->tx_polarity, polarity->rx_polarity);
    412 }
    413 
    414 
    415 /**  PHY polarity get
    416  *   This function is used to get the lane polarity
    417  *
    418  *    @param phy                Pointer to phymod phy access structure
    419  *    @param polarity           Pointer to phymod_polarity_t for rx and tx
    420  *
    421  *    @return PHYMOD_E_NONE     successful function execution
    422  */
    423 int quadra28_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    424 {
    425     return quadra28_tx_rx_polarity_get(phy, &polarity->tx_polarity, &polarity->rx_polarity);
    426 }
    427 
    428 /**  PHY Rx PMD lock
    429  *   PHY Rx PMD lock This function is used to get the rx PMD lock status
    430  *
    431  *    @param phy                Pointer to phymod phy access structure
    432  *    @param rx_seq_done        Pointer to rx sequence
    433  *
    434  *    @return PHYMOD_E_NONE     successful function execution
    435  */
    436 int quadra28_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_seq_done){
    437 
    438     return quadra28_pmd_lock_get(phy, rx_seq_done);
    439 }
    440 
    441 
    442 /**  PHY power set
    443  *   PHY power set This function is used to set the power
    444  *
    445  *    @param phy                Pointer to phymod phy access structure
    446  *    @param power              Pointer to phymod phy power structure
    447  *
    448  *    @return PHYMOD_E_NONE     successful function execution
    449  */
    450 int quadra28_phy_power_set(const phymod_phy_access_t* phy,
    451                         const phymod_phy_power_t* power)
    452 {
    453     return _quadra28_phy_power_set(phy, power);
    454 }
    455 
    456 /*
    457  *    @param flags               Reserved for Furtuer use
    458  *    @param operation           Operation to perform on PLL sequencer
    459  *
    460  *    @return PHYMOD_E_NONE     successful function execution
    461  */
    462 int quadra28_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation)
    463 {
    464 
    465     return  _quadra28_pll_seq_restart(&core->access, flags, operation);
    466 
    467 }
    468 /**  FEC enable set
    469  *   This function is used to enable the FEC
    470  *
    471  *    @param phy                Pointer to phymod phy access structure
    472  *    @param enable             enable or disable
    473  *        1 - enable
    474  *        0 - disable
    475  *
    476  *    @return PHYMOD_E_NONE     successful function execution
    477  */
    478 int quadra28_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
    479 {
    480     return _quadra28_phy_fec_enable_set(phy, enable);
    481 }
    482 /**  FEC enable get
    483  *   This function is used to check whether or not FEC is enabled
    484  *
    485  *    @param phy                Pointer to phymod phy access structure
    486  *    @param enable             enable or disable
    487  *        1 - enable
    488  *        0 - disable
    489  *
    490  *    @return PHYMOD_E_NONE     successful function execution
    491  */
    492 int quadra28_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    493 {
    494     return _quadra28_phy_fec_enable_get(phy, enable);
    495 }
    496 /**  PHY status dump
    497  *   This function is used to display status dump of a core and for given lane
    498  *
    499  *    @param phy                Pointer to phymod phy access structure
    500  *
    501  *    @return PHYMOD_E_NONE     successful function execution
    502  */
    503 int quadra28_phy_status_dump(const phymod_phy_access_t* phy)
    504 {
    505 
    506     PHYMOD_IF_ERR_RETURN(
    507             _quadra28_phy_status_dump(phy));
    508 
    509     return PHYMOD_E_NONE;
    510 
    511 }
    512 
    513 static int _quadra28_reset_mode(const phymod_access_t *pa)
    514 {
    515     int speed = 0;
    516     BCMI_QUADRA28_GENERAL_PURPOSE_3r_t gp_reg3_reg_val;
    517     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
    518     PHYMOD_MEMSET(&gp_reg3_reg_val, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_3r_t));
    519     PHYMOD_MEMSET(&apps_mode0_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));
    520 
    521     PHYMOD_IF_ERR_RETURN(
    522         BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(pa, &gp_reg3_reg_val));
    523     speed = gp_reg3_reg_val.v[0] & 0xF ;
    524     if (speed == 0x4 || speed == 0x7) {
    525         PHYMOD_IF_ERR_RETURN(
    526             quadra28_channel_select (pa, Q28_ALL_LANE));
    527         apps_mode0_reg_val.v[0] = gp_reg3_reg_val.v[0];
    528         BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
    529         PHYMOD_IF_ERR_RETURN(
    530             BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val));
    531         PHYMOD_USLEEP(100);
    532         BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0_reg_val, 0x8882);
    533         PHYMOD_IF_ERR_RETURN(
    534             BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val));
    535         {
    536             BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
    537             PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
    538             PHYMOD_IF_ERR_RETURN(
    539                 BCMI_QUADRA28_READ_PMD_CONTROLr(pa, &pmd_ctrl));
    540             BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1);
    541             PHYMOD_IF_ERR_RETURN(
    542                 BCMI_QUADRA28_WRITE_PMD_CONTROLr(pa, pmd_ctrl));
    543         }
    544         PHYMOD_USLEEP(500);
    545         PHYMOD_IF_ERR_RETURN(
    546                  _quadra28_intf_update_wait_check(pa,apps_mode0_reg_val.v[0], 50000));
    547     }
    548  
    549     return PHYMOD_E_NONE;
    550 }
    551 
    552 int quadra28_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
    553 {
    554     uint32_t chip_id;
    555     PMD_IDENTIFIER_0r_t id0;
    556     PMD_IDENTIFIER_1r_t id1;
    557     const phymod_access_t *pm_acc = &core->access;
    558     
    559     PHYMOD_MEMSET(&id0, 0, sizeof(PMD_IDENTIFIER_0r_t));
    560     PHYMOD_MEMSET(&id1, 0, sizeof(PMD_IDENTIFIER_1r_t));
    561     *is_identified = 0;
    562     if (core_id == 0) {
    563         PHYMOD_IF_ERR_RETURN (
    564            READ_PMD_IDENTIFIER_1r(pm_acc, &id1));
    565         PHYMOD_IF_ERR_RETURN (
    566            READ_PMD_IDENTIFIER_0r(pm_acc, &id0));
    567     } else {
    568         id0.v[0] = (uint16_t) ((core_id >> 16) & 0xffff);
    569         id1.v[0] = (uint16_t) core_id & 0xffff;
    570     }
    571     if ((id0.v[0] == QUADRA28_PMD_ID0 &&
    572         id1.v[0] == QUADRA28_PMD_ID1)) {
    573         if (PHYMOD_ACC_F_PRECONDITION_GET(&core->access)) {
    574            return _quadra28_reset_mode(&core->access);
    575         } 
    576         chip_id =  _quadra28_get_chip_id(&core->access);
    577         if (chip_id == QUADRA28_82780_CHIP_ID || chip_id == QUADRA28_82752_CHIP_ID 
    578              || chip_id == QUADRA28_82758_CHIP_ID || chip_id == QUADRA28_8278F_CHIP_ID) {
    579             /* PHY IDs match and enable Broadcast */
    580             *is_identified = 0x80000001;
    581         }
    582     }
    583     return PHYMOD_E_NONE;
    584 
    585 }
    586 int quadra28_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
    587 {
    588     PHYMOD_IF_ERR_RETURN (
    589          quadra28_soft_reset(&core->access, reset_mode, direction));
    590     return PHYMOD_E_NONE;
    591 
    592 }
    593 
    594 int quadra28_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction)
    595 {
    596     return PHYMOD_E_UNAVAIL;
    597 
    598 }
    599 
    600 int quadra28_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info)
    601 {
    602     PHYMOD_IF_ERR_RETURN( 
    603         quadra28_firmware_info_get(&core->access, fw_info));
    604     return PHYMOD_E_NONE;
    605 
    606 }
    607 
    608 int quadra28_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    609 {
    610     return _quadra28_phy_tx_set(phy, tx);
    611 }
    612 
    613 int quadra28_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
    614 {
    615     PHYMOD_IF_ERR_RETURN( 
    616         _quadra28_phy_tx_get(phy, tx));
    617     return PHYMOD_E_NONE;
    618 }
    619 
    620 int quadra28_phy_media_type_tx_get(const phymod_phy_access_t* phy, phymod_media_typed_t media, phymod_tx_t* tx)
    621 {
    622     TXFIR_CONTROL1r_t txfir_ctrl1;
    623     TXFIR_CONTROL2r_t txfir_ctrl2;
    624 
    625     PHYMOD_MEMSET(tx, 0, sizeof(phymod_tx_t));
    626     PHYMOD_MEMSET(&txfir_ctrl1, 0, sizeof(TXFIR_CONTROL1r_t));
    627     PHYMOD_MEMSET(&txfir_ctrl2, 0, sizeof(TXFIR_CONTROL2r_t));
    628     PHYMOD_IF_ERR_RETURN(
    629         READ_TXFIR_CONTROL1r(&phy->access, &txfir_ctrl1));
    630     PHYMOD_IF_ERR_RETURN(
    631         READ_TXFIR_CONTROL2r(&phy->access, &txfir_ctrl2));
    632 
    633     tx->pre = TXFIR_CONTROL1r_TXFIR_PRE_OVERRIDEf_GET(txfir_ctrl1);
    634     tx->post = TXFIR_CONTROL1r_TXFIR_POST_OVERRIDEf_GET(txfir_ctrl1);
    635     tx->main = TXFIR_CONTROL2r_TXFIR_MAIN_OVERRIDEf_GET(txfir_ctrl2);
    636     tx->post2 = TXFIR_CONTROL2r_TXFIR_POST2f_GET(txfir_ctrl2);
    637 
    638     return PHYMOD_E_NONE;
    639 }
    640 int quadra28_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
    641 {
    642     return _quadra28_phy_rx_set(phy, rx);
    643 }
    644 
    645 int quadra28_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
    646 {
    647     return _quadra28_phy_rx_get(phy, rx);
    648 }
    649 
    650 int quadra28_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset)
    651 {
    652     return _quadra28_phy_reset_set(phy, reset);
    653 }
    654 
    655 int quadra28_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset)
    656 {
    657     return _quadra28_phy_reset_get(phy, reset);
    658 }
    659 
    660 int quadra28_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    661 {
    662     return quadra28_tx_lane_control_set(phy, tx_control);
    663 } 
    664 
    665 int quadra28_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control)
    666 {
    667     int enable = 0;
    668     *tx_control = phymodTxSquelchOn;
    669 
    670     PHYMOD_IF_ERR_RETURN (
    671        quadra28_tx_squelch_get(phy, &enable));
    672     
    673     if (!enable) {
    674         *tx_control = phymodTxSquelchOff;
    675     }
    676     return PHYMOD_E_NONE;
    677 
    678 }
    679 
    680 int quadra28_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
    681 {
    682     return quadra28_rx_lane_control_set(phy, rx_control);
    683 }
    684 
    685 int quadra28_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
    686 {
    687     int enable = 0;
    688     *rx_control = phymodRxSquelchOn;
    689     PHYMOD_IF_ERR_RETURN (
    690        quadra28_rx_squelch_get(phy, &enable));
    691     if (!enable) {
    692         *rx_control = phymodRxSquelchOff;
    693     }
    694     return PHYMOD_E_NONE;
    695 
    696 }
    697 
    698 int quadra28_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type)
    699 {
    700     q28_an_ability_t an_ability;
    701     an_ability.fec_ability = an_ability_set_type->an_fec;
    702 
    703     /*next check pause */
    704     if (PHYMOD_AN_CAP_SYMM_PAUSE_GET(an_ability_set_type)) {
    705         an_ability.pause_ability = Q28_SYMM_PAUSE;
    706     } else if (PHYMOD_AN_CAP_ASYM_PAUSE_GET(an_ability_set_type)) {
    707         an_ability.pause_ability = Q28_ASYM_PAUSE;
    708     } else {
    709         an_ability.pause_ability = Q28_NO_PAUSE;
    710     }
    711 
    712     /* Quadra28 FW set advertisement based on the speed, so no
    713      * need to set advert*/
    714     PHYMOD_IF_ERR_RETURN(_quadra28_phy_autoneg_ability_set(&phy->access, an_ability));
    715 
    716     return PHYMOD_E_NONE;
    717 }
    718 
    719 int quadra28_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    720 {
    721     return _quadra28_phy_autoneg_ability_get(&phy->access, an_ability_get_type);
    722 }
    723 
    724 int quadra28_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
    725 {
    726     uint32_t datapath = 0, datapath1 = 0;
    727     PHYMOD_IF_ERR_RETURN(
    728           phymod_raw_iblk_read(&phy->access, 0x1c91A, &datapath));
    729     PHYMOD_IF_ERR_RETURN(
    730           phymod_raw_iblk_read(&phy->access, 0x1c91B, &datapath1));
    731     datapath |= datapath1;
    732 
    733     PHYMOD_IF_ERR_RETURN
    734          (quadra28_set_config_mode(phy,
    735               init_config->interface.interface_type, init_config->interface.data_rate, 
    736               init_config->interface.ref_clock, datapath, init_config->op_mode));
    737 
    738     /* 0 is the Default init value coming from portmod*/
    739     if ((init_config->polarity.tx_polarity != 0) || 
    740           (init_config->polarity.rx_polarity != 0)) {
    741         PHYMOD_IF_ERR_RETURN(
    742             quadra28_tx_rx_polarity_set (phy, 
    743                 init_config->polarity.tx_polarity, init_config->polarity.rx_polarity));
    744     }
    745     return PHYMOD_E_NONE;
    746 }
    747 
    748 int quadra28_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
    749 {
    750     return _quadra28_loopback_set(phy, loopback, enable);
    751 }
    752 
    753 int quadra28_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
    754 {
    755     return _quadra28_loopback_get(phy, loopback, enable);    
    756 }
    757 
    758 int quadra28_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
    759 {
    760     return _quadra28_phy_power_get(phy, power);
    761 }
    762 
    763 int quadra28_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
    764 {
    765     return _quadra28_phy_autoneg_set(&phy->access, an);
    766 }
    767 
    768 int quadra28_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
    769 {
    770     return _quadra28_phy_autoneg_get(&phy->access, an, an_done);
    771 
    772 }
    773 
    774 int quadra28_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    775 {
    776     return _quadra28_phy_autoneg_remote_ability_get(&phy->access, an_ability_get_type) ;
    777 }
    778 
    779 int quadra28_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
    780 {
    781     return _quadra28_phy_cl72_set(phy, cl72_en);
    782 }
    783 
    784 int quadra28_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
    785 {
    786     return _quadra28_phy_cl72_get(phy, cl72_en);
    787 }
    788 
    789 int quadra28_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
    790 {
    791     return _quadra28_phy_cl72_status_get(phy, status);
    792 }
    793 
    794 int quadra28_phy_i2c_read(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint8_t* data)
    795 {
    796       
    797     return (_quadra28_i2c_read(&phy->access, addr, offset, size, data));
    798   
    799 }
    800 
    801 
    802 
    803 int quadra28_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)
    804 {
    805         
    806     return(_quadra28_i2c_write(&phy->access, addr, offset, size, data));
    807     
    808 }
    809 int quadra28_edc_config_set(const phymod_phy_access_t* phy, const phymod_edc_config_t* edc_config)
    810 {
    811     return _quadra28_edc_config_set(phy, edc_config);
    812 }
    813 int quadra28_edc_config_get(const phymod_phy_access_t* phy, phymod_edc_config_t* edc_config)
    814 {
    815     return _quadra28_edc_config_get(phy, edc_config);
    816 }
    817 
    818 int quadra28_phy_rx_restart(const phymod_phy_access_t* phy)
    819 {
    820     return _quadra28_pll_seq_restart(&phy->access, 0, phymodSeqOpRestart);
    821 }
    822 
    823 int quadra28_failover_mode_set(const phymod_phy_access_t* phy, phymod_failover_mode_t failover_mode)
    824 {
    825     return _quadra28_failover_mode_set(phy, failover_mode);
    826 }
    827 int quadra28_failover_mode_get(const phymod_phy_access_t* phy, phymod_failover_mode_t* failover_mode)
    828 {
    829     return _quadra28_failover_mode_get(phy, failover_mode);
    830 }
    831 
    832 int quadra28_phy_rx_adaptation_resume(const phymod_phy_access_t* phy)
    833 {
    834     return _quadra28_phy_rx_adaptation_resume(phy);
    835 }
    836 
    837 int quadra28_phy_gpio_config_set(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t gpio_mode)
    838 {
    839     return _quadra28_phy_gpio_config_set(phy, pin_no, gpio_mode);
    840 }
    841 int quadra28_phy_gpio_config_get(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t* gpio_mode)
    842 {
    843     return _quadra28_phy_gpio_config_get(phy, pin_no, gpio_mode);
    844 }
    845 int quadra28_phy_gpio_pin_value_set(const phymod_phy_access_t* phy, int pin_no, int value)
    846 {
    847     return _quadra28_phy_gpio_pin_value_set(phy, pin_no, value);
    848 }
    849 int quadra28_phy_gpio_pin_value_get(const phymod_phy_access_t* phy, int pin_no, int* value)
    850 {
    851     return _quadra28_phy_gpio_pin_value_get(phy, pin_no, value);
    852 }
    853 int quadra28_core_lane_map_set(const phymod_core_access_t* core, const phymod_lane_map_t* lane_map)
    854 {
    855     return PHYMOD_E_UNAVAIL;
    856 }
    857 int quadra28_core_lane_map_get(const phymod_core_access_t* core, phymod_lane_map_t* lane_map)
    858 {
    859     return PHYMOD_E_UNAVAIL;
    860 }
    861 int quadra28_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config)
    862 {
    863     return PHYMOD_E_UNAVAIL;
    864 }
    865 int quadra28_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config)
    866 {
    867     return PHYMOD_E_UNAVAIL;
    868 }
    869 int quadra28_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config)
    870 {
    871     return PHYMOD_E_UNAVAIL;
    872 }
    873 int quadra28_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config)
    874 {
    875     return PHYMOD_E_UNAVAIL;
    876 }
    877 int quadra28_phy_multi_get(const phymod_phy_access_t* phy, phymod_multi_data_t* multi_data)
    878 {
    879     return (_quadra28_i2c_read(&phy->access, multi_data->dev_addr, multi_data->offset, multi_data->max_size, multi_data->data));
    880 }
    881 
    882 int quadra28_phy_op_mode_get(const phymod_phy_access_t* phy, phymod_operation_mode_t* op_mode)
    883 {
    884     uint32_t retimer = 0, speed = 0, interface_modes = 0;
    885     phymod_interface_t intf;
    886     phymod_ref_clk_t ref_clk; 
    887     
    888     PHYMOD_IF_ERR_RETURN(
    889          _quadra28_phy_retimer_enable_get(&phy->access, &retimer));
    890 
    891     PHYMOD_IF_ERR_RETURN(
    892         quadra28_get_config_mode(&phy->access, &intf, &speed, &ref_clk, &interface_modes));
    893    
    894     (void) intf;
    895     (void) ref_clk;
    896     (void) interface_modes;
    897     if ((retimer == 0) && (speed == 1000)) {
    898         *op_mode = phymodOperationModePassthru; 
    899     } else if(retimer == 1) {
    900         *op_mode = phymodOperationModeRetimer; 
    901     } else {
    902         *op_mode = phymodOperationModeRepeater; 
    903     }
    904 
    905     return PHYMOD_E_NONE;
    906 }
    907 
    908 
    909 #endif