1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2015-2020
7 #include "txgbe_eeprom.h"
10 * txgbe_init_eeprom_params - Initialize EEPROM params
11 * @hw: pointer to hardware structure
13 * Initializes the EEPROM parameters txgbe_rom_info within the
14 * txgbe_hw struct in order to set up EEPROM access.
16 s32 txgbe_init_eeprom_params(struct txgbe_hw *hw)
18 struct txgbe_rom_info *eeprom = &hw->rom;
23 DEBUGFUNC("txgbe_init_eeprom_params");
25 if (eeprom->type != txgbe_eeprom_unknown)
28 eeprom->type = txgbe_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, TXGBE_SPISTAT);
41 if (!(eec & TXGBE_SPISTAT_BPFLASH)) {
42 eeprom->type = txgbe_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;
54 err = eeprom->read32(hw, TXGBE_SW_REGION_PTR << 1, &eeprom->sw_addr);
56 DEBUGOUT("EEPROM read failed.\n");
60 DEBUGOUT("eeprom params: type = %d, size = %d, address bits: "
61 "%d %d\n", eeprom->type, eeprom->word_size,
62 eeprom->address_bits, eeprom->sw_addr);
68 * txgbe_get_eeprom_semaphore - Get hardware semaphore
69 * @hw: pointer to hardware structure
71 * Sets the hardware semaphores so EEPROM access can occur for bit-bang method
73 s32 txgbe_get_eeprom_semaphore(struct txgbe_hw *hw)
75 s32 status = TXGBE_ERR_EEPROM;
80 DEBUGFUNC("txgbe_get_eeprom_semaphore");
83 /* Get SMBI software semaphore between device drivers first */
84 for (i = 0; i < timeout; i++) {
86 * If the SMBI bit is 0 when we read it, then the bit will be
87 * set and we have the semaphore
89 swsm = rd32(hw, TXGBE_SWSEM);
90 if (!(swsm & TXGBE_SWSEM_PF)) {
98 DEBUGOUT("Driver can't access the eeprom - SMBI Semaphore "
101 * this release is particularly important because our attempts
102 * above to get the semaphore may have succeeded, and if there
103 * was a timeout, we should unconditionally clear the semaphore
104 * bits to free the driver to make progress
106 txgbe_release_eeprom_semaphore(hw);
111 * If the SMBI bit is 0 when we read it, then the bit will be
112 * set and we have the semaphore
114 swsm = rd32(hw, TXGBE_SWSEM);
115 if (!(swsm & TXGBE_SWSEM_PF))
119 /* Now get the semaphore between SW/FW through the SWESMBI bit */
121 for (i = 0; i < timeout; i++) {
122 /* Set the SW EEPROM semaphore bit to request access */
123 wr32m(hw, TXGBE_MNGSWSYNC,
124 TXGBE_MNGSWSYNC_REQ, TXGBE_MNGSWSYNC_REQ);
127 * If we set the bit successfully then we got the
130 swsm = rd32(hw, TXGBE_MNGSWSYNC);
131 if (swsm & TXGBE_MNGSWSYNC_REQ)
138 * Release semaphores and return error if SW EEPROM semaphore
139 * was not granted because we don't have access to the EEPROM
142 DEBUGOUT("SWESMBI Software EEPROM semaphore not granted.\n");
143 txgbe_release_eeprom_semaphore(hw);
144 status = TXGBE_ERR_EEPROM;
147 DEBUGOUT("Software semaphore SMBI between device drivers "
155 * txgbe_release_eeprom_semaphore - Release hardware semaphore
156 * @hw: pointer to hardware structure
158 * This function clears hardware semaphore bits.
160 void txgbe_release_eeprom_semaphore(struct txgbe_hw *hw)
162 DEBUGFUNC("txgbe_release_eeprom_semaphore");
164 wr32m(hw, TXGBE_MNGSWSYNC, TXGBE_MNGSWSYNC_REQ, 0);
165 wr32m(hw, TXGBE_SWSEM, TXGBE_SWSEM_PF, 0);
170 * txgbe_ee_read - Read EEPROM word using a host interface cmd
171 * @hw: pointer to hardware structure
172 * @offset: offset of word in the EEPROM to read
173 * @data: word read from the EEPROM
175 * Reads a 16 bit word from the EEPROM using the hostif.
177 s32 txgbe_ee_read16(struct txgbe_hw *hw, u32 offset,
180 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
181 u32 addr = (offset << 1);
184 err = hw->mac.acquire_swfw_sync(hw, mask);
188 err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
190 hw->mac.release_swfw_sync(hw, mask);
196 * txgbe_ee_readw_buffer- Read EEPROM word(s) using hostif
197 * @hw: pointer to hardware structure
198 * @offset: offset of word in the EEPROM to read
199 * @words: number of words
200 * @data: word(s) read from the EEPROM
202 * Reads a 16 bit word(s) from the EEPROM using the hostif.
204 s32 txgbe_ee_readw_buffer(struct txgbe_hw *hw,
205 u32 offset, u32 words, void *data)
207 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
208 u32 addr = (offset << 1);
209 u32 len = (words << 1);
210 u8 *buf = (u8 *)data;
213 err = hw->mac.acquire_swfw_sync(hw, mask);
218 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
219 ? len : TXGBE_PMMBX_DATA_SIZE);
221 err = txgbe_hic_sr_read(hw, addr, buf, seg);
230 hw->mac.release_swfw_sync(hw, mask);
235 s32 txgbe_ee_readw_sw(struct txgbe_hw *hw, u32 offset,
238 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
239 u32 addr = hw->rom.sw_addr + (offset << 1);
242 err = hw->mac.acquire_swfw_sync(hw, mask);
246 err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 2);
248 hw->mac.release_swfw_sync(hw, mask);
254 * txgbe_ee_read32 - Read EEPROM word using a host interface cmd
255 * @hw: pointer to hardware structure
256 * @offset: offset of word in the EEPROM to read
257 * @data: word read from the EEPROM
259 * Reads a 32 bit word from the EEPROM using the hostif.
261 s32 txgbe_ee_read32(struct txgbe_hw *hw, u32 addr, u32 *data)
263 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
266 err = hw->mac.acquire_swfw_sync(hw, mask);
270 err = txgbe_hic_sr_read(hw, addr, (u8 *)data, 4);
272 hw->mac.release_swfw_sync(hw, mask);
278 * txgbe_ee_write - Write EEPROM word using hostif
279 * @hw: pointer to hardware structure
280 * @offset: offset of word in the EEPROM to write
281 * @data: word write to the EEPROM
283 * Write a 16 bit word to the EEPROM using the hostif.
285 s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset,
288 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
289 u32 addr = (offset << 1);
294 err = hw->mac.acquire_swfw_sync(hw, mask);
298 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
300 hw->mac.release_swfw_sync(hw, mask);
306 * txgbe_ee_writew_buffer - Write EEPROM word(s) using hostif
307 * @hw: pointer to hardware structure
308 * @offset: offset of word in the EEPROM to write
309 * @words: number of words
310 * @data: word(s) write to the EEPROM
312 * Write a 16 bit word(s) to the EEPROM using the hostif.
314 s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw,
315 u32 offset, u32 words, void *data)
317 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
318 u32 addr = (offset << 1);
319 u32 len = (words << 1);
320 u8 *buf = (u8 *)data;
323 err = hw->mac.acquire_swfw_sync(hw, mask);
328 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
329 ? len : TXGBE_PMMBX_DATA_SIZE);
331 err = txgbe_hic_sr_write(hw, addr, buf, seg);
339 hw->mac.release_swfw_sync(hw, mask);
343 s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset,
346 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
347 u32 addr = hw->rom.sw_addr + (offset << 1);
352 err = hw->mac.acquire_swfw_sync(hw, mask);
356 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
358 hw->mac.release_swfw_sync(hw, mask);
364 * txgbe_ee_write32 - Read EEPROM word using a host interface cmd
365 * @hw: pointer to hardware structure
366 * @offset: offset of word in the EEPROM to read
367 * @data: word read from the EEPROM
369 * Reads a 32 bit word from the EEPROM using the hostif.
371 s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data)
373 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
376 err = hw->mac.acquire_swfw_sync(hw, mask);
380 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 4);
382 hw->mac.release_swfw_sync(hw, mask);
388 * txgbe_calc_eeprom_checksum - Calculates and returns the checksum
389 * @hw: pointer to hardware structure
391 * Returns a negative error code on error, or the 16-bit checksum
394 s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw)
396 u16 checksum = 0, read_checksum = 0;
399 u16 buffer[BUFF_SIZE];
401 DEBUGFUNC("txgbe_calc_eeprom_checksum");
403 err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
405 DEBUGOUT("EEPROM read failed\n");
409 for (i = 0; i < TXGBE_EE_CSUM_MAX; i += seg) {
410 seg = (i + BUFF_SIZE < TXGBE_EE_CSUM_MAX
411 ? BUFF_SIZE : TXGBE_EE_CSUM_MAX - i);
412 err = hw->rom.readw_buffer(hw, i, seg, buffer);
415 for (j = 0; j < seg; j++)
416 checksum += buffer[j];
419 checksum = (u16)TXGBE_EEPROM_SUM - checksum + read_checksum;
421 return (s32)checksum;
425 * txgbe_validate_eeprom_checksum - Validate EEPROM checksum
426 * @hw: pointer to hardware structure
427 * @checksum_val: calculated checksum
429 * Performs checksum calculation and validates the EEPROM checksum. If the
430 * caller does not need checksum_val, the value can be NULL.
432 s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw,
436 u16 read_checksum = 0;
439 DEBUGFUNC("txgbe_validate_eeprom_checksum");
441 /* Read the first word from the EEPROM. If this times out or fails, do
442 * not continue or we could be in for a very long wait while every
445 err = hw->rom.read16(hw, 0, &checksum);
447 DEBUGOUT("EEPROM read failed\n");
451 err = hw->rom.calc_checksum(hw);
455 checksum = (u16)(err & 0xffff);
457 err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
459 DEBUGOUT("EEPROM read failed\n");
463 /* Verify read checksum from EEPROM is the same as
464 * calculated checksum
466 if (read_checksum != checksum) {
467 err = TXGBE_ERR_EEPROM_CHECKSUM;
468 DEBUGOUT("EEPROM checksum error\n");
471 /* If the user cares, return the calculated checksum */
473 *checksum_val = checksum;
479 * txgbe_update_eeprom_checksum - Updates the EEPROM checksum
480 * @hw: pointer to hardware structure
482 s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw)
487 DEBUGFUNC("txgbe_update_eeprom_checksum");
489 /* Read the first word from the EEPROM. If this times out or fails, do
490 * not continue or we could be in for a very long wait while every
493 status = hw->rom.read16(hw, 0, &checksum);
495 DEBUGOUT("EEPROM read failed\n");
499 status = hw->rom.calc_checksum(hw);
503 checksum = (u16)(status & 0xffff);
505 status = hw->rom.writew_sw(hw, TXGBE_EEPROM_CHECKSUM, checksum);