1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018 Intel Corporation */
8 * igc_poll_eerd_eewr_done - Poll for EEPROM read/write completion
9 * @hw: pointer to the HW structure
10 * @ee_reg: EEPROM flag for polling
12 * Polls the EEPROM status bit for either read or write completion based
13 * upon the value of 'ee_reg'.
15 static s32
igc_poll_eerd_eewr_done(struct igc_hw
*hw
, int ee_reg
)
17 s32 ret_val
= -IGC_ERR_NVM
;
18 u32 attempts
= 100000;
21 for (i
= 0; i
< attempts
; i
++) {
22 if (ee_reg
== IGC_NVM_POLL_READ
)
27 if (reg
& IGC_NVM_RW_REG_DONE
) {
39 * igc_acquire_nvm - Generic request for access to EEPROM
40 * @hw: pointer to the HW structure
42 * Set the EEPROM access request bit and wait for EEPROM access grant bit.
43 * Return successful if access grant bit set, else clear the request for
44 * EEPROM access and return -IGC_ERR_NVM (-1).
46 s32
igc_acquire_nvm(struct igc_hw
*hw
)
48 s32 timeout
= IGC_NVM_GRANT_ATTEMPTS
;
49 u32 eecd
= rd32(IGC_EECD
);
52 wr32(IGC_EECD
, eecd
| IGC_EECD_REQ
);
53 eecd
= rd32(IGC_EECD
);
56 if (eecd
& IGC_EECD_GNT
)
59 eecd
= rd32(IGC_EECD
);
64 eecd
&= ~IGC_EECD_REQ
;
66 hw_dbg("Could not acquire NVM grant\n");
67 ret_val
= -IGC_ERR_NVM
;
74 * igc_release_nvm - Release exclusive access to EEPROM
75 * @hw: pointer to the HW structure
77 * Stop any current commands to the EEPROM and clear the EEPROM request bit.
79 void igc_release_nvm(struct igc_hw
*hw
)
83 eecd
= rd32(IGC_EECD
);
84 eecd
&= ~IGC_EECD_REQ
;
89 * igc_read_nvm_eerd - Reads EEPROM using EERD register
90 * @hw: pointer to the HW structure
91 * @offset: offset of word in the EEPROM to read
92 * @words: number of words to read
93 * @data: word read from the EEPROM
95 * Reads a 16 bit word from the EEPROM using the EERD register.
97 s32
igc_read_nvm_eerd(struct igc_hw
*hw
, u16 offset
, u16 words
, u16
*data
)
99 struct igc_nvm_info
*nvm
= &hw
->nvm
;
103 /* A check for invalid values: offset too large, too many words,
104 * and not enough words.
106 if (offset
>= nvm
->word_size
|| (words
> (nvm
->word_size
- offset
)) ||
108 hw_dbg("nvm parameter(s) out of bounds\n");
109 ret_val
= -IGC_ERR_NVM
;
113 for (i
= 0; i
< words
; i
++) {
114 eerd
= ((offset
+ i
) << IGC_NVM_RW_ADDR_SHIFT
) +
115 IGC_NVM_RW_REG_START
;
117 wr32(IGC_EERD
, eerd
);
118 ret_val
= igc_poll_eerd_eewr_done(hw
, IGC_NVM_POLL_READ
);
122 data
[i
] = (rd32(IGC_EERD
) >> IGC_NVM_RW_REG_DATA
);
130 * igc_read_mac_addr - Read device MAC address
131 * @hw: pointer to the HW structure
133 s32
igc_read_mac_addr(struct igc_hw
*hw
)
139 rar_high
= rd32(IGC_RAH(0));
140 rar_low
= rd32(IGC_RAL(0));
142 for (i
= 0; i
< IGC_RAL_MAC_ADDR_LEN
; i
++)
143 hw
->mac
.perm_addr
[i
] = (u8
)(rar_low
>> (i
* 8));
145 for (i
= 0; i
< IGC_RAH_MAC_ADDR_LEN
; i
++)
146 hw
->mac
.perm_addr
[i
+ 4] = (u8
)(rar_high
>> (i
* 8));
148 for (i
= 0; i
< ETH_ALEN
; i
++)
149 hw
->mac
.addr
[i
] = hw
->mac
.perm_addr
[i
];
155 * igc_validate_nvm_checksum - Validate EEPROM checksum
156 * @hw: pointer to the HW structure
158 * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
159 * and then verifies that the sum of the EEPROM is equal to 0xBABA.
161 s32
igc_validate_nvm_checksum(struct igc_hw
*hw
)
167 for (i
= 0; i
< (NVM_CHECKSUM_REG
+ 1); i
++) {
168 ret_val
= hw
->nvm
.ops
.read(hw
, i
, 1, &nvm_data
);
170 hw_dbg("NVM Read Error\n");
173 checksum
+= nvm_data
;
176 if (checksum
!= (u16
)NVM_SUM
) {
177 hw_dbg("NVM Checksum Invalid\n");
178 ret_val
= -IGC_ERR_NVM
;
187 * igc_update_nvm_checksum - Update EEPROM checksum
188 * @hw: pointer to the HW structure
190 * Updates the EEPROM checksum by reading/adding each word of the EEPROM
191 * up to the checksum. Then calculates the EEPROM checksum and writes the
192 * value to the EEPROM.
194 s32
igc_update_nvm_checksum(struct igc_hw
*hw
)
200 for (i
= 0; i
< NVM_CHECKSUM_REG
; i
++) {
201 ret_val
= hw
->nvm
.ops
.read(hw
, i
, 1, &nvm_data
);
203 hw_dbg("NVM Read Error while updating checksum.\n");
206 checksum
+= nvm_data
;
208 checksum
= (u16
)NVM_SUM
- checksum
;
209 ret_val
= hw
->nvm
.ops
.write(hw
, NVM_CHECKSUM_REG
, 1, &checksum
);
211 hw_dbg("NVM Write Error while updating checksum.\n");