blob: 9f32c781c4741a33196e69bc410dfd7cb94455a2 [file] [log] [blame]
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +00001/*******************************************************************************
2
3 Intel(R) Gigabit Ethernet Linux driver
Akeem G. Abodunrin4b9ea462013-01-08 18:31:12 +00004 Copyright(c) 2007-2013 Intel Corporation.
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +00005
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Contact Information:
23 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25
26******************************************************************************/
27
28/* e1000_i210
29 * e1000_i211
30 */
31
32#include <linux/types.h>
33#include <linux/if_ether.h>
34
35#include "e1000_hw.h"
36#include "e1000_i210.h"
37
Jeff Kirsher167f3f72014-02-25 17:58:56 -080038static s32 igb_update_flash_i210(struct e1000_hw *hw);
39
Carolyn Wyborny7916a532012-11-21 04:44:10 +000040/**
41 * igb_get_hw_semaphore_i210 - Acquire hardware semaphore
42 * @hw: pointer to the HW structure
43 *
44 * Acquire the HW semaphore to access the PHY or NVM
45 */
46static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
47{
48 u32 swsm;
Carolyn Wyborny7916a532012-11-21 04:44:10 +000049 s32 timeout = hw->nvm.word_size + 1;
50 s32 i = 0;
51
Matthew Vickd44e7a92013-03-22 07:34:20 +000052 /* Get the SW semaphore */
53 while (i < timeout) {
54 swsm = rd32(E1000_SWSM);
55 if (!(swsm & E1000_SWSM_SMBI))
56 break;
57
58 udelay(50);
59 i++;
60 }
61
62 if (i == timeout) {
63 /* In rare circumstances, the SW semaphore may already be held
64 * unintentionally. Clear the semaphore once before giving up.
65 */
66 if (hw->dev_spec._82575.clear_semaphore_once) {
67 hw->dev_spec._82575.clear_semaphore_once = false;
68 igb_put_hw_semaphore(hw);
69 for (i = 0; i < timeout; i++) {
70 swsm = rd32(E1000_SWSM);
71 if (!(swsm & E1000_SWSM_SMBI))
72 break;
73
74 udelay(50);
75 }
76 }
77
78 /* If we do not have the semaphore here, we have to give up. */
79 if (i == timeout) {
80 hw_dbg("Driver can't access device - SMBI bit is set.\n");
81 return -E1000_ERR_NVM;
82 }
83 }
84
Carolyn Wyborny7916a532012-11-21 04:44:10 +000085 /* Get the FW semaphore. */
86 for (i = 0; i < timeout; i++) {
87 swsm = rd32(E1000_SWSM);
88 wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
89
90 /* Semaphore acquired if bit latched */
91 if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
92 break;
93
94 udelay(50);
95 }
96
97 if (i == timeout) {
98 /* Release semaphores */
99 igb_put_hw_semaphore(hw);
100 hw_dbg("Driver can't access the NVM\n");
Matthew Vickd44e7a92013-03-22 07:34:20 +0000101 return -E1000_ERR_NVM;
Carolyn Wyborny7916a532012-11-21 04:44:10 +0000102 }
103
Matthew Vickd44e7a92013-03-22 07:34:20 +0000104 return E1000_SUCCESS;
Carolyn Wyborny7916a532012-11-21 04:44:10 +0000105}
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000106
107/**
108 * igb_acquire_nvm_i210 - Request for access to EEPROM
109 * @hw: pointer to the HW structure
110 *
111 * Acquire the necessary semaphores for exclusive access to the EEPROM.
112 * Set the EEPROM access request bit and wait for EEPROM access grant bit.
113 * Return successful if access grant bit set, else clear the request for
114 * EEPROM access and return -E1000_ERR_NVM (-1).
115 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800116static s32 igb_acquire_nvm_i210(struct e1000_hw *hw)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000117{
118 return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
119}
120
121/**
122 * igb_release_nvm_i210 - Release exclusive access to EEPROM
123 * @hw: pointer to the HW structure
124 *
125 * Stop any current commands to the EEPROM and clear the EEPROM request bit,
126 * then release the semaphores acquired.
127 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800128static void igb_release_nvm_i210(struct e1000_hw *hw)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000129{
130 igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
131}
132
133/**
134 * igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
135 * @hw: pointer to the HW structure
136 * @mask: specifies which semaphore to acquire
137 *
138 * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
139 * will also specify which port we're acquiring the lock for.
140 **/
141s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
142{
143 u32 swfw_sync;
144 u32 swmask = mask;
145 u32 fwmask = mask << 16;
146 s32 ret_val = E1000_SUCCESS;
147 s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
148
149 while (i < timeout) {
150 if (igb_get_hw_semaphore_i210(hw)) {
151 ret_val = -E1000_ERR_SWFW_SYNC;
152 goto out;
153 }
154
155 swfw_sync = rd32(E1000_SW_FW_SYNC);
Matthew Vickd44e7a92013-03-22 07:34:20 +0000156 if (!(swfw_sync & (fwmask | swmask)))
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000157 break;
158
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000159 /* Firmware currently using resource (fwmask) */
Matthew Vickd44e7a92013-03-22 07:34:20 +0000160 igb_put_hw_semaphore(hw);
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000161 mdelay(5);
162 i++;
163 }
164
165 if (i == timeout) {
166 hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
167 ret_val = -E1000_ERR_SWFW_SYNC;
168 goto out;
169 }
170
171 swfw_sync |= swmask;
172 wr32(E1000_SW_FW_SYNC, swfw_sync);
173
Matthew Vickd44e7a92013-03-22 07:34:20 +0000174 igb_put_hw_semaphore(hw);
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000175out:
176 return ret_val;
177}
178
179/**
180 * igb_release_swfw_sync_i210 - Release SW/FW semaphore
181 * @hw: pointer to the HW structure
182 * @mask: specifies which semaphore to acquire
183 *
184 * Release the SW/FW semaphore used to access the PHY or NVM. The mask
185 * will also specify which port we're releasing the lock for.
186 **/
187void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
188{
189 u32 swfw_sync;
190
191 while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
192 ; /* Empty */
193
194 swfw_sync = rd32(E1000_SW_FW_SYNC);
195 swfw_sync &= ~mask;
196 wr32(E1000_SW_FW_SYNC, swfw_sync);
197
Matthew Vickd44e7a92013-03-22 07:34:20 +0000198 igb_put_hw_semaphore(hw);
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000199}
200
201/**
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000202 * igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
203 * @hw: pointer to the HW structure
204 * @offset: offset of word in the Shadow Ram to read
205 * @words: number of words to read
206 * @data: word read from the Shadow Ram
207 *
208 * Reads a 16 bit word from the Shadow Ram using the EERD register.
209 * Uses necessary synchronization semaphores.
210 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800211static s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
212 u16 *data)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000213{
214 s32 status = E1000_SUCCESS;
215 u16 i, count;
216
217 /* We cannot hold synchronization semaphores for too long,
218 * because of forceful takeover procedure. However it is more efficient
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000219 * to read in bursts than synchronizing access for each word.
220 */
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000221 for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
222 count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
223 E1000_EERD_EEWR_MAX_COUNT : (words - i);
224 if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
225 status = igb_read_nvm_eerd(hw, offset, count,
226 data + i);
227 hw->nvm.ops.release(hw);
228 } else {
229 status = E1000_ERR_SWFW_SYNC;
230 }
231
232 if (status != E1000_SUCCESS)
233 break;
234 }
235
236 return status;
237}
238
239/**
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000240 * igb_write_nvm_srwr - Write to Shadow Ram using EEWR
241 * @hw: pointer to the HW structure
242 * @offset: offset within the Shadow Ram to be written to
243 * @words: number of words to write
244 * @data: 16 bit word(s) to be written to the Shadow Ram
245 *
246 * Writes data to Shadow Ram at offset using EEWR register.
247 *
248 * If igb_update_nvm_checksum is not called after this function , the
249 * Shadow Ram will most likely contain an invalid checksum.
250 **/
251static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
252 u16 *data)
253{
254 struct e1000_nvm_info *nvm = &hw->nvm;
255 u32 i, k, eewr = 0;
256 u32 attempts = 100000;
257 s32 ret_val = E1000_SUCCESS;
258
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000259 /* A check for invalid values: offset too large, too many words,
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000260 * too many words for the offset, and not enough words.
261 */
262 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
263 (words == 0)) {
264 hw_dbg("nvm parameter(s) out of bounds\n");
265 ret_val = -E1000_ERR_NVM;
266 goto out;
267 }
268
269 for (i = 0; i < words; i++) {
270 eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
271 (data[i] << E1000_NVM_RW_REG_DATA) |
272 E1000_NVM_RW_REG_START;
273
274 wr32(E1000_SRWR, eewr);
275
276 for (k = 0; k < attempts; k++) {
277 if (E1000_NVM_RW_REG_DONE &
278 rd32(E1000_SRWR)) {
279 ret_val = E1000_SUCCESS;
280 break;
281 }
282 udelay(5);
283 }
284
285 if (ret_val != E1000_SUCCESS) {
286 hw_dbg("Shadow RAM write EEWR timed out\n");
287 break;
288 }
289 }
290
291out:
292 return ret_val;
293}
294
295/**
Carolyn Wyborny7916a532012-11-21 04:44:10 +0000296 * igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
297 * @hw: pointer to the HW structure
298 * @offset: offset within the Shadow RAM to be written to
299 * @words: number of words to write
300 * @data: 16 bit word(s) to be written to the Shadow RAM
301 *
302 * Writes data to Shadow RAM at offset using EEWR register.
303 *
304 * If e1000_update_nvm_checksum is not called after this function , the
305 * data will not be committed to FLASH and also Shadow RAM will most likely
306 * contain an invalid checksum.
307 *
308 * If error code is returned, data and Shadow RAM may be inconsistent - buffer
309 * partially written.
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000310 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800311static s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
312 u16 *data)
Carolyn Wyborny7916a532012-11-21 04:44:10 +0000313{
314 s32 status = E1000_SUCCESS;
315 u16 i, count;
316
317 /* We cannot hold synchronization semaphores for too long,
318 * because of forceful takeover procedure. However it is more efficient
319 * to write in bursts than synchronizing access for each word.
320 */
321 for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
322 count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
323 E1000_EERD_EEWR_MAX_COUNT : (words - i);
324 if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
325 status = igb_write_nvm_srwr(hw, offset, count,
326 data + i);
327 hw->nvm.ops.release(hw);
328 } else {
329 status = E1000_ERR_SWFW_SYNC;
330 }
331
332 if (status != E1000_SUCCESS)
333 break;
334 }
335
336 return status;
337}
338
339/**
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000340 * igb_read_invm_word_i210 - Reads OTP
341 * @hw: pointer to the HW structure
342 * @address: the word address (aka eeprom offset) to read
343 * @data: pointer to the data read
344 *
345 * Reads 16-bit words from the OTP. Return error when the word is not
346 * stored in OTP.
347 **/
348static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
349{
350 s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
351 u32 invm_dword;
352 u16 i;
353 u8 record_type, word_address;
354
355 for (i = 0; i < E1000_INVM_SIZE; i++) {
356 invm_dword = rd32(E1000_INVM_DATA_REG(i));
357 /* Get record type */
358 record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
359 if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
360 break;
361 if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
362 i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
363 if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
364 i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
365 if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
366 word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
367 if (word_address == address) {
368 *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
369 hw_dbg("Read INVM Word 0x%02x = %x",
370 address, *data);
371 status = E1000_SUCCESS;
372 break;
373 }
374 }
375 }
376 if (status != E1000_SUCCESS)
377 hw_dbg("Requested word 0x%02x not found in OTP\n", address);
378 return status;
379}
380
381/**
382 * igb_read_invm_i210 - Read invm wrapper function for I210/I211
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000383 * @hw: pointer to the HW structure
Akeem G. Abodunrin5c17a202013-01-29 10:15:31 +0000384 * @words: number of words to read
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000385 * @data: pointer to the data read
386 *
387 * Wrapper function to return data formerly found in the NVM.
388 **/
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000389static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
390 u16 words __always_unused, u16 *data)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000391{
392 s32 ret_val = E1000_SUCCESS;
393
394 /* Only the MAC addr is required to be present in the iNVM */
395 switch (offset) {
396 case NVM_MAC_ADDR:
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000397 ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]);
398 ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1,
399 &data[1]);
400 ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2,
401 &data[2]);
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000402 if (ret_val != E1000_SUCCESS)
403 hw_dbg("MAC Addr not found in iNVM\n");
404 break;
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000405 case NVM_INIT_CTRL_2:
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000406 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
Carolyn Wyborny1720ee32012-10-11 02:15:45 +0000407 if (ret_val != E1000_SUCCESS) {
408 *data = NVM_INIT_CTRL_2_DEFAULT_I211;
409 ret_val = E1000_SUCCESS;
410 }
411 break;
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000412 case NVM_INIT_CTRL_4:
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000413 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
Carolyn Wyborny1720ee32012-10-11 02:15:45 +0000414 if (ret_val != E1000_SUCCESS) {
415 *data = NVM_INIT_CTRL_4_DEFAULT_I211;
416 ret_val = E1000_SUCCESS;
417 }
418 break;
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000419 case NVM_LED_1_CFG:
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000420 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
Carolyn Wyborny1720ee32012-10-11 02:15:45 +0000421 if (ret_val != E1000_SUCCESS) {
422 *data = NVM_LED_1_CFG_DEFAULT_I211;
423 ret_val = E1000_SUCCESS;
424 }
425 break;
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000426 case NVM_LED_0_2_CFG:
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000427 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
Carolyn Wyborny1720ee32012-10-11 02:15:45 +0000428 if (ret_val != E1000_SUCCESS) {
429 *data = NVM_LED_0_2_CFG_DEFAULT_I211;
430 ret_val = E1000_SUCCESS;
431 }
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000432 break;
Carolyn Wyborny1720ee32012-10-11 02:15:45 +0000433 case NVM_ID_LED_SETTINGS:
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000434 ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
Carolyn Wyborny1720ee32012-10-11 02:15:45 +0000435 if (ret_val != E1000_SUCCESS) {
436 *data = ID_LED_RESERVED_FFFF;
437 ret_val = E1000_SUCCESS;
438 }
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000439 case NVM_SUB_DEV_ID:
440 *data = hw->subsystem_device_id;
441 break;
442 case NVM_SUB_VEN_ID:
443 *data = hw->subsystem_vendor_id;
444 break;
445 case NVM_DEV_ID:
446 *data = hw->device_id;
447 break;
448 case NVM_VEN_ID:
449 *data = hw->vendor_id;
450 break;
451 default:
452 hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
453 *data = NVM_RESERVED_WORD;
454 break;
455 }
456 return ret_val;
457}
458
459/**
Carolyn Wyborny09e77282012-10-23 13:04:37 +0000460 * igb_read_invm_version - Reads iNVM version and image type
461 * @hw: pointer to the HW structure
462 * @invm_ver: version structure for the version read
463 *
464 * Reads iNVM version and image type.
465 **/
466s32 igb_read_invm_version(struct e1000_hw *hw,
467 struct e1000_fw_version *invm_ver) {
468 u32 *record = NULL;
469 u32 *next_record = NULL;
470 u32 i = 0;
471 u32 invm_dword = 0;
472 u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
473 E1000_INVM_RECORD_SIZE_IN_BYTES);
474 u32 buffer[E1000_INVM_SIZE];
475 s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
476 u16 version = 0;
477
478 /* Read iNVM memory */
479 for (i = 0; i < E1000_INVM_SIZE; i++) {
480 invm_dword = rd32(E1000_INVM_DATA_REG(i));
481 buffer[i] = invm_dword;
482 }
483
484 /* Read version number */
485 for (i = 1; i < invm_blocks; i++) {
486 record = &buffer[invm_blocks - i];
487 next_record = &buffer[invm_blocks - i + 1];
488
489 /* Check if we have first version location used */
490 if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
491 version = 0;
492 status = E1000_SUCCESS;
493 break;
494 }
495 /* Check if we have second version location used */
496 else if ((i == 1) &&
497 ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
498 version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
499 status = E1000_SUCCESS;
500 break;
501 }
502 /* Check if we have odd version location
503 * used and it is the last one used
504 */
505 else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
506 ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
507 (i != 1))) {
508 version = (*next_record & E1000_INVM_VER_FIELD_TWO)
509 >> 13;
510 status = E1000_SUCCESS;
511 break;
512 }
513 /* Check if we have even version location
514 * used and it is the last one used
515 */
516 else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
517 ((*record & 0x3) == 0)) {
518 version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
519 status = E1000_SUCCESS;
520 break;
521 }
522 }
523
524 if (status == E1000_SUCCESS) {
525 invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
526 >> E1000_INVM_MAJOR_SHIFT;
527 invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
528 }
529 /* Read Image Type */
530 for (i = 1; i < invm_blocks; i++) {
531 record = &buffer[invm_blocks - i];
532 next_record = &buffer[invm_blocks - i + 1];
533
534 /* Check if we have image type in first location used */
535 if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
536 invm_ver->invm_img_type = 0;
537 status = E1000_SUCCESS;
538 break;
539 }
540 /* Check if we have image type in first location used */
541 else if ((((*record & 0x3) == 0) &&
542 ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
543 ((((*record & 0x3) != 0) && (i != 1)))) {
544 invm_ver->invm_img_type =
545 (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
546 status = E1000_SUCCESS;
547 break;
548 }
549 }
550 return status;
551}
552
553/**
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000554 * igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
555 * @hw: pointer to the HW structure
556 *
557 * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
558 * and then verifies that the sum of the EEPROM is equal to 0xBABA.
559 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800560static s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000561{
562 s32 status = E1000_SUCCESS;
563 s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
564
565 if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
566
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000567 /* Replace the read function with semaphore grabbing with
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000568 * the one that skips this for a while.
569 * We have semaphore taken already here.
570 */
571 read_op_ptr = hw->nvm.ops.read;
572 hw->nvm.ops.read = igb_read_nvm_eerd;
573
574 status = igb_validate_nvm_checksum(hw);
575
576 /* Revert original read operation. */
577 hw->nvm.ops.read = read_op_ptr;
578
579 hw->nvm.ops.release(hw);
580 } else {
581 status = E1000_ERR_SWFW_SYNC;
582 }
583
584 return status;
585}
586
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000587/**
588 * igb_update_nvm_checksum_i210 - Update EEPROM checksum
589 * @hw: pointer to the HW structure
590 *
591 * Updates the EEPROM checksum by reading/adding each word of the EEPROM
592 * up to the checksum. Then calculates the EEPROM checksum and writes the
593 * value to the EEPROM. Next commit EEPROM data onto the Flash.
594 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800595static s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000596{
597 s32 ret_val = E1000_SUCCESS;
598 u16 checksum = 0;
599 u16 i, nvm_data;
600
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000601 /* Read the first word from the EEPROM. If this times out or fails, do
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000602 * not continue or we could be in for a very long wait while every
603 * EEPROM read fails
604 */
605 ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data);
606 if (ret_val != E1000_SUCCESS) {
607 hw_dbg("EEPROM read failed\n");
608 goto out;
609 }
610
611 if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000612 /* Do not use hw->nvm.ops.write, hw->nvm.ops.read
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000613 * because we do not want to take the synchronization
614 * semaphores twice here.
615 */
616
617 for (i = 0; i < NVM_CHECKSUM_REG; i++) {
618 ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data);
619 if (ret_val) {
620 hw->nvm.ops.release(hw);
621 hw_dbg("NVM Read Error while updating checksum.\n");
622 goto out;
623 }
624 checksum += nvm_data;
625 }
626 checksum = (u16) NVM_SUM - checksum;
627 ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
628 &checksum);
629 if (ret_val != E1000_SUCCESS) {
630 hw->nvm.ops.release(hw);
631 hw_dbg("NVM Write Error while updating checksum.\n");
632 goto out;
633 }
634
635 hw->nvm.ops.release(hw);
636
637 ret_val = igb_update_flash_i210(hw);
638 } else {
639 ret_val = -E1000_ERR_SWFW_SYNC;
640 }
641out:
642 return ret_val;
643}
644
645/**
Carolyn Wyborny7916a532012-11-21 04:44:10 +0000646 * igb_pool_flash_update_done_i210 - Pool FLUDONE status.
647 * @hw: pointer to the HW structure
648 *
Jeff Kirsherb980ac12013-02-23 07:29:56 +0000649 **/
Carolyn Wyborny7916a532012-11-21 04:44:10 +0000650static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
651{
652 s32 ret_val = -E1000_ERR_NVM;
653 u32 i, reg;
654
655 for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
656 reg = rd32(E1000_EECD);
657 if (reg & E1000_EECD_FLUDONE_I210) {
658 ret_val = E1000_SUCCESS;
659 break;
660 }
661 udelay(5);
662 }
663
664 return ret_val;
665}
666
667/**
Carolyn Wyborny5a823d82013-07-16 19:17:32 +0000668 * igb_get_flash_presence_i210 - Check if flash device is detected.
669 * @hw: pointer to the HW structure
670 *
671 **/
672bool igb_get_flash_presence_i210(struct e1000_hw *hw)
673{
674 u32 eec = 0;
675 bool ret_val = false;
676
677 eec = rd32(E1000_EECD);
678 if (eec & E1000_EECD_FLASH_DETECTED_I210)
679 ret_val = true;
680
681 return ret_val;
682}
683
684/**
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000685 * igb_update_flash_i210 - Commit EEPROM to the flash
686 * @hw: pointer to the HW structure
687 *
688 **/
Jeff Kirsher167f3f72014-02-25 17:58:56 -0800689static s32 igb_update_flash_i210(struct e1000_hw *hw)
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000690{
691 s32 ret_val = E1000_SUCCESS;
692 u32 flup;
693
694 ret_val = igb_pool_flash_update_done_i210(hw);
695 if (ret_val == -E1000_ERR_NVM) {
696 hw_dbg("Flash update time out\n");
697 goto out;
698 }
699
700 flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210;
701 wr32(E1000_EECD, flup);
702
703 ret_val = igb_pool_flash_update_done_i210(hw);
704 if (ret_val == E1000_SUCCESS)
705 hw_dbg("Flash update complete\n");
706 else
707 hw_dbg("Flash update time out\n");
708
709out:
710 return ret_val;
711}
712
713/**
Carolyn Wybornyf96a8a02012-04-06 23:25:19 +0000714 * igb_valid_led_default_i210 - Verify a valid default LED config
715 * @hw: pointer to the HW structure
716 * @data: pointer to the NVM (EEPROM)
717 *
718 * Read the EEPROM for the current default LED configuration. If the
719 * LED configuration is not valid, set to a valid LED configuration.
720 **/
721s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
722{
723 s32 ret_val;
724
725 ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
726 if (ret_val) {
727 hw_dbg("NVM Read Error\n");
728 goto out;
729 }
730
731 if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
732 switch (hw->phy.media_type) {
733 case e1000_media_type_internal_serdes:
734 *data = ID_LED_DEFAULT_I210_SERDES;
735 break;
736 case e1000_media_type_copper:
737 default:
738 *data = ID_LED_DEFAULT_I210;
739 break;
740 }
741 }
742out:
743 return ret_val;
744}
Matthew Vick87371b92013-02-21 03:32:52 +0000745
746/**
747 * __igb_access_xmdio_reg - Read/write XMDIO register
748 * @hw: pointer to the HW structure
749 * @address: XMDIO address to program
750 * @dev_addr: device address to program
751 * @data: pointer to value to read/write from/to the XMDIO address
752 * @read: boolean flag to indicate read or write
753 **/
754static s32 __igb_access_xmdio_reg(struct e1000_hw *hw, u16 address,
755 u8 dev_addr, u16 *data, bool read)
756{
757 s32 ret_val = E1000_SUCCESS;
758
759 ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
760 if (ret_val)
761 return ret_val;
762
763 ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
764 if (ret_val)
765 return ret_val;
766
767 ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
768 dev_addr);
769 if (ret_val)
770 return ret_val;
771
772 if (read)
773 ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
774 else
775 ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
776 if (ret_val)
777 return ret_val;
778
779 /* Recalibrate the device back to 0 */
780 ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
781 if (ret_val)
782 return ret_val;
783
784 return ret_val;
785}
786
787/**
788 * igb_read_xmdio_reg - Read XMDIO register
789 * @hw: pointer to the HW structure
790 * @addr: XMDIO address to program
791 * @dev_addr: device address to program
792 * @data: value to be read from the EMI address
793 **/
794s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
795{
796 return __igb_access_xmdio_reg(hw, addr, dev_addr, data, true);
797}
798
799/**
800 * igb_write_xmdio_reg - Write XMDIO register
801 * @hw: pointer to the HW structure
802 * @addr: XMDIO address to program
803 * @dev_addr: device address to program
804 * @data: value to be written to the XMDIO address
805 **/
806s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
807{
808 return __igb_access_xmdio_reg(hw, addr, dev_addr, &data, false);
809}
Carolyn Wyborny5a823d82013-07-16 19:17:32 +0000810
811/**
812 * igb_init_nvm_params_i210 - Init NVM func ptrs.
813 * @hw: pointer to the HW structure
814 **/
815s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
816{
817 s32 ret_val = 0;
818 struct e1000_nvm_info *nvm = &hw->nvm;
819
820 nvm->ops.acquire = igb_acquire_nvm_i210;
821 nvm->ops.release = igb_release_nvm_i210;
822 nvm->ops.valid_led_default = igb_valid_led_default_i210;
823
824 /* NVM Function Pointers */
825 if (igb_get_flash_presence_i210(hw)) {
826 hw->nvm.type = e1000_nvm_flash_hw;
827 nvm->ops.read = igb_read_nvm_srrd_i210;
828 nvm->ops.write = igb_write_nvm_srwr_i210;
829 nvm->ops.validate = igb_validate_nvm_checksum_i210;
830 nvm->ops.update = igb_update_nvm_checksum_i210;
831 } else {
832 hw->nvm.type = e1000_nvm_invm;
Carolyn Wybornyef3a0092013-07-17 19:02:53 +0000833 nvm->ops.read = igb_read_invm_i210;
Carolyn Wyborny5a823d82013-07-16 19:17:32 +0000834 nvm->ops.write = NULL;
835 nvm->ops.validate = NULL;
836 nvm->ops.update = NULL;
837 }
838 return ret_val;
839}