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

sesto_cfg_seq.c (311485B)


      1 /*
      2 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3 * 
      4 * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5 * 
      6 */
      7 
      8 /*
      9  *         
     10  * 
     11  * This program is the proprietary software of Broadcom Corporation
     12  * and/or its licensors, and may only be used, duplicated, modified
     13  * or distributed pursuant to the terms and conditions of a separate,
     14  * written license agreement executed between you and Broadcom
     15  * (an "Authorized License").  Except as set forth in an Authorized
     16  * License, Broadcom grants no license (express or implied), right
     17  * to use, or waiver of any kind with respect to the Software, and
     18  * Broadcom expressly reserves all rights in and to the Software
     19  * and all intellectual property rights therein.  IF YOU HAVE
     20  * NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS SOFTWARE
     21  * IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
     22  * ALL USE OF THE SOFTWARE.  
     23  *  
     24  * Except as expressly set forth in the Authorized License,
     25  *  
     26  * 1.     This program, including its structure, sequence and organization,
     27  * constitutes the valuable trade secrets of Broadcom, and you shall use
     28  * all reasonable efforts to protect the confidentiality thereof,
     29  * and to use this information only in connection with your use of
     30  * Broadcom integrated circuit products.
     31  *  
     32  * 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS
     33  * PROVIDED "AS IS" AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES,
     34  * REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY,
     35  * OR OTHERWISE, WITH RESPECT TO THE SOFTWARE.  BROADCOM SPECIFICALLY
     36  * DISCLAIMS ANY AND ALL IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY,
     37  * NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES,
     38  * ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
     39  * CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING
     40  * OUT OF USE OR PERFORMANCE OF THE SOFTWARE.
     41  * 
     42  * 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL
     43  * BROADCOM OR ITS LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL,
     44  * INCIDENTAL, SPECIAL, INDIRECT, OR EXEMPLARY DAMAGES WHATSOEVER
     45  * ARISING OUT OF OR IN ANY WAY RELATING TO YOUR USE OF OR INABILITY
     46  * TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF THE
     47  * POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF
     48  * THE AMOUNT ACTUALLY PAID FOR THE SOFTWARE ITSELF OR USD 1.00,
     49  * WHICHEVER IS GREATER. THESE LIMITATIONS SHALL APPLY NOTWITHSTANDING
     50  * ANY FAILURE OF ESSENTIAL PURPOSE OF ANY LIMITED REMEDY.$
     51  */
     52 
     53 #include <phymod/phymod.h>
     54 #include <phymod/phymod_system.h>
     55 #include <phymod/phymod_diagnostics.h>
     56 #include "sesto_address_defines.h"
     57 #include "sesto_reg_structs.h"
     58 #include "sesto_cfg_seq.h"
     59 #include "sesto_serdes/common/srds_api_enum.h"
     60 #include "sesto_serdes/merlin_sesto_src/merlin_sesto_functions.h"
     61 #include "sesto_serdes/falcon_furia_sesto_src/falcon_furia_sesto_functions.h"
     62 #include <phymod/chip/sesto.h>
     63 
     64 extern unsigned char sesto_falcon_ucode[];
     65 extern unsigned char sesto_merlin_ucode[];
     66 extern unsigned int sesto_falcon_ucode_len;
     67 extern unsigned int sesto_merlin_ucode_len;
     68 
     69 int sesto_get_chipid (const phymod_access_t *pa, uint32_t *chipid, uint32_t *rev) 
     70 {
     71     SES_CTRL_CHIP_ID_TYPE_T chipid_lsb;
     72     SES_CTRL_CHIP_REVISION_TYPE_T chipid_msb_rev;
     73     int rv = PHYMOD_E_NONE;
     74 
     75     READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_CHIP_ID_ADR, chipid_lsb.data);
     76     READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_CHIP_REVISION_ADR, chipid_msb_rev.data);
     77 
     78     *chipid = (chipid_lsb.data) | (chipid_msb_rev.fields.chip_id_19_16 << 16);
     79     *rev = chipid_msb_rev.fields.chip_rev;
     80 
     81     PHYMOD_DEBUG_VERBOSE(("CHIP ID: %x REv:%x\n", *chipid, *rev));
     82 
     83 ERR:
     84     return rv;
     85 }
     86 
     87 /**   Wait master message out 
     88  *    This function is to ensure whether master has sent the previous message
     89  *    out successfully 
     90  *
     91  *    @param pa                 Pointer to phymod access structure 
     92  *    @param exp_message        Expected message specified by user  
     93  *    @param poll_time          Poll interval 
     94  *
     95  *    @return PHYMOD_E_NONE     successful function execution 
     96  */
     97 int _sesto_wait_mst_msgout(const phymod_access_t *pa,
     98                             SESTO_MSGOUT_E exp_message,
     99                             int poll_time)
    100 {
    101     int retry_count = SESTO_FW_DLOAD_RETRY_CNT;
    102     SESTO_MSGOUT_E msgout = 0;
    103     SES_GEN_CNTRLS_MSGOUT_TYPE_T msgout_t;
    104     int rv = PHYMOD_E_NONE;
    105     
    106     do {
    107         /* Read general control msg out  Register */
    108         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MSGOUT_ADR, msgout_t.data);
    109         msgout = (SESTO_MSGOUT_E) msgout_t.fields.msgout_val;
    110         /* wait before reading again */
    111         if (poll_time != 0) {
    112             /* sleep for specified useconds*/
    113             PHYMOD_USLEEP(poll_time);
    114         }
    115         retry_count --;
    116     } while ((msgout != exp_message) &&  retry_count);
    117     
    118     if (!retry_count) {
    119         if (exp_message == MSGOUT_PRGRM_DONE) { 
    120             PHYMOD_DEBUG_VERBOSE(("MSG OUT:%x \n",msgout));
    121             SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Fusing Firmware failed")));
    122         } else {
    123             SESTO_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed")));
    124         }
    125     }
    126 
    127 ERR:
    128     return rv;
    129 }
    130 
    131 int _sesto_fw_enable(const phymod_access_t *pa, uint16_t en_dis) 
    132 {
    133     int rv = PHYMOD_E_NONE;
    134 		
    135     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, en_dis);
    136 
    137 ERR:
    138     return rv;
    139 }
    140 int sesto_micro_download(const phymod_access_t *pa, unsigned char *ucode,
    141                          uint32_t len, uint16_t master, uint16_t *chk_sum) 
    142 {
    143     SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_TYPE_T spi_code_load;
    144     SES_MICRO_BOOT_BOOT_POR_TYPE_T  boot_por;
    145     SES_GEN_CNTRLS_MSGIN_TYPE_T   msg_in;
    146     uint16_t num_bytes = 0, j = 0;
    147     uint16_t num_words = 0;
    148     uint16_t check_sum = 0, cnt = SESTO_FW_DLOAD_RETRY_CNT, data = 0;
    149     int rv = PHYMOD_E_NONE;
    150 
    151     PHYMOD_MEMSET(&spi_code_load, 0 , sizeof(SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_TYPE_T));
    152 
    153 	/* Send boot address */
    154     SESTO_IF_ERR_RETURN(
    155         _sesto_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    156     msg_in.data = 0;
    157     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MSGIN_ADR, 
    158                               msg_in.data);
    159     SESTO_IF_ERR_RETURN(
    160         _sesto_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    161     /* when code_broadcast_en is enable and slave_code_download_en is enale
    162      * we need do msg_in and msg_our as MSGOUT_NEXT */
    163     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_ADR, spi_code_load.data);
    164     if (spi_code_load.fields.code_broadcast_en && (!master)) {
    165         msg_in.data = 0;
    166         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MSGIN_ADR,
    167                               msg_in.data);
    168 
    169     SESTO_IF_ERR_RETURN(
    170         _sesto_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    171     }
    172 
    173     /* Calculate the number of words */
    174     num_words = (len) / 2;
    175 
    176     /* Update message in value field with word length */
    177     msg_in.fields.msgin_val = num_words;
    178     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MSGIN_ADR, 
    179                                  msg_in.data);
    180     num_bytes = len;
    181     for (j = 0; j < num_bytes; j += 2) {
    182 /*
    183         SESTO_IF_ERR_RETURN
    184             (_sesto_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    185 */
    186         data = (ucode[j + 1] << 8) | ucode[j];
    187         check_sum ^= ucode[j] ^ ucode[j + 1];
    188     
    189         /* Send next word */
    190         msg_in.fields.msgin_val = data;
    191         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MSGIN_ADR, 
    192                                  msg_in.data);
    193     }
    194     do {
    195 	    /* check download_done flags*/
    196         READ_SESTO_PMA_PMD_REG(pa, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    197         if (master) {
    198             if (boot_por.fields.mst_dwld_done == 1) {
    199                 PHYMOD_DEBUG_VERBOSE(("Master Dload Done\n"));
    200                 break;
    201             }
    202         } else {
    203             if (boot_por.fields.slv_dwld_done == 1) {
    204                 PHYMOD_DEBUG_VERBOSE(("Slave Dload Done\n"));
    205                 break;
    206             }
    207         }
    208     } while (cnt --);
    209 
    210 	/* check checksum */
    211     check_sum = (check_sum == 0) ? 0x600D : check_sum;
    212     if (master)  {
    213         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_MST_RUNNING_BYTE_CNT, mst_running_byte_cnt_val, data);
    214         if (data != num_bytes) {
    215             SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,(_PHYMOD_MSG("Master Dload fail:")));
    216        } 
    217         PHYMOD_DEBUG_VERBOSE(("Master Byte Cnt:%d\n", data));
    218         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_MST_RUNNING_CHKSUM, mst_running_chksum_val, data);
    219         if (check_sum != data) {
    220             SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    221                 (_PHYMOD_MSG("Master Dload chksum Fail")));
    222         } 
    223         PHYMOD_DEBUG_VERBOSE(("Master Chk sum:0x%x\n", data));
    224         *chk_sum = data;
    225     } else {
    226         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_SLV_RUNNING_BYTE_CNT, slv_running_byte_cnt_val, data);
    227         if (data != num_bytes) {
    228             SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    229                     (_PHYMOD_MSG("SLave Dload fail:")));
    230         } 
    231         PHYMOD_DEBUG_VERBOSE(("Slave Byte Cnt:%d\n", data));
    232         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_SLV_RUNNING_CHKSUM, slv_running_chksum_val, data);
    233         if (check_sum != data) {
    234             SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    235                     (_PHYMOD_MSG("Slave Dload chksum fail ")));
    236         } 
    237         PHYMOD_DEBUG_VERBOSE(("Slave cksum Cnt:0x%x\n", data));
    238         *chk_sum = data;
    239     }
    240 
    241 ERR:
    242     return rv;
    243 }
    244 
    245 int _sesto_firmware_download(const phymod_access_t *pm_acc ,
    246                             unsigned char *sesto_master_ucode, unsigned int master_len,
    247                             unsigned char *sesto_slave_ucode, unsigned int slave_len)
    248 {
    249     uint16_t data1 = 0, retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    250     SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_TYPE_T spi_code_load; 
    251     SES_GEN_CNTRLS_GEN_CONTROL2_TYPE_T gen_ctrl2;
    252     SES_MICRO_BOOT_BOOT_POR_TYPE_T   boot_por;
    253     uint16_t mst_check_sum = 0, slv_check_sum = 0;
    254     int rv = PHYMOD_E_NONE;
    255 
    256     PHYMOD_MEMSET(&spi_code_load, 0 , sizeof(SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_TYPE_T));
    257     PHYMOD_MEMSET(&gen_ctrl2, 0 , sizeof(SES_GEN_CNTRLS_GEN_CONTROL2_TYPE_T));
    258     PHYMOD_MEMSET(&boot_por, 0 , sizeof(SES_MICRO_BOOT_BOOT_POR_TYPE_T));
    259 
    260     /* Skip the mst_dwld_down, slv_dwld_done and chip reset check incase broadcast is enabled */
    261     /* Skip the firmware download
    262      *  mst_download, slv_dwld_done bits are set
    263      */
    264     SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_MICRO_SYNC_7, brdcst_en, data1);
    265     if (!data1) {
    266         READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    267         if ((boot_por.fields.mst_dwld_done) &&
    268             (boot_por.fields.slv_dwld_done)) {
    269             return SESTO_FW_ALREADY_DOWNLOADED;
    270         }
    271 
    272         /* Do chip hard reset and Resetting the Cores */
    273         SESTO_IF_ERR_RETURN(
    274             _sesto_core_reset_set(pm_acc, phymodResetModeHard, phymodResetDirectionInOut));
    275     }
    276     /* Put Master under Reset */
    277     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_rstb, 0);
    278     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_ucp_rstb, 0);
    279 
    280     /* Wait for any pending SPI download
    281      * SPI download is not interrupted by Master Reset
    282      * (this is a safety feature) so we need to wait its 
    283      * completion before starting the MDIO Download */
    284     do {
    285         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_busy, data1);
    286         retry_cnt--;
    287     } while((data1 != 0) && (retry_cnt));
    288     if (retry_cnt == 0) {
    289         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    290               (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET")));
    291         return PHYMOD_E_FAIL;
    292     }
    293 
    294     /* Sesto always supports serial mode if Dload
    295      * Master followed by slave 
    296      * Configure master_code_download_en, slave_code_download_en
    297      * and broadcast enable */
    298     spi_code_load.fields.code_broadcast_en = 0;
    299     spi_code_load.fields.master_code_download_en = 1;
    300     spi_code_load.fields.slave_code_download_en = 1;
    301     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_ADR, 
    302                               spi_code_load.data);
    303 
    304     READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_ADR, data1);
    305     spi_code_load.data = data1;
    306     if (spi_code_load.fields.code_broadcast_en != 0 && spi_code_load.fields.master_code_download_en != 1
    307             && spi_code_load.fields.slave_code_download_en != 1) {
    308         return PHYMOD_E_INTERNAL;
    309     }
    310     /* Select SPI Speed*/
    311     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL3, 
    312                            ucspi_slow, 1); 
    313 
    314     /* Check the not downloading branch of the flow digram
    315      * before writing to serboot.
    316      * wait_mst_msgout(chip_cfg, die, MSGOUT_NOT_DWNLD, 1, 0);*/
    317     
    318     /* Read / Write boot_por
    319      *  write to mst_dwld_done and slv_dwld_done.
    320      *  write to spi_port_used
    321      *  write to serboot */
    322     READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    323     
    324     /* Force Master New Download */
    325     boot_por.fields.mst_dwld_done = 0;
    326     /* Force Slave New Download */
    327     boot_por.fields.slv_dwld_done = 0;
    328     boot_por.fields.serboot = 1;
    329     boot_por.fields.spi_port_used = 0;
    330     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, 
    331                           boot_por.data);
    332 
    333     /* RELEASE Master under Reset */
    334     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_ucp_rstb, 1);
    335     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_rstb, 1);
    336 
    337         /* MDI/I2C Download */
    338         /* Waiting for serboot_busy */
    339     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    340     do {
    341         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_busy, data1);
    342             retry_cnt--;
    343         } while ((data1 == 0) && (retry_cnt));
    344     if (retry_cnt == 0) {
    345         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    346               (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET")));
    347         return PHYMOD_E_FAIL;
    348     }
    349     /* Start download sequence */
    350     /* master boot*/
    351     SESTO_IF_ERR_RETURN(
    352        sesto_micro_download(pm_acc, sesto_master_ucode,
    353                              master_len, 1, &mst_check_sum));
    354 
    355     SESTO_IF_ERR_RETURN(
    356        sesto_micro_download(pm_acc, sesto_slave_ucode,
    357                              slave_len, 0, &slv_check_sum));
    358     SESTO_IF_ERR_RETURN(
    359       _sesto_wait_mst_msgout(pm_acc, MSGOUT_DWNLD_DONE, 0));
    360         /*uint16_t checksum = 0;
    361         SESTO_IF_ERR_RETURN(
    362            _sesto_wait_mst_msgout(pm_acc, MSGOUT_DWNLD_DONE, 0));
    363         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_MST_RUNNING_CHKSUM, mst_running_chksum_val, checksum);
    364         PHYMOD_DEBUG_VERBOSE(("Master CheckSum:%x\n",checksum));
    365         
    366         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_SLV_RUNNING_CHKSUM, slv_running_chksum_val, checksum);
    367         PHYMOD_DEBUG_VERBOSE(("Slave CheckSum:%x\n",checksum));
    368     }*/
    369     /* Check serboot_busy and serboot_done_once*/
    370     SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_busy, data1);
    371     if (data1 != 0) {
    372         PHYMOD_DEBUG_ERROR(("WARN:SERBOOT BUSY HAS UNEXPECTED VALUE\n"));
    373     }
    374     SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_done_once, data1);
    375     if (data1 != 1) {
    376         PHYMOD_DEBUG_ERROR(("WARN:SERBOOT DONE ONCE HAS UNEXPECTED VALUE\n"));
    377     }
    378 
    379     /* check download_done flags again */
    380     READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    381     if (boot_por.fields.mst_dwld_done != 1 || boot_por.fields.slv_dwld_done != 1) {
    382         PHYMOD_DEBUG_ERROR(("WARN:Download Done got cleared\n"));
    383     }
    384 
    385     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    386     do {
    387         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data1);
    388         retry_cnt --;
    389     } while ((data1 != 0) && (retry_cnt));
    390     if (retry_cnt == 0) {
    391         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
    392                (_PHYMOD_MSG("Fireware download failed, micro controller is busy..")));
    393     }
    394     READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_FIRMWARE_VERSION_ADR,
    395                                      data1);
    396     PHYMOD_DEBUG_VERBOSE(("FW Version:0x%x\n", data1));
    397 
    398 ERR:
    399     return rv;
    400 }
    401 int _sesto_eeprom_firmware_download(const phymod_access_t *pm_acc ,
    402                             unsigned char *sesto_ucode, unsigned int ucode_len, uint16_t master)
    403 {
    404     uint16_t data1 = 0, retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    405     uint16_t eeprom_num_of_pages = 0;
    406     SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_TYPE_T spi_code_load;
    407     SES_GEN_CNTRLS_GEN_CONTROL2_TYPE_T gen_ctrl2;
    408     SES_MICRO_BOOT_BOOT_POR_TYPE_T   boot_por;
    409     uint16_t check_sum = 0;
    410     int rv = PHYMOD_E_NONE;
    411 
    412     PHYMOD_MEMSET(&spi_code_load, 0 , sizeof(SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_TYPE_T));
    413     PHYMOD_MEMSET(&gen_ctrl2, 0 , sizeof(SES_GEN_CNTRLS_GEN_CONTROL2_TYPE_T));
    414     PHYMOD_MEMSET(&boot_por, 0 , sizeof(SES_MICRO_BOOT_BOOT_POR_TYPE_T));
    415 
    416     /* Do chip hard reset and Resetting the Cores */
    417     SESTO_IF_ERR_RETURN(
    418         _sesto_core_reset_set(pm_acc, phymodResetModeHard, phymodResetDirectionInOut));
    419     /* Put Master under Reset */
    420     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_rstb, 0);
    421     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_ucp_rstb, 0);
    422 
    423     /* Wait for any pending SPI download
    424      * SPI download is not interrupted by Master Reset
    425      * (this is a safety feature) so we need to wait its
    426      * completion before starting the MDIO Download */
    427 
    428     do {
    429         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_busy, data1);
    430         retry_cnt--;
    431     } while((data1 != 0) && (retry_cnt));
    432     if (retry_cnt == 0) {
    433         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    434               (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET")));
    435     }
    436 
    437     /* Sesto always supports serial mode if Dload
    438      * Master followed by slave
    439      * Configure master_code_download_en, slave_code_download_en
    440      * and broadcast enable */
    441     spi_code_load.fields.code_broadcast_en = 1;
    442     spi_code_load.fields.master_code_download_en = 1;
    443     spi_code_load.fields.slave_code_download_en = !master;
    444     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_ADR, spi_code_load.data);
    445 
    446     READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_SPI_CODE_LOAD_EN_ADR, spi_code_load.data);
    447     if (spi_code_load.fields.code_broadcast_en != 1) {
    448         return PHYMOD_E_INTERNAL;
    449     }
    450 
    451     /* Configure GPREG for programming eeprom */
    452     eeprom_num_of_pages = (uint16_t)(ucode_len/SESTO_M0_EEPROM_PAGE_SIZE);
    453     if (eeprom_num_of_pages > 0x1FF) {
    454         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    455               (_PHYMOD_MSG("ERR:No of EEPROM pages more than Code ROM, Fusing does not support")));
    456     }
    457     eeprom_num_of_pages = 0x1FF;
    458 
    459     /* Start Page of EEPROM*/
    460     /* For master start page is "0" and slave start page is "0x200" in eeprom */
    461     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_GPREG14_ADR, (master ? 0 : 0x200));
    462     /* No of eeprom pages */
    463     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_GPREG15_ADR, eeprom_num_of_pages);
    464     /* Select SPI Speed*/
    465     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL3, ucspi_slow, 1);
    466     /* Reset spi */
    467     /* Assert Reset */
    468     READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2_ADR, gen_ctrl2.data);
    469     gen_ctrl2.fields.spi_rstb = 0;
    470     gen_ctrl2.fields.spi2x_rstb = 0;
    471     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2_ADR, gen_ctrl2.data);
    472 
    473     /* Deassert Reset */
    474     gen_ctrl2.fields.spi_rstb = 1;
    475     gen_ctrl2.fields.spi2x_rstb = 1;
    476     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2_ADR, gen_ctrl2.data);
    477 
    478     /* Check the not downloading branch of the flow digram
    479      * before writing to serboot.
    480      * wait_mst_msgout(chip_cfg, die, MSGOUT_NOT_DWNLD, 1, 0);*/
    481     /* Read / Write boot_por
    482      *  write to mst_dwld_done and slv_dwld_done.
    483      *  write to spi_port_used
    484      *  write to serboot */
    485     READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    486 
    487     /* Force Master New Download */
    488     boot_por.fields.mst_dwld_done = 0;
    489     /* Force Slave New Download */
    490     boot_por.fields.slv_dwld_done = 0;
    491     boot_por.fields.serboot = 1;
    492     boot_por.fields.spi_port_used = 0;
    493     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR,
    494                           boot_por.data);
    495 
    496     /* RELEASE Master under Reset */
    497 
    498     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_ucp_rstb, 1);
    499     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2, m0_mstr_rstb, 1);
    500 
    501     /* MDI/I2C Download */
    502     /* Waiting for serboot_busy */
    503     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    504     do {
    505         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_busy, data1);
    506             retry_cnt--;
    507         } while ((data1 == 0) && (retry_cnt));
    508     if (retry_cnt == 0) {
    509         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    510               (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET")));
    511         return PHYMOD_E_FAIL;
    512     }
    513     /* Start download sequence */
    514     /* master boot*/
    515     SESTO_IF_ERR_RETURN(
    516             sesto_micro_download(pm_acc, sesto_ucode,
    517                                  ucode_len, master, &check_sum));
    518     SESTO_IF_ERR_RETURN(
    519             _sesto_wait_mst_msgout(pm_acc, MSGOUT_DWNLD_DONE, 0));
    520 
    521     /* Check serboot_busy and serboot_done_once*/
    522     SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_busy, data1);
    523     if (data1 != 0) {
    524         PHYMOD_DEBUG_ERROR(("WARN:SERBOOT BUSY HAS UNEXPECTED VALUE\n"));
    525     }
    526     SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_BOOT, serboot_done_once, data1);
    527     if (data1 != 1) {
    528         PHYMOD_DEBUG_ERROR(("WARN:SERBOOT DONE ONCE HAS UNEXPECTED VALUE\n"));
    529     }
    530 
    531     /* check download_done flags again */
    532     READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    533     if (boot_por.fields.mst_dwld_done != 1 || boot_por.fields.slv_dwld_done != 1) {
    534         PHYMOD_DEBUG_ERROR(("WARN:Download Done got cleared\n"));
    535     }
    536     /* Wait for Program EEPROM*/
    537     SESTO_IF_ERR_RETURN(
    538         _sesto_wait_mst_msgout(pm_acc, MSGOUT_PRGRM_DONE,0));
    539         /* Assert SPI Reset*/
    540         gen_ctrl2.fields.spi_rstb = 0;
    541         gen_ctrl2.fields.spi2x_rstb = 0;
    542     WRITE_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_GEN_CONTROL2_ADR, gen_ctrl2.data);
    543 
    544     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    545     do {
    546         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data1);
    547         retry_cnt --;
    548     } while ((data1 != 0) && (retry_cnt));
    549     if (retry_cnt == 0) {
    550         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
    551                (_PHYMOD_MSG("Fireware download failed, micro controller is busy..")));
    552     }
    553     READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_FIRMWARE_VERSION_ADR,
    554                                      data1);
    555     PHYMOD_DEBUG_VERBOSE(("FW Version:0x%x\n", data1));
    556 
    557 ERR:
    558     return rv;
    559 }
    560 
    561 int _sesto_core_init(const phymod_core_access_t* core,
    562                      const phymod_core_init_config_t* init_config)
    563 {
    564     int ret_val = 0; 
    565     uint16_t ip = 0;
    566     uint16_t lane = 0, data = 0;
    567     uint16_t max_lane = 0;
    568     uint32_t rev = 0, chip_id = 0;
    569     phymod_access_t pa;
    570     int rv = PHYMOD_E_NONE;
    571     uint16_t retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
    572     const phymod_access_t *pm_acc = &core->access;
    573     DP_FMON0_MAIN_CONTROL_TYPE_T fmon_main_ctrl;
    574     DP_MMON0_MAIN_CONTROL_TYPE_T mmon_main_ctrl;
    575     SES_MICRO_BOOT_BOOT_POR_TYPE_T boot_por;
    576     uint32_t new_fm_version = 0;
    577     phymod_core_firmware_info_t fw_info;
    578 
    579     PHYMOD_MEMSET(&boot_por, 0 , sizeof(SES_MICRO_BOOT_BOOT_POR_TYPE_T));
    580     PHYMOD_MEMSET(&fmon_main_ctrl, 0 , sizeof(DP_FMON0_MAIN_CONTROL_TYPE_T));
    581     PHYMOD_MEMSET(&mmon_main_ctrl, 0 , sizeof(DP_MMON0_MAIN_CONTROL_TYPE_T));
    582     PHYMOD_MEMSET(&fw_info, 0, sizeof(phymod_core_firmware_info_t));
    583 
    584     SESTO_IF_ERR_RETURN(
    585         sesto_core_firmware_info_get(core, &fw_info));
    586     new_fm_version = sesto_falcon_ucode[sesto_falcon_ucode_len - 3];
    587 
    588     switch(init_config->firmware_load_method)
    589     {
    590         case phymodFirmwareLoadMethodInternal:
    591             PHYMOD_DEBUG_VERBOSE((
    592                "Starting Firmware download through MDIO, it takes few seconds...\n"));
    593 
    594             /* In case of FW Download is only for second die i.e for odd address of the die
    595              * To get the micro out of reset on even die(previous die); for MDIO only
    596              * Applicable for only duel die chips;
    597              * SESTO_CHIP_ID_82790 is 82790 is single die ingnore the micro out of reset
    598              */
    599             SESTO_IF_ERR_RETURN(sesto_get_chipid(pm_acc, &chip_id, &rev));
    600             if (((pm_acc->addr & 0x1) == 0x1) && (chip_id != SESTO_CHIP_ID_82790)) {
    601                 PHYMOD_MEMCPY(&pa, pm_acc, sizeof(phymod_access_t));
    602                 /* modify the mdio address to be even */
    603                 pa.addr &= ~(0x1);
    604                 /* Set the 11th and 9th bit of even die to get the micro out of reset */
    605                 SESTO_CHIP_FIELD_WRITE(&pa, SES_PAD_CTRL_EXT_UC_RSTB_OUT_CONTROL, ext_uc_rstb_out_out_frcval, 1);
    606                 SESTO_CHIP_FIELD_WRITE(&pa, SES_PAD_CTRL_EXT_UC_RSTB_OUT_CONTROL, ext_uc_rstb_out_ibof, 1);
    607             }
    608 
    609             if(PHYMOD_CORE_INIT_F_EXECUTE_PASS1_GET(init_config)) {
    610                 /*Dowdload firmware unicast when rev is 0xA0 that does not support broadcast*/
    611                 if(rev == 0xA0){
    612                 /* FW force method is force or Auto with different FW version then do chip reset */
    613                     if (PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_GET(init_config) ||
    614                        (PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_GET(init_config) && (new_fm_version != (fw_info.fw_version & 0xFF)))) {
    615                         /* Do chip hard reset and Resetting the Cores */
    616                         SESTO_IF_ERR_RETURN(
    617                             _sesto_core_reset_set(pm_acc, phymodResetModeHard, phymodResetDirectionInOut));
    618                     }
    619                     /*  Download FW for one core in MDIO bus, This is called for all core if no broadcast */
    620                     ret_val = _sesto_firmware_download(pm_acc,
    621                                       sesto_falcon_ucode, sesto_falcon_ucode_len,
    622                                       sesto_merlin_ucode, sesto_merlin_ucode_len);
    623                     if ((ret_val != PHYMOD_E_NONE) && (ret_val != SESTO_FW_ALREADY_DOWNLOADED)) {
    624                         SESTO_RETURN_WITH_ERR
    625                             (ret_val, (_PHYMOD_MSG("firmware download failed")));
    626                     } else {
    627                         PHYMOD_DEBUG_VERBOSE(("Firmware download through MDIO success\n"));
    628                     }
    629                 }
    630             }
    631 
    632             /*  Broadcast way of FW download sequence
    633              *  1.  Reset core for all cores
    634              *  2.  Enable the broadcast for all the cores
    635              *  3.  Download FW for one core in MDIO bus
    636              *  4.  Disable the broadcast and Verify the FW on all cores
    637              */
    638 
    639             if (PHYMOD_CORE_INIT_F_RESET_CORE_FOR_FW_LOAD_GET(init_config)) {
    640                 /* FW force method is force or Auto with different FW version then do chip reset */
    641                 if (PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_GET(init_config) ||
    642                    (PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_GET(init_config) && (new_fm_version != (fw_info.fw_version & 0xFF)))) {
    643                     /* Do chip hard reset and Resetting the Cores */
    644                     SESTO_IF_ERR_RETURN(
    645                         _sesto_core_reset_set(pm_acc, phymodResetModeHard, phymodResetDirectionInOut));
    646                 }
    647             } else if (PHYMOD_CORE_INIT_F_UNTIL_FW_LOAD_GET(init_config)) {
    648                 /* FW force method is force or Auto with different FW version then do enable broadcast */
    649                 if (PHYMOD_CORE_INIT_F_FW_FORCE_DOWNLOAD_GET(init_config) ||
    650                    (PHYMOD_CORE_INIT_F_FW_AUTO_DOWNLOAD_GET(init_config) && (new_fm_version != (fw_info.fw_version & 0xFF)))) {
    651                     /* Enable broadcast */
    652                     SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_MICRO_SYNC_7, brdcst_en, 1);
    653                 }
    654             } else if (PHYMOD_CORE_INIT_F_EXECUTE_FW_LOAD_GET(init_config)) {
    655                 /*  Download FW for one core in MDIO bus, This is called for all core if no broadcast */
    656                 ret_val = _sesto_firmware_download(pm_acc,
    657                                   sesto_falcon_ucode, sesto_falcon_ucode_len,
    658                                   sesto_merlin_ucode, sesto_merlin_ucode_len);
    659                 if ((ret_val != PHYMOD_E_NONE) && (ret_val != SESTO_FW_ALREADY_DOWNLOADED)) {
    660                     SESTO_RETURN_WITH_ERR
    661                         (ret_val, (_PHYMOD_MSG("firmware download failed")));
    662                 } else {
    663                     PHYMOD_DEBUG_VERBOSE(("Firmware download through MDIO success\n"));
    664                 }
    665             } else if (PHYMOD_CORE_INIT_F_RESUME_AFTER_FW_LOAD_GET(init_config)) {
    666                 /* Disable broadcast */
    667                 SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_MICRO_SYNC_7, brdcst_en, 0);
    668                 /* check download_done flags again */
    669                 READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    670                 if (boot_por.fields.mst_dwld_done != 1 || boot_por.fields.slv_dwld_done != 1) {
    671                     SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    672                         (_PHYMOD_MSG("ERR:Firmware Download Done got cleared")));
    673                 }
    674                 READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_FIRMWARE_VERSION_ADR, data);
    675                 if (data == 0x1) {
    676                     SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    677                         (_PHYMOD_MSG("ERR:Invalid Firmware version Downloaded")));
    678                 }
    679                 SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_MST_RUNNING_CHKSUM, mst_running_chksum_val, data);
    680                 if (0x600D != data) {
    681                     SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    682                         (_PHYMOD_MSG("Master Dload chksum Fail")));
    683                 }
    684                 SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_SLV_RUNNING_CHKSUM, slv_running_chksum_val, data);
    685                 if (0x600D != data) {
    686                     SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    687                         (_PHYMOD_MSG("Slave Dload chksum Fail")));
    688                 }
    689             }
    690         break;
    691         case phymodFirmwareLoadMethodExternal:
    692             return PHYMOD_E_UNAVAIL;
    693         break;        
    694         case phymodFirmwareLoadMethodNone:
    695              /* Expected to download firmware from Flashed EEPROM */
    696              /* Firmware download works only when serboot pin is set on the chip */
    697              READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    698              if (boot_por.fields.serboot) {
    699                  /* check download_done flags again */
    700                  READ_SESTO_PMA_PMD_REG(pm_acc, SES_MICRO_BOOT_BOOT_POR_ADR, boot_por.data);
    701                  if (boot_por.fields.mst_dwld_done != 1 || boot_por.fields.slv_dwld_done != 1) {
    702                      SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    703                          (_PHYMOD_MSG("ERR:Firmware Download Done got cleared")));
    704                  }
    705                  READ_SESTO_PMA_PMD_REG(pm_acc, SES_GEN_CNTRLS_FIRMWARE_VERSION_ADR, data);
    706                  if (data == 0x1) {
    707                      SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    708                          (_PHYMOD_MSG("ERR:Invalid Firmware version Downloaded")));
    709                  }
    710                  SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_MST_RUNNING_CHKSUM, mst_running_chksum_val, data);
    711                  if (0x600D != data) {
    712                      SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    713                          (_PHYMOD_MSG("Master Dload chksum Fail")));
    714                  }
    715                  SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_SLV_RUNNING_CHKSUM, slv_running_chksum_val, data);
    716                  if (0x600D != data) {
    717                      SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
    718                          (_PHYMOD_MSG("Slave Dload chksum Fail")));
    719                  }
    720                  /* This is required When FW is already downloaded(Phy-1956), It will not affect EEPROM 
    721                   * Download*/
    722                  ret_val = SESTO_FW_ALREADY_DOWNLOADED;
    723 
    724              } else {
    725                  PHYMOD_DEBUG_ERROR(("WARN:SERBOOT PIN VALUE IS EXPECTED\n"));
    726              }
    727         break;
    728         case phymodFirmwareLoadMethodProgEEPROM:
    729             /* EEPROM fusing starts with master fallowed by slave ucode b/w hardreset of chip */
    730             /* Master f/w download using mdio and then fusing to eeprom */
    731             PHYMOD_DEBUG_VERBOSE((
    732                "Starting Firmware download through EEPROM, it takes few seconds...\n"));
    733             /* Slave f/w download using mdio and then fusing to eeprom */
    734             ret_val = _sesto_eeprom_firmware_download(pm_acc,
    735                                sesto_merlin_ucode, sesto_merlin_ucode_len, 0);
    736             if ((ret_val != PHYMOD_E_NONE) && (ret_val != SESTO_FW_ALREADY_DOWNLOADED)) {
    737                 SESTO_RETURN_WITH_ERR
    738                     (ret_val,
    739                     (_PHYMOD_MSG("Slave firmware download failed")));
    740             } else {
    741                 PHYMOD_DEBUG_VERBOSE(("Slave Firmware download through EEPROM success\n"));
    742             }
    743 
    744             ret_val = _sesto_eeprom_firmware_download(pm_acc,
    745                                sesto_falcon_ucode, sesto_falcon_ucode_len, 1);
    746             if ((ret_val != PHYMOD_E_NONE) && (ret_val != SESTO_FW_ALREADY_DOWNLOADED)) {
    747                 SESTO_RETURN_WITH_ERR
    748                     (ret_val,
    749                     (_PHYMOD_MSG("Master firmware download failed")));
    750             } else {
    751                 PHYMOD_DEBUG_VERBOSE(("Master Firmware download through EEPROM success\n"));
    752             }
    753         break;
    754         default:
    755             SESTO_RETURN_WITH_ERR
    756                 (PHYMOD_E_CONFIG,
    757                  (_PHYMOD_MSG("illegal fw load method")));
    758     }
    759 
    760     /* Disable PCS moniter at core_init as deafult is enable */
    761     for (ip = SESTO_MERLIN_CORE ; ip <= SESTO_FALCON_CORE ;ip++) {
    762         max_lane = (ip == SESTO_FALCON_CORE) ? SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
    763         for (lane = 0; lane < max_lane; lane ++) {
    764             if (ip == SESTO_FALCON_CORE) {
    765                 READ_SESTO_PMA_PMD_REG(pm_acc, (DP_FMON0_MAIN_CONTROL_ADR + lane), fmon_main_ctrl.data);
    766                 fmon_main_ctrl.fields.fmon0_main_ctrl &= ~(0x1);
    767                 WRITE_SESTO_PMA_PMD_REG(pm_acc, (DP_FMON0_MAIN_CONTROL_ADR + lane), fmon_main_ctrl.data);
    768                 PHYMOD_DEBUG_VERBOSE(("Falcon Link monitor for Lane:%d Data:0x%x\n",
    769                             lane, fmon_main_ctrl.data));
    770             } else {
    771                 READ_SESTO_PMA_PMD_REG(pm_acc, (DP_MMON0_MAIN_CONTROL_ADR + lane), mmon_main_ctrl.data);
    772                 mmon_main_ctrl.fields.mmon0_main_ctrl &= ~(0x1);
    773                 WRITE_SESTO_PMA_PMD_REG(pm_acc, (DP_MMON0_MAIN_CONTROL_ADR + lane), mmon_main_ctrl.data);
    774                 PHYMOD_DEBUG_VERBOSE(("Merlin Link monitor for Lane:%d Data:0x%x\n",
    775                             lane, mmon_main_ctrl.data));
    776             }
    777         }
    778     }
    779     /* This is WAR for chip limitation: Disable the AN during init
    780        as we are not supposed to call interface set while AN is enabled */
    781         SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_GPREG11, an_enable, data);
    782     if (data) {
    783         SESTO_CHIP_FIELD_WRITE(pm_acc, SES_GEN_CNTRLS_GPREG11, an_enable, 0x0);
    784 
    785         /* Enable FW After configuring mode */
    786         SESTO_IF_ERR_RETURN(
    787             _sesto_fw_enable(pm_acc, SESTO_ENABLE));
    788         do {
    789             SESTO_CHIP_FIELD_READ(pm_acc, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data);
    790 
    791             PHYMOD_DEBUG_VERBOSE(("FW Clear:%d\n",data));
    792             retry_cnt--;
    793         } while((data != 0) && (retry_cnt));
    794         if (retry_cnt == 0) {
    795             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT,
    796                     (_PHYMOD_MSG("WARN:: FW Enable not cleared\n")));
    797         }
    798     }
    799 
    800 ERR:
    801     return rv;
    802 }
    803 
    804 int _sesto_set_slice_reg (const phymod_access_t* pm_acc, SESTO_SLICE_CAST_TYPE cast_type, uint16_t ip, uint16_t dev_type,
    805                           uint16_t mcast_val, uint16_t lane)
    806 {
    807     DEV1_SLICE_SLICE_TYPE_T slice_reg;
    808     int rv = PHYMOD_E_NONE;
    809     
    810     PHYMOD_MEMSET(&slice_reg, 0 , sizeof(DEV1_SLICE_SLICE_TYPE_T));
    811 
    812     if (dev_type == SESTO_DEV_PMA_PMD) {
    813         READ_SESTO_PMA_PMD_REG(pm_acc, DEV1_SLICE_SLICE_ADR, slice_reg.data);
    814     } else {
    815         READ_SESTO_AN_REG(pm_acc, DEV7_SLICE_SLICE_ADR, slice_reg.data);
    816     }
    817     slice_reg.fields.ip   = ip;                 
    818     slice_reg.fields.lane = lane;                   
    819     slice_reg.fields.dev = dev_type;                   
    820     if (cast_type == SESTO_SLICE_UNICAST) {
    821         slice_reg.fields.cast = 0;
    822     } else if (cast_type == SESTO_SLICE_MULTICAST) {
    823         slice_reg.fields.cast = mcast_val;
    824     } else { 
    825         slice_reg.fields.cast = 8;
    826     }
    827     if (dev_type == SESTO_DEV_PMA_PMD) {
    828         WRITE_SESTO_PMA_PMD_REG(pm_acc, DEV1_SLICE_SLICE_ADR, slice_reg.data);
    829     } else {
    830         WRITE_SESTO_AN_REG(pm_acc, DEV7_SLICE_SLICE_ADR, slice_reg.data);
    831     }
    832 
    833 ERR:
    834     return rv;
    835 }
    836 
    837 void _sesto_lane_cast_get(const phymod_phy_access_t *phy, SESTO_CORE_TYPE ip,
    838                           uint16_t *cast_type, uint16_t *mcast_val) 
    839 {
    840     const phymod_access_t *pa = &phy->access;
    841 
    842     switch (pa->lane_mask) {
    843         case 3:
    844             *cast_type = SESTO_SLICE_MULTICAST;
    845             *mcast_val = 1;
    846             break;
    847         case 0xc:
    848             *cast_type = SESTO_SLICE_MULTICAST;
    849             *mcast_val = 2;
    850             break;
    851         case 0x30:
    852             if (ip == SESTO_MERLIN_CORE) {
    853                 *cast_type = SESTO_SLICE_MULTICAST;
    854                 *mcast_val = 3;
    855             } else {
    856                 *cast_type = SESTO_CAST_INVALID;
    857             }
    858             break;
    859         case 0xc0:
    860             if (ip == SESTO_MERLIN_CORE) {
    861                 *cast_type = SESTO_SLICE_MULTICAST;
    862                 *mcast_val = 4;
    863             } else {
    864                 *cast_type = SESTO_CAST_INVALID;
    865             }
    866             break;
    867         case 0x300:
    868             if (ip == SESTO_MERLIN_CORE) {
    869                 *cast_type = SESTO_SLICE_MULTICAST;
    870                 *mcast_val = 5;
    871             } else {
    872                 *cast_type = SESTO_CAST_INVALID;
    873             }
    874             break;
    875         case 0xf:
    876             if (ip == SESTO_MERLIN_CORE) {
    877                 *cast_type = SESTO_SLICE_MULTICAST;
    878                 *mcast_val = 6;
    879             } else {
    880                 *cast_type = SESTO_SLICE_BROADCAST;
    881             }
    882             break;
    883         case 0xf0:
    884             if (ip == SESTO_MERLIN_CORE) {
    885                 *cast_type = SESTO_SLICE_MULTICAST;
    886                 *mcast_val = 7;
    887             } else {
    888                 *cast_type = SESTO_CAST_INVALID;
    889             }
    890             break;
    891         case 0x3ff:
    892             if (ip == SESTO_MERLIN_CORE) {
    893                 *cast_type =SESTO_SLICE_BROADCAST; 
    894             } else {
    895                 *cast_type = SESTO_CAST_INVALID;
    896             }
    897             break;
    898         default:
    899             *cast_type = SESTO_SLICE_UNICAST;
    900         break;
    901     }
    902 }
    903 
    904 int _sesto_rx_pmd_lock_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked)
    905 {
    906     phymod_phy_inf_config_t config;
    907     uint16_t ip = 0;
    908     uint16_t lane = 0;
    909     uint16_t temp = 0;
    910     uint16_t lane_mask = 0, max_lane = 0;
    911     const phymod_access_t *pa = &phy->access;
    912     int rv = PHYMOD_E_NONE;
    913 
    914     if (rx_pmd_locked) {
    915         *rx_pmd_locked = 0xffff;
    916     } else {
    917         return PHYMOD_E_PARAM;
    918     }
    919 
    920     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
    921     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
    922     SESTO_IF_ERR_RETURN(
    923        _sesto_phy_interface_config_get(phy, 0, &config));
    924     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
    925     SESTO_GET_IP(phy, config, ip);
    926 
    927     max_lane = (ip == SESTO_FALCON_CORE) ?
    928                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
    929 
    930     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
    931              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
    932 
    933     for (lane = 0; lane < max_lane; lane ++) {
    934         if (lane_mask & (1 << lane)) {
    935             SESTO_IF_ERR_RETURN(
    936               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, 
    937                         ip, SESTO_DEV_PMA_PMD,  0, lane));
    938             if (ip == SESTO_FALCON_CORE) {
    939 	            SESTO_CHIP_FIELD_READ(pa, F25G_TLB_RX_PMD_RX_LOCK_STATUS, pmd_rx_lock, temp);
    940                 *rx_pmd_locked &= temp;
    941             } else {
    942                 SESTO_CHIP_FIELD_READ(pa, M10G_TLB_RX_PMD_RX_LOCK_STATUS, pmd_rx_lock, temp);
    943                 *rx_pmd_locked &= temp;
    944             }
    945         }
    946     }
    947 
    948 ERR:
    949     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
    950     PHYMOD_FREE(config.device_aux_modes);
    951 
    952     return rv;
    953 }
    954 
    955 int sesto_is_lane_mask_set(const phymod_phy_access_t *phy, uint16_t prt,
    956                            const phymod_phy_inf_config_t *config)
    957 {
    958     phymod_phy_inf_config_t cfg;
    959     uint16_t core = 0;
    960     uint32_t lane_mask = 0;
    961     SESTO_DEVICE_AUX_MODE_T  *aux;
    962 
    963     lane_mask = phy->access.lane_mask;
    964     PHYMOD_MEMCPY(&cfg, config, sizeof(phymod_phy_inf_config_t));
    965     aux = (SESTO_DEVICE_AUX_MODE_T*)config->device_aux_modes;
    966     SESTO_GET_IP(phy, cfg, core) ;
    967     PHYMOD_DEBUG_VERBOSE(("%s :: core:%d port:%d\n", __func__, core, prt));
    968     if (core == SESTO_MERLIN_CORE) {
    969         if (cfg.data_rate == SESTO_SPD_40G || cfg.data_rate == SESTO_SPD_42G) {
    970             if (prt == 0) {
    971                 if (aux->pass_thru) {
    972                     if (aux->BCM84793_capablity) {
    973                         return ((lane_mask & 0xf) == 0xF) ? 1 : 0 ;
    974                     } else {
    975                         return ((lane_mask & 0x33) == 0x33) ? 1 : 0 ;
    976                     }
    977                 } else {
    978                     return ((lane_mask & 0xF) == 0xF) ? 1 : 0;
    979                 }
    980             } else {
    981                 if (aux->pass_thru) {
    982                     return 0;
    983                 } else {
    984                     return ((lane_mask & 0xF0) == 0xf0) ? 1 : 0;
    985                 }
    986             }
    987         }
    988         if (cfg.data_rate == SESTO_SPD_20G || cfg.data_rate == SESTO_SPD_21G) {
    989             /* For 20G PT and MUX we are using same lane MAP*/
    990             if (prt == 0) {
    991                 return ((lane_mask & 0x3) == 0x3) ? 1 :0;
    992             } else {
    993                 return ((lane_mask & 0x30) == 0x30) ? 1 :0;
    994             }
    995         }
    996         if (cfg.data_rate == SESTO_SPD_1G || cfg.data_rate == SESTO_SPD_10G || cfg.data_rate == SESTO_SPD_11G) {
    997             /* For 10G PT and MUX we are using same lane MAP*/
    998             if (prt == 0) {
    999                 return (lane_mask & 0x1) ? 1 :0;
   1000             } else if (prt == 1) {
   1001                 return (lane_mask & 0x2) ? 1 :0;
   1002             } else if (prt == 2) {
   1003                 if (aux->BCM84793_capablity) {
   1004                     return (lane_mask & 0x4) ? 1 :0;
   1005                 } else {
   1006                     return (lane_mask & 0x10) ? 1 :0;
   1007                 }
   1008             } else if (prt == 3) {
   1009                 if (aux->BCM84793_capablity) {
   1010                     return (lane_mask & 0x8) ? 1 :0;
   1011                 } else {
   1012                     return (lane_mask & 0x20) ? 1 :0;
   1013                 }
   1014             }
   1015         }
   1016     } else {
   1017         if (cfg.data_rate == SESTO_SPD_40G || cfg.data_rate == SESTO_SPD_42G) {
   1018             if (prt == 0) {
   1019                 if (aux->pass_thru) {
   1020                     return ((lane_mask & 0xf) == 0xF) ? 1 : 0 ;
   1021                 } else {
   1022                     return ((lane_mask & 0x3) == 0x3) ? 1 : 0;
   1023                 }
   1024             } else {
   1025                 if (aux->pass_thru) {
   1026                     return 0;
   1027                 } else {
   1028                     return ((lane_mask & 0xc) == 0xc) ? 1 : 0;
   1029                 }
   1030             }
   1031         }
   1032         if (cfg.data_rate == SESTO_SPD_20G || cfg.data_rate == SESTO_SPD_21G) {
   1033             if (prt == 0) {
   1034                 if (aux->pass_thru) {
   1035                     return ((lane_mask & 0x3) == 0x3) ? 1 :0;
   1036                 } else {
   1037                     return (lane_mask & 0x1) ? 1 :0;
   1038                 }
   1039             } else {
   1040                 if (aux->pass_thru) {
   1041                     return ((lane_mask & 0xc) == 0xc) ? 1 :0;
   1042                 } else {
   1043                     return (lane_mask & 0x4) ? 1 :0;
   1044                 }
   1045             }
   1046         }
   1047         if (cfg.data_rate == SESTO_SPD_1G || cfg.data_rate == SESTO_SPD_10G || cfg.data_rate == SESTO_SPD_11G) {
   1048             /* For 10G PT and MUX we are using same lane MAP*/
   1049             if (prt == 0) {
   1050                 return (lane_mask & 0x1) ? 1 :0;
   1051             } else if (prt == 1) {
   1052                 return (lane_mask & 0x2) ? 1 :0;
   1053             } else if (prt == 2) {
   1054                 return (lane_mask & 0x4) ? 1 :0;
   1055             } else if (prt == 3) {
   1056                 return (lane_mask & 0x8) ? 1 :0;
   1057             }
   1058         }
   1059     }
   1060 
   1061     return 0;
   1062 }
   1063 /** Configure Dut Mode Register
   1064  */
   1065 int _sesto_config_dut_mode_reg(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t* config)
   1066 {
   1067     uint16_t no_of_ports = 0, port_idx = 0;
   1068     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   1069     DP_SESTO_MODE_CTRL0_TYPE_T mode_ctrl0;
   1070     uint16_t core = 0;
   1071     uint16_t is_lane_used = 0;
   1072     phymod_phy_inf_config_t cfg;
   1073     int rv = PHYMOD_E_NONE;
   1074 
   1075     PHYMOD_MEMSET(&mode_ctrl0, 0, sizeof(DP_SESTO_MODE_CTRL0_TYPE_T));
   1076     PHYMOD_MEMCPY(&cfg, config, sizeof(phymod_phy_inf_config_t));
   1077     SESTO_GET_IP(phy, cfg, core);
   1078 
   1079     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)config->device_aux_modes;
   1080     SESTO_GET_PORT_FROM_MODE(config, no_of_ports, aux_mode);
   1081 
   1082     if (config->data_rate != SESTO_SPD_100G && config->data_rate != SESTO_SPD_106G) {
   1083         READ_SESTO_PMA_PMD_REG(&phy->access, DP_SESTO_MODE_CTRL0_ADR, mode_ctrl0.data);
   1084         for (port_idx=0; port_idx < no_of_ports; port_idx++) {
   1085             if(config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G || config->data_rate == SESTO_SPD_11G) {
   1086                 if ((aux_mode->BCM84793_capablity && core == SESTO_MERLIN_CORE) || core == SESTO_FALCON_CORE) {
   1087                     if (phy->access.lane_mask & (1 << port_idx)) {
   1088                        is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1089                     } else {
   1090                        continue;
   1091                     }
   1092                 } else { /*  For non BCM84793 with Merlin*/
   1093                     if (phy->access.lane_mask & (1 << ((port_idx < 2) ? port_idx : (port_idx + 2)))) {
   1094                        is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1095                     } else {
   1096                        continue;
   1097                     }
   1098                 }
   1099             } else if((config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_42G) && (!aux_mode->pass_thru)) {
   1100                 if (core == SESTO_MERLIN_CORE) {
   1101                     /* MUX Mode*/
   1102                     if (phy->access.lane_mask & (0xF << (port_idx*4))) {
   1103                         is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1104                     } else {
   1105                        continue;
   1106                     }
   1107                 } else {
   1108                     if (phy->access.lane_mask & (0x3 << (port_idx * 2))) {
   1109                         is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1110                     } else {
   1111                         continue;
   1112                     }
   1113                 }
   1114            } else if(config->data_rate == SESTO_SPD_20G || config->data_rate == SESTO_SPD_21G) {
   1115                if (aux_mode->pass_thru) {
   1116                    if (core == SESTO_MERLIN_CORE) {
   1117                        if (phy->access.lane_mask & (0x3 << (port_idx * 4))) {
   1118                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1119                        } else {
   1120                            continue;
   1121                        }
   1122                    } else {
   1123                        if (phy->access.lane_mask & (0x3 << (port_idx * 2))) {
   1124                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1125                        } else {
   1126                            continue;
   1127                        }
   1128                    }
   1129                } else { /* MUX mode*/
   1130                    if (core == SESTO_MERLIN_CORE) {
   1131                        if (phy->access.lane_mask & (0x3 << (port_idx * 4))) {
   1132                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1133                        } else {
   1134                            continue;
   1135                        }
   1136                    } else { /* Falcon*/
   1137                        if (phy->access.lane_mask & (0x1 << (port_idx * 2))) {
   1138                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1139                        } else {
   1140                            continue;
   1141                        }
   1142                    }
   1143                }
   1144            } else {
   1145                 is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1146            }
   1147            if (!is_lane_used) {
   1148                 return PHYMOD_E_PARAM;
   1149            }
   1150            
   1151             /* Program Modes */
   1152             if (((config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_20G ||
   1153                   config->data_rate == SESTO_SPD_42G || config->data_rate == SESTO_SPD_21G) && (port_idx == 0)) ||
   1154                  ((config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G ||
   1155                    config->data_rate == SESTO_SPD_11G) && (port_idx < 2))) {
   1156                 if (config->data_rate == SESTO_SPD_40G || (config->data_rate == SESTO_SPD_42G)) {
   1157                         mode_ctrl0.fields.mode_multiport1_40g_mux = !(aux_mode->pass_thru);
   1158                         /* Clearing the 20G PT & MUX bits and 10G bits*/
   1159                         mode_ctrl0.fields.mode_multiport1_20g_passthru = 0;
   1160                         mode_ctrl0.fields.mode_multiport1_20g_mux = 0; 
   1161                         mode_ctrl0.fields.mode_multiport1_10g1 = 0;
   1162                         mode_ctrl0.fields.mode_multiport1_10g2 = 0;
   1163                 }
   1164                 if (config->data_rate == SESTO_SPD_20G || config->data_rate == SESTO_SPD_21G) {
   1165                     if (aux_mode->pass_thru) {
   1166                        mode_ctrl0.fields.mode_multiport1_20g_passthru = aux_mode->pass_thru;
   1167                        mode_ctrl0.fields.mode_multiport1_20g_mux = 0;
   1168                     } else {
   1169                        mode_ctrl0.fields.mode_multiport1_20g_mux = 1;
   1170                         mode_ctrl0.fields.mode_multiport1_20g_passthru = 0;
   1171                     }
   1172                     /* Clearing the 40G Mux and 20G PT & MUX bits */
   1173                     mode_ctrl0.fields.mode_multiport1_40g_mux = 0;
   1174                     mode_ctrl0.fields.mode_multiport1_10g1 = 0;
   1175                     mode_ctrl0.fields.mode_multiport1_10g2 = 0;
   1176                 }
   1177                 if (config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G || config->data_rate == SESTO_SPD_11G) {
   1178                     if (phy->access.lane_mask & 0x1) {
   1179                         mode_ctrl0.fields.mode_multiport1_10g1 = 1;
   1180                     } if (phy->access.lane_mask & 0x2) {
   1181                         mode_ctrl0.fields.mode_multiport1_10g2 = 1;
   1182                     }
   1183                     /* Clearing the 40G Mux and 20G PT & MUX bits */
   1184                     mode_ctrl0.fields.mode_multiport1_40g_mux = 0;
   1185                     mode_ctrl0.fields.mode_multiport1_20g_passthru = 0;
   1186                     mode_ctrl0.fields.mode_multiport1_20g_mux = 0; 
   1187                 }
   1188             } else {
   1189                 if (config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_42G) {
   1190                     mode_ctrl0.fields.mode_multiport2_40g_mux = !(aux_mode->pass_thru);
   1191                     /* Clearing the 20G PT & MUX bits and 10G bits*/
   1192                     mode_ctrl0.fields.mode_multiport2_20g_passthru = 0;
   1193                     mode_ctrl0.fields.mode_multiport2_20g_mux = 0;
   1194                     mode_ctrl0.fields.mode_multiport2_10g1 = 0;
   1195                     mode_ctrl0.fields.mode_multiport2_10g2 = 0;
   1196                 }
   1197                 if (config->data_rate == SESTO_SPD_20G || config->data_rate == SESTO_SPD_21G) {
   1198                     if (aux_mode->pass_thru) {
   1199                         mode_ctrl0.fields.mode_multiport2_20g_passthru = aux_mode->pass_thru;
   1200                         mode_ctrl0.fields.mode_multiport2_20g_mux = 0;
   1201                     } else {
   1202                         mode_ctrl0.fields.mode_multiport2_20g_mux = 1;
   1203                         mode_ctrl0.fields.mode_multiport2_20g_passthru = 0;
   1204                     }
   1205                     mode_ctrl0.fields.mode_multiport2_40g_mux = 0;
   1206                     mode_ctrl0.fields.mode_multiport2_10g1 = 0;
   1207                     mode_ctrl0.fields.mode_multiport2_10g2 = 0;
   1208                 }
   1209                 if (config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G || config->data_rate == SESTO_SPD_11G) {
   1210                     if ((phy->access.lane_mask & 0x4) || (phy->access.lane_mask & 0x10)) {
   1211                         mode_ctrl0.fields.mode_multiport2_10g1 = 1;
   1212                     } if ((phy->access.lane_mask & 0x8) || (phy->access.lane_mask & 0x20)) {
   1213                         mode_ctrl0.fields.mode_multiport2_10g2 = 1;
   1214                     }
   1215                     /* Clearing the 40G Mux and 20G PT & MUX bits */
   1216                     mode_ctrl0.fields.mode_multiport2_40g_mux = 0;
   1217                     mode_ctrl0.fields.mode_multiport2_20g_passthru = 0;
   1218                     mode_ctrl0.fields.mode_multiport2_20g_mux = 0; 
   1219                 }
   1220             }
   1221         }
   1222     }
   1223     mode_ctrl0.fields.mode_falcon_line = (aux_mode->passthru_sys_side_core == SESTO_MERLIN_CORE) ?
   1224                                                           SESTO_FALCON_CORE : SESTO_MERLIN_CORE;
   1225 
   1226     mode_ctrl0.fields.mode_enzo_combatible_en = aux_mode->BCM84793_capablity;
   1227     mode_ctrl0.fields.mode_100g_gbox_en = (config->data_rate == SESTO_SPD_100G || config->data_rate == SESTO_SPD_106G) ? 1 : 0;
   1228     mode_ctrl0.fields.mode_40g_passthru_en = (config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_42G) &&
   1229                                              (aux_mode->pass_thru);
   1230 
   1231     PHYMOD_DEBUG_VERBOSE(("MODE CTRL0 :0x%x\n", mode_ctrl0.data));
   1232 
   1233     WRITE_SESTO_PMA_PMD_REG(&phy->access, DP_SESTO_MODE_CTRL0_ADR, mode_ctrl0.data);
   1234 
   1235 ERR:
   1236     return rv;
   1237 }
   1238 
   1239 int _sesto_toggle_mer_fal_lane_reset(const phymod_access_t *pa) 
   1240 {
   1241     int rv = PHYMOD_E_NONE;
   1242 
   1243     SESTO_CHIP_FIELD_WRITE(pa, DP_FAL_MER_LINE_SIDE_RESET_CONTROL1, mer_ln_h_rstb, 0);
   1244     SESTO_CHIP_FIELD_WRITE(pa, DP_FAL_MER_LINE_SIDE_RESET_CONTROL1, fal_ln_h_rstb, 0);
   1245     
   1246     PHYMOD_USLEEP(100);
   1247     SESTO_CHIP_FIELD_WRITE(pa, DP_FAL_MER_LINE_SIDE_RESET_CONTROL1, mer_ln_h_rstb, 0x3ff);
   1248     SESTO_CHIP_FIELD_WRITE(pa, DP_FAL_MER_LINE_SIDE_RESET_CONTROL1, fal_ln_h_rstb, 0xf);
   1249 
   1250 ERR:
   1251     return rv;
   1252 }
   1253 
   1254 /** Configure Dut Mode Register
   1255  */
   1256 int _sesto_udms_config(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t* config,
   1257                         SESTO_AN_MODE mode)
   1258 {
   1259     uint16_t no_of_ports = 0, port_idx = 0;
   1260     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   1261     DP_SESTO_MODE_CTRL1_TYPE_T mode_ctrl1;
   1262     phymod_phy_inf_config_t cfg;
   1263     uint16_t core = 0;
   1264     uint16_t is_lane_used = 0;
   1265     int rv = PHYMOD_E_NONE;
   1266 
   1267     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)config->device_aux_modes;
   1268     PHYMOD_MEMSET(&mode_ctrl1, 0, sizeof(DP_SESTO_MODE_CTRL1_TYPE_T));
   1269     PHYMOD_MEMCPY(&cfg, config, sizeof(phymod_phy_inf_config_t));
   1270     SESTO_GET_PORT_FROM_MODE(config, no_of_ports, aux_mode);
   1271     SESTO_GET_IP(phy, cfg, core);
   1272 
   1273     if (config->data_rate != SESTO_SPD_100G && config->data_rate != SESTO_SPD_106G) {
   1274         for (port_idx=0; port_idx < no_of_ports; port_idx++) {
   1275             if(config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G || config->data_rate == SESTO_SPD_11G) {
   1276                 if ((aux_mode->BCM84793_capablity && core == SESTO_MERLIN_CORE) || core == SESTO_FALCON_CORE) {
   1277                     if (phy->access.lane_mask & (1 << port_idx)) {
   1278                        is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1279                     } else {
   1280                        continue;
   1281                     }
   1282                 } else { /*  For non BCM84793 with Merlin*/
   1283                     if (phy->access.lane_mask & (1 << ((port_idx < 2) ? port_idx : (port_idx + 2)))) {
   1284                        is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1285                     } else {
   1286                        continue;
   1287                     }
   1288                 }
   1289             } else if((config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_42G) && (!aux_mode->pass_thru)) {
   1290                 if (core == SESTO_MERLIN_CORE) {
   1291                     /* MUX Mode*/
   1292                     if (phy->access.lane_mask & (0xF << (port_idx*4))) {
   1293                         is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1294                     } else {
   1295                        continue;
   1296                     }
   1297                 } else {
   1298                     if (phy->access.lane_mask & (0x3 << (port_idx * 2))) {
   1299                         is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1300                     } else {
   1301                         continue;
   1302                     }
   1303                 }
   1304            } else if(config->data_rate == SESTO_SPD_20G || config->data_rate == SESTO_SPD_21G) {
   1305                if (aux_mode->pass_thru) {
   1306                    if (core == SESTO_MERLIN_CORE) {
   1307                        if (phy->access.lane_mask & (0x3 << (port_idx * 4))) {
   1308                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1309                        } else {
   1310                            continue;
   1311                        }
   1312                    } else {
   1313                        if (phy->access.lane_mask & (0x3 << (port_idx * 2))) {
   1314                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1315                        } else {
   1316                            continue;
   1317                        }
   1318                    }
   1319                } else { /* MUX mode*/
   1320                    if (core == SESTO_MERLIN_CORE) {
   1321                        if (phy->access.lane_mask & (0x3 << (port_idx * 4))) {
   1322                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1323                        } else {
   1324                            continue;
   1325                        }
   1326                    } else { /* Falcon*/
   1327                        if (phy->access.lane_mask & (0x1 << (port_idx * 2))) {
   1328                            is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1329                        } else {
   1330                            continue;
   1331                        }
   1332                    }
   1333                }
   1334            } else {
   1335                 is_lane_used =  sesto_is_lane_mask_set(phy, port_idx, config);
   1336            }
   1337            if (!is_lane_used) {
   1338                 return PHYMOD_E_PARAM;
   1339            }
   1340 
   1341             READ_SESTO_PMA_PMD_REG(&phy->access, DP_SESTO_MODE_CTRL1_ADR, mode_ctrl1.data);
   1342             /* Program Modes */
   1343             if (((config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_20G ||
   1344                   config->data_rate == SESTO_SPD_42G || config->data_rate == SESTO_SPD_21G) && (port_idx == 0)) ||
   1345                   ((config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G ||
   1346                     config->data_rate == SESTO_SPD_11G) && (port_idx < 2))) {
   1347                 mode_ctrl1.fields.udms_en1 = (mode == SESTO_AN_NONE || mode == SESTO_AN_CL73) ? 1 : 0;
   1348                 if (config->data_rate == SESTO_SPD_20G || config->data_rate == SESTO_SPD_21G ||
   1349                     config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_42G) {
   1350                     mode_ctrl1.fields.mode_dmept1_en = (mode == SESTO_AN_PROP) ? 1 : 0;
   1351                 } else if(config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G || config->data_rate == SESTO_SPD_11G) {
   1352                     if (phy->access.lane_mask & 0x1) {
   1353                         mode_ctrl1.fields.mode_dmept1_en = (mode == SESTO_AN_PROP) ? 1 : 0;
   1354                     } else if (phy->access.lane_mask & 0x2) {
   1355                         mode_ctrl1.fields.mode_dmept1b_en = (mode == SESTO_AN_PROP) ? 1 : 0;
   1356                     }
   1357                 }
   1358             } else {
   1359                 mode_ctrl1.fields.udms_en2 = (mode == SESTO_AN_NONE || mode == SESTO_AN_CL73) ? 1 : 0;
   1360                 if (config->data_rate == SESTO_SPD_20G || config->data_rate == SESTO_SPD_21G ||
   1361                     config->data_rate == SESTO_SPD_40G || config->data_rate == SESTO_SPD_42G) {
   1362                     mode_ctrl1.fields.mode_dmept2_en = (mode == SESTO_AN_PROP) ? 1 : 0;
   1363                 } else if(config->data_rate == SESTO_SPD_1G || config->data_rate == SESTO_SPD_10G || config->data_rate == SESTO_SPD_11G) {
   1364                     if (phy->access.lane_mask & 0x1) {
   1365                         mode_ctrl1.fields.mode_dmept2_en = (mode == SESTO_AN_PROP) ? 1 : 0;
   1366                     } else if (phy->access.lane_mask & 0x2) {
   1367                         mode_ctrl1.fields.mode_dmept2b_en = (mode == SESTO_AN_PROP) ? 1 : 0;
   1368                     }
   1369                 }
   1370             }
   1371         }
   1372     } else {
   1373         mode_ctrl1.fields.udms_en1 = (mode == SESTO_AN_NONE || mode == SESTO_AN_CL73) ? 1 : 0;
   1374     }
   1375     PHYMOD_DEBUG_VERBOSE(("MODE CTRL1 :0x%x\n", mode_ctrl1.data));
   1376     WRITE_SESTO_PMA_PMD_REG(&phy->access, DP_SESTO_MODE_CTRL1_ADR, mode_ctrl1.data);
   1377 
   1378 ERR:
   1379     return rv;
   1380 }
   1381 
   1382 int _sesto_interface_set(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t* config)
   1383 {
   1384     uint16_t phy_type = 0;
   1385     uint16_t media_type = 2, ip = 0; /* Default to optical */
   1386     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   1387     SES_GEN_CNTRLS_GPREG11_TYPE_T   gpreg11;
   1388     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T intf_sel_spd;
   1389     SES_GEN_CNTRLS_MICRO_SYNC_5_TYPE_T intf_sel_p0_p1;
   1390     SES_GEN_CNTRLS_MICRO_SYNC_6_TYPE_T intf_sel_p2_p3;
   1391     phymod_phy_inf_config_t cpy_config;
   1392     uint16_t intf = config->interface_type;
   1393     const phymod_access_t *pa = &phy->access;
   1394     uint16_t dfe_en = 0, dfe_lp_en = 0;
   1395     uint16_t port = 0, no_of_ports = 0;
   1396     uint16_t scrambling_dis = 0;
   1397     int rv = PHYMOD_E_NONE;
   1398 
   1399     PHYMOD_MEMSET(&gpreg11, 0, sizeof(gpreg11));
   1400     PHYMOD_MEMSET(&intf_sel_spd, 0, sizeof(intf_sel_spd));
   1401     PHYMOD_MEMSET(&intf_sel_p0_p1, 0, sizeof(intf_sel_p0_p1));
   1402     PHYMOD_MEMSET(&intf_sel_p2_p3, 0, sizeof(intf_sel_p2_p3));
   1403 
   1404     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)config->device_aux_modes;
   1405     PHYMOD_MEMCPY(&cpy_config, config, sizeof(phymod_phy_inf_config_t));
   1406     SESTO_GET_IP(phy, cpy_config, ip);
   1407     SESTO_GET_PORT_FROM_MODE(config, no_of_ports, aux_mode);
   1408     SESTO_IF_ERR_RETURN(_sesto_port_from_lane_map_get(phy, config, &port));
   1409 
   1410     if (intf == phymodInterfaceSR4 || intf == phymodInterfaceSR10 ||
   1411         intf == phymodInterfaceER4 || intf == phymodInterfaceLR10 ||
   1412         intf == phymodInterfaceSR2 || intf == phymodInterfaceLR2 ||
   1413         intf == phymodInterfaceER2 || intf == phymodInterfaceLR ||
   1414         intf == phymodInterfaceSR || intf == phymodInterfaceER ||
   1415         intf == phymodInterfaceSFI || intf == phymodInterfaceXLPPI) {
   1416         media_type = 2; /*OPTICAL*/
   1417         dfe_en = 0;
   1418         dfe_lp_en = 0;
   1419     } else if (intf == phymodInterfaceCR4 || intf == phymodInterfaceCR ||
   1420                intf == phymodInterfaceCR2 || intf == phymodInterfaceCR10) {
   1421         media_type = 1; /*Copper*/
   1422         dfe_en = 1;
   1423         dfe_lp_en = 0;
   1424     } else if (intf == phymodInterfaceKR4 || intf == phymodInterfaceKR ||
   1425                intf == phymodInterfaceKR2 || intf == phymodInterfaceKR10) {
   1426         media_type = 0; /* Back plane */
   1427         dfe_en = 1;
   1428         dfe_lp_en = 0;
   1429     } else if (intf == phymodInterfaceCAUI4 || intf == phymodInterfaceVSR ||
   1430                intf == phymodInterfaceCAUI || intf == phymodInterfaceCAUI4_C2M ||
   1431                intf == phymodInterfaceCAUI4_C2C) {
   1432         media_type = 0; /* Back plane */
   1433         dfe_en = 1;
   1434         dfe_lp_en = 1;
   1435     } else if (intf == phymodInterfaceXLAUI2 || intf == phymodInterfaceXLAUI ||
   1436                intf == phymodInterfaceXFI) {
   1437         media_type = 0; /* Back plane */
   1438         dfe_en = 0;
   1439         dfe_lp_en = 0;
   1440     } else if (intf == phymodInterfaceLR4) {
   1441         media_type = 2; /*OPTICAL*/
   1442         dfe_en = 0;
   1443         dfe_lp_en = 0;
   1444         if (config->data_rate == SESTO_SPD_100G || config->data_rate == SESTO_SPD_106G) {
   1445             dfe_en = 1;
   1446         }
   1447     } else {
   1448         SESTO_RETURN_WITH_ERR(PHYMOD_E_PARAM,
   1449                (_PHYMOD_MSG("Invalid interface type..")));
   1450     }
   1451 
   1452     /* For 1G support */
   1453     if (config->data_rate == SESTO_SPD_1G) {
   1454         scrambling_dis = 1;
   1455     }
   1456 
   1457     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1458     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1459     if (no_of_ports == 1) { /* 100G/40GPT */
   1460         if (ip == SESTO_MERLIN_CORE) {
   1461             intf_sel_p0_p1.fields.p0_10g_media_type = media_type;
   1462             intf_sel_p0_p1.fields.p0_10g_dfe_on = dfe_en;
   1463             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1464             /* 100G/40GPT has only one port clearing the MICRO_SYNC_6 */
   1465             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, 0x0);
   1466         } else {
   1467             intf_sel_p0_p1.fields.p0_20g_media_type = media_type;
   1468             intf_sel_p0_p1.fields.p0_20g_dfe_on = dfe_en;
   1469             intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode = dfe_lp_en;
   1470             intf_sel_p0_p1.fields.p0_scrambling_dis = scrambling_dis; 
   1471             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1472             /* 100G/40GPT has only one port clearing the MICRO_SYNC_6 */
   1473             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, 0x0);
   1474         }
   1475     } else if (no_of_ports == 2) { /* 40GMUX/20GMUX/20PT */
   1476         if (port == 0) {
   1477             if (ip == SESTO_MERLIN_CORE) {
   1478                 intf_sel_p0_p1.fields.p0_10g_media_type = media_type;
   1479                 intf_sel_p0_p1.fields.p0_10g_dfe_on = dfe_en;
   1480                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1481             } else {
   1482                 intf_sel_p0_p1.fields.p0_20g_media_type = media_type;
   1483                 intf_sel_p0_p1.fields.p0_20g_dfe_on = dfe_en;
   1484                 intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode = dfe_lp_en;
   1485                 intf_sel_p0_p1.fields.p0_scrambling_dis = scrambling_dis;
   1486                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1487             }
   1488         } else {
   1489             if (ip == SESTO_MERLIN_CORE) {
   1490                 intf_sel_p2_p3.fields.p2_10g_media_type = media_type;
   1491                 intf_sel_p2_p3.fields.p2_10g_dfe_on = dfe_en;
   1492                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1493             } else {
   1494                 intf_sel_p2_p3.fields.p2_20g_media_type = media_type;
   1495                 intf_sel_p2_p3.fields.p2_20g_dfe_on = dfe_en;
   1496                 intf_sel_p2_p3.fields.p2_20g_dfe_lp_mode = dfe_lp_en;
   1497                 intf_sel_p2_p3.fields.p2_scrambling_dis = scrambling_dis;
   1498                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1499             }
   1500         }
   1501     } else { /* 10G */
   1502         if (port == 0) {
   1503             if (ip == SESTO_MERLIN_CORE) {
   1504                 intf_sel_p0_p1.fields.p0_10g_media_type = media_type;
   1505                 intf_sel_p0_p1.fields.p0_10g_dfe_on = dfe_en;
   1506                 intf_sel_p0_p1.fields.p0_scrambling_dis = scrambling_dis;
   1507                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1508             } else {
   1509                 intf_sel_p0_p1.fields.p0_20g_media_type = media_type;
   1510                 intf_sel_p0_p1.fields.p0_20g_dfe_on = dfe_en;
   1511                 intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode = dfe_lp_en;
   1512                 intf_sel_p0_p1.fields.p0_scrambling_dis = scrambling_dis;
   1513                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1514             }
   1515         } else if (port == 1) {
   1516             if (ip == SESTO_MERLIN_CORE) {
   1517                 intf_sel_p0_p1.fields.p1_10g_media_type = media_type;
   1518                 intf_sel_p0_p1.fields.p1_10g_dfe_on = dfe_en;
   1519                 intf_sel_p0_p1.fields.p1_scrambling_dis = scrambling_dis;
   1520                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1521             } else {
   1522                 intf_sel_p0_p1.fields.p1_20g_media_type = media_type;
   1523                 intf_sel_p0_p1.fields.p1_20g_dfe_on = dfe_en;
   1524                 intf_sel_p0_p1.fields.p1_20g_dfe_lp_mode = dfe_lp_en;
   1525                 intf_sel_p0_p1.fields.p1_scrambling_dis = scrambling_dis;
   1526                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   1527             }
   1528         } else if (port == 2) {
   1529             if (ip == SESTO_MERLIN_CORE) {
   1530                 intf_sel_p2_p3.fields.p2_10g_media_type = media_type;
   1531                 intf_sel_p2_p3.fields.p2_10g_dfe_on = dfe_en;
   1532                 intf_sel_p2_p3.fields.p2_scrambling_dis = scrambling_dis;
   1533                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1534             } else {
   1535                 intf_sel_p2_p3.fields.p2_20g_media_type = media_type;
   1536                 intf_sel_p2_p3.fields.p2_20g_dfe_on = dfe_en;
   1537                 intf_sel_p2_p3.fields.p2_20g_dfe_lp_mode = dfe_lp_en;
   1538                 intf_sel_p2_p3.fields.p2_scrambling_dis = scrambling_dis;
   1539                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1540             }
   1541         } else {
   1542             if (ip == SESTO_MERLIN_CORE) {
   1543                 intf_sel_p2_p3.fields.p3_10g_media_type = media_type;
   1544                 intf_sel_p2_p3.fields.p3_10g_dfe_on = dfe_en;
   1545                 intf_sel_p2_p3.fields.p3_scrambling_dis = scrambling_dis;
   1546                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1547             } else {
   1548                 intf_sel_p2_p3.fields.p3_20g_media_type = media_type;
   1549                 intf_sel_p2_p3.fields.p3_20g_dfe_on = dfe_en;
   1550                 intf_sel_p2_p3.fields.p3_20g_dfe_lp_mode = dfe_lp_en;
   1551                 intf_sel_p2_p3.fields.p3_scrambling_dis = scrambling_dis;
   1552                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   1553             }
   1554         }
   1555     }  
   1556 
   1557     if (PHYMOD_INTF_MODES_OTN_GET(config)) {
   1558         phy_type = 1;
   1559     } else if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   1560         phy_type = 2;
   1561     } else {
   1562         phy_type = 0; /* Default to ethernet mode*/
   1563     }
   1564     /* Configure PHY Type*/
   1565     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   1566     gpreg11.fields.phy_type = phy_type;
   1567     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   1568 
   1569     /* SES_GEN_CNTRLS_MICRO_SYNC_4_ADR:  12-15 bits are used as scratch register to configure the 1G support */
   1570     /* 12-15 bits also used to support speed change in HIGIG interface mode */
   1571     if ((config->data_rate == SESTO_SPD_1G) || (PHYMOD_INTF_MODES_HIGIG_GET(config) && ((config->data_rate == SESTO_SPD_10G) ||
   1572        (config->data_rate == SESTO_SPD_20G) || (config->data_rate == SESTO_SPD_40G) || (config->data_rate == SESTO_SPD_100G)))){
   1573         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, intf_sel_spd.data);
   1574         intf_sel_spd.data |= (1 << (12 + port));
   1575         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, intf_sel_spd.data);
   1576     } else {
   1577         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, intf_sel_spd.data);
   1578         intf_sel_spd.data &= ~(1 << (12 + port));
   1579         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, intf_sel_spd.data);
   1580     }
   1581 
   1582     PHYMOD_DEBUG_VERBOSE(("GPREG11 data:%x\n",gpreg11.data));
   1583     PHYMOD_DEBUG_VERBOSE(("SYNC_4 data:%x\n",intf_sel_spd.data));
   1584     PHYMOD_DEBUG_VERBOSE(("SYNC_5 data:%x\n",intf_sel_p0_p1.data));
   1585     PHYMOD_DEBUG_VERBOSE(("SYNC_6 data:%x\n",intf_sel_p2_p3.data));
   1586 
   1587     SESTO_IF_ERR_RETURN(
   1588         _sesto_set_ieee_intf(phy, intf, config, ip));
   1589 
   1590 ERR:
   1591     return rv;
   1592 }
   1593 
   1594 int _sesto_set_ieee_intf(const phymod_phy_access_t *phy, uint16_t intf, const phymod_phy_inf_config_t *config, uint16_t ip)
   1595 {
   1596     uint16_t port = 0;
   1597     uint16_t intf_side = 0;
   1598     int rv = PHYMOD_E_NONE;
   1599     const phymod_access_t *pa = &phy->access;
   1600     SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T mod_sel;
   1601 
   1602     PHYMOD_MEMSET(&mod_sel, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T));
   1603     SESTO_IF_ERR_RETURN(
   1604         _sesto_port_from_lane_map_get(phy, config, &port));
   1605     
   1606     READ_SESTO_PMA_PMD_REG(pa, (SES_GEN_CNTRLS_MICRO_SYNC_0_ADR + port), mod_sel.data);
   1607     SESTO_GET_INTF_SIDE(phy, intf_side);
   1608     mod_sel.data = intf_side ? (mod_sel.data & 0xFF) : (mod_sel.data & 0xFF00);
   1609     mod_sel.data |= intf_side ? (intf << 8) : (intf);
   1610     WRITE_SESTO_PMA_PMD_REG(pa, (SES_GEN_CNTRLS_MICRO_SYNC_0_ADR + port), mod_sel.data);
   1611 
   1612 ERR:
   1613     return rv;
   1614 }
   1615 
   1616 int _sesto_get_ieee_intf(const phymod_phy_access_t *phy, uint16_t ip, const phymod_phy_inf_config_t *config, uint16_t *intf)
   1617 {
   1618     uint16_t port = 0;
   1619     uint16_t intf_side = 0;
   1620     int rv = PHYMOD_E_NONE;
   1621     const phymod_access_t *pa = &phy->access;
   1622     SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T mod_sel;
   1623 
   1624     PHYMOD_MEMSET(&mod_sel, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T));
   1625     SESTO_IF_ERR_RETURN(
   1626         _sesto_port_from_lane_map_get(phy, config, &port));
   1627 
   1628     READ_SESTO_PMA_PMD_REG(pa, (SES_GEN_CNTRLS_MICRO_SYNC_0_ADR + port), mod_sel.data);
   1629     SESTO_GET_INTF_SIDE(phy, intf_side);
   1630     *intf = intf_side ? ((mod_sel.data >> 8) & 0xFF) : (mod_sel.data & 0x00FF);
   1631 
   1632 ERR:
   1633     return rv;
   1634 }
   1635 
   1636 int _sesto_pll_config_state_get(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t* config, uint16_t *pll_cfg_state)
   1637 {
   1638     phymod_phy_inf_config_t cfg;
   1639     SESTO_DEVICE_AUX_MODE_T *aux_mode;
   1640     uint16_t ip = 0;
   1641     uint16_t no_of_ports = 0;
   1642     DP_DECODED_MODE_STATUS0_TYPE_T mode_sts0;
   1643     uint16_t fal_pll_lock = 0, mer_pll_lock = 0;
   1644     const phymod_access_t *pa = &phy->access;
   1645     int rv = PHYMOD_E_NONE;
   1646 
   1647     PHYMOD_MEMSET(&cfg, 0, sizeof(phymod_phy_inf_config_t));
   1648     cfg.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   1649     aux_mode = (SESTO_DEVICE_AUX_MODE_T*) config->device_aux_modes;
   1650     SESTO_IF_ERR_RETURN(
   1651        _sesto_phy_interface_config_get(phy, 0, &cfg));
   1652 
   1653     READ_SESTO_PMA_PMD_REG(pa, DP_DECODED_MODE_STATUS0_ADR, mode_sts0.data);
   1654     for (ip = SESTO_MERLIN_CORE; ip <= SESTO_FALCON_CORE; ip++) {
   1655         SESTO_IF_ERR_RETURN(
   1656             _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip, SESTO_DEV_PMA_PMD, 0, 0));
   1657         if (ip == SESTO_FALCON_CORE) {
   1658             SESTO_CHIP_FIELD_READ(pa, FALCON_IF_PMD_PLL_STS, pmd_pll_lock, fal_pll_lock);
   1659         } else {
   1660             SESTO_CHIP_FIELD_READ(pa, MERLIN_IF_PMD_PLL_LOCK_STATUS, pmd_pll_lock, mer_pll_lock);
   1661         }
   1662     }
   1663     /*
   1664      *  PLL div is per die and will be programed only when
   1665      *  1. if there is no pll lock on merlin or falcon
   1666      *  2. speed change b/w 100G to 40G/20G/10G
   1667      *  3. if ref clock freq changes(pll lock lost)
   1668      *  4. On interface_modes changes(IEEE/OTN/HIGIG)
   1669      */
   1670     SESTO_GET_PORT_FROM_MODE(config, no_of_ports, aux_mode);
   1671     if (((fal_pll_lock != 1) || (mer_pll_lock != 1)) || (config->ref_clock != cfg.ref_clock) ||
   1672         ((config->interface_modes & (PHYMOD_INTF_MODES_HIGIG | PHYMOD_INTF_MODES_OTN)) != (cfg.interface_modes & (PHYMOD_INTF_MODES_HIGIG | PHYMOD_INTF_MODES_OTN))) ||
   1673         ((no_of_ports == 1) && (config->data_rate != cfg.data_rate)) || (!mode_sts0.data) ||
   1674         ((no_of_ports > 1) && (cfg.data_rate == SESTO_SPD_100G) && (config->data_rate != SESTO_SPD_100G)) ||
   1675         ((no_of_ports > 1) && (cfg.data_rate == SESTO_SPD_106G) && (config->data_rate != SESTO_SPD_106G))) {
   1676         *pll_cfg_state = 1;
   1677     }
   1678     /* HIGIG mode speed change */
   1679     if ((config->interface_modes == cfg.interface_modes) && (config->data_rate != cfg.data_rate)) {
   1680         *pll_cfg_state = 1;
   1681     }
   1682 
   1683 ERR:
   1684     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   1685     PHYMOD_FREE(cfg.device_aux_modes);
   1686 
   1687     return rv;
   1688 }
   1689 
   1690 
   1691 int _sesto_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config)
   1692 {
   1693     uint16_t pll_cfg_state = 0;
   1694     int rv = PHYMOD_E_NONE;
   1695 
   1696     /* Get the pll config state */
   1697     SESTO_IF_ERR_RETURN(
   1698           _sesto_pll_config_state_get(phy, config, &pll_cfg_state));
   1699 
   1700     /* Configure Ref Clock*/
   1701     PHYMOD_DEBUG_VERBOSE(("Configuring REF clock\n"));
   1702     SESTO_IF_ERR_RETURN(
   1703           _sesto_configure_ref_clock(&phy->access, config->ref_clock));
   1704     
   1705     /* Configure DUT MODE */
   1706     SESTO_IF_ERR_RETURN(
   1707         _sesto_config_dut_mode_reg(phy, config));
   1708     
   1709     /* Enable UDMS for non-an MODE */
   1710     PHYMOD_DEBUG_VERBOSE(("Configuring UDMS\n"));
   1711     SESTO_IF_ERR_RETURN(
   1712         _sesto_udms_config(phy, config, SESTO_AN_NONE));
   1713 
   1714     /* Configure PLL Divider*/
   1715     if (pll_cfg_state) {
   1716         PHYMOD_DEBUG_VERBOSE(("Configuring PLL divider\n"));
   1717         SESTO_IF_ERR_RETURN(
   1718             _sesto_config_pll_div(&phy->access, config));
   1719     }
   1720 
   1721     /* Configure Interface */
   1722     SESTO_IF_ERR_RETURN(
   1723         _sesto_interface_set(phy, config));
   1724 
   1725 ERR:
   1726     return rv;
   1727 }
   1728 
   1729 int _sesto_phy_interface_config_get(const phymod_phy_access_t *phy, uint32_t flags, phymod_phy_inf_config_t *config)
   1730 {
   1731     uint16_t ip = 0, intf_side = 0;
   1732     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   1733     DP_DECODED_MODE_STATUS0_TYPE_T mode_sts0;
   1734     SES_GEN_CNTRLS_GPREG11_TYPE_T   gpreg11;
   1735     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T ref_clk_freq;
   1736     int rv = PHYMOD_E_NONE;
   1737     uint16_t clock = 0, port = 0;
   1738     const phymod_access_t *pa = &phy->access;
   1739     uint16_t lane_mask = pa->lane_mask;
   1740 
   1741     PHYMOD_MEMSET(&mode_sts0, 0, sizeof(DP_DECODED_MODE_STATUS0_TYPE_T));
   1742     PHYMOD_MEMSET(&gpreg11, 0, sizeof(SES_GEN_CNTRLS_GPREG11_TYPE_T));
   1743     PHYMOD_MEMSET(&ref_clk_freq, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T));
   1744     aux_mode = (SESTO_DEVICE_AUX_MODE_T*) config->device_aux_modes;
   1745     if (aux_mode == NULL) {
   1746         PHYMOD_DEBUG_VERBOSE(("AUX MODE MEM NOT ALLOC\n"));
   1747         return PHYMOD_E_PARAM;
   1748     }
   1749     PHYMOD_MEMSET(aux_mode, 0, sizeof(SESTO_DEVICE_AUX_MODE_T));
   1750 
   1751     if (!lane_mask) {
   1752         PHYMOD_DEBUG_VERBOSE(("Invalid Lanemask\n"));
   1753         return PHYMOD_E_PARAM;
   1754     }
   1755     SESTO_GET_INTF_SIDE(phy, intf_side);
   1756     READ_SESTO_PMA_PMD_REG(pa, DP_DECODED_MODE_STATUS0_ADR, mode_sts0.data);
   1757     PHYMOD_DEBUG_VERBOSE(("MODE STS:%x\n", mode_sts0.data));
   1758     if (intf_side == SESTO_IF_LINE) {
   1759         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_FALCON_CORE : SESTO_MERLIN_CORE;
   1760     } else {
   1761         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_MERLIN_CORE : SESTO_FALCON_CORE;
   1762     }
   1763     if (ip == SESTO_FALCON_CORE) {
   1764         if (mode_sts0.fields.decoded_mode_100g_gbox) {
   1765             config->data_rate = SESTO_SPD_100G;
   1766             aux_mode->gearbox_100g_inverse_mode = (mode_sts0.fields.decoded_mode_falcon_line) ? 0 : 1;
   1767         } else if (lane_mask & 0x3) {
   1768             if (mode_sts0.fields.decoded_mode_40g_mux_p1) {
   1769                 config->data_rate = SESTO_SPD_40G;
   1770                 aux_mode->pass_thru = 0;
   1771             } else if (mode_sts0.fields.decoded_mode_40g_passthru) {
   1772                 config->data_rate = SESTO_SPD_40G;
   1773                 aux_mode->pass_thru = 1;
   1774                 aux_mode->BCM84793_capablity = 0;
   1775                 if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1776                     aux_mode->BCM84793_capablity = 1;
   1777                 }
   1778             } else if (mode_sts0.fields.decoded_mode_20g_mux_p1) {
   1779                 config->data_rate = SESTO_SPD_20G;
   1780                 aux_mode->pass_thru = 0;
   1781             } else if (mode_sts0.fields.decoded_mode_20g_passthru_p1) {
   1782                 config->data_rate = SESTO_SPD_20G;
   1783                 aux_mode->pass_thru = 1;
   1784             } else if (mode_sts0.fields.decoded_mode_10g_p1) {
   1785                 config->data_rate = SESTO_SPD_10G;
   1786                 aux_mode->pass_thru = 1;
   1787             } else if (mode_sts0.fields.decoded_mode_10g_p2) {
   1788                 config->data_rate = SESTO_SPD_10G;
   1789                 aux_mode->pass_thru = 1;
   1790             }
   1791         } else if (lane_mask & 0xc) {
   1792             if (mode_sts0.fields.decoded_mode_40g_mux_p2) {
   1793                 config->data_rate = SESTO_SPD_40G;
   1794                 aux_mode->pass_thru = 0;
   1795             } else if (mode_sts0.fields.decoded_mode_40g_passthru) {
   1796                 config->data_rate = SESTO_SPD_40G;
   1797                 aux_mode->pass_thru = 1;
   1798                 aux_mode->BCM84793_capablity = 0;
   1799                 if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1800                     aux_mode->BCM84793_capablity = 1;
   1801                 }
   1802             } else if (mode_sts0.fields.decoded_mode_20g_passthru_p2) {
   1803                 config->data_rate = SESTO_SPD_20G;
   1804                 aux_mode->pass_thru = 1;
   1805             } else if (mode_sts0.fields.decoded_mode_20g_mux_p2) {
   1806                 config->data_rate = SESTO_SPD_20G;
   1807                 aux_mode->pass_thru = 0;
   1808             } else if (mode_sts0.fields.decoded_mode_10g_p3) {
   1809                 config->data_rate = SESTO_SPD_10G;
   1810                 aux_mode->pass_thru = 1;
   1811                 if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1812                     aux_mode->BCM84793_capablity = 1;
   1813                 }
   1814             } else if (mode_sts0.fields.decoded_mode_10g_p4) {
   1815                 config->data_rate = SESTO_SPD_10G;
   1816                 aux_mode->pass_thru = 1;
   1817                 if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1818                     aux_mode->BCM84793_capablity = 1;
   1819                 }
   1820             }
   1821         }
   1822     } else {
   1823         if (mode_sts0.fields.decoded_mode_100g_gbox) {
   1824             config->data_rate = SESTO_SPD_100G;
   1825             aux_mode->gearbox_100g_inverse_mode = (mode_sts0.fields.decoded_mode_falcon_line) ? 0 : 1;
   1826         } else if (lane_mask & 0xF) {
   1827             if ((mode_sts0.fields.decoded_mode_10g_p1) && (lane_mask & 0x1)) {
   1828                 config->data_rate = SESTO_SPD_10G;
   1829                 aux_mode->pass_thru = 1;
   1830             } else if ((mode_sts0.fields.decoded_mode_10g_p2) && (lane_mask & 0x2)) {
   1831                 config->data_rate = SESTO_SPD_10G;
   1832                 aux_mode->pass_thru = 1;
   1833             } else if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1834                 if ((mode_sts0.fields.decoded_mode_10g_p3) && (lane_mask & 0x4)) {
   1835                     config->data_rate = SESTO_SPD_10G;
   1836                     aux_mode->pass_thru = 1;
   1837                     aux_mode->BCM84793_capablity = 1;
   1838                 } else if ((mode_sts0.fields.decoded_mode_10g_p4) && (lane_mask & 0x8)) { 
   1839                     config->data_rate = SESTO_SPD_10G;
   1840                     aux_mode->pass_thru = 1;
   1841                     aux_mode->BCM84793_capablity = 1;
   1842                 } else if (mode_sts0.fields.decoded_mode_40g_passthru) {
   1843                     config->data_rate = SESTO_SPD_40G;
   1844                     aux_mode->pass_thru = 1;
   1845                     aux_mode->BCM84793_capablity = 1;
   1846                 }
   1847             } else if (mode_sts0.fields.decoded_mode_20g_mux_p1) {
   1848                 config->data_rate = SESTO_SPD_20G;
   1849                 aux_mode->pass_thru = 0;
   1850             } else if (mode_sts0.fields.decoded_mode_20g_passthru_p1) {
   1851                 config->data_rate = SESTO_SPD_20G;
   1852                 aux_mode->pass_thru = 1;
   1853             } else if (mode_sts0.fields.decoded_mode_40g_mux_p1) {
   1854                 config->data_rate = SESTO_SPD_40G;
   1855                 aux_mode->pass_thru = 0;
   1856             } else if (mode_sts0.fields.decoded_mode_40g_passthru) {
   1857                 config->data_rate = SESTO_SPD_40G;
   1858                 aux_mode->pass_thru = 1;
   1859                 aux_mode->BCM84793_capablity = 0;
   1860                 if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1861                     aux_mode->BCM84793_capablity = 1;
   1862                 }
   1863             }
   1864         } else if (lane_mask & 0xF0) {
   1865             if (mode_sts0.fields.decoded_mode_10g_p3) {
   1866                 config->data_rate = SESTO_SPD_10G;
   1867                 aux_mode->pass_thru = 1;
   1868             } else if (mode_sts0.fields.decoded_mode_10g_p4) {
   1869                 config->data_rate = SESTO_SPD_10G;
   1870                 aux_mode->pass_thru = 1;
   1871             } else if (mode_sts0.fields.decoded_mode_20g_mux_p2) {
   1872                 config->data_rate = SESTO_SPD_20G;
   1873                 aux_mode->pass_thru = 0;
   1874             } else if (mode_sts0.fields.decoded_mode_20g_passthru_p2) {
   1875                 config->data_rate = SESTO_SPD_20G;
   1876                 aux_mode->pass_thru = 1;
   1877             } else if (mode_sts0.fields.decoded_mode_40g_mux_p2) {
   1878                 config->data_rate = SESTO_SPD_40G;
   1879                 aux_mode->pass_thru = 0;
   1880             } else if (mode_sts0.fields.decoded_mode_40g_passthru) {
   1881                 config->data_rate = SESTO_SPD_40G;
   1882                 aux_mode->pass_thru = 1;
   1883                 if (mode_sts0.fields.decoded_mode_enzo_compatible) {
   1884                     aux_mode->BCM84793_capablity = 1;
   1885                 }
   1886             }
   1887         }
   1888     }
   1889     aux_mode->passthru_sys_side_core =
   1890         (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_MERLIN_CORE : SESTO_FALCON_CORE;
   1891 
   1892     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   1893     if (gpreg11.fields.phy_type  == 1) {
   1894         PHYMOD_INTF_MODES_OTN_SET(config);
   1895     } else if (gpreg11.fields.phy_type == 2) {
   1896         PHYMOD_INTF_MODES_HIGIG_SET(config);
   1897         if (config->data_rate == SESTO_SPD_10G) {
   1898             config->data_rate = SESTO_SPD_11G;
   1899         } else if (config->data_rate == SESTO_SPD_20G) {
   1900             config->data_rate = SESTO_SPD_21G;
   1901         } else if (config->data_rate == SESTO_SPD_40G) {
   1902             config->data_rate = SESTO_SPD_42G;
   1903         } else if (config->data_rate == SESTO_SPD_100G) {
   1904             config->data_rate = SESTO_SPD_106G;
   1905         }
   1906     } else {
   1907         config->interface_modes = 0; /*Ethernet*/
   1908     }
   1909     SESTO_CHIP_FIELD_READ(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, clock);
   1910     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   1911     if (clock <= 0x2) {
   1912         config->ref_clock = ((ref_clk_freq.data >> 8) & 0xF);
   1913     }
   1914     /*SES_GEN_CNTRLS_MICRO_SYNC_4_ADR 12-15 bits are defined for 1G support */
   1915     /* 12-15 bits also used to support speed change in HIGIG interface mode */
   1916     SESTO_IF_ERR_RETURN(_sesto_port_from_lane_map_get(phy, config, &port));
   1917     if ((ref_clk_freq.data >> (12 + port)) & 0x1) {
   1918         if (gpreg11.fields.phy_type == 2) {
   1919             PHYMOD_INTF_MODES_HIGIG_SET(config);
   1920             if (config->data_rate == SESTO_SPD_11G) {
   1921                  config->data_rate = SESTO_SPD_10G;
   1922             } else if (config->data_rate == SESTO_SPD_21G) {
   1923                  config->data_rate = SESTO_SPD_20G;
   1924             } else if (config->data_rate == SESTO_SPD_42G) {
   1925                  config->data_rate = SESTO_SPD_40G;
   1926             } else if (config->data_rate == SESTO_SPD_106G) {
   1927                  config->data_rate = SESTO_SPD_100G;
   1928             }
   1929         } else {
   1930             config->data_rate = SESTO_SPD_1G;
   1931         }
   1932     }
   1933 
   1934     SESTO_IF_ERR_RETURN(
   1935        _sesto_get_ieee_intf(phy, ip, config, &intf_side));
   1936     config->interface_type = intf_side;
   1937     
   1938 ERR:
   1939     return rv;
   1940 }
   1941 
   1942 int _sesto_phy_pcs_link_get(const phymod_phy_access_t *phy, uint32_t *pcs_link)
   1943 {
   1944     int rv = PHYMOD_E_NONE;
   1945     uint32_t lock_lost_lh = 0, error_count = 0;
   1946 
   1947     if (pcs_link) {
   1948         *pcs_link = 0xffff;
   1949     } else {
   1950         return PHYMOD_E_PARAM;
   1951     }
   1952     SESTO_IF_ERR_RETURN(
   1953             _sesto_get_pcs_link_status(phy, pcs_link, &lock_lost_lh, &error_count));
   1954 
   1955 ERR:
   1956     return rv;
   1957 }
   1958 
   1959 int _sesto_configure_ref_clock(const phymod_access_t *pa, phymod_ref_clk_t ref_clk)
   1960 {
   1961     int rv = PHYMOD_E_NONE;
   1962     uint16_t clk_scalar_code = 0x0;
   1963     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T ref_clk_freq;
   1964 
   1965     PHYMOD_MEMSET(&ref_clk_freq, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T));
   1966     /* SES_GEN_CNTRLS_MICRO_SYNC_4_ADR:  8-11 bits are used as scratch register to configure the ref_clk_freq */
   1967 
   1968     switch (ref_clk) {
   1969         case phymodRefClk156Mhz:
   1970         case phymodRefClk312Mhz:
   1971             /* Writing to scratch reg to save in chip */
   1972             READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   1973             ref_clk_freq.data &= 0xF0FF;
   1974             ref_clk_freq.data |= (ref_clk << 8);
   1975             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   1976             SESTO_CHIP_FIELD_READ(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, clk_scalar_code);			
   1977             if (clk_scalar_code != 0x02) { 
   1978                 SESTO_CHIP_FIELD_WRITE(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, 0x02);			
   1979             }
   1980         break;
   1981         case phymodRefClk161Mhz:
   1982         case phymodRefClk322Mhz:
   1983         case phymodRefClk644Mhz:
   1984             /* Writing to scratch reg to save in chip */
   1985             READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   1986             ref_clk_freq.data &= 0xF0FF;
   1987             ref_clk_freq.data |= (ref_clk << 8);
   1988             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   1989             SESTO_CHIP_FIELD_READ(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, clk_scalar_code);			
   1990             if (clk_scalar_code != 0x01) { 
   1991                 SESTO_CHIP_FIELD_WRITE(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, 0x01);
   1992             }
   1993         break;
   1994         case phymodRefClk174Mhz:
   1995         case phymodRefClk349Mhz:
   1996         case phymodRefClk698Mhz:
   1997             /* Writing to scratch reg to save in chip */
   1998             READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   1999             ref_clk_freq.data &= 0xF0FF;
   2000             ref_clk_freq.data |= (ref_clk << 8);
   2001             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, ref_clk_freq.data);
   2002             SESTO_CHIP_FIELD_READ(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, clk_scalar_code);			
   2003             if (clk_scalar_code != 0x0) { 
   2004                 SESTO_CHIP_FIELD_WRITE(pa, SES_CTRL_CLOCK_SCALER_CTRL, clock_scaler_code, 0x0);
   2005             }
   2006         break;
   2007         default:
   2008 	    PHYMOD_DEBUG_ERROR((" This Ref Clock (%d) is not supported\n", ref_clk));
   2009 	    return PHYMOD_E_PARAM;
   2010     }
   2011 
   2012 ERR:
   2013     return rv;
   2014 }
   2015 
   2016 int _sesto_get_pll_modes(phymod_ref_clk_t ref_clk,const phymod_phy_inf_config_t *config, uint16_t *fal_pll_mode, uint16_t *mer_pll_mode) 
   2017 {
   2018     uint32_t speed = config->data_rate;
   2019 
   2020     switch (ref_clk) {
   2021         case phymodRefClk156Mhz:
   2022         case phymodRefClk312Mhz:
   2023             /* No OTN support on 156 and 312 */
   2024             if (PHYMOD_INTF_MODES_OTN_GET(config)) {
   2025                     return PHYMOD_E_PARAM;
   2026             }
   2027             if ((speed == SESTO_SPD_100G) || (speed == SESTO_SPD_106G)) {
   2028                 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   2029                     *fal_pll_mode = SESTO_PLL_MODE_175;
   2030                     *mer_pll_mode = SESTO_PLL_MODE_70;
   2031                     if (speed == SESTO_SPD_100G) {
   2032                         *fal_pll_mode = SESTO_PLL_MODE_165;
   2033                         *mer_pll_mode = SESTO_PLL_MODE_66;
   2034                     }
   2035             } else {
   2036                     *fal_pll_mode = SESTO_PLL_MODE_165;
   2037                     *mer_pll_mode = SESTO_PLL_MODE_66;
   2038             }
   2039         } else {
   2040             /*-- Falcon Line Rate is 10G/20G*/
   2041                 if (PHYMOD_INTF_MODES_HIGIG_GET(config)) {
   2042                     *fal_pll_mode = SESTO_PLL_MODE_140;
   2043                     *mer_pll_mode = SESTO_PLL_MODE_70;
   2044                     if ((speed == SESTO_SPD_40G) || (speed == SESTO_SPD_20G) || (speed == SESTO_SPD_10G)) {
   2045                         *fal_pll_mode = SESTO_PLL_MODE_132;
   2046                         *mer_pll_mode = SESTO_PLL_MODE_66;
   2047                     }
   2048                 } else { /*IEEE MODE*/
   2049                     *fal_pll_mode = SESTO_PLL_MODE_132;
   2050                     *mer_pll_mode = SESTO_PLL_MODE_66;
   2051             }
   2052         }
   2053         break;
   2054         case phymodRefClk161Mhz:
   2055         case phymodRefClk322Mhz:
   2056         case phymodRefClk644Mhz:
   2057             /* No OTN or HIGIG Support on 161/322/644 */
   2058             if ((PHYMOD_INTF_MODES_HIGIG_GET(config)) || (PHYMOD_INTF_MODES_OTN_GET(config))) {
   2059                     return PHYMOD_E_PARAM;
   2060             }
   2061             if (speed == SESTO_SPD_100G) {
   2062                  /*IEEE MODE*/
   2063                     *fal_pll_mode = SESTO_PLL_MODE_160;
   2064                     *mer_pll_mode = SESTO_PLL_MODE_64;
   2065             } else {
   2066                     *fal_pll_mode = SESTO_PLL_MODE_128;
   2067                     *mer_pll_mode = SESTO_PLL_MODE_64;
   2068 	        }
   2069         break;
   2070         case phymodRefClk174Mhz:
   2071         case phymodRefClk349Mhz: 
   2072         case phymodRefClk698Mhz:
   2073             if (speed == SESTO_SPD_100G) {
   2074                 if (PHYMOD_INTF_MODES_OTN_GET(config)) {
   2075                     *fal_pll_mode = SESTO_PLL_MODE_160;
   2076                     *mer_pll_mode = SESTO_PLL_MODE_64;
   2077                 } else {
   2078                     return PHYMOD_E_PARAM;
   2079                 }
   2080             } else {
   2081                 if (PHYMOD_INTF_MODES_OTN_GET(config)) {
   2082                     *fal_pll_mode = SESTO_PLL_MODE_128;
   2083                     *mer_pll_mode = SESTO_PLL_MODE_64;
   2084                 } else {
   2085                     return PHYMOD_E_PARAM;
   2086                 }
   2087             }
   2088         break;
   2089         default:
   2090             return PHYMOD_E_PARAM;
   2091     }
   2092 
   2093     return PHYMOD_E_NONE;
   2094 }
   2095 
   2096 /** Map Merlin PLL Division
   2097  * @param PLL Mode
   2098  * @return Merlin PLL mode mapped value
   2099  */
   2100 int _sesto_map_mer_pll_div(SESTO_PLL_MODE_E pll_mode) 
   2101 {
   2102     switch (pll_mode) {
   2103         case SESTO_PLL_MODE_64:
   2104             return 1;
   2105         case SESTO_PLL_MODE_66:
   2106             return 2;
   2107         case SESTO_PLL_MODE_70:
   2108             return 3;
   2109         default:
   2110 	        PHYMOD_DEBUG_VERBOSE(("PLLMODE %d not supported\n", pll_mode));
   2111             return PHYMOD_E_PARAM; 
   2112     }
   2113 }
   2114 
   2115 int _sesto_config_pll_div(const phymod_access_t *pa, const phymod_phy_inf_config_t *config)
   2116 {
   2117     uint16_t ip = 0, merlin_pll_mode = 0, falcon_pll_mode = 0;
   2118     phymod_ref_clk_t ref_clk = config->ref_clock;
   2119      uint16_t lock = 0, retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   2120     int rv = PHYMOD_E_NONE;
   2121 
   2122     /*Program PLL div of all dies*/
   2123     /* Set pll_mode */
   2124     SESTO_IF_ERR_RETURN(
   2125        _sesto_get_pll_modes(ref_clk, config, &falcon_pll_mode, &merlin_pll_mode));
   2126     for (ip = SESTO_MERLIN_CORE; ip <= SESTO_FALCON_CORE; ip++) {
   2127         PHYMOD_DEBUG_VERBOSE(("%s::  IP:%s Max_lane:%d lanemask:0x%x\n", 
   2128                 __func__, (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", 1, 0x1));
   2129         SESTO_IF_ERR_RETURN(
   2130           _sesto_set_slice_reg(pa, SESTO_SLICE_UNICAST, ip, SESTO_DEV_PMA_PMD, 0, 0));
   2131         if (ip == SESTO_FALCON_CORE) {
   2132                 /* write 0 to core_dp_s_rstb while pll config*/
   2133                 wrc_falcon_furia_sesto_core_dp_s_rstb(0);
   2134                 /* default values  for falcon pll */ 
   2135                 wrc_falcon_furia_sesto_ams_pll_vco2_15g(0x0);
   2136                 wrc_falcon_furia_sesto_ams_pll_force_kvh_bw(0);
   2137                 wrc_falcon_furia_sesto_ams_pll_kvh_force(0);
   2138                 wrc_falcon_furia_sesto_ams_pll_vco_indicator(0);
   2139 
   2140                 /* Set PLL div */
   2141                 switch (falcon_pll_mode) {
   2142                     case SESTO_PLL_MODE_160:
   2143                         if (PHYMOD_INTF_MODES_OTN_GET(config)) {
   2144                             SESTO_IF_ERR_RETURN(
   2145                              falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_160x_refc174));
   2146                         } else {
   2147                             SESTO_IF_ERR_RETURN(
   2148                              falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_160x)); 
   2149                         }
   2150                     break;
   2151                     case SESTO_PLL_MODE_132: 
   2152                         SESTO_IF_ERR_RETURN(
   2153                          falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_132x)); 
   2154                     break;
   2155                     case SESTO_PLL_MODE_128: 
   2156                         SESTO_IF_ERR_RETURN(
   2157                          falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_128x)); 
   2158                     break;
   2159                     case SESTO_PLL_MODE_140: 
   2160                         SESTO_IF_ERR_RETURN(
   2161                          falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_140x));
   2162                     break;
   2163                     case SESTO_PLL_MODE_165: 
   2164                         SESTO_IF_ERR_RETURN(
   2165                          falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_165x));
   2166                     break;
   2167                     case SESTO_PLL_MODE_175: 
   2168                         SESTO_IF_ERR_RETURN(
   2169                          falcon_furia_sesto_configure_pll(pa, FALCON_FURIA_pll_div_175x));
   2170                     break;
   2171                 }
   2172                 /* write 1 to core_dp_s_rstb after pll config*/
   2173                 wrc_falcon_furia_sesto_core_dp_s_rstb(1);
   2174         } else {
   2175             /* write 0 to core_dp_s_rstb while pll config*/
   2176             wrc_core_dp_s_rstb(0);
   2177             if (_sesto_map_mer_pll_div(merlin_pll_mode) == 1) {
   2178                 /*-- PLL Mode 64*/
   2179                 SESTO_IF_ERR_RETURN(
   2180                      merlin_sesto_configure_pll(pa, MERLIN_SESTO_pll_10p3125GHz_161p132MHz));
   2181             } else if (_sesto_map_mer_pll_div(merlin_pll_mode) == 0x2) {
   2182                 /* PLL Mode 66*/
   2183                 SESTO_IF_ERR_RETURN(
   2184                      merlin_sesto_configure_pll(pa, MERLIN_SESTO_pll_10p3125GHz_156p25MHz));
   2185             } else if (_sesto_map_mer_pll_div(merlin_pll_mode) == 0x3) {
   2186                 /* PLL Mode 70*/
   2187                 SESTO_IF_ERR_RETURN(
   2188                      merlin_sesto_configure_pll(pa, MERLIN_SESTO_pll_10p9375GHz_156p25MHz));
   2189             } else {
   2190                 return PHYMOD_E_PARAM;
   2191             }
   2192             /* write 1 to core_dp_s_rstb after pll config*/
   2193             wrc_core_dp_s_rstb(1);
   2194         }
   2195     }
   2196 
   2197     /*check for the pll lock and get the lanes out of reset*/
   2198     do {
   2199         if (ip == SESTO_FALCON_CORE) {
   2200             SESTO_CHIP_FIELD_READ(pa, F25G_PLL_CAL_COM_CTL_STATUS_0, pll_lock, lock);
   2201         } else {
   2202             SESTO_CHIP_FIELD_READ(pa, M10G_PLL_CAL_PLL_CALSTS_0, pll_lock, lock);
   2203         }
   2204         PHYMOD_DEBUG_VERBOSE(("PLL LOCK STS:%d\n", lock));
   2205         retry_cnt--;
   2206     } while((lock != 1) && (retry_cnt));
   2207     if (retry_cnt == 0) {
   2208         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
   2209               (_PHYMOD_MSG("ERR:PLL NOT LOCKED")));
   2210         return PHYMOD_E_FAIL;
   2211     }
   2212 
   2213 ERR:
   2214     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2215     return rv;
   2216 }
   2217 
   2218 int _sesto_core_dp_rstb(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t config)
   2219 {
   2220     uint16_t lane = 0, ip = 0, lock = 0;
   2221     uint16_t max_lane = 0, lane_mask=0;
   2222     uint16_t cast_type = 0, mcast_val=0;
   2223     uint16_t retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   2224     const phymod_access_t *pa = &phy->access;
   2225     int rv = PHYMOD_E_NONE;
   2226 
   2227     SESTO_GET_IP(phy, config, ip);
   2228 
   2229     lane_mask = (pa->lane_mask) ? pa->lane_mask : 0x3ff;
   2230     max_lane = (ip == SESTO_FALCON_CORE) ? SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   2231 
   2232     SESTO_GET_CORE_SLICE_INFO(phy, ip, config, &cast_type, &mcast_val);
   2233     PHYMOD_DEBUG_VERBOSE(("%s:  IP:%s Max_lane:%d lanemask:0x%x cast_type:%d\n", 
   2234                 __func__, (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask,
   2235                  cast_type));
   2236 
   2237     if (cast_type != SESTO_CAST_INVALID) {
   2238         for (lane = 0; lane < max_lane; lane ++) {
   2239             if (lane_mask & (1 << lane)) {
   2240                 SESTO_IF_ERR_RETURN(
   2241                   _sesto_set_slice_reg (pa, cast_type, ip,
   2242                               SESTO_DEV_PMA_PMD, mcast_val, lane));
   2243                 if (ip == SESTO_FALCON_CORE) {
   2244                     SESTO_IF_ERR_RETURN(
   2245                         wrc_falcon_furia_sesto_core_dp_s_rstb(1)); 
   2246                 } else {
   2247                     SESTO_IF_ERR_RETURN(
   2248                        wrc_core_dp_s_rstb(1)); 
   2249                 }
   2250                 if (SESTO_IS_MULTI_BROAD_CAST_SET(cast_type)) {
   2251                     break;
   2252                 }
   2253             }
   2254         }
   2255     }
   2256 
   2257     /*check for the pll lock and get the lanes out of reset*/
   2258     do {
   2259         if (ip == SESTO_FALCON_CORE) {
   2260             SESTO_CHIP_FIELD_READ(pa, F25G_PLL_CAL_COM_CTL_STATUS_0, pll_lock, lock);
   2261         } else {
   2262             SESTO_CHIP_FIELD_READ(pa, M10G_PLL_CAL_PLL_CALSTS_0, pll_lock, lock);
   2263         }
   2264         PHYMOD_DEBUG_VERBOSE(("PLL LOCK STS:%d\n", lock));
   2265         retry_cnt--;
   2266     } while((lock != 1) && (retry_cnt));
   2267     if (retry_cnt == 0) {
   2268         SESTO_RETURN_WITH_ERR(PHYMOD_E_FAIL,
   2269               (_PHYMOD_MSG("ERR:PLL NOT LOCKED")));
   2270         return PHYMOD_E_FAIL;
   2271     }
   2272 
   2273 ERR:
   2274     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2275     return rv;
   2276 }
   2277 
   2278 int _sesto_core_reset_set(const phymod_access_t *pa, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
   2279 {
   2280     SES_GEN_CNTRLS_GEN_CONTROL1_TYPE_T gen_ctrl;
   2281     FALCON_IF_COMMON_CONTROL_TYPE_T  fal_cmn_ctrl;
   2282     MERLIN_IF_COMMON_CONTROL_TYPE_T  mer_cmn_ctrl;
   2283     int rv = PHYMOD_E_NONE;
   2284 
   2285     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL1_ADR, gen_ctrl.data);
   2286     if (reset_mode == phymodResetModeHard) {
   2287         gen_ctrl.fields.resetb = 0;
   2288         gen_ctrl.fields.reg_rstb = 0;
   2289         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL1_ADR, gen_ctrl.data);
   2290 
   2291         /* -- Resetting the Cores*/
   2292         READ_SESTO_PMA_PMD_REG(pa, FALCON_IF_COMMON_CONTROL_ADR, fal_cmn_ctrl.data);
   2293         fal_cmn_ctrl.fields.pmd_por_h_rstb_frcval = 0;
   2294         fal_cmn_ctrl.fields.pmd_por_h_rstb_frc = 1;
   2295         WRITE_SESTO_PMA_PMD_REG(pa, FALCON_IF_COMMON_CONTROL_ADR, fal_cmn_ctrl.data);
   2296 
   2297         READ_SESTO_PMA_PMD_REG(pa, MERLIN_IF_COMMON_CONTROL_ADR, mer_cmn_ctrl.data);
   2298         mer_cmn_ctrl.fields.pmd_por_h_rstb_frcval = 0;
   2299         mer_cmn_ctrl.fields.pmd_por_h_rstb_frc = 1;
   2300         WRITE_SESTO_PMA_PMD_REG(pa, MERLIN_IF_COMMON_CONTROL_ADR, mer_cmn_ctrl.data);
   2301 
   2302         /* -- Releasing the Core resets*/
   2303         SESTO_CHIP_FIELD_WRITE(pa, FALCON_IF_COMMON_CONTROL, pmd_por_h_rstb_frc,0);
   2304         SESTO_CHIP_FIELD_WRITE(pa, MERLIN_IF_COMMON_CONTROL, pmd_por_h_rstb_frc,0);
   2305         PHYMOD_USLEEP(100);
   2306     } else {
   2307         gen_ctrl.fields.reg_rstb = 0;
   2308         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL1_ADR, gen_ctrl.data);
   2309 
   2310         /* Reset the Merlin */
   2311         SESTO_IF_ERR_RETURN(
   2312         _sesto_set_slice_reg (pa, SESTO_SLICE_BROADCAST,
   2313                            SESTO_MERLIN_CORE, SESTO_DEV_PMA_PMD,
   2314                            0, 0));
   2315         SESTO_CHIP_FIELD_WRITE(pa, M10G_CKRST_CTRL_LANE_CLK_RESET_N_POWERDOWN_CONTROL,
   2316                                    ln_s_rstb, 0);
   2317         PHYMOD_USLEEP(100);
   2318         SESTO_CHIP_FIELD_WRITE(pa, M10G_CKRST_CTRL_LANE_CLK_RESET_N_POWERDOWN_CONTROL,
   2319                                    ln_s_rstb, 1);
   2320         /* Reset the Falcon */
   2321         SESTO_IF_ERR_RETURN(
   2322         _sesto_set_slice_reg (pa, SESTO_SLICE_BROADCAST,
   2323                            SESTO_FALCON_CORE, SESTO_DEV_PMA_PMD,
   2324                            0, 0));
   2325         SESTO_CHIP_FIELD_WRITE(pa, F25G_CKRST_CTRL_RPTR_LN_S_RSTB_CONTROL,
   2326                                    ln_s_rstb, 0);
   2327         PHYMOD_USLEEP(100);
   2328         SESTO_CHIP_FIELD_WRITE(pa, F25G_CKRST_CTRL_RPTR_LN_S_RSTB_CONTROL,
   2329                                    ln_s_rstb, 1);
   2330     }
   2331 
   2332 ERR:
   2333     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2334     return rv;
   2335 }
   2336 
   2337 int _sesto_pcs_link_monitor_enable_set(const phymod_phy_access_t *phy, uint16_t en_dis)
   2338 {
   2339     uint16_t lane = 0;
   2340     uint16_t ip = 0;
   2341     phymod_phy_inf_config_t config;
   2342     uint16_t max_lane = 0, lane_mask=0;
   2343     uint16_t reg_addr = 0;
   2344     int rv = PHYMOD_E_NONE;
   2345     const phymod_access_t *pa = &phy->access;
   2346     DP_FMON0_MAIN_CONTROL_TYPE_T fmon_main_ctrl; 
   2347     DP_MMON0_MAIN_CONTROL_TYPE_T mmon_main_ctrl; 
   2348 
   2349     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   2350     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   2351     PHYMOD_MEMSET(&fmon_main_ctrl, 0, sizeof(DP_FMON0_MAIN_CONTROL_TYPE_T));
   2352     PHYMOD_MEMSET(&mmon_main_ctrl, 0, sizeof(DP_MMON0_MAIN_CONTROL_TYPE_T));
   2353     SESTO_IF_ERR_RETURN(
   2354        _sesto_phy_interface_config_get(phy, 0, &config));
   2355 
   2356     SESTO_GET_IP(phy, config, ip);
   2357 
   2358     lane_mask = (pa->lane_mask) ? pa->lane_mask : 0x3ff;
   2359     max_lane = (ip == SESTO_FALCON_CORE) ? SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   2360 
   2361     PHYMOD_DEBUG_VERBOSE(("%s :: IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   2362                 (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   2363     for (lane = 0; lane < max_lane; lane ++) {
   2364         if ((lane_mask & (1 << lane))) {
   2365             if (ip == SESTO_FALCON_CORE) {
   2366                 reg_addr = DP_FMON0_MAIN_CONTROL_ADR + lane;
   2367                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, fmon_main_ctrl.data);
   2368                 fmon_main_ctrl.fields.fmon0_main_ctrl &= ~(0x1);
   2369                 fmon_main_ctrl.fields.fmon0_main_ctrl |= (en_dis ? 0x1 : 0);
   2370                 WRITE_SESTO_PMA_PMD_REG(pa, reg_addr, fmon_main_ctrl.data);
   2371                 PHYMOD_DEBUG_VERBOSE(("Falcon Link monitor for Lane:%d Data:0x%x\n",
   2372                             lane, fmon_main_ctrl.data));
   2373             } else {
   2374                 reg_addr = DP_MMON0_MAIN_CONTROL_ADR + lane;
   2375                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, mmon_main_ctrl.data);
   2376                 mmon_main_ctrl.fields.mmon0_main_ctrl &= ~(0x1);
   2377                 mmon_main_ctrl.fields.mmon0_main_ctrl |= (en_dis ? 0x1 : 0);
   2378                 WRITE_SESTO_PMA_PMD_REG(pa, reg_addr, mmon_main_ctrl.data);
   2379                 PHYMOD_DEBUG_VERBOSE(("Merlin Link monitor for Lane:%d Data:0x%x\n",
   2380                             lane, mmon_main_ctrl.data));
   2381             }
   2382         }
   2383     }
   2384 
   2385 ERR:
   2386     PHYMOD_FREE(config.device_aux_modes);
   2387     return rv;
   2388 }
   2389 
   2390 int _sesto_pcs_link_monitor_enable_get(const phymod_phy_access_t *phy, uint32_t *get_pcs)
   2391 {
   2392     uint16_t lane = 0;
   2393     uint16_t ip = 0;
   2394     phymod_phy_inf_config_t config;
   2395     uint16_t max_lane = 0, lane_mask=0;
   2396     uint16_t reg_addr = 0;
   2397     int rv = PHYMOD_E_NONE;
   2398     const phymod_access_t *pa = &phy->access;
   2399     DP_FMON0_MAIN_CONTROL_TYPE_T fmon_main_ctrl; 
   2400     DP_MMON0_MAIN_CONTROL_TYPE_T mmon_main_ctrl; 
   2401     
   2402     *get_pcs = 0xffff;
   2403     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   2404     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   2405     PHYMOD_MEMSET(&fmon_main_ctrl, 0, sizeof(DP_FMON0_MAIN_CONTROL_TYPE_T));
   2406     PHYMOD_MEMSET(&mmon_main_ctrl, 0, sizeof(DP_MMON0_MAIN_CONTROL_TYPE_T));
   2407     SESTO_IF_ERR_RETURN(
   2408        _sesto_phy_interface_config_get(phy, 0, &config));
   2409 
   2410     SESTO_GET_IP(phy, config, ip);
   2411 
   2412     lane_mask = (pa->lane_mask) ? pa->lane_mask : 0x3ff;
   2413     max_lane = (ip == SESTO_FALCON_CORE) ? SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   2414 
   2415     PHYMOD_DEBUG_VERBOSE(("%s :: IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   2416                 (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   2417     for (lane = 0; lane < max_lane; lane ++) {
   2418         if ((lane_mask & (1 << lane))) {
   2419             if (ip == SESTO_FALCON_CORE) {
   2420                 reg_addr = DP_FMON0_MAIN_CONTROL_ADR + lane;
   2421                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, fmon_main_ctrl.data);
   2422                 *get_pcs &= fmon_main_ctrl.fields.fmon0_main_ctrl & (0x1);
   2423                 PHYMOD_DEBUG_VERBOSE(("Falcon Get Link monitor for Lane:%d Data:0x%x\n",
   2424                             lane, *get_pcs));
   2425             } else {
   2426                 reg_addr = DP_MMON0_MAIN_CONTROL_ADR + lane;
   2427                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, mmon_main_ctrl.data);
   2428                 *get_pcs &= mmon_main_ctrl.fields.mmon0_main_ctrl & (0x1);
   2429                 PHYMOD_DEBUG_VERBOSE(("Merlin Get Link monitor for Lane:%d Data:0x%x\n",
   2430                             lane, *get_pcs));
   2431             }
   2432         }
   2433     }
   2434 
   2435 ERR:
   2436     PHYMOD_FREE(config.device_aux_modes);
   2437 
   2438     return rv;
   2439 }
   2440 
   2441 int _sesto_get_pcs_link_status(const phymod_phy_access_t *phy, uint32_t *link_sts, uint32_t* lock_lost_lh, uint32_t* error_count)
   2442 {
   2443     uint16_t lane = 0;
   2444     uint16_t ip = 0;
   2445     phymod_phy_inf_config_t config;
   2446     uint16_t max_lane = 0, lane_mask=0, count_msb = 0;
   2447     uint16_t reg_addr = 0;
   2448     uint32_t err_cnt = 0, get_pcs = 0;
   2449     int rv = PHYMOD_E_NONE;
   2450     const phymod_access_t *pa = &phy->access;
   2451     DP_FMON0_MAIN_STATUS_TYPE_T fmon_main_sts;
   2452     DP_MMON0_MAIN_STATUS_TYPE_T mmon_main_sts;
   2453     DP_FMON0_LIVE_STATUS_TYPE_T fmon_live_link;
   2454     DP_MMON0_LIVE_STATUS_TYPE_T mmon_live_link;
   2455 
   2456     *link_sts = 0xffff;
   2457 
   2458     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   2459     SESTO_IF_ERR_RETURN(
   2460          _sesto_pcs_link_monitor_enable_get(phy, &get_pcs));
   2461 
   2462     if (get_pcs) {
   2463         config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   2464         SESTO_IF_ERR_RETURN(
   2465            _sesto_phy_interface_config_get(phy, 0, &config));
   2466     
   2467         SESTO_GET_IP(phy, config, ip);
   2468     
   2469         lane_mask = (pa->lane_mask) ? pa->lane_mask : 0x3ff;
   2470         max_lane = (ip == SESTO_FALCON_CORE) ? SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   2471     
   2472         PHYMOD_DEBUG_VERBOSE(("IP:%s Max_lane:%d lanemask:0x%x\n", 
   2473                     (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   2474 
   2475         PHYMOD_DEBUG_VERBOSE(("Getting PCS Status\n"));
   2476         for (lane = 0; lane < max_lane; lane ++) {
   2477             if ((lane_mask & (1 << lane))) {
   2478                 if (ip == SESTO_FALCON_CORE) {
   2479                     reg_addr = (DP_FMON0_LIVE_STATUS_ADR + lane);
   2480                     READ_SESTO_PMA_PMD_REG(pa, reg_addr, fmon_live_link.data);
   2481                     if (fmon_live_link.fields.fmon0_live_stat & 1) { 
   2482                         *link_sts &= 1;
   2483                         /* PCS lock, Now check Loss of lock*/
   2484                         reg_addr = DP_FMON0_MAIN_STATUS_ADR + lane;
   2485                         READ_SESTO_PMA_PMD_REG(pa, reg_addr, fmon_main_sts.data);
   2486                         if (!(fmon_main_sts.fields.fmon0_main_stat & 0x4)) {
   2487                             /* Loss of link : read error cntr*/
   2488                            reg_addr = (DP_FMON0_CL49_BER_STATUS_ADR + lane);
   2489                            READ_SESTO_PMA_PMD_REG(pa, reg_addr, err_cnt);
   2490                            err_cnt &= 0x7F;
   2491                            err_cnt >>= 1;
   2492                            reg_addr = (DP_FMON0_BER_COUNT_MSB_ADR + lane);
   2493                            READ_SESTO_PMA_PMD_REG(pa, reg_addr, count_msb);
   2494                            err_cnt |= (count_msb) << 6;
   2495                            *link_sts &= 0;
   2496                            PHYMOD_DEBUG_VERBOSE(("Lane:%d Loss of lock: 1 Error Cnt:0x%x\n", 
   2497                                        lane, err_cnt));
   2498                         }
   2499                     } else {
   2500                         *link_sts &= 0;
   2501                     }
   2502                 } else {
   2503                     reg_addr = (DP_MMON0_LIVE_STATUS_ADR + lane);
   2504                     READ_SESTO_PMA_PMD_REG(pa, reg_addr, mmon_live_link.data);
   2505                     if (mmon_live_link.fields.mmon0_live_stat & 1) { 
   2506                         *link_sts &= 1;
   2507                         /* PCS lock, Now check Loss of lock*/
   2508                         reg_addr = (DP_MMON0_MAIN_STATUS_ADR + lane);
   2509                         READ_SESTO_PMA_PMD_REG(pa, reg_addr, mmon_main_sts.data);
   2510                         if (!(mmon_main_sts.fields.mmon0_main_stat & 0x4)) {
   2511                             /* Loss of link : read error cntr*/
   2512                            reg_addr = (DP_MMON0_CL49_BER_STATUS_ADR + lane);
   2513                            READ_SESTO_PMA_PMD_REG(pa, reg_addr, err_cnt);
   2514                            err_cnt &= 0x7F;
   2515                            err_cnt >>= 1;
   2516                            reg_addr = (DP_MMON0_BER_COUNT_MSB_ADR + lane);
   2517                            READ_SESTO_PMA_PMD_REG(pa, reg_addr, count_msb);
   2518                            err_cnt |= (count_msb) << 6;
   2519                            *link_sts &= 0;
   2520                            PHYMOD_DEBUG_VERBOSE(("Lane:%d Loss of lock: 1 Error Cnt:0x%x\n", 
   2521                                        lane, err_cnt));
   2522                         }
   2523                     } else {
   2524                         *link_sts &= 0;
   2525                     }
   2526                 }
   2527             }
   2528         }
   2529     } else {
   2530         PHYMOD_DEBUG_VERBOSE(("PCS MON not Enabled, Reading PMD Status\n"));
   2531         SESTO_IF_ERR_RETURN(
   2532                  _sesto_rx_pmd_lock_get(phy, link_sts));
   2533     }
   2534 ERR:
   2535     if (get_pcs) {
   2536         PHYMOD_FREE(config.device_aux_modes);
   2537     }
   2538 
   2539     return rv;
   2540 }
   2541 int _sesto_merlin_falcon_lane_map_get(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t *cfg,
   2542                                      uint32_t* mer_lane_map, uint32_t* fal_lane_map)
   2543 {
   2544     phymod_phy_inf_config_t config;
   2545     uint16_t core = 0;
   2546     uint32_t lane_mask = 0;
   2547     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   2548     const phymod_access_t *pa = &phy->access;
   2549 
   2550     lane_mask = (pa->lane_mask) ? pa->lane_mask : 0x3ff;
   2551     PHYMOD_MEMCPY(&config, cfg, sizeof(phymod_phy_inf_config_t));
   2552     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)cfg->device_aux_modes;
   2553     SESTO_GET_IP(phy, config, core);
   2554     PHYMOD_DEBUG_VERBOSE(("%s :: core:%d\n", __func__, core));
   2555 
   2556     if (config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) {
   2557         *mer_lane_map = 0x3FF;
   2558         *fal_lane_map = 0xF;
   2559     } else if (core == SESTO_MERLIN_CORE) {
   2560         if (config.data_rate == SESTO_SPD_40G || config.data_rate == SESTO_SPD_42G) {
   2561             if ((aux_mode->pass_thru) && (!aux_mode->BCM84793_capablity)) {
   2562                 *mer_lane_map = 0x33;
   2563                 *fal_lane_map = 0xF;        
   2564             } else if (aux_mode->BCM84793_capablity) {
   2565                 *mer_lane_map = 0xF;
   2566                 *fal_lane_map = 0xF;
   2567             } 
   2568             else { 
   2569                 *mer_lane_map = lane_mask;
   2570                 if (lane_mask == 0xF)
   2571                     *fal_lane_map = 0x3;
   2572                 else if(lane_mask == 0xF0)
   2573                     *fal_lane_map = 0xC;
   2574                 else
   2575                     *fal_lane_map = 0xF;
   2576             }
   2577         } else if (config.data_rate == SESTO_SPD_20G || config.data_rate == SESTO_SPD_21G) {
   2578             if (aux_mode->pass_thru) {
   2579                 *mer_lane_map = lane_mask;
   2580                 if (lane_mask == 0x3)
   2581                     *fal_lane_map = 0x3;
   2582                 else if(lane_mask == 0x30)
   2583                     *fal_lane_map = 0xC;
   2584                 else
   2585                     *fal_lane_map = 0xF;
   2586             } else {
   2587                 *mer_lane_map = lane_mask; 
   2588                 if (lane_mask == 0x3)
   2589                     *fal_lane_map = 0x1;
   2590                 else if(lane_mask == 0x30)
   2591                     *fal_lane_map = 0x4;
   2592                 else
   2593                     *fal_lane_map = 0x5;
   2594             }      
   2595         } else { /* 10G */
   2596             if (aux_mode->BCM84793_capablity) {
   2597                 *mer_lane_map = lane_mask;
   2598                 *fal_lane_map = lane_mask;   
   2599             } else {
   2600                 *mer_lane_map = lane_mask;
   2601                 if ((lane_mask == 0x1) || (lane_mask == 0x2))
   2602                     *fal_lane_map = lane_mask;
   2603                 else if((lane_mask == 0x10) || (lane_mask == 0x20))
   2604                     *fal_lane_map = (lane_mask >> 2);
   2605                 else
   2606                     *fal_lane_map = 0xF;
   2607             }
   2608         }
   2609     } else {
   2610         if (config.data_rate == SESTO_SPD_40G || config.data_rate == SESTO_SPD_42G) {
   2611             if ((aux_mode->pass_thru) && (!aux_mode->BCM84793_capablity)) {
   2612                 *mer_lane_map = 0x33;
   2613                 *fal_lane_map = 0xF;
   2614             } else if (aux_mode->BCM84793_capablity) {
   2615                 *mer_lane_map = 0xF;
   2616                 *fal_lane_map = 0xF;
   2617             }
   2618             else {
   2619                 *fal_lane_map = lane_mask;
   2620                 if (lane_mask == 0x3)
   2621                     *mer_lane_map = 0xF;
   2622                 else if(lane_mask == 0xC)
   2623                     *mer_lane_map = 0xF0;
   2624                 else
   2625                     *mer_lane_map = 0xFF;
   2626             }
   2627         } else if (config.data_rate == SESTO_SPD_20G || config.data_rate == SESTO_SPD_21G) {
   2628             if (aux_mode->pass_thru) {
   2629                 *fal_lane_map = lane_mask;
   2630                 if (lane_mask == 0x3)
   2631                     *mer_lane_map = 0x3;
   2632                 else if(lane_mask == 0xC)
   2633                     *mer_lane_map = 0x30;
   2634                 else
   2635                     *mer_lane_map = 0x33;
   2636             } else {
   2637                 *fal_lane_map = lane_mask;
   2638                 if (lane_mask == 0x1)
   2639                     *mer_lane_map = 0x3;
   2640                 else if(lane_mask == 0x4)
   2641                     *mer_lane_map = 0x30;
   2642                 else
   2643                     *mer_lane_map = 0x33;
   2644             }
   2645         } else { /* 10G */
   2646             if (aux_mode->BCM84793_capablity) {
   2647                 *mer_lane_map = lane_mask;
   2648                 *fal_lane_map = lane_mask;
   2649             } else {
   2650                 *fal_lane_map = lane_mask;
   2651                 if ((lane_mask == 0x1) || (lane_mask == 0x2))
   2652                     *mer_lane_map = lane_mask;
   2653                 else if((lane_mask == 0x4) || (lane_mask == 0x8))
   2654                     *mer_lane_map = (lane_mask << 2);
   2655                 else
   2656                     *mer_lane_map = 0x33;
   2657             }
   2658         }
   2659     }
   2660 
   2661     return PHYMOD_E_NONE;
   2662 }
   2663 
   2664 int _sesto_merlin_lpbk_get(const phymod_access_t *pa, phymod_loopback_mode_t loopback, uint32_t* enable)
   2665 {
   2666     int rv = PHYMOD_E_NONE;
   2667 
   2668     switch (loopback) {
   2669         case phymodLoopbackGlobal:
   2670         case phymodLoopbackGlobalPMD:
   2671             /* Merlin Digital loopback get */
   2672             SESTO_CHIP_FIELD_READ(pa, M10G_TLB_RX_DIG_LPBK_CONFIG,
   2673                                       dig_lpbk_en, (*enable)); 
   2674         break;
   2675         case phymodLoopbackRemotePMD:  /* Merlin Remote loopback get */
   2676             SESTO_CHIP_FIELD_READ(pa, M10G_TLB_TX_RMT_LPBK_CONFIG,
   2677                                       rmt_lpbk_en, (*enable)); 
   2678         break;
   2679         case phymodLoopbackRemotePCS:
   2680             return PHYMOD_E_UNAVAIL;
   2681         default:
   2682         break;
   2683     }
   2684 
   2685 ERR:
   2686     return rv;
   2687 }
   2688 
   2689 int _sesto_falcon_lpbk_get(const phymod_access_t *pa, phymod_loopback_mode_t loopback, uint32_t* enable)
   2690 {
   2691     int rv = PHYMOD_E_NONE;
   2692 
   2693     switch (loopback) {
   2694         case phymodLoopbackGlobal:
   2695         case phymodLoopbackGlobalPMD:
   2696             /* Falcon Digital loopback get */
   2697             SESTO_CHIP_FIELD_READ(pa, F25G_TLB_RX_DIG_LPBK_CONFIG,
   2698                                       dig_lpbk_en, (*enable)); 
   2699         break;
   2700         case phymodLoopbackRemotePMD: /* Falcon Remote loopback get */
   2701             SESTO_CHIP_FIELD_READ(pa, F25G_TLB_TX_RMT_LPBK_CONFIG,
   2702                                       rmt_lpbk_en, (*enable)); 
   2703         break;
   2704         case phymodLoopbackRemotePCS:
   2705             return PHYMOD_E_UNAVAIL;
   2706         default:
   2707         break;
   2708     }
   2709 
   2710 ERR:
   2711     return rv;
   2712 }
   2713 
   2714 int _sesto_loopback_get(const phymod_phy_access_t *phy, phymod_loopback_mode_t loopback, uint32_t* enable)
   2715 {
   2716     phymod_phy_inf_config_t config;
   2717     uint16_t ip = 0;
   2718     uint16_t lane = 0;
   2719     uint16_t lane_mask = 0, max_lane = 0;
   2720     const phymod_access_t *pa = &phy->access;
   2721     int rv = PHYMOD_E_NONE;
   2722 
   2723     *enable = 0; 
   2724     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   2725     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   2726     SESTO_IF_ERR_RETURN(
   2727        _sesto_phy_interface_config_get(phy, 0, &config));
   2728     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   2729     SESTO_GET_IP(phy, config, ip);
   2730 
   2731     max_lane = (ip == SESTO_FALCON_CORE) ?
   2732                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   2733 
   2734     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   2735              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   2736 
   2737     for (lane = 0; lane < max_lane; lane ++) {
   2738         if (lane_mask & (1 << lane)) {
   2739             SESTO_IF_ERR_RETURN(
   2740               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2741                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   2742             if (ip == SESTO_FALCON_CORE) {
   2743                 /* FALCON core loopback set */
   2744                 PHYMOD_DEBUG_VERBOSE(("Falcon loopback get\n"));
   2745                 SESTO_IF_ERR_RETURN(
   2746                   _sesto_falcon_lpbk_get(pa, loopback, enable));
   2747                 break;
   2748             } else {
   2749                 /* MERLIN core loopback get */
   2750                 PHYMOD_DEBUG_VERBOSE(("Merlin loopback get\n"));
   2751                 SESTO_IF_ERR_RETURN(
   2752                   _sesto_merlin_lpbk_get(pa, loopback, enable));
   2753                 break;
   2754             }
   2755         }
   2756     }
   2757 
   2758 ERR:
   2759     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2760     PHYMOD_FREE(config.device_aux_modes);
   2761 
   2762     return rv;
   2763 }
   2764 
   2765 int _sesto_falcon_lpbk_set(const phymod_phy_access_t* phy, const phymod_phy_inf_config_t *config,
   2766                            phymod_loopback_mode_t loopback, uint32_t enable)
   2767 {
   2768     uint16_t lane = 0, data = 0;
   2769     uint32_t mer_lane_mask = 0;
   2770     uint32_t fal_lane_mask = 0;
   2771     const phymod_access_t *pa = &phy->access;
   2772     uint16_t lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   2773     int rv = PHYMOD_E_NONE;
   2774 
   2775     SESTO_IF_ERR_RETURN(
   2776         _sesto_merlin_falcon_lane_map_get(phy, config, &mer_lane_mask, &fal_lane_mask));
   2777 
   2778     PHYMOD_DEBUG_VERBOSE(("Falcon loopback set\n"));
   2779 
   2780     switch (loopback) {
   2781         case phymodLoopbackRemotePMD: /* Falcon remote loopback set */
   2782             for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   2783                 if (lane_mask & (1 << lane)) {
   2784                     SESTO_IF_ERR_RETURN(
   2785                       _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2786                                 SESTO_FALCON_CORE, SESTO_DEV_PMA_PMD,
   2787                                 0, lane));
   2788                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_rmt_lpbk(pa, enable));
   2789                     /* Work around for RMT LOOPBACK issue */
   2790                     if (!enable) {
   2791                         SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_tx_pi_loop_timing_src_sel(0x1));
   2792                     }
   2793                     SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_ln_dp_s_rstb(0));
   2794                     PHYMOD_USLEEP(10);
   2795                     SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_ln_dp_s_rstb(1));
   2796                 }
   2797             }
   2798         break;
   2799         case phymodLoopbackRemotePCS:
   2800             return PHYMOD_E_UNAVAIL;
   2801         break;
   2802         case phymodLoopbackGlobal:
   2803         case phymodLoopbackGlobalPMD: /* Falcon digital loopback set */
   2804         {
   2805             for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   2806                 if (mer_lane_mask & (1 << lane)) {
   2807                     SESTO_IF_ERR_RETURN(
   2808                       _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2809                                 SESTO_MERLIN_CORE, SESTO_DEV_PMA_PMD,
   2810                                 0, lane));
   2811                     SESTO_IF_ERR_RETURN(merlin_sesto_dig_lpbk_rptr(pa, enable, DATA_IN_SIDE));
   2812                 }
   2813             }
   2814             SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2815 
   2816             for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   2817                 if (fal_lane_mask & (1 << lane)) {
   2818                     SESTO_IF_ERR_RETURN(
   2819                       _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2820                                 SESTO_FALCON_CORE, SESTO_DEV_PMA_PMD,
   2821                                 0, lane));
   2822                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_dig_lpbk_rptr(pa, enable, DIG_LPBK_SIDE));
   2823                     /* Disable the prbs_chk_en_auto_mode while seting digital loopback */
   2824                     SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_prbs_chk_en_auto_mode((!enable)));
   2825                     /* TX disable while enabling digital loopback if falcon is on line side PHY-1912 */
   2826                     SESTO_CHIP_FIELD_READ(pa, DP_DECODED_MODE_STATUS0, decoded_mode_falcon_line, data);
   2827                     if (data) {
   2828                         SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_sdk_tx_disable(enable));
   2829                     }
   2830                     SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_ln_dp_s_rstb(0));
   2831                     PHYMOD_USLEEP(10);
   2832                     SESTO_IF_ERR_RETURN(wr_falcon_furia_sesto_ln_dp_s_rstb(1));
   2833                 }
   2834             }
   2835             PHYMOD_USLEEP(50);
   2836         }
   2837         break;
   2838         default :
   2839         break;
   2840     }
   2841 
   2842 ERR:
   2843     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2844     return rv;
   2845 }
   2846 
   2847 int _sesto_merlin_lpbk_set(const phymod_phy_access_t* phy, const phymod_phy_inf_config_t *config,
   2848                            phymod_loopback_mode_t loopback, uint32_t enable)
   2849 {
   2850     uint16_t lane = 0, data = 0;
   2851     uint32_t mer_lane_mask = 0;
   2852     uint32_t fal_lane_mask = 0;
   2853     const phymod_access_t *pa = &phy->access;
   2854     uint16_t lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   2855     int rv = PHYMOD_E_NONE;
   2856 
   2857     SESTO_IF_ERR_RETURN(
   2858         _sesto_merlin_falcon_lane_map_get(phy, config, &mer_lane_mask, &fal_lane_mask));
   2859     PHYMOD_DEBUG_VERBOSE(("Merlin loopback set\n"));
   2860 
   2861     switch (loopback) {
   2862         case phymodLoopbackRemotePMD:  /* Merlin remote loopback set */
   2863             for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   2864                 if (lane_mask & (1 << lane)) {
   2865                     SESTO_IF_ERR_RETURN(
   2866                       _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2867                                 SESTO_MERLIN_CORE, SESTO_DEV_PMA_PMD,
   2868                                 0, lane));
   2869                     SESTO_IF_ERR_RETURN(merlin_sesto_rmt_lpbk(pa, enable));
   2870                     SESTO_IF_ERR_RETURN(wr_ln_dp_s_rstb(0));
   2871                     PHYMOD_USLEEP(10);
   2872                     SESTO_IF_ERR_RETURN(wr_ln_dp_s_rstb(1));
   2873 
   2874                 } 
   2875             }
   2876         break;
   2877         case phymodLoopbackRemotePCS:
   2878             return PHYMOD_E_UNAVAIL;
   2879         break;
   2880         case phymodLoopbackGlobal:
   2881         case phymodLoopbackGlobalPMD: /* Merlin digital loopack set */
   2882         {
   2883             for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   2884                 if (fal_lane_mask & (1 << lane)) {
   2885                     SESTO_IF_ERR_RETURN(
   2886                       _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2887                                 SESTO_FALCON_CORE, SESTO_DEV_PMA_PMD,
   2888                                 0, lane));
   2889                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_dig_lpbk_rptr(pa, enable, DATA_IN_SIDE));
   2890                 }
   2891             }
   2892             SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2893 
   2894             for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   2895                 if (mer_lane_mask & (1 << lane)) {
   2896                     SESTO_IF_ERR_RETURN(
   2897                       _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   2898                                 SESTO_MERLIN_CORE, SESTO_DEV_PMA_PMD,
   2899                                 0, lane));
   2900                     SESTO_IF_ERR_RETURN(merlin_sesto_dig_lpbk_rptr(pa, enable, DIG_LPBK_SIDE));
   2901                     /* Disable the prbs_chk_en_auto_mode while seting digital loopback */
   2902                     SESTO_IF_ERR_RETURN(wr_prbs_chk_en_auto_mode((!enable)));
   2903                     /* TX disable while enabling digital loopback if Merlin is on line side  PHY-2086 */
   2904                     SESTO_CHIP_FIELD_READ(pa, DP_DECODED_MODE_STATUS0, decoded_mode_falcon_line, data);
   2905                     if (!data) {
   2906                         SESTO_IF_ERR_RETURN(wr_sdk_tx_disable(enable));
   2907                     }
   2908                     SESTO_IF_ERR_RETURN(wr_ln_dp_s_rstb(0));
   2909                     PHYMOD_USLEEP(10);
   2910                     SESTO_IF_ERR_RETURN(wr_ln_dp_s_rstb(1));
   2911                 }
   2912             }
   2913             PHYMOD_USLEEP(50);
   2914         }
   2915         break;
   2916         default :
   2917         break;
   2918     }
   2919 
   2920 ERR:
   2921     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   2922     return rv;
   2923 }
   2924 int _sesto_if_ctrl_frc_tx_disable(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t *config,
   2925                                   uint32_t enable)
   2926 {
   2927     uint16_t lane = 0;
   2928     uint32_t mer_lane_mask = 0;
   2929     uint32_t fal_lane_mask = 0;
   2930     int rv = PHYMOD_E_NONE;
   2931     const phymod_access_t *pa = &phy->access;
   2932     MERLIN_IF_CONTROL1_LANE0_TYPE_T mer_ctrl_lane;
   2933     FALCON_IF_CONTROL1_LANE0_TYPE_T fal_ctrl_lane;
   2934 
   2935     SESTO_IF_ERR_RETURN(
   2936         _sesto_merlin_falcon_lane_map_get(phy, config, &mer_lane_mask, &fal_lane_mask));
   2937 
   2938     /* Falcon Force clear any Tx disables set by HW */
   2939     for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   2940         if (fal_lane_mask & (1 << lane)) {
   2941             READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL1_LANE0_ADR + lane),
   2942                                        fal_ctrl_lane.data);
   2943             fal_ctrl_lane.fields.pmd_tx_disable_0_frc = (enable ? 1 : 0);
   2944             fal_ctrl_lane.fields.pmd_tx_disable_0_frcval = 0;
   2945             WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL1_LANE0_ADR + lane),
   2946                                        fal_ctrl_lane.data);
   2947         }
   2948     }
   2949     /* Merlin Force clear any Tx disables set by HW */
   2950     for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   2951         if (mer_lane_mask & (1 << lane)) {
   2952             READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL1_LANE0_ADR + lane),
   2953                                         mer_ctrl_lane.data);
   2954             mer_ctrl_lane.fields.pmd_tx_disable_0_frc = (enable ? 1 : 0);
   2955             mer_ctrl_lane.fields.pmd_tx_disable_0_frcval = 0;
   2956             WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL1_LANE0_ADR + lane),
   2957                                         mer_ctrl_lane.data);
   2958         }
   2959     }
   2960 
   2961 ERR:
   2962     return rv;
   2963 }
   2964 
   2965 int _sesto_loopback_set(const phymod_phy_access_t *phy, phymod_loopback_mode_t loopback, uint32_t enable)
   2966 {
   2967     phymod_phy_inf_config_t config;
   2968     uint16_t ip = 0;
   2969     uint32_t temp = 0;
   2970     uint16_t data = 0, retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   2971     SESTO_DEVICE_AUX_MODE_T aux_mode;
   2972     const phymod_access_t *pa = &phy->access;
   2973     int rv = PHYMOD_E_NONE;
   2974 
   2975     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   2976     config.device_aux_modes = &aux_mode;
   2977     SESTO_IF_ERR_RETURN(
   2978        _sesto_phy_interface_config_get(phy, 0, &config));
   2979     SESTO_GET_IP(phy, config, ip);
   2980     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   2981                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   2982 
   2983     PHYMOD_DEBUG_VERBOSE(("sesto looopback set\n"));
   2984     do {
   2985         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data);
   2986     } while ((data != 0) && (retry_cnt --));
   2987     if (retry_cnt == 0) {
   2988         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   2989                (_PHYMOD_MSG("loopback config failed, micro controller is busy..")));
   2990     }
   2991     /*Work around for loopback call without enable loopback */
   2992     SESTO_IF_ERR_RETURN(
   2993         _sesto_loopback_get(phy, loopback, &temp));
   2994 
   2995     if(enable || temp) {
   2996         if (ip == SESTO_FALCON_CORE) {
   2997             /* FALCON core loopback set */
   2998             SESTO_IF_ERR_RETURN(
   2999                 _sesto_falcon_lpbk_set(phy, &config, loopback, enable));
   3000         } else {
   3001             /* MERLIN core loopback set */
   3002             SESTO_IF_ERR_RETURN(
   3003                 _sesto_merlin_lpbk_set(phy, &config, loopback, enable));
   3004         }
   3005 
   3006         /* Set bit 13 in GPREG11 for loopback change */
   3007         SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GPREG11, lpbk_change, 1);
   3008         /* Clear any forces on Tx disables set by HW while disable */
   3009         SESTO_IF_ERR_RETURN(_sesto_if_ctrl_frc_tx_disable(phy, &config, enable));
   3010 
   3011         /*  Set FW_ENABLE = 1 */
   3012         SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, 1);
   3013         do {
   3014             SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data);
   3015         } while ((data != 0) && (retry_cnt --));
   3016         if (retry_cnt == 0) {
   3017             SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   3018                 (_PHYMOD_MSG("loopback config failed, micro controller is busy..")));
   3019         }
   3020         if (enable) {
   3021             /* Clear any forces on Tx disables set by HW */
   3022             SESTO_IF_ERR_RETURN(_sesto_if_ctrl_frc_tx_disable(phy, &config, enable));
   3023 
   3024             if (ip == SESTO_FALCON_CORE) {
   3025                 /* FALCON core loopback set */
   3026                 SESTO_IF_ERR_RETURN(
   3027                     _sesto_falcon_lpbk_set(phy, &config, loopback, enable));
   3028             } else {
   3029                 /* MERLIN core loopback set */
   3030                 SESTO_IF_ERR_RETURN(
   3031                     _sesto_merlin_lpbk_set(phy, &config, loopback, enable));
   3032             }
   3033         }
   3034     }
   3035 
   3036 ERR:
   3037     return rv;
   3038 }
   3039 
   3040 int _sesto_tx_rx_polarity_set(const phymod_phy_access_t *phy, uint32_t tx_polarity, uint32_t rx_polarity)
   3041 {
   3042     phymod_phy_inf_config_t config;
   3043     uint16_t ip = 0;
   3044     uint16_t lane = 0;
   3045     uint16_t lane_mask = 0, max_lane = 0;
   3046     const phymod_access_t *pa = &phy->access;
   3047     int rv = PHYMOD_E_NONE;
   3048 
   3049     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3050     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3051     SESTO_IF_ERR_RETURN(
   3052        _sesto_phy_interface_config_get(phy, 0, &config));
   3053     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3054     SESTO_GET_IP(phy, config, ip);
   3055 
   3056     max_lane = (ip == SESTO_FALCON_CORE) ?
   3057                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3058 
   3059     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3060              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3061 
   3062     for (lane = 0; lane < max_lane; lane ++) {
   3063         if (lane_mask & (1 << lane)) {
   3064             SESTO_IF_ERR_RETURN(
   3065               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3066                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3067             if (ip == SESTO_FALCON_CORE) {
   3068                 /* FALCON polarity inversion */
   3069                 PHYMOD_DEBUG_VERBOSE(("Falcon polarity inversion set\n"));
   3070                 /* Write to Tx misc config register */
   3071                 SESTO_CHIP_FIELD_WRITE(pa, F25G_TLB_TX_TLB_TX_MISC_CONFIG,
   3072                                            tx_pmd_dp_invert, tx_polarity);
   3073                 /* Write to Rx misc config register */
   3074                 SESTO_CHIP_FIELD_WRITE(pa, F25G_TLB_RX_TLB_RX_MISC_CONFIG,
   3075                                            rx_pmd_dp_invert, rx_polarity);
   3076             } else {
   3077                 /* MERLIN polarity inversion */
   3078                 PHYMOD_DEBUG_VERBOSE(("Merlin polarity inversion set\n"));
   3079                 /* Write to Tx misc config register */
   3080                 SESTO_CHIP_FIELD_WRITE(pa, M10G_TLB_TX_TLB_TX_MISC_CONFIG,
   3081                                            tx_pmd_dp_invert, tx_polarity);
   3082                 /* Write to Rx misc config register */
   3083                 SESTO_CHIP_FIELD_WRITE(pa, M10G_TLB_RX_TLB_RX_MISC_CONFIG,
   3084                                            rx_pmd_dp_invert, rx_polarity);
   3085             }
   3086         }
   3087     }
   3088 
   3089 ERR:
   3090     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3091     PHYMOD_FREE(config.device_aux_modes);
   3092 
   3093     return rv;
   3094 }
   3095 
   3096 int _sesto_tx_rx_polarity_get(const phymod_phy_access_t *phy, uint32_t *tx_polarity, uint32_t *rx_polarity)
   3097 {
   3098     phymod_phy_inf_config_t config;
   3099     uint16_t ip = 0;
   3100     uint16_t lane = 0;
   3101     uint16_t lane_mask = 0, max_lane = 0;
   3102     const phymod_access_t *pa = &phy->access;
   3103     int rv = PHYMOD_E_NONE;
   3104 
   3105     *tx_polarity = 1;
   3106     *rx_polarity = 1;
   3107 
   3108     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3109     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3110     SESTO_IF_ERR_RETURN(
   3111        _sesto_phy_interface_config_get(phy, 0, &config));
   3112     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3113     SESTO_GET_IP(phy, config, ip);
   3114 
   3115     max_lane = (ip == SESTO_FALCON_CORE) ?
   3116                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3117 
   3118     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3119              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3120 
   3121     for (lane = 0; lane < max_lane; lane ++) {
   3122         if (lane_mask & (1 << lane)) {
   3123             SESTO_IF_ERR_RETURN(
   3124               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3125                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3126             if (ip == SESTO_FALCON_CORE) {
   3127                 /* FALCON polarity */
   3128                 PHYMOD_DEBUG_VERBOSE(("Falcon polarity get\n"));
   3129                 /* Read to Tx misc config register */
   3130                 SESTO_CHIP_FIELD_READ(pa, F25G_TLB_TX_TLB_TX_MISC_CONFIG,
   3131                                           tx_pmd_dp_invert, (*tx_polarity));
   3132                 /* Read to Rx misc config register */
   3133                 SESTO_CHIP_FIELD_READ(pa, F25G_TLB_RX_TLB_RX_MISC_CONFIG,
   3134                                           rx_pmd_dp_invert, (*rx_polarity));
   3135                 break;
   3136             } else {
   3137                 /* MERLIN polarity */
   3138                 PHYMOD_DEBUG_VERBOSE(("Merlin polarity get\n"));
   3139                 /* Read to Tx misc config register */
   3140                 SESTO_CHIP_FIELD_READ(pa, M10G_TLB_TX_TLB_TX_MISC_CONFIG,
   3141                                           tx_pmd_dp_invert, (*tx_polarity));
   3142                 /* Read to Rx misc config register */
   3143                 SESTO_CHIP_FIELD_READ(pa, M10G_TLB_RX_TLB_RX_MISC_CONFIG,
   3144                                           rx_pmd_dp_invert, (*rx_polarity));
   3145                 break;
   3146             }
   3147         }
   3148     }
   3149 
   3150 ERR:
   3151     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3152     PHYMOD_FREE(config.device_aux_modes);
   3153 
   3154     return rv;
   3155 }
   3156 
   3157 int _sesto_tx_set(const phymod_phy_access_t *phy, const phymod_tx_t* tx)
   3158 {
   3159     phymod_phy_inf_config_t config;
   3160     uint16_t ip = 0;
   3161     uint16_t lane = 0;
   3162     uint16_t lane_mask = 0, max_lane = 0;
   3163     const phymod_access_t *pa = &phy->access;
   3164     int rv = PHYMOD_E_NONE;
   3165 
   3166     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3167     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3168     SESTO_IF_ERR_RETURN(
   3169        _sesto_phy_interface_config_get(phy, 0, &config));
   3170     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3171     SESTO_GET_IP(phy, config, ip);
   3172 
   3173     max_lane = (ip == SESTO_FALCON_CORE) ?
   3174                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3175 
   3176     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3177              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3178 
   3179     for (lane = 0; lane < max_lane; lane ++) {
   3180         if (lane_mask & (1 << lane)) {
   3181             SESTO_IF_ERR_RETURN(
   3182               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3183                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3184             if (ip == SESTO_FALCON_CORE) {
   3185                 /* FALCON TXFIR */
   3186                 PHYMOD_DEBUG_VERBOSE(("Falcon TXFIR set\n"));
   3187                 SESTO_IF_ERR_RETURN
   3188                     (falcon_furia_sesto_write_tx_afe(pa, TX_AFE_PRE, (int8_t)tx->pre));
   3189                 SESTO_IF_ERR_RETURN
   3190                     (falcon_furia_sesto_write_tx_afe(pa, TX_AFE_MAIN, (int8_t)tx->main));
   3191                 SESTO_IF_ERR_RETURN
   3192                     (falcon_furia_sesto_write_tx_afe(pa, TX_AFE_POST1, (int8_t)tx->post));
   3193                 SESTO_IF_ERR_RETURN
   3194                     (falcon_furia_sesto_write_tx_afe(pa, TX_AFE_POST2, (int8_t)tx->post2));
   3195                 SESTO_IF_ERR_RETURN
   3196                     (falcon_furia_sesto_write_tx_afe(pa, TX_AFE_POST3, (int8_t)tx->post3));
   3197                 SESTO_IF_ERR_RETURN
   3198                     (falcon_furia_sesto_write_tx_afe(pa, TX_AFE_AMP, (int8_t)tx->amp));
   3199             } else {
   3200                 /* MERLIN TXFIR */
   3201                 PHYMOD_DEBUG_VERBOSE(("Merlin TXFIR set\n"));
   3202                 SESTO_IF_ERR_RETURN
   3203                     (merlin_sesto_apply_txfir_cfg(pa, (int8_t)tx->pre, (int8_t)tx->main, (int8_t)tx->post, (int8_t)tx->post2));
   3204             }
   3205         }
   3206     }
   3207 
   3208 ERR:
   3209     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3210     PHYMOD_FREE(config.device_aux_modes);
   3211 
   3212     return rv;
   3213 }    
   3214 
   3215 int _sesto_tx_get(const phymod_phy_access_t *phy, phymod_tx_t* tx)
   3216 {
   3217     phymod_phy_inf_config_t config;
   3218     uint16_t ip = 0;
   3219     uint16_t lane = 0;
   3220     uint16_t lane_mask = 0, max_lane = 0;
   3221     const phymod_access_t *pa = &phy->access;
   3222     int rv = PHYMOD_E_NONE;
   3223     int8_t value = 0;
   3224 
   3225     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3226     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3227     SESTO_IF_ERR_RETURN(
   3228        _sesto_phy_interface_config_get(phy, 0, &config));
   3229     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3230     SESTO_GET_IP(phy, config, ip);
   3231 
   3232     max_lane = (ip == SESTO_FALCON_CORE) ?
   3233                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3234 
   3235     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3236              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3237 
   3238     for (lane = 0; lane < max_lane; lane ++) {
   3239         if (lane_mask & (1 << lane)) {
   3240             SESTO_IF_ERR_RETURN(
   3241               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3242                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3243             if (ip == SESTO_FALCON_CORE) {
   3244                 /* FALCON TXFIR */
   3245                 PHYMOD_DEBUG_VERBOSE(("Falcon TXFIR get\n"));
   3246                 SESTO_IF_ERR_RETURN
   3247                     (falcon_furia_sesto_read_tx_afe(pa, TX_AFE_PRE, &value));
   3248                      tx->pre = value;
   3249                 SESTO_IF_ERR_RETURN
   3250                     (falcon_furia_sesto_read_tx_afe(pa, TX_AFE_MAIN, &value));
   3251                     tx->main = value;
   3252                 SESTO_IF_ERR_RETURN
   3253                     (falcon_furia_sesto_read_tx_afe(pa, TX_AFE_POST1, &value));
   3254                     tx->post = value;
   3255                 SESTO_IF_ERR_RETURN
   3256                     (falcon_furia_sesto_read_tx_afe(pa, TX_AFE_POST2, &value));
   3257                     tx->post2 = value;
   3258                 SESTO_IF_ERR_RETURN
   3259                     (falcon_furia_sesto_read_tx_afe(pa, TX_AFE_POST3, &value));
   3260                       tx->post3 = value;
   3261                 SESTO_IF_ERR_RETURN
   3262                     (falcon_furia_sesto_read_tx_afe(pa, TX_AFE_AMP, &value));
   3263                      tx->amp = value;
   3264                 break;
   3265             } else {
   3266                 /* MERLIN TXFIR */
   3267                 PHYMOD_DEBUG_VERBOSE(("Merlin TXFIR get\n"));
   3268                 SESTO_IF_ERR_RETURN
   3269                     (merlin_sesto_read_tx_afe(pa, TX_AFE_PRE, &value));
   3270                      tx->pre = value;
   3271                 SESTO_IF_ERR_RETURN
   3272                     (merlin_sesto_read_tx_afe(pa, TX_AFE_MAIN, &value));
   3273                     tx->main = value;
   3274                 SESTO_IF_ERR_RETURN
   3275                     (merlin_sesto_read_tx_afe(pa, TX_AFE_POST1, &value));
   3276                      tx->post = value;
   3277                 SESTO_IF_ERR_RETURN
   3278                     (merlin_sesto_read_tx_afe(pa, TX_AFE_POST2, &value));
   3279                     tx->post2 = value;
   3280                 break;
   3281             }
   3282         }
   3283     }
   3284 
   3285 ERR:
   3286     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3287     PHYMOD_FREE(config.device_aux_modes);
   3288 
   3289     return rv;
   3290 }    
   3291 
   3292 int _sesto_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
   3293 {
   3294     phymod_phy_inf_config_t config;
   3295     uint16_t ip = 0;
   3296     uint16_t lane = 0;
   3297     uint16_t lane_mask = 0, max_lane = 0;
   3298     uint16_t indx = 0;
   3299     uint8_t MAX_MERLIN_DFES_TAPS = 5;
   3300     const phymod_access_t *pa = &phy->access;
   3301     int rv = PHYMOD_E_NONE;
   3302 
   3303 
   3304     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3305     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3306     SESTO_IF_ERR_RETURN(
   3307        _sesto_phy_interface_config_get(phy, 0, &config));
   3308     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3309     SESTO_GET_IP(phy, config, ip);
   3310 
   3311     max_lane = (ip == SESTO_FALCON_CORE) ?
   3312                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3313 
   3314     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3315              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3316 
   3317     for (lane = 0; lane < max_lane; lane ++) {
   3318         if (lane_mask & (1 << lane)) {
   3319             SESTO_IF_ERR_RETURN(
   3320                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3321                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3322             if (ip == SESTO_FALCON_CORE) {
   3323                 /* FALCON RXFIR set */
   3324                 PHYMOD_DEBUG_VERBOSE(("Falcon RXFIR set\n"));
   3325 
   3326                 /*params check*/
   3327                 for (indx = 0 ; indx < PHYMOD_NUM_DFE_TAPS; indx++){
   3328                     if(rx->dfe[indx].enable && (rx->num_of_dfe_taps > PHYMOD_NUM_DFE_TAPS)) {
   3329                         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set")));
   3330                     }
   3331                 }
   3332 
   3333                 /*vga set*/
   3334                 /* first stop the rx adaption */
   3335                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_stop_rx_adaptation(pa, 1));
   3336                 if (rx->vga.enable) {
   3337                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_write_rx_afe(pa, RX_AFE_VGA, rx->vga.value));
   3338                 }
   3339                 /*dfe set*/
   3340                 for (indx = 0 ; indx < PHYMOD_NUM_DFE_TAPS; indx++){
   3341                     if(rx->dfe[indx].enable){
   3342                         SESTO_IF_ERR_RETURN(falcon_furia_sesto_write_rx_afe(pa, RX_AFE_DFE1+indx, rx->dfe[indx].value));
   3343                     }
   3344                 }
   3345 
   3346                 /*peaking filter set*/
   3347                 if(rx->peaking_filter.enable){
   3348                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_write_rx_afe(pa, RX_AFE_PF, rx->peaking_filter.value));
   3349                 }
   3350 
   3351                 if(rx->low_freq_peaking_filter.enable){
   3352                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_write_rx_afe(pa, RX_AFE_PF2, rx->low_freq_peaking_filter.value));
   3353                 }
   3354             } else {
   3355                 /* MERLIN RXFIR set*/
   3356                 PHYMOD_DEBUG_VERBOSE(("Merlin RXFIR set\n"));
   3357 
   3358                 /*params check*/
   3359                 for (indx = 0 ; indx < MAX_MERLIN_DFES_TAPS; indx++){
   3360                     if(rx->dfe[indx].enable && (rx->num_of_dfe_taps > MAX_MERLIN_DFES_TAPS)) {
   3361                         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("illegal number of DFEs to set")));
   3362                     }
   3363                 }
   3364 
   3365                 /* first stop the rx adaption */
   3366                 SESTO_IF_ERR_RETURN(merlin_sesto_stop_rx_adaptation(pa, 1));
   3367                 /*vga set*/
   3368                 if (rx->vga.enable) {
   3369                     SESTO_IF_ERR_RETURN(merlin_sesto_write_rx_afe(pa, RX_AFE_VGA, rx->vga.value));
   3370                 }
   3371                 /*dfe set*/
   3372                 /* PHYMOD_NUM_DFE_TAPS are 14 but MERLING core has 5 only DFEs */  
   3373                 for (indx = 0 ; indx < MAX_MERLIN_DFES_TAPS; indx++){
   3374                     if(rx->dfe[indx].enable){
   3375                         SESTO_IF_ERR_RETURN(merlin_sesto_write_rx_afe(pa, RX_AFE_DFE1+indx, rx->dfe[indx].value));
   3376                     }
   3377                 }
   3378 
   3379                 /*peaking filter set*/
   3380                 if(rx->peaking_filter.enable){
   3381                     SESTO_IF_ERR_RETURN(merlin_sesto_write_rx_afe(pa, RX_AFE_PF, rx->peaking_filter.value));
   3382                 }
   3383 
   3384                 if(rx->low_freq_peaking_filter.enable){
   3385                     SESTO_IF_ERR_RETURN(merlin_sesto_write_rx_afe(pa, RX_AFE_PF2, rx->low_freq_peaking_filter.value));
   3386                 }
   3387             }
   3388         }
   3389     }
   3390 
   3391 ERR:
   3392     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3393     PHYMOD_FREE(config.device_aux_modes);
   3394 
   3395     return rv;
   3396 }    
   3397 int _sesto_rx_adaptation_resume(const phymod_phy_access_t* phy)
   3398 {
   3399     phymod_phy_inf_config_t config;
   3400     uint16_t ip = 0;
   3401     uint16_t lane = 0;
   3402     uint16_t lane_mask = 0, max_lane = 0;
   3403     const phymod_access_t *pa = &phy->access;
   3404     int rv = PHYMOD_E_NONE;
   3405 
   3406 
   3407     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3408     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3409     SESTO_IF_ERR_RETURN(
   3410        _sesto_phy_interface_config_get(phy, 0, &config));
   3411     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3412     SESTO_GET_IP(phy, config, ip);
   3413 
   3414     max_lane = (ip == SESTO_FALCON_CORE) ?
   3415                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3416 
   3417     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3418              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3419 
   3420     for (lane = 0; lane < max_lane; lane ++) {
   3421         if (lane_mask & (1 << lane)) {
   3422             SESTO_IF_ERR_RETURN(
   3423                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3424                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3425             if (ip == SESTO_FALCON_CORE) {
   3426                 PHYMOD_DEBUG_VERBOSE(("Falcon RX RESUME set\n"));
   3427                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_stop_rx_adaptation(pa, 0));
   3428             } else {
   3429                 PHYMOD_DEBUG_VERBOSE(("Merlin RX RESUME set\n"));
   3430                 SESTO_IF_ERR_RETURN(merlin_sesto_stop_rx_adaptation(pa, 0));
   3431             }
   3432         }
   3433     }
   3434 
   3435 ERR:
   3436     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3437     PHYMOD_FREE(config.device_aux_modes);
   3438 
   3439     return rv;
   3440 }
   3441 
   3442 int _sesto_rx_get(const phymod_phy_access_t *phy, phymod_rx_t* rx)
   3443 {
   3444     phymod_phy_inf_config_t config;
   3445     uint16_t ip = 0;
   3446     uint16_t lane = 0;
   3447     uint16_t indx = 0;
   3448     int8_t dfe = 0;
   3449     int8_t vga = 0;
   3450     int8_t pf = 0;
   3451     int8_t low_freq_pf = 0;
   3452     uint32_t rx_adaptation;
   3453     uint16_t lane_mask = 0, max_lane = 0;
   3454     int8_t MAX_MERLIN_DFES_TAPS = 5;
   3455     const phymod_access_t *pa = &phy->access;
   3456     int rv = PHYMOD_E_NONE;
   3457 
   3458     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3459     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3460     SESTO_IF_ERR_RETURN(
   3461        _sesto_phy_interface_config_get(phy, 0, &config));
   3462     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3463     SESTO_GET_IP(phy, config, ip);
   3464 
   3465     max_lane = (ip == SESTO_FALCON_CORE) ?
   3466                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3467 
   3468     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3469              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3470 
   3471     for (lane = 0; lane < max_lane; lane ++) {
   3472         if (lane_mask & (1 << lane)) {
   3473             SESTO_IF_ERR_RETURN(
   3474              _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3475                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3476             if (ip == SESTO_FALCON_CORE) {
   3477                 /* FALCON RXFIR get */
   3478                 PHYMOD_DEBUG_VERBOSE(("Falcon RXFIR get\n"));
   3479 
   3480                 rx_adaptation = PHYMOD_RX_ADAPTATION_ON_GET(rx);
   3481                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_stop_rx_adaptation(&phy->access, 1));
   3482 
   3483                 /*vga get*/
   3484                 rx->num_of_dfe_taps = PHYMOD_NUM_DFE_TAPS;
   3485                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_read_rx_afe(pa, RX_AFE_VGA, &vga));
   3486                 rx->vga.value = vga; 
   3487                 rx->vga.enable = 1;
   3488 
   3489                 /*dfe get*/
   3490                 for (indx = 0 ; indx < PHYMOD_NUM_DFE_TAPS; indx++){
   3491                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_read_rx_afe(pa, (RX_AFE_DFE1+indx), &dfe));
   3492                     rx->dfe[indx].value = dfe;
   3493                     rx->dfe[indx].enable = 1;
   3494                 }
   3495 
   3496                 /*peaking filter get*/
   3497                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_read_rx_afe(pa, RX_AFE_PF, &pf));
   3498                 rx->peaking_filter.value = pf;
   3499                 rx->peaking_filter.enable = 1;
   3500                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_read_rx_afe(pa, RX_AFE_PF2, &low_freq_pf));
   3501                 rx->low_freq_peaking_filter.value = low_freq_pf;
   3502                 rx->low_freq_peaking_filter.enable = 1;
   3503 
   3504                 if (rx_adaptation) {
   3505                     SESTO_IF_ERR_RETURN(falcon_furia_sesto_stop_rx_adaptation(&phy->access, 0));
   3506                 }
   3507 
   3508                 break;
   3509             } else {
   3510                 /* MERLIN RXFIR get */
   3511                 PHYMOD_DEBUG_VERBOSE(("Merlin RXFIR get\n"));
   3512 
   3513                 rx_adaptation = PHYMOD_RX_ADAPTATION_ON_GET(rx);
   3514                 SESTO_IF_ERR_RETURN(merlin_sesto_stop_rx_adaptation(&phy->access, 1));
   3515 
   3516                 /*vga get*/
   3517                 /* PHYMOD_NUM_DFE_TAPS are 14 but MERLING has only 5 DFEs */  
   3518                 rx->num_of_dfe_taps = MAX_MERLIN_DFES_TAPS;
   3519                 SESTO_IF_ERR_RETURN(merlin_sesto_read_rx_afe(pa, RX_AFE_VGA, &vga));
   3520                 rx->vga.value = vga;
   3521                 rx->vga.enable = 1;
   3522 
   3523                 /*dfe get*/
   3524                 for (indx = 0 ; indx < MAX_MERLIN_DFES_TAPS; indx++){
   3525                     SESTO_IF_ERR_RETURN(merlin_sesto_read_rx_afe(pa, (RX_AFE_DFE1+indx), &dfe));
   3526                     rx->dfe[indx].value = dfe;
   3527                     rx->dfe[indx].enable = 1;
   3528                 }
   3529 
   3530                 /*peaking filter get*/
   3531                 SESTO_IF_ERR_RETURN(merlin_sesto_read_rx_afe(pa, RX_AFE_PF, &pf));
   3532                 rx->peaking_filter.value = pf;
   3533                  rx->peaking_filter.enable = 1;
   3534                 SESTO_IF_ERR_RETURN(merlin_sesto_read_rx_afe(pa, RX_AFE_PF2, &low_freq_pf));
   3535                 rx->low_freq_peaking_filter.value = low_freq_pf;
   3536                 rx->low_freq_peaking_filter.enable = 1;
   3537 
   3538                 if (rx_adaptation) {
   3539                     SESTO_IF_ERR_RETURN(merlin_sesto_stop_rx_adaptation(&phy->access, 0));
   3540                 }
   3541 
   3542                 break;
   3543             }
   3544         }
   3545     }
   3546 
   3547 ERR:
   3548     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3549     PHYMOD_FREE(config.device_aux_modes);
   3550 
   3551     return rv;
   3552 }
   3553 int _sesto_falcon_phy_reset_set(const phymod_access_t *pa, const phymod_phy_reset_t* reset)
   3554 {
   3555     int rv = PHYMOD_E_NONE;
   3556     F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_TYPE_T pwrdwn_ctrl;
   3557 
   3558     /* TX AFE Lane Reset */
   3559     switch (reset->tx) {
   3560         /* In Reset */
   3561         case phymodResetDirectionIn:
   3562             READ_SESTO_PMA_PMD_REG(pa,
   3563                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3564                    pwrdwn_ctrl.data);
   3565             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 1;
   3566             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3567             WRITE_SESTO_PMA_PMD_REG(pa,
   3568                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3569                    pwrdwn_ctrl.data);
   3570 
   3571         break;
   3572         /* Out Reset */
   3573         case phymodResetDirectionOut:
   3574             READ_SESTO_PMA_PMD_REG(pa,
   3575                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3576                    pwrdwn_ctrl.data);
   3577             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 0;
   3578             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3579             WRITE_SESTO_PMA_PMD_REG(pa,
   3580                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3581                    pwrdwn_ctrl.data);
   3582             /* -- Releasing forces -- */
   3583             READ_SESTO_PMA_PMD_REG(pa,
   3584                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3585                    pwrdwn_ctrl.data);
   3586             pwrdwn_ctrl.fields.afe_tx_reset_frc = 0;
   3587             WRITE_SESTO_PMA_PMD_REG(pa,
   3588                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3589                    pwrdwn_ctrl.data);
   3590         break;
   3591         /* Toggle Reset */
   3592         case phymodResetDirectionInOut:
   3593             READ_SESTO_PMA_PMD_REG(pa,
   3594                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3595                    pwrdwn_ctrl.data);
   3596             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 1;
   3597             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3598             WRITE_SESTO_PMA_PMD_REG(pa,
   3599                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3600                    pwrdwn_ctrl.data);
   3601             PHYMOD_USLEEP(10);
   3602             READ_SESTO_PMA_PMD_REG(pa,
   3603                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3604                    pwrdwn_ctrl.data);
   3605             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 0;
   3606             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3607             WRITE_SESTO_PMA_PMD_REG(pa,
   3608                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3609                    pwrdwn_ctrl.data);
   3610             /* -- Releasing forces -- */
   3611             READ_SESTO_PMA_PMD_REG(pa,
   3612                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3613                    pwrdwn_ctrl.data);
   3614             pwrdwn_ctrl.fields.afe_tx_reset_frc = 0;
   3615             WRITE_SESTO_PMA_PMD_REG(pa,
   3616                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3617                    pwrdwn_ctrl.data);
   3618         break;
   3619         default:
   3620         break;
   3621     }
   3622     /* RX AFE Lane Reset */
   3623     switch (reset->rx) {
   3624         /* In Reset */
   3625         case phymodResetDirectionIn:
   3626             READ_SESTO_PMA_PMD_REG(pa,
   3627                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3628                    pwrdwn_ctrl.data);
   3629             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 1;
   3630             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3631             WRITE_SESTO_PMA_PMD_REG(pa,
   3632                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3633                    pwrdwn_ctrl.data);
   3634 
   3635         break;
   3636         /* Out Reset */
   3637         case phymodResetDirectionOut:
   3638             READ_SESTO_PMA_PMD_REG(pa,
   3639                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3640                    pwrdwn_ctrl.data);
   3641             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 0;
   3642             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3643             WRITE_SESTO_PMA_PMD_REG(pa,
   3644                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3645                    pwrdwn_ctrl.data);
   3646             /* -- Releasing forces -- */
   3647             READ_SESTO_PMA_PMD_REG(pa,
   3648                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3649                    pwrdwn_ctrl.data);
   3650             pwrdwn_ctrl.fields.afe_rx_reset_frc = 0;
   3651             WRITE_SESTO_PMA_PMD_REG(pa,
   3652                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3653                    pwrdwn_ctrl.data);
   3654         break;
   3655         /* Toggle Reset */
   3656         case phymodResetDirectionInOut:
   3657             READ_SESTO_PMA_PMD_REG(pa,
   3658                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3659                    pwrdwn_ctrl.data);
   3660             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 1;
   3661             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3662             WRITE_SESTO_PMA_PMD_REG(pa,
   3663                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3664                    pwrdwn_ctrl.data);
   3665             PHYMOD_USLEEP(10);
   3666             READ_SESTO_PMA_PMD_REG(pa,
   3667                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3668                    pwrdwn_ctrl.data);
   3669             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 0;
   3670             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3671             WRITE_SESTO_PMA_PMD_REG(pa,
   3672                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3673                    pwrdwn_ctrl.data);
   3674             /* -- Releasing forces -- */
   3675             READ_SESTO_PMA_PMD_REG(pa,
   3676                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3677                    pwrdwn_ctrl.data);
   3678             pwrdwn_ctrl.fields.afe_rx_reset_frc = 0;
   3679             WRITE_SESTO_PMA_PMD_REG(pa,
   3680                    F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3681                    pwrdwn_ctrl.data);
   3682         break;
   3683         default:
   3684         break;
   3685     }
   3686 
   3687 ERR:
   3688     return rv;
   3689 }
   3690 
   3691 int _sesto_merlin_phy_reset_set(const phymod_access_t *pa, const phymod_phy_reset_t* reset)
   3692 {
   3693     int rv = PHYMOD_E_NONE;
   3694     M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_TYPE_T pwrdwn_ctrl;
   3695 
   3696     /* TX AFE Lane Reset */
   3697     switch (reset->tx) {
   3698         /* In Reset */
   3699         case phymodResetDirectionIn:
   3700             READ_SESTO_PMA_PMD_REG(pa,
   3701                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3702                    pwrdwn_ctrl.data);
   3703             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 1;
   3704             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3705             WRITE_SESTO_PMA_PMD_REG(pa,
   3706                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3707                    pwrdwn_ctrl.data);
   3708 
   3709         break;
   3710         /* Out Reset */
   3711         case phymodResetDirectionOut:
   3712             READ_SESTO_PMA_PMD_REG(pa,
   3713                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3714                    pwrdwn_ctrl.data);
   3715             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 0;
   3716             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3717             WRITE_SESTO_PMA_PMD_REG(pa,
   3718                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3719                    pwrdwn_ctrl.data);
   3720             /* -- Releasing forces -- */
   3721             READ_SESTO_PMA_PMD_REG(pa,
   3722                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3723                    pwrdwn_ctrl.data);
   3724             pwrdwn_ctrl.fields.afe_tx_reset_frc = 0;
   3725             WRITE_SESTO_PMA_PMD_REG(pa,
   3726                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3727                    pwrdwn_ctrl.data);
   3728         break;
   3729         /* Toggle Reset */
   3730         case phymodResetDirectionInOut:
   3731             READ_SESTO_PMA_PMD_REG(pa,
   3732                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3733                    pwrdwn_ctrl.data);
   3734             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 1;
   3735             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3736             WRITE_SESTO_PMA_PMD_REG(pa,
   3737                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3738                    pwrdwn_ctrl.data);
   3739             PHYMOD_USLEEP(10);
   3740             READ_SESTO_PMA_PMD_REG(pa,
   3741                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3742                    pwrdwn_ctrl.data);
   3743             pwrdwn_ctrl.fields.afe_tx_reset_frc_val = 0;
   3744             pwrdwn_ctrl.fields.afe_tx_reset_frc = 1;
   3745             WRITE_SESTO_PMA_PMD_REG(pa,
   3746                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3747                    pwrdwn_ctrl.data);
   3748             /* -- Releasing forces -- */
   3749             READ_SESTO_PMA_PMD_REG(pa,
   3750                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3751                    pwrdwn_ctrl.data);
   3752             pwrdwn_ctrl.fields.afe_tx_reset_frc = 0;
   3753             WRITE_SESTO_PMA_PMD_REG(pa,
   3754                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3755                    pwrdwn_ctrl.data);
   3756         break;
   3757         default:
   3758         break;
   3759     }
   3760 
   3761     /* RX AFE Lane Reset */
   3762     switch (reset->rx) {
   3763         /* In Reset */
   3764         case phymodResetDirectionIn:
   3765             READ_SESTO_PMA_PMD_REG(pa,
   3766                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3767                    pwrdwn_ctrl.data);
   3768             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 1;
   3769             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3770             WRITE_SESTO_PMA_PMD_REG(pa,
   3771                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3772                    pwrdwn_ctrl.data);
   3773         break;
   3774         /* Out Reset */
   3775         case phymodResetDirectionOut:
   3776             READ_SESTO_PMA_PMD_REG(pa,
   3777                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3778                    pwrdwn_ctrl.data);
   3779             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 0;
   3780             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3781             WRITE_SESTO_PMA_PMD_REG(pa,
   3782                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3783                    pwrdwn_ctrl.data);
   3784             /* -- Releasing forces -- */
   3785             READ_SESTO_PMA_PMD_REG(pa,
   3786                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3787                    pwrdwn_ctrl.data);
   3788             pwrdwn_ctrl.fields.afe_rx_reset_frc = 0;
   3789             WRITE_SESTO_PMA_PMD_REG(pa,
   3790                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3791                    pwrdwn_ctrl.data);
   3792         break;
   3793         /* Toggle Reset */
   3794         case phymodResetDirectionInOut:
   3795             READ_SESTO_PMA_PMD_REG(pa,
   3796                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3797                    pwrdwn_ctrl.data);
   3798             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 1;
   3799             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3800             WRITE_SESTO_PMA_PMD_REG(pa,
   3801                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3802                    pwrdwn_ctrl.data);
   3803             PHYMOD_USLEEP(10);
   3804             READ_SESTO_PMA_PMD_REG(pa,
   3805                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3806                    pwrdwn_ctrl.data);
   3807             pwrdwn_ctrl.fields.afe_rx_reset_frc_val = 0;
   3808             pwrdwn_ctrl.fields.afe_rx_reset_frc = 1;
   3809             WRITE_SESTO_PMA_PMD_REG(pa,
   3810                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3811                    pwrdwn_ctrl.data);
   3812             /* -- Releasing forces -- */
   3813             READ_SESTO_PMA_PMD_REG(pa,
   3814                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3815                    pwrdwn_ctrl.data);
   3816             pwrdwn_ctrl.fields.afe_rx_reset_frc = 0;
   3817             WRITE_SESTO_PMA_PMD_REG(pa,
   3818                    M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL_ADR,
   3819                    pwrdwn_ctrl.data);
   3820         break;
   3821         default:
   3822         break;
   3823     }
   3824 
   3825 ERR:
   3826     return rv;
   3827 }
   3828 int _sesto_phy_reset_set(const phymod_phy_access_t *phy, const phymod_phy_reset_t* reset)
   3829 {
   3830     phymod_phy_inf_config_t config;
   3831     uint16_t ip = 0;
   3832     uint16_t lane = 0;
   3833     uint16_t lane_mask = 0, max_lane = 0;
   3834     const phymod_access_t *pa = &phy->access;
   3835     int rv = PHYMOD_E_NONE;
   3836 
   3837     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3838     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3839     SESTO_IF_ERR_RETURN(
   3840        _sesto_phy_interface_config_get(phy, 0, &config));
   3841     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3842     SESTO_GET_IP(phy, config, ip);
   3843 
   3844     max_lane = (ip == SESTO_FALCON_CORE) ?
   3845                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3846 
   3847     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3848              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3849 
   3850 
   3851     for (lane = 0; lane < max_lane; lane ++) {
   3852         if (lane_mask & (1 << lane)) {
   3853             SESTO_IF_ERR_RETURN(
   3854                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3855                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3856             if (ip == SESTO_FALCON_CORE) {
   3857                 /* FALCON TX/RX Reset */
   3858                 PHYMOD_DEBUG_VERBOSE(("Falcon TX/RX Reset set\n"));
   3859                 SESTO_IF_ERR_RETURN(
   3860                     _sesto_falcon_phy_reset_set(pa, reset));
   3861             } else {
   3862                 /* MERLIN TX/RX Reset */
   3863                 PHYMOD_DEBUG_VERBOSE(("Merlin TX/RX Reset set\n"));
   3864                 SESTO_IF_ERR_RETURN(
   3865                     _sesto_merlin_phy_reset_set(pa, reset));
   3866             }
   3867         }
   3868     }
   3869 
   3870 ERR:
   3871     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3872     PHYMOD_FREE(config.device_aux_modes);
   3873 
   3874     return rv;
   3875 }
   3876 int _sesto_phy_reset_get(const phymod_phy_access_t *phy, phymod_phy_reset_t* reset)
   3877 {
   3878     phymod_phy_inf_config_t config;
   3879     uint16_t ip = 0;
   3880     uint16_t rst = 0;
   3881     uint16_t lane = 0;
   3882     uint16_t lane_mask = 0, max_lane = 0;
   3883     const phymod_access_t *pa = &phy->access;
   3884     int rv = PHYMOD_E_NONE;
   3885 
   3886     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3887     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3888     SESTO_IF_ERR_RETURN(
   3889        _sesto_phy_interface_config_get(phy, 0, &config));
   3890     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3891     SESTO_GET_IP(phy, config, ip);
   3892 
   3893     max_lane = (ip == SESTO_FALCON_CORE) ?
   3894                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   3895 
   3896     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   3897              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   3898 
   3899 
   3900     for (lane = 0; lane < max_lane; lane ++) {
   3901         if (lane_mask & (1 << lane)) {
   3902             SESTO_IF_ERR_RETURN(
   3903                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   3904                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   3905             if (ip == SESTO_FALCON_CORE) {
   3906                 /* FALCON TX/RX Reset */
   3907                 PHYMOD_DEBUG_VERBOSE(("Falcon TX/RX Reset get\n"));
   3908                 SESTO_CHIP_FIELD_READ(pa, 
   3909                            F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL,
   3910                            afe_tx_reset_frc_val, rst);
   3911                 if(rst == 0) {
   3912                     /* Out of Reset */
   3913                     reset->tx = phymodResetDirectionOut;
   3914                 } else {
   3915                     /* In Reset */
   3916                     reset->tx = phymodResetDirectionIn;
   3917                 }
   3918 
   3919                 SESTO_CHIP_FIELD_READ(pa, 
   3920                            F25G_CKRST_CTRL_RPTR_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL,
   3921                            afe_rx_reset_frc_val, rst);
   3922                 if(rst == 0) {
   3923                     /* Out of Reset */
   3924                     reset->rx = phymodResetDirectionOut;
   3925                 } else {
   3926                     /* In Reset */
   3927                     reset->rx = phymodResetDirectionIn;
   3928                 }
   3929             } else { 
   3930                 /* MERLIN TX/RX Reset */
   3931                 PHYMOD_DEBUG_VERBOSE(("Merlin TXF/RX Reset get\n"));
   3932                 SESTO_CHIP_FIELD_READ(pa,
   3933                            M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL,
   3934                            afe_tx_reset_frc_val, rst);
   3935                 if(rst == 0) {
   3936                     /* Out of Reset */
   3937                     reset->tx = phymodResetDirectionOut;
   3938                 } else {
   3939                     /* In Reset */
   3940                     reset->tx = phymodResetDirectionIn;
   3941                 }
   3942 
   3943                 SESTO_CHIP_FIELD_READ(pa,
   3944                            M10G_CKRST_CTRL_LANE_AFE_RESET_PWRDWN_CONTROL_CONTROL,
   3945                            afe_rx_reset_frc_val, rst);
   3946                 if(rst == 0) {
   3947                     /* Out of Reset */
   3948                     reset->rx = phymodResetDirectionOut;
   3949                 } else {
   3950                     /* In Reset */
   3951                     reset->rx = phymodResetDirectionIn;
   3952                 }
   3953             }
   3954         }
   3955     }
   3956 
   3957 ERR:
   3958     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   3959     PHYMOD_FREE(config.device_aux_modes);
   3960 
   3961     return rv;
   3962 }
   3963 int _sesto_tx_power_set(const phymod_phy_access_t *phy, uint32_t power_tx)
   3964 {
   3965     phymod_phy_inf_config_t config;
   3966     uint16_t ip = 0;
   3967     uint16_t lane = 0;
   3968     uint16_t lane_mask = 0;
   3969     int rv = PHYMOD_E_NONE;
   3970     const phymod_access_t *pa = &phy->access;
   3971     MERLIN_IF_CONTROL2_LANE0_TYPE_T merlin_ctrl2_lane;
   3972     FALCON_IF_CONTROL2_LANE0_TYPE_T falcon_ctrl2_lane;
   3973 
   3974     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   3975     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   3976     SESTO_IF_ERR_RETURN(
   3977        _sesto_phy_interface_config_get(phy, 0, &config));
   3978     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   3979     SESTO_GET_IP(phy, config, ip);
   3980 
   3981     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s lanemask:0x%x\n", __func__,
   3982              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", lane_mask));
   3983 
   3984     if (ip == SESTO_FALCON_CORE) {
   3985         for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   3986             if (lane_mask & (1 << lane)) {
   3987                 /* FALCON TX Power Set */
   3988                 PHYMOD_DEBUG_VERBOSE(("Falcon TX Power set\n"));
   3989                 switch (power_tx) {
   3990                     case phymodPowerOff: /* Turn off power */
   3991                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   3992                                                    falcon_ctrl2_lane.data);
   3993                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   3994                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 1;
   3995                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   3996                                                     falcon_ctrl2_lane.data);
   3997                     break;
   3998                     case phymodPowerOn: /* Turn on power */
   3999                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4000                                                    falcon_ctrl2_lane.data);
   4001                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4002                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 0;
   4003                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4004                                                     falcon_ctrl2_lane.data);
   4005                         /* -- Releasing forces -- */
   4006                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4007                                                    falcon_ctrl2_lane.data);
   4008                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 0;
   4009                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4010                                                     falcon_ctrl2_lane.data);
   4011                     break;
   4012                     case phymodPowerOffOn: /* Toggle power */
   4013                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4014                                                    falcon_ctrl2_lane.data);
   4015                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4016                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 1;
   4017                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4018                                                     falcon_ctrl2_lane.data);
   4019                         PHYMOD_USLEEP(10000);
   4020                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4021                                                    falcon_ctrl2_lane.data);
   4022                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4023                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 0;
   4024                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4025                                                     falcon_ctrl2_lane.data);
   4026                         /* -- Releasing forces -- */
   4027                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4028                                                    falcon_ctrl2_lane.data);
   4029                         falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 0;
   4030                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4031                                                     falcon_ctrl2_lane.data);
   4032                     break;
   4033                     case phymodPowerNoChange: /* Stay where you are */
   4034                     break;
   4035                     default:
   4036                     break;
   4037                 }
   4038             }
   4039         }
   4040     } else {
   4041         for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   4042             if (lane_mask & (1 << lane)) {
   4043                 /* MERLIN TX Power set */
   4044                 PHYMOD_DEBUG_VERBOSE(("Merlin TX Power set\n"));
   4045                 switch (power_tx) {
   4046                     case phymodPowerOff: /* Turn off power */
   4047                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4048                                                    merlin_ctrl2_lane.data);
   4049                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4050                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 1;
   4051                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4052                                                     merlin_ctrl2_lane.data);
   4053                     break;
   4054                     case phymodPowerOn: /* Turn on power */
   4055                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4056                                                    merlin_ctrl2_lane.data);
   4057                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4058                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 0;
   4059                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4060                                                     merlin_ctrl2_lane.data);
   4061                         /* -- Releasing forces -- */
   4062                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4063                                                    merlin_ctrl2_lane.data);
   4064                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 0;
   4065                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4066                                                     merlin_ctrl2_lane.data);
   4067                     break;
   4068                     case phymodPowerOffOn: /* Toggle power */
   4069                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4070                                                    merlin_ctrl2_lane.data);
   4071                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4072                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 1;
   4073                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4074                                                     merlin_ctrl2_lane.data);
   4075                         PHYMOD_USLEEP(10000);
   4076                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4077                                                    merlin_ctrl2_lane.data);
   4078                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 1;
   4079                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval = 0;
   4080                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4081                                                     merlin_ctrl2_lane.data);
   4082                         /* -- Releasing forces -- */
   4083                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4084                                                    merlin_ctrl2_lane.data);
   4085                         merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frc = 0;
   4086                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4087                                                     merlin_ctrl2_lane.data);
   4088                     break;
   4089                     case phymodPowerNoChange: /* Stay where you are */
   4090                     break;
   4091                     default:
   4092                     break;
   4093                 }
   4094             }
   4095         }
   4096     }
   4097 
   4098 ERR:
   4099     PHYMOD_FREE(config.device_aux_modes);
   4100 
   4101     return rv;
   4102 }
   4103 int _sesto_rx_power_set(const phymod_phy_access_t *phy, uint32_t power_rx)
   4104 {
   4105     phymod_phy_inf_config_t config;
   4106     uint16_t ip = 0;
   4107     uint16_t lane = 0;
   4108     uint16_t lane_mask = 0;
   4109     int rv = PHYMOD_E_NONE;
   4110     const phymod_access_t *pa = &phy->access;
   4111     MERLIN_IF_CONTROL2_LANE0_TYPE_T merlin_ctrl2_lane;
   4112     FALCON_IF_CONTROL2_LANE0_TYPE_T falcon_ctrl2_lane;
   4113 
   4114     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4115     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4116     SESTO_IF_ERR_RETURN(
   4117        _sesto_phy_interface_config_get(phy, 0, &config));
   4118     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4119 
   4120     SESTO_GET_IP(phy, config, ip);
   4121     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   4122                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   4123 
   4124     if (ip == SESTO_FALCON_CORE) {
   4125         for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   4126             if (lane_mask & (1 << lane)) {
   4127                 /* FALCON RX Power Set */
   4128                 PHYMOD_DEBUG_VERBOSE(("Falcon RX Power set\n"));
   4129                 switch (power_rx) {
   4130                     case phymodPowerOff: /* Turn off power */
   4131                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4132                                                    falcon_ctrl2_lane.data);
   4133                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4134                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 1;
   4135                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4136                                                     falcon_ctrl2_lane.data);
   4137                     break;
   4138                     case phymodPowerOn: /* Turn on power */
   4139                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4140                                                    falcon_ctrl2_lane.data);
   4141                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4142                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 0;
   4143                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4144                                                     falcon_ctrl2_lane.data);
   4145                         /* -- Releasing forces -- */
   4146                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4147                                                    falcon_ctrl2_lane.data);
   4148                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 0;
   4149                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4150                                                     falcon_ctrl2_lane.data);
   4151                     break;
   4152                     case phymodPowerOffOn: /* Toggle power */
   4153                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4154                                                    falcon_ctrl2_lane.data);
   4155                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4156                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 1;
   4157                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4158                                                     falcon_ctrl2_lane.data);
   4159                         PHYMOD_USLEEP(10000);
   4160                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4161                                                    falcon_ctrl2_lane.data);
   4162                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4163                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 0;
   4164                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4165                                                     falcon_ctrl2_lane.data);
   4166                         /* -- Releasing forces -- */
   4167                         READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4168                                                    falcon_ctrl2_lane.data);
   4169                         falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 0;
   4170                         WRITE_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4171                                                     falcon_ctrl2_lane.data);
   4172                     break;
   4173                     case phymodPowerNoChange: /* Stay where you are */
   4174                     break;
   4175                     default:
   4176                     break;
   4177                 }
   4178             }
   4179         }
   4180     } else {
   4181         for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   4182             if (lane_mask & (1 << lane)) {
   4183                 /* MERLIN RX Power set */
   4184                 PHYMOD_DEBUG_VERBOSE(("Merlin RX Power set\n"));
   4185                 switch (power_rx) {
   4186                     case phymodPowerOff:  /* Turn off power */
   4187                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4188                                                    merlin_ctrl2_lane.data);
   4189                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4190                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 1;
   4191                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4192                                                     merlin_ctrl2_lane.data);
   4193                     break;
   4194                     case phymodPowerOn:  /* Turn on power */
   4195                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4196                                                    merlin_ctrl2_lane.data);
   4197                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4198                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 0;
   4199                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4200                                                     merlin_ctrl2_lane.data);
   4201                         /* -- Releasing forces -- */
   4202                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4203                                                    merlin_ctrl2_lane.data);
   4204                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 0;
   4205                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4206                                                     merlin_ctrl2_lane.data);
   4207                     break;
   4208                     case phymodPowerOffOn: /* Toggle power */
   4209                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4210                                                    merlin_ctrl2_lane.data);
   4211                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4212                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 1;
   4213                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4214                                                     merlin_ctrl2_lane.data);
   4215                         PHYMOD_USLEEP(10000);
   4216                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4217                                                    merlin_ctrl2_lane.data);
   4218                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 1;
   4219                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval = 0;
   4220                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4221                                                     merlin_ctrl2_lane.data);
   4222                         /* -- Releasing forces -- */
   4223                         READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4224                                                    merlin_ctrl2_lane.data);
   4225                         merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frc = 0;
   4226                         WRITE_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4227                                                     merlin_ctrl2_lane.data);
   4228                     break;
   4229                     case phymodPowerNoChange: /* Stay where you are */
   4230                     break;
   4231                     default:
   4232                     break;
   4233                 }
   4234             }
   4235         }
   4236     }
   4237 
   4238 ERR:
   4239     PHYMOD_FREE(config.device_aux_modes);
   4240 
   4241     return rv;
   4242 }
   4243 
   4244 int _sesto_tx_rx_power_get(const phymod_phy_access_t *phy, phymod_phy_power_t* power)
   4245 {
   4246     phymod_phy_inf_config_t config;
   4247     uint16_t ip = 0;
   4248     uint16_t lane = 0;
   4249     uint16_t lane_mask = 0, max_lane = 0;
   4250     int rv = PHYMOD_E_NONE;
   4251     const phymod_access_t *pa = &phy->access;
   4252     MERLIN_IF_CONTROL2_LANE0_TYPE_T merlin_ctrl2_lane;
   4253     FALCON_IF_CONTROL2_LANE0_TYPE_T falcon_ctrl2_lane;
   4254 
   4255     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4256     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4257     SESTO_IF_ERR_RETURN(
   4258        _sesto_phy_interface_config_get(phy, 0, &config));
   4259     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4260     SESTO_GET_IP(phy, config, ip);
   4261 
   4262     max_lane = (ip == SESTO_FALCON_CORE) ?
   4263                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4264 
   4265     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4266              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4267 
   4268     for (lane = 0; lane < max_lane; lane ++) {
   4269         if (lane_mask & (1 << lane)) {
   4270             if (ip == SESTO_FALCON_CORE) {
   4271                 /* FALCON TX/RX Power Get */
   4272                 PHYMOD_DEBUG_VERBOSE(("Falcon TX/RX Power get\n"));
   4273                 READ_SESTO_PMA_PMD_REG(pa, (FALCON_IF_CONTROL2_LANE0_ADR + lane),
   4274                                                    falcon_ctrl2_lane.data);
   4275                 power->tx = !falcon_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval;
   4276                 power->rx = !falcon_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval;
   4277             } else {
   4278                 /* MERLIN TX/RX Power Get */
   4279                 PHYMOD_DEBUG_VERBOSE(("Merlin TX/RX Power get\n"));
   4280                 READ_SESTO_PMA_PMD_REG(pa, (MERLIN_IF_CONTROL2_LANE0_ADR + lane),
   4281                                                    merlin_ctrl2_lane.data);
   4282                 power->tx = !merlin_ctrl2_lane.fields.pmd_ln_tx_h_pwrdn_0_frcval;
   4283                 power->rx = !merlin_ctrl2_lane.fields.pmd_ln_rx_h_pwrdn_0_frcval;
   4284             }
   4285         }
   4286     }
   4287 
   4288 ERR:
   4289     PHYMOD_FREE(config.device_aux_modes);
   4290 
   4291     return rv;
   4292 }
   4293 
   4294 int _sesto_force_tx_training_set(const phymod_phy_access_t *phy, uint32_t enable)
   4295 {
   4296     phymod_phy_inf_config_t config;
   4297     uint16_t ip = 0;
   4298     uint16_t lane = 0;
   4299     uint16_t lane_mask = 0, max_lane = 0;
   4300     uint16_t data = 0, retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   4301     const phymod_access_t *pa = &phy->access;
   4302     int rv = PHYMOD_E_NONE;
   4303 
   4304     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4305     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4306     SESTO_IF_ERR_RETURN(
   4307        _sesto_phy_interface_config_get(phy, 0, &config));
   4308     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4309     SESTO_GET_IP(phy, config, ip);
   4310 
   4311     max_lane = (ip == SESTO_FALCON_CORE) ?
   4312                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4313 
   4314     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4315              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4316 
   4317     for (lane = 0; lane < max_lane; lane ++) {
   4318         if (lane_mask & (1 << lane)) {
   4319             if (ip == SESTO_FALCON_CORE) { /* Falcon TX Training set on GPREG13 Regs */
   4320                 PHYMOD_DEBUG_VERBOSE(("Falcon TX Training set\n"));
   4321                 SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_GPREG13, tx_trng_20g_ln, data);
   4322                 enable ? (data |= (0x1 << lane)): (data &= (~(0x1 << lane)));
   4323                 SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GPREG13, tx_trng_20g_ln, data);
   4324             } else { /* Merlin TX Training set on GPREG12 Regs */
   4325                 PHYMOD_DEBUG_VERBOSE(("Merlin TX Training set\n"));
   4326                 SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_GPREG12, tx_trng_10g_ln, data);
   4327                 enable ? (data |= (0x1 << lane)): (data &= (~(0x1 << lane)));
   4328                 SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GPREG12, tx_trng_10g_ln, data);
   4329             }
   4330         }
   4331     }
   4332 
   4333     /*  Set FW_ENABLE = 1 */
   4334     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, 1);
   4335     do {
   4336         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data);
   4337         retry_cnt--;
   4338     } while ((data != 0) && (retry_cnt));
   4339     if (retry_cnt == 0) {
   4340         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   4341                (_PHYMOD_MSG("Training set failed, micro controller is busy..")));
   4342     }
   4343 
   4344 ERR:
   4345     PHYMOD_FREE(config.device_aux_modes);
   4346 
   4347     return rv;
   4348 }
   4349 
   4350 int _sesto_force_tx_training_get(const phymod_phy_access_t *phy, uint32_t *enable)
   4351 {
   4352     phymod_phy_inf_config_t config;
   4353     uint16_t ip = 0;
   4354     uint16_t lane = 0;
   4355     uint16_t lane_mask = 0, max_lane = 0;
   4356     uint16_t training_en = 0;
   4357     const phymod_access_t *pa = &phy->access;
   4358     int rv = PHYMOD_E_NONE;
   4359 
   4360     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4361     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4362     SESTO_IF_ERR_RETURN(
   4363        _sesto_phy_interface_config_get(phy, 0, &config));
   4364     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4365     SESTO_GET_IP(phy, config, ip);
   4366 
   4367     max_lane = (ip == SESTO_FALCON_CORE) ?
   4368                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4369 
   4370     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4371              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4372 
   4373     for (lane = 0; lane < max_lane; lane ++) {
   4374         if (lane_mask & (1 << lane)) {
   4375             if (ip == SESTO_FALCON_CORE) { /* Falcon TX Training get on GPREG13 Regs */
   4376                 PHYMOD_DEBUG_VERBOSE(("Falcon TX Training get\n"));
   4377                 SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_GPREG13, tx_trng_20g_ln, training_en);
   4378                 *enable = ((training_en >> lane) & 0x1);
   4379             } else { /* Merlin TX Training get on GPREG12 Regs */
   4380                 PHYMOD_DEBUG_VERBOSE(("Merlin TX Training get\n"));
   4381                 SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_GPREG12, tx_trng_10g_ln, training_en);
   4382                 *enable = ((training_en >> lane) & 0x1);
   4383             }
   4384         }
   4385     }
   4386 
   4387 ERR:
   4388     PHYMOD_FREE(config.device_aux_modes);
   4389 
   4390     return rv;
   4391 }
   4392 
   4393 int _sesto_force_tx_training_status_get(const phymod_phy_access_t *phy, phymod_cl72_status_t* status)
   4394 {
   4395     phymod_phy_inf_config_t config;
   4396     uint16_t ip = 0;
   4397     uint16_t lane = 0;
   4398     uint16_t lane_mask = 0, max_lane = 0;
   4399     uint16_t training_en = 0;
   4400     uint16_t training_failure = 1;
   4401     uint16_t trained = 1;
   4402     const phymod_access_t *pa = &phy->access;
   4403     int rv = PHYMOD_E_NONE;
   4404 
   4405     status->enabled = 0x1;
   4406     status->locked = 0x1;
   4407 
   4408     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4409     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4410     SESTO_IF_ERR_RETURN(
   4411        _sesto_phy_interface_config_get(phy, 0, &config));
   4412     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4413     SESTO_GET_IP(phy, config, ip);
   4414 
   4415     max_lane = (ip == SESTO_FALCON_CORE) ?
   4416                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4417 
   4418     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4419              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4420 
   4421     for (lane = 0; lane < max_lane; lane ++) {
   4422         if (lane_mask & (1 << lane)) {
   4423                 SESTO_IF_ERR_RETURN(
   4424                   _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4425                             ip, SESTO_DEV_PMA_PMD, 0, lane));
   4426             if (ip == SESTO_FALCON_CORE) { /* Falcon TX Training status Reading from IEEE Regs */
   4427                 PHYMOD_DEBUG_VERBOSE(("Falcon TX Training Status get\n"));
   4428                 SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_GPREG13, tx_trng_20g_ln, training_en);
   4429                 status->enabled &= ((training_en >> lane) & 0x1);
   4430                 SESTO_CHIP_FIELD_READ(pa, F25G_CL93N72_IEEE_TX_CL93N72IT_BASE_R_PMD_STATUS_REGISTER_151,
   4431                                           cl93n72_ieee_receiver_status, trained);
   4432                 SESTO_CHIP_FIELD_READ(pa, F25G_CL93N72_IEEE_TX_CL93N72IT_BASE_R_PMD_STATUS_REGISTER_151,
   4433                                           cl93n72_ieee_training_failure, training_failure);
   4434                 status->locked &= ((!training_failure) && (trained));
   4435             } else {  /* Merlin TX Training status Reading from IEEE Regs */
   4436                 PHYMOD_DEBUG_VERBOSE(("Merlin TX Training Status get\n"));
   4437                 SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_GPREG12, tx_trng_10g_ln, training_en);
   4438                 status->enabled &= ((training_en >> lane) & 0x1);
   4439                 SESTO_CHIP_FIELD_READ(pa, M10G_CL72_IEEE_TX_BASE_R_PMD_STATUS_REGISTER_151,
   4440                                           receiver_status, trained);
   4441                 SESTO_CHIP_FIELD_READ(pa, M10G_CL72_IEEE_TX_BASE_R_PMD_STATUS_REGISTER_151,
   4442                                           training_failure, training_failure);
   4443                 status->locked &= ((!training_failure) && (trained));
   4444             }
   4445         }
   4446     }
   4447 
   4448 ERR:
   4449     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   4450     PHYMOD_FREE(config.device_aux_modes);
   4451 
   4452     return rv;
   4453 }
   4454 int _sesto_phy_status_dump(const phymod_phy_access_t *phy)
   4455 {
   4456     phymod_phy_inf_config_t config;
   4457     uint16_t ip = 0, intf_side = 0;
   4458     uint16_t lane = 0, lane_mask = 0;
   4459     const phymod_access_t *pa = &phy->access;
   4460     int rv = PHYMOD_E_NONE;
   4461 
   4462     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4463     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4464     SESTO_IF_ERR_RETURN(
   4465        _sesto_phy_interface_config_get(phy, 0, &config));
   4466     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4467     SESTO_GET_IP(phy, config, ip);
   4468     SESTO_GET_INTF_SIDE(phy, intf_side);
   4469 
   4470     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s lanemask:0x%x\n", __func__,
   4471              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", lane_mask));
   4472 
   4473     USR_PRINTF(("**********************************************\n"));
   4474     USR_PRINTF(("******* PHY status dump for PHY ID: 0x%x ********\n",pa->addr));
   4475     USR_PRINTF(("**********************************************\n"));
   4476     USR_PRINTF(("**** PHY status dump for interface side:%d ****\n",intf_side));
   4477     USR_PRINTF(("***********************************************\n"));
   4478     if (ip == SESTO_FALCON_CORE) { /* Falcon core status dump */
   4479         for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   4480             if (lane_mask & (1 << lane)) {
   4481                 SESTO_IF_ERR_RETURN(
   4482                   _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4483                             SESTO_FALCON_CORE, SESTO_DEV_PMA_PMD, 0, lane));
   4484                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_display_core_config(pa));
   4485                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_display_core_state(pa));
   4486                 break;
   4487             }
   4488         }
   4489     } else {  /* Merlin core status dump */
   4490         for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   4491             if (lane_mask & (1 << lane)) {
   4492                 SESTO_IF_ERR_RETURN(
   4493                   _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4494                             SESTO_MERLIN_CORE, SESTO_DEV_PMA_PMD, 0, lane));
   4495                 SESTO_IF_ERR_RETURN(merlin_sesto_display_core_config(pa));
   4496                 SESTO_IF_ERR_RETURN(merlin_sesto_display_core_state(pa));
   4497                 break;
   4498             }
   4499         }
   4500     }
   4501     if (ip == SESTO_FALCON_CORE) { /* Falcon lanes status dump */
   4502         for(lane = 0; lane < SESTO_MAX_FALCON_LANE; lane ++) {
   4503             if (lane_mask & (1 << lane)) {
   4504                 SESTO_IF_ERR_RETURN(
   4505                   _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4506                             SESTO_FALCON_CORE, SESTO_DEV_PMA_PMD,
   4507                             0, lane));
   4508                 PHYMOD_DEBUG_VERBOSE(("Falcon Status dump\n"));
   4509                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_display_lane_state_hdr(pa));
   4510                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_display_lane_state(pa));
   4511                 SESTO_IF_ERR_RETURN(falcon_furia_sesto_display_lane_config(pa));
   4512             }
   4513         }
   4514     } else {   /* Merlin lanes status dump */
   4515         for(lane = 0; lane < SESTO_MAX_MERLIN_LANE; lane ++) {
   4516             if (lane_mask & (1 << lane)) {
   4517                 SESTO_IF_ERR_RETURN(
   4518                   _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4519                             SESTO_MERLIN_CORE, SESTO_DEV_PMA_PMD,
   4520                             0, lane));
   4521                 PHYMOD_DEBUG_VERBOSE(("Merlin Status dump\n"));
   4522                 SESTO_IF_ERR_RETURN(merlin_sesto_display_lane_state_hdr(pa));
   4523                 SESTO_IF_ERR_RETURN(merlin_sesto_display_lane_state(pa));
   4524                 SESTO_IF_ERR_RETURN(merlin_sesto_display_lane_config(pa));
   4525             }
   4526         }
   4527     }
   4528 
   4529 ERR:
   4530     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   4531     PHYMOD_FREE(config.device_aux_modes);
   4532 
   4533     return rv;
   4534 }
   4535 
   4536 int _sesto_tx_enable_set(const phymod_phy_access_t *phy, int16_t enable) 
   4537 {
   4538     phymod_phy_inf_config_t config;
   4539     uint16_t ip = 0;
   4540     uint16_t lane = 0, max_lane = 0, reg_addr = 0;
   4541     uint16_t lane_mask = 0;
   4542     int rv = PHYMOD_E_NONE;
   4543     const phymod_access_t *pa = &phy->access;
   4544     MERLIN_IF_CONTROL1_LANE0_TYPE_T mer_ctrl1;
   4545     FALCON_IF_CONTROL1_LANE0_TYPE_T fal_ctrl1;
   4546 
   4547     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4548     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4549     SESTO_IF_ERR_RETURN(
   4550        _sesto_phy_interface_config_get(phy, 0, &config));
   4551     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4552     SESTO_GET_IP(phy, config, ip);
   4553 
   4554     max_lane = (ip == SESTO_FALCON_CORE) ? 
   4555                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4556     
   4557     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 
   4558              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4559 
   4560     /* TX squelch set with pmd_tx_disable_0_frcval */
   4561     for (lane = 0; lane < max_lane; lane ++) {
   4562         if (lane_mask & (1 << lane)) {
   4563             if (ip == SESTO_FALCON_CORE) {
   4564                 reg_addr = FALCON_IF_CONTROL1_LANE0_ADR + lane; 
   4565                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, fal_ctrl1.data);
   4566                 fal_ctrl1.fields.pmd_tx_disable_0_frc = 1;
   4567                 fal_ctrl1.fields.pmd_tx_disable_0_frcval = (!enable);
   4568                 WRITE_SESTO_PMA_PMD_REG(pa, reg_addr, fal_ctrl1.data);
   4569                 /* -- Releasing forces -- */
   4570                 if (enable) {
   4571                     READ_SESTO_PMA_PMD_REG(pa, reg_addr, fal_ctrl1.data);
   4572                     fal_ctrl1.fields.pmd_tx_disable_0_frc = 0;
   4573                     WRITE_SESTO_PMA_PMD_REG(pa, reg_addr, fal_ctrl1.data);
   4574                 }
   4575             } else {
   4576                 reg_addr = MERLIN_IF_CONTROL1_LANE0_ADR + lane; 
   4577                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, mer_ctrl1.data);
   4578                 mer_ctrl1.fields.pmd_tx_disable_0_frc = 1;
   4579                 mer_ctrl1.fields.pmd_tx_disable_0_frcval = (!enable);
   4580                 WRITE_SESTO_PMA_PMD_REG(pa, reg_addr, mer_ctrl1.data);
   4581                 /* -- Releasing forces -- */
   4582                 if (enable) {
   4583                     READ_SESTO_PMA_PMD_REG(pa, reg_addr, mer_ctrl1.data);
   4584                     mer_ctrl1.fields.pmd_tx_disable_0_frc = 0;
   4585                     WRITE_SESTO_PMA_PMD_REG(pa, reg_addr, mer_ctrl1.data);
   4586                 }
   4587             }
   4588         }
   4589     }
   4590 
   4591 ERR:
   4592     PHYMOD_FREE(config.device_aux_modes);
   4593 
   4594     return rv;
   4595 }
   4596 
   4597 int _sesto_tx_enable_get(const phymod_phy_access_t *phy, int16_t *enable)
   4598 {
   4599     phymod_phy_inf_config_t config;
   4600     uint16_t ip = 0;
   4601     uint16_t lane = 0, max_lane = 0, reg_addr = 0;
   4602     uint16_t lane_mask = 0;
   4603     int rv = PHYMOD_E_NONE;
   4604     const phymod_access_t *pa = &phy->access;
   4605     MERLIN_IF_CONTROL1_LANE0_TYPE_T mer_ctrl1;
   4606     FALCON_IF_CONTROL1_LANE0_TYPE_T fal_ctrl1;
   4607 
   4608     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4609     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4610     SESTO_IF_ERR_RETURN(
   4611        _sesto_phy_interface_config_get(phy, 0, &config));
   4612     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4613     SESTO_GET_IP(phy, config, ip);
   4614 
   4615     max_lane = (ip == SESTO_FALCON_CORE) ?
   4616                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4617 
   4618     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4619              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4620 
   4621     /* TX squelch get with pmd_tx_disable_0_frcval */
   4622     for (lane = 0; lane < max_lane; lane ++) {
   4623         if (lane_mask & (1 << lane)) {
   4624             if (ip == SESTO_FALCON_CORE) {
   4625                 reg_addr = FALCON_IF_CONTROL1_LANE0_ADR + lane;
   4626                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, fal_ctrl1.data);
   4627                 *enable = !fal_ctrl1.fields.pmd_tx_disable_0_frcval;
   4628             } else {
   4629                 reg_addr = MERLIN_IF_CONTROL1_LANE0_ADR + lane;
   4630                 READ_SESTO_PMA_PMD_REG(pa, reg_addr, mer_ctrl1.data);
   4631                 *enable = !mer_ctrl1.fields.pmd_tx_disable_0_frcval;
   4632             }
   4633         }
   4634     }
   4635 
   4636 ERR:
   4637     PHYMOD_FREE(config.device_aux_modes);
   4638 
   4639     return rv;
   4640 }
   4641 
   4642 
   4643 int _sesto_tx_dp_reset(const phymod_phy_access_t *phy)
   4644 {
   4645     phymod_phy_inf_config_t config;
   4646     uint16_t ip = 0;
   4647     uint16_t lane = 0, max_lane = 0;
   4648     uint16_t lane_mask = 0;
   4649     int rv = PHYMOD_E_NONE;
   4650     const phymod_access_t *pa = &phy->access;
   4651     DP_LANE_RESET_CONTROL0_TYPE_T dp_rst;
   4652 
   4653     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4654     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4655     SESTO_IF_ERR_RETURN(
   4656        _sesto_phy_interface_config_get(phy, 0, &config));
   4657     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4658     
   4659     SESTO_GET_IP(phy, config, ip);
   4660     max_lane = (ip == SESTO_FALCON_CORE) ? 
   4661                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4662     
   4663     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 
   4664              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4665 
   4666     /* Reset TX data path */
   4667     for (lane = 0; lane < max_lane; lane ++) {
   4668         if (lane_mask & (1 << lane)) {
   4669             READ_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4670             if (ip == SESTO_FALCON_CORE) {
   4671                 dp_rst.fields.demux_ilane_dp_rstb &= ~(1 << lane);
   4672             } else {
   4673                 dp_rst.fields.mux_ilane_dp_rstb &= ~(1 << lane);
   4674             }
   4675             WRITE_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4676             PHYMOD_USLEEP(1000);
   4677             READ_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4678             if (ip == SESTO_FALCON_CORE) {
   4679                 dp_rst.fields.demux_ilane_dp_rstb |= (1 << lane);
   4680             } else {
   4681                 dp_rst.fields.mux_ilane_dp_rstb |= (1 << lane);
   4682             }
   4683             WRITE_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4684 
   4685         }
   4686     }
   4687 
   4688 ERR:
   4689     PHYMOD_FREE(config.device_aux_modes);
   4690 
   4691     return rv;
   4692 }
   4693 
   4694 int _sesto_rx_enable_set(const phymod_phy_access_t *phy, int16_t enable) 
   4695 {
   4696     phymod_phy_inf_config_t config;
   4697     uint16_t ip = 0;
   4698     uint16_t lane = 0, max_lane = 0;
   4699     uint16_t lane_mask = 0;
   4700     int rv = PHYMOD_E_NONE;
   4701     const phymod_access_t *pa = &phy->access;
   4702     M10G_SIGDET_SIGDET_CTRL_1_TYPE_T merlin_ctrl1_lane;
   4703     F25G_SIGDET_SIGDET_CTRL_1_TYPE_T falcon_ctrl1_lane;
   4704 
   4705     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4706     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4707     SESTO_IF_ERR_RETURN(
   4708        _sesto_phy_interface_config_get(phy, 0, &config));
   4709     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4710     SESTO_GET_IP(phy, config, ip);
   4711 
   4712     max_lane = (ip == SESTO_FALCON_CORE) ?
   4713                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4714 
   4715     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4716              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4717 
   4718     /* RX squelch set with signal_detect_frc_val */
   4719     for (lane = 0; lane < max_lane; lane ++) {
   4720         if (lane_mask & (1 << lane)) {
   4721             SESTO_IF_ERR_RETURN(
   4722               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4723                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   4724             if (ip == SESTO_FALCON_CORE) {
   4725                 READ_SESTO_PMA_PMD_REG(pa, F25G_SIGDET_SIGDET_CTRL_1_ADR, falcon_ctrl1_lane.data);
   4726                 falcon_ctrl1_lane.fields.signal_detect_frc = 1;
   4727                 falcon_ctrl1_lane.fields.signal_detect_frc_val = enable;
   4728                 WRITE_SESTO_PMA_PMD_REG(pa, F25G_SIGDET_SIGDET_CTRL_1_ADR, falcon_ctrl1_lane.data);
   4729                 /* -- Releasing forces -- */
   4730                 if (enable) {
   4731                     READ_SESTO_PMA_PMD_REG(pa, F25G_SIGDET_SIGDET_CTRL_1_ADR, falcon_ctrl1_lane.data);
   4732                     falcon_ctrl1_lane.fields.signal_detect_frc = 0;
   4733                     WRITE_SESTO_PMA_PMD_REG(pa, F25G_SIGDET_SIGDET_CTRL_1_ADR, falcon_ctrl1_lane.data);
   4734                 }
   4735             } else { 
   4736                 READ_SESTO_PMA_PMD_REG(pa, M10G_SIGDET_SIGDET_CTRL_1_ADR, merlin_ctrl1_lane.data);
   4737                 merlin_ctrl1_lane.fields.signal_detect_frc = 1;
   4738                 merlin_ctrl1_lane.fields.signal_detect_frc_val= enable;
   4739                 WRITE_SESTO_PMA_PMD_REG(pa, M10G_SIGDET_SIGDET_CTRL_1_ADR, merlin_ctrl1_lane.data);
   4740                 /* -- Releasing forces -- */
   4741                 if (enable) {
   4742                     READ_SESTO_PMA_PMD_REG(pa, M10G_SIGDET_SIGDET_CTRL_1_ADR, merlin_ctrl1_lane.data);
   4743                     merlin_ctrl1_lane.fields.signal_detect_frc = 0;
   4744                     WRITE_SESTO_PMA_PMD_REG(pa, M10G_SIGDET_SIGDET_CTRL_1_ADR, merlin_ctrl1_lane.data);
   4745                 }
   4746             }
   4747         }
   4748     }
   4749 ERR:
   4750     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   4751     PHYMOD_FREE(config.device_aux_modes);
   4752 
   4753     return rv;
   4754 }
   4755 
   4756 int _sesto_rx_enable_get(const phymod_phy_access_t *phy, int16_t *enable)
   4757 {
   4758     phymod_phy_inf_config_t config;
   4759     uint16_t ip = 0;
   4760     uint16_t lane = 0, max_lane = 0;
   4761     uint16_t lane_mask = 0;
   4762     int rv = PHYMOD_E_NONE;
   4763     const phymod_access_t *pa = &phy->access;
   4764     M10G_SIGDET_SIGDET_CTRL_1_TYPE_T merlin_ctrl1_lane;
   4765     F25G_SIGDET_SIGDET_CTRL_1_TYPE_T falcon_ctrl1_lane;
   4766 
   4767     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4768     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4769     SESTO_IF_ERR_RETURN(
   4770        _sesto_phy_interface_config_get(phy, 0, &config));
   4771     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4772     SESTO_GET_IP(phy, config, ip);
   4773 
   4774     max_lane = (ip == SESTO_FALCON_CORE) ?
   4775                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4776 
   4777     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   4778              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4779 
   4780     /* RX squelch get with signal_detect_frc_val */
   4781     for (lane = 0; lane < max_lane; lane ++) {
   4782         if (lane_mask & (1 << lane)) {
   4783             SESTO_IF_ERR_RETURN(
   4784               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   4785                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   4786             if (ip == SESTO_FALCON_CORE) {
   4787                 READ_SESTO_PMA_PMD_REG(pa, F25G_SIGDET_SIGDET_CTRL_1_ADR, falcon_ctrl1_lane.data);
   4788                 *enable = falcon_ctrl1_lane.fields.signal_detect_frc_val;
   4789             } else {
   4790                 READ_SESTO_PMA_PMD_REG(pa, M10G_SIGDET_SIGDET_CTRL_1_ADR, merlin_ctrl1_lane.data);
   4791                 *enable = merlin_ctrl1_lane.fields.signal_detect_frc_val;
   4792             }
   4793         }
   4794     }
   4795 
   4796 ERR:
   4797     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   4798     PHYMOD_FREE(config.device_aux_modes);
   4799 
   4800     return rv;
   4801 }
   4802 
   4803 int _sesto_rx_dp_reset(const phymod_phy_access_t *phy)
   4804 {
   4805     phymod_phy_inf_config_t config;
   4806     uint16_t ip = 0;
   4807     uint16_t lane = 0, max_lane = 0;
   4808     uint16_t lane_mask = 0;
   4809     int rv = PHYMOD_E_NONE;
   4810     const phymod_access_t *pa = &phy->access;
   4811     DP_LANE_RESET_CONTROL0_TYPE_T dp_rst;
   4812 
   4813     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4814     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4815     SESTO_IF_ERR_RETURN(
   4816        _sesto_phy_interface_config_get(phy, 0, &config));
   4817     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4818     
   4819     SESTO_GET_IP(phy, config, ip);
   4820     max_lane = (ip == SESTO_FALCON_CORE) ? 
   4821                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   4822     
   4823     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__, 
   4824              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   4825 
   4826     /* Reset RX data path */
   4827     for (lane = 0; lane < max_lane; lane ++) {
   4828         if (lane_mask & (1 << lane)) {
   4829             READ_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4830             if (ip == SESTO_FALCON_CORE) {
   4831                 dp_rst.fields.demux_ilane_dp_rstb &= ~(1 << lane);
   4832             } else {
   4833                 dp_rst.fields.mux_ilane_dp_rstb &= ~(1 << lane);
   4834             }
   4835             WRITE_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4836             PHYMOD_USLEEP(1000);
   4837             READ_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4838             if (ip == SESTO_FALCON_CORE) {
   4839                 dp_rst.fields.demux_ilane_dp_rstb |= (1 << lane);
   4840             } else {
   4841                 dp_rst.fields.mux_ilane_dp_rstb |= (1 << lane);
   4842             }
   4843             WRITE_SESTO_PMA_PMD_REG(pa, DP_LANE_RESET_CONTROL0_ADR, dp_rst.data);
   4844         }
   4845     }
   4846 
   4847 ERR:
   4848     PHYMOD_FREE(config.device_aux_modes);
   4849 
   4850     return rv;
   4851 }
   4852 
   4853 
   4854 int _sesto_tx_lane_control_set(const phymod_phy_access_t *phy,  phymod_phy_tx_lane_control_t tx_control)
   4855 {
   4856     int rv = PHYMOD_E_NONE;
   4857 
   4858     switch (tx_control) {
   4859         case phymodTxTrafficDisable: /* disable tx traffic */
   4860         case phymodTxTrafficEnable: /* enable tx traffic */
   4861             return PHYMOD_E_UNAVAIL;
   4862         case phymodTxReset: /* reset tx data path */
   4863             SESTO_IF_ERR_RETURN(_sesto_tx_dp_reset(phy));
   4864         break;
   4865         case phymodTxSquelchOn: /* squelch tx */
   4866             SESTO_IF_ERR_RETURN(_sesto_tx_enable_set(phy, SESTO_DISABLE));
   4867         break;
   4868         case phymodTxSquelchOff: /* squelch tx off */
   4869             SESTO_IF_ERR_RETURN(_sesto_tx_enable_set(phy, SESTO_ENABLE));
   4870         break;
   4871         default:
   4872             return PHYMOD_E_PARAM;
   4873     }
   4874 
   4875 ERR:
   4876     return rv;
   4877 }
   4878 int _sesto_rx_lane_control_set(const phymod_phy_access_t *phy,  phymod_phy_rx_lane_control_t rx_control)
   4879 {
   4880     int rv = PHYMOD_E_NONE;
   4881 
   4882     switch (rx_control) {
   4883         case phymodRxReset: /* reset rx data path */
   4884             SESTO_IF_ERR_RETURN(_sesto_rx_dp_reset(phy));
   4885             break;
   4886         case phymodRxSquelchOn: /* squelch rx */
   4887             SESTO_IF_ERR_RETURN(_sesto_rx_enable_set(phy, SESTO_DISABLE));
   4888         break;
   4889         case phymodRxSquelchOff: /* squelch rx off */
   4890             SESTO_IF_ERR_RETURN(_sesto_rx_enable_set(phy, SESTO_ENABLE));
   4891         break;
   4892         default:
   4893             return PHYMOD_E_PARAM;
   4894     }
   4895 
   4896 ERR:
   4897     return rv;
   4898 }
   4899 
   4900 int _sesto_tx_lane_control_get(const phymod_phy_access_t *phy,  phymod_phy_tx_lane_control_t *tx_control)
   4901 {
   4902     int16_t tx_ctrl = 0;
   4903     int rv = PHYMOD_E_NONE;
   4904 
   4905     switch (*tx_control) {
   4906         case phymodTxTrafficDisable: /* disable tx traffic */
   4907         case phymodTxTrafficEnable: /* enable tx traffic */
   4908         case phymodTxReset: /* reset tx data path */
   4909             return PHYMOD_E_UNAVAIL;
   4910         break;
   4911         case phymodTxSquelchOn: /* squelch tx */
   4912             SESTO_IF_ERR_RETURN(_sesto_tx_enable_get(phy, &tx_ctrl));
   4913             *tx_control = tx_ctrl ? phymodTxSquelchOff: phymodTxSquelchOn;
   4914         break;
   4915         case phymodTxSquelchOff: /* squelch tx off */
   4916             SESTO_IF_ERR_RETURN(_sesto_tx_enable_get(phy, &tx_ctrl));
   4917             *tx_control = tx_ctrl ? phymodTxSquelchOff: phymodTxSquelchOn;
   4918         break;
   4919         default:
   4920             SESTO_IF_ERR_RETURN(_sesto_tx_enable_get(phy, &tx_ctrl));
   4921             *tx_control = tx_ctrl ? phymodTxSquelchOff: phymodTxSquelchOn;
   4922         break;
   4923     }
   4924 
   4925 ERR:
   4926     return rv;
   4927 }
   4928 int _sesto_rx_lane_control_get(const phymod_phy_access_t *phy,  phymod_phy_rx_lane_control_t *rx_control)
   4929 {
   4930     int16_t rx_ctrl = 0;
   4931     int rv = PHYMOD_E_NONE;
   4932 
   4933     switch (*rx_control) {
   4934         case phymodRxReset: /* reset rx data path */
   4935             return PHYMOD_E_UNAVAIL;
   4936         case phymodRxSquelchOn: /* squelch rx */
   4937             SESTO_IF_ERR_RETURN(_sesto_rx_enable_get(phy, &rx_ctrl));
   4938             *rx_control = rx_ctrl ? phymodRxSquelchOff: phymodRxSquelchOn;
   4939         break;
   4940         case phymodRxSquelchOff: /* squelch rx off */
   4941             SESTO_IF_ERR_RETURN(_sesto_rx_enable_get(phy, &rx_ctrl));
   4942             *rx_control = rx_ctrl ? phymodRxSquelchOff: phymodRxSquelchOn;
   4943         break;
   4944         default:
   4945             return PHYMOD_E_PARAM;
   4946     }
   4947 
   4948 ERR:
   4949     return rv;
   4950 }
   4951 int _sesto_intr_phymod_intr(const phymod_phy_access_t *phy, uint32_t intr_type, uint16_t *intr)
   4952 {
   4953     phymod_phy_inf_config_t config;
   4954     uint16_t ip = 0, lane_mask = 0;
   4955     int rv = PHYMOD_E_NONE;
   4956     const phymod_access_t *pa = &phy->access;
   4957 
   4958     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   4959     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   4960     SESTO_IF_ERR_RETURN( _sesto_phy_interface_config_get(phy, 0, &config));
   4961     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   4962     SESTO_GET_IP(phy, config, ip);
   4963 
   4964     switch (intr_type) {
   4965         case PHYMOD_INTR_LINK_EVENT:
   4966             *intr = (ip == SESTO_FALCON_CORE) ? SESTO_INT_DEMUX_PMD_LOCK_LOST : SESTO_INT_MUX_PMD_LOCK_LOST;
   4967         break;
   4968         case PHYMOD_INTR_AUTONEG_EVENT:
   4969             if (ip == SESTO_FALCON_CORE) {
   4970                 *intr = SESTO_INT_DEMUX_CL73_AN_COMPLETE;
   4971             } else {
   4972                 if (lane_mask == 0xF) {                         /* 40G MUX P1 */
   4973                     *intr = SESTO_INT_MUX_CL73_AN_COMPLETE_P1;
   4974                 } else if (lane_mask == 0xF0) {                 /* 40G MUX P1 */
   4975                     *intr = SESTO_INT_MUX_CL73_AN_COMPLETE_P2;
   4976                 } else {                                        /* 40G PT based on AN Master lane */
   4977                     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T an_mst_sel;
   4978                     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   4979                     if (((an_mst_sel.data & 0xF) >= 4) && ((an_mst_sel.data & 0xF) <= 5)) {
   4980                          *intr = SESTO_INT_MUX_CL73_AN_COMPLETE_P2;
   4981                     } else {
   4982                          *intr = SESTO_INT_MUX_CL73_AN_COMPLETE_P1;
   4983                     }
   4984                 }
   4985             }
   4986         break;
   4987         case PHYMOD_INTR_PLL_EVENT:
   4988             *intr = (ip == SESTO_FALCON_CORE) ? SESTO_INT_PLL_25G_LOCK_LOST : SESTO_INT_PLL_10G_LOCK_LOST;
   4989         break;
   4990         case PHYMOD_INTR_EMON_EVENT:
   4991             *intr = (ip == SESTO_FALCON_CORE) ? SESTO_INT_DEMUX_PCS_MON_LOCK_LOST : SESTO_INT_MUX_PCS_MON_LOCK_LOST;
   4992         break;
   4993         default:
   4994             return PHYMOD_E_NONE;
   4995     }
   4996 ERR:
   4997     PHYMOD_FREE(config.device_aux_modes);
   4998 
   4999     return rv;
   5000 }
   5001 
   5002 int  _sesto_get_intr_reg(const phymod_phy_access_t *phy, uint32_t intr_type, uint16_t *bit_pos, uint16_t *int_grp)
   5003 {
   5004     uint16_t intr = -1;
   5005     int rv = PHYMOD_E_NONE;
   5006 
   5007     SESTO_IF_ERR_RETURN(_sesto_intr_phymod_intr(phy, intr_type, &intr));
   5008     *int_grp = -1;
   5009 
   5010     /* Get the interrupt bit postion in the reg and interrupt group */
   5011     switch (intr) {
   5012         case SESTO_INT_M0_SLV_SYSRESET_REQ:          *bit_pos =  0;   *int_grp =  0; break;
   5013         case SESTO_INT_M0_MST_SYSRESET_REQ:          *bit_pos =  1;   *int_grp =  0; break;
   5014         case SESTO_INT_M0_SLV_LOCKUP:                *bit_pos =  2;   *int_grp =  0; break;
   5015         case SESTO_INT_M0_MST_LOCKUP:                *bit_pos =  3;   *int_grp =  0; break;
   5016         case SESTO_INT_M0_SLV_MISC_INTR:             *bit_pos =  4;   *int_grp =  0; break;
   5017         case SESTO_INT_M0_MST_MISC_INTR:             *bit_pos =  5;   *int_grp =  0; break;
   5018         case SESTO_INT_M0_SLV_MSGOUT_INTR:           *bit_pos =  6;   *int_grp =  0; break;
   5019         case SESTO_INT_M0_MST_MSGOUT_INTR:           *bit_pos =  7;   *int_grp =  0; break;
   5020         case SESTO_INT_M0_SLV_DED:                   *bit_pos =  8;   *int_grp =  0; break;
   5021         case SESTO_INT_M0_SLV_SEC:                   *bit_pos =  9;   *int_grp =  0; break;
   5022         case SESTO_INT_M0_MST_DED:                   *bit_pos = 10;   *int_grp =  0; break;
   5023         case SESTO_INT_M0_MST_SEC:                   *bit_pos = 11;   *int_grp =  0; break;
   5024         case SESTO_INT_MODULE2_INTRB_LOW:            *bit_pos = 12;   *int_grp =  0; break;
   5025         case SESTO_INT_MODULE2_INTRB_HIGH:           *bit_pos = 13;   *int_grp =  0; break;
   5026         case SESTO_INT_MODULE1_INTRB_LOW:            *bit_pos = 14;   *int_grp =  0; break;
   5027         case SESTO_INT_MODULE1_INTRB_HIGH:           *bit_pos = 15;   *int_grp =  0; break;
   5028         case SESTO_INT_MUX_PMD_LOCK_LOST:            *bit_pos =  0;   *int_grp =  1; break;
   5029         case SESTO_INT_MUX_PMD_LOCK_FOUND:           *bit_pos =  1;   *int_grp =  1; break;
   5030         case SESTO_INT_MUX_SIGDET_LOST:              *bit_pos =  2;   *int_grp =  1; break;
   5031         case SESTO_INT_MUX_SIGDET_FOUND:             *bit_pos =  3;   *int_grp =  1; break;
   5032         case SESTO_INT_PLL_10G_LOCK_LOST:            *bit_pos =  4;   *int_grp =  1; break;
   5033         case SESTO_INT_PLL_10G_LOCK_FOUND:           *bit_pos =  5;   *int_grp =  1; break;
   5034         case SESTO_INT_MERLIN_PMI_ARB_WDOG_EXP:      *bit_pos =  6;   *int_grp =  1; break;
   5035         case SESTO_INT_MERLIN_PMI_M0_WDOG_EXP:       *bit_pos =  7;   *int_grp =  1; break;
   5036         case SESTO_INT_DEMUX_PMD_LOCK_LOST:          *bit_pos =  0;   *int_grp =  2; break;
   5037         case SESTO_INT_DEMUX_PMD_LOCK_FOUND:         *bit_pos =  1;   *int_grp =  2; break;
   5038         case SESTO_INT_DEMUX_SIGDET_LOST:            *bit_pos =  2;   *int_grp =  2; break;
   5039         case SESTO_INT_DEMUX_SIGDET_FOUND:           *bit_pos =  3;   *int_grp =  2; break;
   5040         case SESTO_INT_PLL_25G_LOCK_LOST:            *bit_pos =  4;   *int_grp =  2; break;
   5041         case SESTO_INT_PLL_25G_LOCK_FOUND:           *bit_pos =  5;   *int_grp =  2; break;
   5042         case SESTO_INT_FALCON_PMD_ARB_WDOG_EXP:      *bit_pos =  6;   *int_grp =  2; break;
   5043         case SESTO_INT_FALCON_PMD_M0_WDOG_EXP:       *bit_pos =  7;   *int_grp =  2; break;
   5044         case SESTO_INT_CL91_RX_ALIGN_LOST:           *bit_pos =  0;   *int_grp =  3; break;
   5045         case SESTO_INT_CL91_RX_ALIGN_FOUND:          *bit_pos =  1;   *int_grp =  3; break;
   5046         case SESTO_INT_DEMUX_ONEG_INBAND_MSG_LOST:   *bit_pos =  2;   *int_grp =  3; break;
   5047         case SESTO_INT_DEMUX_ONEG_INBAND_MSG_FOUND:  *bit_pos =  3;   *int_grp =  3; break;
   5048         case SESTO_INT_DEMUX_PCS_MON_LOCK_LOST:      *bit_pos =  4;   *int_grp =  3; break;
   5049         case SESTO_INT_DEMUX_PCS_MON_LOCK_FOUND:     *bit_pos =  5;   *int_grp =  3; break;
   5050         case SESTO_INT_DEMUX_FIFOERR:                *bit_pos =  6;   *int_grp =  3; break;
   5051         case SESTO_INT_DEMUX_CL73_AN_RESTARTED:      *bit_pos =  7;   *int_grp =  3; break;
   5052         case SESTO_INT_DEMUX_CL73_AN_COMPLETE:       *bit_pos =  8;   *int_grp =  3; break;
   5053         case SESTO_INT_CL91_TX_ALIGN_LOST:           *bit_pos =  0;   *int_grp =  4; break;
   5054         case SESTO_INT_CL91_TX_ALIGN_FOUND:          *bit_pos =  1;   *int_grp =  4; break;
   5055         case SESTO_INT_MUX_ONEG_INBAND_MSG_LOST:     *bit_pos =  2;   *int_grp =  4; break;
   5056         case SESTO_INT_MUX_ONEG_INBAND_MSG_FOUND:    *bit_pos =  3;   *int_grp =  4; break;
   5057         case SESTO_INT_MUX_PCS_MON_LOCK_LOST:        *bit_pos =  4;   *int_grp =  4; break;
   5058         case SESTO_INT_MUX_PCS_MON_LOCK_FOUND:       *bit_pos =  5;   *int_grp =  4; break;
   5059         case SESTO_INT_MUX_FIFOERR:                  *bit_pos =  6;   *int_grp =  4; break;
   5060         case SESTO_INT_MUX_CL73_AN_RESTARTED:        *bit_pos =  7;   *int_grp =  4; break;
   5061         case SESTO_INT_MUX_CL73_AN_COMPLETE:         *bit_pos =  8;   *int_grp =  4; break;
   5062         case SESTO_INT_MUX_CL73_AN_RESTARTED_P2:     *bit_pos =  9;   *int_grp =  4; break;
   5063         case SESTO_INT_MUX_CL73_AN_RESTARTED_P1:     *bit_pos = 10;   *int_grp =  4; break;
   5064         case SESTO_INT_MUX_CL73_AN_COMPLETE_P2:      *bit_pos = 11;   *int_grp =  4; break;
   5065         case SESTO_INT_MUX_CL73_AN_COMPLETE_P1:      *bit_pos = 12;   *int_grp =  4; break;
   5066         default:
   5067             return PHYMOD_E_PARAM;
   5068     }
   5069 
   5070 ERR:
   5071     return rv;
   5072 }
   5073 int _sesto_ext_intr_enable_set(const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t enable)
   5074 {
   5075     uint16_t intr_grp = 0;
   5076     uint16_t bit_pos = 0;
   5077     uint16_t intr_mask = 0;
   5078     int rv = PHYMOD_E_NONE;
   5079     SES_CTRL_M0_EIER_TYPE_T    m0_eier;
   5080     SES_CTRL_MM_EIER_TYPE_T    mm_eier;
   5081     SES_CTRL_DF_EIER_TYPE_T    df_eier;
   5082     SES_CTRL_DEMUX_EIER_TYPE_T demux_eier;
   5083     SES_CTRL_MUX_EIER_TYPE_T   mux_eier;
   5084     const phymod_access_t *pa = &phy->access;
   5085 
   5086     PHYMOD_MEMSET(&m0_eier, 0, sizeof(SES_CTRL_M0_EIER_TYPE_T));
   5087     PHYMOD_MEMSET(&mm_eier, 0, sizeof(SES_CTRL_MM_EIER_TYPE_T));
   5088     PHYMOD_MEMSET(&df_eier, 0, sizeof(SES_CTRL_DF_EIER_TYPE_T));
   5089     PHYMOD_MEMSET(&demux_eier, 0, sizeof(SES_CTRL_DEMUX_EIER_TYPE_T));
   5090     PHYMOD_MEMSET(&mux_eier, 0, sizeof(SES_CTRL_MUX_EIER_TYPE_T));
   5091     
   5092 
   5093     /* Get the interrupt bit postion in the reg and interrupt group */
   5094     _sesto_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp);
   5095     intr_mask = enable ? (0x1 << bit_pos) : (~(0x1 << bit_pos));
   5096 
   5097     /* Interrupt enable set on specified interrupt group */
   5098     switch(intr_grp) {
   5099         case SESTO_M0_INTR_GRP:
   5100            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_M0_EIER_ADR, m0_eier.data);
   5101            m0_eier.data =  enable ? (intr_mask | m0_eier.data) : (intr_mask & m0_eier.data);
   5102            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_M0_EIER_ADR, m0_eier.data);
   5103         break;
   5104         case SESTO_MM_INTR_GRP:
   5105            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_MM_EIER_ADR, mm_eier.data);
   5106            mm_eier.data =  enable ? (intr_mask | mm_eier.data) : (intr_mask & mm_eier.data);
   5107            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_MM_EIER_ADR, mm_eier.data);
   5108         break;
   5109         case SESTO_DF_INTR_GRP:
   5110            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_DF_EIER_ADR, df_eier.data);
   5111            df_eier.data =  enable ? (intr_mask | df_eier.data) : (intr_mask & df_eier.data);
   5112            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_DF_EIER_ADR, df_eier.data);
   5113         break;
   5114         case SESTO_DEMUX_INTR_GRP:
   5115            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_DEMUX_EIER_ADR, demux_eier.data);
   5116            demux_eier.data =  enable ? (intr_mask | demux_eier.data) : (intr_mask & demux_eier.data);
   5117            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_DEMUX_EIER_ADR, demux_eier.data);
   5118         break;
   5119         case SESTO_MUX_INTR_GRP:
   5120            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_MUX_EIER_ADR, mux_eier.data);
   5121            mux_eier.data =  enable ? (intr_mask | mux_eier.data) : (intr_mask & mux_eier.data);
   5122            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_MUX_EIER_ADR, mux_eier.data);
   5123         break;
   5124         default:
   5125             return PHYMOD_E_NONE;
   5126     }
   5127 
   5128 ERR:
   5129     return rv;
   5130 }
   5131 int _sesto_ext_intr_enable_get(const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t *enable)
   5132 {
   5133     uint16_t intr_grp = 0;
   5134     uint16_t bit_pos = 0;
   5135     uint16_t data = 0;
   5136     int rv = PHYMOD_E_NONE;
   5137     SES_CTRL_M0_EIER_TYPE_T    m0_eier;
   5138     SES_CTRL_MM_EIER_TYPE_T    mm_eier;
   5139     SES_CTRL_DF_EIER_TYPE_T    df_eier;
   5140     SES_CTRL_DEMUX_EIER_TYPE_T demux_eier;
   5141     SES_CTRL_MUX_EIER_TYPE_T   mux_eier;
   5142     const phymod_access_t *pa = &phy->access;
   5143 
   5144     PHYMOD_MEMSET(&m0_eier, 0, sizeof(SES_CTRL_M0_EIER_TYPE_T));
   5145     PHYMOD_MEMSET(&mm_eier, 0, sizeof(SES_CTRL_MM_EIER_TYPE_T));
   5146     PHYMOD_MEMSET(&df_eier, 0, sizeof(SES_CTRL_DF_EIER_TYPE_T));
   5147     PHYMOD_MEMSET(&demux_eier, 0, sizeof(SES_CTRL_DEMUX_EIER_TYPE_T));
   5148     PHYMOD_MEMSET(&mux_eier, 0, sizeof(SES_CTRL_MUX_EIER_TYPE_T));
   5149     *enable = 0;
   5150 
   5151     /* Get the interrupt bit postion in the reg and interrupt group */
   5152     _sesto_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp);
   5153 
   5154     /* Interrupt enable get on specified interrupt group */
   5155     switch(intr_grp) {
   5156         case SESTO_M0_INTR_GRP:
   5157            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_M0_EIER_ADR, m0_eier.data);
   5158            data = m0_eier.data;
   5159         break;
   5160         case SESTO_MM_INTR_GRP:
   5161            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_MM_EIER_ADR, mm_eier.data);
   5162            data = mm_eier.data;
   5163         break;
   5164         case SESTO_DF_INTR_GRP:
   5165            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_DF_EIER_ADR, df_eier.data);
   5166            data = df_eier.data;
   5167         break;
   5168         case SESTO_DEMUX_INTR_GRP:
   5169            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_DEMUX_EIER_ADR, demux_eier.data);
   5170            data = demux_eier.data;
   5171         break;
   5172         case SESTO_MUX_INTR_GRP:
   5173            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_MUX_EIER_ADR, mux_eier.data);
   5174            data = mux_eier.data;
   5175         break;
   5176         default:
   5177             return PHYMOD_E_NONE;
   5178     }
   5179     *enable = (data & (0x1 << bit_pos)) ? 1 : 0;
   5180 
   5181 ERR:
   5182     return rv;
   5183 }
   5184 
   5185 int _sesto_ext_intr_status_get(const phymod_phy_access_t *phy, uint32_t intr_type, uint32_t *intr_status)
   5186 {
   5187     uint16_t intr_grp = 0;
   5188     uint16_t bit_pos = 0;
   5189     uint16_t data = 0;
   5190     int rv = PHYMOD_E_NONE;
   5191     SES_CTRL_M0_EIPR_TYPE_T    m0_eipr;
   5192     SES_CTRL_MM_EIPR_TYPE_T    mm_eipr;
   5193     SES_CTRL_DF_EIPR_TYPE_T    df_eipr;
   5194     SES_CTRL_DEMUX_EIPR_TYPE_T demux_eipr;
   5195     SES_CTRL_MUX_EIPR_TYPE_T   mux_eipr;
   5196     const phymod_access_t *pa = &phy->access;
   5197 
   5198     PHYMOD_MEMSET(&m0_eipr, 0, sizeof(SES_CTRL_M0_EIPR_TYPE_T));
   5199     PHYMOD_MEMSET(&mm_eipr, 0, sizeof(SES_CTRL_MM_EIPR_TYPE_T));
   5200     PHYMOD_MEMSET(&df_eipr, 0, sizeof(SES_CTRL_DF_EIPR_TYPE_T));
   5201     PHYMOD_MEMSET(&demux_eipr, 0, sizeof(SES_CTRL_DEMUX_EIPR_TYPE_T));
   5202     PHYMOD_MEMSET(&mux_eipr, 0, sizeof(SES_CTRL_MUX_EIPR_TYPE_T));
   5203     *intr_status = 0;
   5204 
   5205     /* Get the interrupt bit postion in the reg and interrupt group */
   5206     _sesto_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp);
   5207 
   5208     /* Interrupt status get on specified interrupt group */
   5209     switch(intr_grp) {
   5210         case SESTO_M0_INTR_GRP:
   5211            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_M0_EIPR_ADR, m0_eipr.data);
   5212            data = m0_eipr.data;
   5213         break;
   5214         case SESTO_MM_INTR_GRP:
   5215            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_MM_EIPR_ADR, mm_eipr.data);
   5216            data = mm_eipr.data;
   5217         break;
   5218         case SESTO_DF_INTR_GRP:
   5219            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_DF_EIPR_ADR, df_eipr.data);
   5220            data = df_eipr.data;
   5221         break;
   5222         case SESTO_DEMUX_INTR_GRP:
   5223            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_DEMUX_EIPR_ADR, demux_eipr.data);
   5224            data = demux_eipr.data;
   5225         break;
   5226         case SESTO_MUX_INTR_GRP:
   5227            READ_SESTO_PMA_PMD_REG(pa, SES_CTRL_MUX_EIPR_ADR, mux_eipr.data);
   5228            data = mux_eipr.data;
   5229         break;
   5230         default:
   5231             return PHYMOD_E_NONE;
   5232     }
   5233     *intr_status = (data & (0x1 << bit_pos)) ? 1 : 0;
   5234 
   5235 ERR:
   5236     return rv;
   5237 }
   5238 
   5239 int _sesto_ext_intr_status_clear(const phymod_phy_access_t *phy, uint32_t intr_type)
   5240 {
   5241     uint16_t intr_grp = 0;
   5242     uint16_t bit_pos = 0;
   5243     uint16_t intr_mask = 0;
   5244     int rv = PHYMOD_E_NONE;
   5245     SES_CTRL_M0_EISR_TYPE_T    m0_eisr;
   5246     SES_CTRL_MM_EISR_TYPE_T    mm_eisr;
   5247     SES_CTRL_DF_EISR_TYPE_T    df_eisr;
   5248     SES_CTRL_DEMUX_EISR_TYPE_T demux_eisr;
   5249     SES_CTRL_MUX_EISR_TYPE_T   mux_eisr;
   5250     const phymod_access_t *pa = &phy->access;
   5251 
   5252     PHYMOD_MEMSET(&m0_eisr, 0, sizeof(SES_CTRL_M0_EISR_TYPE_T));
   5253     PHYMOD_MEMSET(&mm_eisr, 0, sizeof(SES_CTRL_MM_EISR_TYPE_T));
   5254     PHYMOD_MEMSET(&df_eisr, 0, sizeof(SES_CTRL_DF_EISR_TYPE_T));
   5255     PHYMOD_MEMSET(&demux_eisr, 0, sizeof(SES_CTRL_DEMUX_EISR_TYPE_T));
   5256     PHYMOD_MEMSET(&mux_eisr, 0, sizeof(SES_CTRL_MUX_EISR_TYPE_T));
   5257 
   5258     /* Get the interrupt bit postion in the reg and interrupt group */
   5259     _sesto_get_intr_reg(phy, intr_type, &bit_pos, &intr_grp);
   5260     intr_mask = 0x1 << bit_pos;
   5261 
   5262     /* Interrupt status clear on specified interrupt group */
   5263     switch(intr_grp) {
   5264         case SESTO_M0_INTR_GRP:
   5265            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_M0_EISR_ADR, intr_mask);
   5266         break;
   5267         case SESTO_MM_INTR_GRP:
   5268            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_MM_EISR_ADR, intr_mask);
   5269         break;
   5270         case SESTO_DF_INTR_GRP:
   5271            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_DF_EISR_ADR, intr_mask);
   5272         break;
   5273         case SESTO_DEMUX_INTR_GRP:
   5274            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_DEMUX_EISR_ADR, intr_mask);
   5275         break;
   5276         case SESTO_MUX_INTR_GRP:
   5277            WRITE_SESTO_PMA_PMD_REG(pa, SES_CTRL_MUX_EISR_ADR, intr_mask);
   5278         break;
   5279         default:
   5280             return PHYMOD_E_NONE;
   5281     }
   5282 
   5283 ERR:
   5284     return rv;
   5285 }
   5286 
   5287 int _sesto_pll_sequencer_restart(const phymod_core_access_t *core, phymod_sequencer_operation_t operation)
   5288 {
   5289     uint16_t ip = 0, intf_side = 0;
   5290     int rv = PHYMOD_E_NONE;
   5291     const phymod_access_t *pa = &core->access;
   5292     DP_DECODED_MODE_STATUS0_TYPE_T mode_sts0;
   5293     FALCON_IF_COMMON_CONTROL_TYPE_T  fal_cmn_ctrl;
   5294     MERLIN_IF_COMMON_CONTROL_TYPE_T  mer_cmn_ctrl;
   5295 
   5296     SESTO_GET_INTF_SIDE(core, intf_side);
   5297     READ_SESTO_PMA_PMD_REG(pa, DP_DECODED_MODE_STATUS0_ADR, mode_sts0.data);
   5298     if (intf_side == SESTO_IF_LINE) {
   5299         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_FALCON_CORE : SESTO_MERLIN_CORE;
   5300     } else {
   5301         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_MERLIN_CORE : SESTO_FALCON_CORE;
   5302     }
   5303     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   5304                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   5305     switch(operation) {
   5306         case phymodSeqOpStop:
   5307         case phymodSeqOpStart:
   5308             return PHYMOD_E_UNAVAIL;
   5309         /* Toggle PLL Sequencer with pmd_core_dp_h_rstb_frcval */
   5310         case phymodSeqOpRestart:
   5311             if (ip == SESTO_FALCON_CORE) {
   5312                 READ_SESTO_PMA_PMD_REG(pa, FALCON_IF_COMMON_CONTROL_ADR, fal_cmn_ctrl.data);
   5313                 fal_cmn_ctrl.fields.pmd_core_dp_h_rstb_frc = 1;
   5314                 fal_cmn_ctrl.fields.pmd_core_dp_h_rstb_frcval = 0;
   5315                 WRITE_SESTO_PMA_PMD_REG(pa, FALCON_IF_COMMON_CONTROL_ADR, fal_cmn_ctrl.data);
   5316                 PHYMOD_USLEEP(1000);
   5317                 READ_SESTO_PMA_PMD_REG(pa, FALCON_IF_COMMON_CONTROL_ADR, fal_cmn_ctrl.data);
   5318                 fal_cmn_ctrl.fields.pmd_core_dp_h_rstb_frc = 1;
   5319                 fal_cmn_ctrl.fields.pmd_core_dp_h_rstb_frcval = 1;
   5320                 WRITE_SESTO_PMA_PMD_REG(pa, FALCON_IF_COMMON_CONTROL_ADR, fal_cmn_ctrl.data);
   5321             } else {
   5322                 READ_SESTO_PMA_PMD_REG(pa, MERLIN_IF_COMMON_CONTROL_ADR, mer_cmn_ctrl.data);
   5323                 mer_cmn_ctrl.fields.pmd_core_dp_h_rstb_frc = 1;
   5324                 mer_cmn_ctrl.fields.pmd_core_dp_h_rstb_frcval = 0;
   5325                 WRITE_SESTO_PMA_PMD_REG(pa, MERLIN_IF_COMMON_CONTROL_ADR, mer_cmn_ctrl.data);
   5326                 PHYMOD_USLEEP(1000);
   5327                 READ_SESTO_PMA_PMD_REG(pa, MERLIN_IF_COMMON_CONTROL_ADR, mer_cmn_ctrl.data);
   5328                 mer_cmn_ctrl.fields.pmd_core_dp_h_rstb_frc = 1;
   5329                 mer_cmn_ctrl.fields.pmd_core_dp_h_rstb_frcval = 1;
   5330                 WRITE_SESTO_PMA_PMD_REG(pa, MERLIN_IF_COMMON_CONTROL_ADR, mer_cmn_ctrl.data);
   5331 
   5332             }
   5333         break;
   5334         default:
   5335         break;
   5336     }
   5337     /* Clear FRC of rstb */
   5338     SESTO_CHIP_FIELD_WRITE(pa, FALCON_IF_COMMON_CONTROL, pmd_core_dp_h_rstb_frc, 0);
   5339     SESTO_CHIP_FIELD_WRITE(pa, MERLIN_IF_COMMON_CONTROL, pmd_core_dp_h_rstb_frc, 0);
   5340 
   5341 ERR:
   5342     return rv;
   5343 }
   5344 
   5345 int _sesto_fec_enable_set(const phymod_phy_access_t *phy, uint32_t enable)
   5346 {
   5347     uint16_t ip = 0, intf_side = 0;
   5348     int rv = PHYMOD_E_NONE;
   5349     const phymod_access_t *pa = &phy->access;
   5350     DP_DECODED_MODE_STATUS0_TYPE_T mode_sts0;
   5351 
   5352     SESTO_GET_INTF_SIDE(phy, intf_side);
   5353     READ_SESTO_PMA_PMD_REG(pa, DP_DECODED_MODE_STATUS0_ADR, mode_sts0.data);
   5354     if (intf_side == SESTO_IF_LINE) {
   5355         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_FALCON_CORE : SESTO_MERLIN_CORE;
   5356     } else {
   5357         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_MERLIN_CORE : SESTO_FALCON_CORE;
   5358     }
   5359 
   5360     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   5361                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   5362     /* Enables 100G FEC in Gearbox mode */
   5363     if (ip == SESTO_FALCON_CORE) {
   5364         SESTO_CHIP_FIELD_WRITE(pa, DP_SESTO_MODE_CTRL0, mode_cl91_en, enable);
   5365     } else {
   5366         SESTO_RETURN_WITH_ERR(PHYMOD_E_PARAM,
   5367             (_PHYMOD_MSG("FEC Applicable for Gearbox mode and 25G SERDES only")));
   5368     }
   5369 
   5370 ERR:
   5371     return rv;
   5372 }
   5373 int _sesto_fec_enable_get(const phymod_phy_access_t *phy, uint32_t* enable)
   5374 {
   5375     uint16_t ip = 0, intf_side = 0;
   5376     int rv = PHYMOD_E_NONE;
   5377     const phymod_access_t *pa = &phy->access;
   5378     DP_DECODED_MODE_STATUS0_TYPE_T mode_sts0;
   5379 
   5380     SESTO_GET_INTF_SIDE(phy, intf_side);
   5381     READ_SESTO_PMA_PMD_REG(pa, DP_DECODED_MODE_STATUS0_ADR, mode_sts0.data);
   5382     if (intf_side == SESTO_IF_LINE) {
   5383         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_FALCON_CORE : SESTO_MERLIN_CORE;
   5384     } else {
   5385         ip = (mode_sts0.fields.decoded_mode_falcon_line) ? SESTO_MERLIN_CORE : SESTO_FALCON_CORE;
   5386     }
   5387 
   5388     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   5389                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   5390     /* FEC status on 100G Gearbox mode */
   5391     if (ip == SESTO_FALCON_CORE) {
   5392         SESTO_CHIP_FIELD_READ(pa, DP_SESTO_MODE_CTRL0, mode_cl91_en, (*enable));
   5393     } else {
   5394         SESTO_RETURN_WITH_ERR(PHYMOD_E_PARAM,
   5395             (_PHYMOD_MSG("FEC Applicable for Gearbox mode and 25G SERDES only")));
   5396     }
   5397 
   5398 ERR:
   5399     return rv;
   5400 }
   5401 
   5402 int _sesto_config_hcd_link_sts (const phymod_access_t* pa, phymod_phy_inf_config_t config, uint16_t ip ) 
   5403 {
   5404     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   5405     int rv = PHYMOD_E_NONE;
   5406     RX_ANA_REGS_ANARXCONTROL3_TYPE_T an_rx_ctrl3;
   5407  
   5408     aux_mode = config.device_aux_modes;
   5409 
   5410     if (!aux_mode->pass_thru && config.data_rate != SESTO_SPD_100G) {
   5411         /* 40G Mux Mode*/
   5412         if (pa->lane_mask & 0xF) {
   5413            SESTO_IF_ERR_RETURN(
   5414                _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5415                                          SESTO_DEV_AN, 0, 0));
   5416         } else {
   5417            SESTO_IF_ERR_RETURN(
   5418                _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5419                                          SESTO_DEV_AN, 0, 1));
   5420         }
   5421     } else {
   5422         SESTO_IF_ERR_RETURN(
   5423                _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5424                                          SESTO_DEV_AN, 0, 0));
   5425     }
   5426     
   5427     /* HCD_LINK_REG_WR */
   5428     READ_SESTO_AN_REG(pa, RX_ANA_REGS_ANARXCONTROL3_ADR,
   5429                         an_rx_ctrl3.data);
   5430     an_rx_ctrl3.fields.use_kr4_block_lock_sm = 0;
   5431     an_rx_ctrl3.fields.use_kr4_pmd_lock_sm = 1;
   5432     WRITE_SESTO_AN_REG(pa, RX_ANA_REGS_ANARXCONTROL3_ADR,
   5433                         an_rx_ctrl3.data);
   5434 
   5435 ERR:
   5436     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   5437     return rv;
   5438 }
   5439 
   5440 int _sesto_autoneg_ability_set(const phymod_phy_access_t* phy, sesto_an_ability_t *an_ability)
   5441 {
   5442     phymod_phy_inf_config_t config;
   5443     uint16_t ip = 0, data = 0;
   5444     uint16_t lane_mask = 0;
   5445     uint16_t intf_side = 0;
   5446     int rv = PHYMOD_E_NONE;
   5447     const phymod_access_t *pa = &phy->access;
   5448     IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_TYPE_T adv1;
   5449     IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_TYPE_T adv2;
   5450     IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_TYPE_T adv3;
   5451     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T an_mst_sel;
   5452     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   5453  
   5454     PHYMOD_MEMSET(&adv1, 0, sizeof(IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_TYPE_T));
   5455     PHYMOD_MEMSET(&adv2, 0, sizeof(IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_TYPE_T));
   5456     PHYMOD_MEMSET(&adv3, 0, sizeof(IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_TYPE_T));
   5457     PHYMOD_MEMSET(&an_mst_sel, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T));
   5458 
   5459     SESTO_GET_INTF_SIDE(phy, intf_side);
   5460     if (intf_side == SESTO_IF_SYS) {
   5461         /* AN can performed only on line side */
   5462         return PHYMOD_E_PARAM;
   5463     }
   5464 
   5465     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   5466     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   5467     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   5468     aux_mode = config.device_aux_modes; 
   5469 
   5470     SESTO_IF_ERR_RETURN(_sesto_phy_interface_config_get(phy, 0, &config));
   5471     
   5472     if ((config.data_rate == SESTO_SPD_10G || config.data_rate == SESTO_SPD_20G ||
   5473          config.data_rate == SESTO_SPD_11G || config.data_rate == SESTO_SPD_21G) ||
   5474         ((config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) && aux_mode->gearbox_100g_inverse_mode)) {
   5475         goto ERR;
   5476     }
   5477     SESTO_GET_IP(phy, config, ip);
   5478     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5479     /* SES_GEN_CNTRLS_MICRO_SYNC_4_ADR: 0-7 bits are used as scratch register to configure the master lane */
   5480     if (!aux_mode->pass_thru && config.data_rate != SESTO_SPD_100G) {
   5481         /* 40G Mux Mode*/
   5482         if (lane_mask & 0xF) {
   5483             SESTO_IF_ERR_RETURN(_sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5484                                          SESTO_DEV_AN, 0, 0));
   5485             if (an_ability->an_master_lane < 4) {
   5486                 READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5487                 an_mst_sel.data &= 0xFFF0;
   5488                 an_mst_sel.data |= an_ability->an_master_lane;
   5489                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5490             } else {
   5491                 PHYMOD_DEBUG_ERROR(("Invalid AN Master lane config, should be between 0 to 3\n"));
   5492             }
   5493         } else {
   5494             SESTO_IF_ERR_RETURN(
   5495                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5496                                          SESTO_DEV_AN, 0, 1));
   5497             if (an_ability->an_master_lane < 4) {
   5498                 READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5499                 an_mst_sel.data &= 0xFF0F;
   5500                 an_mst_sel.data |= (an_ability->an_master_lane << 4);
   5501                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5502             } else {
   5503                 PHYMOD_DEBUG_ERROR(("Invalid AN Master lane config, should be between 0 to 3\n"));
   5504             }
   5505         }
   5506     } else {
   5507         if ((aux_mode->BCM84793_capablity) || (config.data_rate == SESTO_SPD_100G)) {
   5508             if (an_ability->an_master_lane < 4) {
   5509             READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5510                 an_mst_sel.data &= 0xFF00;
   5511             an_mst_sel.data |= an_ability->an_master_lane;
   5512             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5513         } else {
   5514                 PHYMOD_DEBUG_ERROR(("Invalid AN Master lane config, should be between 0 to 3 depends on mode configuration\n"));
   5515         }
   5516         } else if ((an_ability->an_master_lane < 2) ||
   5517             (((an_ability->an_master_lane & 0xF) >= 4) && ((an_ability->an_master_lane & 0xF) <= 5))) {
   5518             READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5519             an_mst_sel.data &= 0xFF00;
   5520             an_mst_sel.data |= an_ability->an_master_lane;
   5521             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5522         } else {
   5523             PHYMOD_DEBUG_ERROR(("Invalid AN Master lane config, should be between 0-1 or 4-5 depends on mode configuration\n"));
   5524         }
   5525 
   5526 
   5527         if (((an_ability->an_master_lane & 0xF) >= 4) && ((an_ability->an_master_lane & 0xF) <= 5)) {
   5528             SESTO_IF_ERR_RETURN(
   5529                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5530                                          SESTO_DEV_AN, 0, 1));
   5531         } else {
   5532             SESTO_IF_ERR_RETURN(
   5533                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5534                                          SESTO_DEV_AN, 0, 0));
   5535         }
   5536     }
   5537 
   5538     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_ADR,
   5539                         adv3.data);
   5540     adv3.fields.fec_requested = an_ability->cl73_adv.an_fec; 
   5541     WRITE_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_ADR,
   5542                         adv3.data);
   5543 
   5544     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_ADR,
   5545                         adv2.data);
   5546     adv2.fields.techability = an_ability->cl73_adv.an_base_speed;
   5547     WRITE_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_ADR,
   5548                         adv2.data);
   5549 
   5550     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_ADR,
   5551                         adv1.data);
   5552     adv1.fields.pause = an_ability->cl73_adv.an_pause;
   5553     WRITE_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_ADR,
   5554                          adv1.data);
   5555 
   5556     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   5557     SESTO_IF_ERR_RETURN(_sesto_config_hcd_link_sts (pa, config, ip));
   5558 
   5559     /* AN without TX training set GPREG11[11] to 1 */
   5560     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, data);
   5561     an_ability->cl73_adv.an_cl72 ? (data &= (~(0x1 << 11))) : (data |= (0x1 << 11));
   5562     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, data);
   5563 
   5564 ERR:
   5565     PHYMOD_FREE(config.device_aux_modes);
   5566 
   5567     return rv;
   5568 }
   5569 
   5570 int _sesto_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
   5571 {
   5572     phymod_phy_inf_config_t config;
   5573     uint16_t ip = 0;
   5574     uint16_t lane_mask = 0;
   5575     uint16_t retry_cnt = 0;
   5576     uint16_t intf_side = 0, data1;
   5577     int rv = PHYMOD_E_NONE;
   5578     SES_GEN_CNTRLS_GPREG11_TYPE_T gpreg11;
   5579     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T an_mst_sel;
   5580     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   5581     const phymod_access_t *pa = &phy->access;
   5582 
   5583     SESTO_GET_INTF_SIDE(phy, intf_side);
   5584     if (intf_side == SESTO_IF_SYS) {
   5585         /* AN can performed only on line side */
   5586         return PHYMOD_E_PARAM;
   5587     }
   5588 
   5589     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   5590     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   5591     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   5592 
   5593     SESTO_IF_ERR_RETURN(_sesto_phy_interface_config_get(phy, 0, &config));
   5594     aux_mode = config.device_aux_modes;
   5595 
   5596     if ((config.data_rate == SESTO_SPD_10G || config.data_rate == SESTO_SPD_20G ||
   5597          config.data_rate == SESTO_SPD_11G || config.data_rate == SESTO_SPD_21G) ||
   5598         ((config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) && aux_mode->gearbox_100g_inverse_mode)) {
   5599         if (an->enable) {
   5600             PHYMOD_DEBUG_ERROR(("Invalid config for CL73, AN does not support for 10G/11G, 20G/21G and 100G Inverse mode\n"));
   5601         }
   5602         goto ERR;
   5603     }
   5604 
   5605     SESTO_GET_IP(phy, config, ip);
   5606     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s lanemask:0x%x\n", __func__,
   5607              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", lane_mask));
   5608 
   5609     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   5610     do {
   5611         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data1);
   5612         /* ATE_GUIDELINES : Sleep 10ms*/
   5613         retry_cnt--;
   5614     } while ((data1 != 0) && (retry_cnt));
   5615 
   5616     if (retry_cnt == 0) {
   5617         PHYMOD_DEBUG_VERBOSE(("WARN:: FW Enable not cleared\n"));
   5618         goto ERR;
   5619     }
   5620 
   5621     /* Setting the master lane by reading static config at scratch register and enable AN*/
   5622     if (an->an_mode == phymod_AN_MODE_CL73) {
   5623         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   5624         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5625 
   5626         if (an->enable) {
   5627             READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG10_ADR, data1);
   5628             data1 &= (~(0x7 << 8)); /* PMD Lock check delay through GPREG10[11:8], default value is '0' of 100ms */
   5629             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG10_ADR, data1);
   5630         }
   5631 
   5632         if (!aux_mode->pass_thru && config.data_rate != SESTO_SPD_100G) {
   5633             /* 40G Mux Mode*/
   5634             if (lane_mask & 0xF) {
   5635                 /* Master lane config and AN Enable */
   5636                 if ((an_mst_sel.data & 0xF) <= 3) {
   5637                     SESTO_CHIP_FIELD_WRITE(pa, DP_MER_AN_LANE_SELECT, mer_an_lane_sel0to3, (an_mst_sel.data & 0xF));
   5638                 } else {
   5639                     PHYMOD_DEBUG_ERROR(("Invalid AN master lane, should be b/w 0 to 3\n"));
   5640                 }
   5641                 if (an->enable) {
   5642                     gpreg11.fields.an_enable |= 0x1;
   5643                 } else {
   5644                     gpreg11.fields.an_enable &= ~(0x1);
   5645                 }
   5646             } else {
   5647                 /* Master lane config and AN Enable */
   5648                 if (((an_mst_sel.data >> 4) & 0xF) <= 3) {
   5649                     SESTO_CHIP_FIELD_WRITE(pa, DP_MER_AN_LANE_SELECT,
   5650                                            mer_an_lane_sel4to7, ((an_mst_sel.data >> 4) & 0xF));
   5651                 } else {
   5652                     PHYMOD_DEBUG_ERROR(("Invalid AN master lane, should be b/w 0 to 3\n"));
   5653                 }
   5654                 if (an->enable) {
   5655                     gpreg11.fields.an_enable |= 0x2;
   5656                 } else {
   5657                     gpreg11.fields.an_enable &= ~(0x2);
   5658                 }
   5659             }
   5660         } else {
   5661             /* 40G PT and 100G GBOX */
   5662             if (ip == SESTO_FALCON_CORE) {
   5663                 /* Master lane config  and AN Enable */
   5664                 if ((an_mst_sel.data & 0xF) <= 3) {
   5665                     SESTO_CHIP_FIELD_WRITE(pa, DP_FAL_AN_LANE_SELECT, fal_an_lane_sel0to3, (an_mst_sel.data & 0xF));
   5666                 } else {
   5667                     PHYMOD_DEBUG_ERROR(("Invalid AN master lane, should be b/w 0 to 3\n"));
   5668                 }
   5669                 if (an->enable) {
   5670                     gpreg11.fields.an_enable |= 0x1;
   5671                 } else {
   5672                     gpreg11.fields.an_enable &= ~(0x1);
   5673                 }
   5674             } else {
   5675                 if (((an_mst_sel.data & 0xF) <= 1) || (aux_mode->BCM84793_capablity & ((an_mst_sel.data & 0xF) <= 3))) {
   5676                     /* Master lane config  and AN Enable */
   5677                     SESTO_CHIP_FIELD_WRITE(pa, DP_MER_AN_LANE_SELECT, mer_an_lane_sel0to3, (an_mst_sel.data & 0xF));
   5678                     if (an->enable) {
   5679                         gpreg11.fields.an_enable |= 0x1;
   5680                     } else {
   5681                         gpreg11.fields.an_enable &= ~(0x1);
   5682                     }
   5683                 } else if (((an_mst_sel.data & 0xF) >= 4) && ((an_mst_sel.data & 0xF) <= 5)) {
   5684                     /* Master lane config  and AN Enable */
   5685                     SESTO_CHIP_FIELD_WRITE(pa, DP_MER_AN_LANE_SELECT, mer_an_lane_sel4to7, ((an_mst_sel.data & 0xF) - 4));
   5686                     if (an->enable) {
   5687                         gpreg11.fields.an_enable |= 0x2;
   5688                     } else {
   5689                         gpreg11.fields.an_enable &= ~(0x2);
   5690                     }
   5691                 } else {
   5692                     /* AN Enable */
   5693                     PHYMOD_DEBUG_ERROR(("Invalid AN master lane, should be b/w 0-1 or 4-5 depends on mode configuration\n"));
   5694                     if (an->enable) {
   5695                         gpreg11.fields.an_enable |= 0x1;
   5696                     } else {
   5697                         gpreg11.fields.an_enable &= ~(0x1);
   5698                     }
   5699                 }
   5700             }
   5701         }
   5702         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   5703     } else {
   5704         goto ERR;
   5705     }
   5706 
   5707     /*Setting the FW Enable to 1*/
   5708     SESTO_IF_ERR_RETURN( _sesto_fw_enable(pa, 1));
   5709 
   5710     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   5711     do {
   5712         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data1);
   5713         /* ATE_GUIDELINES : Sleep 10ms*/
   5714         retry_cnt--;
   5715     } while ((data1 != 0) && (retry_cnt));
   5716 
   5717     if (retry_cnt == 0) {
   5718         PHYMOD_DEBUG_VERBOSE(("WARN:: FW Enable not cleared\n"));
   5719         goto ERR;
   5720     }
   5721 
   5722 ERR:
   5723     PHYMOD_FREE(config.device_aux_modes);
   5724 
   5725     return rv;
   5726 }
   5727 
   5728 int _sesto_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t *an_done)
   5729 {
   5730     phymod_phy_inf_config_t config;
   5731     uint16_t ip = 0;
   5732     uint16_t lane_mask = 0;
   5733     uint16_t intf_side = 0;
   5734     int rv = PHYMOD_E_NONE;
   5735     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   5736     IEEE_AN_BLK0_AN_STATUS_REGISTER_TYPE_T an_status;
   5737     IEEE_AN_BLK0_AN_CONTROL_REGISTER_TYPE_T an_ctrl;
   5738     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T an_mst_sel;
   5739     const phymod_access_t *pa = &phy->access;
   5740 
   5741     SESTO_GET_INTF_SIDE(phy, intf_side);
   5742     if (intf_side == SESTO_IF_SYS) {
   5743         /* AN can performed only on line side */
   5744         return PHYMOD_E_PARAM;
   5745     }
   5746     PHYMOD_MEMSET(&an_mst_sel, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T));
   5747     PHYMOD_MEMSET(&an_status, 0, sizeof(IEEE_AN_BLK0_AN_STATUS_REGISTER_TYPE_T));
   5748     PHYMOD_MEMSET(&an_ctrl, 0, sizeof(IEEE_AN_BLK0_AN_CONTROL_REGISTER_TYPE_T));
   5749 
   5750     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   5751     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   5752     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   5753     aux_mode = config.device_aux_modes;
   5754 
   5755     SESTO_IF_ERR_RETURN(
   5756        _sesto_phy_interface_config_get(phy, 0, &config));
   5757     aux_mode = config.device_aux_modes;
   5758 
   5759     /* AN does not support 10G, 20G and 100G Inverse mode */
   5760     if ((config.data_rate == SESTO_SPD_10G || config.data_rate == SESTO_SPD_20G ||
   5761          config.data_rate == SESTO_SPD_11G || config.data_rate == SESTO_SPD_21G) ||
   5762         ((config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) && aux_mode->gearbox_100g_inverse_mode)) {
   5763         goto ERR;
   5764     }
   5765 
   5766     SESTO_GET_IP(phy, config, ip);
   5767     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s lanemask:0x%x\n", __func__,
   5768              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", lane_mask));
   5769 
   5770     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5771     if (!aux_mode->pass_thru && config.data_rate != SESTO_SPD_100G) {
   5772         /* 40G Mux Mode*/
   5773         if (lane_mask & 0xF) {
   5774             SESTO_IF_ERR_RETURN(
   5775                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5776                                          SESTO_DEV_AN, 0, 0));
   5777         } else {
   5778             SESTO_IF_ERR_RETURN(
   5779                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5780                                          SESTO_DEV_AN, 0, 1));
   5781         }
   5782     } else {
   5783         if (((an_mst_sel.data & 0xF) >= 4) && ((an_mst_sel.data & 0xF) <= 5)) {
   5784             SESTO_IF_ERR_RETURN(
   5785                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5786                                          SESTO_DEV_AN, 0, 1));
   5787         } else {
   5788             SESTO_IF_ERR_RETURN(
   5789                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5790                                          SESTO_DEV_AN, 0, 0));
   5791         }
   5792     }
   5793 
   5794     /* AN enable status */
   5795     READ_SESTO_AN_REG(pa, IEEE_AN_BLK0_AN_CONTROL_REGISTER_ADR, an_ctrl.data);
   5796     an->enable = an_ctrl.fields.auto_negotiationenable;
   5797 
   5798     /* AN Mode */
   5799     an->an_mode = phymod_AN_MODE_CL73;
   5800 
   5801     /* AN complete status read AN_DONE */
   5802     READ_SESTO_AN_REG(pa, IEEE_AN_BLK0_AN_STATUS_REGISTER_ADR, an_status.data);
   5803     *an_done = an_status.fields.auto_negotiationcomplete;
   5804 
   5805 ERR:
   5806     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   5807     PHYMOD_FREE(config.device_aux_modes);
   5808 
   5809     return rv;
   5810 }
   5811 
   5812 int _sesto_autoneg_ability_get(const phymod_phy_access_t* phy, sesto_an_ability_t *an_ability)
   5813 {
   5814     phymod_phy_inf_config_t config;
   5815     uint16_t ip = 0;
   5816     uint16_t lane_mask = 0;
   5817     uint16_t intf_side = 0;
   5818     int rv = PHYMOD_E_NONE;
   5819     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   5820     IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_TYPE_T adv1;
   5821     IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_TYPE_T adv2;
   5822     IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_TYPE_T adv3;
   5823     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T an_mst_sel;
   5824     const phymod_access_t *pa = &phy->access;
   5825 
   5826 
   5827     SESTO_GET_INTF_SIDE(phy, intf_side);
   5828     if (intf_side == SESTO_IF_SYS) {
   5829         /* AN can performed only on line side */
   5830         return PHYMOD_E_PARAM;
   5831     }
   5832 
   5833     PHYMOD_MEMSET(&adv1, 0, sizeof(IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_TYPE_T));
   5834     PHYMOD_MEMSET(&adv2, 0, sizeof(IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_TYPE_T));
   5835     PHYMOD_MEMSET(&adv3, 0, sizeof(IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_TYPE_T));
   5836     PHYMOD_MEMSET(&an_mst_sel, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T));
   5837 
   5838     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   5839     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   5840     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   5841     aux_mode = config.device_aux_modes;
   5842 
   5843     SESTO_IF_ERR_RETURN(
   5844        _sesto_phy_interface_config_get(phy, 0, &config));
   5845 
   5846     /* AN does not support 10G, 20G and 100G Inverse mode */
   5847     if ((config.data_rate == SESTO_SPD_10G || config.data_rate == SESTO_SPD_20G ||
   5848          config.data_rate == SESTO_SPD_11G || config.data_rate == SESTO_SPD_21G) ||
   5849         ((config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) && aux_mode->gearbox_100g_inverse_mode)) {
   5850         goto ERR;
   5851     }
   5852 
   5853     SESTO_GET_IP(phy, config, ip);
   5854     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s lanemask:0x%x\n", __func__,
   5855              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", lane_mask));
   5856 
   5857     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5858     if (!aux_mode->pass_thru && config.data_rate != SESTO_SPD_100G) {
   5859         /* 40G Mux Mode*/
   5860         if (lane_mask & 0xF) {
   5861             SESTO_IF_ERR_RETURN(
   5862                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5863                                          SESTO_DEV_AN, 0, 0));
   5864         } else {
   5865             SESTO_IF_ERR_RETURN(
   5866                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5867                                          SESTO_DEV_AN, 0, 1));
   5868         }
   5869     } else {
   5870         if (((an_mst_sel.data & 0xF) >= 4) && ((an_mst_sel.data & 0xF) <= 5)) {
   5871             SESTO_IF_ERR_RETURN(
   5872                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5873                                          SESTO_DEV_AN, 0, 1));
   5874         } else {
   5875             SESTO_IF_ERR_RETURN(
   5876                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5877                                          SESTO_DEV_AN, 0, 0));
   5878         }
   5879     }
   5880 
   5881     /* Fec ability */
   5882     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_3_REGISTER_ADR,
   5883                         adv3.data);
   5884     an_ability->cl73_adv.an_fec = adv3.fields.fec_requested;
   5885 
   5886     /* Techability */
   5887     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_2_REGISTER_ADR,
   5888                         adv2.data);
   5889     an_ability->cl73_adv.an_base_speed = adv2.fields.techability;
   5890 
   5891     /* AN ability */
   5892     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_ADVERTISEMENT_1_REGISTER_ADR,
   5893                         adv1.data);
   5894     an_ability->cl73_adv.an_pause = adv1.fields.pause;
   5895 
   5896 ERR:
   5897     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   5898     PHYMOD_FREE(config.device_aux_modes);
   5899 
   5900     return rv;
   5901 }
   5902 
   5903 int _sesto_autoneg_remote_ability_get(const phymod_phy_access_t *phy, phymod_autoneg_ability_t* an_ability_get)
   5904 {
   5905     phymod_phy_inf_config_t config;
   5906     uint16_t ip = 0;
   5907     uint16_t lane_mask = 0;
   5908     uint16_t intf_side = 0;
   5909     int rv = PHYMOD_E_NONE;
   5910     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   5911     IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_1_REG_TYPE_T adv1;
   5912     IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_2_REG_TYPE_T adv2;
   5913     IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_3_REG_TYPE_T adv3;
   5914     SES_GEN_CNTRLS_MICRO_SYNC_4_TYPE_T an_mst_sel;
   5915     const phymod_access_t *pa = &phy->access;
   5916 
   5917     SESTO_GET_INTF_SIDE(phy, intf_side);
   5918     if (intf_side == SESTO_IF_SYS) {
   5919         /* AN can performed only on line side */
   5920         return PHYMOD_E_PARAM;
   5921     }
   5922 
   5923     PHYMOD_MEMSET(&adv1, 0, sizeof(IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_1_REG_TYPE_T));
   5924     PHYMOD_MEMSET(&adv2, 0, sizeof(IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_2_REG_TYPE_T));
   5925     PHYMOD_MEMSET(&adv3, 0, sizeof(IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_3_REG_TYPE_T));
   5926     PHYMOD_MEMSET(&an_mst_sel, 0, sizeof(SES_GEN_CNTRLS_MICRO_SYNC_0_TYPE_T));
   5927 
   5928     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   5929     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   5930     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   5931     aux_mode = config.device_aux_modes;
   5932 
   5933     SESTO_IF_ERR_RETURN(
   5934        _sesto_phy_interface_config_get(phy, 0, &config));
   5935 
   5936     /* AN does not support 10G, 20G and 100G Inverse mode */
   5937     if ((config.data_rate == SESTO_SPD_10G || config.data_rate == SESTO_SPD_20G ||
   5938          config.data_rate == SESTO_SPD_11G || config.data_rate == SESTO_SPD_21G) ||
   5939         ((config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) && aux_mode->gearbox_100g_inverse_mode)) {
   5940         goto ERR;
   5941     }
   5942 
   5943     SESTO_GET_IP(phy, config, ip);
   5944     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s lanemask:0x%x\n", __func__,
   5945              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", lane_mask));
   5946 
   5947     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_4_ADR, an_mst_sel.data);
   5948     if (!aux_mode->pass_thru && config.data_rate != SESTO_SPD_100G) {
   5949         /* 40G Mux Mode*/
   5950         if (lane_mask & 0xF) {
   5951             SESTO_IF_ERR_RETURN(
   5952                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5953                                          SESTO_DEV_AN, 0, 0));
   5954         } else {
   5955             SESTO_IF_ERR_RETURN(
   5956                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5957                                          SESTO_DEV_AN, 0, 1));
   5958         }
   5959     } else {
   5960         if (((an_mst_sel.data & 0xF) >= 4) && ((an_mst_sel.data & 0xF) <= 5)) {
   5961             SESTO_IF_ERR_RETURN(
   5962                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5963                                          SESTO_DEV_AN, 0, 1));
   5964         } else {
   5965             SESTO_IF_ERR_RETURN(
   5966                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   5967                                          SESTO_DEV_AN, 0, 0));
   5968         }
   5969     }
   5970 
   5971     /* Fec ability */
   5972     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_3_REG_ADR,
   5973                         adv3.data);
   5974     an_ability_get->an_fec = (adv3.data & 0xC000) >> 15;
   5975 
   5976     /* Techability */
   5977     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_2_REG_ADR,
   5978                         adv2.data);
   5979     an_ability_get->an_cap = (adv2.data & 0xFFE0) >> 5;
   5980 
   5981     /* AN ability */
   5982     READ_SESTO_AN_REG(pa, IEEE_AN_BLK1_AN_LP_BASE_PAGE_ABILITY_1_REG_ADR,
   5983                         adv1.data);
   5984     if (adv1.data & 0x400) {
   5985         PHYMOD_AN_CAP_ASYM_PAUSE_SET(an_ability_get);
   5986     } else if (adv1.data & 0x800) {
   5987         PHYMOD_AN_CAP_SYMM_PAUSE_SET(an_ability_get);
   5988     }
   5989 
   5990 ERR:
   5991     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   5992     PHYMOD_FREE(config.device_aux_modes);
   5993 
   5994     return rv;
   5995 }
   5996 
   5997 
   5998 int _sesto_port_from_lane_map_get(const phymod_phy_access_t *phy, const phymod_phy_inf_config_t* cfg, uint16_t *port)
   5999 {
   6000     phymod_phy_inf_config_t config;
   6001     uint16_t ip = 0;
   6002     uint16_t lane_mask = 0;
   6003     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   6004     DP_SESTO_MODE_CTRL0_TYPE_T ctrl0;
   6005     int rv = PHYMOD_E_NONE;
   6006     const phymod_access_t *pa = &phy->access;
   6007 
   6008     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   6009     PHYMOD_MEMCPY(&config, cfg, sizeof(phymod_phy_inf_config_t));
   6010     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)cfg->device_aux_modes;
   6011     SESTO_GET_IP(phy, config, ip);
   6012 
   6013     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   6014                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   6015 
   6016     PHYMOD_MEMSET(&ctrl0, 0, sizeof(DP_SESTO_MODE_CTRL0_TYPE_T));
   6017     READ_SESTO_PMA_PMD_REG(pa, DP_SESTO_MODE_CTRL0_ADR,ctrl0.data);
   6018     if (config.data_rate == SESTO_SPD_100G || config.data_rate == SESTO_SPD_106G) {
   6019         *port = 0;
   6020     } else if (config.data_rate == SESTO_SPD_40G || config.data_rate == SESTO_SPD_42G) {
   6021         if (ip == SESTO_FALCON_CORE) {
   6022             if (aux_mode->pass_thru || aux_mode->BCM84793_capablity) {
   6023                 if (lane_mask == 0xF) {        /*port 0 */
   6024                     *port = 0;
   6025                 }
   6026             } else {   /* 40G MUX */
   6027                 if (lane_mask == 0x3) {        /* port 0 */
   6028                     *port = 0;
   6029                 } else if (lane_mask == 0xC) { /* port 1 */
   6030                     *port = 1;
   6031                 }
   6032             }
   6033         } else {
   6034             if (aux_mode->pass_thru || aux_mode->BCM84793_capablity) {
   6035                 if (lane_mask == 0x33) {       /* port 0 */
   6036                     *port = 0;
   6037                 }
   6038                 else if (lane_mask == 0xF) {   /* port 0 */
   6039                     *port = 0;
   6040                 }
   6041             } else {   /* 40G MUX */
   6042                 if (lane_mask == 0xF) {        /* port 0 */
   6043                     *port = 0;
   6044                 } else if (lane_mask == 0xF0) { /* port 1 */
   6045                     *port = 1;
   6046                 }
   6047             }
   6048         }
   6049         if (ctrl0.fields.mode_multiport2_40g_mux && ctrl0.fields.mode_multiport1_10g1 &&
   6050             ctrl0.fields.mode_multiport1_10g2) {
   6051             *port += 1;
   6052         }
   6053     } else if (config.data_rate == SESTO_SPD_20G || config.data_rate == SESTO_SPD_21G) {
   6054         if (ip == SESTO_FALCON_CORE) {
   6055             if (aux_mode->pass_thru) {
   6056                 if (lane_mask == 0x3) {        /* port 0 */
   6057                     *port = 0;
   6058                 } else if (lane_mask == 0xC) { /* port 1 */
   6059                     *port = 1;
   6060                 }
   6061             } else {   /* 20G MUX */
   6062                 if (lane_mask == 0x1) {        /* port 0 */
   6063                     *port = 0;
   6064                 } else if (lane_mask == 0x4) { /* port 1 */
   6065                     *port = 1;
   6066                 }
   6067             }
   6068         } else  { /* 20G PT & MUX */
   6069             if (lane_mask == 0x3) {          /* port 0 */
   6070                 *port = 0;
   6071             } else if (lane_mask == 0x30) {  /* port 1 */
   6072                 *port = 1;
   6073             }
   6074         }
   6075         if ((ctrl0.fields.mode_multiport2_20g_mux || ctrl0.fields.mode_multiport2_20g_passthru) &&
   6076             (ctrl0.fields.mode_multiport1_10g1 && ctrl0.fields.mode_multiport1_10g2)) {
   6077             *port += 1;
   6078         }
   6079     } else if (config.data_rate == SESTO_SPD_1G || config.data_rate == SESTO_SPD_10G || config.data_rate == SESTO_SPD_11G) {
   6080         if (ip == SESTO_FALCON_CORE) {
   6081             if (lane_mask == 0x1) {          /* port 0 */
   6082                 *port = 0;
   6083             } else if (lane_mask == 0x2) {   /* port 1 */
   6084                 *port = 1;
   6085             } else if (lane_mask == 0x4) {   /* port 2 */
   6086                 *port = 2;
   6087             } else if (lane_mask == 0x8) {   /* port 3 */
   6088                 *port = 3;
   6089             }
   6090         } else {
   6091             if (lane_mask == 0x1) {          /* port 0 */
   6092                 *port = 0;
   6093             } else if (lane_mask == 0x2) {   /* port 1 */
   6094                 *port = 1;
   6095             } else if (lane_mask == 0x10) {  /* port 2 */
   6096                 *port = 2;
   6097             } else if (lane_mask == 0x20) {  /* port 3 */
   6098                 *port = 3;
   6099             } else if ((lane_mask == 0x4) && (aux_mode->BCM84793_capablity)){
   6100                 *port = 2;
   6101             } else if ((lane_mask == 0x8) && (aux_mode->BCM84793_capablity)){
   6102                 *port = 3;
   6103             }
   6104         }
   6105     }
   6106 
   6107 ERR:
   6108     return rv;
   6109 }
   6110 int _sesto_module_write(const phymod_access_t *pa, uint32_t slv_dev_addr, uint32_t start_addr,
   6111                             uint32_t no_of_bytes, const uint8_t *write_data)
   6112 {
   6113     uint16_t lane_mask = 0;
   6114     uint32_t index = 0;
   6115     uint32_t lower_page_bytes = 0;
   6116     uint32_t upper_page_bytes = 0;
   6117     uint32_t upper_page_flag = 0;
   6118     uint32_t lower_page_flag = 0;
   6119     uint32_t lower_page_start_addr = 0;
   6120     uint32_t upper_page_start_addr = 0;
   6121     SES_GEN_CNTRLS_GEN_CONTROL3_TYPE_T gen_ctrl;
   6122     uint16_t START_OF_NVRAM = 0x0;
   6123     int rv = PHYMOD_E_NONE;
   6124 
   6125     if(start_addr > 255) {
   6126         return PHYMOD_E_PARAM;
   6127     }
   6128     /* qsfp mode or legacy mode */
   6129     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6130     gen_ctrl.fields.qsfp_mode = 1;
   6131     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6132 
   6133     /* qsfp mode reset at begining */
   6134     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GEN_CONTROL1, modctrl_rstb, 0);
   6135     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GEN_CONTROL1, modctrl_rstb, 1);
   6136 
   6137     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   6138     if (lane_mask <= 0xF) { /* QSFP module 0 */
   6139         /* Active Low Select to read NVRAM for QSFP module 0 */
   6140         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6141         gen_ctrl.fields.qsfp_sel0b = 0;
   6142         gen_ctrl.fields.qsfp_sel1b = 1;
   6143         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6144         /* Module 0 NVRAM ADDR is SES_MODULE_CNTRL_RAM_NVR0_ADR */
   6145         START_OF_NVRAM = 0x0;
   6146     } else if (lane_mask <= 0xF0) {  /* QSFP module 1 */
   6147         /* Active Low Select to read NVRAM for QSFP module 1 */
   6148         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6149         gen_ctrl.fields.qsfp_sel0b = 1;
   6150         gen_ctrl.fields.qsfp_sel1b = 0;
   6151         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6152         /* Module 1 NVRAM ADDR is SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM*/
   6153         START_OF_NVRAM = 0x100;
   6154     }
   6155 
   6156     /* Configure the slave device ID default is 0x50 */
   6157     SESTO_CHIP_FIELD_WRITE(pa, SES_MODULE_CNTRL_DEV_ID, sl_dev_add, slv_dev_addr);
   6158 
   6159     if(no_of_bytes == 0) {
   6160         /* Perform module controller reset and FLUSH */
   6161         SESTO_IF_ERR_RETURN(
   6162             _sesto_set_module_command(pa, 0, 0, 0, SESTO_FLUSH));
   6163         return rv;
   6164     }
   6165     /* if requested number of bytes are not within the boundary (0- 255)
   6166      * need to calculate what maximum number of bytes can be taken into
   6167      * account for reading or writing to module
   6168      */
   6169     if ((no_of_bytes + start_addr) >= 256) {
   6170         no_of_bytes = 255 - start_addr + 1;
   6171     }
   6172 
   6173     /* To determine page to be written is lower page or upper page or
   6174      * both lower and upper page
   6175      */
   6176     if ((start_addr + no_of_bytes - 1) > 127) {
   6177         /* lower page */
   6178         if (start_addr <= 127) {
   6179             lower_page_bytes = 127 - start_addr + 1;
   6180             lower_page_flag = 1;
   6181             lower_page_start_addr = start_addr;
   6182         }
   6183         /* upper page */
   6184         if ((start_addr + no_of_bytes) > 127) {
   6185             upper_page_flag = 1;
   6186             upper_page_bytes = no_of_bytes - lower_page_bytes;
   6187             if(start_addr > 128) {
   6188                 upper_page_start_addr = start_addr;
   6189             } else {
   6190                 upper_page_start_addr = 128;
   6191             }
   6192         }
   6193     } else { /* only lower page */
   6194         lower_page_bytes = no_of_bytes;
   6195         lower_page_flag = 1;
   6196         lower_page_start_addr = start_addr;
   6197     }
   6198 
   6199     /* Wtite data to NVRAM */
   6200     for (index = 0; index < no_of_bytes; index++) {
   6201         WRITE_SESTO_PMA_PMD_REG(pa,
   6202             (SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM + start_addr + index), write_data[index]);
   6203     }
   6204 
   6205     if(lower_page_flag) {
   6206         SESTO_IF_ERR_RETURN(
   6207             _sesto_set_module_command(pa, 0, 0, 0, SESTO_FLUSH));
   6208         for (index = 0; index < (lower_page_bytes / 4); index ++) {
   6209             SESTO_IF_ERR_RETURN(
   6210                 _sesto_set_module_command(pa, SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM +
   6211                     lower_page_start_addr + (4 * index), lower_page_start_addr + (4 * index), 3, SESTO_WRITE));
   6212         }
   6213         if ((lower_page_bytes % 4) > 0) {
   6214             SESTO_IF_ERR_RETURN(
   6215                 _sesto_set_module_command(pa, SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM +
   6216                     lower_page_start_addr + (4 * index), lower_page_start_addr + (4 * index),
   6217                                                        ((lower_page_bytes % 4) - 1), SESTO_WRITE));
   6218         }
   6219         lower_page_flag = 0;
   6220     }
   6221 
   6222     if(upper_page_flag) {
   6223         SESTO_IF_ERR_RETURN(
   6224             _sesto_set_module_command(pa, 0, 0, 0, SESTO_FLUSH));
   6225         for (index = 0; index < (upper_page_bytes / 4); index++) {
   6226             SESTO_IF_ERR_RETURN(
   6227                 _sesto_set_module_command(pa, (SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM +
   6228                     upper_page_start_addr + (4 * index)), upper_page_start_addr + (4 * index), 3, SESTO_WRITE));
   6229         }
   6230         if ((upper_page_bytes%4) > 0) {
   6231             SESTO_IF_ERR_RETURN(
   6232                 _sesto_set_module_command(pa, (SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM +
   6233                     upper_page_start_addr + (4 * index)), upper_page_start_addr + (4 * index),
   6234                                                         ((upper_page_bytes % 4) - 1), SESTO_WRITE));
   6235         }
   6236         upper_page_flag = 0;
   6237     }
   6238 
   6239 ERR:
   6240     return rv;
   6241 }
   6242 
   6243 int _sesto_module_read(const phymod_access_t *pa, uint32_t slv_dev_addr, uint32_t start_addr,
   6244                       uint32_t no_of_bytes, uint8_t *read_data)
   6245 {
   6246     uint32_t index = 0;
   6247     uint16_t lane_mask = 0;
   6248     uint16_t rd_data = 0;
   6249     uint32_t lower_page_bytes = 0;
   6250     uint32_t upper_page_bytes = 0;
   6251     uint32_t upper_page_flag = 0;
   6252     uint32_t lower_page_start_addr = 0;
   6253     uint32_t upper_page_start_addr = 0;
   6254     uint32_t lower_page_flag = 0;
   6255     uint16_t START_OF_NVRAM = 0x0;
   6256     int rv = PHYMOD_E_NONE;
   6257     SES_GEN_CNTRLS_GEN_CONTROL3_TYPE_T gen_ctrl;
   6258 
   6259     if(start_addr > 255) {
   6260         return PHYMOD_E_PARAM;
   6261     }
   6262     /* qsfp mode or legacy mode */
   6263     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6264     gen_ctrl.fields.qsfp_mode = 1;
   6265     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6266 
   6267     /* qsfp mode reset at begining */
   6268     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GEN_CONTROL1, modctrl_rstb, 0);
   6269     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_GEN_CONTROL1, modctrl_rstb, 1);
   6270 
   6271     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   6272     if (lane_mask <= 0xF) { /* QSFP module 0 */
   6273         /* Active Low Select to read NVRAM for QSFP module 0 */
   6274         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6275         gen_ctrl.fields.qsfp_sel0b = 0;
   6276         gen_ctrl.fields.qsfp_sel1b = 1;
   6277         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6278         /* Module 0 NVRAM ADDR is SES_MODULE_CNTRL_RAM_NVR0_ADR */
   6279         START_OF_NVRAM = 0x0;
   6280     } else if (lane_mask <= 0xF0) {  /* QSFP module 1 */
   6281         /* Active Low Select to read NVRAM for QSFP module 1 */
   6282         READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6283         gen_ctrl.fields.qsfp_sel0b = 1;
   6284         gen_ctrl.fields.qsfp_sel1b = 0;
   6285         WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GEN_CONTROL3_ADR, gen_ctrl.data);
   6286         /* Module 1 NVRAM ADDR is SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM*/
   6287         START_OF_NVRAM = 0x100;
   6288     }
   6289 
   6290     /* Configure the slave device ID default is 0x50 */
   6291     SESTO_CHIP_FIELD_WRITE(pa, SES_MODULE_CNTRL_DEV_ID, sl_dev_add, slv_dev_addr);
   6292 
   6293     if(no_of_bytes == 0) {
   6294         /* Perform module controller reset and FLUSH */
   6295         SESTO_IF_ERR_RETURN(
   6296             _sesto_set_module_command(pa, 0, 0, 0, SESTO_FLUSH));
   6297         return rv;
   6298     }
   6299     if ((no_of_bytes + start_addr) >= 256) {
   6300         no_of_bytes = 255 - start_addr + 1;
   6301     }
   6302 
   6303     /* To determine page to be written is lower page or upper page or
   6304      * both lower and upper page
   6305      */
   6306     if ((start_addr+no_of_bytes - 1) > 127) {
   6307         /* lower page */
   6308         if (start_addr <= 127) {
   6309             lower_page_bytes = 127 - start_addr + 1;
   6310             lower_page_flag = 1;
   6311             lower_page_start_addr = start_addr;
   6312         }
   6313         /* upper page */
   6314         if ((start_addr + no_of_bytes) > 127) {
   6315             upper_page_flag = 1;
   6316             upper_page_bytes = no_of_bytes - lower_page_bytes;
   6317             if(start_addr > 128) {
   6318                 upper_page_start_addr = start_addr;
   6319             } else {
   6320                 upper_page_start_addr = 128;
   6321             }
   6322         }
   6323     } else { /* only lower page */
   6324         lower_page_bytes = no_of_bytes;
   6325         lower_page_flag = 1;
   6326         lower_page_start_addr = start_addr;
   6327     }
   6328 
   6329     if (lower_page_flag) {
   6330         SESTO_IF_ERR_RETURN(
   6331             _sesto_set_module_command(pa, 0, 0, 0, SESTO_FLUSH));
   6332         SESTO_IF_ERR_RETURN(
   6333             _sesto_set_module_command(pa, SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM +
   6334                 lower_page_start_addr, lower_page_start_addr, lower_page_bytes - 1, SESTO_RANDOM_ADDRESS_READ));
   6335         lower_page_flag = 0;
   6336     }
   6337 
   6338     /* Need to check with chip team how we can read upper page */
   6339     if (upper_page_flag) {
   6340         SESTO_IF_ERR_RETURN(
   6341             _sesto_set_module_command(pa, 0, 0, 0, SESTO_FLUSH));
   6342         SESTO_IF_ERR_RETURN(
   6343             _sesto_set_module_command(pa, SES_MODULE_CNTRL_RAM_NVR0_ADR + START_OF_NVRAM +
   6344                 upper_page_start_addr, upper_page_start_addr, upper_page_bytes - 1, SESTO_RANDOM_ADDRESS_READ));
   6345         upper_page_flag = 0;
   6346     }
   6347 
   6348     /* Read data from NVRAM */
   6349     for (index = 0; index < no_of_bytes; index++) {
   6350        READ_SESTO_PMA_PMD_REG(pa, (SES_MODULE_CNTRL_RAM_NVR0_ADR + start_addr + index), rd_data);
   6351        read_data[index] = (unsigned char) (rd_data & 0xff);
   6352     }
   6353 
   6354 ERR:
   6355     return rv;
   6356 }
   6357 
   6358 int _sesto_set_module_command(const phymod_access_t *pa, uint16_t xfer_addr,
   6359                                uint32_t slv_addr, unsigned char xfer_cnt, SESTO_I2CM_CMD_E cmd)
   6360 {
   6361     SES_MODULE_CNTRL_STATUS_TYPE_T mctrl_status;
   6362     uint16_t retry_count = 500;
   6363     uint32_t wait_timeout_us = 0;
   6364     int rv = PHYMOD_E_NONE;
   6365     wait_timeout_us = ((2*(xfer_cnt+1))*100)/5;
   6366 
   6367     if (cmd == SESTO_FLUSH) {
   6368        WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_CONTROL_ADR, 0xC000);
   6369     } else {
   6370         WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_XFER_ADDRESS_ADR, xfer_addr);
   6371         WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_XFER_COUNT_ADR, xfer_cnt);
   6372 
   6373         if (cmd == SESTO_CURRENT_ADDRESS_READ) {
   6374             WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_CONTROL_ADR, 0x8001);
   6375         } else if (cmd == SESTO_RANDOM_ADDRESS_READ ) {
   6376             WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_ADDRESS_ADR, slv_addr);
   6377             WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_CONTROL_ADR, 0x8003);
   6378         } else {
   6379             WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_ADDRESS_ADR, slv_addr);
   6380             WRITE_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_CONTROL_ADR, 0x8022);
   6381         }
   6382     }
   6383 
   6384     if ((cmd == SESTO_CURRENT_ADDRESS_READ) ||
   6385         (cmd == SESTO_RANDOM_ADDRESS_READ) ||
   6386         (cmd == SESTO_WRITE)) {
   6387         do {
   6388             READ_SESTO_PMA_PMD_REG(pa, SES_MODULE_CNTRL_STATUS_ADR, mctrl_status.data);
   6389             PHYMOD_USLEEP(wait_timeout_us);
   6390         } while((mctrl_status.fields.xaction_done == 0) && --retry_count);
   6391         if(!retry_count) {
   6392             SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG, (_PHYMOD_MSG("Module controller: I2C transaction failed..")));
   6393         }
   6394     }
   6395 
   6396 ERR:
   6397     return rv;
   6398 }
   6399 
   6400 int _sesto_gpio_config_set(const phymod_access_t *pa, int pin_number, phymod_gpio_mode_t gpio_mode)
   6401 {
   6402     int rv = PHYMOD_E_NONE;
   6403     SES_PAD_CTRL_GPIO_0_CONTROL_TYPE_T pad_ctrl_gpio_ctrl;
   6404 
   6405     PHYMOD_MEMSET(&pad_ctrl_gpio_ctrl, 0 , sizeof(SES_PAD_CTRL_GPIO_0_CONTROL_TYPE_T));
   6406     if (pin_number > 3) {
   6407         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   6408             (_PHYMOD_MSG("Invalid GPIO pin selected, Valid GPIOs are (0 - 3)")));
   6409     }
   6410 
   6411     READ_SESTO_PMA_PMD_REG(pa,
   6412                           (SES_PAD_CTRL_GPIO_0_CONTROL_ADR + (pin_number * 2)),
   6413                            pad_ctrl_gpio_ctrl.data);
   6414 
   6415     switch (gpio_mode) {
   6416       case phymodGpioModeDisabled:
   6417           return rv;
   6418       case phymodGpioModeOutput:
   6419           pad_ctrl_gpio_ctrl.fields.gpio_0_oeb = 0;
   6420       break;
   6421       case phymodGpioModeInput:
   6422           pad_ctrl_gpio_ctrl.fields.gpio_0_oeb = 1;
   6423       break;
   6424       default:
   6425           return PHYMOD_E_PARAM;
   6426     }
   6427 
   6428     WRITE_SESTO_PMA_PMD_REG(pa,
   6429                           (SES_PAD_CTRL_GPIO_0_CONTROL_ADR + (pin_number * 2)),
   6430                            pad_ctrl_gpio_ctrl.data);
   6431 ERR:
   6432     return rv;
   6433 }
   6434 
   6435 int _sesto_gpio_config_get(const phymod_access_t *pa, int pin_number, phymod_gpio_mode_t* gpio_mode)
   6436 {
   6437     int rv = PHYMOD_E_NONE;
   6438     SES_PAD_CTRL_GPIO_0_CONTROL_TYPE_T pad_ctrl_gpio_ctrl;
   6439 
   6440     PHYMOD_MEMSET(&pad_ctrl_gpio_ctrl, 0 , sizeof(SES_PAD_CTRL_GPIO_0_CONTROL_TYPE_T));
   6441     if (pin_number > 3) {
   6442         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   6443             (_PHYMOD_MSG("Invalid GPIO pin selected, Valid GPIOs are (0 - 3)")));
   6444     }
   6445 
   6446     READ_SESTO_PMA_PMD_REG(pa,
   6447                           (SES_PAD_CTRL_GPIO_0_CONTROL_ADR + (pin_number * 2)),
   6448                            pad_ctrl_gpio_ctrl.data);
   6449 
   6450     switch(pad_ctrl_gpio_ctrl.fields.gpio_0_oeb) {
   6451         case 0:
   6452             *gpio_mode = phymodGpioModeOutput;
   6453         break;
   6454         case 1:
   6455             *gpio_mode = phymodGpioModeInput;
   6456         break;
   6457         default:
   6458         break;
   6459     }
   6460 
   6461 ERR:
   6462     return rv;
   6463 }
   6464 
   6465 int _sesto_gpio_pin_value_set(const phymod_access_t *pa, int pin_number, int value)
   6466 {
   6467     int rv = PHYMOD_E_NONE;
   6468     SES_PAD_CTRL_GPIO_0_CONTROL_TYPE_T pad_ctrl_gpio_ctrl;
   6469 
   6470     PHYMOD_MEMSET(&pad_ctrl_gpio_ctrl, 0 , sizeof(SES_PAD_CTRL_GPIO_0_CONTROL_TYPE_T));
   6471     if (pin_number > 3) {
   6472         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   6473             (_PHYMOD_MSG("Invalid GPIO pin selected, Valid GPIOs are (0 - 3)")));
   6474     }
   6475     READ_SESTO_PMA_PMD_REG(pa,
   6476                           (SES_PAD_CTRL_GPIO_0_CONTROL_ADR + (pin_number * 2)),
   6477                            pad_ctrl_gpio_ctrl.data);
   6478 
   6479     pad_ctrl_gpio_ctrl.fields.gpio_0_ibof = 1;
   6480     pad_ctrl_gpio_ctrl.fields.gpio_0_out_frcval = value ? 1 : 0;
   6481 
   6482     WRITE_SESTO_PMA_PMD_REG(pa,
   6483                           (SES_PAD_CTRL_GPIO_0_CONTROL_ADR + (pin_number * 2)),
   6484                            pad_ctrl_gpio_ctrl.data);
   6485 ERR:
   6486     return rv;
   6487 }
   6488 
   6489 int _sesto_gpio_pin_value_get(const phymod_access_t *pa, int pin_number, int* value)
   6490 {
   6491     int rv = PHYMOD_E_NONE;
   6492     SES_PAD_CTRL_GPIO_0_STATUS_TYPE_T pad_sts_gpio;
   6493 
   6494     PHYMOD_MEMSET(&pad_sts_gpio, 0, sizeof(SES_PAD_CTRL_GPIO_0_STATUS_TYPE_T));
   6495     if (pin_number > 3) {
   6496         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   6497             (_PHYMOD_MSG("Invalid GPIO pin selected, Valid GPIOs are (0 - 3)")));
   6498     }
   6499 
   6500     READ_SESTO_PMA_PMD_REG(pa,
   6501                           (SES_PAD_CTRL_GPIO_0_STATUS_ADR + (pin_number * 2)),
   6502                            pad_sts_gpio.data);
   6503     *value = pad_sts_gpio.fields.gpio_0_din;
   6504 
   6505 ERR:
   6506     return rv;
   6507 }
   6508 
   6509 int _sesto_phy_repeater_mode_set(const phymod_phy_access_t *phy, phymod_operation_mode_t repeater_mode)
   6510 {
   6511     phymod_phy_inf_config_t config;
   6512     uint16_t ip = 0;
   6513     uint16_t port = 0;
   6514     uint16_t data = 0, retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   6515     int rv = PHYMOD_E_NONE;
   6516     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   6517     SES_GEN_CNTRLS_GPREG11_TYPE_T gpreg11;
   6518     const phymod_access_t *pa = &phy->access;
   6519 
   6520     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   6521     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   6522     aux_mode = config.device_aux_modes;
   6523 
   6524     SESTO_IF_ERR_RETURN(
   6525        _sesto_phy_interface_config_get(phy, 0, &config));
   6526 
   6527     ip = aux_mode->passthru_sys_side_core ? SESTO_MERLIN_CORE : SESTO_FALCON_CORE;
   6528 
   6529     /* ip == SESTO_MERLIN_CORE, line sie core is SESTO_FALCON_CORE */
   6530     PHYMOD_DEBUG_VERBOSE(("%s:: IP:%s \n", __func__,
   6531                  (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON"));
   6532     PHYMOD_MEMSET(&gpreg11, 0, sizeof(SES_GEN_CNTRLS_GPREG11_TYPE_T));
   6533     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   6534 
   6535     SESTO_IF_ERR_RETURN(
   6536         _sesto_port_from_lane_map_get(phy, &config, &port));
   6537 
   6538 
   6539     if (ip == SESTO_FALCON_CORE) {
   6540         if (!repeater_mode) {
   6541             gpreg11.fields.dis_rptr_20g_to_10g |= (0x1 << port);
   6542         } else {
   6543             gpreg11.fields.dis_rptr_20g_to_10g &= ~(0x1 << port);
   6544         }
   6545     } else {
   6546         if (!repeater_mode) {
   6547             gpreg11.fields.dis_rptr_10g_to_20g |= (0x1 << port);
   6548         } else {
   6549             gpreg11.fields.dis_rptr_10g_to_20g &= ~(0x1 << port);
   6550         }
   6551     }
   6552     WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_GPREG11_ADR, gpreg11.data);
   6553 
   6554     /*  Set FW_ENABLE = 1 */
   6555     SESTO_CHIP_FIELD_WRITE(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, 1);
   6556     do {
   6557         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data);
   6558     } while ((data != 0) && (retry_cnt --));
   6559     if (retry_cnt == 0) {
   6560         SESTO_RETURN_WITH_ERR(PHYMOD_E_CONFIG,
   6561                (_PHYMOD_MSG("repeater_mode_set failed, micro controller is busy..")));
   6562     }
   6563 
   6564 ERR:
   6565     PHYMOD_FREE(config.device_aux_modes);
   6566 
   6567     return rv;
   6568 }
   6569 int _sesto_core_cfg_tx_set(const phymod_phy_access_t *phy,const phymod_tx_t* tx)
   6570 {
   6571     phymod_tx_t tmp_tx;
   6572     int rv = PHYMOD_E_NONE;
   6573 
   6574     PHYMOD_MEMSET(&tmp_tx,0x0,sizeof(phymod_tx_t));
   6575     SESTO_IF_ERR_RETURN(
   6576             _sesto_tx_get(phy,&tmp_tx));
   6577     if (!(((tx->main & 0x7F) == 0x7F) && ((tx->pre & 0x7F) == 0x7F) && ((tx->post & 0x7F) == 0x7F))) {
   6578         tmp_tx.pre = tx->pre;
   6579         tmp_tx.main = tx->main;
   6580         tmp_tx.post = tx->post;
   6581 
   6582     }
   6583     tmp_tx.amp = tx->amp;
   6584     SESTO_IF_ERR_RETURN(
   6585             _sesto_tx_set(phy,&tmp_tx));
   6586 
   6587 ERR:
   6588     return rv;
   6589 }
   6590 
   6591 int _sesto_core_cfg_polarity_set(const phymod_phy_access_t *phy, uint32_t tx_polarity, uint32_t rx_polarity)
   6592 {
   6593     phymod_phy_inf_config_t config;
   6594     uint16_t ip = 0;
   6595     uint16_t lane = 0;
   6596     uint16_t lane_mask = 0, max_lane = 0;
   6597     uint32_t rx_lane_polarity = 0;
   6598     uint32_t tx_lane_polarity = 0;
   6599     int rv = PHYMOD_E_NONE;
   6600     const phymod_access_t *pa = &phy->access;
   6601 
   6602     if (rx_polarity == 0 && tx_polarity == 0) {
   6603         return rv;
   6604     }
   6605 
   6606     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   6607     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   6608     SESTO_IF_ERR_RETURN(
   6609        _sesto_phy_interface_config_get(phy, 0, &config));
   6610     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   6611     SESTO_GET_IP(phy, config, ip);
   6612 
   6613     max_lane = (ip == SESTO_FALCON_CORE) ?
   6614                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   6615 
   6616     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   6617              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   6618 
   6619     for (lane = 0; lane < max_lane; lane ++) {
   6620         if (lane_mask & (1 << lane)) {
   6621             SESTO_IF_ERR_RETURN(
   6622               _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST,
   6623                         ip, SESTO_DEV_PMA_PMD, 0, lane));
   6624             if (rx_polarity != 0) {
   6625                 rx_lane_polarity = (rx_polarity >> lane) & 0x1;
   6626             }
   6627             if (tx_polarity != 0) {
   6628                 tx_lane_polarity = (tx_polarity >> lane) & 0x1;
   6629             }
   6630             if (ip == SESTO_FALCON_CORE) {
   6631                 /* FALCON polarity inversion */
   6632                 PHYMOD_DEBUG_VERBOSE(("Falcon polarity inversion set\n"));
   6633                 if (tx_lane_polarity) {
   6634                     /* Write to Tx misc config register */
   6635                     SESTO_CHIP_FIELD_WRITE(pa, F25G_TLB_TX_TLB_TX_MISC_CONFIG,
   6636                                            tx_pmd_dp_invert, tx_lane_polarity);
   6637                 }
   6638                 if (rx_lane_polarity) {
   6639                     /* Write to Rx misc config register */
   6640                     SESTO_CHIP_FIELD_WRITE(pa, F25G_TLB_RX_TLB_RX_MISC_CONFIG,
   6641                                            rx_pmd_dp_invert, rx_lane_polarity);
   6642                 }
   6643             } else {
   6644                 /* MERLIN polarity inversion */
   6645                 PHYMOD_DEBUG_VERBOSE(("Merlin polarity inversion set\n"));
   6646                 if (tx_lane_polarity) {
   6647                     /* Write to Tx misc config register */
   6648                     SESTO_CHIP_FIELD_WRITE(pa, M10G_TLB_TX_TLB_TX_MISC_CONFIG,
   6649                                            tx_pmd_dp_invert, tx_lane_polarity);
   6650                 }
   6651                 if (rx_lane_polarity) {
   6652                     /* Write to Rx misc config register */
   6653                     SESTO_CHIP_FIELD_WRITE(pa, M10G_TLB_RX_TLB_RX_MISC_CONFIG,
   6654                                            rx_pmd_dp_invert, rx_lane_polarity);
   6655                 }
   6656             }
   6657         }
   6658     }
   6659 ERR:
   6660     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   6661     PHYMOD_FREE(config.device_aux_modes);
   6662 
   6663     return rv;
   6664 }
   6665 
   6666 err_code_t _sesto_merlin_read_pll_range(const phymod_access_t *pa, uint32_t *pll_range)
   6667 {
   6668   err_code_t __err;
   6669   __err=ERR_CODE_NONE;
   6670   *pll_range = rdc_pll_range();
   6671   return (ERR_CODE_NONE);
   6672 }
   6673 err_code_t _sesto_falcon_read_pll_range(const phymod_access_t *pa, uint32_t *pll_range)
   6674 {
   6675   err_code_t __err;
   6676   __err=ERR_CODE_NONE;
   6677   *pll_range = rdc_falcon_furia_sesto_ams_pll_range();
   6678   return (ERR_CODE_NONE);
   6679 }
   6680 
   6681 int _sesto_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_config)
   6682 {
   6683     uint16_t ip = 0, data = 0;
   6684     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   6685     SES_GEN_CNTRLS_MICRO_SYNC_5_TYPE_T intf_sel_p0_p1;
   6686     SES_GEN_CNTRLS_MICRO_SYNC_6_TYPE_T intf_sel_p2_p3;
   6687     phymod_phy_inf_config_t config;
   6688     const phymod_access_t *pa = &phy->access;
   6689     uint16_t retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   6690     uint16_t port = 0, no_of_ports = 0;
   6691     int rv = PHYMOD_E_NONE;
   6692 
   6693     PHYMOD_MEMSET(&intf_sel_p0_p1, 0, sizeof(intf_sel_p0_p1));
   6694     PHYMOD_MEMSET(&intf_sel_p2_p3, 0, sizeof(intf_sel_p2_p3));
   6695 
   6696     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   6697     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   6698     SESTO_IF_ERR_RETURN(
   6699        _sesto_phy_interface_config_get(phy, 0, &config));
   6700     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)config.device_aux_modes;
   6701     SESTO_GET_IP(phy, config, ip);
   6702     SESTO_GET_PORT_FROM_MODE((&config), no_of_ports, aux_mode);
   6703     SESTO_IF_ERR_RETURN(_sesto_port_from_lane_map_get(phy, &config, &port));
   6704 
   6705     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6706     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6707     if (no_of_ports == 1) { /* 100G/40GPT */
   6708         if (ip == SESTO_MERLIN_CORE) {
   6709             if (fw_config.UnreliableLos) {
   6710                 intf_sel_p0_p1.fields.p0_10g_media_type = 3;
   6711             } else {
   6712                 intf_sel_p0_p1.fields.p0_10g_media_type = fw_config.MediaType;
   6713             }
   6714             intf_sel_p0_p1.fields.p0_10g_dfe_on = fw_config.DfeOn;
   6715             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6716         } else {
   6717             if (fw_config.UnreliableLos) {
   6718                 intf_sel_p0_p1.fields.p0_20g_media_type = 3;
   6719             } else {
   6720                 intf_sel_p0_p1.fields.p0_20g_media_type = fw_config.MediaType;
   6721             }
   6722             intf_sel_p0_p1.fields.p0_20g_dfe_on = fw_config.DfeOn;
   6723             intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6724             intf_sel_p0_p1.fields.p0_scrambling_dis = fw_config.ScramblingDisable;
   6725             WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6726         }
   6727     } else if (no_of_ports == 2) { /* 40GMUX/20GMUX/20PT */
   6728         if (port == 0) {
   6729             if (ip == SESTO_MERLIN_CORE) {
   6730                 if (fw_config.UnreliableLos) {
   6731                     intf_sel_p0_p1.fields.p0_10g_media_type = 3;
   6732                 } else {
   6733                     intf_sel_p0_p1.fields.p0_10g_media_type = fw_config.MediaType;
   6734                 }
   6735                 intf_sel_p0_p1.fields.p0_10g_dfe_on = fw_config.DfeOn;
   6736                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6737             } else {
   6738                 if (fw_config.UnreliableLos) {
   6739                     intf_sel_p0_p1.fields.p0_20g_media_type = 3;
   6740                 } else {
   6741                     intf_sel_p0_p1.fields.p0_20g_media_type = fw_config.MediaType;
   6742                 }
   6743                 intf_sel_p0_p1.fields.p0_20g_dfe_on = fw_config.DfeOn;
   6744                 intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6745                 intf_sel_p0_p1.fields.p0_scrambling_dis = fw_config.ScramblingDisable;
   6746                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6747             }
   6748         } else {
   6749             if (ip == SESTO_MERLIN_CORE) {
   6750                 if (fw_config.UnreliableLos) {
   6751                     intf_sel_p2_p3.fields.p2_10g_media_type = 3;
   6752                 } else {
   6753                     intf_sel_p2_p3.fields.p2_10g_media_type = fw_config.MediaType;
   6754                 }
   6755                 intf_sel_p2_p3.fields.p2_10g_dfe_on = fw_config.DfeOn;
   6756                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6757             } else {
   6758                 if (fw_config.UnreliableLos) {
   6759                     intf_sel_p2_p3.fields.p2_20g_media_type = 3;
   6760                 } else {
   6761                     intf_sel_p2_p3.fields.p2_20g_media_type = fw_config.MediaType;
   6762                 }
   6763                 intf_sel_p2_p3.fields.p2_20g_dfe_on = fw_config.DfeOn;
   6764                 intf_sel_p2_p3.fields.p2_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6765                 intf_sel_p2_p3.fields.p2_scrambling_dis = fw_config.ScramblingDisable;
   6766                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6767             }
   6768         }
   6769     } else { /* 10G */
   6770         if (port == 0) {
   6771             if (ip == SESTO_MERLIN_CORE) {
   6772                 if (fw_config.UnreliableLos) {
   6773                     intf_sel_p0_p1.fields.p0_10g_media_type = 3;
   6774                 } else {
   6775                     intf_sel_p0_p1.fields.p0_10g_media_type = fw_config.MediaType;
   6776                 }
   6777                 intf_sel_p0_p1.fields.p0_10g_dfe_on = fw_config.DfeOn;
   6778                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6779             } else {
   6780                 if (fw_config.UnreliableLos) {
   6781                     intf_sel_p0_p1.fields.p0_20g_media_type = 3;
   6782                 } else {
   6783                     intf_sel_p0_p1.fields.p0_20g_media_type = fw_config.MediaType;
   6784                 }
   6785                 intf_sel_p0_p1.fields.p0_20g_dfe_on = fw_config.DfeOn;
   6786                 intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6787                 intf_sel_p0_p1.fields.p0_scrambling_dis = fw_config.ScramblingDisable;
   6788                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6789             }
   6790         } else if (port == 1) {
   6791             if (ip == SESTO_MERLIN_CORE) {
   6792                 if (fw_config.UnreliableLos) {
   6793                     intf_sel_p0_p1.fields.p1_10g_media_type = 3;
   6794                 } else {
   6795                     intf_sel_p0_p1.fields.p1_10g_media_type = fw_config.MediaType;
   6796                 }
   6797                 intf_sel_p0_p1.fields.p1_10g_dfe_on = fw_config.DfeOn;
   6798                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6799             } else {
   6800                 if (fw_config.UnreliableLos) {
   6801                     intf_sel_p0_p1.fields.p1_20g_media_type = 3;
   6802                 } else {
   6803                     intf_sel_p0_p1.fields.p1_20g_media_type = fw_config.MediaType;
   6804                 }
   6805                 intf_sel_p0_p1.fields.p1_20g_dfe_on = fw_config.DfeOn;
   6806                 intf_sel_p0_p1.fields.p1_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6807                 intf_sel_p0_p1.fields.p1_scrambling_dis = fw_config.ScramblingDisable;
   6808                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6809             }
   6810         } else if (port == 2) {
   6811             if (ip == SESTO_MERLIN_CORE) {
   6812                 if (fw_config.UnreliableLos) {
   6813                     intf_sel_p2_p3.fields.p2_10g_media_type = 3;
   6814                 } else {
   6815                     intf_sel_p2_p3.fields.p2_10g_media_type = fw_config.MediaType;
   6816                 }
   6817                 intf_sel_p2_p3.fields.p2_10g_dfe_on = fw_config.DfeOn;
   6818                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6819             } else {
   6820                 if (fw_config.UnreliableLos) {
   6821                     intf_sel_p2_p3.fields.p2_20g_media_type = 3;
   6822                 } else {
   6823                     intf_sel_p2_p3.fields.p2_20g_media_type = fw_config.MediaType;
   6824                 }
   6825                 intf_sel_p2_p3.fields.p2_20g_dfe_on = fw_config.DfeOn;
   6826                 intf_sel_p2_p3.fields.p2_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6827                 intf_sel_p2_p3.fields.p2_scrambling_dis = fw_config.ScramblingDisable;
   6828                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6829             }
   6830         } else {
   6831             if (ip == SESTO_MERLIN_CORE) {
   6832                 if (fw_config.UnreliableLos) {
   6833                     intf_sel_p2_p3.fields.p3_10g_media_type = 3;
   6834                 } else {
   6835                     intf_sel_p2_p3.fields.p3_10g_media_type = fw_config.MediaType;
   6836                 }
   6837                 intf_sel_p2_p3.fields.p3_10g_dfe_on = fw_config.DfeOn;
   6838                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6839             } else {
   6840                 if (fw_config.UnreliableLos) {
   6841                     intf_sel_p2_p3.fields.p3_20g_media_type = 3;
   6842                 } else {
   6843                     intf_sel_p2_p3.fields.p3_20g_media_type = fw_config.MediaType;
   6844                 }
   6845                 intf_sel_p2_p3.fields.p3_20g_dfe_on = fw_config.DfeOn;
   6846                 intf_sel_p2_p3.fields.p3_20g_dfe_lp_mode = fw_config.LpDfeOn;
   6847                 intf_sel_p2_p3.fields.p3_scrambling_dis = fw_config.ScramblingDisable;
   6848                 WRITE_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6849             }
   6850         }
   6851     }
   6852 
   6853     /*Setting the FW Enable to 1*/
   6854     SESTO_IF_ERR_RETURN( _sesto_fw_enable(pa, 1));
   6855 
   6856     retry_cnt = SESTO_FW_DLOAD_RETRY_CNT;
   6857     do {
   6858         SESTO_CHIP_FIELD_READ(pa, SES_GEN_CNTRLS_FIRMWARE_ENABLE, fw_enable_val, data);
   6859         retry_cnt--;
   6860     } while ((data != 0) && (retry_cnt));
   6861 
   6862     if (retry_cnt == 0) {
   6863         PHYMOD_DEBUG_VERBOSE(("WARN:: FW Enable not cleared\n"));
   6864         goto ERR;
   6865     }
   6866 
   6867 ERR:
   6868     PHYMOD_FREE(config.device_aux_modes);
   6869     return rv;
   6870 }
   6871 
   6872 int _sesto_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_config)
   6873 {
   6874     uint16_t ip = 0;
   6875     SESTO_DEVICE_AUX_MODE_T  *aux_mode;
   6876     SES_GEN_CNTRLS_MICRO_SYNC_5_TYPE_T intf_sel_p0_p1;
   6877     SES_GEN_CNTRLS_MICRO_SYNC_6_TYPE_T intf_sel_p2_p3;
   6878     phymod_phy_inf_config_t config;
   6879     const phymod_access_t *pa = &phy->access;
   6880     uint16_t port = 0, no_of_ports = 0;
   6881     int rv = PHYMOD_E_NONE;
   6882 
   6883     PHYMOD_MEMSET(&intf_sel_p0_p1, 0, sizeof(intf_sel_p0_p1));
   6884     PHYMOD_MEMSET(&intf_sel_p2_p3, 0, sizeof(intf_sel_p2_p3));
   6885 
   6886     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   6887     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   6888     SESTO_IF_ERR_RETURN(
   6889        _sesto_phy_interface_config_get(phy, 0, &config));
   6890     aux_mode = (SESTO_DEVICE_AUX_MODE_T*)config.device_aux_modes;
   6891     SESTO_GET_IP(phy, config, ip);
   6892     SESTO_GET_PORT_FROM_MODE((&config), no_of_ports, aux_mode);
   6893     SESTO_IF_ERR_RETURN(_sesto_port_from_lane_map_get(phy, &config, &port));
   6894 
   6895     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_5_ADR, intf_sel_p0_p1.data);
   6896     READ_SESTO_PMA_PMD_REG(pa, SES_GEN_CNTRLS_MICRO_SYNC_6_ADR, intf_sel_p2_p3.data);
   6897     if (no_of_ports == 1) { /* 100G/40GPT */
   6898         if (ip == SESTO_MERLIN_CORE) {
   6899             if (intf_sel_p0_p1.fields.p0_10g_media_type == 3) {
   6900                 fw_config->UnreliableLos = 1;
   6901                 fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6902             } else {
   6903                 fw_config->MediaType = intf_sel_p0_p1.fields.p0_10g_media_type;
   6904             }
   6905             fw_config->DfeOn =  intf_sel_p0_p1.fields.p0_10g_dfe_on;
   6906         } else {
   6907             if (intf_sel_p0_p1.fields.p0_20g_media_type == 3) {
   6908                 fw_config->UnreliableLos = 1;
   6909                 fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6910             } else {
   6911                 fw_config->MediaType = intf_sel_p0_p1.fields.p0_20g_media_type;
   6912             }
   6913             fw_config->DfeOn =  intf_sel_p0_p1.fields.p0_20g_dfe_on;
   6914             fw_config->LpDfeOn = intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode;
   6915             fw_config->ScramblingDisable = intf_sel_p0_p1.fields.p0_scrambling_dis;
   6916         }
   6917     } else if (no_of_ports == 2) { /* 40GMUX/20GMUX/20PT */
   6918         if (port == 0) {
   6919             if (ip == SESTO_MERLIN_CORE) {
   6920                 if (intf_sel_p0_p1.fields.p0_10g_media_type == 3) {
   6921                     fw_config->UnreliableLos = 1;
   6922                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6923                 } else {
   6924                     fw_config->MediaType = intf_sel_p0_p1.fields.p0_10g_media_type;
   6925                 }
   6926                 fw_config->DfeOn =  intf_sel_p0_p1.fields.p0_10g_dfe_on;
   6927             } else {
   6928                 if (intf_sel_p0_p1.fields.p0_20g_media_type == 3) {
   6929                     fw_config->UnreliableLos = 1;
   6930                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6931                 } else {
   6932                     fw_config->MediaType = intf_sel_p0_p1.fields.p0_20g_media_type;
   6933                 }
   6934                 fw_config->DfeOn =  intf_sel_p0_p1.fields.p0_20g_dfe_on;
   6935                 fw_config->LpDfeOn = intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode;
   6936                 fw_config->ScramblingDisable = intf_sel_p0_p1.fields.p0_scrambling_dis;
   6937             }
   6938         } else {
   6939             if (ip == SESTO_MERLIN_CORE) {
   6940                 if (intf_sel_p2_p3.fields.p2_10g_media_type == 3) {
   6941                     fw_config->UnreliableLos = 1;
   6942                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6943                 } else {
   6944                     fw_config->MediaType = intf_sel_p2_p3.fields.p2_10g_media_type;
   6945                 }
   6946                 fw_config->DfeOn =  intf_sel_p2_p3.fields.p2_10g_dfe_on;
   6947             } else {
   6948                 if (intf_sel_p2_p3.fields.p2_20g_media_type == 3) {
   6949                     fw_config->UnreliableLos = 1;
   6950                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6951                 } else {
   6952                     fw_config->MediaType = intf_sel_p2_p3.fields.p2_20g_media_type;
   6953                 }
   6954                 fw_config->DfeOn =  intf_sel_p2_p3.fields.p2_20g_dfe_on;
   6955                 fw_config->LpDfeOn = intf_sel_p2_p3.fields.p2_20g_dfe_lp_mode;
   6956                 fw_config->ScramblingDisable = intf_sel_p2_p3.fields.p2_scrambling_dis;
   6957             }
   6958         }
   6959     } else { /* 10G */
   6960         if (port == 0) {
   6961             if (ip == SESTO_MERLIN_CORE) {
   6962                 if (intf_sel_p0_p1.fields.p0_10g_media_type == 3) {
   6963                     fw_config->UnreliableLos = 1;
   6964                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6965                 } else {
   6966                     fw_config->MediaType = intf_sel_p0_p1.fields.p0_10g_media_type;
   6967                 }
   6968                 fw_config->DfeOn =  intf_sel_p0_p1.fields.p0_10g_dfe_on;
   6969             } else {
   6970                 if (intf_sel_p0_p1.fields.p0_20g_media_type == 3) {
   6971                     fw_config->UnreliableLos = 1;
   6972                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6973                 } else {
   6974                     fw_config->MediaType = intf_sel_p0_p1.fields.p0_20g_media_type;
   6975                 }
   6976                 fw_config->DfeOn =  intf_sel_p0_p1.fields.p0_20g_dfe_on;
   6977                 fw_config->LpDfeOn = intf_sel_p0_p1.fields.p0_20g_dfe_lp_mode;
   6978                 fw_config->ScramblingDisable = intf_sel_p0_p1.fields.p0_scrambling_dis;
   6979             }
   6980         } else if (port == 1) {
   6981             if (ip == SESTO_MERLIN_CORE) {
   6982                 if (intf_sel_p0_p1.fields.p1_10g_media_type == 3) {
   6983                     fw_config->UnreliableLos = 1;
   6984                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6985                 } else {
   6986                     fw_config->MediaType = intf_sel_p0_p1.fields.p1_10g_media_type;
   6987                 }
   6988                 fw_config->DfeOn =  intf_sel_p0_p1.fields.p1_10g_dfe_on;
   6989             } else {
   6990                 if (intf_sel_p0_p1.fields.p1_20g_media_type == 3) {
   6991                     fw_config->UnreliableLos = 1;
   6992                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   6993                 } else {
   6994                     fw_config->MediaType = intf_sel_p0_p1.fields.p1_20g_media_type;
   6995                 }
   6996                 fw_config->DfeOn =  intf_sel_p0_p1.fields.p1_20g_dfe_on;
   6997                 fw_config->LpDfeOn = intf_sel_p0_p1.fields.p1_20g_dfe_lp_mode;
   6998                 fw_config->ScramblingDisable = intf_sel_p0_p1.fields.p1_scrambling_dis;
   6999             }
   7000         } else if (port == 2) {
   7001             if (ip == SESTO_MERLIN_CORE) {
   7002                 if (intf_sel_p2_p3.fields.p2_10g_media_type == 3) {
   7003                     fw_config->UnreliableLos = 1;
   7004                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   7005                 } else {
   7006                     fw_config->MediaType = intf_sel_p2_p3.fields.p2_10g_media_type;
   7007                 }
   7008                 fw_config->DfeOn =  intf_sel_p2_p3.fields.p2_10g_dfe_on;
   7009             } else {
   7010                 if (intf_sel_p2_p3.fields.p2_20g_media_type == 3) {
   7011                     fw_config->UnreliableLos = 1;
   7012                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   7013                 } else {
   7014                     fw_config->MediaType = intf_sel_p2_p3.fields.p2_20g_media_type;
   7015                 }
   7016                 fw_config->DfeOn =  intf_sel_p2_p3.fields.p2_20g_dfe_on;
   7017                 fw_config->LpDfeOn = intf_sel_p2_p3.fields.p2_20g_dfe_lp_mode;
   7018                 fw_config->ScramblingDisable = intf_sel_p2_p3.fields.p2_scrambling_dis;
   7019             }
   7020         } else {
   7021             if (ip == SESTO_MERLIN_CORE) {
   7022                 if (intf_sel_p2_p3.fields.p3_10g_media_type == 3) {
   7023                     fw_config->UnreliableLos = 1;
   7024                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   7025                 } else {
   7026                     fw_config->MediaType = intf_sel_p2_p3.fields.p3_10g_media_type;
   7027                 }
   7028                 fw_config->DfeOn =  intf_sel_p2_p3.fields.p3_10g_dfe_on;
   7029             } else {
   7030                 if (intf_sel_p2_p3.fields.p3_20g_media_type) {
   7031                     fw_config->UnreliableLos = 1;
   7032                     fw_config->MediaType = phymodFirmwareMediaTypeOptics;
   7033                 } else {
   7034                     fw_config->MediaType = intf_sel_p2_p3.fields.p3_20g_media_type;
   7035                 }
   7036                 fw_config->DfeOn =  intf_sel_p2_p3.fields.p3_20g_dfe_on;
   7037                 fw_config->LpDfeOn = intf_sel_p2_p3.fields.p3_20g_dfe_lp_mode;
   7038                 fw_config->ScramblingDisable = intf_sel_p2_p3.fields.p2_scrambling_dis;
   7039             }
   7040         }
   7041     }
   7042 
   7043 ERR:
   7044     PHYMOD_FREE(config.device_aux_modes);
   7045     return rv;
   7046 }
   7047 
   7048 int _sesto_phy_short_channel_mode_set(const phymod_phy_access_t *phy, uint32_t enable)
   7049 {
   7050     phymod_phy_inf_config_t config;
   7051     uint16_t data = 0;
   7052     uint16_t ip = 0, lane = 0;
   7053     uint16_t lane_mask = 0, max_lane = 0;
   7054     const phymod_access_t *pa = &phy->access;
   7055     int rv = PHYMOD_E_NONE;
   7056 
   7057     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   7058     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   7059     SESTO_IF_ERR_RETURN(
   7060        _sesto_phy_interface_config_get(phy, 0, &config));
   7061     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   7062     SESTO_GET_IP(phy, config, ip);
   7063 
   7064     max_lane = (ip == SESTO_FALCON_CORE) ?
   7065                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   7066 
   7067     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   7068              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   7069 
   7070     if (ip == SESTO_MERLIN_CORE) {
   7071         /* short_channel_mode can performed only on falcon side */
   7072         return PHYMOD_E_PARAM;
   7073     }
   7074 
   7075     for (lane = 0; lane < max_lane; lane ++) {
   7076         if (lane_mask & (1 << lane)) {
   7077             SESTO_IF_ERR_RETURN(
   7078                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip, SESTO_DEV_PMA_PMD, 0, lane));
   7079             /* put the lane under dp reset */
   7080             SESTO_CHIP_FIELD_WRITE(pa, F25G_CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL, ln_dp_s_rstb, 0);
   7081             /* config RAM variable */
   7082             SESTO_CHIP_FIELD_WRITE(pa, SES_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD, mst_dram_mem_add, (0x420 + (lane * 0x130)));
   7083             SESTO_CHIP_FIELD_READ(pa, SES_M0ACCESS_DATA_MASTER_DRAM_RDATA, mst_dram_rdata, data);
   7084             enable ? (data |= (0x1 << 11)): (data &= (~(0x1 << 11)));
   7085             SESTO_CHIP_FIELD_WRITE(pa, SES_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD, mst_dram_mem_add, (0x420 + (lane * 0x130)));
   7086             SESTO_CHIP_FIELD_WRITE(pa, SES_M0ACCESS_DATA_MASTER_DRAM_WDATA, mst_dram_wdata, data);
   7087             /* Relase the lane under dp reset */
   7088             SESTO_CHIP_FIELD_WRITE(pa, F25G_CKRST_CTRL_RPTR_LANE_CLK_RESET_N_POWERDOWN_CONTROL, ln_dp_s_rstb, 1);
   7089         }
   7090     }
   7091 ERR:
   7092     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   7093     PHYMOD_FREE(config.device_aux_modes);
   7094 
   7095     return rv;
   7096 }
   7097 
   7098 int _sesto_phy_short_channel_mode_get(const phymod_phy_access_t *phy, uint32_t *enable, uint32_t *status)
   7099 {
   7100     phymod_phy_inf_config_t config;
   7101     uint16_t data = 0;
   7102     uint16_t ip = 0, lane = 0;
   7103     uint16_t lane_mask = 0, max_lane = 0;
   7104     const phymod_access_t *pa = &phy->access;
   7105     int rv = PHYMOD_E_NONE;
   7106     *enable = 1;
   7107 
   7108     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   7109     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   7110     SESTO_IF_ERR_RETURN(
   7111        _sesto_phy_interface_config_get(phy, 0, &config));
   7112     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   7113     SESTO_GET_IP(phy, config, ip);
   7114 
   7115     max_lane = (ip == SESTO_FALCON_CORE) ?
   7116                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   7117 
   7118     PHYMOD_DEBUG_VERBOSE(("%s ::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   7119              (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   7120 
   7121     if (ip == SESTO_MERLIN_CORE) {
   7122         /* short_channel_mode can performed only on falcon side */
   7123         return PHYMOD_E_PARAM;
   7124     }
   7125 
   7126     for (lane = 0; lane < max_lane; lane ++) {
   7127         if (lane_mask & (1 << lane)) {
   7128             /* config RAM variable */
   7129             SESTO_CHIP_FIELD_WRITE(pa, SES_M0ACCESS_ADDR_MASTER_DRAM_MEM_ADD, mst_dram_mem_add, (0x420 + (lane * 0x130)));
   7130             SESTO_CHIP_FIELD_READ(pa, SES_M0ACCESS_DATA_MASTER_DRAM_RDATA, mst_dram_rdata, data);
   7131             *enable &= ((data >> 11) & 0x1);
   7132         }
   7133     }
   7134 ERR:
   7135     SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   7136     PHYMOD_FREE(config.device_aux_modes);
   7137 
   7138     return rv;
   7139 }
   7140 
   7141 int _sesto_phy_eye_margin_est_get(const phymod_phy_access_t *phy, int *left_eye_mUI, int *right_eye_mUI, int *upper_eye_mV, int *lower_eye_mV)
   7142 {
   7143     phymod_phy_inf_config_t config;
   7144     
   7145     uint16_t ip = 0;
   7146     uint16_t lane = 0, max_lane = 0;
   7147     uint16_t lane_mask = 0;
   7148     int rv = PHYMOD_E_NONE;
   7149     const phymod_access_t *pa = &phy->access;
   7150     PHYMOD_MEMSET(&config, 0, sizeof(phymod_phy_inf_config_t));
   7151     config.device_aux_modes = PHYMOD_MALLOC(sizeof(SESTO_DEVICE_AUX_MODE_T), "sesto_device_aux_mode");
   7152     SESTO_IF_ERR_RETURN(
   7153        _sesto_phy_interface_config_get(phy, 0, &config));
   7154 
   7155     SESTO_GET_IP(phy, config, ip);
   7156     max_lane = (ip == SESTO_FALCON_CORE) ?
   7157                    SESTO_MAX_FALCON_LANE : SESTO_MAX_MERLIN_LANE;
   7158 
   7159     lane_mask = PHYMOD_ACC_LANE_MASK(pa);
   7160     PHYMOD_DEBUG_VERBOSE(("%s::IP:%s Max_lane:%d lanemask:0x%x\n", __func__,
   7161                 (ip == SESTO_MERLIN_CORE)?"MERLIN":"FALCON", max_lane, lane_mask));
   7162 
   7163     for (lane = 0; lane < max_lane; lane++) {
   7164         if ((lane_mask & (1 << lane))) {
   7165             SESTO_IF_ERR_RETURN (
   7166                 _sesto_set_slice_reg (pa, SESTO_SLICE_UNICAST, ip,
   7167                      SESTO_DEV_PMA_PMD, 0, lane));
   7168             PHYMOD_DEBUG_VERBOSE(("Phy Diagnostics for Lane:%d \n",lane));
   7169             if(ip == SESTO_FALCON_CORE) {
   7170                 SESTO_IF_ERR_RETURN (
   7171                     _falcon_furia_sesto_eye_margin_est_get(pa,left_eye_mUI,right_eye_mUI,upper_eye_mV,lower_eye_mV));
   7172                  break;
   7173             } else {
   7174                 SESTO_IF_ERR_RETURN (
   7175                      _merlin_sesto_eye_margin_est_get(pa,left_eye_mUI,right_eye_mUI,upper_eye_mV,lower_eye_mV));
   7176         break;
   7177 
   7178             }
   7179         }
   7180     }
   7181     ERR:
   7182        SESTO_RESET_SLICE(pa, SESTO_DEV_PMA_PMD);
   7183        PHYMOD_FREE(config.device_aux_modes);
   7184    return rv;
   7185 }
   7186 
   7187