Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3 : : * Copyright(c) 2010-2017 Intel Corporation
4 : : */
5 : :
6 : : #include "ngbe_hw.h"
7 : : #include "ngbe_mng.h"
8 : : #include "ngbe_eeprom.h"
9 : :
10 : : /**
11 : : * ngbe_init_eeprom_params - Initialize EEPROM params
12 : : * @hw: pointer to hardware structure
13 : : *
14 : : * Initializes the EEPROM parameters ngbe_rom_info within the
15 : : * ngbe_hw struct in order to set up EEPROM access.
16 : : **/
17 : 0 : s32 ngbe_init_eeprom_params(struct ngbe_hw *hw)
18 : : {
19 : : struct ngbe_rom_info *eeprom = &hw->rom;
20 : : u32 eec;
21 : : u16 eeprom_size;
22 : :
23 [ # # ]: 0 : if (eeprom->type != ngbe_eeprom_unknown)
24 : : return 0;
25 : :
26 : 0 : eeprom->type = ngbe_eeprom_none;
27 : : /* Set default semaphore delay to 10ms which is a well
28 : : * tested value
29 : : */
30 : 0 : eeprom->semaphore_delay = 10; /*ms*/
31 : : /* Clear EEPROM page size, it will be initialized as needed */
32 : 0 : eeprom->word_page_size = 0;
33 : :
34 : : /*
35 : : * Check for EEPROM present first.
36 : : * If not present leave as none
37 : : */
38 : : eec = rd32(hw, NGBE_SPISTAT);
39 [ # # ]: 0 : if (!(eec & NGBE_SPISTAT_BPFLASH)) {
40 : 0 : eeprom->type = ngbe_eeprom_flash;
41 : :
42 : : /*
43 : : * SPI EEPROM is assumed here. This code would need to
44 : : * change if a future EEPROM is not SPI.
45 : : */
46 : : eeprom_size = 4096;
47 : 0 : eeprom->word_size = eeprom_size >> 1;
48 : : }
49 : :
50 : 0 : eeprom->address_bits = 16;
51 : 0 : eeprom->sw_addr = 0x80;
52 : :
53 : 0 : DEBUGOUT("eeprom params: type = %d, size = %d, address bits: %d %d",
54 : : eeprom->type, eeprom->word_size,
55 : : eeprom->address_bits, eeprom->sw_addr);
56 : :
57 : 0 : return 0;
58 : : }
59 : :
60 : : /**
61 : : * ngbe_get_eeprom_semaphore - Get hardware semaphore
62 : : * @hw: pointer to hardware structure
63 : : *
64 : : * Sets the hardware semaphores so EEPROM access can occur for bit-bang method
65 : : **/
66 : 0 : s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw)
67 : : {
68 : : s32 status = NGBE_ERR_EEPROM;
69 : : u32 timeout = 2000;
70 : : u32 i;
71 : : u32 swsm;
72 : :
73 : : /* Get SMBI software semaphore between device drivers first */
74 [ # # ]: 0 : for (i = 0; i < timeout; i++) {
75 : : /*
76 : : * If the SMBI bit is 0 when we read it, then the bit will be
77 : : * set and we have the semaphore
78 : : */
79 : : swsm = rd32(hw, NGBE_SWSEM);
80 [ # # ]: 0 : if (!(swsm & NGBE_SWSEM_PF)) {
81 : : status = 0;
82 : : break;
83 : : }
84 : 0 : usec_delay(50);
85 : : }
86 : :
87 [ # # ]: 0 : if (i == timeout) {
88 : 0 : DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore not granted.");
89 : : /*
90 : : * this release is particularly important because our attempts
91 : : * above to get the semaphore may have succeeded, and if there
92 : : * was a timeout, we should unconditionally clear the semaphore
93 : : * bits to free the driver to make progress
94 : : */
95 : 0 : ngbe_release_eeprom_semaphore(hw);
96 : :
97 : 0 : usec_delay(50);
98 : : /*
99 : : * one last try
100 : : * If the SMBI bit is 0 when we read it, then the bit will be
101 : : * set and we have the semaphore
102 : : */
103 : : swsm = rd32(hw, NGBE_SWSEM);
104 [ # # ]: 0 : if (!(swsm & NGBE_SWSEM_PF))
105 : : status = 0;
106 : : }
107 : :
108 : 0 : return status;
109 : : }
110 : :
111 : : /**
112 : : * ngbe_release_eeprom_semaphore - Release hardware semaphore
113 : : * @hw: pointer to hardware structure
114 : : *
115 : : * This function clears hardware semaphore bits.
116 : : **/
117 : 0 : void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw)
118 : : {
119 : : wr32m(hw, NGBE_SWSEM, NGBE_SWSEM_PF, 0);
120 : : ngbe_flush(hw);
121 : 0 : }
122 : :
123 : : /**
124 : : * ngbe_ee_read_buffer- Read EEPROM word(s) using hostif
125 : : * @hw: pointer to hardware structure
126 : : * @offset: offset of word in the EEPROM to read
127 : : * @words: number of words
128 : : * @data: word(s) read from the EEPROM
129 : : *
130 : : * Reads a 16 bit word(s) from the EEPROM using the hostif.
131 : : **/
132 : 0 : s32 ngbe_ee_readw_buffer(struct ngbe_hw *hw,
133 : : u32 offset, u32 words, void *data)
134 : : {
135 : : const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH;
136 : 0 : u32 addr = (offset << 1);
137 : 0 : u32 len = (words << 1);
138 : : u8 *buf = (u8 *)data;
139 : : int err;
140 : :
141 : 0 : err = hw->mac.acquire_swfw_sync(hw, mask);
142 [ # # ]: 0 : if (err)
143 : : return err;
144 : :
145 [ # # ]: 0 : while (len) {
146 : 0 : u32 seg = (len <= NGBE_PMMBX_DATA_SIZE
147 : : ? len : NGBE_PMMBX_DATA_SIZE);
148 : :
149 : 0 : err = ngbe_hic_sr_read(hw, addr, buf, seg);
150 [ # # ]: 0 : if (err)
151 : : break;
152 : :
153 : 0 : len -= seg;
154 : 0 : addr += seg;
155 : 0 : buf += seg;
156 : : }
157 : :
158 : 0 : hw->mac.release_swfw_sync(hw, mask);
159 : 0 : return err;
160 : : }
161 : :
162 : : /**
163 : : * ngbe_ee_read32 - Read EEPROM word using a host interface cmd
164 : : * @hw: pointer to hardware structure
165 : : * @offset: offset of word in the EEPROM to read
166 : : * @data: word read from the EEPROM
167 : : *
168 : : * Reads a 32 bit word from the EEPROM using the hostif.
169 : : **/
170 : 0 : s32 ngbe_ee_read32(struct ngbe_hw *hw, u32 addr, u32 *data)
171 : : {
172 : : const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH;
173 : : int err;
174 : :
175 : 0 : err = hw->mac.acquire_swfw_sync(hw, mask);
176 [ # # ]: 0 : if (err)
177 : : return err;
178 : :
179 : 0 : err = ngbe_hic_sr_read(hw, addr, (u8 *)data, 4);
180 : :
181 : 0 : hw->mac.release_swfw_sync(hw, mask);
182 : :
183 : 0 : return err;
184 : : }
185 : :
186 : : /**
187 : : * ngbe_ee_write_buffer - Write EEPROM word(s) using hostif
188 : : * @hw: pointer to hardware structure
189 : : * @offset: offset of word in the EEPROM to write
190 : : * @words: number of words
191 : : * @data: word(s) write to the EEPROM
192 : : *
193 : : * Write a 16 bit word(s) to the EEPROM using the hostif.
194 : : **/
195 : 0 : s32 ngbe_ee_writew_buffer(struct ngbe_hw *hw,
196 : : u32 offset, u32 words, void *data)
197 : : {
198 : : const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH;
199 : 0 : u32 addr = (offset << 1);
200 : 0 : u32 len = (words << 1);
201 : : u8 *buf = (u8 *)data;
202 : : int err;
203 : :
204 : 0 : err = hw->mac.acquire_swfw_sync(hw, mask);
205 [ # # ]: 0 : if (err)
206 : : return err;
207 : :
208 [ # # ]: 0 : while (len) {
209 : 0 : u32 seg = (len <= NGBE_PMMBX_DATA_SIZE
210 : : ? len : NGBE_PMMBX_DATA_SIZE);
211 : :
212 : 0 : err = ngbe_hic_sr_write(hw, addr, buf, seg);
213 [ # # ]: 0 : if (err)
214 : : break;
215 : :
216 : 0 : len -= seg;
217 : 0 : buf += seg;
218 : : }
219 : :
220 : 0 : hw->mac.release_swfw_sync(hw, mask);
221 : 0 : return err;
222 : : }
223 : :
224 : : /**
225 : : * ngbe_validate_eeprom_checksum_em - Validate EEPROM checksum
226 : : * @hw: pointer to hardware structure
227 : : * @checksum_val: calculated checksum
228 : : *
229 : : * Performs checksum calculation and validates the EEPROM checksum. If the
230 : : * caller does not need checksum_val, the value can be NULL.
231 : : **/
232 : 0 : s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw,
233 : : u16 *checksum_val)
234 : : {
235 : : u32 eeprom_cksum_devcap = 0;
236 : : int err = 0;
237 : :
238 : : UNREFERENCED_PARAMETER(checksum_val);
239 : :
240 : : /* Check EEPROM only once */
241 [ # # ]: 0 : if (hw->bus.lan_id == 0) {
242 : : wr32(hw, NGBE_CALSUM_CAP_STATUS, 0x0);
243 : : wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, 0x0);
244 : : } else {
245 : : eeprom_cksum_devcap = rd32(hw, NGBE_CALSUM_CAP_STATUS);
246 : 0 : hw->rom.saved_version = rd32(hw, NGBE_EEPROM_VERSION_STORE_REG);
247 : : }
248 : :
249 [ # # # # ]: 0 : if (hw->bus.lan_id == 0 || eeprom_cksum_devcap == 0) {
250 : 0 : err = ngbe_hic_check_cap(hw);
251 [ # # ]: 0 : if (err != 0) {
252 : 0 : PMD_INIT_LOG(ERR,
253 : : "The EEPROM checksum is not valid: %d", err);
254 : 0 : return -EIO;
255 : : }
256 : : }
257 : :
258 : 0 : hw->rom.cksum_devcap = eeprom_cksum_devcap & 0xffff;
259 : :
260 : 0 : return err;
261 : : }
262 : :
263 : : /**
264 : : * ngbe_save_eeprom_version
265 : : * @hw: pointer to hardware structure
266 : : *
267 : : * Save off EEPROM version number and Option Rom version which
268 : : * together make a unique identify for the eeprom
269 : : */
270 : 0 : s32 ngbe_save_eeprom_version(struct ngbe_hw *hw)
271 : : {
272 : 0 : u32 eeprom_verl = 0;
273 : : u32 etrack_id = 0;
274 : 0 : u32 offset = (hw->rom.sw_addr + NGBE_EEPROM_VERSION_L) << 1;
275 : :
276 [ # # ]: 0 : if (hw->bus.lan_id == 0) {
277 : 0 : hw->rom.read32(hw, offset, &eeprom_verl);
278 : 0 : etrack_id = eeprom_verl;
279 : : wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, etrack_id);
280 : 0 : wr32(hw, NGBE_CALSUM_CAP_STATUS,
281 : 0 : hw->rom.cksum_devcap | 0x10000);
282 [ # # ]: 0 : } else if (hw->rom.cksum_devcap) {
283 : 0 : etrack_id = hw->rom.saved_version;
284 : : } else {
285 : 0 : hw->rom.read32(hw, offset, &eeprom_verl);
286 : 0 : etrack_id = eeprom_verl;
287 : : }
288 : :
289 : 0 : hw->eeprom_id = etrack_id;
290 : :
291 : 0 : return 0;
292 : : }
|