1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3 * Copyright(c) 2010-2017 Intel Corporation
8 #include "ngbe_eeprom.h"
11 * ngbe_init_eeprom_params - Initialize EEPROM params
12 * @hw: pointer to hardware structure
14 * Initializes the EEPROM parameters ngbe_rom_info within the
15 * ngbe_hw struct in order to set up EEPROM access.
17 s32 ngbe_init_eeprom_params(struct ngbe_hw *hw)
19 struct ngbe_rom_info *eeprom = &hw->rom;
23 DEBUGFUNC("ngbe_init_eeprom_params");
25 if (eeprom->type != ngbe_eeprom_unknown)
28 eeprom->type = ngbe_eeprom_none;
29 /* Set default semaphore delay to 10ms which is a well
32 eeprom->semaphore_delay = 10; /*ms*/
33 /* Clear EEPROM page size, it will be initialized as needed */
34 eeprom->word_page_size = 0;
37 * Check for EEPROM present first.
38 * If not present leave as none
40 eec = rd32(hw, NGBE_SPISTAT);
41 if (!(eec & NGBE_SPISTAT_BPFLASH)) {
42 eeprom->type = ngbe_eeprom_flash;
45 * SPI EEPROM is assumed here. This code would need to
46 * change if a future EEPROM is not SPI.
49 eeprom->word_size = eeprom_size >> 1;
52 eeprom->address_bits = 16;
53 eeprom->sw_addr = 0x80;
55 DEBUGOUT("eeprom params: type = %d, size = %d, address bits: "
56 "%d %d\n", eeprom->type, eeprom->word_size,
57 eeprom->address_bits, eeprom->sw_addr);
63 * ngbe_get_eeprom_semaphore - Get hardware semaphore
64 * @hw: pointer to hardware structure
66 * Sets the hardware semaphores so EEPROM access can occur for bit-bang method
68 s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw)
70 s32 status = NGBE_ERR_EEPROM;
75 DEBUGFUNC("ngbe_get_eeprom_semaphore");
78 /* Get SMBI software semaphore between device drivers first */
79 for (i = 0; i < timeout; i++) {
81 * If the SMBI bit is 0 when we read it, then the bit will be
82 * set and we have the semaphore
84 swsm = rd32(hw, NGBE_SWSEM);
85 if (!(swsm & NGBE_SWSEM_PF)) {
93 DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore "
96 * this release is particularly important because our attempts
97 * above to get the semaphore may have succeeded, and if there
98 * was a timeout, we should unconditionally clear the semaphore
99 * bits to free the driver to make progress
101 ngbe_release_eeprom_semaphore(hw);
106 * If the SMBI bit is 0 when we read it, then the bit will be
107 * set and we have the semaphore
109 swsm = rd32(hw, NGBE_SWSEM);
110 if (!(swsm & NGBE_SWSEM_PF))
114 /* Now get the semaphore between SW/FW through the SWESMBI bit */
116 for (i = 0; i < timeout; i++) {
117 /* Set the SW EEPROM semaphore bit to request access */
118 wr32m(hw, NGBE_MNGSWSYNC,
119 NGBE_MNGSWSYNC_REQ, NGBE_MNGSWSYNC_REQ);
122 * If we set the bit successfully then we got the
125 swsm = rd32(hw, NGBE_MNGSWSYNC);
126 if (swsm & NGBE_MNGSWSYNC_REQ)
133 * Release semaphores and return error if SW EEPROM semaphore
134 * was not granted because we don't have access to the EEPROM
137 DEBUGOUT("SWESMBI Software EEPROM semaphore not granted.\n");
138 ngbe_release_eeprom_semaphore(hw);
139 status = NGBE_ERR_EEPROM;
142 DEBUGOUT("Software semaphore SMBI between device drivers "
150 * ngbe_release_eeprom_semaphore - Release hardware semaphore
151 * @hw: pointer to hardware structure
153 * This function clears hardware semaphore bits.
155 void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw)
157 DEBUGFUNC("ngbe_release_eeprom_semaphore");
159 wr32m(hw, NGBE_MNGSWSYNC, NGBE_MNGSWSYNC_REQ, 0);
160 wr32m(hw, NGBE_SWSEM, NGBE_SWSEM_PF, 0);
165 * ngbe_ee_read_buffer- Read EEPROM word(s) using hostif
166 * @hw: pointer to hardware structure
167 * @offset: offset of word in the EEPROM to read
168 * @words: number of words
169 * @data: word(s) read from the EEPROM
171 * Reads a 16 bit word(s) from the EEPROM using the hostif.
173 s32 ngbe_ee_readw_buffer(struct ngbe_hw *hw,
174 u32 offset, u32 words, void *data)
176 const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH;
177 u32 addr = (offset << 1);
178 u32 len = (words << 1);
179 u8 *buf = (u8 *)data;
182 err = hw->mac.acquire_swfw_sync(hw, mask);
187 u32 seg = (len <= NGBE_PMMBX_DATA_SIZE
188 ? len : NGBE_PMMBX_DATA_SIZE);
190 err = ngbe_hic_sr_read(hw, addr, buf, seg);
199 hw->mac.release_swfw_sync(hw, mask);
204 * ngbe_ee_read32 - Read EEPROM word using a host interface cmd
205 * @hw: pointer to hardware structure
206 * @offset: offset of word in the EEPROM to read
207 * @data: word read from the EEPROM
209 * Reads a 32 bit word from the EEPROM using the hostif.
211 s32 ngbe_ee_read32(struct ngbe_hw *hw, u32 addr, u32 *data)
213 const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH;
216 err = hw->mac.acquire_swfw_sync(hw, mask);
220 err = ngbe_hic_sr_read(hw, addr, (u8 *)data, 4);
222 hw->mac.release_swfw_sync(hw, mask);
228 * ngbe_ee_write_buffer - Write EEPROM word(s) using hostif
229 * @hw: pointer to hardware structure
230 * @offset: offset of word in the EEPROM to write
231 * @words: number of words
232 * @data: word(s) write to the EEPROM
234 * Write a 16 bit word(s) to the EEPROM using the hostif.
236 s32 ngbe_ee_writew_buffer(struct ngbe_hw *hw,
237 u32 offset, u32 words, void *data)
239 const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH;
240 u32 addr = (offset << 1);
241 u32 len = (words << 1);
242 u8 *buf = (u8 *)data;
245 err = hw->mac.acquire_swfw_sync(hw, mask);
250 u32 seg = (len <= NGBE_PMMBX_DATA_SIZE
251 ? len : NGBE_PMMBX_DATA_SIZE);
253 err = ngbe_hic_sr_write(hw, addr, buf, seg);
261 hw->mac.release_swfw_sync(hw, mask);
266 * ngbe_validate_eeprom_checksum_em - Validate EEPROM checksum
267 * @hw: pointer to hardware structure
268 * @checksum_val: calculated checksum
270 * Performs checksum calculation and validates the EEPROM checksum. If the
271 * caller does not need checksum_val, the value can be NULL.
273 s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw,
276 u32 eeprom_cksum_devcap = 0;
279 DEBUGFUNC("ngbe_validate_eeprom_checksum_em");
280 UNREFERENCED_PARAMETER(checksum_val);
282 /* Check EEPROM only once */
283 if (hw->bus.lan_id == 0) {
284 wr32(hw, NGBE_CALSUM_CAP_STATUS, 0x0);
285 wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, 0x0);
287 eeprom_cksum_devcap = rd32(hw, NGBE_CALSUM_CAP_STATUS);
288 hw->rom.saved_version = rd32(hw, NGBE_EEPROM_VERSION_STORE_REG);
291 if (hw->bus.lan_id == 0 || eeprom_cksum_devcap == 0) {
292 err = ngbe_hic_check_cap(hw);
295 "The EEPROM checksum is not valid: %d", err);
300 hw->rom.cksum_devcap = eeprom_cksum_devcap & 0xffff;
306 * ngbe_save_eeprom_version
307 * @hw: pointer to hardware structure
309 * Save off EEPROM version number and Option Rom version which
310 * together make a unique identify for the eeprom
312 s32 ngbe_save_eeprom_version(struct ngbe_hw *hw)
316 u32 offset = (hw->rom.sw_addr + NGBE_EEPROM_VERSION_L) << 1;
318 DEBUGFUNC("ngbe_save_eeprom_version");
320 if (hw->bus.lan_id == 0) {
321 hw->rom.read32(hw, offset, &eeprom_verl);
322 etrack_id = eeprom_verl;
323 wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, etrack_id);
324 wr32(hw, NGBE_CALSUM_CAP_STATUS,
325 hw->rom.cksum_devcap | 0x10000);
326 } else if (hw->rom.cksum_devcap) {
327 etrack_id = hw->rom.saved_version;
329 hw->rom.read32(hw, offset, &eeprom_verl);
330 etrack_id = eeprom_verl;
333 hw->eeprom_id = etrack_id;