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

merlin16_dependencies.c (7966B)


      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  *  This file implements Switch specific Bus access to the PMD.
      7 */
      8 
      9 #include "common/srds_api_err_code.h"
     10 #include "common/srds_api_types.h"
     11 #include "merlin16_common.h"
     12 #include "merlin16_dependencies.h"
     13 #include <phymod/acc/phymod_tsc_iblk.h>
     14 #include <phymod/phymod.h> 
     15 #include <phymod/phymod_system.h>
     16 
     17 
     18 /** Read a register from the currently selected Serdes IP Lane.
     19  * @param sa__ is an opaque state vector passed through to device access functions.
     20  * @param address Address of register to be read
     21  * @param *val value read out from the register
     22  * @return Error code generated by read function (returns ERR_CODE_NONE if no errors)
     23  */
     24 err_code_t merlin16_pmd_rdt_reg(srds_access_t *sa__, uint16_t address, uint16_t *val)
     25 {
     26     uint32_t data;
     27     phymod_tsc_iblk_read(sa__, (PHYMOD_REG_ACC_TSC_IBLK | 0x10000 | (uint32_t) address), &data);
     28     data = data & 0xffff; 
     29     *val = (uint16_t)data;
     30     return ( 0 );
     31 }
     32 
     33 /** Write to a register from the currently selected Serdes IP Lane.
     34  * @param sa__ is an opaque state vector passed through to device access functions.
     35  * @param address Address of register to be written
     36  * @param val Value to be written to the register
     37  * @return Error code generated by write function (returns ERR_CODE_NONE if no errors)
     38  */
     39 err_code_t merlin16_pmd_wr_reg(srds_access_t *sa__, uint16_t address, uint16_t val)
     40 {
     41     uint32_t data = 0xffff & val;
     42     uint32_t error_code;
     43     error_code = phymod_tsc_iblk_write(sa__, (PHYMOD_REG_ACC_TSC_IBLK | 0x10000 | (uint32_t) address), data);
     44     if(error_code)
     45       return  ERR_CODE_DATA_NOTAVAIL; 
     46     return  ERR_CODE_NONE; 
     47 }
     48 
     49 /** Masked Register Write to the currently selected Serdes IP core/lane.
     50  * If using Serdes MDIO controller to access the registers, implement this function using merlin16_pmd_mdio_mwr_reg(..)
     51  *
     52  * If NOT using a Serdes MDIO controller or the Serdes PMI Masked write feature, please use the following code to
     53  * implement this function
     54  *
     55  *    merlin16_pmd_wr_reg(addr, ((merlin16_pmd_rd_reg(addr) & ~mask) | (mask & (val << lsb))));
     56  *
     57  * @param sa__ is an opaque state vector passed through to device access functions.
     58  * @param addr Address of register to be written
     59  * @param mask 16-bit mask indicating the position of the field with bits of 1s
     60  * @param lsb  LSB of the field
     61  * @param val  16bit value to be written
     62  * @return Error code generated by write function (returns ERR_CODE_NONE if no errors)
     63  */
     64 err_code_t merlin16_pmd_mwr_reg(srds_access_t *sa__, uint16_t addr, uint16_t mask, uint8_t lsb, uint16_t val)
     65 {
     66     uint32_t mymask = (uint32_t)mask;
     67     phymod_access_t sa_copy;    
     68     uint32_t i;
     69     uint32_t error_code;
     70     
     71     uint32_t data = ((mymask << 16) & 0xffff0000) | val << lsb;
     72 
     73     error_code=0;
     74     PHYMOD_MEMCPY(&sa_copy, sa__, sizeof(srds_access_t));
     75     for(i=1; i <= 0x8; i = i << 1) {
     76         if(i & sa__->lane_mask) {
     77             sa_copy.lane_mask = i;
     78             error_code+=phymod_tsc_iblk_write(&sa_copy, (PHYMOD_REG_ACC_TSC_IBLK | 0x10000 | (uint32_t) addr), data);
     79         }
     80     }
     81     if(error_code)
     82         return  ERR_CODE_DATA_NOTAVAIL; 
     83     return ERR_CODE_NONE; 
     84 }
     85 
     86 /** Write to a PRAM location for the currently selected Serdes IP Core.
     87  *  The address is auto-incrementing, per the PRAM interface specification.
     88  * @param sa__ is an opaque state vector passed through to device access functions.
     89  * @param val Value to be written
     90  * @return Error code generated by write function (returns ERR_CODE_NONE if no errors)
     91  */
     92 err_code_t merlin16_pmd_wr_pram(srds_access_t *sa__, uint8_t val)
     93 {
     94     return ERR_CODE_NONE;
     95 }
     96 
     97 /** Write message to the logger with the designated verbose level.
     98  * Output is sent to stdout and a logfile
     99  * @param message_verbose_level   Verbose level for the current message
    100  * @param *format Format string as in printf
    101  * @param ... Additional variables used as in printf
    102  * @return Error code generated by function (returns ERR_CODE_NONE if no errors)
    103  */
    104 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT
    105 int logger_write(srds_access_t *sa__, int message_verbose_level, const char *format, ...)
    106 {
    107     return ERR_CODE_NONE;
    108 }
    109 #endif
    110 
    111 /** Delay the execution of the code for atleast specified amount of time in nanoseconds.
    112  * This function is used ONLY for delays less than 1 microsecond, non-zero error code may be returned otherwise.
    113  * The user can implement this as an empty function if their register access latency exceeds 1 microsecond.
    114  * @param delay_ns Delay in nanoseconds
    115  * @return Error code generated by delay function (returns ERR_CODE_NONE if no errors)
    116  */
    117 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT
    118 err_code_t merlin16_delay_ns(srds_access_t *sa__, uint16_t delay_ns)
    119 {
    120     uint32_t delay;
    121     delay = delay_ns / 1000; 
    122     if(!delay) {
    123         delay = 1;
    124     }
    125     PHYMOD_USLEEP(delay);
    126     return 0;
    127 }
    128 #else
    129 err_code_t merlin16_delay_ns(uint16_t delay_ns)
    130 {
    131     uint32_t delay;
    132     delay = delay_ns / 1000; 
    133     if(!delay) {
    134         delay = 1;
    135     }
    136     PHYMOD_USLEEP(delay);
    137     return 0;
    138 }
    139 #endif
    140 
    141 /** Delay the execution of the code for atleast specified amount of time in microseconds.
    142  * For longer delays, accuracy is required. When requested delay is > 100ms, the implemented delay is assumed
    143  * to be < 10% bigger than requested.
    144  * This function is used ONLY for delays greater than or equal to 1 microsecond.
    145  * @param delay_us Delay in microseconds
    146  * @return Error code generated by delay function (returns ERR_CODE_NONE if no errors)
    147  */
    148 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT
    149 err_code_t merlin16_delay_us(srds_access_t *sa__, uint32_t delay_us)
    150 {
    151     PHYMOD_USLEEP(delay_us);
    152     return 0;
    153 }
    154 #else
    155 err_code_t merlin16_delay_us(uint32_t delay_us)
    156 {
    157     PHYMOD_USLEEP(delay_us);
    158     return 0;
    159 }
    160 #endif
    161 
    162 /** Delay the execution of the code for atleast specified amount of time in milliseconds.
    163  * For longer delays, accuracy is required. When requested delay is > 100ms, the implemented delay is assumed
    164  * to be < 10% bigger than requested.
    165  * This function is used ONLY for delays greater than or equal to 1 millisecond.
    166  * @param delay_ms Delay in milliseconds
    167  * @return Error code generated by delay function (returns ERR_CODE_NONE if no errors)
    168  */
    169 #ifdef SRDS_API_ALL_FUNCTIONS_HAVE_ACCESS_STRUCT
    170 err_code_t merlin16_delay_ms(srds_access_t *sa__, uint32_t delay_ms)
    171 {
    172     return 0;
    173 }
    174 #else
    175 err_code_t merlin16_delay_ms(uint32_t delay_ms)
    176 {
    177     uint32_t delay;
    178     delay = delay_ms * 1000;
    179     if (!delay ) {
    180         delay = 1;
    181     }
    182     PHYMOD_USLEEP(delay);
    183     return ( 0 );
    184 }
    185 #endif
    186 
    187 /** Return the address of current selected Serdes IP Core.
    188  * @param sa__ is an opaque state vector passed through to device access functions.
    189  * @return the IP level address of the current core.
    190  */
    191 uint8_t merlin16_get_core(srds_access_t *sa__)
    192 {
    193     return 0;
    194 }
    195 
    196 /** Return the address of current selected Serdes IP lane.
    197  * @param sa__ is an opaque state vector passed through to device access functions.
    198  * @return the IP level address of the current lane. 0 to N-1, for an N lane IP
    199  */
    200 uint8_t merlin16_get_lane(srds_access_t *sa__)
    201 {
    202     if(sa__->lane_mask == 0x1) {
    203         return 0;
    204     } else if(sa__->lane_mask == 0x2) {
    205         return 1;
    206     } else if(sa__->lane_mask == 0x4) {
    207         return 2;
    208     } else if(sa__->lane_mask == 0x8) {
    209         return 3;
    210     } else {
    211         return 0;
    212     }
    213 }
    214 
    215 /** Set the address of current selected Serdes IP lane.  Used in diagnostic
    216  * and core-level management functions.
    217  * @param sa__ is an opaque state vector passed through to device access functions.
    218  * @param lane_index is the lane index
    219  * @return Any error code generated during execution; ERR_CODE NONE otherwise.
    220  */
    221 err_code_t merlin16_set_lane(srds_access_t *sa__, uint8_t lane_index)
    222 {
    223     return ERR_CODE_NONE;
    224 }
    225 
    226