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_read_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_read_buffer - Read EEPROM byte(s) using hostif
279 * @hw: pointer to hardware structure
280 * @addr: offset of bytes in the EEPROM to read
281 * @len: number of bytes
282 * @data: byte(s) read from the EEPROM
284 * Reads a 8 bit byte(s) from the EEPROM using the hostif.
286 s32 txgbe_ee_read_buffer(struct txgbe_hw *hw,
287 u32 addr, u32 len, void *data)
289 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
290 u8 *buf = (u8 *)data;
293 err = hw->mac.acquire_swfw_sync(hw, mask);
298 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
299 ? len : TXGBE_PMMBX_DATA_SIZE);
301 err = txgbe_hic_sr_read(hw, addr, buf, seg);
309 hw->mac.release_swfw_sync(hw, mask);
314 * txgbe_ee_write - Write EEPROM word using hostif
315 * @hw: pointer to hardware structure
316 * @offset: offset of word in the EEPROM to write
317 * @data: word write to the EEPROM
319 * Write a 16 bit word to the EEPROM using the hostif.
321 s32 txgbe_ee_write16(struct txgbe_hw *hw, u32 offset,
324 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
325 u32 addr = (offset << 1);
330 err = hw->mac.acquire_swfw_sync(hw, mask);
334 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
336 hw->mac.release_swfw_sync(hw, mask);
342 * txgbe_ee_write_buffer - Write EEPROM word(s) using hostif
343 * @hw: pointer to hardware structure
344 * @offset: offset of word in the EEPROM to write
345 * @words: number of words
346 * @data: word(s) write to the EEPROM
348 * Write a 16 bit word(s) to the EEPROM using the hostif.
350 s32 txgbe_ee_writew_buffer(struct txgbe_hw *hw,
351 u32 offset, u32 words, void *data)
353 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
354 u32 addr = (offset << 1);
355 u32 len = (words << 1);
356 u8 *buf = (u8 *)data;
359 err = hw->mac.acquire_swfw_sync(hw, mask);
364 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
365 ? len : TXGBE_PMMBX_DATA_SIZE);
367 err = txgbe_hic_sr_write(hw, addr, buf, seg);
375 hw->mac.release_swfw_sync(hw, mask);
379 s32 txgbe_ee_writew_sw(struct txgbe_hw *hw, u32 offset,
382 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
383 u32 addr = hw->rom.sw_addr + (offset << 1);
388 err = hw->mac.acquire_swfw_sync(hw, mask);
392 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 2);
394 hw->mac.release_swfw_sync(hw, mask);
400 * txgbe_ee_write32 - Read EEPROM word using a host interface cmd
401 * @hw: pointer to hardware structure
402 * @offset: offset of word in the EEPROM to read
403 * @data: word read from the EEPROM
405 * Reads a 32 bit word from the EEPROM using the hostif.
407 s32 txgbe_ee_write32(struct txgbe_hw *hw, u32 addr, u32 data)
409 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
412 err = hw->mac.acquire_swfw_sync(hw, mask);
416 err = txgbe_hic_sr_write(hw, addr, (u8 *)&data, 4);
418 hw->mac.release_swfw_sync(hw, mask);
424 * txgbe_ee_write_buffer - Write EEPROM byte(s) using hostif
425 * @hw: pointer to hardware structure
426 * @addr: offset of bytes in the EEPROM to write
427 * @len: number of bytes
428 * @data: word(s) write to the EEPROM
430 * Write a 8 bit byte(s) to the EEPROM using the hostif.
432 s32 txgbe_ee_write_buffer(struct txgbe_hw *hw,
433 u32 addr, u32 len, void *data)
435 const u32 mask = TXGBE_MNGSEM_SWMBX | TXGBE_MNGSEM_SWFLASH;
436 u8 *buf = (u8 *)data;
439 err = hw->mac.acquire_swfw_sync(hw, mask);
444 u32 seg = (len <= TXGBE_PMMBX_DATA_SIZE
445 ? len : TXGBE_PMMBX_DATA_SIZE);
447 err = txgbe_hic_sr_write(hw, addr, buf, seg);
455 hw->mac.release_swfw_sync(hw, mask);
460 * txgbe_calc_eeprom_checksum - Calculates and returns the checksum
461 * @hw: pointer to hardware structure
463 * Returns a negative error code on error, or the 16-bit checksum
466 s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw)
468 u16 checksum = 0, read_checksum = 0;
471 u16 buffer[BUFF_SIZE];
473 DEBUGFUNC("txgbe_calc_eeprom_checksum");
475 err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
477 DEBUGOUT("EEPROM read failed\n");
481 for (i = 0; i < TXGBE_EE_CSUM_MAX; i += seg) {
482 seg = (i + BUFF_SIZE < TXGBE_EE_CSUM_MAX
483 ? BUFF_SIZE : TXGBE_EE_CSUM_MAX - i);
484 err = hw->rom.readw_buffer(hw, i, seg, buffer);
487 for (j = 0; j < seg; j++)
488 checksum += buffer[j];
491 checksum = (u16)TXGBE_EEPROM_SUM - checksum + read_checksum;
493 return (s32)checksum;
497 * txgbe_validate_eeprom_checksum - Validate EEPROM checksum
498 * @hw: pointer to hardware structure
499 * @checksum_val: calculated checksum
501 * Performs checksum calculation and validates the EEPROM checksum. If the
502 * caller does not need checksum_val, the value can be NULL.
504 s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw,
508 u16 read_checksum = 0;
511 DEBUGFUNC("txgbe_validate_eeprom_checksum");
513 /* Read the first word from the EEPROM. If this times out or fails, do
514 * not continue or we could be in for a very long wait while every
517 err = hw->rom.read16(hw, 0, &checksum);
519 DEBUGOUT("EEPROM read failed\n");
523 err = hw->rom.calc_checksum(hw);
527 checksum = (u16)(err & 0xffff);
529 err = hw->rom.readw_sw(hw, TXGBE_EEPROM_CHECKSUM, &read_checksum);
531 DEBUGOUT("EEPROM read failed\n");
535 /* Verify read checksum from EEPROM is the same as
536 * calculated checksum
538 if (read_checksum != checksum) {
539 err = TXGBE_ERR_EEPROM_CHECKSUM;
540 DEBUGOUT("EEPROM checksum error\n");
543 /* If the user cares, return the calculated checksum */
545 *checksum_val = checksum;
551 * txgbe_update_eeprom_checksum - Updates the EEPROM checksum
552 * @hw: pointer to hardware structure
554 s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw)
559 DEBUGFUNC("txgbe_update_eeprom_checksum");
561 /* Read the first word from the EEPROM. If this times out or fails, do
562 * not continue or we could be in for a very long wait while every
565 status = hw->rom.read16(hw, 0, &checksum);
567 DEBUGOUT("EEPROM read failed\n");
571 status = hw->rom.calc_checksum(hw);
575 checksum = (u16)(status & 0xffff);
577 status = hw->rom.writew_sw(hw, TXGBE_EEPROM_CHECKSUM, checksum);