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_cfg_seq.c (179061B)


      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 * File: quadra28.c
     10 * Purpose: tier1 phymod microcode download support for Broadcom 40G Quadra28 
     11 * note
     12 */
     13 /*
     14  * Includes
     15  */
     16 #include <phymod/phymod.h>
     17 #include <phymod/phymod_system.h>
     18 #include "quadra28_cfg_seq.h"
     19 #include "quadra28_reg_access.h"
     20 #include "bcmi_quadra28_defs.h"
     21 #include "quadra28_serdes/common/srds_api_enum.h"
     22 #include "quadra28_serdes/merlin_quadra28_functions.h"
     23 static 
     24 int _quadra28_merlin_phy_reset_get(phymod_access_t *pa,  phymod_phy_reset_t* reset);
     25 static 
     26 int _quadra28_merlin_phy_reset_set(phymod_access_t *pa, const phymod_phy_reset_t* reset);
     27 
     28 static int quadra28_power_set(const phymod_access_t *pa, const phymod_phy_power_t* power);
     29 
     30 static int quadra28_power_get(const phymod_access_t *pa, phymod_phy_power_t* power);
     31 
     32 int quadra28_channel_select (const phymod_access_t *pa, uint16_t lane)
     33 {
     34     BCMI_QUADRA28_CONFIG_ACCESSr_t  single_pmd_bcast_sel;
     35     ADDRESS_EXTENSIONr_t single_pmd_ch_sel;
     36 
     37     PHYMOD_MEMSET(&single_pmd_bcast_sel, 0 , sizeof(BCMI_QUADRA28_CONFIG_ACCESSr_t));
     38     PHYMOD_MEMSET(&single_pmd_ch_sel, 0 , sizeof(ADDRESS_EXTENSIONr_t));
     39 
     40     PHYMOD_IF_ERR_RETURN(
     41         BCMI_QUADRA28_READ_CONFIG_ACCESSr(pa, &single_pmd_bcast_sel));
     42     PHYMOD_IF_ERR_RETURN(
     43             BCMI_QUADRA28_READ_ADDRESS_EXTENSIONr(pa, &single_pmd_ch_sel));
     44 
     45     if (lane == Q28_ALL_LANE) {
     46         PHYMOD_IF_ERR_RETURN(
     47             BCMI_QUADRA28_READ_ADDRESS_EXTENSIONr(pa, &single_pmd_ch_sel));
     48         BCMI_QUADRA28_ADDRESS_EXTENSIONr_AER_CHf_SET(single_pmd_ch_sel, 0);
     49         PHYMOD_IF_ERR_RETURN(
     50             BCMI_QUADRA28_WRITE_ADDRESS_EXTENSIONr(pa, single_pmd_ch_sel));
     51 
     52         /* Enable Broadcast mode*/
     53         BCMI_QUADRA28_CONFIG_ACCESSr_BROADCAST_ENABLEf_SET(single_pmd_bcast_sel,1);
     54         PHYMOD_IF_ERR_RETURN(
     55             BCMI_QUADRA28_WRITE_CONFIG_ACCESSr(pa, single_pmd_bcast_sel));
     56     } else {
     57         BCMI_QUADRA28_ADDRESS_EXTENSIONr_AER_CHf_SET(single_pmd_ch_sel, lane);
     58         PHYMOD_IF_ERR_RETURN(
     59             BCMI_QUADRA28_WRITE_ADDRESS_EXTENSIONr(pa, single_pmd_ch_sel));
     60     }
     61     return PHYMOD_E_NONE;
     62 }
     63 
     64 /**   read chip ID
     65  *    This function is used to set the operating mode of the PHY
     66  *
     67  *    @param pa                 Pointer to phymod access structure 
     68  *    @return PHYMOD_E_NONE     successful function execution 
     69  */
     70 uint32_t  _quadra28_get_chip_id(const phymod_access_t *pa)
     71 {
     72     CHIP_ID0r_t chipid_lsb;
     73     CHIP_ID1r_t chipid_msb;
     74     int32_t chipid = 0;
     75 
     76     PHYMOD_MEMSET(&chipid_lsb, 0, sizeof(CHIP_ID0r_t));
     77     PHYMOD_MEMSET(&chipid_msb, 0, sizeof(CHIP_ID1r_t));
     78 
     79     PHYMOD_IF_ERR_RETURN(
     80             READ_CHIP_ID0r(pa, &chipid_lsb));
     81     PHYMOD_IF_ERR_RETURN(
     82             READ_CHIP_ID1r(pa, &chipid_msb));
     83     chipid = CHIP_ID0r_GET(chipid_lsb);
     84     chipid |= (CHIP_ID1r_GET(chipid_msb)) << 16;
     85     
     86     return chipid;
     87 } 
     88 /**   poll intf update 
     89  *    This function is used to set the operating mode of the PHY
     90  *
     91  *    @param pa                 Pointer to phymod access structure 
     92                 
     93  *    @timeout                  timeout in us
     94  *    @return PHYMOD_E_NONE     successful function execution 
     95  */
     96 int _quadra28_intf_update_wait_check(const phymod_access_t *pa, uint32_t apps_mode0_reg_val,
     97                    int32_t timeout)          /* max wait time to check */
     98 {
     99     uint32_t timer_counter = 0;
    100     GENERAL_PURPOSE_3r_t gen_pur_reg_3r_val;
    101     timer_counter = (timeout / DELAY_1_MS_FROM_US);
    102     PHYMOD_MEMSET(&gen_pur_reg_3r_val, 0, sizeof(GENERAL_PURPOSE_3r_t));
    103     do {
    104         /* Read C843 register & compare its value with apps_mod0_reg_val */
    105         PHYMOD_IF_ERR_RETURN(READ_GENERAL_PURPOSE_3r(pa,&gen_pur_reg_3r_val));   
    106         if ((gen_pur_reg_3r_val.v[0] & 0xffff) == (apps_mode0_reg_val & 0xffff)) {
    107             return PHYMOD_E_NONE;
    108         }
    109         PHYMOD_USLEEP(DELAY_1_MS_FROM_US);
    110         timer_counter--;
    111     } while(timer_counter > 0);
    112     PHYMOD_DIAG_OUT(("Error Gp3:%x app:%x--:%x\n", gen_pur_reg_3r_val.v[0], apps_mode0_reg_val,pa->addr));
    113     return PHYMOD_E_FAIL;
    114 } 
    115 
    116 /**   Set config mode 
    117  *    This function is used to set the operating mode of the PHY
    118  *
    119  *    @param pa                 Pointer to phymod access structure 
    120  *    @param intf               Interface specified by user 
    121  *    @param speed              Speed val as specified by user  
    122  *    @param ref_clk            Reference clock frequency to set 
    123  *                              the PHY into specified interface 
    124  *                              and speed
    125  * 
    126  *    @return PHYMOD_E_NONE     successful function execution 
    127  */
    128 int quadra28_set_config_mode(const phymod_phy_access_t *phy,
    129                        phymod_interface_t intf,
    130                        uint32_t speed,
    131                        phymod_ref_clk_t ref_clk, uint32_t datapath,
    132                        uint16_t retimer)
    133 {
    134     uint16_t single_pmd_mode = 0;
    135     uint32_t pkg_side = 0;
    136     phymod_access_t acc_cpy;
    137     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
    138     MDIO_BROADCAST_CONTROLr_t mdio_broadcast_ctrl_reg;
    139     uint32_t phy_id = 0, lane_index = 0;
    140     int retry_cnt = 20;
    141     BCMI_QUADRA28_APPS_MODE_1r_t apps_mode1_reg;
    142     PHYMOD_MEMSET(&apps_mode1_reg, 0, sizeof(BCMI_QUADRA28_APPS_MODE_1r_t));
    143     PHYMOD_MEMSET(&apps_mode0_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));
    144     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
    145     PHYMOD_MEMSET(&mdio_broadcast_ctrl_reg, 0, sizeof(MDIO_BROADCAST_CONTROLr_t));
    146     phy_id = (phy->access.addr & 0x1f);
    147     QUADRA28_GET_LOC(phy, pkg_side);
    148     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    149 
    150     PHYMOD_IF_ERR_RETURN(READ_APPS_MODE_0r(&acc_cpy,&apps_mode0_reg_val));
    151 
    152     if (speed >= Q28_SPEED_40G) {
    153         for (lane_index = 0; lane_index < QUADRA28_MAX_LANE; lane_index ++) {
    154             acc_cpy.addr = phy->access.addr + lane_index;
    155             BCMI_QUADRA28_MDIO_BROADCAST_CONTROLr_MDIO_MCAST_ENf_SET(mdio_broadcast_ctrl_reg, 1);
    156             MDIO_BROADCAST_CONTROLr_MDIO_MULTICAST_PHYADf_SET(mdio_broadcast_ctrl_reg, phy_id);
    157             PHYMOD_IF_ERR_RETURN 
    158                    (WRITE_MDIO_BROADCAST_CONTROLr(&acc_cpy, mdio_broadcast_ctrl_reg));
    159         }
    160         acc_cpy.addr = phy->access.addr;
    161     }
    162     
    163     if ((speed <= Q28_SPEED_12P5G) ||
    164          BCMI_QUADRA28_APPS_MODE_0r_SPEEDf_GET(apps_mode0_reg_val) == 0x4 || 
    165          BCMI_QUADRA28_APPS_MODE_0r_SPEEDf_GET(apps_mode0_reg_val) == 0x7) {
    166          PHYMOD_IF_ERR_RETURN (
    167                 quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
    168     }
    169     if (datapath != 0xffff) {
    170         if (datapath == phymodDatapathNormal) {
    171             datapath = 0;
    172         } else {
    173             datapath = 1;
    174         }
    175     }
    176 
    177     
    178     /* Configure port speed */
    179     PHYMOD_IF_ERR_RETURN(_quadra28_config_port_speed (speed, \
    180         (uint32_t*)&apps_mode0_reg_val.v[0], (uint16_t*)&single_pmd_mode));
    181     if(Q28_INTF_LINE == pkg_side) {
    182         /* Configure line side interface */
    183         PHYMOD_IF_ERR_RETURN(_quadra28_config_line_interface(&phy->access, (uint32_t*)&apps_mode0_reg_val.v[0], 
    184             intf, speed));
    185     } else {
    186         /* configure system side interface */
    187         PHYMOD_IF_ERR_RETURN(_quadra28_config_sys_interface(&phy->access, (uint32_t*)&apps_mode0_reg_val.v[0], 
    188             intf));  
    189     } 
    190 
    191     if (speed >= Q28_SPEED_40G) {
    192          PHYMOD_IF_ERR_RETURN (
    193            BCMI_QUADRA28_READ_APPS_MODE_1r(&acc_cpy, &apps_mode1_reg));
    194          BCMI_QUADRA28_APPS_MODE_1r_RETIMER_MODEf_SET(apps_mode1_reg, 0);
    195          PHYMOD_IF_ERR_RETURN (
    196              BCMI_QUADRA28_WRITE_APPS_MODE_1r(&acc_cpy, apps_mode1_reg));
    197     } else {
    198         if (retimer != 0xFFFF) {
    199             PHYMOD_IF_ERR_RETURN (
    200               BCMI_QUADRA28_READ_APPS_MODE_1r(&acc_cpy, &apps_mode1_reg));
    201             BCMI_QUADRA28_APPS_MODE_1r_RETIMER_MODEf_SET(apps_mode1_reg, 
    202                     (retimer == phymodOperationModeRetimer) ? 1 : 0);
    203             PHYMOD_IF_ERR_RETURN (
    204               BCMI_QUADRA28_WRITE_APPS_MODE_1r(&acc_cpy, apps_mode1_reg));
    205         }
    206     }
    207     /* Resetting Datapath with the value got in core init*/
    208     if (datapath != 0xFFFF) {
    209         BCMI_QUADRA28_APPS_MODE_0r_ENABLE_ULL_DATAPATHf_SET(apps_mode0_reg_val, datapath);
    210     }
    211     PHYMOD_IF_ERR_RETURN(
    212                 _quadra28_refclk_set(&acc_cpy, phymodRefClk156Mhz));
    213 
    214     BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
    215     PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
    216     PHYMOD_USLEEP(10000);
    217     /* Set bit 7 in C8D8 reg to update changes */
    218     BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 1);
    219     PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
    220 
    221     PHYMOD_IF_ERR_RETURN(_quadra28_intf_update_wait_check(&acc_cpy,apps_mode0_reg_val.v[0], 50000));
    222 
    223     {
    224         BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
    225         BCMI_QUADRA28_CHIP_MODEr_t chip_mode;
    226         BCMI_QUADRA28_MERLIN_MISC_CTRLr_t reset_done;
    227         PHYMOD_MEMSET(&chip_mode, 0, sizeof(BCMI_QUADRA28_CHIP_MODEr_t));
    228         PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
    229         PHYMOD_MEMSET(&reset_done, 0, sizeof(BCMI_QUADRA28_MERLIN_MISC_CTRLr_t));
    230 
    231         PHYMOD_IF_ERR_RETURN(
    232             BCMI_QUADRA28_READ_CHIP_MODEr(&acc_cpy, &chip_mode));
    233         if (speed == Q28_SPEED_40G) {
    234             CHIP_MODEr_CHIP_MODEf_SET(chip_mode, 1);
    235         } else {
    236             CHIP_MODEr_CHIP_MODEf_SET(chip_mode, 0);
    237         }
    238         PHYMOD_IF_ERR_RETURN(
    239             BCMI_QUADRA28_WRITE_CHIP_MODEr(&acc_cpy, chip_mode));
    240 
    241         PHYMOD_IF_ERR_RETURN(
    242             BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
    243         BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1);
    244         PHYMOD_IF_ERR_RETURN(
    245             BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
    246     }
    247     {
    248         BCMI_QUADRA28_MERLIN_MISC_CTRLr_t reset_ack;
    249         BCMI_QUADRA28_XGXSSTATUSr_t xgs_sts;
    250         BCMI_QUADRA28_GENERAL_PURPOSE_1r_t gpreg_1;
    251         PHYMOD_MEMSET(&gpreg_1, 0, sizeof(gpreg_1));
    252         do {
    253             PHYMOD_IF_ERR_RETURN(
    254                 BCMI_QUADRA28_READ_MERLIN_MISC_CTRLr(&acc_cpy, &reset_ack));
    255             PHYMOD_USLEEP(1000);
    256             retry_cnt --;
    257         } while (((reset_ack.v[0] & 0x8000) != 0x8000) && retry_cnt);
    258         if (retry_cnt <= 0) {
    259             return PHYMOD_E_TIMEOUT;
    260         }
    261         retry_cnt = 20;
    262         PHYMOD_IF_ERR_RETURN(
    263                 BCMI_QUADRA28_READ_GENERAL_PURPOSE_1r(&acc_cpy, &gpreg_1));
    264         if (BCMI_QUADRA28_GENERAL_PURPOSE_1r_TXON_PAD_STATUSf_GET(gpreg_1) != 0) {
    265             do {
    266                 PHYMOD_IF_ERR_RETURN(
    267                     BCMI_QUADRA28_READ_XGXSSTATUSr(&acc_cpy, &xgs_sts));
    268                 PHYMOD_USLEEP(800);
    269                 retry_cnt --;
    270             }  while (((xgs_sts.v[0] & 0x800) != 0x800) && retry_cnt);
    271             if (retry_cnt <= 0) {
    272                 return PHYMOD_E_TIMEOUT;
    273             } 
    274         }
    275     } 
    276     apps_mode0_reg_val.v[0] &= 0xFF7F;
    277     PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
    278 
    279     PHYMOD_IF_ERR_RETURN(_quadra28_intf_update_wait_check(&acc_cpy,apps_mode0_reg_val.v[0], 50000));
    280     return PHYMOD_E_NONE;
    281 
    282 }
    283 /**   Get config mode 
    284  *    This function is used to retrieve the operating mode of the PHY
    285  *
    286  *    @param phy                Pointer to phy structure 
    287  *    @param intf               Interface type 
    288  *    @param speed              Speed val retrieved from PHY 
    289  *    @param ref_clk            Reference clock 
    290  *    @param interface_modes    Supported interface modes
    291  * 
    292  *    @return PHYMOD_E_NONE     successful function execution 
    293  */
    294 int quadra28_get_config_mode(const phymod_access_t *pa,
    295                        phymod_interface_t *intf,
    296                        uint32_t *speed,
    297                        phymod_ref_clk_t *ref_clk,
    298                        uint32_t *interface_modes)
    299 {
    300     uint16_t ref_clk_scaler_val = 0; 
    301     int pkg_side = 0;
    302     APPS_MODE_2r_t apps_mod2_reg_val;
    303     GENERAL_PURPOSE_3r_t gen_pur_reg_3r_val;
    304     uint16_t config_speed  = 0;
    305     phymod_access_t acc_cpy;
    306    
    307     *speed = 0;
    308     *intf = 0;
    309     *ref_clk = 0; 
    310 
    311     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
    312     PHYMOD_MEMSET(&gen_pur_reg_3r_val, 0, sizeof(GENERAL_PURPOSE_3r_t));
    313     PHYMOD_MEMSET(&apps_mod2_reg_val, 0 , sizeof(BCMI_QUADRA28_APPS_MODE_2r_t));
    314 
    315     QUADRA28_GET_IF_SIDE(acc_cpy.flags, pkg_side);
    316     if (acc_cpy.lane_mask == 0xf) {
    317         PHYMOD_IF_ERR_RETURN(
    318             quadra28_channel_select(&acc_cpy, 0));
    319     } else {
    320         /* Check the speed of 1st channel of this DIE*/
    321         PHYMOD_IF_ERR_RETURN(READ_GENERAL_PURPOSE_3r(&acc_cpy, &gen_pur_reg_3r_val));
    322         /* Extract bits for speed */
    323         config_speed = (gen_pur_reg_3r_val.v[0] & 0xF);
    324         if (0x1 == config_speed){
    325             *speed = Q28_SPEED_1G;
    326         } else if (0x2 == config_speed) {
    327             *speed = Q28_SPEED_10G;
    328         } else if (0x8 == config_speed) {
    329             *speed = Q28_SPEED_11P5G;
    330         } else if (0xC  == config_speed) {
    331             *speed = Q28_SPEED_20G;
    332         } else if (0x4  == config_speed) {
    333             *speed = Q28_SPEED_40G;
    334         } else if (0x7  == config_speed) {
    335             *speed = Q28_SPEED_42G;
    336             *interface_modes = PHYMOD_INTF_MODES_HIGIG; 
    337         } else if (0x5  == config_speed) {
    338             *speed = Q28_SPEED_HG11;
    339             *interface_modes = PHYMOD_INTF_MODES_HIGIG; 
    340         }
    341         if (*speed <= Q28_SPEED_HG11) {
    342             /* If lane mask is nott 0xF, assuming it as 10G*/
    343             Q28_10G_PHY_ID_WORK_AROUND(10000, acc_cpy);
    344         }
    345     }
    346    
    347     PHYMOD_IF_ERR_RETURN(READ_APPS_MODE_2r(&acc_cpy, &apps_mod2_reg_val));
    348     ref_clk_scaler_val = APPS_MODE_2r_REFERENCE_CLOCKf_GET(apps_mod2_reg_val);
    349     
    350     PHYMOD_IF_ERR_RETURN(READ_GENERAL_PURPOSE_3r(&acc_cpy, &gen_pur_reg_3r_val));
    351 
    352     /* Extract bits for speed */
    353     config_speed = (gen_pur_reg_3r_val.v[0] & 0xF);
    354     if (0x1 == config_speed){
    355         *speed = Q28_SPEED_1G;
    356     } else if (0x2 == config_speed) {
    357         *speed = Q28_SPEED_10G;
    358     } else if (0x8 == config_speed) {
    359         *speed = Q28_SPEED_11P5G;
    360     } else if (0xC  == config_speed) {
    361         *speed = Q28_SPEED_20G;
    362     } else if (0x4  == config_speed) {
    363         *speed = Q28_SPEED_40G;
    364     } else if (0x7  == config_speed) {
    365         *speed = Q28_SPEED_42G;
    366         *interface_modes = PHYMOD_INTF_MODES_HIGIG; 
    367     } else if (0x5  == config_speed) {
    368         *speed = Q28_SPEED_HG11;
    369         *interface_modes = PHYMOD_INTF_MODES_HIGIG; 
    370     }
    371 
    372     /* should use speed info & line side supported connections for Q28*/
    373     if (Q28_INTF_LINE == pkg_side) {
    374         if ((Q28_SPEED_42G == *speed || Q28_SPEED_40G == *speed)) {
    375             if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(14)) && 
    376               (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(9)))) {
    377                 *intf = phymodInterfaceLR4;
    378             } else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(9)) && 
    379                     (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(8))) &&
    380                     (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(14)))) {
    381                 *intf = phymodInterfaceCR4;
    382             } else if ((!(gen_pur_reg_3r_val.v[0] & Q28_BIT(8))) &&
    383                       (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(14)))) {
    384                 *intf = phymodInterfaceSR4;
    385             } else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(8)) &&
    386                       (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(14)))) {
    387                 *intf = phymodInterfaceKR4;
    388             } else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(14)) && 
    389                        (gen_pur_reg_3r_val.v[0] & Q28_BIT(9))) {
    390                 *intf = phymodInterfaceXLAUI;
    391             }
    392         } else if((Q28_SPEED_10G == *speed || Q28_SPEED_HG11 == *speed)) {
    393             if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(9)) &&
    394                 (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(8))) &&
    395                 (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(14)))) {
    396                *intf = phymodInterfaceCR;
    397             } else if ((!(gen_pur_reg_3r_val.v[0] & Q28_BIT(8))) &&
    398                        (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(14)))) {
    399                *intf = phymodInterfaceSR;
    400             }  else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(8)) &&
    401                        (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(14)))) {
    402                *intf = phymodInterfaceKR;
    403             } else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(14)) && 
    404                        (gen_pur_reg_3r_val.v[0] & Q28_BIT(12)) &&
    405                        (gen_pur_reg_3r_val.v[0] & Q28_BIT(9))) {
    406                *intf = phymodInterfaceZR;
    407             } else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(4)) && 
    408                        (gen_pur_reg_3r_val.v[0] & Q28_BIT(5)) &&
    409                        (gen_pur_reg_3r_val.v[0] & Q28_BIT(14))) {
    410                *intf = phymodInterfaceLRM;
    411             } else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(14)) && 
    412                        (gen_pur_reg_3r_val.v[0] & Q28_BIT(9))) {
    413                *intf = phymodInterfaceXFI;
    414             } else if ((!(gen_pur_reg_3r_val.v[0] & Q28_BIT(9))) && 
    415                       (gen_pur_reg_3r_val.v[0] & Q28_BIT(14))) {
    416                *intf = phymodInterfaceLR;
    417             }
    418         } else if (Q28_SPEED_1G == *speed) {
    419             if ((!(gen_pur_reg_3r_val.v[0] & Q28_BIT(8))) &&
    420                 (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(10)))) {
    421                 /**intf = phymodInterface1000X;*/
    422                 /*Since interface 1000X is not supported in phyctrl
    423                  * returning as SR*/
    424                 *intf = phymodInterfaceSR;
    425             } else if (gen_pur_reg_3r_val.v[0] & Q28_BIT(8)) {
    426                 *intf = phymodInterfaceKX;
    427             }
    428         }
    429     } else if (Q28_INTF_SYS == pkg_side) {
    430        /* If speed is 40G or 42G, system side connections: XLAUI, Forced CL72 */
    431         if (Q28_SPEED_40G == *speed || Q28_SPEED_42G == *speed) {
    432             if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(15)) &&
    433                  (gen_pur_reg_3r_val.v[0] & Q28_BIT(11))) {
    434                 *intf = phymodInterfaceXLAUI;
    435             } else if ((gen_pur_reg_3r_val.v[0] & (Q28_BIT(11))) && 
    436                     !(gen_pur_reg_3r_val.v[0] & (Q28_BIT(15)))) {
    437                 *intf = phymodInterfaceCR4;
    438             } else if ((gen_pur_reg_3r_val.v[0] & (Q28_BIT(10)))) {
    439                 *intf = phymodInterfaceKR4;
    440             }
    441         } else if((Q28_SPEED_10G == *speed || Q28_SPEED_HG11 == *speed)) {
    442             if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(15)) &&
    443                  (gen_pur_reg_3r_val.v[0] & Q28_BIT(11))) {
    444                 *intf = phymodInterfaceXFI;
    445             } else if ((gen_pur_reg_3r_val.v[0] & (Q28_BIT(10)))) {
    446                 *intf = phymodInterfaceKR;
    447             }else if ((gen_pur_reg_3r_val.v[0] & Q28_BIT(11))){
    448                 *intf = phymodInterfaceCR;
    449             }
    450         } else if(*speed == Q28_SPEED_1G) {
    451             if ((!(gen_pur_reg_3r_val.v[0] & Q28_BIT(8))) &&
    452                 (!(gen_pur_reg_3r_val.v[0] & Q28_BIT(10)))) {
    453                 /**intf = phymodInterface1000X;*/
    454                 /*Since interface 1000X is not supported in phyctrl
    455                  * returning as SR*/
    456                 *intf = phymodInterfaceSR;
    457             } else if (gen_pur_reg_3r_val.v[0] & Q28_BIT(8)) {
    458                 *intf = phymodInterfaceKX;
    459             }
    460         }
    461         if (*intf == 0) {
    462             return PHYMOD_E_FAIL;
    463         }
    464     }
    465     
    466     if (phymodRefClk156Mhz == ref_clk_scaler_val) {
    467         *ref_clk = phymodRefClk156Mhz;
    468     } else {
    469         *ref_clk = phymodRefClk155Mhz; /* check this */
    470     }
    471    
    472     return PHYMOD_E_NONE;
    473 }
    474 
    475 /**   Configure PRBS generator 
    476  *    This function is used to configure PRBS generator with user provided
    477  *    polynomial and invert data information 
    478  *
    479  *    @param pa                 Pointer to phymod access structure 
    480  *    @param flags              Flags to prbs config 
    481  *    @param prbs_mode          User specified polynomial
    482  *                              0 - PRBS7
    483  *                              1 - PRBS9
    484  *                              2 - PRBS11    
    485  *                              3 - PRBS15
    486  *                              4 - PRBS23
    487  *                              5 - PRBS31
    488  *                              6 - PRBS58
    489  * 
    490  *    @param prbs_inv           User specified invert data config
    491  *                              0 - do not invert PRBS data  
    492  *                              1 - invert PRBS data  
    493  *
    494  *    @return PHYMOD_E_NONE     successful function execution 
    495  */
    496 int quara28_prbs_config_set(const phymod_phy_access_t *phy,
    497                         uint32_t flags,
    498                         uint32_t prbs_mode,
    499                         uint32_t prbs_inv)
    500 {
    501 
    502     int pkg_side = 0;
    503     int num_lanes = QUADRA28_MAX_LANE; /* num of lanes in octal package core */
    504     int lane_index = 0, pmd_mode = 0;
    505     unsigned short int lane_map = 0;
    506     uint32_t speed = 0;
    507     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
    508     BCMI_QUADRA28_PRBS_CHK_CONFIGr_t ckr_cfg;
    509     BCMI_QUADRA28_GENERAL_PURPOSE_3r_t gpreg3;
    510     phymod_access_t acc_cpy;
    511     
    512     /* Get the lane map from phymod access */
    513     lane_map = PHYMOD_ACC_LANE_MASK(&phy->access);
    514     QUADRA28_GET_LOC(phy,pkg_side);
    515 
    516     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
    517     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));
    518     PHYMOD_MEMSET(&ckr_cfg, 0 , sizeof(BCMI_QUADRA28_PRBS_CHK_CONFIGr_t));
    519     PHYMOD_MEMSET(&gpreg3, 0 , sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_3r_t));
    520     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
    521     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    522     QUADRA28_SELECT_SIDE(&acc_cpy, side_sel_reg_val, pkg_side);
    523     if (pmd_mode == Q28_SINGLE_PMD) {
    524         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
    525             if (((lane_map >> lane_index) & 1) == 0x1) {
    526                 PHYMOD_IF_ERR_RETURN(
    527                    quadra28_channel_select(&acc_cpy,
    528                       ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
    529 
    530                 if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)){
    531                     PHYMOD_IF_ERR_RETURN(
    532                             merlin_quadra28_config_tx_prbs(&acc_cpy, prbs_mode, (uint8_t)prbs_inv)); 
    533                 }
    534                 /* Following code block for PRBS Checker or RX*/
    535                 if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    536                     PHYMOD_IF_ERR_RETURN(
    537                             merlin_quadra28_config_rx_prbs(&acc_cpy, prbs_mode, PRBS_INITIAL_SEED_HYSTERESIS, (uint8_t)prbs_inv)); 
    538                 }
    539                 if (Q28_ALL_LANE == lane_map){
    540                     break;
    541                 }
    542             }
    543         }
    544     } else {
    545         if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)){
    546             PHYMOD_IF_ERR_RETURN(
    547                 merlin_quadra28_config_tx_prbs(&acc_cpy, prbs_mode, (uint8_t)prbs_inv)); 
    548         }
    549         /* Following code block for PRBS Checker or RX*/
    550         if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    551             PHYMOD_IF_ERR_RETURN(
    552                 merlin_quadra28_config_rx_prbs(&acc_cpy, prbs_mode, PRBS_INITIAL_SEED_HYSTERESIS, (uint8_t)prbs_inv));
    553             PHYMOD_IF_ERR_RETURN(
    554                 BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(&acc_cpy, &gpreg3));
    555             if (gpreg3.v[0] & 0x20) {
    556                 PHYMOD_IF_ERR_RETURN(
    557                     BCMI_QUADRA28_READ_PRBS_CHK_CONFIGr(&acc_cpy, &ckr_cfg));
    558                 BCMI_QUADRA28_PRBS_CHK_CONFIGr_PRBS_CHK_EN_AUTO_MODEf_SET(ckr_cfg,0);
    559                 PHYMOD_IF_ERR_RETURN(
    560                     BCMI_QUADRA28_WRITE_PRBS_CHK_CONFIGr(&acc_cpy, ckr_cfg));
    561             }
    562 
    563         }
    564     }
    565     
    566     /* restore Q28_INTF_LINE side */
    567     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val,Q28_INTF_LINE);	
    568 
    569     return PHYMOD_E_NONE;
    570 }
    571 
    572 /**   Get PRBS generator configuration 
    573  *    This function is used to retrieve PRBS generator configuration from 
    574  *    the chip 
    575  *
    576  *    @param pa                 Pointer to phymod access structure 
    577  *    @param flags              Flags for prbs
    578  *    @param prbs_mode          Configured Polynomial retrieved from chip 
    579  *    @param prbs_inv           Configured invert data retrieved from chip
    580  *                              0 - do not invert PRBS data  
    581  *                              1 - invert PRBS data  
    582  *
    583  *    @return PHYMOD_E_NONE     successful function execution 
    584  */
    585 int quadra28_prbs_config_get(const phymod_phy_access_t *phy,
    586                         uint32_t flags,
    587                         enum srds_prbs_polynomial_enum *prbs_mode,
    588                         uint32_t *prbs_inv)
    589 {
    590 
    591     int lane_map = 0;
    592     int pkg_side = 0;
    593     int num_lanes = QUADRA28_MAX_LANE;
    594     int lane_index = 0;
    595     uint8_t prbs_invert = 0;
    596     uint32_t prbs_checker_mode = 0;
    597     phymod_access_t acc_cpy;
    598     int pmd_mode = 0;
    599     uint32_t speed = 0;
    600     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
    601 
    602     *prbs_inv = 0;
    603     *prbs_mode = 0; 
    604     
    605     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
    606     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));
    607     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
    608     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    609 
    610     /* Get the lane map from phymod access */ 
    611     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
    612     QUADRA28_GET_LOC(phy,pkg_side);
    613     
    614     QUADRA28_SELECT_SIDE(&acc_cpy, side_sel_reg_val, pkg_side);
    615 
    616     if (pmd_mode == Q28_SINGLE_PMD) {
    617         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
    618             if (((lane_map >> lane_index) & 1) == 0x1) {
    619                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
    620                 if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)){
    621                     PHYMOD_IF_ERR_RETURN(
    622                             merlin_quadra28_get_tx_prbs_config(&acc_cpy, prbs_mode, &prbs_invert));
    623                     *prbs_inv = prbs_invert;
    624                 }
    625                 if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    626                     /* Read Serdes API */
    627                     PHYMOD_IF_ERR_RETURN(
    628                             merlin_quadra28_get_rx_prbs_config(&acc_cpy, prbs_mode, &prbs_checker_mode, &prbs_invert));
    629                     *prbs_inv = prbs_invert;
    630                 }
    631                 break;
    632             }
    633         }
    634     } else {
    635         if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)){
    636             PHYMOD_IF_ERR_RETURN(
    637                     merlin_quadra28_get_tx_prbs_config(&acc_cpy, prbs_mode, &prbs_invert));
    638             *prbs_inv = prbs_invert;
    639         }
    640         if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    641            /* Read Serdes API */
    642             PHYMOD_IF_ERR_RETURN(
    643                    merlin_quadra28_get_rx_prbs_config(&acc_cpy, prbs_mode, &prbs_checker_mode, &prbs_invert));
    644             *prbs_inv = prbs_invert;
    645         }
    646     }
    647 
    648     /* restore Q28_INTF_LINE side */
    649     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val,Q28_INTF_LINE);	
    650     return PHYMOD_E_NONE;  
    651 }
    652 
    653 /**   Enable PRBS generator and PRBS checker 
    654  *    This function is used to enable or disable PRBS generator and PRBS checker
    655  *    as requested by the user  
    656  *
    657  *    @param pa                 Pointer to phymod access structure 
    658  *    @param flags              Flags for prbs
    659  *    @param enable              Enable or disable as specified by the user
    660  *                              1 - Enable
    661  *                              0 - Disable 
    662  * 
    663  *    @return PHYMOD_E_NONE     successful function execution 
    664  */
    665 int quadra28_prbs_enable_set(const phymod_phy_access_t *phy, uint32_t flags, uint32_t enable_state)
    666 {
    667     int pkg_side = 0;
    668     int num_lanes = QUADRA28_MAX_LANE; /* num of lanes in octal package core */
    669     int lane_index = 0;
    670     int lane_map = 0;
    671     phymod_access_t acc_cpy;
    672     int pmd_mode = 0;
    673     uint32_t speed = 0;
    674     SIDE_SELECTIONr_t side_sel_reg;
    675     BCMI_QUADRA28_PRBS_GEN_CONFIGr_t prbs_gen_config_reg_val;
    676     BCMI_QUADRA28_PRBS_CHK_CONFIGr_t prbs_chk_config_reg_val;
    677  
    678     PHYMOD_MEMSET(&prbs_gen_config_reg_val, 0, sizeof(BCMI_QUADRA28_PRBS_GEN_CONFIGr_t));
    679     PHYMOD_MEMSET(&prbs_chk_config_reg_val, 0, sizeof(BCMI_QUADRA28_PRBS_CHK_CONFIGr_t));
    680     PHYMOD_MEMSET(&side_sel_reg, 0, sizeof(SIDE_SELECTIONr_t));
    681     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
    682 
    683     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
    684     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    685    
    686     /* Get the lane map from phymod access */
    687     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
    688     QUADRA28_GET_LOC(phy,pkg_side);
    689     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg, pkg_side);
    690     
    691     if (pmd_mode == Q28_SINGLE_PMD) {
    692         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
    693             if (((lane_map >> lane_index) & 1) == 0x1) {
    694                 PHYMOD_IF_ERR_RETURN(
    695                    quadra28_channel_select(&acc_cpy,
    696                       ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
    697 
    698                 /* Select respective side */
    699                 if ((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)) {
    700                     PHYMOD_IF_ERR_RETURN(
    701                       merlin_quadra28_tx_prbs_en(&acc_cpy, enable_state));
    702                 }
    703                 /* Following code block for PRBS Checker or RX*/
    704                 if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    705                     PHYMOD_IF_ERR_RETURN(
    706                        merlin_quadra28_rx_prbs_en(&acc_cpy, enable_state));
    707                 }
    708                 if (lane_map == Q28_ALL_LANE) {
    709                     break;
    710                 }
    711             }
    712         }
    713     } else {
    714        /* Select respective side */
    715         if ((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)) {
    716             PHYMOD_IF_ERR_RETURN(
    717               merlin_quadra28_tx_prbs_en(&acc_cpy, enable_state));
    718         }
    719         /* Following code block for PRBS Checker or RX*/
    720         if((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    721             PHYMOD_IF_ERR_RETURN(
    722                merlin_quadra28_rx_prbs_en(&acc_cpy, enable_state));
    723         }
    724     }
    725     /* restore Q28_INTF_LINE side */
    726     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg,Q28_INTF_LINE);		
    727     return PHYMOD_E_NONE;
    728 }
    729 
    730 /**   Get Enable status of PRBS generator and PRBS checker 
    731  *    This function is used to retrieve the enable status of PRBS generator and
    732  *    PRBS checker
    733  *
    734  *    @param pa                 Pointer to phymod access structure 
    735  *    @param flags              Flags for prbs
    736  *    @param enable              Enable or disable read from chip 
    737  *                              1 - Enable
    738  *                              0 - Disable 
    739  * 
    740  *    @return PHYMOD_E_NONE     successful function execution 
    741  */
    742 int quadra28_prbs_enable_get(const phymod_phy_access_t *phy, uint32_t flags, uint32_t *enable)
    743 {
    744     int pkg_side = 0;
    745     int num_lanes = QUADRA28_MAX_LANE; /* num of lanes in octal package core */
    746     int lane_index = 0;
    747     int lane_map = 0;
    748     SIDE_SELECTIONr_t side_sel_reg;
    749     BCMI_QUADRA28_PRBS_GEN_CONFIGr_t prbs_gen_config_reg_val;
    750     BCMI_QUADRA28_PRBS_CHK_CONFIGr_t prbs_chk_config_reg_val;
    751     uint8_t gen_en = 0;
    752     uint8_t chk_en = 0;
    753     phymod_access_t acc_cpy;
    754     int pmd_mode = 0;
    755     uint32_t speed = 0;
    756     
    757     *enable = 0;
    758 
    759     /* Get the lane map from phymod access */
    760     lane_map = PHYMOD_ACC_LANE_MASK(&phy->access);
    761     QUADRA28_GET_LOC(phy,pkg_side);
    762     
    763     PHYMOD_MEMSET(&prbs_gen_config_reg_val, 0, sizeof(BCMI_QUADRA28_PRBS_GEN_CONFIGr_t));
    764     PHYMOD_MEMSET(&prbs_chk_config_reg_val, 0, sizeof(BCMI_QUADRA28_PRBS_CHK_CONFIGr_t));
    765     PHYMOD_MEMSET(&side_sel_reg, 0, sizeof(BCMI_QUADRA28_PRBS_CHK_CONFIGr_t));
    766     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
    767     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
    768     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    769     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg, pkg_side);
    770 
    771     if (pmd_mode == Q28_SINGLE_PMD) {
    772         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
    773             if (((lane_map >> lane_index) & 1) == 0x1) {
    774                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
    775                 if ((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)) {
    776                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_get_tx_prbs_en(&acc_cpy, &gen_en));
    777                     *enable = gen_en;
    778                 }
    779                 if ((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    780                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_get_rx_prbs_en(&acc_cpy, &chk_en));
    781                     *enable = chk_en;
    782                 }
    783                 break;				
    784             }
    785          }
    786     } else {
    787         if ((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_TX)) {
    788             PHYMOD_IF_ERR_RETURN(merlin_quadra28_get_tx_prbs_en(&acc_cpy, &gen_en));
    789             *enable = gen_en;
    790         }
    791         if ((flags == 0) || (flags == PHYMOD_PRBS_DIRECTION_RX)) {
    792             PHYMOD_IF_ERR_RETURN(merlin_quadra28_get_rx_prbs_en(&acc_cpy, &chk_en));
    793             *enable = chk_en;
    794         }
    795     }
    796     if (flags == 0) {
    797         if(gen_en && chk_en) {
    798             *enable = 1;
    799         } else {
    800             *enable = 0;
    801         }
    802     }
    803      /* restore Q28_INTF_LINE side */
    804     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg,Q28_INTF_LINE);	
    805     return PHYMOD_E_NONE;
    806 }
    807 
    808 
    809 /**   Get PRBS lock and error status 
    810  *    This function is used to retrieve PRBS lock, loss of lock and error counts
    811  *    from the chip 
    812  *
    813  *    @param pa                 Pointer to phymod access structure 
    814  *    @param lock_status        PRBS lock status denotes PRBS generator and 
    815  *                              checker are locked to same polynomial data
    816  *    @param lock_loss          Lo of lock denotes PRBS generator and checker
    817  *                              are not in sync   
    818  *    @param error_count        PRBS error count retrieved from chip
    819  *
    820  *    @return PHYMOD_E_NONE     successful function execution 
    821  */
    822 int quadra28_prbs_status_get(const phymod_phy_access_t *phy,
    823                                 uint32_t *lock_status,
    824                                 uint32_t *lock_loss,
    825                                 uint32_t *error_count)
    826 {
    827     int lane_map = 0;
    828     int pkg_side = 0;
    829     int num_lanes = QUADRA28_MAX_LANE;
    830     int lane_index = 0; 
    831     uint8_t loss_of_lock = 0;
    832     uint32_t per_lane_err_count = 0;
    833     uint8_t prbs_chk_lock_stat;
    834     phymod_access_t acc_cpy;
    835     int pmd_mode = 0;
    836     uint32_t speed = 0;
    837     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
    838 
    839     *lock_status = 1;
    840     *lock_loss = 1;
    841     *error_count = 0;
    842    
    843     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));	
    844     PHYMOD_MEMCPY(&acc_cpy,&phy->access, sizeof(phymod_access_t));
    845 
    846     /* Get the lane map from phymod access */ 
    847     lane_map = PHYMOD_ACC_LANE_MASK(&phy->access);
    848     QUADRA28_GET_LOC(phy, pkg_side);
    849     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
    850     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    851     
    852     /* Select respective side */
    853     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
    854     if (pmd_mode == Q28_SINGLE_PMD) {
    855         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
    856             if (((lane_map >> lane_index) & 1) == 0x1) {
    857                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
    858                    
    859                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_prbs_chk_lock_state(&acc_cpy, (uint8_t*)&prbs_chk_lock_stat));
    860  
    861                 *lock_status &= prbs_chk_lock_stat;
    862                 
    863                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_prbs_err_count_state(&acc_cpy, &per_lane_err_count, &loss_of_lock));
    864                 *error_count |= per_lane_err_count;
    865                 *lock_loss &= loss_of_lock;
    866             }
    867         }
    868     } else {
    869         PHYMOD_IF_ERR_RETURN(merlin_quadra28_prbs_chk_lock_state(&acc_cpy, (uint8_t*)&prbs_chk_lock_stat));
    870         *lock_status &= prbs_chk_lock_stat;
    871         PHYMOD_IF_ERR_RETURN(merlin_quadra28_prbs_err_count_state(&acc_cpy, &per_lane_err_count, &loss_of_lock));
    872         *error_count |= per_lane_err_count;
    873         *lock_loss &= loss_of_lock;
    874     }
    875     /* restore Q28_INTF_LINE side */
    876     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val,Q28_INTF_LINE);	
    877     return PHYMOD_E_NONE;
    878 }								
    879 /**   Get  link status of PHY 
    880  *    This function is used to retrieve the link status of PHY chip
    881  *
    882  *    @param pa                 Pointer to phymod access structure 
    883  *
    884  *    @param link_status        link status of the PHY 
    885  *                              1 - Up 
    886  *                              0 - Down 
    887  * 
    888  *    @return PHYMOD_E_NONE     successful function execution 
    889  */
    890 int quadra28_link_status(const phymod_phy_access_t *phy, uint32_t *link_status)
    891 {
    892     int pkg_side = 0;
    893     int num_lanes = QUADRA28_MAX_LANE;
    894     int lane_map = 0;
    895     uint32_t retime_enable = 0, pcs_status = 0; 
    896     int lane_index = 0;
    897     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
    898     BCMI_QUADRA28_PMD_STATUSr_t ieee_pmd_status1_reg_val;
    899     BCMI_QUADRA28_PCS_STATUS1r_t pcs_status1_reg_val;	
    900     phymod_access_t acc_cpy;
    901     int pmd_mode = 0;
    902     uint32_t speed = 0;
    903 
    904  
    905     PHYMOD_MEMSET(&side_sel_reg_val, 0, sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));
    906     PHYMOD_MEMSET(&ieee_pmd_status1_reg_val, 0, sizeof(BCMI_QUADRA28_PMD_STATUSr_t));
    907     PHYMOD_MEMSET(&pcs_status1_reg_val, 0, sizeof(BCMI_QUADRA28_PCS_STATUS1r_t)); 
    908     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
    909 
    910     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
    911     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
    912 
    913     QUADRA28_GET_LOC(phy, pkg_side);
    914     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
    915 
    916     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val,pkg_side);
    917     *link_status = 1;
    918 
    919     if (pmd_mode == Q28_SINGLE_PMD) {
    920         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
    921             if (((lane_map >> lane_index) & 1) == 0x1) {
    922                 /* select a lane */
    923                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
    924                 
    925                 /* Get PMD status */
    926                 PHYMOD_IF_ERR_RETURN(BCMI_QUADRA28_READ_PMD_STATUSr(&acc_cpy, &ieee_pmd_status1_reg_val));
    927                 *link_status &= BCMI_QUADRA28_PMD_STATUSr_LN_LKDTCDRf_GET(ieee_pmd_status1_reg_val);
    928              }
    929          }
    930     } else {
    931        /* Get PCS status if PCS is ON */
    932        PHYMOD_IF_ERR_RETURN(
    933             _quadra28_phy_retimer_enable_get(&acc_cpy, &retime_enable));
    934        if (1 == retime_enable) {
    935            if (speed == 1000) {
    936               PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_read(&acc_cpy, 0x7ffe1, &pcs_status));
    937               *link_status &= ((pcs_status & 0x4) >> 2);
    938            } else {
    939                PHYMOD_IF_ERR_RETURN(
    940                        BCMI_QUADRA28_READ_PCS_STATUS1r(&acc_cpy, &pcs_status1_reg_val));
    941                *link_status &= BCMI_QUADRA28_PCS_STATUS1r_PCS_RECEIVE_LINK_STATUSf_GET(pcs_status1_reg_val);
    942            }
    943        }
    944        /* Get PMD status */
    945        PHYMOD_IF_ERR_RETURN(BCMI_QUADRA28_READ_PMD_STATUSr(&acc_cpy, &ieee_pmd_status1_reg_val));
    946        *link_status &= BCMI_QUADRA28_PMD_STATUSr_LN_LKDTCDRf_GET(ieee_pmd_status1_reg_val);
    947     }
    948     /* restore Q28_INTF_LINE side */
    949     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val,Q28_INTF_LINE);
    950     return PHYMOD_E_NONE;
    951     
    952 }
    953 
    954 int _quadra28_refclk_set(const phymod_access_t *pa, uint32_t ref_clk) 
    955 {
    956     BCMI_QUADRA28_APPS_MODE_2r_t apps_mod2_reg_val;
    957        
    958     PHYMOD_MEMSET(&apps_mod2_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_2r_t));
    959     PHYMOD_IF_ERR_RETURN(BCMI_QUADRA28_READ_APPS_MODE_2r(pa, &apps_mod2_reg_val));
    960     if (phymodRefClk156Mhz == ref_clk) {
    961         BCMI_QUADRA28_APPS_MODE_2r_REFERENCE_CLOCKf_SET(apps_mod2_reg_val,0);
    962     } else {
    963         BCMI_QUADRA28_APPS_MODE_2r_REFERENCE_CLOCKf_SET(apps_mod2_reg_val,1);
    964     }
    965 
    966     PHYMOD_IF_ERR_RETURN(BCMI_QUADRA28_WRITE_APPS_MODE_2r(pa, apps_mod2_reg_val));
    967    
    968     return PHYMOD_E_NONE;
    969 }
    970 
    971 /**   Set Tx Rx polarity 
    972  *    This function is used to set Tx Rx polarity of a single lane
    973  *    or multiple lanes 
    974  *
    975  *    @param phy                 Pointer to phymod access structure 
    976  *    @param tx_polarity        Tx polarity 
    977  *    @param rx_polarity        Rx polarity 
    978  *
    979  *    @return PHYMOD_E_NONE     successful function execution 
    980  */
    981 int quadra28_tx_rx_polarity_set (const phymod_phy_access_t *phy, uint32_t tx_polarity, uint32_t rx_polarity)
    982 {
    983     int lane_map = 0;
    984     int pkg_side = 0;
    985     int num_lanes = QUADRA28_MAX_LANE;
    986     int lane_index = 0;
    987     BCMI_QUADRA28_TX_CTRL_0r_t tx_ctrl0r_config;
    988     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
    989     BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_t  tx_misc;
    990     BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_t   rx_misc;
    991     phymod_access_t acc_cpy;
    992     int pmd_mode = 0;
    993     uint32_t speed = 0;
    994     uint8_t datapath = 0;
    995     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));	
    996     PHYMOD_MEMSET(&tx_ctrl0r_config, 0 , sizeof(BCMI_QUADRA28_TX_CTRL_0r_t));
    997     PHYMOD_MEMSET(&tx_misc, 0 , sizeof(BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_t));
    998     PHYMOD_MEMSET(&rx_misc, 0 , sizeof(BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_t));
    999     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1000 
   1001     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1002     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1003   
   1004     /* Get the lane map from phymod access */
   1005     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1006     QUADRA28_GET_LOC(phy, pkg_side);
   1007     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val,pkg_side);
   1008     Q28_GET_DATAPATH(&acc_cpy, datapath);
   1009     if (pmd_mode == Q28_SINGLE_PMD) {
   1010         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1011             if (((lane_map >> lane_index) & 1) == 0x1) {
   1012                 PHYMOD_IF_ERR_RETURN(
   1013                    quadra28_channel_select(&acc_cpy, lane_index));
   1014                 if (datapath == phymodDatapathUll) {
   1015                     if (tx_polarity == 0xFFFF || tx_polarity == 0xFFFFFFFF) {
   1016                         continue;
   1017                     }
   1018                     /* Read 4bit tx config register for both line & sys side */
   1019                     PHYMOD_IF_ERR_RETURN
   1020                         (BCMI_QUADRA28_READ_TX_CTRL_0r(&acc_cpy, &tx_ctrl0r_config));
   1021                     /* Program 4-bit Line Side Tx Polarity Flip */
   1022                     BCMI_QUADRA28_TX_CTRL_0r_LL_POLARITY_FLIPf_SET(tx_ctrl0r_config, 
   1023                             ((tx_polarity >> lane_index) & 1));
   1024                     /* Write to Rx config register - 4-bit */
   1025                     PHYMOD_IF_ERR_RETURN(
   1026                         BCMI_QUADRA28_WRITE_TX_CTRL_0r(&acc_cpy, tx_ctrl0r_config));
   1027                 } else {
   1028                     if (tx_polarity == 0xFFFF || tx_polarity == 0xFFFFFFFF) {
   1029                         continue;
   1030                     }
   1031                     PHYMOD_IF_ERR_RETURN(
   1032                         BCMI_QUADRA28_READ_TLB_TX_MISC_CONFIGr(&acc_cpy, &tx_misc));
   1033                     BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_TX_PMD_DP_INVERTf_SET(tx_misc, 
   1034                                   ((tx_polarity >> lane_index) & 1));
   1035                     PHYMOD_IF_ERR_RETURN(
   1036                         BCMI_QUADRA28_WRITE_TLB_TX_MISC_CONFIGr(&acc_cpy, tx_misc));
   1037                     if (rx_polarity == 0xFFFF || rx_polarity == 0xFFFFFFFF) {
   1038                         continue;
   1039                     }
   1040                     PHYMOD_IF_ERR_RETURN(
   1041                         BCMI_QUADRA28_READ_TLB_RX_MISC_CONFIGr(&acc_cpy, &rx_misc));
   1042                     BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_RX_PMD_DP_INVERTf_SET(rx_misc, 
   1043                                    ((rx_polarity >> lane_index) & 1));
   1044                     PHYMOD_IF_ERR_RETURN(
   1045                         BCMI_QUADRA28_WRITE_TLB_RX_MISC_CONFIGr(&acc_cpy, rx_misc));
   1046                 }
   1047             }
   1048         } /* End for */
   1049     } else {
   1050          
   1051         if (datapath == phymodDatapathUll) {
   1052             if ((tx_polarity != 0xFFFF) && (tx_polarity != 0xFFFFFFFF)) {
   1053                 /* Read 4bit tx config register for both line & sys side */
   1054                 PHYMOD_IF_ERR_RETURN
   1055                     (BCMI_QUADRA28_READ_TX_CTRL_0r(&acc_cpy, &tx_ctrl0r_config));
   1056                                    
   1057                 /* Program 4-bit Line Side Tx Polarity Flip */
   1058                 BCMI_QUADRA28_TX_CTRL_0r_LL_POLARITY_FLIPf_SET(tx_ctrl0r_config, tx_polarity);
   1059                 
   1060                 /* Write to Rx config register - 4-bit */
   1061                 PHYMOD_IF_ERR_RETURN(
   1062                     BCMI_QUADRA28_WRITE_TX_CTRL_0r(&acc_cpy, tx_ctrl0r_config));
   1063             }
   1064         } else {
   1065             if ((tx_polarity != 0xFFFF) && (tx_polarity != 0xFFFFFFFF)) {
   1066                 PHYMOD_IF_ERR_RETURN(
   1067                     BCMI_QUADRA28_READ_TLB_TX_MISC_CONFIGr(&acc_cpy, &tx_misc));
   1068                 BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_TX_PMD_DP_INVERTf_SET(tx_misc, tx_polarity);
   1069                 PHYMOD_IF_ERR_RETURN(
   1070                     BCMI_QUADRA28_WRITE_TLB_TX_MISC_CONFIGr(&acc_cpy, tx_misc));
   1071             }
   1072             if ((rx_polarity != 0xFFFF) && (rx_polarity != 0xFFFFFFFF)) {
   1073                 PHYMOD_IF_ERR_RETURN(
   1074                     BCMI_QUADRA28_READ_TLB_RX_MISC_CONFIGr(&acc_cpy, &rx_misc));
   1075                 BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_RX_PMD_DP_INVERTf_SET(rx_misc, rx_polarity); 
   1076                 PHYMOD_IF_ERR_RETURN(
   1077                     BCMI_QUADRA28_WRITE_TLB_RX_MISC_CONFIGr(&acc_cpy, rx_misc));
   1078             }
   1079         }
   1080     }
   1081     /* restore Q28_INTF_LINE side */
   1082     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val,Q28_INTF_LINE);
   1083     return PHYMOD_E_NONE;
   1084 }
   1085 /**   Get Tx Rx polarity 
   1086  *    This function is used to get Tx Rx polarity of a specific lane
   1087  *    specified by user 
   1088  *
   1089  *    @param phy                 Pointer to phymod access structure 
   1090  *    @param tx_polarity        Tx polarity 
   1091  *    @param rx_polarity        Rx polarity 
   1092  *
   1093  *    @return PHYMOD_E_NONE     successful function execution 
   1094  */
   1095 int quadra28_tx_rx_polarity_get (const phymod_phy_access_t *phy, uint32_t *tx_polarity, uint32_t *rx_polarity)
   1096 {
   1097     int lane_map = 0;
   1098     int pkg_side = 0;
   1099     int num_lanes = 0;
   1100     int lane_index = 0;
   1101     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
   1102     phymod_access_t acc_cpy;
   1103     int pmd_mode = 0;
   1104     uint32_t speed = 0;
   1105     BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_t  tx_misc;
   1106     BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_t   rx_misc;
   1107     uint8_t datapath = 0;
   1108     BCMI_QUADRA28_TX_CTRL_0r_t tx_ctrl0r_config;
   1109 
   1110     PHYMOD_MEMSET(&tx_misc, 0 , sizeof(BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_t));
   1111     PHYMOD_MEMSET(&rx_misc, 0 , sizeof(BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_t));
   1112     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));	
   1113     PHYMOD_MEMSET(&tx_ctrl0r_config, 0 , sizeof(BCMI_QUADRA28_TX_CTRL_0r_t));	
   1114     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1115 
   1116     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1117     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1118 
   1119     /* Get the lane map from phymod access */
   1120     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1121     QUADRA28_GET_LOC(phy, pkg_side);
   1122     
   1123     Q28_GET_DATAPATH(&acc_cpy, datapath);
   1124     num_lanes = QUADRA28_MAX_LANE; /* for octal pkg */
   1125 
   1126     *tx_polarity = 0;
   1127     *rx_polarity = 0;
   1128     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1129 
   1130     if (pmd_mode == Q28_SINGLE_PMD) {
   1131         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1132             if (((lane_map >> lane_index) & 1) == 0x1) {
   1133                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1134                 if (datapath == phymodDatapathUll) {
   1135                     PHYMOD_IF_ERR_RETURN
   1136                       (BCMI_QUADRA28_READ_TX_CTRL_0r(&acc_cpy, &tx_ctrl0r_config));
   1137                     *tx_polarity |= (BCMI_QUADRA28_TX_CTRL_0r_LL_POLARITY_FLIPf_GET(tx_ctrl0r_config)) << lane_index;
   1138                 } else {
   1139                     PHYMOD_IF_ERR_RETURN(
   1140                         BCMI_QUADRA28_READ_TLB_TX_MISC_CONFIGr(&acc_cpy, &tx_misc));
   1141                     *tx_polarity |= BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_TX_PMD_DP_INVERTf_GET(tx_misc) << lane_index;
   1142                     PHYMOD_IF_ERR_RETURN(
   1143                         BCMI_QUADRA28_READ_TLB_RX_MISC_CONFIGr(&acc_cpy, &rx_misc));
   1144                     *rx_polarity |= BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_RX_PMD_DP_INVERTf_GET(rx_misc) << lane_index; 
   1145                 }
   1146             }
   1147         }
   1148     } else {
   1149         if (datapath == phymodDatapathUll) {
   1150             PHYMOD_IF_ERR_RETURN
   1151               (BCMI_QUADRA28_READ_TX_CTRL_0r(&acc_cpy, &tx_ctrl0r_config));
   1152             *tx_polarity = BCMI_QUADRA28_TX_CTRL_0r_LL_POLARITY_FLIPf_GET(tx_ctrl0r_config);
   1153         } else {
   1154             PHYMOD_IF_ERR_RETURN(
   1155                BCMI_QUADRA28_READ_TLB_TX_MISC_CONFIGr(&acc_cpy, &tx_misc));
   1156             *tx_polarity = BCMI_QUADRA28_TLB_TX_MISC_CONFIGr_TX_PMD_DP_INVERTf_GET(tx_misc);
   1157             PHYMOD_IF_ERR_RETURN(
   1158                BCMI_QUADRA28_READ_TLB_RX_MISC_CONFIGr(&acc_cpy, &rx_misc));
   1159             *rx_polarity = BCMI_QUADRA28_TLB_RX_MISC_CONFIGr_RX_PMD_DP_INVERTf_GET(rx_misc); 
   1160         }
   1161 
   1162     }
   1163     
   1164     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1165     return PHYMOD_E_NONE;
   1166 }
   1167 
   1168 /**  PMD lock get 
   1169  *    
   1170  *    @param pa                 Pointer to phymod access structure
   1171  *    @param rx_seq_done        RX sew done status
   1172  *
   1173  *    @return PHYMOD_E_NONE     successful function execution 
   1174  */
   1175 int quadra28_pmd_lock_get(const phymod_phy_access_t *phy, uint32_t *rx_seq_done) 
   1176 {
   1177     uint8_t rx_pmd_lock = 0;
   1178     int lane_map = 0;
   1179     int pkg_side = 0;
   1180     int num_lanes = QUADRA28_MAX_LANE;
   1181     int lane_index = 0;
   1182     phymod_access_t acc_cpy;
   1183     int pmd_mode = 0;
   1184     uint32_t speed = 0;
   1185     MDIO_BROADCAST_CONTROLr_t mdio_broadcast_ctrl;
   1186     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
   1187  
   1188     /* Initializing with invalid value*/
   1189     if(NULL != rx_seq_done) {
   1190         *rx_seq_done = 0xFFFF;
   1191     } else {
   1192         return PHYMOD_E_PARAM;
   1193     }
   1194     PHYMOD_MEMSET(&mdio_broadcast_ctrl, 0 , sizeof(MDIO_BROADCAST_CONTROLr_t));	
   1195     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));
   1196     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1197     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1198     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1199 
   1200     /* Get the lane map from phymod access */
   1201     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1202     QUADRA28_GET_LOC(phy, pkg_side);
   1203     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1204  
   1205     if (pmd_mode == Q28_SINGLE_PMD) {
   1206         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1207             if (((lane_map >> lane_index) & 1) == 0x1) {
   1208                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1209                 PHYMOD_IF_ERR_RETURN(
   1210                     merlin_quadra28_pmd_lock_status(&acc_cpy, &rx_pmd_lock));
   1211                 *rx_seq_done &= rx_pmd_lock;
   1212             }
   1213         }
   1214     } else {
   1215         if(NULL != rx_seq_done) {
   1216             PHYMOD_IF_ERR_RETURN(
   1217                 merlin_quadra28_pmd_lock_status(&acc_cpy, &rx_pmd_lock));
   1218             *rx_seq_done &= rx_pmd_lock;
   1219         }
   1220     }
   1221     /* restore Q28_INTF_LINE side */
   1222     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1223     return PHYMOD_E_NONE;
   1224 }
   1225 
   1226 /**   Set line side interface  
   1227  *    This function is used to set the operating mode of the PHY
   1228  *
   1229  *    @param reg_val            Pointer to apps mode reg 
   1230  *    @param intf               Interface specified by user 
   1231  * 
   1232  *    @return PHYMOD_E_NONE     successful function execution 
   1233  */
   1234 int _quadra28_config_line_interface(const phymod_access_t *pa, uint32_t* reg_val, phymod_interface_t intf, uint32_t speed)
   1235 {
   1236     int return_val = PHYMOD_E_NONE;
   1237     uint32_t mask = 0, enable = 0;
   1238     if (speed == Q28_SPEED_10G || speed == Q28_SPEED_HG11) {
   1239         if ((intf != phymodInterfaceSR) && (intf != phymodInterfaceCR) &&
   1240                 (intf != phymodInterfaceLR) && (intf != phymodInterfaceKR) &&
   1241                 (intf != phymodInterfaceXFI) &&(intf != phymodInterfaceZR) &&
   1242                 (intf != phymodInterfaceLRM)) {
   1243             PHYMOD_DIAG_OUT(("Interface %d not supported, so setting default interface \n", intf));
   1244             intf = phymodInterfaceSR;
   1245         }
   1246     } else if(speed == Q28_SPEED_40G || speed == Q28_SPEED_42G) {
   1247         if ((intf != phymodInterfaceSR4) && (intf != phymodInterfaceCR4) &&
   1248                 (intf != phymodInterfaceLR4) && (intf != phymodInterfaceKR4) &&
   1249                 (intf != phymodInterfaceXLAUI)) {
   1250             PHYMOD_DIAG_OUT(("Interface %d not supported, so setting default interface \n", intf));
   1251             intf = phymodInterfaceSR4;
   1252         }
   1253     } else if (speed == Q28_SPEED_1G) {
   1254         if ((intf != phymodInterface1000X) && (intf != phymodInterfaceKX)
   1255                 && (intf != phymodInterfaceSR)) {
   1256             PHYMOD_DIAG_OUT(("Interface %d not supported, so setting default interface \n", intf));
   1257             intf = phymodInterface1000X;
   1258         }
   1259     }
   1260     /* Need this, If Configured as ZR previously*/
   1261     if ((*reg_val & 0x5A00 ) == 0x5A00) {
   1262         *reg_val |= (Q28_BIT(15));
   1263     }
   1264     switch (intf)
   1265     {
   1266         case phymodInterfaceSR:  
   1267         case phymodInterfaceSR4:
   1268             mask = ~(Q28_BIT(4) | Q28_BIT(5)| Q28_BIT(8) | 
   1269                     Q28_BIT(14) | Q28_BIT(9) | Q28_BIT(12));
   1270             *reg_val &= mask;
   1271             break;
   1272         case phymodInterfaceKX:
   1273             mask = ~ (Q28_BIT(4) | Q28_BIT(5)|Q28_BIT(8) | 
   1274                     Q28_BIT(14) | Q28_BIT(9) | Q28_BIT(15) | 
   1275                     Q28_BIT(11));
   1276             *reg_val &= mask;
   1277              PHYMOD_IF_ERR_RETURN(
   1278                      _quadra28_phy_retimer_enable_get(pa, &enable));
   1279              /* Setting both line and sys*/
   1280              if (enable) {
   1281                 *reg_val |= 0x500;
   1282              } else {
   1283                  /* Chip limitation: AN Will not work properly when its is enabled on both line and 
   1284                   * system side in repeater mode*/
   1285                 *reg_val |= 0x100;
   1286              }
   1287             break;
   1288         case phymodInterfaceKR:
   1289         case phymodInterfaceKR4:
   1290             mask = ~(Q28_BIT(4) | Q28_BIT(5)|Q28_BIT(8) | 
   1291                     Q28_BIT(14) | Q28_BIT(9)| Q28_BIT(12));
   1292             *reg_val &= mask;
   1293             *reg_val |= 0x100;            
   1294             break;
   1295         case phymodInterfaceCR:
   1296         case phymodInterfaceCX:
   1297         case phymodInterfaceCR4:
   1298             mask = ~(Q28_BIT(4) | Q28_BIT(5)|Q28_BIT(8) | 
   1299                     Q28_BIT(14) | Q28_BIT(9)| Q28_BIT(12));
   1300             *reg_val &= mask;
   1301             *reg_val|= 0x200;
   1302             break;
   1303        
   1304         case phymodInterfaceLR:       
   1305         case phymodInterfaceLR4:
   1306             mask = ~(Q28_BIT(4) | Q28_BIT(5) | Q28_BIT(8) 
   1307                     | Q28_BIT(14) | Q28_BIT(9)| Q28_BIT(12));
   1308             *reg_val &= mask;
   1309             *reg_val |= 0x4000;
   1310             break;
   1311         case phymodInterface1000X:
   1312             mask = 0xF;
   1313             *reg_val &= mask;
   1314             break;
   1315         case phymodInterfaceXLAUI:
   1316         case phymodInterfaceXFI:
   1317             mask = ~(Q28_BIT(4) | Q28_BIT(5) | Q28_BIT(8) | 
   1318                     Q28_BIT(14) | Q28_BIT(9)| Q28_BIT(12));
   1319             *reg_val &= mask;
   1320             *reg_val |= 0x4200;
   1321             break;
   1322         case phymodInterfaceZR:
   1323             mask = ~(Q28_BIT(4) | Q28_BIT(5) | Q28_BIT(8) | 
   1324                     Q28_BIT(14) | Q28_BIT(9) | Q28_BIT(15));
   1325             *reg_val &= mask;
   1326             *reg_val |= 0x5A00;
   1327             break;
   1328         case phymodInterfaceLRM:
   1329             *reg_val &= 0xF;
   1330             *reg_val |= 0xC830;
   1331             break;
   1332 
   1333         default:
   1334             return_val = PHYMOD_E_FAIL;
   1335             break;
   1336     } 
   1337     return return_val;
   1338 }
   1339 
   1340 /**   Set sys side interface  
   1341  *    This function is used to set the operating mode of the PHY
   1342  *
   1343  *    @param reg_val            Pointer to apps mode reg 
   1344  *    @param intf               Interface specified by user 
   1345  * 
   1346  *    @return PHYMOD_E_NONE     successful function execution 
   1347  */
   1348 int _quadra28_config_sys_interface(const phymod_access_t *pa, uint32_t* reg_val, phymod_interface_t intf)
   1349 {
   1350     uint32_t mask = 0, enable = 0;
   1351     /* configure the System side port mode - interface type */
   1352     switch (intf)
   1353     {
   1354         case phymodInterfaceXLAUI:
   1355         case phymodInterfaceXFI:
   1356             mask = ~(Q28_BIT(11) | Q28_BIT(15) | Q28_BIT(10));
   1357             *reg_val &= mask;
   1358             *reg_val |= 0x8800;
   1359             break;
   1360         case phymodInterface1000X:
   1361             mask = ~(Q28_BIT(11) | Q28_BIT(15) | Q28_BIT(10));
   1362             *reg_val &= mask;
   1363             break;
   1364         case phymodInterfaceKX:
   1365             mask = ~(Q28_BIT(11) | Q28_BIT(15) | Q28_BIT(10));
   1366             *reg_val &= mask;
   1367             PHYMOD_IF_ERR_RETURN(
   1368                      _quadra28_phy_retimer_enable_get(pa, &enable));
   1369              /* Setting both line and sys*/
   1370             if (enable) {
   1371                 *reg_val |= 0x500;
   1372             } else {
   1373                 /* Chip limitation: AN Will not work properly when its is enabled on both line and 
   1374                  * system side in repeater mode*/
   1375                 *reg_val |= 0x100;
   1376             }
   1377             break;
   1378         case phymodInterfaceCR4:
   1379         case phymodInterfaceCX4:
   1380         case phymodInterfaceCR:
   1381             mask = ~(Q28_BIT(11) | Q28_BIT(15) | Q28_BIT(10));
   1382             *reg_val &= mask;
   1383             *reg_val |= 0x800;
   1384             break;
   1385         case phymodInterfaceKR4:
   1386         case phymodInterfaceKR:
   1387             mask = ~(Q28_BIT(11) | Q28_BIT(15) | Q28_BIT(10));
   1388             *reg_val &= mask;
   1389             *reg_val |= 0x400;
   1390 
   1391             break;
   1392         default:
   1393             return PHYMOD_E_FAIL;            
   1394     } 
   1395     return PHYMOD_E_NONE;
   1396 }
   1397 
   1398 /**   Set port speed  
   1399  *    This function is used to set the operating mode of the PHY
   1400  *
   1401  *    @param reg_val            Pointer to apps mode reg 
   1402  *    @param speed              Interface specified by user 
   1403  *    @param mode_type          port mode (single vs multiple)
   1404  * 
   1405  *    @return PHYMOD_E_NONE     successful function execution 
   1406  */
   1407 int _quadra28_config_port_speed(uint32_t speed, uint32_t* reg_val, uint16_t* mode_type)
   1408 {
   1409     int return_val = PHYMOD_E_NONE; 
   1410     *reg_val &= ~(0xF);
   1411     *mode_type = 0;
   1412     switch (speed)
   1413     {
   1414         case SPEED_1G_OS8P25:
   1415             *reg_val |= 0x1;
   1416             break;
   1417 
   1418         case Q28_SPEED_10G:
   1419             *reg_val |= 0x2;
   1420             break;
   1421 
   1422         case Q28_SPEED_1G:
   1423             *reg_val |= 0x1;
   1424             break;
   1425 
   1426         case Q28_SPEED_11P5G:
   1427             *reg_val |= 0x8;
   1428             break;
   1429 
   1430         case Q28_SPEED_20G: /* KR2 2 * 10.3125G */
   1431             *reg_val |= 0xC;
   1432             break;
   1433 
   1434         case Q28_SPEED_40G:
   1435             *reg_val |= 0x4;
   1436             *mode_type = 1;
   1437             break;
   1438 
   1439         case Q28_SPEED_42G:
   1440             *reg_val |= 0x7;
   1441             *mode_type = 1;
   1442             break;
   1443         case Q28_SPEED_HG11:
   1444             *reg_val |= 0x5;
   1445             break;
   1446            
   1447         default:
   1448             return_val = PHYMOD_E_PARAM;
   1449             break;
   1450 
   1451     }/* End: Switch for speed */
   1452     return return_val;
   1453 }
   1454 
   1455 int quadra28_tx_lane_control_set(const phymod_phy_access_t *phy,
   1456                               phymod_phy_tx_lane_control_t tx_control)
   1457 {
   1458     int lane_map = 0;
   1459     int pkg_side = 0;
   1460     int num_lanes = QUADRA28_MAX_LANE;
   1461     int lane_index = 0;
   1462     uint16_t err_code = 0;
   1463     PMD_TRANSMIT_DISABLEr_t tx_disable;
   1464 #ifdef SA_PLP_SUPPORT
   1465 	BCMI_QUADRA28_MISC_CONTROL1r_t misc_ctrl;
   1466 #endif
   1467     BCMI_QUADRA28_SIDE_SELECTIONr_t side_sel_reg_val;
   1468     int pmd_mode = 0;
   1469     uint32_t speed = 0;
   1470     phymod_access_t acc_cpy;
   1471     phymod_access_t *pa=&acc_cpy; 
   1472     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(BCMI_QUADRA28_SIDE_SELECTIONr_t));	
   1473     PHYMOD_MEMSET(&tx_disable, 0 , sizeof(PMD_TRANSMIT_DISABLEr_t));
   1474 #ifdef SA_PLP_SUPPORT
   1475 	PHYMOD_MEMSET(&misc_ctrl, 0 , sizeof(BCMI_QUADRA28_MISC_CONTROL1r_t));
   1476 #endif
   1477     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1478     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1479     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1480 
   1481     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1482 
   1483     /* Get the lane map from phymod access */
   1484     QUADRA28_GET_LOC(phy, pkg_side);   
   1485     QUADRA28_SELECT_SIDE(&acc_cpy, side_sel_reg_val, pkg_side);
   1486 
   1487     if (pmd_mode == Q28_SINGLE_PMD) {
   1488         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   1489             if (((lane_map >> lane_index) & 1) == 0x1) {
   1490                 PHYMOD_IF_ERR_RETURN(
   1491                    quadra28_channel_select(&acc_cpy,
   1492                       ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   1493                 switch(tx_control) {
   1494                     case phymodTxSquelchOn:
   1495                        PHYMOD_IF_ERR_RETURN(
   1496                            READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   1497                        PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET
   1498                                                         (tx_disable, 1);
   1499                        PHYMOD_IF_ERR_RETURN(
   1500                            WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_disable));
   1501 #ifdef SA_PLP_SUPPORT
   1502                        PHYMOD_IF_ERR_RETURN(
   1503                            BCMI_QUADRA28_READ_MISC_CONTROL1r(&acc_cpy,&misc_ctrl));
   1504                        BCMI_QUADRA28_MISC_CONTROL1r_PMD_TX_DISABLE_PIN_DISf_SET(misc_ctrl,0);
   1505                        PHYMOD_IF_ERR_RETURN(
   1506                            BCMI_QUADRA28_WRITE_MISC_CONTROL1r(&acc_cpy,misc_ctrl));
   1507 #endif
   1508                        break;
   1509                     case phymodTxSquelchOff:
   1510                        PHYMOD_IF_ERR_RETURN(
   1511                            READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   1512                        PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET
   1513                                                         (tx_disable, 0);
   1514                        PHYMOD_IF_ERR_RETURN(
   1515                            WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_disable));
   1516 #ifdef SA_PLP_SUPPORT
   1517                        PHYMOD_IF_ERR_RETURN(
   1518                            BCMI_QUADRA28_READ_MISC_CONTROL1r(&acc_cpy,&misc_ctrl));
   1519                        BCMI_QUADRA28_MISC_CONTROL1r_PMD_TX_DISABLE_PIN_DISf_SET(misc_ctrl,1);
   1520                        PHYMOD_IF_ERR_RETURN(
   1521                            BCMI_QUADRA28_WRITE_MISC_CONTROL1r(&acc_cpy,misc_ctrl));
   1522 #endif
   1523                        break;
   1524                     case phymodTxReset:
   1525                        err_code = wr_ln_dp_s_rstb(0);
   1526                        if (err_code != ERR_CODE_NONE){
   1527                            return err_code;
   1528                        }
   1529                        break;
   1530                     default:
   1531                        return PHYMOD_E_UNAVAIL;
   1532                 }
   1533                 if (Q28_ALL_LANE == lane_map) {
   1534                     break;
   1535                 }
   1536             }
   1537         }
   1538     } else {
   1539         switch(tx_control) {
   1540             case phymodTxSquelchOn:
   1541                 PHYMOD_IF_ERR_RETURN(
   1542                     READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   1543                 PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET
   1544                                                  (tx_disable, 1);
   1545                 PHYMOD_IF_ERR_RETURN(
   1546                     WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_disable));
   1547 #ifdef SA_PLP_SUPPORT
   1548                 PHYMOD_IF_ERR_RETURN(
   1549                     BCMI_QUADRA28_READ_MISC_CONTROL1r(&acc_cpy,&misc_ctrl));
   1550                 BCMI_QUADRA28_MISC_CONTROL1r_PMD_TX_DISABLE_PIN_DISf_SET(misc_ctrl,0);
   1551                 PHYMOD_IF_ERR_RETURN(
   1552                     BCMI_QUADRA28_WRITE_MISC_CONTROL1r(&acc_cpy,misc_ctrl));
   1553 #endif
   1554                break;
   1555             case phymodTxSquelchOff:
   1556                 PHYMOD_IF_ERR_RETURN(
   1557                     READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   1558                 PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET
   1559                                                  (tx_disable, 0);
   1560                 PHYMOD_IF_ERR_RETURN(
   1561                     WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_disable));
   1562 #ifdef SA_PLP_SUPPORT
   1563                 PHYMOD_IF_ERR_RETURN(
   1564                     BCMI_QUADRA28_READ_MISC_CONTROL1r(&acc_cpy,&misc_ctrl));
   1565                BCMI_QUADRA28_MISC_CONTROL1r_PMD_TX_DISABLE_PIN_DISf_SET(misc_ctrl,1);
   1566                PHYMOD_IF_ERR_RETURN(
   1567                     BCMI_QUADRA28_WRITE_MISC_CONTROL1r(&acc_cpy,misc_ctrl));
   1568 #endif
   1569                 break;
   1570             case phymodTxReset:
   1571                 err_code = wr_ln_dp_s_rstb(0);
   1572                 if (err_code != ERR_CODE_NONE){
   1573                     return err_code;
   1574                 }
   1575                 break;
   1576             default:
   1577                return PHYMOD_E_UNAVAIL;
   1578         }
   1579     }
   1580     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy, side_sel_reg_val, Q28_INTF_LINE);
   1581     return PHYMOD_E_NONE;    
   1582 }
   1583 
   1584 int quadra28_tx_squelch_get(const phymod_phy_access_t *phy,
   1585                                int *tx_squelch)
   1586 {
   1587     int lane_map = 0;
   1588     int pkg_side = 0;
   1589     int num_lanes = QUADRA28_MAX_LANE;
   1590     int lane_index = 0;
   1591     PMD_TRANSMIT_DISABLEr_t tx_disable;
   1592     SIDE_SELECTIONr_t side_sel_reg_val;
   1593     int pmd_mode = 0;
   1594     uint32_t speed = 0;
   1595     phymod_access_t acc_cpy;
   1596 
   1597     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1598     PHYMOD_MEMSET(&tx_disable, 0 , sizeof(PMD_TRANSMIT_DISABLEr_t));	
   1599     PHYMOD_MEMCPY(&acc_cpy,&phy->access, sizeof(phymod_access_t));
   1600     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1601     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1602 
   1603     /* Get the lane map from phymod access */
   1604     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1605     QUADRA28_GET_LOC(phy, pkg_side);   
   1606     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1607 
   1608     if (pmd_mode == Q28_SINGLE_PMD) {
   1609         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   1610             if (((lane_map >> lane_index) & 1) == 0x1) {
   1611                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1612                 PHYMOD_IF_ERR_RETURN(
   1613                     READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   1614                 *tx_squelch = 
   1615                     PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_GET(tx_disable);
   1616                 break;
   1617             }
   1618         }
   1619     } else {
   1620         PHYMOD_IF_ERR_RETURN(
   1621             READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   1622         *tx_squelch = 
   1623             PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_GET(tx_disable);
   1624     }
   1625     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1626 
   1627     return PHYMOD_E_NONE;
   1628 }
   1629 
   1630 int quadra28_rx_lane_control_set(const phymod_phy_access_t *phy,
   1631                               phymod_phy_rx_lane_control_t rx_control)
   1632 {
   1633     int lane_map = 0;
   1634     int pkg_side = 0;
   1635     int num_lanes = QUADRA28_MAX_LANE;
   1636     int lane_index = 0;
   1637     uint16_t err_code = 0;
   1638     SIDE_SELECTIONr_t side_sel_reg_val;
   1639     SIGDET_CTRL_1r_t sigdet_ctrl1_reg;
   1640     int pmd_mode = 0;
   1641     uint32_t speed = 0;
   1642     phymod_access_t acc_cpy;
   1643     phymod_access_t *pa=&acc_cpy;   
   1644     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1645     PHYMOD_MEMSET(&sigdet_ctrl1_reg, 0 , sizeof(SIGDET_CTRL_1r_t));
   1646     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1647     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1648     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1649 
   1650     /* Get the lane map from phymod access */
   1651     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1652     QUADRA28_GET_LOC(phy, pkg_side);   
   1653     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   1654 
   1655     if (pmd_mode == Q28_SINGLE_PMD) {
   1656         switch(rx_control) {
   1657             case phymodRxSquelchOff:
   1658             case phymodRxSquelchOn: 
   1659                 for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1660                     if (((lane_map >> lane_index) & 1) == 0x1) {
   1661                         PHYMOD_IF_ERR_RETURN(
   1662                             quadra28_channel_select(&acc_cpy,
   1663                             ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   1664                         PHYMOD_IF_ERR_RETURN(                
   1665                             READ_SIGDET_CTRL_1r(&acc_cpy, &sigdet_ctrl1_reg));
   1666                         SIGDET_CTRL_1r_SIGNAL_DETECT_FRC_VALf_SET(sigdet_ctrl1_reg, 
   1667                                    ((rx_control == phymodRxSquelchOn) ? 0 : 1));
   1668                         SIGDET_CTRL_1r_SIGNAL_DETECT_FRCf_SET(sigdet_ctrl1_reg, 1);
   1669                         PHYMOD_IF_ERR_RETURN(  
   1670                              WRITE_SIGDET_CTRL_1r(&acc_cpy, sigdet_ctrl1_reg));
   1671                         /* If there is no RX squelch change the force to 0
   1672                          * i.e. get the RX status from Analog*/
   1673                         if (rx_control == phymodRxSquelchOff) {
   1674                             SIGDET_CTRL_1r_SIGNAL_DETECT_FRCf_SET(sigdet_ctrl1_reg, 0);
   1675                             PHYMOD_IF_ERR_RETURN(  
   1676                              WRITE_SIGDET_CTRL_1r(&acc_cpy, sigdet_ctrl1_reg));
   1677 
   1678                         }
   1679                         if (Q28_ALL_LANE == lane_map) {
   1680                              break;
   1681                         }
   1682                     }
   1683                 }
   1684             break;
   1685             case phymodRxReset:
   1686                 err_code = wr_ln_dp_s_rstb(0);
   1687                 if (err_code != ERR_CODE_NONE){
   1688                     return err_code;
   1689                 }
   1690             break;
   1691             default:
   1692                 return PHYMOD_E_UNAVAIL;
   1693         }
   1694     } else {
   1695         switch(rx_control) {
   1696             case phymodRxSquelchOn: 
   1697             case phymodRxSquelchOff:
   1698                 PHYMOD_IF_ERR_RETURN(                
   1699                     READ_SIGDET_CTRL_1r(&acc_cpy, &sigdet_ctrl1_reg));
   1700                 SIGDET_CTRL_1r_SIGNAL_DETECT_FRC_VALf_SET(sigdet_ctrl1_reg, 
   1701                         ((rx_control == phymodRxSquelchOn) ? 0 : 1));
   1702                 SIGDET_CTRL_1r_SIGNAL_DETECT_FRCf_SET(sigdet_ctrl1_reg, 1);
   1703                 PHYMOD_IF_ERR_RETURN(  
   1704                     WRITE_SIGDET_CTRL_1r(&acc_cpy, sigdet_ctrl1_reg));
   1705                 /* If there is no RX squelch change the force to 0
   1706                  * i.e. get the RX status from Analog*/
   1707                  if (rx_control == phymodRxSquelchOff) {
   1708                      SIGDET_CTRL_1r_SIGNAL_DETECT_FRCf_SET(sigdet_ctrl1_reg, 0);
   1709                      PHYMOD_IF_ERR_RETURN(  
   1710                           WRITE_SIGDET_CTRL_1r(&acc_cpy, sigdet_ctrl1_reg));
   1711                   }
   1712 
   1713             break;
   1714             case phymodRxReset:
   1715                 err_code = wr_ln_dp_s_rstb(0);
   1716                 if (err_code != ERR_CODE_NONE){
   1717                     return err_code;
   1718                 }
   1719             break;
   1720             default:
   1721                 return PHYMOD_E_UNAVAIL;
   1722         }
   1723     }
   1724     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);         
   1725     return PHYMOD_E_NONE;
   1726 }
   1727 
   1728 int quadra28_rx_squelch_get(const phymod_phy_access_t *phy, int *rx_squelch)
   1729 {
   1730     int lane_map = 0;
   1731     int pkg_side = 0;
   1732     int num_lanes = QUADRA28_MAX_LANE;
   1733     int lane_index = 0;
   1734     SIDE_SELECTIONr_t side_sel_reg_val;
   1735     SIGDET_CTRL_1r_t sigdet_ctrl1_reg;
   1736     int pmd_mode = 0;
   1737     uint32_t speed = 0;
   1738     phymod_access_t acc_cpy;
   1739 
   1740     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1741     PHYMOD_MEMSET(&sigdet_ctrl1_reg, 0 , sizeof(SIGDET_CTRL_1r_t));
   1742     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1743     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1744     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1745 
   1746     /* Get the lane map from phymod access */
   1747     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1748     QUADRA28_GET_LOC(phy, pkg_side);   
   1749     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1750 
   1751     if (pmd_mode == Q28_SINGLE_PMD) {
   1752         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   1753             if (((lane_map >> lane_index) & 1) == 0x1) {
   1754                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1755                 PHYMOD_IF_ERR_RETURN(                
   1756                      READ_SIGDET_CTRL_1r(&acc_cpy, &sigdet_ctrl1_reg));
   1757                 *rx_squelch = SIGDET_CTRL_1r_SIGNAL_DETECT_FRCf_GET(sigdet_ctrl1_reg) ?
   1758                                1 : 0;
   1759                 break;
   1760             }
   1761         }
   1762     } else {
   1763         PHYMOD_IF_ERR_RETURN(                
   1764              READ_SIGDET_CTRL_1r(&acc_cpy, &sigdet_ctrl1_reg));
   1765         *rx_squelch = SIGDET_CTRL_1r_SIGNAL_DETECT_FRCf_GET(sigdet_ctrl1_reg) ?
   1766                        1 : 0;
   1767     }
   1768     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1769 
   1770     return PHYMOD_E_NONE;
   1771 }
   1772 
   1773 int quadra28_display_eye_scan(const phymod_phy_access_t *phy)
   1774 {
   1775     int lane_map = 0;
   1776     int pkg_side = 0;
   1777     int num_lanes = QUADRA28_MAX_LANE;
   1778     int lane_index = 0;
   1779     SIDE_SELECTIONr_t side_sel_reg_val;
   1780     int pmd_mode = 0;
   1781     uint32_t speed = 0;
   1782     phymod_access_t acc_cpy;
   1783 
   1784     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1785     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1786     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1787     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1788     /* Get the lane map from phymod access */
   1789     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1790     QUADRA28_GET_LOC(phy, pkg_side);   
   1791     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1792     if (pmd_mode == Q28_SINGLE_PMD) {
   1793         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1794             if (((lane_map >> lane_index) & 1) == 0x1) {
   1795                 PHYMOD_DIAG_OUT((" eyescan for lane = %d lanemap:%x\n",     lane_index, lane_map));
   1796 
   1797                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1798                 PHYMOD_IF_ERR_RETURN
   1799                     (merlin_quadra28_display_lane_state_hdr(&acc_cpy));
   1800                 PHYMOD_IF_ERR_RETURN
   1801                     (merlin_quadra28_display_lane_state(&acc_cpy)); 
   1802                 PHYMOD_IF_ERR_RETURN
   1803                         (merlin_quadra28_display_eye_scan(&acc_cpy));
   1804             }
   1805         }
   1806     } else {
   1807         PHYMOD_IF_ERR_RETURN
   1808             (merlin_quadra28_display_lane_state_hdr(&acc_cpy));
   1809         PHYMOD_IF_ERR_RETURN
   1810             (merlin_quadra28_display_lane_state(&acc_cpy)); 
   1811         PHYMOD_IF_ERR_RETURN
   1812                 (merlin_quadra28_display_eye_scan(&acc_cpy));
   1813     }
   1814     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1815     return PHYMOD_E_NONE;
   1816 }
   1817 
   1818 int quadra28_ber_proj (const phymod_phy_access_t *phy, const phymod_phy_eyescan_options_t* eyescan_options)
   1819 {
   1820     int lane_map = 0;
   1821     int pkg_side = 0;
   1822     int num_lanes = QUADRA28_MAX_LANE;
   1823     int lane_index = 0;
   1824     SIDE_SELECTIONr_t side_sel_reg_val;
   1825     int pmd_mode = 0;
   1826     uint32_t speed = 0;
   1827 #ifdef SERDES_API_FLOATING_POINT
   1828     USR_DOUBLE speedD;
   1829     BCMI_QUADRA28_PRBS_CHK_CONFIGr_t chk_config;
   1830 #endif
   1831     phymod_access_t acc_cpy;
   1832 
   1833     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1834 #ifdef SERDES_API_FLOATING_POINT
   1835     PHYMOD_MEMSET(&chk_config, 0 , sizeof(BCMI_QUADRA28_PRBS_CHK_CONFIGr_t));	
   1836 #endif    
   1837     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1838     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1839     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1840     /* Get the lane map from phymod access */
   1841     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1842     QUADRA28_GET_LOC(phy, pkg_side);   
   1843     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1844     if (pmd_mode == Q28_SINGLE_PMD) {
   1845         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1846             if (((lane_map >> lane_index) & 1) == 0x1) {
   1847                 PHYMOD_DIAG_OUT((" BER proj for lane = %d lanemap:%x\n",     lane_index, lane_map));
   1848 
   1849                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1850 #ifdef SERDES_API_FLOATING_POINT
   1851                 if ((speed == Q28_SPEED_40G) || (speed == Q28_SPEED_10G) 
   1852                       || (speed == Q28_SPEED_20G) || (speed == Q28_SPEED_1G)) {
   1853                     speedD = 10312 * 1000.0 * 1000.0;
   1854                 } else if((speed == Q28_SPEED_42G) || (speed == Q28_SPEED_HG11)) {
   1855                     speedD = 10937 * 1000.0 * 1000.0;
   1856                 } else if(speed == Q28_SPEED_11P5G) {
   1857                     speedD = 11500 * 1000.0 * 1000.0;
   1858                 } else {
   1859                     speedD = 10312 * 1000.0 * 1000.0;
   1860                 }
   1861 
   1862                 PHYMOD_IF_ERR_RETURN
   1863                     (merlin_quadra28_eye_margin_proj((&acc_cpy), speedD, eyescan_options->ber_proj_scan_mode,
   1864                                eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt));
   1865                 PHYMOD_IF_ERR_RETURN(
   1866                      BCMI_QUADRA28_READ_PRBS_CHK_CONFIGr(&acc_cpy, &chk_config));
   1867                 BCMI_QUADRA28_PRBS_CHK_CONFIGr_TRNSUM_ERROR_COUNT_ENf_SET(chk_config, 0);
   1868                 PHYMOD_IF_ERR_RETURN(
   1869                      BCMI_QUADRA28_WRITE_PRBS_CHK_CONFIGr(&acc_cpy, chk_config));
   1870 #else 
   1871                 PHYMOD_DIAG_OUT(("BER PROJ needs SERDES_API_FLOATING_POINT define to operate\n"));
   1872                 return PHYMOD_E_RESOURCE;
   1873 #endif
   1874 
   1875             }
   1876         }
   1877     } else {
   1878 #ifdef SERDES_API_FLOATING_POINT
   1879         if ((speed == Q28_SPEED_40G) || (speed == Q28_SPEED_10G) 
   1880                  || (speed == Q28_SPEED_20G) || (speed == Q28_SPEED_1G)) {
   1881             speedD = 10312 * 1000.0 * 1000.0;
   1882         } else if((speed == Q28_SPEED_42G) || (speed == Q28_SPEED_HG11)) {
   1883             speedD = 10937 * 1000.0 * 1000.0;
   1884         } else if(speed == Q28_SPEED_11P5G) {
   1885             speedD = 11500 * 1000.0 * 1000.0;
   1886         } else {
   1887             speedD = 10312 * 1000.0 * 1000.0;
   1888         }
   1889 
   1890         PHYMOD_IF_ERR_RETURN
   1891             (merlin_quadra28_eye_margin_proj((&acc_cpy), speedD, eyescan_options->ber_proj_scan_mode,
   1892                                eyescan_options->ber_proj_timer_cnt, eyescan_options->ber_proj_err_cnt));
   1893         PHYMOD_IF_ERR_RETURN(
   1894              BCMI_QUADRA28_READ_PRBS_CHK_CONFIGr(&acc_cpy, &chk_config));
   1895         BCMI_QUADRA28_PRBS_CHK_CONFIGr_TRNSUM_ERROR_COUNT_ENf_SET(chk_config, 0);
   1896         PHYMOD_IF_ERR_RETURN(
   1897              BCMI_QUADRA28_WRITE_PRBS_CHK_CONFIGr(&acc_cpy, chk_config));
   1898 #else 
   1899         PHYMOD_DIAG_OUT(("BER PROJ needs SERDES_API_FLOATING_POINT define to operate\n"));
   1900         return PHYMOD_E_RESOURCE;
   1901 #endif
   1902 
   1903     }
   1904     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1905     return PHYMOD_E_NONE;
   1906 }
   1907 
   1908 int _quadra28_phy_status_dump(const phymod_phy_access_t *phy)
   1909 {
   1910     int lane_map = 0;
   1911     int pkg_side = 0;
   1912     int num_lanes = QUADRA28_MAX_LANE;
   1913     int lane_index = 0;
   1914     SIDE_SELECTIONr_t side_sel_reg_val;
   1915     int pmd_mode = 0;
   1916     uint32_t speed = 0;
   1917     phymod_access_t acc_cpy;
   1918     uint8_t trace_mem[768];
   1919 
   1920     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1921     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1922     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1923     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1924 
   1925     /* Get the lane map from phymod access */
   1926     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1927     QUADRA28_GET_LOC(phy, pkg_side);   
   1928     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1929 
   1930     PHYMOD_DIAG_OUT((" ***************************************\n"));
   1931     PHYMOD_DIAG_OUT((" ******* PHY status dump for Q28 PHY ID:0x%x ********\n", acc_cpy.addr));
   1932     PHYMOD_DIAG_OUT((" ***************************************\n"));
   1933     PHYMOD_DIAG_OUT((" ***************************************\n"));
   1934     PHYMOD_DIAG_OUT((" ******* PHY status dump for side:%x ********\n", pkg_side));
   1935     PHYMOD_DIAG_OUT((" ***************************************\n"));
   1936     PHYMOD_IF_ERR_RETURN(merlin_quadra28_display_core_config(&acc_cpy));
   1937     PHYMOD_IF_ERR_RETURN(merlin_quadra28_display_core_state(&acc_cpy));
   1938     
   1939     if (pmd_mode == Q28_SINGLE_PMD) {
   1940         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   1941             if (((lane_map >> lane_index) & 1) == 0x1) {
   1942                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1943                 PHYMOD_IF_ERR_RETURN
   1944                     (merlin_quadra28_display_lane_state_hdr(&acc_cpy));
   1945                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_display_lane_state(&acc_cpy));
   1946                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_display_lane_config(&acc_cpy));
   1947                 if ((lane_index & 1) == 0) {
   1948                     PHYMOD_IF_ERR_RETURN(
   1949                          merlin_quadra28_read_event_log(&acc_cpy, trace_mem, 2));
   1950                 }
   1951             }
   1952         }
   1953     } else {
   1954         PHYMOD_IF_ERR_RETURN
   1955             (merlin_quadra28_display_lane_state_hdr(&acc_cpy));
   1956         PHYMOD_IF_ERR_RETURN(merlin_quadra28_display_lane_state(&acc_cpy));
   1957         PHYMOD_IF_ERR_RETURN(merlin_quadra28_display_lane_config(&acc_cpy));
   1958         PHYMOD_IF_ERR_RETURN(
   1959              merlin_quadra28_read_event_log(&acc_cpy, trace_mem, 2));
   1960 
   1961     }
   1962     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   1963     return PHYMOD_E_NONE;
   1964 }
   1965 
   1966 int _quadra28_phy_diagnostics_get(const phymod_phy_access_t *phy, phymod_phy_diagnostics_t* diag)
   1967 {
   1968     int lane_map = 0;
   1969     int pkg_side = 0;
   1970     int num_lanes = QUADRA28_MAX_LANE;
   1971     int lane_index = 0;
   1972     SIDE_SELECTIONr_t side_sel_reg_val;
   1973     int pmd_mode = 0;
   1974     uint32_t speed = 0;
   1975     phymod_access_t acc_cpy;
   1976     merlin_quadra28_lane_state_st_define state;
   1977 
   1978     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   1979     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   1980     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   1981     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   1982 
   1983     /* Get the lane map from phymod access */
   1984     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   1985     QUADRA28_GET_LOC(phy, pkg_side);   
   1986     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   1987     if (pmd_mode == Q28_SINGLE_PMD) {
   1988         for(lane_index = 0; lane_index < num_lanes; lane_index++) {
   1989             if (((lane_map >> lane_index) & 1) == 0x1) {
   1990                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   1991                 PHYMOD_IF_ERR_RETURN
   1992                     (merlin_quadra28_read_lane_state_define(&acc_cpy, &state));
   1993                 diag->signal_detect = state.sig_det;
   1994                 diag->osr_mode = state.osr_mode.tx_rx;
   1995                 diag->rx_lock = state.rx_lock;
   1996                 diag->tx_ppm = state.tx_ppm;
   1997                 diag->clk90_offset = state.clk90;
   1998                 diag->clkp1_offset = state.clkp1;
   1999                 diag->p1_lvl = state.p1_lvl;
   2000                 diag->dfe1_dcd = state.dfe1_dcd;
   2001                 diag->dfe2_dcd = state.dfe2_dcd;
   2002                 diag->slicer_offset.offset_pe = state.pe;
   2003                 diag->slicer_offset.offset_ze = state.ze;
   2004                 diag->slicer_offset.offset_me = state.me;
   2005                 diag->slicer_offset.offset_po = state.po;
   2006                 diag->slicer_offset.offset_zo = state.zo;
   2007                 diag->slicer_offset.offset_mo = state.mo;
   2008                 diag->eyescan.heye_left = state.heye_left;
   2009                 diag->eyescan.heye_right = state.heye_right;
   2010                 diag->eyescan.veye_upper = state.veye_upper;
   2011                 diag->eyescan.veye_lower = state.veye_lower;
   2012                 diag->link_time = state.link_time;
   2013                 diag->pf_main = state.pf_main;
   2014                 diag->pf_hiz = state.pf_hiz;
   2015                 diag->pf_bst = state.pf_bst;
   2016                 diag->pf_low = 0; /* Not Availble in serdes API*/
   2017                 diag->pf2_ctrl = state.pf2_ctrl;
   2018                 diag->vga = state.vga;
   2019                 diag->dc_offset = state.dc_offset;
   2020                 diag->p1_lvl_ctrl = state.p1_lvl_ctrl;
   2021                 diag->dfe1 = state.dfe1;
   2022                 diag->dfe2 = state.dfe2;
   2023                 diag->dfe3 = state.dfe3;
   2024                 diag->dfe4 = state.dfe4;
   2025                 diag->dfe5 = state.dfe5;
   2026                 diag->dfe6 = state.dfe6;
   2027                 diag->txfir_pre = state.txfir_pre;
   2028                 diag->txfir_main = state.txfir_main;
   2029                 diag->txfir_post1 = state.txfir_post1;
   2030                 diag->txfir_post2 = state.txfir_post2;
   2031                 diag->txfir_post3 = state.txfir_post3;
   2032                 diag->tx_amp_ctrl = 0; /* Not Availble in serdes API*/
   2033                 diag->br_pd_en = state.br_pd_en;
   2034                 break;
   2035             }
   2036         }
   2037     } else {
   2038         PHYMOD_IF_ERR_RETURN
   2039             (merlin_quadra28_read_lane_state_define(&acc_cpy, &state));
   2040         diag->signal_detect = state.sig_det;
   2041         diag->osr_mode = state.osr_mode.tx_rx;
   2042         diag->rx_lock = state.rx_lock;
   2043         diag->tx_ppm = state.tx_ppm;
   2044         diag->clk90_offset = state.clk90;
   2045         diag->clkp1_offset = state.clkp1;
   2046         diag->p1_lvl = state.p1_lvl;
   2047         diag->dfe1_dcd = state.dfe1_dcd;
   2048         diag->dfe2_dcd = state.dfe2_dcd;
   2049         diag->slicer_offset.offset_pe = state.pe;
   2050         diag->slicer_offset.offset_ze = state.ze;
   2051         diag->slicer_offset.offset_me = state.me;
   2052         diag->slicer_offset.offset_po = state.po;
   2053         diag->slicer_offset.offset_zo = state.zo;
   2054         diag->slicer_offset.offset_mo = state.mo;
   2055         diag->eyescan.heye_left = state.heye_left;
   2056         diag->eyescan.heye_right = state.heye_right;
   2057         diag->eyescan.veye_upper = state.veye_upper;
   2058         diag->eyescan.veye_lower = state.veye_lower;
   2059         diag->link_time = state.link_time;
   2060         diag->pf_main = state.pf_main;
   2061         diag->pf_hiz = state.pf_hiz;
   2062         diag->pf_bst = state.pf_bst;
   2063         diag->pf_low = 0; /* Not Availble in serdes API*/
   2064         diag->pf2_ctrl = state.pf2_ctrl;
   2065         diag->vga = state.vga;
   2066         diag->dc_offset = state.dc_offset;
   2067         diag->p1_lvl_ctrl = state.p1_lvl_ctrl;
   2068         diag->dfe1 = state.dfe1;
   2069         diag->dfe2 = state.dfe2;
   2070         diag->dfe3 = state.dfe3;
   2071         diag->dfe4 = state.dfe4;
   2072         diag->dfe5 = state.dfe5;
   2073         diag->dfe6 = state.dfe6;
   2074         diag->txfir_pre = state.txfir_pre;
   2075         diag->txfir_main = state.txfir_main;
   2076         diag->txfir_post1 = state.txfir_post1;
   2077         diag->txfir_post2 = state.txfir_post2;
   2078         diag->txfir_post3 = state.txfir_post3;
   2079         diag->tx_amp_ctrl = 0; /* Not Availble in serdes API*/
   2080         diag->br_pd_en = state.br_pd_en;
   2081     }
   2082     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2083     return PHYMOD_E_NONE;
   2084 }
   2085 
   2086 int quadra28_soft_reset(const phymod_access_t* pa, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
   2087 {
   2088     int pkg_side = 0;
   2089     uint32_t acc_flags = 0; 
   2090     SIDE_SELECTIONr_t side_sel_reg_val;
   2091     uint32_t speed = 0;
   2092     phymod_access_t acc_cpy;
   2093     PMD_CONTROLr_t  pmd_ctrl;
   2094 
   2095     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2096     PHYMOD_MEMSET(&pmd_ctrl, 0 , sizeof(PMD_CONTROLr_t));	
   2097     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   2098     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2099 
   2100     /* Get the lane map from phymod access */
   2101     acc_flags = PHYMOD_ACC_FLAGS(&acc_cpy);
   2102     QUADRA28_GET_IF_SIDE(acc_flags, pkg_side);   
   2103     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   2104     if (reset_mode == phymodResetModeSoft) {
   2105         PHYMOD_IF_ERR_RETURN(
   2106             BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2107         BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1);
   2108         PHYMOD_IF_ERR_RETURN(
   2109             BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
   2110     } else {
   2111         return PHYMOD_E_UNAVAIL;
   2112     }
   2113 
   2114     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2115     return PHYMOD_E_NONE;
   2116 }
   2117 
   2118 int _quadra28_phy_reset_set(const phymod_phy_access_t *phy,  const phymod_phy_reset_t* reset)
   2119 {
   2120     int lane_map = 0;
   2121     int pkg_side = 0;
   2122     int num_lanes = QUADRA28_MAX_LANE;
   2123     int lane_index = 0;
   2124     SIDE_SELECTIONr_t side_sel_reg_val;
   2125     int pmd_mode = 0;
   2126     uint32_t speed = 0;
   2127     phymod_access_t acc_cpy;
   2128    
   2129     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2130     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2131     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2132     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2133 
   2134     /* Get the lane map from phymod access */
   2135     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2136     QUADRA28_GET_LOC(phy, pkg_side);   
   2137     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2138 
   2139     if (pmd_mode == Q28_SINGLE_PMD) {
   2140         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2141             if (((lane_map >> lane_index) & 1) == 0x1) {
   2142                 PHYMOD_IF_ERR_RETURN(
   2143                         quadra28_channel_select(&acc_cpy,
   2144                         ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   2145                 PHYMOD_IF_ERR_RETURN(
   2146                         _quadra28_merlin_phy_reset_set(&acc_cpy, reset));
   2147                 if (lane_map == Q28_ALL_LANE) {
   2148                     break;
   2149                 }
   2150             }
   2151         }
   2152     } else {
   2153         PHYMOD_IF_ERR_RETURN(
   2154              _quadra28_merlin_phy_reset_set(&acc_cpy, reset));
   2155     }
   2156 
   2157     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2158     return PHYMOD_E_NONE;
   2159 }
   2160 
   2161 static int _quadra28_merlin_phy_reset_set( phymod_access_t *pa, const phymod_phy_reset_t* reset)
   2162 {
   2163     /* TX AFE Lane Reset */
   2164     switch (reset->tx) {
   2165         /* In Reset */
   2166         case phymodResetDirectionIn:
   2167             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc_val(1));
   2168             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc(1));
   2169         break;
   2170         /* Out Reset */
   2171         case phymodResetDirectionOut:
   2172             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc_val(0));
   2173             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc(1));
   2174         break;
   2175         /* Toggle Reset */
   2176         case phymodResetDirectionInOut:
   2177             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc_val(1));
   2178             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc(1));
   2179             PHYMOD_USLEEP(10);
   2180             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc_val(0));
   2181             PHYMOD_IF_ERR_RETURN(wr_afe_tx_reset_frc(1));
   2182 
   2183         break;
   2184         default:
   2185         break;
   2186     }
   2187 
   2188     /* RX AFE Lane Reset */
   2189     switch (reset->rx) {
   2190         /* In Reset */
   2191         case phymodResetDirectionIn:
   2192             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc_val(1));
   2193             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc(1));
   2194         break;
   2195         /* Out Reset */
   2196         case phymodResetDirectionOut:
   2197             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc_val(0));
   2198             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc(1));
   2199         break;
   2200         /* Toggle Reset */
   2201         case phymodResetDirectionInOut:
   2202             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc_val(1));
   2203             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc(1));
   2204 
   2205             PHYMOD_USLEEP(10);
   2206             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc_val(0));
   2207             PHYMOD_IF_ERR_RETURN(wr_afe_rx_reset_frc(1));
   2208 
   2209         break;
   2210         default:
   2211         break;
   2212     }
   2213 
   2214     return PHYMOD_E_NONE;
   2215 }
   2216 
   2217 int _quadra28_phy_reset_get( const phymod_phy_access_t *phy,  phymod_phy_reset_t* reset)
   2218 {
   2219     int lane_map = 0;
   2220     int pkg_side = 0;
   2221     int num_lanes = QUADRA28_MAX_LANE;
   2222     int lane_index = 0;
   2223     SIDE_SELECTIONr_t side_sel_reg_val;
   2224     SIGDET_CTRL_1r_t sigdet_ctrl1_reg;
   2225     int pmd_mode = 0;
   2226     uint32_t speed = 0;
   2227     phymod_access_t acc_cpy;
   2228 
   2229     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2230     PHYMOD_MEMSET(&sigdet_ctrl1_reg, 0 , sizeof(SIGDET_CTRL_1r_t));
   2231     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2232     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2233     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2234 
   2235     /* Get the lane map from phymod access */
   2236     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2237     QUADRA28_GET_LOC(phy, pkg_side);   
   2238     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);
   2239 
   2240     if (pmd_mode == Q28_SINGLE_PMD) {
   2241         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2242             if (((lane_map >> lane_index) & 1) == 0x1) {
   2243                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   2244                 PHYMOD_IF_ERR_RETURN (
   2245                    _quadra28_merlin_phy_reset_get(&acc_cpy, reset));
   2246                 break;
   2247             }
   2248         }
   2249     } else {
   2250         PHYMOD_IF_ERR_RETURN (
   2251           _quadra28_merlin_phy_reset_get(&acc_cpy, reset));
   2252 
   2253     }
   2254     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2255 
   2256     return PHYMOD_E_NONE;
   2257 
   2258 }
   2259 
   2260 static int _quadra28_merlin_phy_reset_get( phymod_access_t *pa,  phymod_phy_reset_t* reset)
   2261 {
   2262     uint8_t data = 0;
   2263     uint16_t __err = 0;
   2264     data = rd_afe_tx_reset_frc_val();
   2265     if (data == 0) {
   2266         /* Out of Reset */
   2267         reset->tx = phymodResetDirectionOut;
   2268     } else {
   2269         /* In Reset */
   2270         reset->tx = phymodResetDirectionIn;
   2271     }
   2272     data = rd_afe_rx_reset_frc_val();
   2273     if (data == 0) {
   2274         /* Out of Reset */
   2275         reset->rx = phymodResetDirectionOut;
   2276     } else {
   2277         /* In Reset */
   2278         reset->rx = phymodResetDirectionIn;
   2279     }
   2280     return __err;
   2281 }
   2282 
   2283 int _quadra28_loopback_set(const phymod_phy_access_t *phy, phymod_loopback_mode_t loopback, uint32_t enable)
   2284 {
   2285     int lane_map = 0;
   2286     int pkg_side = 0;
   2287     int num_lanes = QUADRA28_MAX_LANE;
   2288     int lane_index = 0;
   2289     SIDE_SELECTIONr_t side_sel_reg_val;
   2290     int pmd_mode = 0;
   2291     uint32_t speed = 0;
   2292     phymod_access_t acc_cpy;
   2293     uint8_t datapath = 0;
   2294     PMD_TRANSMIT_DISABLEr_t tx_disable;
   2295     BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   2296 
   2297     PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   2298     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2299     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2300     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2301     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2302 
   2303     /* Get the lane map from phymod access */
   2304     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2305     QUADRA28_GET_LOC(phy, pkg_side);   
   2306     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2307     Q28_GET_DATAPATH(&acc_cpy, datapath);
   2308     if (datapath == phymodDatapathUll && 
   2309              loopback == phymodLoopbackRemotePMD) {
   2310         PHYMOD_DIAG_OUT(("Remote loopback doesnt support 4-bit datapath\n"));
   2311         return PHYMOD_E_PARAM;
   2312     }
   2313     if (pmd_mode == Q28_SINGLE_PMD) {
   2314         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2315             if (((lane_map >> lane_index) & 1) == 0x1) {
   2316                 PHYMOD_IF_ERR_RETURN(
   2317                         quadra28_channel_select(&acc_cpy,
   2318                         ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   2319                 if (loopback == phymodLoopbackGlobalPMD) {
   2320                     PHYMOD_IF_ERR_RETURN(
   2321                         BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2322                     BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_SET(pmd_ctrl, enable);
   2323                     PHYMOD_IF_ERR_RETURN(
   2324                         BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
   2325                     /*PHYMOD_IF_ERR_RETURN(
   2326                          merlin_quadra28_dig_lpbk(&acc_cpy, enable));*/
   2327                 } else if (loopback == phymodLoopbackRemotePMD) {
   2328                     PHYMOD_IF_ERR_RETURN(
   2329                          merlin_quadra28_rmt_lpbk(&acc_cpy, enable));
   2330                 } else if(loopback == phymodLoopbackGlobal) {
   2331                     BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   2332                     PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   2333                     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2334                     /*PHYMOD_IF_ERR_RETURN(
   2335                          merlin_quadra28_dig_lpbk(&acc_cpy, enable));*/
   2336                     PHYMOD_IF_ERR_RETURN(
   2337                        BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2338                     BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_SET(pmd_ctrl, enable);
   2339                     PHYMOD_IF_ERR_RETURN(
   2340                         BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
   2341                     /* Squelch TX */
   2342                     PHYMOD_IF_ERR_RETURN(
   2343                         READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   2344                     BCMI_QUADRA28_PMD_TRANSMIT_DISABLEr_PMD_TRANSMITDISABLE_0f_SET
   2345                                                      (tx_disable, enable);
   2346                     PHYMOD_IF_ERR_RETURN(
   2347                         WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_disable));
   2348                 } else {
   2349                     return PHYMOD_E_UNAVAIL;
   2350                 }
   2351                 if (lane_map == Q28_ALL_LANE) {
   2352                     break;
   2353                 }
   2354             }
   2355         }
   2356     } else {
   2357         if (loopback == phymodLoopbackGlobalPMD) { 
   2358            PHYMOD_IF_ERR_RETURN(
   2359                BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2360            BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_SET(pmd_ctrl, enable);
   2361            PHYMOD_IF_ERR_RETURN(
   2362                BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
   2363             /*PHYMOD_IF_ERR_RETURN(
   2364                  merlin_quadra28_dig_lpbk(&acc_cpy, enable));*/
   2365         } else if (loopback == phymodLoopbackRemotePMD) {
   2366             PHYMOD_IF_ERR_RETURN(
   2367                  merlin_quadra28_rmt_lpbk(&acc_cpy, enable));
   2368         } else if (loopback == phymodLoopbackGlobal) {
   2369            BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   2370            PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   2371            QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2372            
   2373            /*PHYMOD_IF_ERR_RETURN(
   2374            merlin_quadra28_dig_lpbk(&acc_cpy, enable));*/
   2375            PHYMOD_IF_ERR_RETURN(
   2376                BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2377            BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_SET(pmd_ctrl, enable);
   2378            PHYMOD_IF_ERR_RETURN(
   2379                BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
   2380 
   2381            /* Squelch TX */
   2382            PHYMOD_IF_ERR_RETURN(
   2383                READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_disable));
   2384            BCMI_QUADRA28_PMD_TRANSMIT_DISABLEr_PMD_TRANSMITDISABLE_0f_SET
   2385                                             (tx_disable, enable);
   2386            PHYMOD_IF_ERR_RETURN(
   2387                WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_disable));
   2388         } else {
   2389             return PHYMOD_E_UNAVAIL;
   2390         }
   2391     }
   2392     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2393     return PHYMOD_E_NONE;
   2394 }
   2395 
   2396 int _quadra28_loopback_get(const phymod_phy_access_t *phy, phymod_loopback_mode_t loopback, uint32_t* enable)
   2397 {
   2398     int lane_map = 0;
   2399     int pkg_side = 0;
   2400     int num_lanes = QUADRA28_MAX_LANE;
   2401     int lane_index = 0;
   2402     SIDE_SELECTIONr_t side_sel_reg_val;
   2403     int pmd_mode = 0;
   2404     uint32_t speed = 0;
   2405     phymod_access_t acc_cpy;
   2406     BCMI_QUADRA28_DIG_LPBK_CONFIGr_t dig_loopback;
   2407     RMT_LPBK_CONFIGr_t rmt_loopback;
   2408     BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   2409    
   2410     PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   2411     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2412     PHYMOD_MEMSET(&dig_loopback, 0 , sizeof(BCMI_QUADRA28_DIG_LPBK_CONFIGr_t));	
   2413     PHYMOD_MEMSET(&rmt_loopback, 0 , sizeof(RMT_LPBK_CONFIGr_t));	
   2414     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2415     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2416     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2417 
   2418     /* Get the lane map from phymod access */
   2419     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2420     QUADRA28_GET_LOC(phy, pkg_side);   
   2421     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2422 
   2423     if (pmd_mode == Q28_SINGLE_PMD) {
   2424         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2425             if (((lane_map >> lane_index) & 1) == 0x1) {
   2426                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   2427                 if (loopback == phymodLoopbackGlobalPMD) {
   2428                     /*PHYMOD_IF_ERR_RETURN(
   2429                         READ_DIG_LPBK_CONFIGr(&acc_cpy, &dig_loopback));*/
   2430                    PHYMOD_IF_ERR_RETURN(
   2431                        BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2432                    *enable = BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_GET(pmd_ctrl);
   2433                 } else if (loopback == phymodLoopbackGlobal) {
   2434                    QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2435                    PHYMOD_IF_ERR_RETURN(
   2436                        BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2437                    *enable = BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_GET(pmd_ctrl);
   2438                 } else if (loopback == phymodLoopbackRemotePMD) {
   2439                     PHYMOD_IF_ERR_RETURN(
   2440                         READ_RMT_LPBK_CONFIGr(&acc_cpy, &rmt_loopback));
   2441                     *enable = RMT_LPBK_CONFIGr_RMT_LPBK_ENf_GET(rmt_loopback);
   2442                 } else {
   2443                     return PHYMOD_E_UNAVAIL;
   2444                 }
   2445                 break;
   2446             }
   2447         }
   2448     } else {
   2449         if (loopback == phymodLoopbackGlobalPMD) {
   2450             PHYMOD_IF_ERR_RETURN(
   2451                  BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2452             *enable = BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_GET(pmd_ctrl);
   2453         } else if (loopback == phymodLoopbackRemotePMD) {
   2454             PHYMOD_IF_ERR_RETURN(
   2455                 READ_RMT_LPBK_CONFIGr(&acc_cpy, &rmt_loopback));
   2456             *enable = RMT_LPBK_CONFIGr_RMT_LPBK_ENf_GET(rmt_loopback);
   2457         } else if (loopback == phymodLoopbackGlobal) {
   2458             QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2459             PHYMOD_IF_ERR_RETURN(
   2460                 BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   2461             *enable = BCMI_QUADRA28_PMD_CONTROLr_PMA_LOOPBACKf_GET(pmd_ctrl);
   2462 
   2463         } else {
   2464             return PHYMOD_E_UNAVAIL;
   2465         }
   2466     }
   2467     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2468 
   2469     return PHYMOD_E_NONE;
   2470 }
   2471 
   2472 int _quadra28_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
   2473 {
   2474     int lane_map = 0;
   2475     int pkg_side = 0;
   2476     int num_lanes = QUADRA28_MAX_LANE;
   2477     int lane_index = 0;
   2478     SIDE_SELECTIONr_t side_sel_reg_val;
   2479     int pmd_mode = 0;
   2480     uint32_t speed = 0;
   2481     phymod_access_t acc_cpy;
   2482    
   2483     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2484     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2485     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2486     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2487 
   2488     /* Get the lane map from phymod access */
   2489     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2490     QUADRA28_GET_LOC(phy, pkg_side);   
   2491     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2492 
   2493     if (pmd_mode == Q28_SINGLE_PMD) {
   2494         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2495             if (((lane_map >> lane_index) & 1) == 0x1) {
   2496                 PHYMOD_IF_ERR_RETURN(
   2497                     quadra28_channel_select(&acc_cpy,
   2498                         ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   2499                 PHYMOD_IF_ERR_RETURN(quadra28_power_set(&acc_cpy, power));
   2500                 if (Q28_ALL_LANE == lane_map) {
   2501                     break;
   2502                 }
   2503             }
   2504         }
   2505     } else {
   2506         PHYMOD_IF_ERR_RETURN(quadra28_power_set(&acc_cpy, power));
   2507     }
   2508 
   2509     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2510     return PHYMOD_E_NONE;
   2511 }
   2512 
   2513 static int quadra28_power_set(const phymod_access_t *pa, const phymod_phy_power_t* power)
   2514 {
   2515     
   2516     PMD_TRANSMIT_DISABLEr_t tx_disable;
   2517     if (power->tx != phymodPowerNoChange) {
   2518         if ( power->tx == phymodPowerOn) {
   2519             PHYMOD_IF_ERR_RETURN(wr_ln_tx_s_pwrdn(0));
   2520             PHYMOD_IF_ERR_RETURN(   
   2521               READ_PMD_TRANSMIT_DISABLEr(pa, &tx_disable));
   2522             PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET(tx_disable, 0);
   2523             PHYMOD_IF_ERR_RETURN(
   2524                            WRITE_PMD_TRANSMIT_DISABLEr(pa, tx_disable)); 
   2525         } else if (power->tx == phymodPowerOff) {
   2526             PHYMOD_IF_ERR_RETURN(wr_ln_tx_s_pwrdn(1));
   2527             PHYMOD_IF_ERR_RETURN(
   2528                READ_PMD_TRANSMIT_DISABLEr(pa, &tx_disable));
   2529             PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET(tx_disable, 1);
   2530             PHYMOD_IF_ERR_RETURN(
   2531                            WRITE_PMD_TRANSMIT_DISABLEr(pa, tx_disable)); 
   2532         } else if (power->tx == phymodPowerOffOn) {
   2533             PHYMOD_IF_ERR_RETURN(wr_ln_tx_s_pwrdn(1));
   2534             PHYMOD_IF_ERR_RETURN(
   2535                READ_PMD_TRANSMIT_DISABLEr(pa, &tx_disable));
   2536             PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET(tx_disable, 1);
   2537             PHYMOD_IF_ERR_RETURN(
   2538                            WRITE_PMD_TRANSMIT_DISABLEr(pa, tx_disable)); 
   2539             PHYMOD_USLEEP(500);
   2540             PHYMOD_IF_ERR_RETURN(wr_ln_tx_s_pwrdn(0));
   2541             PHYMOD_IF_ERR_RETURN(
   2542                READ_PMD_TRANSMIT_DISABLEr(pa, &tx_disable));
   2543             PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET(tx_disable, 0);
   2544             PHYMOD_IF_ERR_RETURN(
   2545                            WRITE_PMD_TRANSMIT_DISABLEr(pa, tx_disable)); 
   2546         }
   2547     }
   2548     if (power->rx != phymodPowerNoChange) {
   2549         if (power->rx == phymodPowerOn) {
   2550             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc_val(0));
   2551             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc(0));
   2552         } else if (power->rx == phymodPowerOff) {
   2553             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc_val(1));
   2554             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc(1));
   2555         } else if (power->rx == phymodPowerOffOn) {
   2556             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc_val(1));
   2557             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc(1));
   2558 
   2559             PHYMOD_USLEEP(500);
   2560             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc_val(0));
   2561             PHYMOD_IF_ERR_RETURN(wr_afe_rx_pwrdn_frc(0));
   2562 
   2563         }
   2564     }
   2565 
   2566     return PHYMOD_E_NONE;
   2567 }
   2568 
   2569 int _quadra28_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
   2570 {
   2571     int lane_map = 0;
   2572     int pkg_side = 0;
   2573     int num_lanes = QUADRA28_MAX_LANE;
   2574     int lane_index = 0;
   2575     SIDE_SELECTIONr_t side_sel_reg_val;
   2576     int pmd_mode = 0;
   2577     uint32_t speed = 0;
   2578     phymod_access_t acc_cpy;
   2579    
   2580     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2581     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2582     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2583     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2584 
   2585     /* Get the lane map from phymod access */
   2586     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2587     QUADRA28_GET_LOC(phy, pkg_side);   
   2588     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2589 
   2590     if (pmd_mode == Q28_SINGLE_PMD) {
   2591         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2592             if (((lane_map >> lane_index) & 1) == 0x1) {
   2593                 PHYMOD_IF_ERR_RETURN(quadra28_channel_select(&acc_cpy, lane_index));
   2594                 PHYMOD_IF_ERR_RETURN (
   2595                     quadra28_power_get(&acc_cpy, power));
   2596                 break;
   2597             }
   2598         }
   2599     } else {
   2600         PHYMOD_IF_ERR_RETURN (
   2601               quadra28_power_get(&acc_cpy, power));
   2602     }
   2603     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2604     return PHYMOD_E_NONE;
   2605 
   2606 }
   2607 static int quadra28_power_get(const phymod_access_t *pa, phymod_phy_power_t* power)
   2608 {
   2609     uint8_t temp = 0;
   2610     uint16_t __err = 0;
   2611     temp = rd_ln_tx_s_pwrdn();
   2612     if (temp == 0) {
   2613         power->tx = phymodPowerOn;
   2614     } else {
   2615         power->tx = phymodPowerOff;
   2616     }
   2617     temp = rd_afe_rx_pwrdn_frc();
   2618     if (temp == 0) {
   2619         power->rx = phymodPowerOn;
   2620     } else {
   2621         power->rx = phymodPowerOff;
   2622     }
   2623     return __err;
   2624 }
   2625 
   2626 int _quadra28_pll_seq_restart(const phymod_access_t *pa, uint32_t flag, phymod_sequencer_operation_t operation)
   2627 {
   2628     BCMI_QUADRA28_XGXSCONTROLr_t xgs_ctrl;
   2629     int pkg_side = 0;
   2630     uint32_t acc_flags = 0; 
   2631     SIDE_SELECTIONr_t side_sel_reg_val;
   2632     int pmd_mode = 0;
   2633     uint32_t speed = 0;
   2634     phymod_access_t acc_cpy;
   2635    
   2636     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2637     PHYMOD_MEMSET(&xgs_ctrl, 0 , sizeof(BCMI_QUADRA28_XGXSCONTROLr_t));
   2638     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   2639     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2640     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2641 
   2642     /* Get the lane map from phymod access */
   2643     acc_flags = PHYMOD_ACC_FLAGS(&acc_cpy);
   2644     QUADRA28_GET_IF_SIDE(acc_flags, pkg_side);   
   2645     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2646 
   2647     if (pmd_mode == Q28_SINGLE_PMD) {
   2648         PHYMOD_IF_ERR_RETURN(
   2649             quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   2650     }
   2651     PHYMOD_IF_ERR_RETURN(
   2652         BCMI_QUADRA28_READ_XGXSCONTROLr(&acc_cpy, &xgs_ctrl));
   2653     if (operation == phymodSeqOpStop) {
   2654         BCMI_QUADRA28_XGXSCONTROLr_START_SEQUENCERf_SET(xgs_ctrl, 0);
   2655         PHYMOD_IF_ERR_RETURN(
   2656             BCMI_QUADRA28_WRITE_XGXSCONTROLr(&acc_cpy, xgs_ctrl));
   2657     } else if(operation == phymodSeqOpStart) {
   2658         BCMI_QUADRA28_XGXSCONTROLr_START_SEQUENCERf_SET(xgs_ctrl, 1);
   2659         PHYMOD_IF_ERR_RETURN(
   2660             BCMI_QUADRA28_WRITE_XGXSCONTROLr(&acc_cpy, xgs_ctrl));
   2661     } else if (operation == phymodSeqOpRestart) {
   2662         BCMI_QUADRA28_XGXSCONTROLr_START_SEQUENCERf_SET(xgs_ctrl, 0);
   2663         PHYMOD_IF_ERR_RETURN(
   2664             BCMI_QUADRA28_WRITE_XGXSCONTROLr(&acc_cpy, xgs_ctrl));
   2665         PHYMOD_USLEEP(1000);
   2666         BCMI_QUADRA28_XGXSCONTROLr_START_SEQUENCERf_SET(xgs_ctrl, 1);
   2667         PHYMOD_IF_ERR_RETURN(
   2668             BCMI_QUADRA28_WRITE_XGXSCONTROLr(&acc_cpy, xgs_ctrl));
   2669     } else {
   2670         return PHYMOD_E_PARAM;
   2671     }
   2672 
   2673     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2674 
   2675     return PHYMOD_E_NONE;
   2676 }
   2677 
   2678 int _quadra28_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
   2679 {
   2680     int lane_map = 0;
   2681     int pkg_side = 0;
   2682     int num_lanes = QUADRA28_MAX_LANE;
   2683     int lane_index = 0;
   2684     SIDE_SELECTIONr_t side_sel_reg_val;
   2685     int pmd_mode = 0;
   2686     uint32_t speed = 0;
   2687     phymod_access_t acc_cpy;
   2688    
   2689     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2690     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2691     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2692     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2693 
   2694     /* Get the lane map from phymod access */
   2695     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2696     QUADRA28_GET_LOC(phy, pkg_side);   
   2697     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2698 
   2699     if (pmd_mode == Q28_SINGLE_PMD) {
   2700         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2701             if (((lane_map >> lane_index) & 1) == 0x1) {
   2702                 PHYMOD_IF_ERR_RETURN(
   2703                     quadra28_channel_select(&acc_cpy,
   2704                         ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   2705                 PHYMOD_IF_ERR_RETURN(
   2706                      merlin_quadra28_apply_txfir_cfg(&acc_cpy, (int8_t)tx->pre, (int8_t)tx->main, (int8_t)tx->post, (int8_t)tx->post2));
   2707                 if (Q28_ALL_LANE == lane_map) {
   2708                     break;
   2709                 }
   2710             }
   2711         }
   2712     } else {
   2713         PHYMOD_IF_ERR_RETURN(
   2714           merlin_quadra28_apply_txfir_cfg(&acc_cpy, (int8_t)tx->pre, (int8_t)tx->main, (int8_t)tx->post, (int8_t)tx->post2));
   2715     }
   2716 
   2717     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2718     return PHYMOD_E_NONE;
   2719 }
   2720 
   2721 int _quadra28_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx) 
   2722 {
   2723     int lane_map = 0;
   2724     int pkg_side = 0;
   2725     int num_lanes = QUADRA28_MAX_LANE;
   2726     int lane_index = 0;
   2727     SIDE_SELECTIONr_t side_sel_reg_val;
   2728     int pmd_mode = 0;
   2729     uint32_t speed = 0;
   2730     int8_t value;
   2731     phymod_access_t acc_cpy;
   2732    
   2733     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2734     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2735     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2736     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2737 
   2738     /* Get the lane map from phymod access */
   2739     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2740     QUADRA28_GET_LOC(phy, pkg_side);   
   2741     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2742 
   2743     if (pmd_mode == Q28_SINGLE_PMD) {
   2744         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2745             if (((lane_map >> lane_index) & 1) == 0x1) {
   2746                 PHYMOD_IF_ERR_RETURN(
   2747                     quadra28_channel_select(&acc_cpy, lane_index));
   2748                 break;
   2749            }
   2750         }
   2751     }
   2752     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_tx_afe(&acc_cpy, TX_AFE_PRE, &value));
   2753     tx->pre = value;
   2754     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_tx_afe(&acc_cpy, TX_AFE_MAIN, &value));
   2755     tx->main = value;
   2756     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_tx_afe(&acc_cpy, TX_AFE_POST1, &value));
   2757     tx->post = value;
   2758     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_tx_afe(&acc_cpy, TX_AFE_POST2, &value));
   2759     tx->post2 = value;
   2760 
   2761     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2762     return PHYMOD_E_NONE;
   2763 }
   2764 
   2765 int _quadra28_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
   2766 {
   2767     int lane_map = 0;
   2768     int pkg_side = 0;
   2769     int num_lanes = QUADRA28_MAX_LANE;
   2770     int lane_index = 0;
   2771     SIDE_SELECTIONr_t side_sel_reg_val;
   2772     int pmd_mode = 0, idx = 0;
   2773     uint32_t speed = 0;
   2774     phymod_access_t acc_cpy;
   2775    
   2776     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2777     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2778     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2779     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2780 
   2781     /* Get the lane map from phymod access */
   2782     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2783     QUADRA28_GET_LOC(phy, pkg_side);   
   2784     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2785 
   2786     if (pmd_mode == Q28_SINGLE_PMD) {
   2787         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2788             if (((lane_map >> lane_index) & 1) == 0x1) {
   2789                 PHYMOD_IF_ERR_RETURN(
   2790                     quadra28_channel_select(&acc_cpy,
   2791                         ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   2792                 if (rx->vga.enable) {
   2793                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2794                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_VGA, rx->vga.value));
   2795                 } 
   2796 
   2797                 for (idx = 0 ; idx < rx->num_of_dfe_taps ; idx++) {
   2798                     if (rx->dfe[idx].enable) {
   2799                         PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2800                         PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_DFE1 + idx,
   2801                                              rx->dfe[idx].value));
   2802                     }
   2803                 }
   2804                 if (rx->peaking_filter.enable) {
   2805                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2806                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_PF, rx->peaking_filter.value));
   2807                 } 
   2808                 if (rx->low_freq_peaking_filter.enable) {
   2809                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2810                     PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_PF2, rx->low_freq_peaking_filter.value));
   2811                 }
   2812 
   2813                 if (Q28_ALL_LANE == lane_map) {
   2814                     break;
   2815                 }
   2816             }
   2817         }
   2818     } else {
   2819         if (rx->vga.enable) {
   2820             PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2821             PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_VGA, rx->vga.value));
   2822         } 
   2823 
   2824         for (idx = 0 ; idx < rx->num_of_dfe_taps ; idx++) {
   2825             if (rx->dfe[idx].enable) {
   2826                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2827                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_DFE1 + idx,
   2828                                      rx->dfe[idx].value));
   2829             }
   2830         }
   2831         if (rx->peaking_filter.enable) {
   2832             PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2833             PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_PF, rx->peaking_filter.value));
   2834         } 
   2835         if (rx->low_freq_peaking_filter.enable) {
   2836             PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 1));
   2837             PHYMOD_IF_ERR_RETURN(merlin_quadra28_write_rx_afe(&acc_cpy, RX_AFE_PF2, rx->low_freq_peaking_filter.value));
   2838         }
   2839     }
   2840 
   2841     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2842     return PHYMOD_E_NONE;
   2843 }
   2844 
   2845 int _quadra28_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
   2846 {
   2847     int lane_map = 0;
   2848     int pkg_side = 0;
   2849     int num_lanes = QUADRA28_MAX_LANE;
   2850     int lane_index = 0;
   2851     SIDE_SELECTIONr_t side_sel_reg_val;
   2852     int pmd_mode = 0, idx = 0;
   2853     uint32_t speed = 0;
   2854     int8_t data = 0;
   2855     phymod_access_t acc_cpy;
   2856    
   2857     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   2858     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   2859     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2860     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2861     if (rx) {
   2862         PHYMOD_MEMSET(rx, 0 , sizeof(phymod_rx_t));	
   2863     }else{
   2864 	    return PHYMOD_E_MEMORY;	
   2865     }
   2866 
   2867     /* Get the lane map from phymod access */
   2868     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   2869     QUADRA28_GET_LOC(phy, pkg_side);   
   2870     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   2871 
   2872     if (pmd_mode == Q28_SINGLE_PMD) {
   2873         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   2874             if (((lane_map >> lane_index) & 1) == 0x1) {
   2875                 PHYMOD_IF_ERR_RETURN(
   2876                     quadra28_channel_select(&acc_cpy, lane_index));
   2877                 break;
   2878            }
   2879         }
   2880     }
   2881 
   2882     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_rx_afe(&acc_cpy, RX_AFE_VGA, &data));
   2883     rx->vga.value = data;
   2884 
   2885     for (idx = 0; idx < 5 ; idx++) {
   2886         PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_rx_afe(&acc_cpy, RX_AFE_DFE1 + idx, &data));
   2887         rx->dfe[idx].value = data;
   2888         rx->dfe[idx].enable = 1 ;
   2889     }
   2890     rx->num_of_dfe_taps = 5;
   2891 
   2892     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_rx_afe(&acc_cpy, RX_AFE_PF, &data));
   2893     rx->peaking_filter.value = data;
   2894     PHYMOD_IF_ERR_RETURN(merlin_quadra28_read_rx_afe(&acc_cpy, RX_AFE_PF2, &data));
   2895     rx->low_freq_peaking_filter.value = data;
   2896 
   2897     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   2898     return PHYMOD_E_NONE;
   2899 }
   2900 
   2901 int _quadra28_phy_autoneg_ability_set(const phymod_access_t* pa, q28_an_ability_t an_ability)
   2902 {
   2903     BCMI_QUADRA28_AN_ADVERTISEMENT_1r_t pause_adv;
   2904     BCMI_QUADRA28_AN_ADVERTISEMENT_3r_t fec_adv;
   2905     uint32_t speed = 0;
   2906     phymod_access_t acc_cpy;
   2907     int pmd_mode = 0;
   2908    
   2909     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   2910     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2911     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2912     Q28_UNUSED_PARAM(pmd_mode);
   2913     PHYMOD_MEMSET(&pause_adv, 0, sizeof(BCMI_QUADRA28_AN_ADVERTISEMENT_1r_t));
   2914     PHYMOD_MEMSET(&fec_adv, 0, sizeof(BCMI_QUADRA28_AN_ADVERTISEMENT_3r_t));
   2915 
   2916     PHYMOD_IF_ERR_RETURN(
   2917         BCMI_QUADRA28_READ_AN_ADVERTISEMENT_1r(&acc_cpy, &pause_adv));
   2918     PHYMOD_IF_ERR_RETURN(
   2919         BCMI_QUADRA28_READ_AN_ADVERTISEMENT_3r(&acc_cpy, &fec_adv));
   2920 
   2921     BCMI_QUADRA28_AN_ADVERTISEMENT_1r_PAUSEf_SET(pause_adv, an_ability.pause_ability);
   2922     BCMI_QUADRA28_AN_ADVERTISEMENT_3r_FEC_REQUESTEDf_SET(fec_adv, an_ability.fec_ability);
   2923     
   2924     PHYMOD_IF_ERR_RETURN(
   2925         BCMI_QUADRA28_WRITE_AN_ADVERTISEMENT_1r(&acc_cpy, pause_adv));
   2926     PHYMOD_IF_ERR_RETURN(
   2927         BCMI_QUADRA28_WRITE_AN_ADVERTISEMENT_3r(&acc_cpy, fec_adv));
   2928 
   2929     return PHYMOD_E_NONE;
   2930 }
   2931 
   2932 int _quadra28_phy_autoneg_ability_get(const phymod_access_t* pa, phymod_autoneg_ability_t* an_ability)
   2933 {
   2934     uint16_t ability;
   2935     BCMI_QUADRA28_AN_ADVERTISEMENT_1r_t pause_ability;
   2936     BCMI_QUADRA28_AN_ADVERTISEMENT_2r_t tech_ability;
   2937     BCMI_QUADRA28_AN_ADVERTISEMENT_3r_t fec_ability;
   2938     uint32_t speed = 0;
   2939     phymod_access_t acc_cpy;
   2940     int pmd_mode = 0;
   2941    
   2942     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   2943     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   2944     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   2945     Q28_UNUSED_PARAM(pmd_mode);
   2946 
   2947     PHYMOD_MEMSET(&pause_ability, 0, sizeof(BCMI_QUADRA28_AN_ADVERTISEMENT_1r_t));
   2948     PHYMOD_MEMSET(&tech_ability, 0, sizeof(BCMI_QUADRA28_AN_ADVERTISEMENT_2r_t));
   2949     PHYMOD_MEMSET(&fec_ability, 0, sizeof(BCMI_QUADRA28_AN_ADVERTISEMENT_3r_t));
   2950 
   2951     PHYMOD_IF_ERR_RETURN(
   2952         BCMI_QUADRA28_READ_AN_ADVERTISEMENT_1r(&acc_cpy, &pause_ability));
   2953     PHYMOD_IF_ERR_RETURN(
   2954         BCMI_QUADRA28_READ_AN_ADVERTISEMENT_2r(&acc_cpy, &tech_ability));
   2955     PHYMOD_IF_ERR_RETURN(
   2956         BCMI_QUADRA28_READ_AN_ADVERTISEMENT_3r(&acc_cpy, &fec_ability));
   2957 
   2958     ability = BCMI_QUADRA28_AN_ADVERTISEMENT_1r_PAUSEf_GET(pause_ability);
   2959     if (ability == Q28_SYMM_PAUSE) {
   2960         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability);
   2961     } else if(ability == Q28_ASYM_PAUSE) {
   2962         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability);
   2963     } else {
   2964         PHYMOD_AN_CAP_SYMM_PAUSE_CLR(an_ability);
   2965         PHYMOD_AN_CAP_ASYM_PAUSE_CLR(an_ability);
   2966     }
   2967     ability = BCMI_QUADRA28_AN_ADVERTISEMENT_2r_TECHABILITYf_GET(tech_ability); 
   2968     /*first check cl73 ability*/
   2969     switch (ability) {
   2970         case Q28_CL73_100GBASE_CR10:
   2971             PHYMOD_AN_CAP_100G_CR10_SET(an_ability->an_cap);
   2972         break;
   2973         case Q28_CL73_40GBASE_CR4:
   2974             PHYMOD_AN_CAP_40G_CR4_SET(an_ability->an_cap);
   2975         break;
   2976         case Q28_CL73_40GBASE_KR4:
   2977             PHYMOD_AN_CAP_40G_KR4_SET(an_ability->an_cap);
   2978         break;
   2979         case Q28_CL73_10GBASE_KR:
   2980             PHYMOD_AN_CAP_10G_KR_SET(an_ability->an_cap);
   2981         break;
   2982         case Q28_CL73_1000BASE_KX:
   2983             PHYMOD_AN_CAP_1G_KX_SET(an_ability->an_cap);
   2984         break;
   2985         case Q28_CL73_100GBASE_CR4:
   2986             PHYMOD_AN_CAP_100G_CR4_SET(an_ability->an_cap);
   2987         break;
   2988         case Q28_CL73_100GBASE_KR4:
   2989             PHYMOD_AN_CAP_100G_KR4_SET(an_ability->an_cap);
   2990         break;
   2991         default:
   2992             break;
   2993     }
   2994     an_ability->an_fec = BCMI_QUADRA28_AN_ADVERTISEMENT_3r_FEC_REQUESTEDf_GET(fec_ability);
   2995 
   2996     return PHYMOD_E_NONE;
   2997 }
   2998 
   2999 int _quadra28_phy_autoneg_get(const phymod_access_t* pa, phymod_autoneg_control_t* an, uint32_t* an_done)
   3000 {
   3001     BCMI_QUADRA28_AN_STATUSr_t an_status;
   3002     BCMI_QUADRA28_AN_CONTROLr_t an_control;
   3003     uint32_t speed = 0;
   3004     phymod_access_t acc_cpy;
   3005     phymod_interface_t intf;
   3006     phymod_ref_clk_t ref_clk;
   3007     uint32_t intf_modes = 0, an_enable = 0, an_cl37_sts = 0;
   3008  
   3009     PHYMOD_MEMSET(&an_status, 0, sizeof(BCMI_QUADRA28_AN_STATUSr_t));
   3010     PHYMOD_MEMSET(&an_control, 0, sizeof(BCMI_QUADRA28_AN_CONTROLr));
   3011     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   3012     PHYMOD_IF_ERR_RETURN (
   3013          quadra28_get_config_mode(&acc_cpy, &intf, &speed, &ref_clk, &intf_modes));
   3014     Q28_UNUSED_PARAM(ref_clk);   
   3015     Q28_UNUSED_PARAM(intf_modes);
   3016     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3017 
   3018     if ((speed == 1000) && (intf == phymodInterfaceSR)) {
   3019         PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_read(&acc_cpy, 0x7ffe0, &an_enable));
   3020         PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_read(&acc_cpy, 0x7ffe1, &an_cl37_sts));
   3021         if (an_enable & (1 << 12)) {
   3022             an->enable = 1;
   3023             an->an_mode = phymod_AN_MODE_CL37;
   3024         } else {
   3025             an->enable = 0;
   3026         }
   3027         if (an_cl37_sts & (1 << 5)) {
   3028             *an_done = 1;
   3029         } else {
   3030             *an_done = 0;
   3031         }
   3032     } else {
   3033         PHYMOD_IF_ERR_RETURN(
   3034             BCMI_QUADRA28_READ_AN_STATUSr(&acc_cpy, &an_status));
   3035         PHYMOD_IF_ERR_RETURN(
   3036             BCMI_QUADRA28_READ_AN_CONTROLr(&acc_cpy, &an_control));
   3037         an->an_mode = phymod_AN_MODE_CL73;
   3038         *an_done = BCMI_QUADRA28_AN_STATUSr_AUTO_NEGOTIATIONCOMPLETEf_GET(an_status);
   3039         an->enable = BCMI_QUADRA28_AN_CONTROLr_AUTO_NEGOTIATIONENABLEf_GET(an_control);
   3040     }
   3041    
   3042 
   3043 
   3044     return PHYMOD_E_NONE;
   3045 }
   3046 
   3047 int _quadra28_phy_autoneg_set(const phymod_access_t* pa, const phymod_autoneg_control_t* an)
   3048 {
   3049     BCMI_QUADRA28_AN_CONTROLr_t an_control;
   3050     uint32_t speed = 0;
   3051     phymod_access_t acc_cpy;
   3052     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0;
   3053     BCMI_QUADRA28_GENERAL_PURPOSE_3r_t gp_reg3_reg_val;
   3054     BCMI_QUADRA28_APPS_MODE_1r_t apps_mode1;
   3055     BCMI_QUADRA28_PMD_TRANSMIT_DISABLEr_t tx_dis;
   3056     unsigned int an_enable = 0, retry_cnt=20;
   3057     BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   3058     BCMI_QUADRA28_MERLIN_MISC_CTRLr_t reset_ack;
   3059     BCMI_QUADRA28_XGXSSTATUSr_t xgs_sts;
   3060     phymod_interface_t intf;
   3061     phymod_ref_clk_t ref_clk;
   3062     uint32_t intf_modes = 0;
   3063 
   3064     PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   3065     PHYMOD_MEMSET(&apps_mode0, 0, sizeof(apps_mode0));
   3066     PHYMOD_MEMSET(&apps_mode1, 0, sizeof(apps_mode1));
   3067     PHYMOD_MEMSET(&tx_dis, 0, sizeof(tx_dis));
   3068     PHYMOD_MEMSET(&gp_reg3_reg_val, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_3r_t));
   3069     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   3070 
   3071     PHYMOD_IF_ERR_RETURN (
   3072          quadra28_get_config_mode(&acc_cpy, &intf, &speed, &ref_clk, &intf_modes));
   3073     Q28_UNUSED_PARAM(ref_clk);   
   3074     Q28_UNUSED_PARAM(intf_modes);
   3075     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3076 
   3077     PHYMOD_MEMSET(&an_control, 0, sizeof(BCMI_QUADRA28_AN_CONTROLr));
   3078     if (an->an_mode == phymod_AN_MODE_CL37 ||
   3079             ((speed == 1000) && (intf == phymodInterfaceSR))) {
   3080         PHYMOD_IF_ERR_RETURN(
   3081             BCMI_QUADRA28_READ_APPS_MODE_1r (&acc_cpy, &apps_mode1));
   3082         if (!BCMI_QUADRA28_APPS_MODE_1r_RETIMER_MODEf_GET(apps_mode1)) {
   3083             /*CL37 will be set only if the chip is confiured as re-timer
   3084              * Not enabling if re-time mode is not set*/
   3085             /* Fix for PHY-2821*/
   3086             return PHYMOD_E_NONE;
   3087         }
   3088         /* Configure 1G(1.25G)-retime */
   3089         PHYMOD_IF_ERR_RETURN(
   3090             BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(&acc_cpy, &gp_reg3_reg_val));
   3091         apps_mode0.v[0] = gp_reg3_reg_val.v[0];
   3092         BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0, 0);
   3093         PHYMOD_IF_ERR_RETURN(
   3094             BCMI_QUADRA28_WRITE_APPS_MODE_0r(&acc_cpy, apps_mode0));
   3095 
   3096         PHYMOD_IF_ERR_RETURN(_quadra28_intf_update_wait_check(&acc_cpy,
   3097                     apps_mode0.v[0], 50000));
   3098         /*PHYMOD_IF_ERR_RETURN(
   3099             BCMI_QUADRA28_READ_APPS_MODE_1r (&acc_cpy, &apps_mode1));
   3100         BCMI_QUADRA28_APPS_MODE_1r_RETIMER_MODEf_SET(apps_mode1,1);
   3101         PHYMOD_IF_ERR_RETURN(
   3102             BCMI_QUADRA28_WRITE_APPS_MODE_1r (&acc_cpy, apps_mode1));*/
   3103         if (an->enable) {
   3104             BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0, 0x81);
   3105         } else {
   3106             BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0, 0x83);
   3107         }
   3108         PHYMOD_IF_ERR_RETURN(
   3109             BCMI_QUADRA28_WRITE_APPS_MODE_0r (&acc_cpy, apps_mode0));
   3110 
   3111         PHYMOD_IF_ERR_RETURN(_quadra28_intf_update_wait_check(&acc_cpy,
   3112                     apps_mode0.v[0], 50000));
   3113         if (an->enable) {
   3114             BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0, 0x1);
   3115         } else {
   3116             BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0, 0x3);
   3117         }
   3118         PHYMOD_IF_ERR_RETURN(
   3119             BCMI_QUADRA28_WRITE_APPS_MODE_0r (&acc_cpy, apps_mode0));
   3120 
   3121         PHYMOD_IF_ERR_RETURN(_quadra28_intf_update_wait_check(&acc_cpy,
   3122                     apps_mode0.v[0], 50000));
   3123 
   3124         /* Perform softreset and wait for reset to clear*/ 
   3125         PHYMOD_IF_ERR_RETURN(
   3126             BCMI_QUADRA28_READ_PMD_CONTROLr(&acc_cpy, &pmd_ctrl));
   3127         BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1);
   3128         PHYMOD_IF_ERR_RETURN(
   3129             BCMI_QUADRA28_WRITE_PMD_CONTROLr(&acc_cpy, pmd_ctrl));
   3130         do {
   3131             PHYMOD_IF_ERR_RETURN(
   3132                 BCMI_QUADRA28_READ_MERLIN_MISC_CTRLr(&acc_cpy, &reset_ack));
   3133             PHYMOD_USLEEP(1000);
   3134             retry_cnt --;
   3135         } while (((reset_ack.v[0] & 0x8000) != 0x8000) && retry_cnt);
   3136         if (retry_cnt <= 0) {
   3137             return PHYMOD_E_TIMEOUT;
   3138         }
   3139         retry_cnt = 20;
   3140         do {
   3141             PHYMOD_IF_ERR_RETURN(
   3142                 BCMI_QUADRA28_READ_XGXSSTATUSr(&acc_cpy, &xgs_sts));
   3143             PHYMOD_USLEEP(800);
   3144             retry_cnt --;
   3145         }  while (((xgs_sts.v[0] & 0x800) != 0x800) && retry_cnt);
   3146         if (retry_cnt <= 0) {
   3147             return PHYMOD_E_TIMEOUT;
   3148         } 
   3149         /* Enable AN by disabling tx*/
   3150         PHYMOD_IF_ERR_RETURN(
   3151             BCMI_QUADRA28_READ_PMD_TRANSMIT_DISABLEr(&acc_cpy, &tx_dis));
   3152         BCMI_QUADRA28_PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET(tx_dis,1);
   3153         PHYMOD_IF_ERR_RETURN(
   3154             BCMI_QUADRA28_WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_dis));
   3155 
   3156         PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_read(&acc_cpy, 0x7ffe0, &an_enable));
   3157         if (an->enable == 1) {
   3158             an_enable |= 1 << 12;
   3159         } else {
   3160             an_enable &= ~(1 << 12);
   3161         }
   3162         PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(&acc_cpy, 0x7ffe0, an_enable));
   3163         BCMI_QUADRA28_PMD_TRANSMIT_DISABLEr_GLOBAL_PMDTRANSMIT_DISABLEf_SET(tx_dis,0);
   3164         PHYMOD_IF_ERR_RETURN(
   3165             BCMI_QUADRA28_WRITE_PMD_TRANSMIT_DISABLEr(&acc_cpy, tx_dis));
   3166     } else {
   3167         PHYMOD_IF_ERR_RETURN(
   3168             BCMI_QUADRA28_READ_AN_CONTROLr(&acc_cpy, &an_control));
   3169    
   3170         BCMI_QUADRA28_AN_CONTROLr_AUTO_NEGOTIATIONENABLEf_SET(an_control, an->enable);
   3171         PHYMOD_IF_ERR_RETURN(
   3172             BCMI_QUADRA28_WRITE_AN_CONTROLr(&acc_cpy, an_control));
   3173     }
   3174 
   3175     return PHYMOD_E_NONE;
   3176 }
   3177 
   3178 int _quadra28_phy_autoneg_remote_ability_get(const phymod_access_t* pa, phymod_autoneg_ability_t* an_ability)
   3179 {
   3180     BCMI_QUADRA28_AN_LP_BASE_PAGE_ABILITY_1r_t lp_pause_ability;
   3181     BCMI_QUADRA28_AN_LP_BASE_PAGE_ABILITY_2r_t lp_tech_ability;
   3182     BCMI_QUADRA28_AN_LP_BASE_PAGE_ABILITY_3r_t lp_fec_ability;
   3183     uint16_t ability;
   3184     uint32_t speed = 0;
   3185     phymod_access_t acc_cpy;
   3186     int pmd_mode = 0;
   3187    
   3188     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   3189     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3190     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3191     Q28_UNUSED_PARAM(pmd_mode);
   3192 
   3193     PHYMOD_MEMSET(&lp_pause_ability, 0, sizeof(BCMI_QUADRA28_AN_LP_BASE_PAGE_ABILITY_1r_t));
   3194     PHYMOD_MEMSET(&lp_tech_ability, 0, sizeof(BCMI_QUADRA28_AN_LP_BASE_PAGE_ABILITY_2r_t));
   3195     PHYMOD_MEMSET(&lp_fec_ability, 0, sizeof(BCMI_QUADRA28_AN_LP_BASE_PAGE_ABILITY_3r_t));
   3196  
   3197     PHYMOD_IF_ERR_RETURN(
   3198         BCMI_QUADRA28_READ_AN_LP_BASE_PAGE_ABILITY_1r(&acc_cpy, &lp_pause_ability));
   3199     PHYMOD_IF_ERR_RETURN(
   3200         BCMI_QUADRA28_READ_AN_LP_BASE_PAGE_ABILITY_2r(&acc_cpy, &lp_tech_ability));
   3201     PHYMOD_IF_ERR_RETURN(
   3202         BCMI_QUADRA28_READ_AN_LP_BASE_PAGE_ABILITY_3r(&acc_cpy, &lp_fec_ability));
   3203 
   3204     ability = (lp_pause_ability.v[0] >> 10) & 0x7;
   3205     if (ability == Q28_SYMM_PAUSE) {
   3206         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability);
   3207     } else if(ability == Q28_ASYM_PAUSE) {
   3208         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability);
   3209     } else {
   3210         PHYMOD_AN_CAP_SYMM_PAUSE_CLR(an_ability);
   3211         PHYMOD_AN_CAP_ASYM_PAUSE_CLR(an_ability);
   3212     }
   3213     ability = (lp_tech_ability.v[0] >> 5) & 0x7ff; 
   3214     /*first check cl73 ability*/
   3215     switch (ability) {
   3216         case Q28_CL73_100GBASE_CR10:
   3217             PHYMOD_AN_CAP_100G_CR10_SET(an_ability->an_cap);
   3218         break;
   3219         case Q28_CL73_40GBASE_CR4:
   3220             PHYMOD_AN_CAP_40G_CR4_SET(an_ability->an_cap);
   3221         break;
   3222         case Q28_CL73_40GBASE_KR4:
   3223             PHYMOD_AN_CAP_40G_KR4_SET(an_ability->an_cap);
   3224         break;
   3225         case Q28_CL73_10GBASE_KR:
   3226             PHYMOD_AN_CAP_10G_KR_SET(an_ability->an_cap);
   3227         break;
   3228         case Q28_CL73_1000BASE_KX:
   3229             PHYMOD_AN_CAP_1G_KX_SET(an_ability->an_cap);
   3230         break;
   3231         case Q28_CL73_100GBASE_CR4:
   3232             PHYMOD_AN_CAP_100G_CR4_SET(an_ability->an_cap);
   3233         break;
   3234         case Q28_CL73_100GBASE_KR4:
   3235             PHYMOD_AN_CAP_100G_KR4_SET(an_ability->an_cap);
   3236         break;
   3237         default:
   3238             break;
   3239     }
   3240     an_ability->an_fec = (lp_fec_ability.v[0] >> 14) & 0x3 ;
   3241 
   3242     return PHYMOD_E_NONE;
   3243 }
   3244 
   3245 int _quadra28_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
   3246 {
   3247     int pkg_side = 0;
   3248     int pmd_mode = 0;
   3249     uint32_t speed = 0;
   3250     phymod_access_t acc_cpy;
   3251     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
   3252    
   3253     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   3254     PHYMOD_MEMSET(&apps_mode0_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));
   3255     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3256     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3257 
   3258     /* Get the lane map from phymod access */
   3259     QUADRA28_GET_LOC(phy, pkg_side);
   3260     PHYMOD_IF_ERR_RETURN(
   3261         BCMI_QUADRA28_READ_APPS_MODE_0r(&acc_cpy, &apps_mode0_reg_val));
   3262     if (pkg_side == Q28_INTF_LINE) {
   3263         BCMI_QUADRA28_APPS_MODE_0r_LINE_FORCE_CL72f_SET(apps_mode0_reg_val, (cl72_en ? 1 :0));
   3264     } else {
   3265         BCMI_QUADRA28_APPS_MODE_0r_SYSTEM_FORCE_CL72f_SET(apps_mode0_reg_val, (cl72_en ? 1 :0));
   3266     }
   3267     if (pmd_mode == Q28_SINGLE_PMD) {
   3268         PHYMOD_IF_ERR_RETURN (quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   3269     }
   3270     PHYMOD_IF_ERR_RETURN(
   3271             BCMI_QUADRA28_WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3272 
   3273     BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 1);
   3274 
   3275     PHYMOD_IF_ERR_RETURN(
   3276             BCMI_QUADRA28_WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3277 
   3278     PHYMOD_IF_ERR_RETURN(
   3279             _quadra28_intf_update_wait_check(&acc_cpy,apps_mode0_reg_val.v[0], 50000));
   3280 
   3281     PHYMOD_USLEEP(500);
   3282 
   3283     BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
   3284     
   3285     PHYMOD_IF_ERR_RETURN(
   3286             BCMI_QUADRA28_WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3287 
   3288     PHYMOD_IF_ERR_RETURN(
   3289             _quadra28_intf_update_wait_check(&acc_cpy,apps_mode0_reg_val.v[0], 50000));
   3290 
   3291     return PHYMOD_E_NONE;
   3292 }
   3293 
   3294 int _quadra28_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
   3295 {
   3296     int pkg_side = 0;
   3297     int pmd_mode = 0;
   3298     uint32_t speed = 0;
   3299     phymod_access_t acc_cpy;
   3300     BCMI_QUADRA28_APPS_MODE_0r_t mode_sts_val;
   3301    
   3302     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   3303     PHYMOD_MEMSET(&mode_sts_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));
   3304     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3305     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3306     Q28_UNUSED_PARAM(pmd_mode);
   3307     /* Get the lane map from phymod access */
   3308     QUADRA28_GET_LOC(phy, pkg_side);
   3309 
   3310     PHYMOD_IF_ERR_RETURN(
   3311         BCMI_QUADRA28_READ_APPS_MODE_0r(&acc_cpy, &mode_sts_val));
   3312     if (pkg_side == Q28_INTF_LINE) {
   3313         *cl72_en = BCMI_QUADRA28_APPS_MODE_0r_LINE_FORCE_CL72f_GET(mode_sts_val);
   3314     } else {
   3315         *cl72_en = BCMI_QUADRA28_APPS_MODE_0r_SYSTEM_FORCE_CL72f_GET(mode_sts_val);
   3316     }
   3317 
   3318     return PHYMOD_E_NONE;
   3319 }
   3320 
   3321 int _quadra28_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
   3322 {
   3323     int lane_map = 0;
   3324     int pkg_side = 0;
   3325     SIDE_SELECTIONr_t side_sel_reg_val;
   3326     int pmd_mode = 0;
   3327     uint32_t speed = 0;
   3328     uint32_t cl72_status = 0xFFFF;
   3329     phymod_access_t acc_cpy;
   3330     BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_t cl72_sts;
   3331    
   3332     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   3333     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   3334     PHYMOD_MEMSET(&cl72_sts, 0, sizeof(BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_t));
   3335     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3336     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3337 
   3338     /* Get the lane map from phymod access */
   3339     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   3340     QUADRA28_GET_LOC(phy, pkg_side);
   3341     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   3342 
   3343     PHYMOD_IF_ERR_RETURN (
   3344         BCMI_QUADRA28_READ_BASE_R_PMD_STATUS_151r(&acc_cpy, &cl72_sts));
   3345 
   3346     if (pmd_mode == Q28_SINGLE_PMD) {
   3347         if (lane_map & 1) {
   3348             cl72_status &= BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_RECEIVER_STATUS_0f_GET(cl72_sts);
   3349         }
   3350         if (lane_map & 2) {
   3351             cl72_status &= BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_RECEIVER_STATUS_1f_GET(cl72_sts);
   3352         }
   3353         if (lane_map & 4) {
   3354             cl72_status &= BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_RECEIVER_STATUS_2f_GET(cl72_sts);
   3355         }
   3356         if (lane_map & 8) {
   3357             cl72_status &= BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_RECEIVER_STATUS_3f_GET(cl72_sts);
   3358         }
   3359 
   3360     } else {
   3361         cl72_status &= BCMI_QUADRA28_BASE_R_PMD_STATUS_151r_RECEIVER_STATUS_0f_GET(cl72_sts);
   3362     }
   3363     status->locked = cl72_status;
   3364     PHYMOD_IF_ERR_RETURN (
   3365         _quadra28_phy_cl72_get(phy, &status->enabled));
   3366     
   3367 
   3368     return PHYMOD_E_NONE;
   3369 }
   3370 
   3371 int _quadra28_finish_mask_seq(const phymod_access_t *pa) 
   3372 {
   3373     int retry_cnt = 20;
   3374 
   3375     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
   3376     PHYMOD_MEMSET(&apps_mode0_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));
   3377 
   3378     PHYMOD_IF_ERR_RETURN (
   3379         BCMI_QUADRA28_READ_APPS_MODE_0r(pa, &apps_mode0_reg_val));
   3380 
   3381     BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 1);
   3382 
   3383     PHYMOD_IF_ERR_RETURN(
   3384             BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa,apps_mode0_reg_val));
   3385 
   3386     PHYMOD_IF_ERR_RETURN(
   3387             _quadra28_intf_update_wait_check(pa,apps_mode0_reg_val.v[0], 50000));
   3388     {
   3389         BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   3390         PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   3391 
   3392         PHYMOD_IF_ERR_RETURN(
   3393             BCMI_QUADRA28_READ_PMD_CONTROLr(pa, &pmd_ctrl));
   3394         BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1);
   3395         PHYMOD_IF_ERR_RETURN(
   3396             BCMI_QUADRA28_WRITE_PMD_CONTROLr(pa, pmd_ctrl));
   3397     }
   3398     {
   3399         BCMI_QUADRA28_MERLIN_MISC_CTRLr_t reset_ack;
   3400         BCMI_QUADRA28_XGXSSTATUSr_t xgs_sts;
   3401         do {
   3402             PHYMOD_IF_ERR_RETURN(
   3403                 BCMI_QUADRA28_READ_MERLIN_MISC_CTRLr(pa, &reset_ack));
   3404             PHYMOD_USLEEP(1000);
   3405             retry_cnt --;
   3406         } while (((reset_ack.v[0] & 0x8000) != 0x8000) && retry_cnt);
   3407         if (retry_cnt <= 0) {
   3408             return PHYMOD_E_TIMEOUT;
   3409         }
   3410         retry_cnt = 20;
   3411         do {
   3412             PHYMOD_IF_ERR_RETURN(
   3413                 BCMI_QUADRA28_READ_XGXSSTATUSr(pa, &xgs_sts));
   3414             PHYMOD_USLEEP(800);
   3415             retry_cnt --;
   3416         }  while (((xgs_sts.v[0] & 0x800) != 0x800) && retry_cnt);
   3417         if (retry_cnt <= 0) {
   3418             return PHYMOD_E_TIMEOUT;
   3419         } 
   3420     } 
   3421 
   3422     BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
   3423     
   3424     PHYMOD_IF_ERR_RETURN(
   3425             BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val));
   3426 
   3427     PHYMOD_IF_ERR_RETURN(
   3428             _quadra28_intf_update_wait_check(pa, apps_mode0_reg_val.v[0], 50000));
   3429 
   3430     return PHYMOD_E_NONE;
   3431 
   3432 }
   3433 
   3434 int _quadra28_phy_retimer_enable(const phymod_access_t *pa, uint32_t enable)
   3435 {
   3436     int pmd_mode = 0;
   3437     uint32_t speed = 0;
   3438     phymod_access_t acc_cpy;
   3439     BCMI_QUADRA28_APPS_MODE_1r_t apps_mode1_reg;
   3440     SIDE_SELECTIONr_t side_sel_reg_val;
   3441    
   3442     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   3443     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   3444     PHYMOD_MEMSET(&apps_mode1_reg, 0, sizeof(BCMI_QUADRA28_APPS_MODE_1r_t));
   3445     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3446     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3447 
   3448     if (pmd_mode == Q28_SINGLE_PMD) {
   3449         if (enable) {
   3450             PHYMOD_DIAG_OUT(("Retimer not supported in 40G/42G. So enabling repeater\n"));
   3451             return PHYMOD_E_NONE;
   3452         }
   3453         PHYMOD_IF_ERR_RETURN (
   3454              quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   3455     }
   3456     PHYMOD_IF_ERR_RETURN (
   3457         BCMI_QUADRA28_READ_APPS_MODE_1r(&acc_cpy, &apps_mode1_reg));
   3458 
   3459     BCMI_QUADRA28_APPS_MODE_1r_RETIMER_MODEf_SET(apps_mode1_reg, enable);
   3460 
   3461     PHYMOD_IF_ERR_RETURN (
   3462         BCMI_QUADRA28_WRITE_APPS_MODE_1r(&acc_cpy, apps_mode1_reg));
   3463 
   3464     PHYMOD_IF_ERR_RETURN (
   3465         _quadra28_finish_mask_seq(&acc_cpy));
   3466     
   3467     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   3468     return PHYMOD_E_NONE;
   3469 }
   3470 
   3471 int _quadra28_phy_retimer_enable_get(const phymod_access_t *pa, uint32_t *enable)
   3472 {
   3473     int pmd_mode = 0;
   3474     uint32_t speed = 0;
   3475     phymod_access_t acc_cpy;
   3476     BCMI_QUADRA28_APPS_MODE_1r_t apps_mode1_reg;
   3477    
   3478     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   3479     PHYMOD_MEMSET(&apps_mode1_reg, 0, sizeof(BCMI_QUADRA28_APPS_MODE_1r_t));
   3480     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3481     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3482     Q28_UNUSED_PARAM(pmd_mode);
   3483 
   3484     PHYMOD_IF_ERR_RETURN (
   3485         BCMI_QUADRA28_READ_APPS_MODE_1r(&acc_cpy, &apps_mode1_reg));
   3486 
   3487     *enable = BCMI_QUADRA28_APPS_MODE_1r_RETIMER_MODEf_GET(apps_mode1_reg);
   3488 
   3489     return PHYMOD_E_NONE;
   3490 }
   3491 
   3492 int _quadra28_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
   3493 {
   3494     int pkg_side = 0;
   3495     int pmd_mode = 0;
   3496     uint32_t speed = 0;
   3497     phymod_access_t acc_cpy;
   3498     BCMI_QUADRA28_APPS_MODE_1r_t apps_mode1_reg_val;
   3499    
   3500     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   3501     PHYMOD_MEMSET(&apps_mode1_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_1r_t));
   3502     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3503     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3504 
   3505     /* Get the lane map from phymod access */
   3506     QUADRA28_GET_LOC(phy, pkg_side);
   3507     PHYMOD_IF_ERR_RETURN(
   3508         BCMI_QUADRA28_READ_APPS_MODE_1r(&acc_cpy, &apps_mode1_reg_val));
   3509     if (pkg_side == Q28_INTF_LINE) {
   3510         apps_mode1_reg_val.v[0] &= 0xCFFF;
   3511         apps_mode1_reg_val.v[0] |= (enable ? (0x3 << 12) : 0);
   3512     } else {
   3513         apps_mode1_reg_val.v[0] &= 0x3FFF;
   3514         apps_mode1_reg_val.v[0] |= (enable ? (0xC << 12) : 0);
   3515     }
   3516     if (pmd_mode == Q28_SINGLE_PMD) {
   3517         PHYMOD_IF_ERR_RETURN (quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   3518     }
   3519 
   3520     PHYMOD_IF_ERR_RETURN(
   3521             BCMI_QUADRA28_WRITE_APPS_MODE_1r(&acc_cpy,apps_mode1_reg_val));
   3522 
   3523     PHYMOD_IF_ERR_RETURN (
   3524         _quadra28_finish_mask_seq(&acc_cpy));
   3525 
   3526     return PHYMOD_E_NONE;
   3527 }
   3528 
   3529 int _quadra28_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
   3530 {
   3531     int pkg_side = 0;
   3532     int pmd_mode = 0;
   3533     uint32_t speed = 0;
   3534     phymod_access_t acc_cpy;
   3535     BCMI_QUADRA28_APPS_MODE_1r_t apps_mode1_reg_val;
   3536    
   3537     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   3538     PHYMOD_MEMSET(&apps_mode1_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_1r_t));
   3539     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3540     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3541     Q28_UNUSED_PARAM(pmd_mode);
   3542 
   3543     /* Get the lane map from phymod access */
   3544     QUADRA28_GET_LOC(phy, pkg_side);
   3545     PHYMOD_IF_ERR_RETURN(
   3546         BCMI_QUADRA28_READ_APPS_MODE_1r(&acc_cpy, &apps_mode1_reg_val));
   3547 
   3548     if (pkg_side == Q28_INTF_LINE) {
   3549         *enable = (apps_mode1_reg_val.v[0] & 0x3000) ? 1 : 0;
   3550     } else {
   3551         *enable = (apps_mode1_reg_val.v[0] & 0xC000) ? 1 : 0;
   3552     }
   3553 
   3554     return PHYMOD_E_NONE;
   3555 }
   3556 
   3557 int _quadra28_set_datapath(const phymod_access_t *pa, int speed, phymod_datapath_t op_datapath)
   3558 {
   3559     phymod_access_t acc_cpy;
   3560     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
   3561     SIDE_SELECTIONr_t side_sel_reg_val;
   3562     uint16_t max_lane = 0, lane_idx = 0, retry_cnt =0;
   3563     uint32_t chip_id;
   3564     GENERAL_PURPOSE_3r_t gen_pur_reg_3r_val;
   3565 
   3566     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   3567     PHYMOD_MEMSET(&apps_mode0_reg_val, 0 , sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));	
   3568     PHYMOD_MEMSET(&gen_pur_reg_3r_val, 0 , sizeof(GENERAL_PURPOSE_3r_t));	
   3569     PHYMOD_MEMCPY(&acc_cpy, pa, sizeof(phymod_access_t));
   3570     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3571     PHYMOD_IF_ERR_RETURN(READ_APPS_MODE_0r(&acc_cpy, &apps_mode0_reg_val));
   3572     if (speed >= Q28_SPEED_40G) {
   3573         PHYMOD_IF_ERR_RETURN (
   3574                 quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   3575     }
   3576     if (op_datapath == phymodDatapathNormal) {
   3577         BCMI_QUADRA28_APPS_MODE_0r_ENABLE_ULL_DATAPATHf_SET(apps_mode0_reg_val, 0);
   3578     } else if (op_datapath == phymodDatapathUll) {
   3579         BCMI_QUADRA28_APPS_MODE_0r_ENABLE_ULL_DATAPATHf_SET(apps_mode0_reg_val, 1);
   3580     } else {
   3581         BCMI_QUADRA28_APPS_MODE_0r_ENABLE_ULL_DATAPATHf_SET(apps_mode0_reg_val, 0);
   3582     }
   3583     
   3584     if (speed >= Q28_SPEED_40G) {
   3585         PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3586         PHYMOD_IF_ERR_RETURN(
   3587                 _quadra28_finish_mask_seq(&acc_cpy));
   3588     } else {
   3589         chip_id =  _quadra28_get_chip_id(&acc_cpy);
   3590         max_lane = (chip_id == QUADRA28_82752_CHIP_ID) ? 2 : QUADRA28_MAX_LANE;
   3591         acc_cpy.addr &= ~(0x3);
   3592         for (lane_idx = 0; lane_idx < max_lane; lane_idx ++) {
   3593             retry_cnt = 20;
   3594             acc_cpy.addr |= lane_idx;
   3595             BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
   3596             PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3597             do {
   3598                 PHYMOD_IF_ERR_RETURN(
   3599                   BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(&acc_cpy,&gen_pur_reg_3r_val));
   3600                 PHYMOD_USLEEP(200);
   3601             } while(((gen_pur_reg_3r_val.v[0] & 0x80) != 0) && retry_cnt--);
   3602             if (retry_cnt == 0) {
   3603                 return PHYMOD_E_TIMEOUT;
   3604             }
   3605             PHYMOD_IF_ERR_RETURN(
   3606                     _quadra28_finish_mask_seq(&acc_cpy));
   3607             acc_cpy.addr &= ~(0x3);
   3608         }
   3609         acc_cpy.addr = pa->addr;
   3610     }
   3611     
   3612     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   3613 
   3614     return PHYMOD_E_NONE;
   3615 }
   3616 
   3617 
   3618 int _quadra28_i2c_write(const phymod_access_t *pa, uint32_t slv_addr, uint32_t start_addr,
   3619                        uint32_t no_of_bytes, const uint8_t *write_data)
   3620 {
   3621     BCMI_QUADRA28_I2C_CONTROLr_t   i2c_ctrl;
   3622     uint8_t data[QUADRA28_I2C_MAX_BYTE];
   3623     uint32_t index = 0;
   3624     
   3625     if (no_of_bytes > QUADRA28_I2C_MAX_BYTE) {
   3626         return PHYMOD_E_PARAM;
   3627     }
   3628     PHYMOD_MEMSET(&i2c_ctrl, 0, sizeof(BCMI_QUADRA28_I2C_CONTROLr_t));
   3629     PHYMOD_MEMSET(data, 0, QUADRA28_I2C_MAX_BYTE);
   3630     PHYMOD_MEMCPY(data, write_data, no_of_bytes);
   3631 
   3632     /* Clear the latched status */
   3633     PHYMOD_IF_ERR_RETURN
   3634         (BCMI_QUADRA28_READ_I2C_CONTROLr(pa, &i2c_ctrl));
   3635     for (index = 0; index < (no_of_bytes/Q28_MAX_BYTES); index++) { 
   3636         PHYMOD_IF_ERR_RETURN
   3637             (_quadra28_i2c_rw(pa, slv_addr, (start_addr+(index*Q28_MAX_BYTES)), Q28_MAX_BYTES, Q28_I2C_WRITE, (data+(index*Q28_MAX_BYTES))));
   3638     }
   3639 
   3640     return PHYMOD_E_NONE;
   3641 }
   3642 
   3643 int _quadra28_i2c_read(const phymod_access_t *pa, uint32_t i2c_slave_addr, uint32_t slave_start_addr,
   3644                       uint32_t no_of_bytes, uint8_t *read_data)
   3645 {
   3646     BCMI_QUADRA28_I2C_CONTROLr_t   i2c_ctrl;
   3647 
   3648     PHYMOD_MEMSET(&i2c_ctrl, 0, sizeof(BCMI_QUADRA28_I2C_CONTROLr_t));
   3649 
   3650     /* Clear the latched status */
   3651     PHYMOD_IF_ERR_RETURN
   3652         (BCMI_QUADRA28_READ_I2C_CONTROLr(pa, &i2c_ctrl));
   3653     PHYMOD_IF_ERR_RETURN
   3654             (_quadra28_i2c_rw(pa, i2c_slave_addr, slave_start_addr, no_of_bytes, Q28_I2C_READ , read_data));
   3655     return PHYMOD_E_NONE;
   3656 }
   3657 
   3658 int _quadra28_i2c_rw(const phymod_access_t *pa, uint32_t slv_addr, 
   3659                      uint32_t slave_start_addr, uint16_t xfer_cnt, uint8_t acc_type, uint8_t *data) 
   3660 {
   3661     BCMI_QUADRA28_I2C_CONTROLr_t    i2c_control;
   3662     BCMI_QUADRA28_I2C_TRANSFER_SIZEr_t  i2c_xfer_size; 
   3663     BCMI_QUADRA28_I2C_EXTERNAL_NVM_ADDRESSr_t eeprom_start_addr; 
   3664     BCMI_QUADRA28_I2C_INTERNAL_ADDRESSr_t  nvram_addr;
   3665     BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_t i2c_config;
   3666     uint16_t cnt_index = 0, temp_cnt = xfer_cnt;
   3667     uint32_t ram_data = 0;
   3668     uint32_t tries = 10;
   3669 
   3670     PHYMOD_MEMSET(&i2c_control, 0, sizeof(BCMI_QUADRA28_I2C_CONTROLr_t));
   3671     PHYMOD_MEMSET(&i2c_xfer_size, 0, sizeof(BCMI_QUADRA28_I2C_TRANSFER_SIZEr_t));
   3672     PHYMOD_MEMSET(&eeprom_start_addr, 0, sizeof(BCMI_QUADRA28_I2C_EXTERNAL_NVM_ADDRESSr_t));
   3673     PHYMOD_MEMSET(&nvram_addr, 0, sizeof(BCMI_QUADRA28_I2C_INTERNAL_ADDRESSr_t));
   3674     PHYMOD_MEMSET(&i2c_config, 0, sizeof(BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_t));
   3675 
   3676     if (acc_type == Q28_I2C_WRITE) {
   3677 
   3678         /* Setup Starting address*/
   3679         BCMI_QUADRA28_I2C_EXTERNAL_NVM_ADDRESSr_SET(eeprom_start_addr, slave_start_addr);
   3680         PHYMOD_IF_ERR_RETURN(
   3681             BCMI_QUADRA28_WRITE_I2C_EXTERNAL_NVM_ADDRESSr(pa, eeprom_start_addr));
   3682         BCMI_QUADRA28_I2C_INTERNAL_ADDRESSr_SET(nvram_addr, QUADRA28_I2C_RAM_START_ADDRESS);
   3683         PHYMOD_IF_ERR_RETURN(
   3684             BCMI_QUADRA28_WRITE_I2C_INTERNAL_ADDRESSr(pa, nvram_addr));
   3685 
   3686         BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_IMC_SL_DEV_ADDf_SET(i2c_config, slv_addr);
   3687         BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_IMC_I2C_SPEEDf_SET(i2c_config, 0);
   3688         BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_IMC_XFER_ADDR_23_16f_SET(i2c_config, 1);
   3689         PHYMOD_IF_ERR_RETURN(
   3690             BCMI_QUADRA28_WRITE_I2C_SLAVE_ID_ADDRESSr(pa, i2c_config));
   3691 
   3692         /* Write Data in to RAM location*/
   3693         for (cnt_index = 0; cnt_index < temp_cnt; cnt_index++) {
   3694             PHYMOD_IF_ERR_RETURN(
   3695                 phymod_raw_iblk_write(pa, (QUADRA28_I2C_RAM_START_ADDRESS + cnt_index),(0xff << 8) | data[cnt_index]));
   3696         }
   3697 
   3698         BCMI_QUADRA28_I2C_TRANSFER_SIZEr_IMC_XFER_CNTf_SET(i2c_xfer_size, xfer_cnt);
   3699         
   3700         /* Add Tx count*/
   3701         PHYMOD_IF_ERR_RETURN(
   3702             BCMI_QUADRA28_WRITE_I2C_TRANSFER_SIZEr(pa, i2c_xfer_size));
   3703     } else {
   3704         BCMI_QUADRA28_I2C_TRANSFER_SIZEr_IMC_XFER_CNTf_SET(i2c_xfer_size, xfer_cnt);
   3705         /* Add Tx count*/
   3706         PHYMOD_IF_ERR_RETURN(
   3707             BCMI_QUADRA28_WRITE_I2C_TRANSFER_SIZEr(pa, i2c_xfer_size));
   3708         
   3709         /* Setup Starting address*/
   3710         BCMI_QUADRA28_I2C_EXTERNAL_NVM_ADDRESSr_SET(eeprom_start_addr, slave_start_addr);
   3711         PHYMOD_IF_ERR_RETURN(
   3712             BCMI_QUADRA28_WRITE_I2C_EXTERNAL_NVM_ADDRESSr(pa, eeprom_start_addr));
   3713 
   3714         /* Setting up internal RAm address*/
   3715         BCMI_QUADRA28_I2C_INTERNAL_ADDRESSr_SET(nvram_addr, QUADRA28_I2C_RAM_START_ADDRESS);
   3716         PHYMOD_IF_ERR_RETURN(
   3717             BCMI_QUADRA28_WRITE_I2C_INTERNAL_ADDRESSr(pa, nvram_addr));
   3718 
   3719         /* Setting up slave address*/
   3720         BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_IMC_SL_DEV_ADDf_SET(i2c_config, slv_addr);
   3721         BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_IMC_I2C_SPEEDf_SET(i2c_config, 1);
   3722         BCMI_QUADRA28_I2C_SLAVE_ID_ADDRESSr_IMC_XFER_ADDR_23_16f_SET(i2c_config, 1);
   3723         PHYMOD_IF_ERR_RETURN(
   3724             BCMI_QUADRA28_WRITE_I2C_SLAVE_ID_ADDRESSr(pa, i2c_config));
   3725     }
   3726 
   3727     PHYMOD_IF_ERR_RETURN(
   3728             BCMI_QUADRA28_READ_I2C_CONTROLr(pa, &i2c_control));
   3729     if (BCMI_QUADRA28_I2C_CONTROLr_I2C_STATUSf_GET(i2c_control) != 0) {
   3730         return PHYMOD_E_CONFIG;
   3731     }
   3732     
   3733     BCMI_QUADRA28_I2C_CONTROLr_EXTENDED_R_Wf_SET(i2c_control, 2);
   3734     BCMI_QUADRA28_I2C_CONTROLr_SLAVE_CMDf_SET(i2c_control, ((acc_type == Q28_I2C_WRITE) ? 1 : 0));
   3735     BCMI_QUADRA28_I2C_CONTROLr_I2C_MASTER_ENABLEf_SET(i2c_control, 1);
   3736     PHYMOD_IF_ERR_RETURN(
   3737             BCMI_QUADRA28_WRITE_I2C_CONTROLr(pa, i2c_control));
   3738    
   3739     do {
   3740         PHYMOD_USLEEP(100 * xfer_cnt);
   3741         PHYMOD_IF_ERR_RETURN(
   3742             BCMI_QUADRA28_READ_I2C_CONTROLr(pa, &i2c_control));
   3743     } while((BCMI_QUADRA28_I2C_CONTROLr_I2C_STATUSf_GET(i2c_control) != 1) && (--tries > 0));
   3744 
   3745     if (BCMI_QUADRA28_I2C_CONTROLr_I2C_STATUSf_GET(i2c_control) != 1) {
   3746         return PHYMOD_E_TIMEOUT;
   3747     }
   3748     if (acc_type == Q28_I2C_READ) {
   3749         /* Write Data in to RAM location*/
   3750         for (cnt_index = 0; cnt_index < temp_cnt; cnt_index ++) {
   3751             PHYMOD_IF_ERR_RETURN(
   3752                 phymod_raw_iblk_read(pa, (QUADRA28_I2C_RAM_START_ADDRESS + cnt_index),&ram_data));
   3753             *data = (ram_data & 0xff);
   3754             data ++;
   3755         }
   3756     }
   3757     return PHYMOD_E_NONE;
   3758 }
   3759 
   3760 int _quadra28_edc_config_set(const phymod_phy_access_t* phy, const phymod_edc_config_t* edc_config)
   3761 {
   3762     phymod_access_t acc_cpy;
   3763     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
   3764     SIDE_SELECTIONr_t side_sel_reg_val;
   3765     uint16_t retry_cnt =0;
   3766     int speed = 0;
   3767     GENERAL_PURPOSE_3r_t gen_pur_reg_3r_val;
   3768     uint8_t datapath = 0;
   3769     phymod_access_t pa = phy->access;
   3770     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));
   3771     PHYMOD_MEMSET(&apps_mode0_reg_val, 0 , sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));	
   3772     PHYMOD_MEMSET(&gen_pur_reg_3r_val, 0 , sizeof(GENERAL_PURPOSE_3r_t));	
   3773     PHYMOD_MEMCPY(&acc_cpy, &pa, sizeof(phymod_access_t));
   3774     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3775     Q28_GET_DATAPATH(&acc_cpy, datapath);
   3776     PHYMOD_IF_ERR_RETURN(READ_APPS_MODE_0r(&acc_cpy, &apps_mode0_reg_val));
   3777     
   3778     if (speed >= Q28_SPEED_40G) {
   3779         PHYMOD_IF_ERR_RETURN (
   3780                 quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   3781     }
   3782     if (edc_config->method != phymodEdcConfigMethodNone) {
   3783         apps_mode0_reg_val.v[0] &= 0xf ;
   3784         apps_mode0_reg_val.v[0] |= 0xC830;
   3785         if (datapath == phymodDatapathUll) {
   3786             BCMI_QUADRA28_APPS_MODE_0r_ENABLE_ULL_DATAPATHf_SET(apps_mode0_reg_val,1);
   3787         }
   3788     } else {
   3789         apps_mode0_reg_val.v[0] &= 0xf ;
   3790         BCMI_QUADRA28_APPS_MODE_0r_SYTEM_LRf_SET(apps_mode0_reg_val,1);
   3791         BCMI_QUADRA28_APPS_MODE_0r_SYSTEM_CUf_SET(apps_mode0_reg_val,1);
   3792         if (datapath == phymodDatapathUll) {
   3793             BCMI_QUADRA28_APPS_MODE_0r_ENABLE_ULL_DATAPATHf_SET(apps_mode0_reg_val,1);
   3794         }
   3795     }
   3796 
   3797     if (speed >= Q28_SPEED_40G) {
   3798         PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3799         PHYMOD_IF_ERR_RETURN(
   3800                 _quadra28_finish_mask_seq(&acc_cpy));
   3801     } else {
   3802         retry_cnt = 20;
   3803         BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
   3804         PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,apps_mode0_reg_val));
   3805         do {
   3806             PHYMOD_IF_ERR_RETURN(
   3807               BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(&acc_cpy,&gen_pur_reg_3r_val));
   3808             PHYMOD_USLEEP(200);
   3809         } while(((gen_pur_reg_3r_val.v[0] & 0x80) != 0) && retry_cnt--);
   3810         if (retry_cnt == 0) {
   3811             return PHYMOD_E_TIMEOUT;
   3812         }
   3813         PHYMOD_IF_ERR_RETURN(
   3814               _quadra28_finish_mask_seq(&acc_cpy));
   3815     }
   3816     
   3817     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   3818 
   3819     return PHYMOD_E_NONE;
   3820 }
   3821 
   3822 int _quadra28_edc_config_get(const phymod_phy_access_t* phy, phymod_edc_config_t* edc_config)
   3823 {
   3824     phymod_access_t acc_cpy;
   3825     GENERAL_PURPOSE_3r_t gen_pur_reg_3r_val;
   3826     uint16_t temp = 0;
   3827     int speed = 0;
   3828     phymod_access_t pa = phy->access;
   3829 
   3830     PHYMOD_MEMSET(&gen_pur_reg_3r_val, 0 , sizeof(GENERAL_PURPOSE_3r_t));	
   3831     PHYMOD_MEMCPY(&acc_cpy, &pa, sizeof(phymod_access_t));
   3832     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3833 
   3834     PHYMOD_IF_ERR_RETURN(
   3835               BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(&acc_cpy,&gen_pur_reg_3r_val));
   3836     temp = (BCMI_QUADRA28_GENERAL_PURPOSE_3r_GET(gen_pur_reg_3r_val) & 0x10) >> 4;
   3837 
   3838     edc_config->method = (temp)? phymodEdcConfigMethodHardware: phymodEdcConfigMethodNone;
   3839 
   3840     return PHYMOD_E_NONE;
   3841 }
   3842 
   3843 int _quadra28_soft_reset(phymod_access_t *pa) 
   3844 {
   3845     BCMI_QUADRA28_PMD_CONTROLr_t pmd_ctrl;
   3846     BCMI_QUADRA28_MERLIN_MISC_CTRLr_t reset_ack;
   3847     BCMI_QUADRA28_XGXSSTATUSr_t xgs_sts;
   3848     int retry_cnt = 20;
   3849 
   3850     PHYMOD_MEMSET(&pmd_ctrl, 0, sizeof(BCMI_QUADRA28_PMD_CONTROLr_t));
   3851 
   3852     PHYMOD_IF_ERR_RETURN(
   3853         BCMI_QUADRA28_READ_PMD_CONTROLr(pa, &pmd_ctrl));
   3854     BCMI_QUADRA28_PMD_CONTROLr_RESETf_SET(pmd_ctrl, 1);
   3855     PHYMOD_IF_ERR_RETURN(
   3856         BCMI_QUADRA28_WRITE_PMD_CONTROLr(pa, pmd_ctrl));
   3857 
   3858     do {
   3859         PHYMOD_IF_ERR_RETURN(
   3860             BCMI_QUADRA28_READ_MERLIN_MISC_CTRLr(pa, &reset_ack));
   3861         PHYMOD_USLEEP(1000);
   3862         retry_cnt --;
   3863     } while (((reset_ack.v[0] & 0x8000) != 0x8000) && retry_cnt);
   3864     if (retry_cnt <= 0) {
   3865         return PHYMOD_E_TIMEOUT;
   3866     }
   3867     retry_cnt = 20;
   3868     do {
   3869         PHYMOD_IF_ERR_RETURN(
   3870             BCMI_QUADRA28_READ_XGXSSTATUSr(pa, &xgs_sts));
   3871         PHYMOD_USLEEP(800);
   3872         retry_cnt --;
   3873     }  while (((xgs_sts.v[0] & 0x800) != 0x800) && retry_cnt);
   3874     if (retry_cnt <= 0) {
   3875         return PHYMOD_E_TIMEOUT;
   3876     }
   3877     return PHYMOD_E_NONE;
   3878 }
   3879 
   3880 int _quadra28_failover_mode_set(const phymod_phy_access_t* phy, phymod_failover_mode_t failover_mode)
   3881 {
   3882     uint32_t speed = 0;
   3883     uint16_t if_side = 0;
   3884     uint32_t fov_mode = 0, read_mode = 0;
   3885     int pmd_mode = 0;
   3886     uint8_t datapath = 0;
   3887     int retry_cnt = 20;
   3888     uint32_t chip_id = 0;
   3889     uint8_t fov_port_phy = 0;
   3890     SIDE_SELECTIONr_t side_sel_reg_val;
   3891     phymod_access_t acc_cpy = phy->access;
   3892     BCMI_QUADRA28_MDIO_BROADCAST_CONTROLr_t bcast_ctrl;
   3893     BCMI_QUADRA28_APPS_MODE_2r_t aps_mode2;
   3894     BCMI_QUADRA28_APPS_MODE_0r_t aps_mode0;
   3895     uint16_t lane = 0;
   3896     BCMI_QUADRA28_RING_CONFIGURATIONr_t ring_conf;
   3897     
   3898     PHYMOD_MEMSET(&bcast_ctrl, 0, sizeof(bcast_ctrl));
   3899     PHYMOD_MEMSET(&aps_mode2, 0, sizeof(aps_mode2));
   3900     PHYMOD_MEMSET(&aps_mode0, 0, sizeof(aps_mode0));
   3901     PHYMOD_MEMSET(&ring_conf, 0, sizeof(ring_conf));
   3902     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   3903     Q28_GET_DATAPATH(&acc_cpy, datapath);
   3904     QUADRA28_GET_LOC(phy, if_side);
   3905     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   3906     fov_port_phy = (pmd_mode == Q28_SINGLE_PMD) ? 4 : 1;
   3907     chip_id = _quadra28_get_chip_id(&acc_cpy);
   3908     /*40G FOv can be performed only on 2 DIE(82780/8278f)*/
   3909     if (((chip_id != QUADRA28_82780_CHIP_ID) && (chip_id != QUADRA28_8278F_CHIP_ID))
   3910             && (pmd_mode == Q28_SINGLE_PMD)) {
   3911         return PHYMOD_E_UNAVAIL;
   3912     }
   3913     if (datapath == phymodDatapathUll) {
   3914         return PHYMOD_E_CONFIG;
   3915     }
   3916     if (failover_mode == phymodFailovermodeNone) { 
   3917         fov_mode = 0;
   3918     } else if (if_side == Q28_INTF_LINE) {
   3919         if (acc_cpy.addr & fov_port_phy) {
   3920             fov_mode = Q28_FOV_TYPE_N1S0;
   3921         } else {
   3922             fov_mode = Q28_FOV_TYPE_N0S1;
   3923         }
   3924     } else {
   3925         if (acc_cpy.addr & fov_port_phy) {
   3926             fov_mode = Q28_FOV_TYPE_N0S1;
   3927         } else {
   3928             fov_mode = Q28_FOV_TYPE_N1S0;
   3929         }
   3930     }
   3931     if (pmd_mode == Q28_SINGLE_PMD) {
   3932         if ( fov_mode != 0) {
   3933             /* As per programming seq, FOV can be configured only with 10G mode, so Changing mode for DIE 1*/
   3934             acc_cpy.addr = (acc_cpy.addr & ~0x7);
   3935             PHYMOD_IF_ERR_RETURN(_quadra28_clear_mode_config(&acc_cpy));
   3936             /* As per programming seq, FOV can be configured only with 10G mode, so Changing mode for DIE 1*/
   3937             acc_cpy.addr = (acc_cpy.addr & ~0x7) | 4;
   3938             PHYMOD_IF_ERR_RETURN(_quadra28_clear_mode_config(&acc_cpy));
   3939 
   3940             acc_cpy.addr = (acc_cpy.addr & ~0x7);
   3941             /* Enable multicast for all the 8 lanes*/
   3942             for (lane = 0; lane <= 7; lane ++) {
   3943                 acc_cpy.addr &= ~7;
   3944                 acc_cpy.addr |= lane;
   3945                 PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(&acc_cpy,0x1c8db,lane));
   3946             }
   3947             /* Setting up multicast for octal channel,
   3948              * No need to enable Multicast for ch1*/
   3949             for (lane = 1; lane <= 7; lane ++) {
   3950                 acc_cpy.addr &= ~7;
   3951                 acc_cpy.addr |= lane;
   3952                 if (lane == 0) {
   3953                     continue;
   3954                 }
   3955 
   3956                 PHYMOD_IF_ERR_RETURN(
   3957                     BCMI_QUADRA28_READ_MDIO_BROADCAST_CONTROLr(&acc_cpy, &bcast_ctrl));
   3958                 BCMI_QUADRA28_MDIO_BROADCAST_CONTROLr_MDIO_MCAST_ENf_SET(bcast_ctrl, 1);
   3959                 BCMI_QUADRA28_MDIO_BROADCAST_CONTROLr_MDIO_MULTICAST_PHYADf_SET(bcast_ctrl, 0);
   3960                 PHYMOD_IF_ERR_RETURN(
   3961                     BCMI_QUADRA28_WRITE_MDIO_BROADCAST_CONTROLr(&acc_cpy, bcast_ctrl));
   3962             }
   3963             PHYMOD_USLEEP(100000); /* Delay as per PGM seq*/
   3964             acc_cpy.addr &= (~7);
   3965             PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(&acc_cpy,Q28_TOP_GP_REG0,0));
   3966             BCMI_QUADRA28_APPS_MODE_2r_SET(aps_mode2, 0x8000 );
   3967             PHYMOD_IF_ERR_RETURN(
   3968                BCMI_QUADRA28_WRITE_APPS_MODE_2r(&acc_cpy, aps_mode2));
   3969             
   3970             /*set Write finish mask*/
   3971             PHYMOD_IF_ERR_RETURN(
   3972               BCMI_QUADRA28_READ_APPS_MODE_0r(&acc_cpy, &aps_mode0));
   3973             BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(aps_mode0, 0);
   3974             PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,aps_mode0));
   3975             PHYMOD_IF_ERR_RETURN(
   3976               _quadra28_intf_update_wait_check(&acc_cpy, aps_mode0.v[0], 50000));
   3977 
   3978             PHYMOD_USLEEP(100000); /* Delay as per PGM seq*/
   3979             /* Clear Write finish mask*/
   3980             aps_mode0.v[0] = 0x8884;   /* As per PGM seq, it works only for SR4*/
   3981             PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,aps_mode0));
   3982             PHYMOD_IF_ERR_RETURN(
   3983               _quadra28_intf_update_wait_check(&acc_cpy, aps_mode0.v[0], 50000));
   3984 
   3985             /*set Write finish mask*/
   3986             PHYMOD_IF_ERR_RETURN(
   3987               BCMI_QUADRA28_READ_APPS_MODE_0r(&acc_cpy, &aps_mode0));
   3988             BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(aps_mode0, 0);
   3989             PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,aps_mode0));
   3990             PHYMOD_IF_ERR_RETURN(
   3991               _quadra28_intf_update_wait_check(&acc_cpy, aps_mode0.v[0], 50000));
   3992 
   3993             acc_cpy.addr |= 4; /* Die 2 soft reset*/
   3994             PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   3995 
   3996             acc_cpy.addr &= ~7;
   3997             /* Soft reset for die 1*/
   3998             PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   3999 
   4000             PHYMOD_USLEEP(200000);
   4001 
   4002             /* Ring reset*/
   4003             acc_cpy.addr &= ~7;
   4004             acc_cpy.addr |= 4;
   4005             PHYMOD_IF_ERR_RETURN(
   4006                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4007             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 1);
   4008             PHYMOD_IF_ERR_RETURN(
   4009                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4010 
   4011             acc_cpy.addr &= ~7;
   4012             PHYMOD_IF_ERR_RETURN(
   4013                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4014             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 1);
   4015             PHYMOD_IF_ERR_RETURN(
   4016                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4017 
   4018             acc_cpy.addr |= 4;
   4019             PHYMOD_IF_ERR_RETURN(
   4020                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4021             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 0);
   4022             PHYMOD_IF_ERR_RETURN(
   4023                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4024 
   4025             acc_cpy.addr &= ~7;
   4026             PHYMOD_IF_ERR_RETURN(
   4027                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4028             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 0);
   4029             PHYMOD_IF_ERR_RETURN(
   4030                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4031 
   4032             /* Enabling FOV mode*/
   4033             acc_cpy.addr &= ~7;
   4034             PHYMOD_IF_ERR_RETURN (
   4035                     quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   4036             PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(&acc_cpy,Q28_TOP_GP_REG0,fov_mode));
   4037             do {
   4038                 PHYMOD_IF_ERR_RETURN(
   4039                         phymod_raw_iblk_read(&acc_cpy, Q28_TOP_GP_REG1, &read_mode));
   4040                 PHYMOD_USLEEP(200);
   4041             } while((retry_cnt--) && (read_mode != fov_mode));
   4042             
   4043             PHYMOD_IF_ERR_RETURN (
   4044                     quadra28_channel_select(&acc_cpy, 0));
   4045             PHYMOD_USLEEP(100000);
   4046 
   4047             acc_cpy.addr |= 4; /* Die 2 soft reset*/
   4048             PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   4049 
   4050             acc_cpy.addr &= ~7;
   4051             /* Soft reset for die 1*/
   4052             PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   4053 
   4054             PHYMOD_USLEEP(200000);
   4055 
   4056             /* Ring reset*/
   4057             acc_cpy.addr &= ~7;
   4058             acc_cpy.addr |= 4;
   4059             PHYMOD_IF_ERR_RETURN(
   4060                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4061             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 1);
   4062             PHYMOD_IF_ERR_RETURN(
   4063                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4064 
   4065             acc_cpy.addr &= ~7;
   4066             PHYMOD_IF_ERR_RETURN(
   4067                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4068             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 1);
   4069             PHYMOD_IF_ERR_RETURN(
   4070                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4071 
   4072             acc_cpy.addr |= 4;
   4073             PHYMOD_IF_ERR_RETURN(
   4074                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4075             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 0);
   4076             PHYMOD_IF_ERR_RETURN(
   4077                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4078 
   4079             acc_cpy.addr &= ~7;
   4080             PHYMOD_IF_ERR_RETURN(
   4081                 BCMI_QUADRA28_READ_RING_CONFIGURATIONr(&acc_cpy, &ring_conf));
   4082             BCMI_QUADRA28_RING_CONFIGURATIONr_RING_SOFTRESETf_SET(ring_conf, 0);
   4083             PHYMOD_IF_ERR_RETURN(
   4084                 BCMI_QUADRA28_WRITE_RING_CONFIGURATIONr(&acc_cpy, ring_conf));
   4085         } else {
   4086             phymod_phy_access_t local_phy;
   4087             int16_t die;
   4088             PHYMOD_MEMCPY(&local_phy, phy, sizeof(phymod_phy_access_t));
   4089             for (die = 1;die >=0; die --) {
   4090                 acc_cpy.addr &= ~7;
   4091                 acc_cpy.addr |= die * 4;
   4092                 PHYMOD_IF_ERR_RETURN (
   4093                         quadra28_channel_select(&acc_cpy, Q28_ALL_LANE));
   4094                 BCMI_QUADRA28_APPS_MODE_2r_SET(aps_mode2, 0);
   4095                 PHYMOD_IF_ERR_RETURN(
   4096                    BCMI_QUADRA28_WRITE_APPS_MODE_2r(&acc_cpy, aps_mode2));
   4097                 PHYMOD_IF_ERR_RETURN(
   4098                         phymod_raw_iblk_write(&acc_cpy,Q28_TOP_GP_REG0,0));
   4099                 aps_mode0.v[0] = 0x8882;   /* As per PGM seq, it works only for SR*/
   4100                 PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,aps_mode0));
   4101                 PHYMOD_IF_ERR_RETURN(
   4102                     _quadra28_intf_update_wait_check(&acc_cpy, aps_mode0.v[0], 50000));
   4103 
   4104                 /*set Write finish mask*/
   4105                 PHYMOD_IF_ERR_RETURN(
   4106                     BCMI_QUADRA28_READ_APPS_MODE_0r(&acc_cpy, &aps_mode0));
   4107                 BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(aps_mode0, 0);
   4108                 PHYMOD_IF_ERR_RETURN(WRITE_APPS_MODE_0r(&acc_cpy,aps_mode0));
   4109                 PHYMOD_IF_ERR_RETURN(
   4110                    _quadra28_intf_update_wait_check(&acc_cpy, aps_mode0.v[0], 50000));
   4111 
   4112                 PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   4113             }
   4114             /* Move to 40G default mode*/
   4115             local_phy.access.addr &= ~0x7;
   4116             PHYMOD_IF_ERR_RETURN(
   4117                    quadra28_set_config_mode(&local_phy, phymodInterfaceSR4, 40000,
   4118                        0, 0xFFFF, 0xFFFF));
   4119             local_phy.port_loc = phymodPortLocSys; 
   4120             PHYMOD_IF_ERR_RETURN(
   4121                    quadra28_set_config_mode(&local_phy, phymodInterfaceXLAUI, 40000,
   4122                        0, 0xFFFF, 0xFFFF));
   4123 
   4124             local_phy.port_loc = phymodPortLocLine; 
   4125             local_phy.access.addr |= 0x4;
   4126             PHYMOD_IF_ERR_RETURN(
   4127                    quadra28_set_config_mode(&local_phy, phymodInterfaceSR4, 40000,
   4128                        0, 0xFFFF, 0xFFFF));
   4129             local_phy.port_loc = phymodPortLocSys; 
   4130             PHYMOD_IF_ERR_RETURN(
   4131                    quadra28_set_config_mode(&local_phy, phymodInterfaceXLAUI, 40000,
   4132                        0,0xFFFF, 0xFFFF));
   4133         }
   4134     } else {
   4135         /* Enable FOV for both the channels on a core*/
   4136         acc_cpy.addr &= (~1);
   4137         PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(&acc_cpy,Q28_TOP_GP_REG0,fov_mode));
   4138         do {
   4139             PHYMOD_IF_ERR_RETURN(
   4140                     phymod_raw_iblk_read(&acc_cpy, Q28_TOP_GP_REG1, &read_mode));
   4141             PHYMOD_USLEEP(200);
   4142         } while((retry_cnt--) && (read_mode != fov_mode));
   4143 
   4144         PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   4145         retry_cnt = 20;
   4146         acc_cpy.addr |= 1;
   4147         PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(&acc_cpy,Q28_TOP_GP_REG0,fov_mode));
   4148         do {
   4149             PHYMOD_IF_ERR_RETURN(
   4150                     phymod_raw_iblk_read(&acc_cpy, Q28_TOP_GP_REG1, &read_mode));
   4151             PHYMOD_USLEEP(200);
   4152         } while((retry_cnt--) && (read_mode != fov_mode));
   4153         PHYMOD_IF_ERR_RETURN(_quadra28_soft_reset(&acc_cpy));
   4154     }
   4155     
   4156     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   4157     return PHYMOD_E_NONE;
   4158 }
   4159 
   4160 int _quadra28_failover_mode_get(const phymod_phy_access_t* phy, phymod_failover_mode_t* failover_mode)
   4161 {
   4162     uint32_t speed = 0;
   4163     uint32_t fov_mode = 0;
   4164     uint8_t datapath = 0;
   4165     phymod_access_t acc_cpy = phy->access;
   4166 
   4167     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   4168     Q28_GET_DATAPATH(&acc_cpy, datapath);
   4169 
   4170     if (datapath == phymodDatapathUll) {
   4171         return PHYMOD_E_CONFIG;
   4172     }
   4173 
   4174     PHYMOD_IF_ERR_RETURN(
   4175          phymod_raw_iblk_read(&acc_cpy, Q28_TOP_GP_REG1, &fov_mode));
   4176     if (fov_mode == 0) {
   4177         *failover_mode = phymodFailovermodeNone; 
   4178     } else {
   4179         *failover_mode = phymodFailovermodeEnable;
   4180     }
   4181 
   4182     return PHYMOD_E_NONE;
   4183 }
   4184 
   4185 int _quadra28_phy_rx_adaptation_resume(const phymod_phy_access_t *phy)
   4186 {
   4187     int lane_map = 0;
   4188     int pkg_side = 0;
   4189     int num_lanes = QUADRA28_MAX_LANE;
   4190     int lane_index = 0;
   4191     SIDE_SELECTIONr_t side_sel_reg_val;
   4192     int pmd_mode = 0;
   4193     uint32_t speed = 0;
   4194     phymod_access_t acc_cpy;
   4195    
   4196     PHYMOD_MEMSET(&side_sel_reg_val, 0 , sizeof(SIDE_SELECTIONr_t));	
   4197     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   4198     Q28_GET_PMD_MODE(&acc_cpy, pmd_mode);
   4199     Q28_10G_PHY_ID_WORK_AROUND(speed, acc_cpy);
   4200 
   4201     /* Get the lane map from phymod access */
   4202     lane_map = PHYMOD_ACC_LANE_MASK(&acc_cpy);
   4203     QUADRA28_GET_LOC(phy, pkg_side);   
   4204     QUADRA28_SELECT_SIDE(&acc_cpy,side_sel_reg_val, pkg_side);   
   4205 
   4206     if (pmd_mode == Q28_SINGLE_PMD) {
   4207         for (lane_index = 0; lane_index < num_lanes; lane_index++) {
   4208             if (((lane_map >> lane_index) & 1) == 0x1) {
   4209                 PHYMOD_IF_ERR_RETURN(
   4210                     quadra28_channel_select(&acc_cpy,
   4211                         ((lane_map == Q28_ALL_LANE)? Q28_ALL_LANE : lane_index)));
   4212 
   4213                 PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 0));
   4214                 if (lane_map == Q28_ALL_LANE) {
   4215                     break;
   4216                 }
   4217             }
   4218         }
   4219     } else {
   4220         PHYMOD_IF_ERR_RETURN(merlin_quadra28_stop_rx_adaptation(&acc_cpy, 0));
   4221     }
   4222 
   4223     QUADRA28_RESET_SIDE_BCST_CTRL(&acc_cpy,side_sel_reg_val, Q28_INTF_LINE);
   4224 
   4225     return PHYMOD_E_NONE;
   4226 }
   4227 
   4228 int _quadra28_phy_gpio_config_set(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t gpio_mode)
   4229 {
   4230     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t gpio_config_ctrl_1;
   4231     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t gpio_config_ctrl_2;
   4232     phymod_access_t acc_cpy;
   4233     uint16_t temp = 0;
   4234     PHYMOD_MEMSET(&gpio_config_ctrl_1, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t));
   4235     PHYMOD_MEMSET(&gpio_config_ctrl_2, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t));
   4236     PHYMOD_MEMSET(&acc_cpy, 0, sizeof(phymod_access_t));
   4237     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   4238 
   4239     if (pin_no > 5) {
   4240         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Q28 has only 5 GPIOs (0 - 5)")));
   4241     }
   4242     PHYMOD_IF_ERR_RETURN(
   4243         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROLr(&acc_cpy, &gpio_config_ctrl_1));
   4244     
   4245     PHYMOD_IF_ERR_RETURN(
   4246         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROL_2r(&acc_cpy, &gpio_config_ctrl_2));
   4247 
   4248     switch (gpio_mode) {
   4249       case phymodGpioModeDisabled:
   4250           return PHYMOD_E_NONE;
   4251       case phymodGpioModeOutput:
   4252           if (pin_no < 2) {
   4253               temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DISf_GET(gpio_config_ctrl_1);
   4254               temp &= ~(1 << pin_no);
   4255               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DISf_SET(gpio_config_ctrl_1,temp);
   4256           } else if (pin_no == 2 || pin_no == 3) {
   4257               temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DISf_GET(gpio_config_ctrl_2);
   4258               temp &= ~(1 << (pin_no - 2));
   4259               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DISf_SET(gpio_config_ctrl_2, temp);
   4260           }  else if (pin_no == 4) {
   4261               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_OPRXLOS_DISf_SET(gpio_config_ctrl_1, 0);
   4262           } else if (pin_no == 5) {
   4263               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_MOD_ABS_DISf_SET(gpio_config_ctrl_1, 0);
   4264           }
   4265 
   4266       break;     
   4267       case phymodGpioModeInput:
   4268           if (pin_no < 2) {
   4269               temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DISf_GET(gpio_config_ctrl_1);
   4270               temp &= ~(1 << pin_no);
   4271               temp |= (1 << pin_no);
   4272               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DISf_SET(gpio_config_ctrl_1,temp);
   4273           } else if (pin_no == 2 || pin_no == 3) {
   4274               temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DISf_GET(gpio_config_ctrl_2);
   4275               temp &= ~(1 << (pin_no - 2));
   4276               temp |= (1 << (pin_no - 2));
   4277               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DISf_SET(gpio_config_ctrl_2, temp);
   4278           }  else if (pin_no == 4) {
   4279               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_OPRXLOS_DISf_SET(gpio_config_ctrl_1, 1);
   4280           } else if (pin_no == 5) {
   4281               BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_MOD_ABS_DISf_SET(gpio_config_ctrl_1, 1);
   4282           }
   4283       break;    
   4284       default:
   4285           return PHYMOD_E_PARAM;
   4286     }
   4287     PHYMOD_IF_ERR_RETURN(
   4288         BCMI_QUADRA28_WRITE_GENERAL_PURPOSE_IO_CONTROLr(&acc_cpy, gpio_config_ctrl_1));
   4289     
   4290     PHYMOD_IF_ERR_RETURN(
   4291         BCMI_QUADRA28_WRITE_GENERAL_PURPOSE_IO_CONTROL_2r(&acc_cpy, gpio_config_ctrl_2));
   4292 
   4293 
   4294     return PHYMOD_E_NONE;
   4295 }
   4296 
   4297 int _quadra28_phy_gpio_config_get(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t* gpio_mode)
   4298 {
   4299     phymod_access_t acc_cpy;
   4300     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t gpio_config_ctrl_1;
   4301     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t gpio_config_ctrl_2;
   4302     uint16_t temp = 0;
   4303     PHYMOD_MEMSET(&gpio_config_ctrl_1, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t));
   4304     PHYMOD_MEMSET(&gpio_config_ctrl_2, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t));
   4305     PHYMOD_MEMSET(&acc_cpy, 0, sizeof(phymod_access_t));
   4306     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   4307 
   4308     if (pin_no > 5) {
   4309         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Q28 has only 5 GPIOs (0 - 5)")));
   4310     }
   4311     PHYMOD_IF_ERR_RETURN(
   4312         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROLr(&acc_cpy, &gpio_config_ctrl_1));
   4313     
   4314     PHYMOD_IF_ERR_RETURN(
   4315         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROL_2r(&acc_cpy, &gpio_config_ctrl_2));
   4316 
   4317     if (pin_no < 2) {
   4318         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DISf_GET(gpio_config_ctrl_1);
   4319         temp = (pin_no == 0) ? (temp & 1) : ((temp & 2) >> 1);
   4320     } else if (pin_no == 2 || pin_no == 3) {
   4321         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DISf_GET(gpio_config_ctrl_2);
   4322         temp = (pin_no == 2) ? (temp & 1) : ((temp & 2) >> 1);
   4323     }  else if (pin_no == 4) {
   4324         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_OPRXLOS_DISf_GET(gpio_config_ctrl_1);
   4325     } else if (pin_no == 5) {
   4326         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_MOD_ABS_DISf_GET(gpio_config_ctrl_1);
   4327     }
   4328     if (temp == 1) {
   4329         *gpio_mode = phymodGpioModeInput;
   4330     } else {
   4331         *gpio_mode = phymodGpioModeOutput;
   4332     }
   4333 
   4334     return PHYMOD_E_NONE;
   4335 }
   4336 
   4337 int _quadra28_phy_gpio_pin_value_set(const phymod_phy_access_t* phy, int pin_no, int value)
   4338 {
   4339     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t gpio_config_ctrl_1;
   4340     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t gpio_config_ctrl_2;
   4341     phymod_access_t acc_cpy;
   4342     uint16_t temp = 0;
   4343     PHYMOD_MEMSET(&gpio_config_ctrl_1, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t));
   4344     PHYMOD_MEMSET(&gpio_config_ctrl_2, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t));
   4345     PHYMOD_MEMSET(&acc_cpy, 0, sizeof(phymod_access_t));
   4346     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   4347 
   4348     if (pin_no > 5) {
   4349         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Q28 has only 5 GPIOs (0 - 5)")));
   4350     }
   4351     PHYMOD_IF_ERR_RETURN(
   4352         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROLr(&acc_cpy, &gpio_config_ctrl_1));
   4353     
   4354     PHYMOD_IF_ERR_RETURN(
   4355         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROL_2r(&acc_cpy, &gpio_config_ctrl_2));
   4356 
   4357     if (pin_no < 2) {
   4358         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DATf_GET(gpio_config_ctrl_1);
   4359         temp &= ~(1 << pin_no);
   4360         temp |= (value << pin_no);
   4361         BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OUT_GP_DATf_SET(gpio_config_ctrl_1,temp);
   4362     } else if (pin_no == 2 || pin_no == 3) {
   4363         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DATf_GET(gpio_config_ctrl_2);
   4364         temp &= ~(1 << (pin_no-2));
   4365         temp |= (value << (pin_no - 2));
   4366         BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_OUT_GP_DATf_SET(gpio_config_ctrl_2, temp);
   4367     }  else if (pin_no == 4) {
   4368         BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_OPT_RX_LOS_OUTf_SET(gpio_config_ctrl_1, value);
   4369     } else if (pin_no == 5) {
   4370         BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_MOD_ABS_OUTf_SET(gpio_config_ctrl_1, value);
   4371     }
   4372     PHYMOD_IF_ERR_RETURN(
   4373         BCMI_QUADRA28_WRITE_GENERAL_PURPOSE_IO_CONTROLr(&acc_cpy, gpio_config_ctrl_1));
   4374     
   4375     PHYMOD_IF_ERR_RETURN(
   4376         BCMI_QUADRA28_WRITE_GENERAL_PURPOSE_IO_CONTROL_2r(&acc_cpy, gpio_config_ctrl_2));
   4377 
   4378     return PHYMOD_E_NONE;
   4379 }
   4380 
   4381 int _quadra28_phy_gpio_pin_value_get(const phymod_phy_access_t* phy, int pin_no, int* value)
   4382 {
   4383     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t gpio_config_ctrl_1;
   4384     BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t gpio_config_ctrl_2;
   4385     phymod_access_t acc_cpy;
   4386     uint16_t temp = 0;
   4387     PHYMOD_MEMSET(&gpio_config_ctrl_1, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_t));
   4388     PHYMOD_MEMSET(&gpio_config_ctrl_2, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_t));
   4389     PHYMOD_MEMSET(&acc_cpy, 0, sizeof(phymod_access_t));
   4390     PHYMOD_MEMCPY(&acc_cpy, &phy->access, sizeof(phymod_access_t));
   4391 
   4392     if (pin_no > 5) {
   4393         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Q28 has only 5 GPIOs (0 - 5)")));
   4394     }
   4395     PHYMOD_IF_ERR_RETURN(
   4396         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROLr(&acc_cpy, &gpio_config_ctrl_1));
   4397     
   4398     PHYMOD_IF_ERR_RETURN(
   4399         BCMI_QUADRA28_READ_GENERAL_PURPOSE_IO_CONTROL_2r(&acc_cpy, &gpio_config_ctrl_2));
   4400 
   4401     if (pin_no < 2) {
   4402         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_IN_GP_DATf_GET(gpio_config_ctrl_1);
   4403         *value = (pin_no == 0)? (temp & 1) : ((temp & 2) >> 1);
   4404     } else if (pin_no == 2 || pin_no == 3) {
   4405         temp = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROL_2r_IN_GP_DATf_GET(gpio_config_ctrl_2);
   4406         *value = (pin_no == 2)? (temp & 1) : ((temp & 2) >> 1);
   4407     }  else if (pin_no == 4) {
   4408         *value = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_IN_OPRXLOS_DATf_GET(gpio_config_ctrl_1);
   4409     } else if (pin_no == 5) {
   4410         *value = BCMI_QUADRA28_GENERAL_PURPOSE_IO_CONTROLr_IN_MOD_ABS_DATf_GET(gpio_config_ctrl_1);
   4411     }
   4412 
   4413     return PHYMOD_E_NONE;
   4414 }
   4415