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_pcieg3_dependencies.c (8213B)


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