furia_reg_access.c (6210B)
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 /* 11 * Includes 12 */ 13 #include <phymod/phymod_acc.h> 14 #include <phymod/phymod_reg.h> 15 #include "furia_reg_access.h" 16 #include "furia_regs_structs.h" 17 #include "furia_address_defines.h" 18 19 /* 20 * Defines 21 */ 22 #define FORCE_CL45 0x20 23 24 25 /** Read Register 26 * This function is used to read the register content of given 27 * register address 28 * 29 * @param pa Pointer to phymod access structure 30 * @param addr Register address supplied by user 31 * @param data Regiser content/value of the given register 32 * 33 * @return ioerr Error return 34 * 0 - Success 35 * any other value - Error 36 */ 37 int furia_reg_read(const phymod_access_t *pa, uint32_t addr, uint32_t *data) 38 { 39 int ioerr = 0; 40 uint32_t reg_val; 41 uint32_t devad = (addr >> 16) & 0x3f; 42 43 if (pa == NULL) { 44 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("NULL parameter"))); 45 } 46 47 if(devad == 0) { 48 ioerr = PHYMOD_BUS_READ(pa, ((1 << 16) | addr), ®_val); 49 } else { 50 ioerr = PHYMOD_BUS_READ(pa, addr, ®_val); 51 } 52 53 *data = reg_val; 54 return ioerr; 55 } 56 57 /** Write Register 58 * This function is used to write the content to given register 59 * 60 * @param pa Pointer to phymod access structure 61 * @param addr Register address supplied by user 62 * @param data Regiser content/value to be written to register 63 * 64 * @return ioerr Error return 65 * 0 - Success 66 * any other value - Error 67 */ 68 int furia_reg_write(const phymod_access_t *pa, uint32_t addr, uint32_t data) 69 { 70 int ioerr = 0; 71 uint32_t devad = (addr >> 16) & 0xf; 72 73 if (pa == NULL) { 74 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("NULL parameter"))); 75 } 76 77 if((devad == 0) || (pa->devad == 0)) { 78 ioerr = PHYMOD_BUS_WRITE(pa, ((1 << 16) | addr), data); 79 } else { 80 ioerr = PHYMOD_BUS_WRITE(pa, addr, data); 81 } 82 83 84 return ioerr; 85 } 86 87 /** Modify Register 88 * This function is used to modify the content without overwriting it 89 * 90 * @param pa Pointer to phymod access structure 91 * @param addr Register address supplied by user 92 * @param reg_data Regiser data for modified portion 93 * @param reg_mask Register mask for the data bits to be modified 94 * 95 * @return ioerr Error return 96 * 0 - Success 97 * any other value - Error 98 */ 99 int furia_reg_modify(const phymod_access_t *pa, 100 uint32_t addr, 101 uint16_t reg_data, 102 uint16_t reg_mask) 103 { 104 int ioerr = 0; 105 uint32_t reg_val; 106 uint16_t tmp, otmp; 107 108 if (pa == NULL) { 109 PHYMOD_RETURN_WITH_ERR(PHYMOD_E_PARAM, (_PHYMOD_MSG("NULL parameter"))); 110 } 111 112 reg_data = reg_data & reg_mask; 113 114 /* Use clause 45 access if supported */ 115 ioerr += PHYMOD_BUS_READ(pa, addr, ®_val); 116 117 tmp = (uint16_t) (reg_val & 0xffff); 118 otmp = tmp; 119 tmp &= ~(reg_mask); 120 tmp |= reg_data; 121 122 if (otmp != tmp) { 123 ioerr += PHYMOD_BUS_WRITE(pa, addr, tmp); 124 } 125 126 return ioerr; 127 } 128 /** Set slice register 129 * This function is used to set the slice register for indirect 130 * accessing of register 131 * 132 * @param pa Pointer to phymod access structure 133 * @param intf_side Interface side 134 * 0 - Line side 1 - System side 135 * @param wr_lane Write lane information 136 * 0xF - broadcast 137 * 0x3 - multicast01 138 * 0xC - multicast23 139 * 0x8 - ln3 140 * 0x4 - ln2 141 * 0x2 - ln1 142 * 0x1 - ln0 143 * @param rd_lane Read lane information 144 * 0x0 = ReadLane_0 145 * 0x1 = ReadLane_1 146 * 0x2 = ReadLane_2 147 * 0x3 = ReadLane_3 148 * 149 * @return ioerr Error return 150 * 0 - Success 151 * any other value - Error 152 */ 153 int furia_set_slice_reg(const phymod_access_t *pa, 154 uint16_t intf_side, 155 uint16_t wr_lane, 156 uint16_t rd_lane) 157 { 158 int ioerr = 0; 159 DEV1_SLICE_SLICE_t slice; 160 161 if (pa == NULL) { 162 return -1; 163 } 164 ioerr += READ_FURIA_PMA_PMD_REG(pa,\ 165 DEV1_SLICE_slice_Adr,\ 166 &slice.data); 167 slice.fields.sysen = intf_side; 168 slice.fields.wr_lane = wr_lane; 169 slice.fields.rd_lane = rd_lane; 170 if(!pa->devad) { 171 slice.fields.devid = 1; 172 } else { 173 slice.fields.devid = pa->devad; 174 } 175 176 ioerr += WRITE_FURIA_PMA_PMD_REG(pa,\ 177 DEV1_SLICE_slice_Adr,\ 178 slice.data); 179 return ioerr; 180 } 181 int furia_set_an_slice_reg(const phymod_access_t *pa, 182 uint16_t intf_side, 183 uint16_t wr_lane, 184 uint16_t rd_lane) 185 { 186 int ioerr = 0; 187 DEV7_SLICE_SLICE_t slice; 188 189 if (pa == NULL) { 190 return -1; 191 } 192 ioerr += READ_FURIA_PMA_PMD_REG(pa,\ 193 DEV7_SLICE_slice_Adr,\ 194 &slice.data); 195 slice.fields.sysen = intf_side; 196 slice.fields.wr_lane = wr_lane; 197 slice.fields.rd_lane = rd_lane; 198 slice.fields.devid = 7; 199 200 ioerr += WRITE_FURIA_AN_REG(pa,\ 201 DEV7_SLICE_slice_Adr,\ 202 slice.data); 203 return ioerr; 204 }