[go: nahoru, domu]

e1000_i210.c revision 4b9ea4626b52c113c367c4776c9bb11b7231393d
1/*******************************************************************************
2
3  Intel(R) Gigabit Ethernet Linux driver
4  Copyright(c) 2007-2013 Intel Corporation.
5
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
38/**
39 * igb_get_hw_semaphore_i210 - Acquire hardware semaphore
40 *  @hw: pointer to the HW structure
41 *
42 *  Acquire the HW semaphore to access the PHY or NVM
43 */
44static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
45{
46	u32 swsm;
47	s32 ret_val = E1000_SUCCESS;
48	s32 timeout = hw->nvm.word_size + 1;
49	s32 i = 0;
50
51	/* Get the FW semaphore. */
52	for (i = 0; i < timeout; i++) {
53		swsm = rd32(E1000_SWSM);
54		wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
55
56		/* Semaphore acquired if bit latched */
57		if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
58			break;
59
60		udelay(50);
61	}
62
63	if (i == timeout) {
64		/* Release semaphores */
65		igb_put_hw_semaphore(hw);
66		hw_dbg("Driver can't access the NVM\n");
67		ret_val = -E1000_ERR_NVM;
68		goto out;
69	}
70
71out:
72	return ret_val;
73}
74
75/**
76 *  igb_acquire_nvm_i210 - Request for access to EEPROM
77 *  @hw: pointer to the HW structure
78 *
79 *  Acquire the necessary semaphores for exclusive access to the EEPROM.
80 *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
81 *  Return successful if access grant bit set, else clear the request for
82 *  EEPROM access and return -E1000_ERR_NVM (-1).
83 **/
84s32 igb_acquire_nvm_i210(struct e1000_hw *hw)
85{
86	return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
87}
88
89/**
90 *  igb_release_nvm_i210 - Release exclusive access to EEPROM
91 *  @hw: pointer to the HW structure
92 *
93 *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
94 *  then release the semaphores acquired.
95 **/
96void igb_release_nvm_i210(struct e1000_hw *hw)
97{
98	igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
99}
100
101/**
102 *  igb_put_hw_semaphore_i210 - Release hardware semaphore
103 *  @hw: pointer to the HW structure
104 *
105 *  Release hardware semaphore used to access the PHY or NVM
106 */
107static void igb_put_hw_semaphore_i210(struct e1000_hw *hw)
108{
109	u32 swsm;
110
111	swsm = rd32(E1000_SWSM);
112
113	swsm &= ~E1000_SWSM_SWESMBI;
114
115	wr32(E1000_SWSM, swsm);
116}
117
118/**
119 *  igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
120 *  @hw: pointer to the HW structure
121 *  @mask: specifies which semaphore to acquire
122 *
123 *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
124 *  will also specify which port we're acquiring the lock for.
125 **/
126s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
127{
128	u32 swfw_sync;
129	u32 swmask = mask;
130	u32 fwmask = mask << 16;
131	s32 ret_val = E1000_SUCCESS;
132	s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
133
134	while (i < timeout) {
135		if (igb_get_hw_semaphore_i210(hw)) {
136			ret_val = -E1000_ERR_SWFW_SYNC;
137			goto out;
138		}
139
140		swfw_sync = rd32(E1000_SW_FW_SYNC);
141		if (!(swfw_sync & fwmask))
142			break;
143
144		/*
145		 * Firmware currently using resource (fwmask)
146		 */
147		igb_put_hw_semaphore_i210(hw);
148		mdelay(5);
149		i++;
150	}
151
152	if (i == timeout) {
153		hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
154		ret_val = -E1000_ERR_SWFW_SYNC;
155		goto out;
156	}
157
158	swfw_sync |= swmask;
159	wr32(E1000_SW_FW_SYNC, swfw_sync);
160
161	igb_put_hw_semaphore_i210(hw);
162out:
163	return ret_val;
164}
165
166/**
167 *  igb_release_swfw_sync_i210 - Release SW/FW semaphore
168 *  @hw: pointer to the HW structure
169 *  @mask: specifies which semaphore to acquire
170 *
171 *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
172 *  will also specify which port we're releasing the lock for.
173 **/
174void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
175{
176	u32 swfw_sync;
177
178	while (igb_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
179		; /* Empty */
180
181	swfw_sync = rd32(E1000_SW_FW_SYNC);
182	swfw_sync &= ~mask;
183	wr32(E1000_SW_FW_SYNC, swfw_sync);
184
185	igb_put_hw_semaphore_i210(hw);
186}
187
188/**
189 *  igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
190 *  @hw: pointer to the HW structure
191 *  @offset: offset of word in the Shadow Ram to read
192 *  @words: number of words to read
193 *  @data: word read from the Shadow Ram
194 *
195 *  Reads a 16 bit word from the Shadow Ram using the EERD register.
196 *  Uses necessary synchronization semaphores.
197 **/
198s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
199			     u16 *data)
200{
201	s32 status = E1000_SUCCESS;
202	u16 i, count;
203
204	/* We cannot hold synchronization semaphores for too long,
205	 * because of forceful takeover procedure. However it is more efficient
206	 * to read in bursts than synchronizing access for each word. */
207	for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
208		count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
209			E1000_EERD_EEWR_MAX_COUNT : (words - i);
210		if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
211			status = igb_read_nvm_eerd(hw, offset, count,
212						     data + i);
213			hw->nvm.ops.release(hw);
214		} else {
215			status = E1000_ERR_SWFW_SYNC;
216		}
217
218		if (status != E1000_SUCCESS)
219			break;
220	}
221
222	return status;
223}
224
225/**
226 *  igb_write_nvm_srwr - Write to Shadow Ram using EEWR
227 *  @hw: pointer to the HW structure
228 *  @offset: offset within the Shadow Ram to be written to
229 *  @words: number of words to write
230 *  @data: 16 bit word(s) to be written to the Shadow Ram
231 *
232 *  Writes data to Shadow Ram at offset using EEWR register.
233 *
234 *  If igb_update_nvm_checksum is not called after this function , the
235 *  Shadow Ram will most likely contain an invalid checksum.
236 **/
237static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
238				u16 *data)
239{
240	struct e1000_nvm_info *nvm = &hw->nvm;
241	u32 i, k, eewr = 0;
242	u32 attempts = 100000;
243	s32 ret_val = E1000_SUCCESS;
244
245	/*
246	 * A check for invalid values:  offset too large, too many words,
247	 * too many words for the offset, and not enough words.
248	 */
249	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
250	    (words == 0)) {
251		hw_dbg("nvm parameter(s) out of bounds\n");
252		ret_val = -E1000_ERR_NVM;
253		goto out;
254	}
255
256	for (i = 0; i < words; i++) {
257		eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
258			(data[i] << E1000_NVM_RW_REG_DATA) |
259			E1000_NVM_RW_REG_START;
260
261		wr32(E1000_SRWR, eewr);
262
263		for (k = 0; k < attempts; k++) {
264			if (E1000_NVM_RW_REG_DONE &
265			    rd32(E1000_SRWR)) {
266				ret_val = E1000_SUCCESS;
267				break;
268			}
269			udelay(5);
270	}
271
272		if (ret_val != E1000_SUCCESS) {
273			hw_dbg("Shadow RAM write EEWR timed out\n");
274			break;
275		}
276	}
277
278out:
279	return ret_val;
280}
281
282/**
283 *  igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
284 *  @hw: pointer to the HW structure
285 *  @offset: offset within the Shadow RAM to be written to
286 *  @words: number of words to write
287 *  @data: 16 bit word(s) to be written to the Shadow RAM
288 *
289 *  Writes data to Shadow RAM at offset using EEWR register.
290 *
291 *  If e1000_update_nvm_checksum is not called after this function , the
292 *  data will not be committed to FLASH and also Shadow RAM will most likely
293 *  contain an invalid checksum.
294 *
295 *  If error code is returned, data and Shadow RAM may be inconsistent - buffer
296 *  partially written.
297 */
298s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
299			      u16 *data)
300{
301	s32 status = E1000_SUCCESS;
302	u16 i, count;
303
304	/* We cannot hold synchronization semaphores for too long,
305	 * because of forceful takeover procedure. However it is more efficient
306	 * to write in bursts than synchronizing access for each word.
307	 */
308	for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
309		count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
310			E1000_EERD_EEWR_MAX_COUNT : (words - i);
311		if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
312			status = igb_write_nvm_srwr(hw, offset, count,
313						      data + i);
314			hw->nvm.ops.release(hw);
315		} else {
316			status = E1000_ERR_SWFW_SYNC;
317		}
318
319		if (status != E1000_SUCCESS)
320			break;
321	}
322
323	return status;
324}
325
326/**
327 *  igb_read_nvm_i211 - Read NVM wrapper function for I211
328 *  @hw: pointer to the HW structure
329 *  @address: the word address (aka eeprom offset) to read
330 *  @data: pointer to the data read
331 *
332 *  Wrapper function to return data formerly found in the NVM.
333 **/
334s32 igb_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
335			       u16 *data)
336{
337	s32 ret_val = E1000_SUCCESS;
338
339	/* Only the MAC addr is required to be present in the iNVM */
340	switch (offset) {
341	case NVM_MAC_ADDR:
342		ret_val = igb_read_invm_i211(hw, offset, &data[0]);
343		ret_val |= igb_read_invm_i211(hw, offset+1, &data[1]);
344		ret_val |= igb_read_invm_i211(hw, offset+2, &data[2]);
345		if (ret_val != E1000_SUCCESS)
346			hw_dbg("MAC Addr not found in iNVM\n");
347		break;
348	case NVM_INIT_CTRL_2:
349		ret_val = igb_read_invm_i211(hw, (u8)offset, data);
350		if (ret_val != E1000_SUCCESS) {
351			*data = NVM_INIT_CTRL_2_DEFAULT_I211;
352			ret_val = E1000_SUCCESS;
353		}
354		break;
355	case NVM_INIT_CTRL_4:
356		ret_val = igb_read_invm_i211(hw, (u8)offset, data);
357		if (ret_val != E1000_SUCCESS) {
358			*data = NVM_INIT_CTRL_4_DEFAULT_I211;
359			ret_val = E1000_SUCCESS;
360		}
361		break;
362	case NVM_LED_1_CFG:
363		ret_val = igb_read_invm_i211(hw, (u8)offset, data);
364		if (ret_val != E1000_SUCCESS) {
365			*data = NVM_LED_1_CFG_DEFAULT_I211;
366			ret_val = E1000_SUCCESS;
367		}
368		break;
369	case NVM_LED_0_2_CFG:
370		igb_read_invm_i211(hw, offset, data);
371		if (ret_val != E1000_SUCCESS) {
372			*data = NVM_LED_0_2_CFG_DEFAULT_I211;
373			ret_val = E1000_SUCCESS;
374		}
375		break;
376	case NVM_ID_LED_SETTINGS:
377		ret_val = igb_read_invm_i211(hw, (u8)offset, data);
378		if (ret_val != E1000_SUCCESS) {
379			*data = ID_LED_RESERVED_FFFF;
380			ret_val = E1000_SUCCESS;
381		}
382	case NVM_SUB_DEV_ID:
383		*data = hw->subsystem_device_id;
384		break;
385	case NVM_SUB_VEN_ID:
386		*data = hw->subsystem_vendor_id;
387		break;
388	case NVM_DEV_ID:
389		*data = hw->device_id;
390		break;
391	case NVM_VEN_ID:
392		*data = hw->vendor_id;
393		break;
394	default:
395		hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
396		*data = NVM_RESERVED_WORD;
397		break;
398	}
399	return ret_val;
400}
401
402/**
403 *  igb_read_invm_i211 - Reads OTP
404 *  @hw: pointer to the HW structure
405 *  @address: the word address (aka eeprom offset) to read
406 *  @data: pointer to the data read
407 *
408 *  Reads 16-bit words from the OTP. Return error when the word is not
409 *  stored in OTP.
410 **/
411s32 igb_read_invm_i211(struct e1000_hw *hw, u16 address, u16 *data)
412{
413	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
414	u32 invm_dword;
415	u16 i;
416	u8 record_type, word_address;
417
418	for (i = 0; i < E1000_INVM_SIZE; i++) {
419		invm_dword = rd32(E1000_INVM_DATA_REG(i));
420		/* Get record type */
421		record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
422		if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
423			break;
424		if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
425			i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
426		if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
427			i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
428		if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
429			word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
430			if (word_address == (u8)address) {
431				*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
432				hw_dbg("Read INVM Word 0x%02x = %x",
433					  address, *data);
434				status = E1000_SUCCESS;
435				break;
436			}
437		}
438	}
439	if (status != E1000_SUCCESS)
440		hw_dbg("Requested word 0x%02x not found in OTP\n", address);
441	return status;
442}
443
444/**
445 *  igb_read_invm_version - Reads iNVM version and image type
446 *  @hw: pointer to the HW structure
447 *  @invm_ver: version structure for the version read
448 *
449 *  Reads iNVM version and image type.
450 **/
451s32 igb_read_invm_version(struct e1000_hw *hw,
452			  struct e1000_fw_version *invm_ver) {
453	u32 *record = NULL;
454	u32 *next_record = NULL;
455	u32 i = 0;
456	u32 invm_dword = 0;
457	u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
458					     E1000_INVM_RECORD_SIZE_IN_BYTES);
459	u32 buffer[E1000_INVM_SIZE];
460	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
461	u16 version = 0;
462
463	/* Read iNVM memory */
464	for (i = 0; i < E1000_INVM_SIZE; i++) {
465		invm_dword = rd32(E1000_INVM_DATA_REG(i));
466		buffer[i] = invm_dword;
467	}
468
469	/* Read version number */
470	for (i = 1; i < invm_blocks; i++) {
471		record = &buffer[invm_blocks - i];
472		next_record = &buffer[invm_blocks - i + 1];
473
474		/* Check if we have first version location used */
475		if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
476			version = 0;
477			status = E1000_SUCCESS;
478			break;
479		}
480		/* Check if we have second version location used */
481		else if ((i == 1) &&
482			 ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
483			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
484			status = E1000_SUCCESS;
485			break;
486		}
487		/* Check if we have odd version location
488		 * used and it is the last one used
489		 */
490		else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
491			 ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
492			 (i != 1))) {
493			version = (*next_record & E1000_INVM_VER_FIELD_TWO)
494				  >> 13;
495			status = E1000_SUCCESS;
496			break;
497		}
498		/* Check if we have even version location
499		 * used and it is the last one used
500		 */
501		else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
502			 ((*record & 0x3) == 0)) {
503			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
504			status = E1000_SUCCESS;
505			break;
506		}
507	}
508
509	if (status == E1000_SUCCESS) {
510		invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
511					>> E1000_INVM_MAJOR_SHIFT;
512		invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
513	}
514	/* Read Image Type */
515	for (i = 1; i < invm_blocks; i++) {
516		record = &buffer[invm_blocks - i];
517		next_record = &buffer[invm_blocks - i + 1];
518
519		/* Check if we have image type in first location used */
520		if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
521			invm_ver->invm_img_type = 0;
522			status = E1000_SUCCESS;
523			break;
524		}
525		/* Check if we have image type in first location used */
526		else if ((((*record & 0x3) == 0) &&
527			 ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
528			 ((((*record & 0x3) != 0) && (i != 1)))) {
529			invm_ver->invm_img_type =
530				(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
531			status = E1000_SUCCESS;
532			break;
533		}
534	}
535	return status;
536}
537
538/**
539 *  igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
540 *  @hw: pointer to the HW structure
541 *
542 *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
543 *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
544 **/
545s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
546{
547	s32 status = E1000_SUCCESS;
548	s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
549
550	if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
551
552		/*
553		 * Replace the read function with semaphore grabbing with
554		 * the one that skips this for a while.
555		 * We have semaphore taken already here.
556		 */
557		read_op_ptr = hw->nvm.ops.read;
558		hw->nvm.ops.read = igb_read_nvm_eerd;
559
560		status = igb_validate_nvm_checksum(hw);
561
562		/* Revert original read operation. */
563		hw->nvm.ops.read = read_op_ptr;
564
565		hw->nvm.ops.release(hw);
566	} else {
567		status = E1000_ERR_SWFW_SYNC;
568	}
569
570	return status;
571}
572
573
574/**
575 *  igb_update_nvm_checksum_i210 - Update EEPROM checksum
576 *  @hw: pointer to the HW structure
577 *
578 *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
579 *  up to the checksum.  Then calculates the EEPROM checksum and writes the
580 *  value to the EEPROM. Next commit EEPROM data onto the Flash.
581 **/
582s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
583{
584	s32 ret_val = E1000_SUCCESS;
585	u16 checksum = 0;
586	u16 i, nvm_data;
587
588	/*
589	 * Read the first word from the EEPROM. If this times out or fails, do
590	 * not continue or we could be in for a very long wait while every
591	 * EEPROM read fails
592	 */
593	ret_val = igb_read_nvm_eerd(hw, 0, 1, &nvm_data);
594	if (ret_val != E1000_SUCCESS) {
595		hw_dbg("EEPROM read failed\n");
596		goto out;
597	}
598
599	if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
600		/*
601		 * Do not use hw->nvm.ops.write, hw->nvm.ops.read
602		 * because we do not want to take the synchronization
603		 * semaphores twice here.
604		 */
605
606		for (i = 0; i < NVM_CHECKSUM_REG; i++) {
607			ret_val = igb_read_nvm_eerd(hw, i, 1, &nvm_data);
608			if (ret_val) {
609				hw->nvm.ops.release(hw);
610				hw_dbg("NVM Read Error while updating checksum.\n");
611				goto out;
612			}
613			checksum += nvm_data;
614		}
615		checksum = (u16) NVM_SUM - checksum;
616		ret_val = igb_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
617						&checksum);
618		if (ret_val != E1000_SUCCESS) {
619			hw->nvm.ops.release(hw);
620			hw_dbg("NVM Write Error while updating checksum.\n");
621			goto out;
622		}
623
624		hw->nvm.ops.release(hw);
625
626		ret_val = igb_update_flash_i210(hw);
627	} else {
628		ret_val = -E1000_ERR_SWFW_SYNC;
629	}
630out:
631	return ret_val;
632}
633
634/**
635 *  igb_pool_flash_update_done_i210 - Pool FLUDONE status.
636 *  @hw: pointer to the HW structure
637 *
638 */
639static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
640{
641	s32 ret_val = -E1000_ERR_NVM;
642	u32 i, reg;
643
644	for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
645		reg = rd32(E1000_EECD);
646		if (reg & E1000_EECD_FLUDONE_I210) {
647			ret_val = E1000_SUCCESS;
648			break;
649		}
650		udelay(5);
651	}
652
653	return ret_val;
654}
655
656/**
657 *  igb_update_flash_i210 - Commit EEPROM to the flash
658 *  @hw: pointer to the HW structure
659 *
660 **/
661s32 igb_update_flash_i210(struct e1000_hw *hw)
662{
663	s32 ret_val = E1000_SUCCESS;
664	u32 flup;
665
666	ret_val = igb_pool_flash_update_done_i210(hw);
667	if (ret_val == -E1000_ERR_NVM) {
668		hw_dbg("Flash update time out\n");
669		goto out;
670	}
671
672	flup = rd32(E1000_EECD) | E1000_EECD_FLUPD_I210;
673	wr32(E1000_EECD, flup);
674
675	ret_val = igb_pool_flash_update_done_i210(hw);
676	if (ret_val == E1000_SUCCESS)
677		hw_dbg("Flash update complete\n");
678	else
679		hw_dbg("Flash update time out\n");
680
681out:
682	return ret_val;
683}
684
685/**
686 *  igb_valid_led_default_i210 - Verify a valid default LED config
687 *  @hw: pointer to the HW structure
688 *  @data: pointer to the NVM (EEPROM)
689 *
690 *  Read the EEPROM for the current default LED configuration.  If the
691 *  LED configuration is not valid, set to a valid LED configuration.
692 **/
693s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
694{
695	s32 ret_val;
696
697	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
698	if (ret_val) {
699		hw_dbg("NVM Read Error\n");
700		goto out;
701	}
702
703	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
704		switch (hw->phy.media_type) {
705		case e1000_media_type_internal_serdes:
706			*data = ID_LED_DEFAULT_I210_SERDES;
707			break;
708		case e1000_media_type_copper:
709		default:
710			*data = ID_LED_DEFAULT_I210;
711			break;
712		}
713	}
714out:
715	return ret_val;
716}
717