openbcm

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

quadra28_micro_seq.c (37061B)


      1 /*
      2 *
      3 * 
      4 *
      5 5 *
      6 5 *
      7 5 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      8 5 * 
      9 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved.
     10 5 * Broadcom Proprietary and Confidential. All rights reserved.$
     11 7  *
     12 8  * File: quadra28.c
     13    * Purpose: tier1 phymod microcode download support for Broadcom 40G Quadra28 
     14    * note
     15 */
     16 
     17 /*
     18  * Includes
     19  */
     20 #include <phymod/phymod.h>
     21 #include <phymod/phymod_system.h>
     22 #include "quadra28_reg_access.h"
     23 #include "quadra28_types.h"
     24 #include "bcmi_quadra28_defs.h"
     25 #include "quadra28_cfg_seq.h"
     26 
     27 static int _quadra28_verify_fw_download(const phymod_access_t *pa, int edc);
     28 
     29 /* If it is single PMD, we need to clear it before downloading FW*/
     30 int _quadra28_clear_mode_config(phymod_access_t *pa)
     31 {
     32     int speed = 0;
     33     BCMI_QUADRA28_GENERAL_PURPOSE_3r_t gp_reg3_reg_val;
     34     BCMI_QUADRA28_APPS_MODE_0r_t apps_mode0_reg_val;
     35     PHYMOD_MEMSET(&gp_reg3_reg_val, 0, sizeof(BCMI_QUADRA28_GENERAL_PURPOSE_3r_t));
     36     PHYMOD_MEMSET(&apps_mode0_reg_val, 0, sizeof(BCMI_QUADRA28_APPS_MODE_0r_t));
     37 
     38     PHYMOD_IF_ERR_RETURN(
     39         BCMI_QUADRA28_READ_GENERAL_PURPOSE_3r(pa, &gp_reg3_reg_val));
     40     speed = gp_reg3_reg_val.v[0] & 0xF ;
     41     if (speed == 0x4 || speed == 0x7) {
     42         PHYMOD_IF_ERR_RETURN(
     43             quadra28_channel_select (pa, Q28_ALL_LANE));
     44         apps_mode0_reg_val.v[0] = gp_reg3_reg_val.v[0];
     45         BCMI_QUADRA28_APPS_MODE_0r_FINISH_CHANGEf_SET(apps_mode0_reg_val, 0);
     46         PHYMOD_IF_ERR_RETURN(
     47             BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val));
     48         PHYMOD_USLEEP(100);
     49         BCMI_QUADRA28_APPS_MODE_0r_SET(apps_mode0_reg_val, 0x8882);
     50         PHYMOD_IF_ERR_RETURN(
     51             BCMI_QUADRA28_WRITE_APPS_MODE_0r(pa, apps_mode0_reg_val));
     52         PHYMOD_USLEEP(100);
     53         PHYMOD_IF_ERR_RETURN(
     54                  _quadra28_intf_update_wait_check(pa,apps_mode0_reg_val.v[0], 50000));
     55     }
     56 
     57     return PHYMOD_E_NONE;
     58 }
     59 
     60 static int _quadra28_verify_fw_download(const phymod_access_t *pa, int edc)
     61 {
     62     MSG_OUTr_t msg_out_reg;
     63     BOOT_CHECKSUMr_t checksum_reg;
     64     PHYMOD_MEMSET(&msg_out_reg, 0, sizeof(MSG_OUTr_t));
     65     PHYMOD_MEMSET(&checksum_reg, 0, sizeof(BOOT_CHECKSUMr_t));
     66     PHYMOD_IF_ERR_RETURN((BCMI_QUADRA28_READ_MSG_OUTr(pa,&msg_out_reg)));
     67     msg_out_reg.v[0] = MSG_OUTr_MESSAGE_OUTf_GET(msg_out_reg);
     68     if (0x4321 == msg_out_reg.v[0]){
     69        /* step19: Wait 4ms */
     70         PHYMOD_USLEEP(4000);
     71     } else {
     72        return PHYMOD_E_FAIL;
     73     }      
     74     /* Intermediate step in vbs */
     75     PHYMOD_IF_ERR_RETURN((BCMI_QUADRA28_READ_MSG_OUTr(pa,&msg_out_reg)));
     76     msg_out_reg.v[0] = MSG_OUTr_MESSAGE_OUTf_GET(msg_out_reg);   
     77     if (0x300 != msg_out_reg.v[0]) {
     78        return PHYMOD_E_FAIL;
     79     }
     80     if (!edc) {
     81         /* step 20 Read checksum (expected 0x600D) */
     82         PHYMOD_IF_ERR_RETURN
     83             (BCMI_QUADRA28_READ_BOOT_CHECKSUMr(pa, &checksum_reg)); 
     84         checksum_reg.v[0]=BCMI_QUADRA28_BOOT_CHECKSUMr_BOOT_CHKSUMf_GET(checksum_reg); 
     85         if (0x600D != checksum_reg.v[0]) {
     86             /*Checksum is correct */
     87             return PHYMOD_E_FAIL;
     88         }
     89     } else {
     90         BCMI_QUADRA28_GP_4r_t gp_4;
     91         PHYMOD_MEMSET(&gp_4, 0, sizeof(BCMI_QUADRA28_GP_4r_t));
     92         PHYMOD_IF_ERR_RETURN(
     93             BCMI_QUADRA28_READ_GP_4r(pa, &gp_4));
     94         if (0x600D != gp_4.v[0]) {
     95             /*Checksum is not correct */
     96             return PHYMOD_E_FAIL;
     97         }
     98     }
     99     
    100     return PHYMOD_E_NONE; 
    101 }
    102 
    103 int quadra28_firmware_info_get(const phymod_access_t *pa, phymod_core_firmware_info_t *fw_info)
    104 {
    105     uint32_t fw_ver = 0;
    106     BOOT_CHECKSUMr_t mst_running_chksum;
    107 
    108     /* Read the firmware version */
    109     PHYMOD_IF_ERR_RETURN(
    110         phymod_raw_iblk_read(pa, (0x10000 | (uint32_t) 0xC161), &fw_ver));
    111  
    112     fw_info->fw_version = (fw_ver & 0xff); 
    113     PHYMOD_IF_ERR_RETURN( 
    114         BCMI_QUADRA28_READ_BOOT_CHECKSUMr(pa, 
    115             &mst_running_chksum));
    116     fw_info->fw_crc = BCMI_QUADRA28_BOOT_CHECKSUMr_BOOT_CHKSUMf_GET(mst_running_chksum);
    117    
    118     return PHYMOD_E_NONE;
    119 }
    120 
    121 int quadra28_write_message(const phymod_access_t *pa, int wrdata, int *rddata)
    122 {
    123     int tmp_data = 0, retry_cnt = 0;
    124     BCMI_QUADRA28_MESSAGE_OUTr_t msg_out;
    125     BCMI_QUADRA28_MESSAGE_INr_t msg_in;
    126     BCMI_QUADRA28_GENERAL_STATUS_1r_t   gen_sts;
    127 
    128     PHYMOD_MEMSET(&msg_out, 0, sizeof(BCMI_QUADRA28_MESSAGE_OUTr_t));
    129     PHYMOD_MEMSET(&msg_in, 0, sizeof(BCMI_QUADRA28_MESSAGE_INr_t));
    130     PHYMOD_MEMSET(&gen_sts, 0, sizeof(BCMI_QUADRA28_GENERAL_STATUS_1r_t));
    131 
    132     /* Clear any lingering Message out from Micro.*/
    133     PHYMOD_IF_ERR_RETURN(
    134         BCMI_QUADRA28_READ_MESSAGE_OUTr(pa, &msg_out));
    135 
    136     /* Write SPI Control Register Write Command.*/
    137     BCMI_QUADRA28_MESSAGE_INr_SET(msg_in, wrdata);
    138     PHYMOD_IF_ERR_RETURN(
    139            BCMI_QUADRA28_WRITE_MESSAGE_INr(pa, msg_in));
    140     do {
    141         PHYMOD_IF_ERR_RETURN(
    142             BCMI_QUADRA28_READ_GENERAL_STATUS_1r(pa, &gen_sts));
    143         tmp_data = BCMI_QUADRA28_GENERAL_STATUS_1r_GET (gen_sts);
    144         retry_cnt ++;
    145     } while (((tmp_data & 0x4000) == 0) && (retry_cnt < Q28_RETRY_CNT));
    146 
    147     if (retry_cnt >= Q28_RETRY_CNT) {
    148         return PHYMOD_E_CONFIG;
    149     }
    150 
    151     PHYMOD_IF_ERR_RETURN(
    152         BCMI_QUADRA28_READ_MESSAGE_OUTr(pa, &msg_out));
    153     *rddata = BCMI_QUADRA28_MESSAGE_OUTr_GET(msg_out);
    154 
    155     return PHYMOD_E_NONE;
    156 }
    157 
    158 int q28_get_spi_eeprom_status(const phymod_access_t *pa) 
    159 {
    160     int retry_cnt = 0, retry_cnt_1 = 0;
    161     int SPI_READY = 1;
    162     int wr_data = 0, rd_data = 0;
    163     while ((SPI_READY == 1) && (retry_cnt_1 < Q28_RETRY_CNT)) {
    164         /* Set-up SPI Controller To Receive SPI EEPROM Status.
    165          * Write SPI Control Register Write Command.*/
    166         wr_data = ((Q28_WR_CPU_CTRL_REGS * 0x0100) | 0x1);
    167         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    168         /* Write SPI Control -2 Register Address.*/
    169         wr_data = Q28_SPI_CTRL_2_H;
    170         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    171         
    172         /* Write SPI Control -2 Register Word-2.*/
    173         wr_data = 0x0100;	/* C402 = 0, clear all status. C403 = 1, to enable Done Status.*/
    174         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    175 
    176         /* Fill-up SPI Transmit Fifo To check SPI Status.
    177          * Write SPI Control Register Write Command.*/
    178         /* Write to Transmit Fifo D000-onwards.*/
    179         wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    180         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    181         
    182         /* Write Tx Fifo Register Address.*/
    183         wr_data = Q28_SPI_TXFIFO;
    184         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    185         
    186         /* Write SPI Tx Fifo Control Word-1.*/
    187         wr_data = ((0x0100) | Q28_MSGTYPE_HRD); /* D000 = Only 1 byte Message ( 1byte to transmit for RDSR opcode). */
    188         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    189         
    190         /* Write SPI Tx Fifo Control Word-2.*/
    191         wr_data = Q28_RDSR_OPCODE;                  /* D002 = RDSR Opcode for transmit. */
    192         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    193                 
    194         /* Write SPI Control Register Write Command.*/
    195         wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    196         PHYMOD_IF_ERR_RETURN(quadra28_write_message(pa, wr_data, &rd_data));
    197 
    198         /* Write SPI Control -1 Register Address.*/
    199         wr_data = Q28_SPI_CTRL_1_L;
    200         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    201         
    202         /* Write SPI Control -1 Register Word-1.*/
    203         wr_data = 0x0101;
    204         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    205         
    206         /* Write SPI Control -1 Register Word-2.*/
    207         wr_data = 0x0100;
    208         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    209 
    210         /*Write SPI Control Register Write Command.*/
    211         wr_data = ((Q28_WR_CPU_CTRL_REGS * 0x0100) | 1);
    212         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    213 
    214         /* Write SPI Control -1 Register Address.*/
    215         wr_data = Q28_SPI_CTRL_1_H;
    216         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    217         
    218         /* Write SPI Control -1 Register Word-2.*/
    219         wr_data = 0x0103;
    220         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    221  
    222         do {
    223            wr_data = ((Q28_RD_CPU_CTRL_REGS * 0x0100) | 1);
    224            PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    225            wr_data = Q28_SPI_CTRL_1_L;
    226            PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    227            retry_cnt ++;
    228         } while (((rd_data & 0x0100) == 0) && (retry_cnt < Q28_RETRY_CNT));
    229         if (retry_cnt >= Q28_RETRY_CNT) {
    230             PHYMOD_DIAG_OUT(("ERROR on retry cnt 1 \n"));
    231             return PHYMOD_E_CONFIG;
    232         }
    233         retry_cnt = 0;
    234 
    235         /* Write SPI Control Register Read Command.*/
    236         wr_data = ((Q28_RD_CPU_CTRL_REGS * 0x0100) | 1);
    237         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    238         
    239         /* Write SPI Control -1 Register Address.*/
    240         wr_data = Q28_SPI_RXFIFO;
    241         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    242         
    243         if ((rd_data & 1) == 0) {
    244             SPI_READY = 0;
    245         }
    246         retry_cnt_1 ++;
    247     }
    248     if (retry_cnt_1 >= Q28_RETRY_CNT) {
    249         PHYMOD_DIAG_OUT(("ERROR on retry cnt 2 \n"));
    250         return PHYMOD_E_CONFIG;
    251     }
    252 
    253     return PHYMOD_E_NONE;
    254 }
    255 
    256 int quadra28_rom_dload(const phymod_access_t *pa, uint8_t *new_fw, uint32_t fw_length)
    257 {
    258     int retry_cnt = 0, retry_cnt_1 = 0;
    259     BCMI_QUADRA28_GENERAL_CONTROL_2r_t  gen_ctrl2;
    260     BCMI_QUADRA28_BOOT_CONTROLr_t   boot_ctrl;
    261     BCMI_QUADRA28_GENERAL_CONTROL_1r_t  gen_ctrl1;
    262     BCMI_QUADRA28_MSG_OUTr_t q28_msg_out ;
    263     int wr_data = 0, rd_data = 0, j = 0, i = 0,xfer_size = 0;
    264     uint32_t temp = 0;
    265 
    266     PHYMOD_MEMSET(&q28_msg_out, 0, sizeof(BCMI_QUADRA28_MSG_OUTr_t));
    267     PHYMOD_MEMSET(&gen_ctrl2, 0, sizeof(BCMI_QUADRA28_GENERAL_CONTROL_2r_t));
    268     PHYMOD_MEMSET(&gen_ctrl1, 0, sizeof(BCMI_QUADRA28_GENERAL_CONTROL_1r_t));
    269     PHYMOD_MEMSET(&boot_ctrl, 0, sizeof(BCMI_QUADRA28_BOOT_CONTROLr_t));
    270 
    271     /* clear bit 12 in FFD1 To use Countach address mapping */
    272     PHYMOD_IF_ERR_RETURN(
    273         BCMI_QUADRA28_READ_GENERAL_CONTROL_2r(pa, &gen_ctrl2));
    274     BCMI_QUADRA28_GENERAL_CONTROL_2r_LEGACY_BOOT_SELf_SET(gen_ctrl2, 0);
    275     PHYMOD_IF_ERR_RETURN(
    276         BCMI_QUADRA28_WRITE_GENERAL_CONTROL_2r(pa, gen_ctrl2));
    277 
    278      /* SPI boot from ROM*/
    279     BCMI_QUADRA28_BOOT_CONTROLr_SET(boot_ctrl, 0x4);
    280     PHYMOD_IF_ERR_RETURN(
    281         BCMI_QUADRA28_WRITE_BOOT_CONTROLr(pa, boot_ctrl));
    282 
    283     /* reset micro*/
    284     BCMI_QUADRA28_GENERAL_CONTROL_1r_SET(gen_ctrl1, 1);
    285     PHYMOD_IF_ERR_RETURN(
    286         BCMI_QUADRA28_WRITE_GENERAL_CONTROL_1r(pa, gen_ctrl1));
    287 
    288     /* 5Ms sleep*/
    289     PHYMOD_USLEEP(5000);
    290     BCMI_QUADRA28_GENERAL_CONTROL_1r_SET(gen_ctrl1, 0);
    291     PHYMOD_IF_ERR_RETURN(
    292         BCMI_QUADRA28_WRITE_GENERAL_CONTROL_1r(pa, gen_ctrl1));
    293 
    294     PHYMOD_IF_ERR_RETURN(
    295         BCMI_QUADRA28_READ_GENERAL_CONTROL_2r(pa, &gen_ctrl2));
    296     BCMI_QUADRA28_GENERAL_CONTROL_2r_LEGACY_BOOT_SELf_SET(gen_ctrl2, 0);
    297     PHYMOD_IF_ERR_RETURN(
    298         BCMI_QUADRA28_WRITE_GENERAL_CONTROL_2r(pa, gen_ctrl2));
    299 
    300     /* Sleep for 2 sec*/
    301     PHYMOD_SLEEP(2);
    302 
    303     /* Enable the LASI For Message out.*/
    304     PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(pa, 0x19000, 0x4));
    305     PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_write(pa, 0x19002, 0x4));
    306 
    307     /* De-assert SPI EEPROM Block Protection.
    308      * Write SPI Control Register Write Command.*/
    309     /* Write to C400, C401, C402, C403 Registers.*/
    310     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    311     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    312     if (rd_data != 0xABCD) {
    313         PHYMOD_DIAG_OUT(("ERROR -MSG OUT register 0x%x It should be 0xABCD\n", rd_data));
    314         return PHYMOD_E_CONFIG;
    315     }
    316 
    317     /* Write SPI Control -2 Register Address*/
    318     wr_data = Q28_SPI_CTRL_2_L;
    319     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    320      
    321     /* Write SPI Control -2 Register Word-1.*/
    322     wr_data = 0x8200;	 /* C400 = 0 for 0 Fill Byte. C401 = 02 for SPI Clcok to be divide by 2 and little endian fifo.*/
    323     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    324     if (rd_data != 0xABCD) {
    325        PHYMOD_DIAG_OUT(("ERROR -MSG OUT register 0x%x It should be 0xABCD\n", rd_data));
    326        return PHYMOD_E_CONFIG;
    327     }
    328     
    329     /* Write SPI Control -2 Register Word-2.*/
    330     wr_data = 0x0100;	/* C402 = 0, clear all status. C403 = 1, to enable Done Status.*/
    331     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    332     if (rd_data != 0x4321) {
    333        PHYMOD_DIAG_OUT(("ERROR -MSG OUT register 0x%x It should be 0x4321\n", rd_data));
    334        return PHYMOD_E_CONFIG;
    335     }
    336 
    337     /* Fill-up SPI Transmit Fifo With SPI EEPROM Messages.
    338      * Write SPI Control Register Write Command.*/
    339     /* Write to Transmit Fifo D000-onwards.*/
    340     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 4);
    341     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    342      
    343     /* Write Tx Fifo Register Address.*/
    344     wr_data = Q28_SPI_TXFIFO;	
    345     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    346      
    347     /* Write SPI Tx Fifo Control Word-1.*/
    348     wr_data = (0x0100 | Q28_MSGTYPE_HWR);  /* D000 = Only 1 byte Message ( 1byte to transmit for WREN opcode). */
    349     /* D001 = Write Message And  Higher byte of Transfer Size. */
    350     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    351         
    352     /* Write SPI Tx Fifo Control Word-2.*/
    353     wr_data = ((Q28_MSGTYPE_HWR * 0x0100) | Q28_WREN_OPCODE); /*{MSGTYPE_HWR, WREN_OPCODE}; D002 = WREN Opcode For transmit. */
    354     /* D003 = 2 byte WREN OPCODE Message.*/ 
    355     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    356         
    357     /* Write SPI Tx Fifo Control Word-3.*/
    358     wr_data = ((Q28_WRSR_OPCODE * 0x0100) | 0x02);  /* D004 = For this command transfer size =2 (1 byte opcode, 1 byte wr data),*/
    359     /* D005 = WRSR Opcode.*/
    360     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    361            
    362     /* Write SPI Tx Fifo Control Word-4.*/
    363     wr_data = ((0x02 * 0x0100) | 0x02);     /* D006 = 0x02, byte for status register, 
    364                                               * Bit 7, WPEN = 0, Bit 3:2, BP1:0=0, No block protect, 
    365                                               * Bit 1, WEN = 1, Write Enabled.
    366                                               * D005 = WRSR Opcode.*/
    367     PHYMOD_IF_ERR_RETURN (quadra28_write_message (pa, wr_data, &rd_data));
    368 
    369     /* Write SPI Control Register Write Command.*/
    370     /* Write to SPI Control Register C000 onwards.*/
    371     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    372     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    373 
    374     /* Write SPI Control -1 Register Address.*/
    375     wr_data = Q28_SPI_CTRL_1_L;
    376     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    377      
    378     /* Write SPI Control -1 Register Word-1.*/
    379     wr_data = 0x0101;	/* C000 = 1 to clear CMD Done Status. C001 = 1 to clear CMD Done INT Status.*/
    380     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    381      
    382     /* Write SPI Control -1 Register Word-2.*/
    383     wr_data = 0x0003;	/* C002 = 3, Start Immidiate Command. C003 = 0, No Prepend byte for Write.*/
    384     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    385     
    386     /* Wait For WRSR Command To be written*/
    387     do {
    388         wr_data = ((Q28_RD_CPU_CTRL_REGS * 0x0100) | 1);
    389         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    390         wr_data = Q28_SPI_CTRL_1_L;
    391         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    392         retry_cnt++;
    393     } while (((rd_data & 0x0100) == 0) && (retry_cnt < Q28_RETRY_CNT));
    394     if (retry_cnt >= Q28_RETRY_CNT) {
    395         return PHYMOD_E_CONFIG;
    396     }
    397     retry_cnt = 0;
    398 
    399     PHYMOD_IF_ERR_RETURN(q28_get_spi_eeprom_status(pa));
    400 
    401     for (j = 0 ; j < fw_length; j+= Q28_WR_BLOCK_SIZE) {
    402         /* Setup SPI Controller.*/
    403         /* Write SPI Control Register Write Command.*/
    404         /* Write to C400, C401, C402, C403 Registers.*/
    405         wr_data = ( (Q28_WR_CPU_CTRL_FIFO* 0x0100) | 2);  
    406         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    407     
    408         /* Write SPI Control -2 Register Address.*/
    409         wr_data = Q28_SPI_CTRL_2_L;
    410         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    411         
    412         /* Write SPI Control -2 Register Word-1.*/
    413         wr_data = 0x8200;    /* C400 = 0 for 0 Fill Byte. C401 = 02 for SPI Clcok to be divide by 2 and little endian fifo.*/
    414         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    415 
    416         /* Write SPI Control -2 Register Word-2.*/
    417         wr_data = 0x0100;    /* C402 = 0, clear all status. C403 = 1, to enable Done Status.*/
    418         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    419             
    420         /* Fill-up SPI Transmit Fifo.*/
    421         /* Write SPI Control Register Write Command.*/
    422         wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | (4 + (Q28_WR_BLOCK_SIZE/2)));
    423         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    424         
    425         /* Write Tx Fifo Register Address.*/
    426         wr_data = Q28_SPI_TXFIFO;
    427         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    428         
    429         /* Write SPI Tx Fifo Control Word-1.*/
    430         wr_data = ( 0x0100 | Q28_MSGTYPE_HWR); 
    431         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    432         
    433         /* Write SPI Tx Fifo Control Word-2.*/
    434         wr_data = ((Q28_MSGTYPE_HWR * 0x0100) | Q28_WREN_OPCODE); 
    435         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));          
    436            
    437         
    438         /* Write SPI Tx Fifo Control Word-3.*/
    439         wr_data = ((Q28_WR_OPCODE * 0x0100) | (0x3 + Q28_WR_BLOCK_SIZE));   
    440         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    441            
    442         
    443         /* Write SPI Tx Fifo Control Word-4.*/
    444         wr_data = (((j & 0x00FF) * 0x0100) | ((j & 0xFF00)/ 0x0100));
    445         /* D006 = SPI EEPROM Destination Address (higher byte sent out first). 
    446          * D007 = SPI EEPROM Destination Address (lower byte sent out later).*/
    447         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    448 
    449         xfer_size = fw_length - j;
    450         if ( xfer_size > Q28_WR_BLOCK_SIZE) { 
    451             xfer_size = Q28_WR_BLOCK_SIZE;  
    452         }
    453         for (i = 0 ; i<(xfer_size-1); i+=2) {
    454           	/* Write SPI Tx Fifo Data Word-4.*/
    455           	wr_data = ((new_fw [i+j+1] * 0x0100) | new_fw [i+j]);  /* D008 = Low Byte. D009 = High Byte.*/
    456           	PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    457         }
    458         
    459         /* Set-up SPI Controller To Transmit.*/
    460         /* Write SPI Control Register Write Command.*/
    461         /* Write to SPI Control Register C000 onwards.*/
    462         wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2); 
    463         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    464 
    465         /* Write SPI Control -1 Register Address.*/
    466         wr_data = Q28_SPI_CTRL_1_L;
    467         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    468         
    469         /* Write SPI Control -1 Register Word-1.*/
    470         wr_data = 0x0501;    /* C000 = 1 to clear CMD Done Status. C001 = 1 to clear CMD Done INT Status.*/
    471         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    472         
    473         /* Write SPI Control -1 Register Word-2.*/
    474         wr_data = 0x0003;    /* C002 = 3, Start Immidiate Command. C003 = 0, No Prepend byte for Write.*/
    475         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    476 
    477         /* Wait For 64 bytes To be written. */
    478         if ((j % 2048) == 0) {       
    479             PHYMOD_DIAG_OUT(("INFO -- Write SPI EEPROM at address: 0x%x\n", j));
    480         }
    481         rd_data = 0;
    482         while (((rd_data & 0x0100) == 0) && (retry_cnt < Q28_RETRY_CNT)) { 
    483             /* Write SPI Control Register Read Command.*/
    484             /* Read from SPI Controller register C000.*/
    485             wr_data = ((Q28_RD_CPU_CTRL_REGS * 0x0100) | 1); 
    486             PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    487         
    488             /* Write SPI Control -1 Register Address.*/
    489             wr_data = Q28_SPI_CTRL_1_L;
    490             PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    491             retry_cnt ++; 
    492         }
    493         if (retry_cnt >= Q28_RETRY_CNT) {
    494             return PHYMOD_E_CONFIG;
    495         }
    496         retry_cnt = 0;
    497         PHYMOD_IF_ERR_RETURN(q28_get_spi_eeprom_status(pa));
    498     }
    499     PHYMOD_DIAG_OUT(("INFO -- Completes 0x%x bytes of SPI EEPROM write operation\n", j));
    500 
    501     /* Re-Assert SPI EEPROM Block Protection.*/
    502     /* Write SPI Control Register Write Command.*/
    503     /* Write to C400, C401, C402, C403 Registers.*/
    504     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    505     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    506     
    507     /* Write SPI Control -2 Register Address.*/
    508     wr_data = Q28_SPI_CTRL_2_L;
    509     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    510      
    511     /* Write SPI Control -2 Register Word-1.*/
    512     wr_data = 0x8200;	/* C400 = 0 for 0 Fill Byte. C401 = 02 for SPI Clcok to be divide by 2 and little endian fifo.*/
    513     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    514 
    515     /* Write SPI Control -2 Register Word-2.*/
    516     wr_data = 0x0100;	/* C402 = 0, clear all status. C403 = 1, to enable Done Status.*/
    517     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    518           
    519     /* Fill-up SPI Transmit Fifo With SPI EEPROM Messages.*/
    520     /* Write SPI Control Register Write Command.*/
    521     /* Write to Transmit Fifo D000-onwards.*/
    522     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 4);
    523     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    524      
    525     /* Write Tx Fifo Register Address.*/
    526     wr_data = Q28_SPI_TXFIFO;	/* D000.*/
    527     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    528      
    529     /* Write SPI Tx Fifo Control Word-1.*/
    530     wr_data = (0x0100 | Q28_MSGTYPE_HWR);
    531     /* D000 = Only 1 byte Message ( 1byte to transmit for WREN opcode). */
    532     /* D001 = Write Message And  Higher byte of Transfer Size. */
    533     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    534 
    535     /* Write SPI Tx Fifo Control Word-2.*/
    536     wr_data = ((Q28_MSGTYPE_HWR *  0x0100) | Q28_WREN_OPCODE) ;
    537     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    538     /* D003 = 2 byte WREN OPCODE Message*/
    539         
    540     /* Write SPI Tx Fifo Control Word-3.*/
    541     wr_data = ((Q28_WRSR_OPCODE * 0x0100) | 0x02);
    542     /* D004 = For this command transfer size =2 (1 byte opcode, 1 byte wr data),*/
    543     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    544     /* D005 = WRSR Opcode.*/
    545            
    546     /* Write SPI Tx Fifo Control Word-4.*/
    547     wr_data = ((0x0C * 0x0100) | 0x0C) ;
    548     /* D006 = 0x02, byte for status register, 
    549      * Bit 7, WPEN = 0, Bit 3:2, BP1:0=3, All block protected, 
    550      * Bit 1, WEN = 0, Write Enabled.
    551      * D005 = WRSR Opcode.*/
    552     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    553 
    554     /* Write SPI Control Register Write Command.*/
    555     /* Write to SPI Control Register C000 onwards.*/
    556     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    557     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    558 
    559     /* Write SPI Control -1 Register Address.*/
    560     wr_data = Q28_SPI_CTRL_1_L;
    561     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    562      
    563     /* Write SPI Control -1 Register Word-1.*/
    564     wr_data = 0x0101;	/* C000 = 1 to clear CMD Done Status. C001 = 1 to clear CMD Done INT Status.*/
    565     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    566      
    567      /* Write SPI Control -1 Register Word-2.*/
    568     wr_data = 0x0003;	/* C002 = 3, Start Immidiate Command. C003 = 0, No Prepend byte for Write.*/
    569     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    570 
    571     /* Wait For WRSR Command To be written.          */
    572     rd_data = 0;
    573     while (((rd_data & 0x0100) == 0) && (retry_cnt < Q28_RETRY_CNT)) {
    574         /* Write SPI Control Register Read Command.*/
    575         /*Read from SPI Controller register C000.*/
    576         wr_data = ((Q28_RD_CPU_CTRL_REGS * 0x0100) | 1);
    577         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    578         wr_data = Q28_SPI_CTRL_1_L;
    579         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));
    580         retry_cnt ++;
    581     }
    582     if (retry_cnt >= Q28_RETRY_CNT) {
    583         return PHYMOD_E_CONFIG;
    584     }
    585     retry_cnt = 0;
    586 
    587     PHYMOD_IF_ERR_RETURN(q28_get_spi_eeprom_status(pa));
    588 
    589     /* Disable SPI EEPROM.*/
    590     /* Write SPI Control Register Write Command.*/
    591     /* Write to C400, C401, C402, C403 Registers.*/
    592     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    593     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    594     
    595     /* Write SPI Control -2 Register Address.*/
    596     wr_data = Q28_SPI_CTRL_2_L;
    597     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    598     
    599     /* Write SPI Control -2 Register Word-1.*/
    600     wr_data = 0x8200;	/* C400 = 0 for 0 Fill Byte. C401 = 02 for SPI Clcok to be divide by 2 and little endian fifo.*/
    601     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    602 
    603     /* Write SPI Control -2 Register Word-2.*/
    604     wr_data = 0x0100;	/* C402 = 0, clear all status. C403 = 1, to enable Done Status.*/
    605     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    606     
    607     
    608     /* Fill-up SPI Transmit Fifo With SPI EEPROM Messages.*/
    609     /* Write SPI Control Register Write Command.*/
    610     wr_data = ( (Q28_WR_CPU_CTRL_FIFO* 0x0100) | 2);
    611     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    612     
    613     /* Write Tx Fifo Register Address.*/
    614     wr_data = Q28_SPI_TXFIFO;	   /* D000.*/
    615     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    616     
    617 
    618     /* Write SPI Tx Fifo Control Word-1.*/
    619     wr_data = ((0x0100) | Q28_MSGTYPE_HWR); /* D000 = Only 1 byte Message ( 1byte to transmit for WRDI opcode). */
    620     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data));             /* D001 = Write Message And  Higher byte of Transfer Size.*/
    621 
    622     
    623     /* Write SPI Tx Fifo Control Word-2.*/
    624     wr_data = Q28_WRDI_OPCODE; /* D002 = WRDI Opcode for transmit. */
    625     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    626        
    627     /* Write SPI Control Register Write Command.*/
    628     /* Write to SPI Control Register C000 onwards.*/
    629     wr_data = ((Q28_WR_CPU_CTRL_FIFO * 0x0100) | 2);
    630     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    631 
    632     /* Write SPI Control -1 Register Address.*/
    633     wr_data = Q28_SPI_CTRL_1_L;
    634     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    635     
    636     /* Write SPI Control -1 Register Word-1.*/
    637     wr_data = 0x0101;	/* C000 = 1 to clear CMD Done Status. C001 = 1 to clear CMD Done INT Status.*/
    638     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    639     
    640     /*Write SPI Control -1 Register Word-2.*/
    641     wr_data = 0x0003;	/* C002 = 3, Start Immidiate Command. C003 = 0, No Prepend byte for Write.*/
    642     PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    643 
    644     /* Wait For WRDI Command To be written.*/
    645     rd_data = 0;
    646     while (((rd_data & 0x0100) == 0) && (retry_cnt < Q28_RETRY_CNT)) {
    647        /* Write SPI Control Register Read Command.*/
    648        /* Read from SPI Controller register C000.*/
    649         wr_data = ((Q28_RD_CPU_CTRL_REGS * 0x0100) | 1);
    650         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    651         if (rd_data != 0xABCD) {
    652             PHYMOD_DIAG_OUT(("ERROR -MSG OUT register 0x%x It should be 0xABCD\n", rd_data));
    653             return PHYMOD_E_CONFIG;
    654         }
    655         /* Write SPI Control -1 Register Address.*/
    656         wr_data = Q28_SPI_CTRL_1_L;
    657         PHYMOD_IF_ERR_RETURN(quadra28_write_message (pa, wr_data, &rd_data)); 
    658      
    659         temp = 0x0000;
    660         while (((temp & 0x4) == 0) && (retry_cnt_1 < Q28_RETRY_CNT)) {
    661             PHYMOD_IF_ERR_RETURN(phymod_raw_iblk_read(pa, 0x19005, &temp));
    662             retry_cnt_1 ++;
    663         }
    664         if (retry_cnt_1 >= Q28_RETRY_CNT) {
    665             return PHYMOD_E_CONFIG;
    666         }
    667         retry_cnt_1 = 0;
    668 
    669         PHYMOD_IF_ERR_RETURN(
    670             BCMI_QUADRA28_READ_MSG_OUTr(pa, &q28_msg_out));
    671         wr_data	= BCMI_QUADRA28_MSG_OUTr_GET(q28_msg_out);
    672         retry_cnt ++;
    673     }
    674     if (retry_cnt >= Q28_RETRY_CNT) {
    675         return PHYMOD_E_CONFIG;
    676     }
    677     PHYMOD_DIAG_OUT(("UCODE Downloaded on EEPROM \n"));
    678     return PHYMOD_E_NONE;
    679 }
    680 
    681 int quadra28_before_fw_load(const phymod_core_access_t* core,
    682                             const phymod_core_init_config_t *init_config,
    683                             uint32_t chip_id)
    684 {
    685     phymod_access_t pa;
    686     MDIO_BROADCAST_CONTROLr_t mdio_broadcast_ctrl_reg;
    687     uint16_t index = 0, max_lane = 0;
    688 
    689     max_lane = (chip_id == QUADRA28_82752_CHIP_ID) ? 1 : 3; 
    690     PHYMOD_MEMSET(&mdio_broadcast_ctrl_reg, 0, sizeof(MDIO_BROADCAST_CONTROLr_t));
    691     PHYMOD_MEMCPY(&pa, &core->access, sizeof( phymod_access_t));
    692 
    693     PHYMOD_IF_ERR_RETURN(
    694         _quadra28_clear_mode_config(&pa));
    695     
    696     for (index = 0; index <= max_lane; index++) {
    697         pa.addr &=  ~max_lane;
    698         pa.addr |=  index;
    699         /* Step1: Enable broadcast mode */
    700         PHYMOD_IF_ERR_RETURN
    701             (READ_MDIO_BROADCAST_CONTROLr(&pa, &mdio_broadcast_ctrl_reg));
    702         MDIO_BROADCAST_CONTROLr_MDIO_BCAST_ENf_SET(mdio_broadcast_ctrl_reg, 1);     
    703         PHYMOD_IF_ERR_RETURN
    704             (WRITE_MDIO_BROADCAST_CONTROLr(&pa, mdio_broadcast_ctrl_reg));
    705     }
    706 
    707     return PHYMOD_E_NONE;
    708 }
    709 
    710 int quadra28_bcast_fw_load(const phymod_core_access_t* core,
    711                            const phymod_core_init_config_t *init_config, 
    712                            uint8_t *new_fw,
    713                            uint32_t fw_length)
    714 {
    715     phymod_access_t pa;
    716     GENERAL_CONTROL_2r_t general_ctrl_reg2;
    717     GENERAL_CONTROL_1r_t general_ctrl_reg1;
    718     GEN_CTRLr_t general_ctrl_reg;
    719     SPI_PORT_CONTROL_STATUSr_t spi_port_ctrl_reg;
    720     MSG_INr_t msg_in_reg;
    721     CL73CONTROL8r_t cl73_ctrl8_reg;
    722     uint32_t index = 0;
    723     uint16_t data16;
    724 
    725     PHYMOD_MEMSET(&cl73_ctrl8_reg, 0, sizeof(CL73CONTROL8r_t));
    726     PHYMOD_MEMSET(&general_ctrl_reg1, 0, sizeof(GENERAL_CONTROL_1r_t));
    727     PHYMOD_MEMSET(&general_ctrl_reg, 0, sizeof(GEN_CTRLr_t));
    728     PHYMOD_MEMSET(&spi_port_ctrl_reg, 0, sizeof(BCMI_QUADRA28_SPI_PORT_CONTROL_STATUSr_t));
    729     PHYMOD_MEMSET(&msg_in_reg, 0, sizeof(MSG_INr_t));
    730     PHYMOD_MEMSET(&general_ctrl_reg2, 0, sizeof(GENERAL_CONTROL_2r_t));
    731     PHYMOD_MEMCPY(&pa, &core->access, sizeof( phymod_access_t));
    732    
    733 
    734     /* Set 0xFFD1 to read from MGT-M8051 register */
    735     PHYMOD_IF_ERR_RETURN
    736         (READ_GENERAL_CONTROL_2r(&pa,&general_ctrl_reg2));
    737     GENERAL_CONTROL_2r_LEGACY_BOOT_SELf_SET(general_ctrl_reg2, 1);
    738     
    739     PHYMOD_IF_ERR_RETURN
    740         (WRITE_GENERAL_CONTROL_2r(&pa,general_ctrl_reg2));
    741     PHYMOD_MEMSET(&general_ctrl_reg2, 0, sizeof(GENERAL_CONTROL_2r_t)); 
    742   
    743     /* Step5: Select MDIO interface for microcode download */
    744     PHYMOD_IF_ERR_RETURN
    745         (BCMI_QUADRA28_READ_SPI_PORT_CONTROL_STATUSr(&pa, 
    746             &spi_port_ctrl_reg));
    747 
    748     BCMI_QUADRA28_SPI_PORT_CONTROL_STATUSr_SPI_PORT_USEDf_SET(spi_port_ctrl_reg, 0);                       
    749     BCMI_QUADRA28_SPI_PORT_CONTROL_STATUSr_SPI_BOOTf_SET(spi_port_ctrl_reg, 1);
    750     BCMI_QUADRA28_SPI_PORT_CONTROL_STATUSr_SPI_DWLD_DONEf_SET(spi_port_ctrl_reg, 0);
    751     PHYMOD_IF_ERR_RETURN
    752         (BCMI_QUADRA28_WRITE_SPI_PORT_CONTROL_STATUSr(&pa, 
    753             spi_port_ctrl_reg));    
    754  
    755     /* Step3: Reset MGT-M8051 uc at address 1.FFD0 */
    756     BCMI_QUADRA28_GENERAL_CONTROL_1r_SET(general_ctrl_reg1, 1);
    757     PHYMOD_IF_ERR_RETURN
    758         (WRITE_GENERAL_CONTROL_1r(&pa,
    759             general_ctrl_reg1));
    760 
    761     /* Step2: Reset EDc-M8051 uc at address 1.CA10 */
    762     PHYMOD_IF_ERR_RETURN
    763         (BCMI_QUADRA28_READ_GEN_CTRLr(&pa, &general_ctrl_reg));
    764 
    765     BCMI_QUADRA28_GEN_CTRLr_UCRSTf_SET(general_ctrl_reg, 1);
    766 
    767     PHYMOD_IF_ERR_RETURN
    768         (BCMI_QUADRA28_WRITE_GEN_CTRLr(&pa, general_ctrl_reg));   
    769    
    770            
    771     /* Step8:  Release EDC-M8051 from reset */
    772     PHYMOD_IF_ERR_RETURN
    773         (BCMI_QUADRA28_READ_GEN_CTRLr(&pa, &general_ctrl_reg));
    774     BCMI_QUADRA28_GEN_CTRLr_UCRSTf_SET(general_ctrl_reg, 0);
    775     PHYMOD_IF_ERR_RETURN
    776         (BCMI_QUADRA28_WRITE_GEN_CTRLr(&pa, general_ctrl_reg));
    777     
    778     /* step9: Release MGT_M8051 uc from reset */    
    779     BCMI_QUADRA28_GENERAL_CONTROL_1r_SET(general_ctrl_reg1, 0);
    780     PHYMOD_IF_ERR_RETURN
    781         (WRITE_GENERAL_CONTROL_1r(&pa, general_ctrl_reg1));
    782    
    783     /* step10: wait 1 ms */
    784     PHYMOD_USLEEP(1000);
    785 
    786     /* step11: send initial RAM address */
    787     BCMI_QUADRA28_MSG_INr_SET (msg_in_reg, 0x8000);
    788     PHYMOD_IF_ERR_RETURN
    789        (BCMI_QUADRA28_WRITE_MSG_INr(&pa, msg_in_reg));
    790 
    791     /* step12: wait 15 us */
    792     PHYMOD_USLEEP(20);   
    793    
    794     /* step13: send microcode size to 1.ca12 */
    795     BCMI_QUADRA28_MSG_INr_MESSAGE_INf_SET(msg_in_reg,fw_length/2);
    796     PHYMOD_IF_ERR_RETURN
    797        (BCMI_QUADRA28_WRITE_MSG_INr(&pa, msg_in_reg));
    798 
    799     PHYMOD_USLEEP(20);
    800     /* step15 to step 16: send 16-bit microcode word */
    801     PHYMOD_IF_ERR_RETURN
    802             (BCMI_QUADRA28_READ_MSG_INr(&pa,
    803                 &msg_in_reg)); 
    804     
    805     for (index = 0; index < (fw_length) - 1; index+=2){
    806         data16 = ((new_fw[index] << 8)| new_fw[index+1]);
    807         PHYMOD_USLEEP(15);
    808         BCMI_QUADRA28_MSG_INr_MESSAGE_INf_SET(msg_in_reg,data16);
    809         PHYMOD_IF_ERR_RETURN
    810             (BCMI_QUADRA28_WRITE_MSG_INr(&pa, msg_in_reg));
    811     }
    812     
    813     return PHYMOD_E_NONE;
    814 }
    815 
    816 int quadra28_bcast_after_fw_load(const phymod_core_access_t* core, uint32_t chip_id)
    817 {
    818     uint32_t phy_addr = 0;
    819     uint16_t index = 0, max_lane = 0;
    820     phymod_access_t pa;
    821     GENERAL_CONTROL_2r_t general_ctrl_reg2;
    822     int ret_val = 0;
    823 
    824     PHYMOD_MEMSET(&general_ctrl_reg2, 0, sizeof(GENERAL_CONTROL_2r_t));
    825     PHYMOD_MEMCPY(&pa, &core->access, sizeof( phymod_access_t));
    826     phy_addr = pa.addr;
    827     max_lane = (chip_id == QUADRA28_82752_CHIP_ID) ? 1 : 3; 
    828     PHYMOD_IF_ERR_RETURN
    829        (READ_GENERAL_CONTROL_2r(&pa,&general_ctrl_reg2));
    830     GENERAL_CONTROL_2r_LEGACY_BOOT_SELf_SET(general_ctrl_reg2, 1);
    831     PHYMOD_IF_ERR_RETURN
    832       (WRITE_GENERAL_CONTROL_2r(&pa,general_ctrl_reg2));        
    833 
    834     PHYMOD_USLEEP(4000);
    835     /* Do it from all three locations */
    836     /* if not read, they will be in wait and not update checksum */
    837     /* Q28 3 processors - flip FFD1 bits to read either from MGT-M8051 or EDC-M8051 */
    838     /* Verify for all processors - 3 in each */
    839     /* use phy address for other two EDC-M8051 lanes */
    840     /* Verify checksum on MGT-M8051 for a phy lane */
    841     for (index = 0; index <= max_lane; index+=2) {
    842     int ret_val = 0;
    843          pa.addr &=  ~max_lane;
    844          pa.addr |=  index;
    845          if ((pa.addr & 1) == 0) {
    846             ret_val = _quadra28_verify_fw_download(&pa, 0);
    847             if (ret_val != 0) {
    848                return ret_val;
    849             }
    850          }
    851     }
    852     pa.addr = phy_addr ;
    853     PHYMOD_IF_ERR_RETURN
    854         (READ_GENERAL_CONTROL_2r(&pa,&general_ctrl_reg2));
    855     GENERAL_CONTROL_2r_LEGACY_BOOT_SELf_SET(general_ctrl_reg2, 0);
    856     PHYMOD_IF_ERR_RETURN
    857        (WRITE_GENERAL_CONTROL_2r(&pa,general_ctrl_reg2));        
    858     PHYMOD_USLEEP(4000);
    859     /* Verification for EDC*/
    860     for (index = 0; index <= max_lane; index++) {
    861         pa.addr &=  ~max_lane;
    862         pa.addr |=  index;
    863         ret_val = _quadra28_verify_fw_download(&pa, 1);
    864         if (ret_val != 0) {
    865             return ret_val;
    866         }
    867     }
    868 
    869     return PHYMOD_E_NONE;
    870 }
    871 
    872 int quadra28_bcast_disable(const phymod_core_access_t* core, uint32_t chip_id)
    873 {
    874     phymod_access_t pa;
    875     MDIO_BROADCAST_CONTROLr_t mdio_broadcast_ctrl_reg;
    876     uint16_t index = 0, max_lane = 0;
    877 
    878     max_lane = (chip_id == QUADRA28_82752_CHIP_ID) ? 1 : 3; 
    879     PHYMOD_MEMSET(&mdio_broadcast_ctrl_reg, 0, sizeof(MDIO_BROADCAST_CONTROLr_t));
    880     PHYMOD_MEMCPY(&pa, &core->access, sizeof( phymod_access_t));
    881 
    882     for (index = 0; index <= max_lane; index++) {
    883         pa.addr &=  ~max_lane;
    884         pa.addr |=  index;
    885         /* Step1: Enable broadcast mode */
    886         PHYMOD_IF_ERR_RETURN
    887             (READ_MDIO_BROADCAST_CONTROLr(&pa, &mdio_broadcast_ctrl_reg));
    888         MDIO_BROADCAST_CONTROLr_MDIO_BCAST_ENf_SET(mdio_broadcast_ctrl_reg, 1);     
    889         PHYMOD_IF_ERR_RETURN
    890             (WRITE_MDIO_BROADCAST_CONTROLr(&pa, mdio_broadcast_ctrl_reg));
    891     }
    892 
    893     return PHYMOD_E_NONE;
    894 }
    895