openbcm

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

furia_micro_seq.c (18601B)


      1 /*
      2  *         
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved. 
      8  */
      9 /* 
     10  * Includes
     11  */
     12 #include <phymod/phymod_system.h>
     13 #include "furia_micro_seq.h"
     14 #include "furia_cfg_seq.h"
     15 #include "furia_regs_structs.h"
     16 #include "furia_reg_access.h"
     17 #include "furia_address_defines.h"
     18 #include "furia_types.h"
     19 
     20 /*
     21  *  Defines
     22  */
     23 #define FURIA_FW_DLOAD_RETRY_CNT 50000 
     24 #define FURIA_M0_EEPROM_PAGE_SIZE 64
     25 /* 
     26  *  Types
     27  */
     28 
     29 /*
     30  *  Macros
     31  */
     32 
     33 /*
     34  *  Global Variables
     35  */
     36 
     37 /*
     38  *  Functions
     39  */
     40 
     41 /**   Wait master message out 
     42  *    This function is to ensure whether master has sent the previous message
     43  *    out successfully 
     44  *
     45  *    @param pa                 Pointer to phymod access structure 
     46  *    @param exp_message        Expected message specified by user  
     47  *    @param poll_time          Poll interval 
     48  *
     49  *    @return PHYMOD_E_NONE     successful function execution 
     50  */
     51 int _furia_wait_mst_msgout(const phymod_access_t *pa,
     52                             FURIA_MSGOUT_E exp_message,
     53                             int poll_time)
     54 {
     55     int retry_count = FURIA_FW_DLOAD_RETRY_CNT;
     56     FURIA_MSGOUT_E msgout = 0;
     57     FUR_GEN_CNTRLS_MSGOUT_t msgout_t;
     58     
     59     do {
     60         /* Read general control msg out  Register */
     61         PHYMOD_IF_ERR_RETURN
     62             (READ_FURIA_PMA_PMD_REG(pa,\
     63                                     FUR_GEN_CNTRLS_msgout_Adr,\
     64                                     &msgout_t.data));
     65         msgout = (FURIA_MSGOUT_E) msgout_t.fields.msgout_val;
     66         /* wait before reading again */
     67         if (poll_time != 0) {
     68             /* sleep for specified seconds*/
     69             PHYMOD_USLEEP(poll_time/FURIA_FW_DLOAD_RETRY_CNT);
     70         }
     71         retry_count--;
     72     } while ((msgout != exp_message) &&  retry_count);
     73    
     74     if(!retry_count) {
     75         if(exp_message == MSGOUT_PRGRM_DONE) { 
     76             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, (_PHYMOD_MSG("Fusing Firmware failed")));
     77         } else {
     78             PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed")));
     79         }
     80     } 
     81     
     82     return PHYMOD_E_NONE; 
     83 }
     84 /**   Download and Fuse firmware 
     85  *    This function is used to download the firmware through I2C/MDIO
     86  *    and fuse it to SPI EEPROM if prg_eeprom flag is set 
     87  *
     88  *    @param pa                 Pointer to phymod access structure 
     89  *    @param new_fw             Pointer to firmware array 
     90  *    @param fw_length          Length of the firmware array 
     91  *    @param prg_eeprom         Flag used to program EEPROM
     92  *
     93  *    @return num_bytes         number of bytes successfully downloaded
     94  */
     95 int furia_download_prog_eeprom(const phymod_access_t *pa,
     96                                  uint8_t *new_fw,
     97                                  uint32_t fw_length,
     98                                  uint8_t prg_eeprom)
     99 {
    100     uint16_t data16 = 0;
    101     uint16_t num_bytes = 0;
    102     uint16_t num_words = 0;
    103     uint16_t j = 0;
    104     uint16_t ser_boot_busy = 0; 
    105     FUR_GEN_CNTRLS_MSGIN_t msgin;
    106     FUR_GEN_CNTRLS_GEN_CONTROL2_t gen_ctrl2;
    107     FUR_GEN_CNTRLS_GEN_CONTROL3_t gen_ctrl3;
    108     FUR_GEN_CNTRLS_BOOT_t gen_ctrl_boot;
    109     FUR_GEN_CNTRLS_SPI_CODE_LOAD_EN_t spi_code_ld_en;
    110     FUR_MICRO_BOOT_BOOT_POR_t micro_boot_por;
    111     FUR_GEN_CNTRLS_MST_RUNNING_CHKSUM_t mst_running_chksum;
    112     FUR_GEN_CNTRLS_SLV_RUNNING_CHKSUM_t slv_running_chksum;
    113     FUR_GEN_CNTRLS_MST_RUNNING_BYTE_CNT_t mst_running_byte_cnt;
    114     FUR_GEN_CNTRLS_SLV_RUNNING_BYTE_CNT_t slv_running_byte_cnt;
    115     FUR_GEN_CNTRLS_GEN_CONTROL1_t gen_ctrl1;
    116     FUR_GEN_CNTRLS_gpreg14_t gpreg14;
    117     FUR_GEN_CNTRLS_gpreg15_t gpreg15;
    118     uint16_t m_chksum = 0;
    119     uint16_t s_chksum = 0;
    120     uint16_t m_byte_cnt = 0;  
    121     uint16_t s_byte_cnt = 0;  
    122     uint16_t check_sum = 0;
    123     int retry_count = FURIA_FW_DLOAD_RETRY_CNT;
    124     int eeprom_num_of_pages = 0;
    125     phymod_tx_t tx_params;
    126 
    127     PHYMOD_MEMSET(&msgin, 0, sizeof(FUR_GEN_CNTRLS_MSGIN_t));
    128     PHYMOD_MEMSET(&gen_ctrl2, 0, sizeof(FUR_GEN_CNTRLS_GEN_CONTROL2_t));
    129     PHYMOD_MEMSET(&gen_ctrl3, 0, sizeof(FUR_GEN_CNTRLS_GEN_CONTROL3_t));
    130     PHYMOD_MEMSET(&gen_ctrl_boot, 0, sizeof(FUR_GEN_CNTRLS_BOOT_t));
    131     PHYMOD_MEMSET(&spi_code_ld_en, 0, sizeof(FUR_GEN_CNTRLS_SPI_CODE_LOAD_EN_t));
    132     PHYMOD_MEMSET(&micro_boot_por, 0, sizeof(FUR_MICRO_BOOT_BOOT_POR_t));
    133     PHYMOD_MEMSET(&mst_running_chksum, 0, sizeof(FUR_GEN_CNTRLS_MST_RUNNING_CHKSUM_t));
    134     PHYMOD_MEMSET(&slv_running_chksum, 0, sizeof(FUR_GEN_CNTRLS_SLV_RUNNING_CHKSUM_t));
    135     PHYMOD_MEMSET(&mst_running_byte_cnt, 0, sizeof(FUR_GEN_CNTRLS_MST_RUNNING_BYTE_CNT_t));
    136     PHYMOD_MEMSET(&slv_running_byte_cnt, 0, sizeof(FUR_GEN_CNTRLS_SLV_RUNNING_BYTE_CNT_t));
    137     PHYMOD_MEMSET(&gen_ctrl1, 0 , sizeof(FUR_GEN_CNTRLS_GEN_CONTROL1_t));
    138     PHYMOD_MEMSET(&gpreg14, 0 , sizeof(FUR_GEN_CNTRLS_gpreg14_t));
    139     PHYMOD_MEMSET(&gpreg15, 0 , sizeof(FUR_GEN_CNTRLS_gpreg15_t));
    140     PHYMOD_MEMSET(&tx_params, 0 , sizeof(phymod_tx_t));
    141 
    142     /* Skip the firmware download 
    143      *  i) if serboot bin is low and mst_download, slv_dwld_done bits are set
    144      */
    145     PHYMOD_IF_ERR_RETURN
    146         (READ_FURIA_PMA_PMD_REG(pa,\
    147                                 FUR_MICRO_BOOT_boot_por_Adr,\
    148                                 &micro_boot_por.data));
    149 
    150     if (!prg_eeprom) {
    151         PHYMOD_IF_ERR_RETURN
    152             (READ_FURIA_PMA_PMD_REG(pa,\
    153                                     FUR_GEN_CNTRLS_mst_running_byte_cnt_Adr,\
    154                                     &mst_running_byte_cnt.data));
    155         m_byte_cnt = mst_running_byte_cnt.fields.mst_running_byte_cnt_val;
    156 
    157         PHYMOD_IF_ERR_RETURN
    158             (READ_FURIA_PMA_PMD_REG(pa,\
    159                                     FUR_GEN_CNTRLS_slv_running_byte_cnt_Adr,\
    160                                     &slv_running_byte_cnt.data));
    161         s_byte_cnt = slv_running_byte_cnt.fields.slv_running_byte_cnt_val;
    162 
    163         if (((m_byte_cnt == fw_length) || 
    164              (s_byte_cnt == fw_length))&&
    165             (micro_boot_por.fields.mst_dwld_done) &&
    166             (micro_boot_por.fields.slv_dwld_done)) {
    167             return FURIA_FW_ALREADY_DOWNLOADED;
    168         }
    169     }
    170 
    171     /* Set Tx driver current, FIR main/pre/post default values 
    172      *  Default values are 
    173      *  driver current = 0xf
    174      *  TX FIR main = 0x3c
    175      *  TX FIR pre = 0x0
    176      *  TX FIR post = 0x0
    177      */ 
    178 
    179     PHYMOD_IF_ERR_RETURN
    180          (furia_tx_get(pa, &tx_params)); 
    181     tx_params.amp = 0xf;
    182     tx_params.pre = 0x0;
    183     tx_params.post = 0x0;
    184     tx_params.main = 0x3c;
    185     PHYMOD_IF_ERR_RETURN
    186          (furia_tx_set(pa, &tx_params));  
    187     /* Do chip reset */
    188     PHYMOD_IF_ERR_RETURN
    189         (READ_FURIA_PMA_PMD_REG(pa,\
    190                                 FUR_GEN_CNTRLS_gen_control1_Adr,\
    191                                 &gen_ctrl1.data));
    192     gen_ctrl1.fields.resetb = 0;
    193 
    194     PHYMOD_IF_ERR_RETURN
    195         (WRITE_FURIA_PMA_PMD_REG(pa,\
    196                                  FUR_GEN_CNTRLS_gen_control1_Adr,\
    197                                  gen_ctrl1.data));
    198 
    199     /* Perform master reset */
    200     PHYMOD_IF_ERR_RETURN
    201         (READ_FURIA_PMA_PMD_REG(pa,\
    202                                 FUR_GEN_CNTRLS_gen_control2_Adr,\
    203                                 &gen_ctrl2.data));
    204     gen_ctrl2.fields.m0_mstr_rstb = 0;
    205     gen_ctrl2.fields.m0_mstr_ucp_rstb = 0; 
    206 
    207     PHYMOD_IF_ERR_RETURN
    208         (WRITE_FURIA_PMA_PMD_REG(pa,\
    209                                  FUR_GEN_CNTRLS_gen_control2_Adr,\
    210                                  gen_ctrl2.data));
    211 
    212     /* Wait for the serboot busy bit to become zero */
    213     PHYMOD_IF_ERR_RETURN
    214         (READ_FURIA_PMA_PMD_REG(pa,\
    215                                 FUR_GEN_CNTRLS_boot_Adr,\
    216                                 &gen_ctrl_boot.data));
    217 
    218     /* Wait for any pending SPI download
    219      * SPI download is not interrupted by Master Reset
    220      * (this is a safety feature) so we need to wait its 
    221      * completion before starting the MDIO Download */
    222     do {
    223         PHYMOD_IF_ERR_RETURN
    224             (READ_FURIA_PMA_PMD_REG(pa,\
    225                                     FUR_GEN_CNTRLS_boot_Adr,\
    226                                     &gen_ctrl_boot.data));
    227         ser_boot_busy = gen_ctrl_boot.fields.serboot_busy;
    228         PHYMOD_USLEEP(500);
    229         retry_count--;
    230     } while((ser_boot_busy != 0) && (retry_count));
    231 
    232     if (retry_count == 0) {
    233         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 
    234               (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET")));
    235     }
    236   
    237     /* Program master enable, slave enable, broadcast enable bits */
    238     PHYMOD_IF_ERR_RETURN
    239         (READ_FURIA_PMA_PMD_REG(pa,\
    240                                 FUR_GEN_CNTRLS_spi_code_load_en_Adr,\
    241                                 &spi_code_ld_en.data));
    242 
    243     spi_code_ld_en.fields.code_broadcast_en = 1;
    244     spi_code_ld_en.fields.slave_code_download_en = 1; 
    245     spi_code_ld_en.fields.master_code_download_en = 1; 
    246 
    247     PHYMOD_IF_ERR_RETURN
    248         (WRITE_FURIA_PMA_PMD_REG(pa,\
    249                                  FUR_GEN_CNTRLS_spi_code_load_en_Adr,\
    250                                  spi_code_ld_en.data));
    251 
    252     PHYMOD_IF_ERR_RETURN
    253         (READ_FURIA_PMA_PMD_REG(pa,\
    254                                 FUR_GEN_CNTRLS_spi_code_load_en_Adr,\
    255                                 &spi_code_ld_en.data));
    256     if ((spi_code_ld_en.fields.code_broadcast_en != 1) &&
    257         (spi_code_ld_en.fields.master_code_download_en != 1) &&
    258         (spi_code_ld_en.fields.slave_code_download_en != 1)) {
    259         return PHYMOD_E_INTERNAL;
    260     }
    261     /* Select SPI speed */
    262     PHYMOD_IF_ERR_RETURN
    263         (READ_FURIA_PMA_PMD_REG(pa,\
    264                                 FUR_GEN_CNTRLS_gen_control3_Adr,\
    265                                 &gen_ctrl3.data));
    266     gen_ctrl3.fields.ucspi_slow = 1; 
    267     PHYMOD_IF_ERR_RETURN
    268         (WRITE_FURIA_PMA_PMD_REG(pa,\
    269                                  FUR_GEN_CNTRLS_gen_control3_Adr,\
    270                                  gen_ctrl3.data));
    271     if(prg_eeprom) {
    272         /* Configuration for programming SPI EEPROM */
    273         eeprom_num_of_pages = fw_length/FURIA_M0_EEPROM_PAGE_SIZE;
    274         /*program GPReg 14 with eeprom start page */
    275         gpreg14.data = 0;
    276         PHYMOD_IF_ERR_RETURN
    277             (WRITE_FURIA_PMA_PMD_REG(pa, FUR_GEN_CNTRLS_gpreg14_Adr, gpreg14.data));
    278         /*program GPReg 15 with eeprom number of pages */
    279         gpreg15.data = eeprom_num_of_pages;
    280         PHYMOD_IF_ERR_RETURN
    281             (WRITE_FURIA_PMA_PMD_REG(pa,
    282                                      FUR_GEN_CNTRLS_gpreg15_Adr,
    283                                      gpreg15.data));
    284    
    285         /* Assert Reset by writing zero to spi_rstb, spi2x_rstb */
    286         PHYMOD_IF_ERR_RETURN
    287             (READ_FURIA_PMA_PMD_REG(pa,\
    288                                     FUR_GEN_CNTRLS_gen_control2_Adr,\
    289                                     &gen_ctrl2.data));
    290         gen_ctrl2.fields.spi_rstb = 0; 
    291         gen_ctrl2.fields.spi2x_rstb = 0; 
    292 
    293         PHYMOD_IF_ERR_RETURN
    294             (WRITE_FURIA_PMA_PMD_REG(pa,\
    295                                      FUR_GEN_CNTRLS_gen_control2_Adr,\
    296                                      gen_ctrl2.data));
    297 
    298         /* Deassert Reset by setting spi_rstb, spi2x_rstb bits */
    299         PHYMOD_IF_ERR_RETURN
    300             (READ_FURIA_PMA_PMD_REG(pa,\
    301                                     FUR_GEN_CNTRLS_gen_control2_Adr,\
    302                                     &gen_ctrl2.data));
    303         gen_ctrl2.fields.spi_rstb = 1; 
    304         gen_ctrl2.fields.spi2x_rstb = 1; 
    305 
    306         PHYMOD_IF_ERR_RETURN
    307             (WRITE_FURIA_PMA_PMD_REG(pa,\
    308                                      FUR_GEN_CNTRLS_gen_control2_Adr,\
    309                                      gen_ctrl2.data));
    310     }
    311     /* Force master download done, slave download done bit to 0 
    312      * set external boot (serboot) to 1 */
    313     PHYMOD_IF_ERR_RETURN
    314         (READ_FURIA_PMA_PMD_REG(pa,\
    315                                 FUR_MICRO_BOOT_boot_por_Adr,\
    316                                 &micro_boot_por.data));
    317 
    318     micro_boot_por.fields.mst_dwld_done = 0;
    319     micro_boot_por.fields.slv_dwld_done = 0;
    320     micro_boot_por.fields.serboot = 1;
    321     micro_boot_por.fields.spi_port_used = 0;
    322     PHYMOD_IF_ERR_RETURN
    323         (WRITE_FURIA_PMA_PMD_REG(pa,\
    324                                  FUR_MICRO_BOOT_boot_por_Adr,\
    325                                  micro_boot_por.data));
    326 
    327 
    328     /* Bring back m0 master to normal state*/
    329     PHYMOD_IF_ERR_RETURN
    330         (READ_FURIA_PMA_PMD_REG(pa,\
    331                                 FUR_GEN_CNTRLS_gen_control2_Adr,\
    332                                 &gen_ctrl2.data));
    333 
    334     gen_ctrl2.fields.m0_mstr_rstb = 1;
    335     gen_ctrl2.fields.m0_mstr_ucp_rstb = 1; 
    336 
    337     PHYMOD_IF_ERR_RETURN
    338         (WRITE_FURIA_PMA_PMD_REG(pa,\
    339                                  FUR_GEN_CNTRLS_gen_control2_Adr,\
    340                                  gen_ctrl2.data));
    341 
    342     /* MDI/I2C Download */
    343     /* Waiting for serboot_busy */
    344     retry_count = FURIA_FW_DLOAD_RETRY_CNT;
    345     do {
    346         PHYMOD_IF_ERR_RETURN
    347             (READ_FURIA_PMA_PMD_REG(pa,\
    348                                     FUR_GEN_CNTRLS_boot_Adr,\
    349                                     &gen_ctrl_boot.data));
    350 
    351         ser_boot_busy = gen_ctrl_boot.fields.serboot_busy;
    352         PHYMOD_USLEEP(500);
    353         retry_count--;
    354     } while ((ser_boot_busy == 0) && (retry_count));
    355     if (retry_count == 0) {
    356         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_FAIL, 
    357               (_PHYMOD_MSG("ERR:SERBOOT BUSY BIT SET")));
    358     }
    359     /* Program master and slave boot address */ 
    360     PHYMOD_IF_ERR_RETURN
    361         (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    362 
    363     msgin.fields.msgin_val = 0x0000;
    364     PHYMOD_IF_ERR_RETURN
    365         (WRITE_FURIA_PMA_PMD_REG(pa,\
    366                                  FUR_GEN_CNTRLS_msgin_Adr,\
    367                                  msgin.data));
    368 
    369     PHYMOD_IF_ERR_RETURN
    370         (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    371     msgin.fields.msgin_val = 0x0000;
    372     PHYMOD_IF_ERR_RETURN
    373         (WRITE_FURIA_PMA_PMD_REG(pa,\
    374                                  FUR_GEN_CNTRLS_msgin_Adr,\
    375                                  msgin.data));
    376    
    377     PHYMOD_IF_ERR_RETURN
    378         (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    379 
    380     /* Calculate the number of words */
    381     num_words = (fw_length) / 2;
    382 
    383     /* Update message in value field with word length */
    384     msgin.fields.msgin_val = num_words;
    385     PHYMOD_IF_ERR_RETURN
    386         (WRITE_FURIA_PMA_PMD_REG(pa,\
    387                                  FUR_GEN_CNTRLS_msgin_Adr,\
    388                                  msgin.data));
    389 
    390     num_bytes = fw_length;
    391 
    392     for (j = 0; j < num_bytes; j += 2) {
    393         /* Wait MSGOUT_NEXT from M0 */
    394         PHYMOD_IF_ERR_RETURN
    395             (_furia_wait_mst_msgout(pa, MSGOUT_NEXT, 0));
    396 
    397         data16 = (new_fw[j + 1] << 8) | new_fw[j];
    398         check_sum ^= new_fw[j] ^ new_fw[j + 1];
    399         /* Send next word */
    400         msgin.fields.msgin_val = data16;
    401 
    402         PHYMOD_IF_ERR_RETURN
    403             (WRITE_FURIA_PMA_PMD_REG(pa,\
    404                                      FUR_GEN_CNTRLS_msgin_Adr,\
    405                                      msgin.data));
    406     }
    407 
    408     check_sum = check_sum ? check_sum : 0x600D;
    409     /*Check whether firmware is downloaded for both master and slave micro*/
    410     PHYMOD_IF_ERR_RETURN
    411         (READ_FURIA_PMA_PMD_REG(pa,\
    412                                 FUR_MICRO_BOOT_boot_por_Adr,\
    413                                 &micro_boot_por.data));
    414 
    415     if((!micro_boot_por.fields.mst_dwld_done) || (!micro_boot_por.fields.slv_dwld_done)) {
    416         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed")));
    417     } 
    418 
    419     PHYMOD_IF_ERR_RETURN
    420         (READ_FURIA_PMA_PMD_REG(pa,\
    421                                 FUR_GEN_CNTRLS_mst_running_byte_cnt_Adr,\
    422                                 &mst_running_byte_cnt.data));
    423     m_byte_cnt = mst_running_byte_cnt.fields.mst_running_byte_cnt_val;
    424 
    425     PHYMOD_IF_ERR_RETURN
    426         (READ_FURIA_PMA_PMD_REG(pa,\
    427                                 FUR_GEN_CNTRLS_slv_running_byte_cnt_Adr,\
    428                                 &slv_running_byte_cnt.data));
    429     s_byte_cnt = slv_running_byte_cnt.fields.slv_running_byte_cnt_val;
    430 
    431     if ((m_byte_cnt != num_bytes) || (s_byte_cnt != num_bytes)) {
    432         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download incomplete with byte count mismatch")));
    433     }
    434 
    435     /* Compare the checksum for data integrity */ 
    436     PHYMOD_IF_ERR_RETURN
    437         (READ_FURIA_PMA_PMD_REG(pa,\
    438                                 FUR_GEN_CNTRLS_mst_running_chksum_Adr,\
    439                                 &mst_running_chksum.data));
    440     m_chksum = mst_running_chksum.fields.mst_running_chksum_val;
    441     PHYMOD_IF_ERR_RETURN
    442         (READ_FURIA_PMA_PMD_REG(pa,\
    443                                 FUR_GEN_CNTRLS_slv_running_chksum_Adr,\
    444                                 &slv_running_chksum.data));
    445     s_chksum = slv_running_chksum.fields.slv_running_chksum_val;
    446  
    447     if((m_chksum != check_sum) || (s_chksum != check_sum)) {
    448         PHYMOD_RETURN_WITH_ERR(PHYMOD_E_INIT, (_PHYMOD_MSG("Firmware download failed with checksum mismatch")));
    449     }
    450 
    451     /* To Check whether the firmware download through MDIO is done */
    452     PHYMOD_IF_ERR_RETURN
    453         (_furia_wait_mst_msgout(pa, MSGOUT_DWNLD_DONE, 0));
    454     /* Wait for programming EEPROM */
    455     if(prg_eeprom) {
    456         PHYMOD_IF_ERR_RETURN
    457             (_furia_wait_mst_msgout(pa, MSGOUT_PRGRM_DONE, 10000000));
    458         /* Assert Reset by writing zero to spi_rstb, spi2x_rstb */
    459         PHYMOD_IF_ERR_RETURN
    460             (READ_FURIA_PMA_PMD_REG(pa,\
    461                                     FUR_GEN_CNTRLS_gen_control2_Adr,\
    462                                     &gen_ctrl2.data));
    463         gen_ctrl2.fields.spi_rstb = 0;
    464         gen_ctrl2.fields.spi2x_rstb = 0;
    465 
    466         PHYMOD_IF_ERR_RETURN
    467             (WRITE_FURIA_PMA_PMD_REG(pa,\
    468                                      FUR_GEN_CNTRLS_gen_control2_Adr,\
    469                                      gen_ctrl2.data));
    470     }
    471 
    472     return m_byte_cnt;
    473 }
    474 
    475 int furia_firmware_info_get(const phymod_access_t *pa, phymod_core_firmware_info_t *fw_info)
    476 {
    477     FUR_GEN_CNTRLS_FIRMWARE_VERSION_t firmware_version;
    478     FUR_GEN_CNTRLS_MST_RUNNING_CHKSUM_t mst_running_chksum;
    479     /* Read the firmware version */
    480     PHYMOD_IF_ERR_RETURN
    481         (READ_FURIA_PMA_PMD_REG(pa,\
    482                                 FUR_GEN_CNTRLS_firmware_version_Adr,\
    483                                 &firmware_version.data));
    484     fw_info->fw_version = firmware_version.data; 
    485     PHYMOD_IF_ERR_RETURN
    486         (READ_FURIA_PMA_PMD_REG(pa,\
    487                                 FUR_GEN_CNTRLS_mst_running_chksum_Adr,\
    488                                 &mst_running_chksum.data));
    489     fw_info->fw_crc = mst_running_chksum.data; 
    490     return PHYMOD_E_NONE;
    491 }