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