1a551c94aSIdo Barnea/*******************************************************************************
2a551c94aSIdo Barnea
3a551c94aSIdo BarneaCopyright (c) 2001-2015, Intel Corporation
4a551c94aSIdo BarneaAll rights reserved.
5a551c94aSIdo Barnea
6a551c94aSIdo BarneaRedistribution and use in source and binary forms, with or without
7a551c94aSIdo Barneamodification, are permitted provided that the following conditions are met:
8a551c94aSIdo Barnea
9a551c94aSIdo Barnea 1. Redistributions of source code must retain the above copyright notice,
10a551c94aSIdo Barnea    this list of conditions and the following disclaimer.
11a551c94aSIdo Barnea
12a551c94aSIdo Barnea 2. Redistributions in binary form must reproduce the above copyright
13a551c94aSIdo Barnea    notice, this list of conditions and the following disclaimer in the
14a551c94aSIdo Barnea    documentation and/or other materials provided with the distribution.
15a551c94aSIdo Barnea
16a551c94aSIdo Barnea 3. Neither the name of the Intel Corporation nor the names of its
17a551c94aSIdo Barnea    contributors may be used to endorse or promote products derived from
18a551c94aSIdo Barnea    this software without specific prior written permission.
19a551c94aSIdo Barnea
31a551c94aSIdo Barnea
32a551c94aSIdo Barnea***************************************************************************/
33a551c94aSIdo Barnea
34a551c94aSIdo Barnea#include "e1000_api.h"
35a551c94aSIdo Barnea
36a551c94aSIdo Barnea
37a551c94aSIdo BarneaSTATIC s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
38a551c94aSIdo BarneaSTATIC void e1000_release_nvm_i210(struct e1000_hw *hw);
39a551c94aSIdo BarneaSTATIC s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
40a551c94aSIdo BarneaSTATIC s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
41a551c94aSIdo Barnea				u16 *data);
42a551c94aSIdo BarneaSTATIC s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
43a551c94aSIdo BarneaSTATIC s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
44a551c94aSIdo Barnea
45a551c94aSIdo Barnea/**
46a551c94aSIdo Barnea *  e1000_acquire_nvm_i210 - Request for access to EEPROM
47a551c94aSIdo Barnea *  @hw: pointer to the HW structure
48a551c94aSIdo Barnea *
49a551c94aSIdo Barnea *  Acquire the necessary semaphores for exclusive access to the EEPROM.
50a551c94aSIdo Barnea *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
51a551c94aSIdo Barnea *  Return successful if access grant bit set, else clear the request for
52a551c94aSIdo Barnea *  EEPROM access and return -E1000_ERR_NVM (-1).
53a551c94aSIdo Barnea **/
54a551c94aSIdo BarneaSTATIC s32 e1000_acquire_nvm_i210(struct e1000_hw *hw)
55a551c94aSIdo Barnea{
56a551c94aSIdo Barnea	s32 ret_val;
57a551c94aSIdo Barnea
58a551c94aSIdo Barnea	DEBUGFUNC("e1000_acquire_nvm_i210");
59a551c94aSIdo Barnea
60a551c94aSIdo Barnea	ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
61a551c94aSIdo Barnea
62a551c94aSIdo Barnea	return ret_val;
63a551c94aSIdo Barnea}
64a551c94aSIdo Barnea
65a551c94aSIdo Barnea/**
66a551c94aSIdo Barnea *  e1000_release_nvm_i210 - Release exclusive access to EEPROM
67a551c94aSIdo Barnea *  @hw: pointer to the HW structure
68a551c94aSIdo Barnea *
69a551c94aSIdo Barnea *  Stop any current commands to the EEPROM and clear the EEPROM request bit,
70a551c94aSIdo Barnea *  then release the semaphores acquired.
71a551c94aSIdo Barnea **/
72a551c94aSIdo BarneaSTATIC void e1000_release_nvm_i210(struct e1000_hw *hw)
73a551c94aSIdo Barnea{
74a551c94aSIdo Barnea	DEBUGFUNC("e1000_release_nvm_i210");
75a551c94aSIdo Barnea
76a551c94aSIdo Barnea	e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
77a551c94aSIdo Barnea}
78a551c94aSIdo Barnea
79a551c94aSIdo Barnea/**
80a551c94aSIdo Barnea *  e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
81a551c94aSIdo Barnea *  @hw: pointer to the HW structure
82a551c94aSIdo Barnea *  @mask: specifies which semaphore to acquire
83a551c94aSIdo Barnea *
84a551c94aSIdo Barnea *  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
85a551c94aSIdo Barnea *  will also specify which port we're acquiring the lock for.
86a551c94aSIdo Barnea **/
87a551c94aSIdo Barneas32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
88a551c94aSIdo Barnea{
89a551c94aSIdo Barnea	u32 swfw_sync;
90a551c94aSIdo Barnea	u32 swmask = mask;
91a551c94aSIdo Barnea	u32 fwmask = mask << 16;
92a551c94aSIdo Barnea	s32 ret_val = E1000_SUCCESS;
93a551c94aSIdo Barnea	s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
94a551c94aSIdo Barnea
95a551c94aSIdo Barnea	DEBUGFUNC("e1000_acquire_swfw_sync_i210");
96a551c94aSIdo Barnea
97a551c94aSIdo Barnea	while (i < timeout) {
98a551c94aSIdo Barnea		if (e1000_get_hw_semaphore_i210(hw)) {
99a551c94aSIdo Barnea			ret_val = -E1000_ERR_SWFW_SYNC;
100a551c94aSIdo Barnea			goto out;
101a551c94aSIdo Barnea		}
102a551c94aSIdo Barnea
103a551c94aSIdo Barnea		swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
104a551c94aSIdo Barnea		if (!(swfw_sync & (fwmask | swmask)))
105a551c94aSIdo Barnea			break;
106a551c94aSIdo Barnea
107a551c94aSIdo Barnea		/*
108a551c94aSIdo Barnea		 * Firmware currently using resource (fwmask)
109a551c94aSIdo Barnea		 * or other software thread using resource (swmask)
110a551c94aSIdo Barnea		 */
111a551c94aSIdo Barnea		e1000_put_hw_semaphore_generic(hw);
112a551c94aSIdo Barnea		msec_delay_irq(5);
113a551c94aSIdo Barnea		i++;
114a551c94aSIdo Barnea	}
115a551c94aSIdo Barnea
116a551c94aSIdo Barnea	if (i == timeout) {
117a551c94aSIdo Barnea		DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
118a551c94aSIdo Barnea		ret_val = -E1000_ERR_SWFW_SYNC;
119a551c94aSIdo Barnea		goto out;
120a551c94aSIdo Barnea	}
121a551c94aSIdo Barnea
122a551c94aSIdo Barnea	swfw_sync |= swmask;
123a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
124a551c94aSIdo Barnea
125a551c94aSIdo Barnea	e1000_put_hw_semaphore_generic(hw);
126a551c94aSIdo Barnea
127a551c94aSIdo Barneaout:
128a551c94aSIdo Barnea	return ret_val;
129a551c94aSIdo Barnea}
130a551c94aSIdo Barnea
131a551c94aSIdo Barnea/**
132a551c94aSIdo Barnea *  e1000_release_swfw_sync_i210 - Release SW/FW semaphore
133a551c94aSIdo Barnea *  @hw: pointer to the HW structure
134a551c94aSIdo Barnea *  @mask: specifies which semaphore to acquire
135a551c94aSIdo Barnea *
136a551c94aSIdo Barnea *  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
137a551c94aSIdo Barnea *  will also specify which port we're releasing the lock for.
138a551c94aSIdo Barnea **/
139a551c94aSIdo Barneavoid e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
140a551c94aSIdo Barnea{
141a551c94aSIdo Barnea	u32 swfw_sync;
142a551c94aSIdo Barnea
143a551c94aSIdo Barnea	DEBUGFUNC("e1000_release_swfw_sync_i210");
144a551c94aSIdo Barnea
145a551c94aSIdo Barnea	while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
146a551c94aSIdo Barnea		; /* Empty */
147a551c94aSIdo Barnea
148a551c94aSIdo Barnea	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
149a551c94aSIdo Barnea	swfw_sync &= ~mask;
150a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
151a551c94aSIdo Barnea
152a551c94aSIdo Barnea	e1000_put_hw_semaphore_generic(hw);
153a551c94aSIdo Barnea}
154a551c94aSIdo Barnea
155a551c94aSIdo Barnea/**
156a551c94aSIdo Barnea *  e1000_get_hw_semaphore_i210 - Acquire hardware semaphore
157a551c94aSIdo Barnea *  @hw: pointer to the HW structure
158a551c94aSIdo Barnea *
159a551c94aSIdo Barnea *  Acquire the HW semaphore to access the PHY or NVM
160a551c94aSIdo Barnea **/
161a551c94aSIdo BarneaSTATIC s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
162a551c94aSIdo Barnea{
163a551c94aSIdo Barnea	u32 swsm;
164a551c94aSIdo Barnea	s32 timeout = hw->nvm.word_size + 1;
165a551c94aSIdo Barnea	s32 i = 0;
166a551c94aSIdo Barnea
167a551c94aSIdo Barnea	DEBUGFUNC("e1000_get_hw_semaphore_i210");
168a551c94aSIdo Barnea
169a551c94aSIdo Barnea	/* Get the SW semaphore */
170a551c94aSIdo Barnea	while (i < timeout) {
171a551c94aSIdo Barnea		swsm = E1000_READ_REG(hw, E1000_SWSM);
172a551c94aSIdo Barnea		if (!(swsm & E1000_SWSM_SMBI))
173a551c94aSIdo Barnea			break;
174a551c94aSIdo Barnea
175a551c94aSIdo Barnea		usec_delay(50);
176a551c94aSIdo Barnea		i++;
177a551c94aSIdo Barnea	}
178a551c94aSIdo Barnea
179a551c94aSIdo Barnea	if (i == timeout) {
180a551c94aSIdo Barnea		/* In rare circumstances, the SW semaphore may already be held
181a551c94aSIdo Barnea		 * unintentionally. Clear the semaphore once before giving up.
182a551c94aSIdo Barnea		 */
183a551c94aSIdo Barnea		if (hw->dev_spec._82575.clear_semaphore_once) {
184a551c94aSIdo Barnea			hw->dev_spec._82575.clear_semaphore_once = false;
185a551c94aSIdo Barnea			e1000_put_hw_semaphore_generic(hw);
186a551c94aSIdo Barnea			for (i = 0; i < timeout; i++) {
187a551c94aSIdo Barnea				swsm = E1000_READ_REG(hw, E1000_SWSM);
188a551c94aSIdo Barnea				if (!(swsm & E1000_SWSM_SMBI))
189a551c94aSIdo Barnea					break;
190a551c94aSIdo Barnea
191a551c94aSIdo Barnea				usec_delay(50);
192a551c94aSIdo Barnea			}
193a551c94aSIdo Barnea		}
194a551c94aSIdo Barnea
195a551c94aSIdo Barnea		/* If we do not have the semaphore here, we have to give up. */
196a551c94aSIdo Barnea		if (i == timeout) {
197a551c94aSIdo Barnea			DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
198a551c94aSIdo Barnea			return -E1000_ERR_NVM;
199a551c94aSIdo Barnea		}
200a551c94aSIdo Barnea	}
201a551c94aSIdo Barnea
202a551c94aSIdo Barnea	/* Get the FW semaphore. */
203a551c94aSIdo Barnea	for (i = 0; i < timeout; i++) {
204a551c94aSIdo Barnea		swsm = E1000_READ_REG(hw, E1000_SWSM);
205a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
206a551c94aSIdo Barnea
207a551c94aSIdo Barnea		/* Semaphore acquired if bit latched */
208a551c94aSIdo Barnea		if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
209a551c94aSIdo Barnea			break;
210a551c94aSIdo Barnea
211a551c94aSIdo Barnea		usec_delay(50);
212a551c94aSIdo Barnea	}
213a551c94aSIdo Barnea
214a551c94aSIdo Barnea	if (i == timeout) {
215a551c94aSIdo Barnea		/* Release semaphores */
216a551c94aSIdo Barnea		e1000_put_hw_semaphore_generic(hw);
217a551c94aSIdo Barnea		DEBUGOUT("Driver can't access the NVM\n");
218a551c94aSIdo Barnea		return -E1000_ERR_NVM;
219a551c94aSIdo Barnea	}
220a551c94aSIdo Barnea
221a551c94aSIdo Barnea	return E1000_SUCCESS;
222a551c94aSIdo Barnea}
223a551c94aSIdo Barnea
224a551c94aSIdo Barnea/**
225a551c94aSIdo Barnea *  e1000_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
226a551c94aSIdo Barnea *  @hw: pointer to the HW structure
227a551c94aSIdo Barnea *  @offset: offset of word in the Shadow Ram to read
228a551c94aSIdo Barnea *  @words: number of words to read
229a551c94aSIdo Barnea *  @data: word read from the Shadow Ram
230a551c94aSIdo Barnea *
231a551c94aSIdo Barnea *  Reads a 16 bit word from the Shadow Ram using the EERD register.
232a551c94aSIdo Barnea *  Uses necessary synchronization semaphores.
233a551c94aSIdo Barnea **/
234a551c94aSIdo Barneas32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
235a551c94aSIdo Barnea			     u16 *data)
236a551c94aSIdo Barnea{
237a551c94aSIdo Barnea	s32 status = E1000_SUCCESS;
238a551c94aSIdo Barnea	u16 i, count;
239a551c94aSIdo Barnea
240a551c94aSIdo Barnea	DEBUGFUNC("e1000_read_nvm_srrd_i210");
241a551c94aSIdo Barnea
242a551c94aSIdo Barnea	/* We cannot hold synchronization semaphores for too long,
243a551c94aSIdo Barnea	 * because of forceful takeover procedure. However it is more efficient
244a551c94aSIdo Barnea	 * to read in bursts than synchronizing access for each word. */
245a551c94aSIdo Barnea	for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
246a551c94aSIdo Barnea		count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
247a551c94aSIdo Barnea			E1000_EERD_EEWR_MAX_COUNT : (words - i);
248a551c94aSIdo Barnea		if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
249a551c94aSIdo Barnea			status = e1000_read_nvm_eerd(hw, offset, count,
250a551c94aSIdo Barnea						     data + i);
251a551c94aSIdo Barnea			hw->nvm.ops.release(hw);
252a551c94aSIdo Barnea		} else {
253a551c94aSIdo Barnea			status = E1000_ERR_SWFW_SYNC;
254a551c94aSIdo Barnea		}
255a551c94aSIdo Barnea
256a551c94aSIdo Barnea		if (status != E1000_SUCCESS)
257a551c94aSIdo Barnea			break;
258a551c94aSIdo Barnea	}
259a551c94aSIdo Barnea
260a551c94aSIdo Barnea	return status;
261a551c94aSIdo Barnea}
262a551c94aSIdo Barnea
263a551c94aSIdo Barnea/**
264a551c94aSIdo Barnea *  e1000_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
265a551c94aSIdo Barnea *  @hw: pointer to the HW structure
266a551c94aSIdo Barnea *  @offset: offset within the Shadow RAM to be written to
267a551c94aSIdo Barnea *  @words: number of words to write
268a551c94aSIdo Barnea *  @data: 16 bit word(s) to be written to the Shadow RAM
269a551c94aSIdo Barnea *
270a551c94aSIdo Barnea *  Writes data to Shadow RAM at offset using EEWR register.
271a551c94aSIdo Barnea *
272a551c94aSIdo Barnea *  If e1000_update_nvm_checksum is not called after this function , the
273a551c94aSIdo Barnea *  data will not be committed to FLASH and also Shadow RAM will most likely
274a551c94aSIdo Barnea *  contain an invalid checksum.
275a551c94aSIdo Barnea *
276a551c94aSIdo Barnea *  If error code is returned, data and Shadow RAM may be inconsistent - buffer
277a551c94aSIdo Barnea *  partially written.
278a551c94aSIdo Barnea **/
279a551c94aSIdo Barneas32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
280a551c94aSIdo Barnea			      u16 *data)
281a551c94aSIdo Barnea{
282a551c94aSIdo Barnea	s32 status = E1000_SUCCESS;
283a551c94aSIdo Barnea	u16 i, count;
284a551c94aSIdo Barnea
285a551c94aSIdo Barnea	DEBUGFUNC("e1000_write_nvm_srwr_i210");
286a551c94aSIdo Barnea
287a551c94aSIdo Barnea	/* We cannot hold synchronization semaphores for too long,
288a551c94aSIdo Barnea	 * because of forceful takeover procedure. However it is more efficient
289a551c94aSIdo Barnea	 * to write in bursts than synchronizing access for each word. */
290a551c94aSIdo Barnea	for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
291a551c94aSIdo Barnea		count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
292a551c94aSIdo Barnea			E1000_EERD_EEWR_MAX_COUNT : (words - i);
293a551c94aSIdo Barnea		if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
294a551c94aSIdo Barnea			status = e1000_write_nvm_srwr(hw, offset, count,
295a551c94aSIdo Barnea						      data + i);
296a551c94aSIdo Barnea			hw->nvm.ops.release(hw);
297a551c94aSIdo Barnea		} else {
298a551c94aSIdo Barnea			status = E1000_ERR_SWFW_SYNC;
299a551c94aSIdo Barnea		}
300a551c94aSIdo Barnea
301a551c94aSIdo Barnea		if (status != E1000_SUCCESS)
302a551c94aSIdo Barnea			break;
303a551c94aSIdo Barnea	}
304a551c94aSIdo Barnea
305a551c94aSIdo Barnea	return status;
306a551c94aSIdo Barnea}
307a551c94aSIdo Barnea
308a551c94aSIdo Barnea/**
309a551c94aSIdo Barnea *  e1000_write_nvm_srwr - Write to Shadow Ram using EEWR
310a551c94aSIdo Barnea *  @hw: pointer to the HW structure
311a551c94aSIdo Barnea *  @offset: offset within the Shadow Ram to be written to
312a551c94aSIdo Barnea *  @words: number of words to write
313a551c94aSIdo Barnea *  @data: 16 bit word(s) to be written to the Shadow Ram
314a551c94aSIdo Barnea *
315a551c94aSIdo Barnea *  Writes data to Shadow Ram at offset using EEWR register.
316a551c94aSIdo Barnea *
317a551c94aSIdo Barnea *  If e1000_update_nvm_checksum is not called after this function , the
318a551c94aSIdo Barnea *  Shadow Ram will most likely contain an invalid checksum.
319a551c94aSIdo Barnea **/
320a551c94aSIdo BarneaSTATIC s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
321a551c94aSIdo Barnea				u16 *data)
322a551c94aSIdo Barnea{
323a551c94aSIdo Barnea	struct e1000_nvm_info *nvm = &hw->nvm;
324a551c94aSIdo Barnea	u32 i, k, eewr = 0;
325a551c94aSIdo Barnea	u32 attempts = 100000;
326a551c94aSIdo Barnea	s32 ret_val = E1000_SUCCESS;
327a551c94aSIdo Barnea
328a551c94aSIdo Barnea	DEBUGFUNC("e1000_write_nvm_srwr");
329a551c94aSIdo Barnea
330a551c94aSIdo Barnea	/*
331a551c94aSIdo Barnea	 * A check for invalid values:  offset too large, too many words,
332a551c94aSIdo Barnea	 * too many words for the offset, and not enough words.
333a551c94aSIdo Barnea	 */
334a551c94aSIdo Barnea	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
335a551c94aSIdo Barnea	    (words == 0)) {
336a551c94aSIdo Barnea		DEBUGOUT("nvm parameter(s) out of bounds\n");
337a551c94aSIdo Barnea		ret_val = -E1000_ERR_NVM;
338a551c94aSIdo Barnea		goto out;
339a551c94aSIdo Barnea	}
340a551c94aSIdo Barnea
341a551c94aSIdo Barnea	for (i = 0; i < words; i++) {
342a551c94aSIdo Barnea		eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
343a551c94aSIdo Barnea			(data[i] << E1000_NVM_RW_REG_DATA) |
344a551c94aSIdo Barnea			E1000_NVM_RW_REG_START;
345a551c94aSIdo Barnea
346a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_SRWR, eewr);
347a551c94aSIdo Barnea
348a551c94aSIdo Barnea		for (k = 0; k < attempts; k++) {
349a551c94aSIdo Barnea			if (E1000_NVM_RW_REG_DONE &
350a551c94aSIdo Barnea			    E1000_READ_REG(hw, E1000_SRWR)) {
351a551c94aSIdo Barnea				ret_val = E1000_SUCCESS;
352a551c94aSIdo Barnea				break;
353a551c94aSIdo Barnea			}
354a551c94aSIdo Barnea			usec_delay(5);
355a551c94aSIdo Barnea		}
356a551c94aSIdo Barnea
357a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
358a551c94aSIdo Barnea			DEBUGOUT("Shadow RAM write EEWR timed out\n");
359a551c94aSIdo Barnea			break;
360a551c94aSIdo Barnea		}
361a551c94aSIdo Barnea	}
362a551c94aSIdo Barnea
363a551c94aSIdo Barneaout:
364a551c94aSIdo Barnea	return ret_val;
365a551c94aSIdo Barnea}
366a551c94aSIdo Barnea
367a551c94aSIdo Barnea/** e1000_read_invm_word_i210 - Reads OTP
368a551c94aSIdo Barnea *  @hw: pointer to the HW structure
369a551c94aSIdo Barnea *  @address: the word address (aka eeprom offset) to read
370a551c94aSIdo Barnea *  @data: pointer to the data read
371a551c94aSIdo Barnea *
372a551c94aSIdo Barnea *  Reads 16-bit words from the OTP. Return error when the word is not
373a551c94aSIdo Barnea *  stored in OTP.
374a551c94aSIdo Barnea **/
375a551c94aSIdo BarneaSTATIC s32 e1000_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
376a551c94aSIdo Barnea{
377a551c94aSIdo Barnea	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
378a551c94aSIdo Barnea	u32 invm_dword;
379a551c94aSIdo Barnea	u16 i;
380a551c94aSIdo Barnea	u8 record_type, word_address;
381a551c94aSIdo Barnea
382a551c94aSIdo Barnea	DEBUGFUNC("e1000_read_invm_word_i210");
383a551c94aSIdo Barnea
384a551c94aSIdo Barnea	for (i = 0; i < E1000_INVM_SIZE; i++) {
385a551c94aSIdo Barnea		invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
386a551c94aSIdo Barnea		/* Get record type */
387a551c94aSIdo Barnea		record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
388a551c94aSIdo Barnea		if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
389a551c94aSIdo Barnea			break;
390a551c94aSIdo Barnea		if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
391a551c94aSIdo Barnea			i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
392a551c94aSIdo Barnea		if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
393a551c94aSIdo Barnea			i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
394a551c94aSIdo Barnea		if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
395a551c94aSIdo Barnea			word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
396a551c94aSIdo Barnea			if (word_address == address) {
397a551c94aSIdo Barnea				*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
398a551c94aSIdo Barnea				DEBUGOUT2("Read INVM Word 0x%02x = %x",
399a551c94aSIdo Barnea					  address, *data);
400a551c94aSIdo Barnea				status = E1000_SUCCESS;
401a551c94aSIdo Barnea				break;
402a551c94aSIdo Barnea			}
403a551c94aSIdo Barnea		}
404a551c94aSIdo Barnea	}
405a551c94aSIdo Barnea	if (status != E1000_SUCCESS)
406a551c94aSIdo Barnea		DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
407a551c94aSIdo Barnea	return status;
408a551c94aSIdo Barnea}
409a551c94aSIdo Barnea
410a551c94aSIdo Barnea/** e1000_read_invm_i210 - Read invm wrapper function for I210/I211
411a551c94aSIdo Barnea *  @hw: pointer to the HW structure
412a551c94aSIdo Barnea *  @address: the word address (aka eeprom offset) to read
413a551c94aSIdo Barnea *  @data: pointer to the data read
414a551c94aSIdo Barnea *
415a551c94aSIdo Barnea *  Wrapper function to return data formerly found in the NVM.
416a551c94aSIdo Barnea **/
417a551c94aSIdo BarneaSTATIC s32 e1000_read_invm_i210(struct e1000_hw *hw, u16 offset,
418a551c94aSIdo Barnea				u16 E1000_UNUSEDARG words, u16 *data)
419a551c94aSIdo Barnea{
420a551c94aSIdo Barnea	s32 ret_val = E1000_SUCCESS;
421a551c94aSIdo Barnea	UNREFERENCED_1PARAMETER(words);
422a551c94aSIdo Barnea
423a551c94aSIdo Barnea	DEBUGFUNC("e1000_read_invm_i210");
424a551c94aSIdo Barnea
425a551c94aSIdo Barnea	/* Only the MAC addr is required to be present in the iNVM */
426a551c94aSIdo Barnea	switch (offset) {
427a551c94aSIdo Barnea	case NVM_MAC_ADDR:
428a551c94aSIdo Barnea		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, &data[0]);
429a551c94aSIdo Barnea		ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+1,
430a551c94aSIdo Barnea						     &data[1]);
431a551c94aSIdo Barnea		ret_val |= e1000_read_invm_word_i210(hw, (u8)offset+2,
432a551c94aSIdo Barnea						     &data[2]);
433a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS)
434a551c94aSIdo Barnea			DEBUGOUT("MAC Addr not found in iNVM\n");
435a551c94aSIdo Barnea		break;
436a551c94aSIdo Barnea	case NVM_INIT_CTRL_2:
437a551c94aSIdo Barnea		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
438a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
439a551c94aSIdo Barnea			*data = NVM_INIT_CTRL_2_DEFAULT_I211;
440a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
441a551c94aSIdo Barnea		}
442a551c94aSIdo Barnea		break;
443a551c94aSIdo Barnea	case NVM_INIT_CTRL_4:
444a551c94aSIdo Barnea		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
445a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
446a551c94aSIdo Barnea			*data = NVM_INIT_CTRL_4_DEFAULT_I211;
447a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
448a551c94aSIdo Barnea		}
449a551c94aSIdo Barnea		break;
450a551c94aSIdo Barnea	case NVM_LED_1_CFG:
451a551c94aSIdo Barnea		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
452a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
453a551c94aSIdo Barnea			*data = NVM_LED_1_CFG_DEFAULT_I211;
454a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
455a551c94aSIdo Barnea		}
456a551c94aSIdo Barnea		break;
457a551c94aSIdo Barnea	case NVM_LED_0_2_CFG:
458a551c94aSIdo Barnea		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
459a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
460a551c94aSIdo Barnea			*data = NVM_LED_0_2_CFG_DEFAULT_I211;
461a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
462a551c94aSIdo Barnea		}
463a551c94aSIdo Barnea		break;
464a551c94aSIdo Barnea	case NVM_ID_LED_SETTINGS:
465a551c94aSIdo Barnea		ret_val = e1000_read_invm_word_i210(hw, (u8)offset, data);
466a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
467a551c94aSIdo Barnea			*data = ID_LED_RESERVED_FFFF;
468a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
469a551c94aSIdo Barnea		}
470a551c94aSIdo Barnea		break;
471a551c94aSIdo Barnea	case NVM_SUB_DEV_ID:
472a551c94aSIdo Barnea		*data = hw->subsystem_device_id;
473a551c94aSIdo Barnea		break;
474a551c94aSIdo Barnea	case NVM_SUB_VEN_ID:
475a551c94aSIdo Barnea		*data = hw->subsystem_vendor_id;
476a551c94aSIdo Barnea		break;
477a551c94aSIdo Barnea	case NVM_DEV_ID:
478a551c94aSIdo Barnea		*data = hw->device_id;
479a551c94aSIdo Barnea		break;
480a551c94aSIdo Barnea	case NVM_VEN_ID:
481a551c94aSIdo Barnea		*data = hw->vendor_id;
482a551c94aSIdo Barnea		break;
483a551c94aSIdo Barnea	default:
484a551c94aSIdo Barnea		DEBUGOUT1("NVM word 0x%02x is not mapped.\n", offset);
485a551c94aSIdo Barnea		*data = NVM_RESERVED_WORD;
486a551c94aSIdo Barnea		break;
487a551c94aSIdo Barnea	}
488a551c94aSIdo Barnea	return ret_val;
489a551c94aSIdo Barnea}
490a551c94aSIdo Barnea
491a551c94aSIdo Barnea/**
492a551c94aSIdo Barnea *  e1000_read_invm_version - Reads iNVM version and image type
493a551c94aSIdo Barnea *  @hw: pointer to the HW structure
494a551c94aSIdo Barnea *  @invm_ver: version structure for the version read
495a551c94aSIdo Barnea *
496a551c94aSIdo Barnea *  Reads iNVM version and image type.
497a551c94aSIdo Barnea **/
498a551c94aSIdo Barneas32 e1000_read_invm_version(struct e1000_hw *hw,
499a551c94aSIdo Barnea			    struct e1000_fw_version *invm_ver)
500a551c94aSIdo Barnea{
501a551c94aSIdo Barnea	u32 *record = NULL;
502a551c94aSIdo Barnea	u32 *next_record = NULL;
503a551c94aSIdo Barnea	u32 i = 0;
504a551c94aSIdo Barnea	u32 invm_dword = 0;
505a551c94aSIdo Barnea	u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
506a551c94aSIdo Barnea					     E1000_INVM_RECORD_SIZE_IN_BYTES);
507a551c94aSIdo Barnea	u32 buffer[E1000_INVM_SIZE];
508a551c94aSIdo Barnea	s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
509a551c94aSIdo Barnea	u16 version = 0;
510a551c94aSIdo Barnea
511a551c94aSIdo Barnea	DEBUGFUNC("e1000_read_invm_version");
512a551c94aSIdo Barnea
513a551c94aSIdo Barnea	/* Read iNVM memory */
514a551c94aSIdo Barnea	for (i = 0; i < E1000_INVM_SIZE; i++) {
515a551c94aSIdo Barnea		invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
516a551c94aSIdo Barnea		buffer[i] = invm_dword;
517a551c94aSIdo Barnea	}
518a551c94aSIdo Barnea
519a551c94aSIdo Barnea	/* Read version number */
520a551c94aSIdo Barnea	for (i = 1; i < invm_blocks; i++) {
521a551c94aSIdo Barnea		record = &buffer[invm_blocks - i];
522a551c94aSIdo Barnea		next_record = &buffer[invm_blocks - i + 1];
523a551c94aSIdo Barnea
524a551c94aSIdo Barnea		/* Check if we have first version location used */
525a551c94aSIdo Barnea		if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
526a551c94aSIdo Barnea			version = 0;
527a551c94aSIdo Barnea			status = E1000_SUCCESS;
528a551c94aSIdo Barnea			break;
529a551c94aSIdo Barnea		}
530a551c94aSIdo Barnea		/* Check if we have second version location used */
531a551c94aSIdo Barnea		else if ((i == 1) &&
532a551c94aSIdo Barnea			 ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
533a551c94aSIdo Barnea			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
534a551c94aSIdo Barnea			status = E1000_SUCCESS;
535a551c94aSIdo Barnea			break;
536a551c94aSIdo Barnea		}
537a551c94aSIdo Barnea		/*
538a551c94aSIdo Barnea		 * Check if we have odd version location
539a551c94aSIdo Barnea		 * used and it is the last one used
540a551c94aSIdo Barnea		 */
541a551c94aSIdo Barnea		else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
542a551c94aSIdo Barnea			 ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
543a551c94aSIdo Barnea			 (i != 1))) {
544a551c94aSIdo Barnea			version = (*next_record & E1000_INVM_VER_FIELD_TWO)
545a551c94aSIdo Barnea				  >> 13;
546a551c94aSIdo Barnea			status = E1000_SUCCESS;
547a551c94aSIdo Barnea			break;
548a551c94aSIdo Barnea		}
549a551c94aSIdo Barnea		/*
550a551c94aSIdo Barnea		 * Check if we have even version location
551a551c94aSIdo Barnea		 * used and it is the last one used
552a551c94aSIdo Barnea		 */
553a551c94aSIdo Barnea		else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
554a551c94aSIdo Barnea			 ((*record & 0x3) == 0)) {
555a551c94aSIdo Barnea			version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
556a551c94aSIdo Barnea			status = E1000_SUCCESS;
557a551c94aSIdo Barnea			break;
558a551c94aSIdo Barnea		}
559a551c94aSIdo Barnea	}
560a551c94aSIdo Barnea
561a551c94aSIdo Barnea	if (status == E1000_SUCCESS) {
562a551c94aSIdo Barnea		invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
563a551c94aSIdo Barnea					>> E1000_INVM_MAJOR_SHIFT;
564a551c94aSIdo Barnea		invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
565a551c94aSIdo Barnea	}
566a551c94aSIdo Barnea	/* Read Image Type */
567a551c94aSIdo Barnea	for (i = 1; i < invm_blocks; i++) {
568a551c94aSIdo Barnea		record = &buffer[invm_blocks - i];
569a551c94aSIdo Barnea		next_record = &buffer[invm_blocks - i + 1];
570a551c94aSIdo Barnea
571a551c94aSIdo Barnea		/* Check if we have image type in first location used */
572a551c94aSIdo Barnea		if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
573a551c94aSIdo Barnea			invm_ver->invm_img_type = 0;
574a551c94aSIdo Barnea			status = E1000_SUCCESS;
575a551c94aSIdo Barnea			break;
576a551c94aSIdo Barnea		}
577a551c94aSIdo Barnea		/* Check if we have image type in first location used */
578a551c94aSIdo Barnea		else if ((((*record & 0x3) == 0) &&
579a551c94aSIdo Barnea			 ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
580a551c94aSIdo Barnea			 ((((*record & 0x3) != 0) && (i != 1)))) {
581a551c94aSIdo Barnea			invm_ver->invm_img_type =
582a551c94aSIdo Barnea				(*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
583a551c94aSIdo Barnea			status = E1000_SUCCESS;
584a551c94aSIdo Barnea			break;
585a551c94aSIdo Barnea		}
586a551c94aSIdo Barnea	}
587a551c94aSIdo Barnea	return status;
588a551c94aSIdo Barnea}
589a551c94aSIdo Barnea
590a551c94aSIdo Barnea/**
591a551c94aSIdo Barnea *  e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
592a551c94aSIdo Barnea *  @hw: pointer to the HW structure
593a551c94aSIdo Barnea *
594a551c94aSIdo Barnea *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
595a551c94aSIdo Barnea *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
596a551c94aSIdo Barnea **/
597a551c94aSIdo Barneas32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw)
598a551c94aSIdo Barnea{
599a551c94aSIdo Barnea	s32 status = E1000_SUCCESS;
600a551c94aSIdo Barnea	s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
601a551c94aSIdo Barnea
602a551c94aSIdo Barnea	DEBUGFUNC("e1000_validate_nvm_checksum_i210");
603a551c94aSIdo Barnea
604a551c94aSIdo Barnea	if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
605a551c94aSIdo Barnea
606a551c94aSIdo Barnea		/*
607a551c94aSIdo Barnea		 * Replace the read function with semaphore grabbing with
608a551c94aSIdo Barnea		 * the one that skips this for a while.
609a551c94aSIdo Barnea		 * We have semaphore taken already here.
610a551c94aSIdo Barnea		 */
611a551c94aSIdo Barnea		read_op_ptr = hw->nvm.ops.read;
612a551c94aSIdo Barnea		hw->nvm.ops.read = e1000_read_nvm_eerd;
613a551c94aSIdo Barnea
614a551c94aSIdo Barnea		status = e1000_validate_nvm_checksum_generic(hw);
615a551c94aSIdo Barnea
616a551c94aSIdo Barnea		/* Revert original read operation. */
617a551c94aSIdo Barnea		hw->nvm.ops.read = read_op_ptr;
618a551c94aSIdo Barnea
619a551c94aSIdo Barnea		hw->nvm.ops.release(hw);
620a551c94aSIdo Barnea	} else {
621a551c94aSIdo Barnea		status = E1000_ERR_SWFW_SYNC;
622a551c94aSIdo Barnea	}
623a551c94aSIdo Barnea
624a551c94aSIdo Barnea	return status;
625a551c94aSIdo Barnea}
626a551c94aSIdo Barnea
627a551c94aSIdo Barnea
628a551c94aSIdo Barnea/**
629a551c94aSIdo Barnea *  e1000_update_nvm_checksum_i210 - Update EEPROM checksum
630a551c94aSIdo Barnea *  @hw: pointer to the HW structure
631a551c94aSIdo Barnea *
632a551c94aSIdo Barnea *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
633a551c94aSIdo Barnea *  up to the checksum.  Then calculates the EEPROM checksum and writes the
634a551c94aSIdo Barnea *  value to the EEPROM. Next commit EEPROM data onto the Flash.
635a551c94aSIdo Barnea **/
636a551c94aSIdo Barneas32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
637a551c94aSIdo Barnea{
638a551c94aSIdo Barnea	s32 ret_val;
639a551c94aSIdo Barnea	u16 checksum = 0;
640a551c94aSIdo Barnea	u16 i, nvm_data;
641a551c94aSIdo Barnea
642a551c94aSIdo Barnea	DEBUGFUNC("e1000_update_nvm_checksum_i210");
643a551c94aSIdo Barnea
644a551c94aSIdo Barnea	/*
645a551c94aSIdo Barnea	 * Read the first word from the EEPROM. If this times out or fails, do
646a551c94aSIdo Barnea	 * not continue or we could be in for a very long wait while every
647a551c94aSIdo Barnea	 * EEPROM read fails
648a551c94aSIdo Barnea	 */
649a551c94aSIdo Barnea	ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data);
650a551c94aSIdo Barnea	if (ret_val != E1000_SUCCESS) {
651a551c94aSIdo Barnea		DEBUGOUT("EEPROM read failed\n");
652a551c94aSIdo Barnea		goto out;
653a551c94aSIdo Barnea	}
654a551c94aSIdo Barnea
655a551c94aSIdo Barnea	if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
656a551c94aSIdo Barnea		/*
657a551c94aSIdo Barnea		 * Do not use hw->nvm.ops.write, hw->nvm.ops.read
658a551c94aSIdo Barnea		 * because we do not want to take the synchronization
659a551c94aSIdo Barnea		 * semaphores twice here.
660a551c94aSIdo Barnea		 */
661a551c94aSIdo Barnea
662a551c94aSIdo Barnea		for (i = 0; i < NVM_CHECKSUM_REG; i++) {
663a551c94aSIdo Barnea			ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data);
664a551c94aSIdo Barnea			if (ret_val) {
665a551c94aSIdo Barnea				hw->nvm.ops.release(hw);
666a551c94aSIdo Barnea				DEBUGOUT("NVM Read Error while updating checksum.\n");
667a551c94aSIdo Barnea				goto out;
668a551c94aSIdo Barnea			}
669a551c94aSIdo Barnea			checksum += nvm_data;
670a551c94aSIdo Barnea		}
671a551c94aSIdo Barnea		checksum = (u16) NVM_SUM - checksum;
672a551c94aSIdo Barnea		ret_val = e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
673a551c94aSIdo Barnea						&checksum);
674a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS) {
675a551c94aSIdo Barnea			hw->nvm.ops.release(hw);
676a551c94aSIdo Barnea			DEBUGOUT("NVM Write Error while updating checksum.\n");
677a551c94aSIdo Barnea			goto out;
678a551c94aSIdo Barnea		}
679a551c94aSIdo Barnea
680a551c94aSIdo Barnea		hw->nvm.ops.release(hw);
681a551c94aSIdo Barnea
682a551c94aSIdo Barnea		ret_val = e1000_update_flash_i210(hw);
683a551c94aSIdo Barnea	} else {
684a551c94aSIdo Barnea		ret_val = E1000_ERR_SWFW_SYNC;
685a551c94aSIdo Barnea	}
686a551c94aSIdo Barneaout:
687a551c94aSIdo Barnea	return ret_val;
688a551c94aSIdo Barnea}
689a551c94aSIdo Barnea
690a551c94aSIdo Barnea/**
691a551c94aSIdo Barnea *  e1000_get_flash_presence_i210 - Check if flash device is detected.
692a551c94aSIdo Barnea *  @hw: pointer to the HW structure
693a551c94aSIdo Barnea *
694a551c94aSIdo Barnea **/
695a551c94aSIdo Barneabool e1000_get_flash_presence_i210(struct e1000_hw *hw)
696a551c94aSIdo Barnea{
697a551c94aSIdo Barnea	u32 eec = 0;
698a551c94aSIdo Barnea	bool ret_val = false;
699a551c94aSIdo Barnea
700a551c94aSIdo Barnea	DEBUGFUNC("e1000_get_flash_presence_i210");
701a551c94aSIdo Barnea
702a551c94aSIdo Barnea	eec = E1000_READ_REG(hw, E1000_EECD);
703a551c94aSIdo Barnea
704a551c94aSIdo Barnea	if (eec & E1000_EECD_FLASH_DETECTED_I210)
705a551c94aSIdo Barnea		ret_val = true;
706a551c94aSIdo Barnea
707a551c94aSIdo Barnea	return ret_val;
708a551c94aSIdo Barnea}
709a551c94aSIdo Barnea
710a551c94aSIdo Barnea/**
711a551c94aSIdo Barnea *  e1000_update_flash_i210 - Commit EEPROM to the flash
712a551c94aSIdo Barnea *  @hw: pointer to the HW structure
713a551c94aSIdo Barnea *
714a551c94aSIdo Barnea **/
715a551c94aSIdo Barneas32 e1000_update_flash_i210(struct e1000_hw *hw)
716a551c94aSIdo Barnea{
717a551c94aSIdo Barnea	s32 ret_val;
718a551c94aSIdo Barnea	u32 flup;
719a551c94aSIdo Barnea
720a551c94aSIdo Barnea	DEBUGFUNC("e1000_update_flash_i210");
721a551c94aSIdo Barnea
722a551c94aSIdo Barnea	ret_val = e1000_pool_flash_update_done_i210(hw);
723a551c94aSIdo Barnea	if (ret_val == -E1000_ERR_NVM) {
724a551c94aSIdo Barnea		DEBUGOUT("Flash update time out\n");
725a551c94aSIdo Barnea		goto out;
726a551c94aSIdo Barnea	}
727a551c94aSIdo Barnea
728a551c94aSIdo Barnea	flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I210;
729a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_EECD, flup);
730a551c94aSIdo Barnea
731a551c94aSIdo Barnea	ret_val = e1000_pool_flash_update_done_i210(hw);
732a551c94aSIdo Barnea	if (ret_val == E1000_SUCCESS)
733a551c94aSIdo Barnea		DEBUGOUT("Flash update complete\n");
734a551c94aSIdo Barnea	else
735a551c94aSIdo Barnea		DEBUGOUT("Flash update time out\n");
736a551c94aSIdo Barnea
737a551c94aSIdo Barneaout:
738a551c94aSIdo Barnea	return ret_val;
739a551c94aSIdo Barnea}
740a551c94aSIdo Barnea
741a551c94aSIdo Barnea/**
742a551c94aSIdo Barnea *  e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
743a551c94aSIdo Barnea *  @hw: pointer to the HW structure
744a551c94aSIdo Barnea *
745a551c94aSIdo Barnea **/
746a551c94aSIdo Barneas32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
747a551c94aSIdo Barnea{
748a551c94aSIdo Barnea	s32 ret_val = -E1000_ERR_NVM;
749a551c94aSIdo Barnea	u32 i, reg;
750a551c94aSIdo Barnea
751a551c94aSIdo Barnea	DEBUGFUNC("e1000_pool_flash_update_done_i210");
752a551c94aSIdo Barnea
753a551c94aSIdo Barnea	for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
754a551c94aSIdo Barnea		reg = E1000_READ_REG(hw, E1000_EECD);
755a551c94aSIdo Barnea		if (reg & E1000_EECD_FLUDONE_I210) {
756a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
757a551c94aSIdo Barnea			break;
758a551c94aSIdo Barnea		}
759a551c94aSIdo Barnea		usec_delay(5);
760a551c94aSIdo Barnea	}
761a551c94aSIdo Barnea
762a551c94aSIdo Barnea	return ret_val;
763a551c94aSIdo Barnea}
764a551c94aSIdo Barnea
765a551c94aSIdo Barnea/**
766a551c94aSIdo Barnea *  e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers
767a551c94aSIdo Barnea *  @hw: pointer to the HW structure
768a551c94aSIdo Barnea *
769a551c94aSIdo Barnea *  Initialize the i210/i211 NVM parameters and function pointers.
770a551c94aSIdo Barnea **/
771a551c94aSIdo BarneaSTATIC s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
772a551c94aSIdo Barnea{
773a551c94aSIdo Barnea	s32 ret_val;
774a551c94aSIdo Barnea	struct e1000_nvm_info *nvm = &hw->nvm;
775a551c94aSIdo Barnea
776a551c94aSIdo Barnea	DEBUGFUNC("e1000_init_nvm_params_i210");
777a551c94aSIdo Barnea
778a551c94aSIdo Barnea	ret_val = e1000_init_nvm_params_82575(hw);
779a551c94aSIdo Barnea	nvm->ops.acquire = e1000_acquire_nvm_i210;
780a551c94aSIdo Barnea	nvm->ops.release = e1000_release_nvm_i210;
781a551c94aSIdo Barnea	nvm->ops.valid_led_default = e1000_valid_led_default_i210;
782a551c94aSIdo Barnea	if (e1000_get_flash_presence_i210(hw)) {
783a551c94aSIdo Barnea		hw->nvm.type = e1000_nvm_flash_hw;
784a551c94aSIdo Barnea		nvm->ops.read    = e1000_read_nvm_srrd_i210;
785a551c94aSIdo Barnea		nvm->ops.write   = e1000_write_nvm_srwr_i210;
786a551c94aSIdo Barnea		nvm->ops.validate = e1000_validate_nvm_checksum_i210;
787a551c94aSIdo Barnea		nvm->ops.update   = e1000_update_nvm_checksum_i210;
788a551c94aSIdo Barnea	} else {
789a551c94aSIdo Barnea		hw->nvm.type = e1000_nvm_invm;
790a551c94aSIdo Barnea		nvm->ops.read     = e1000_read_invm_i210;
791a551c94aSIdo Barnea		nvm->ops.write    = e1000_null_write_nvm;
792a551c94aSIdo Barnea		nvm->ops.validate = e1000_null_ops_generic;
793a551c94aSIdo Barnea		nvm->ops.update   = e1000_null_ops_generic;
794a551c94aSIdo Barnea	}
795a551c94aSIdo Barnea	return ret_val;
796a551c94aSIdo Barnea}
797a551c94aSIdo Barnea
798a551c94aSIdo Barnea/**
799a551c94aSIdo Barnea *  e1000_init_function_pointers_i210 - Init func ptrs.
800a551c94aSIdo Barnea *  @hw: pointer to the HW structure
801a551c94aSIdo Barnea *
802a551c94aSIdo Barnea *  Called to initialize all function pointers and parameters.
803a551c94aSIdo Barnea **/
804a551c94aSIdo Barneavoid e1000_init_function_pointers_i210(struct e1000_hw *hw)
805a551c94aSIdo Barnea{
806a551c94aSIdo Barnea	e1000_init_function_pointers_82575(hw);
807a551c94aSIdo Barnea	hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
808a551c94aSIdo Barnea
809a551c94aSIdo Barnea	return;
810a551c94aSIdo Barnea}
811a551c94aSIdo Barnea
812a551c94aSIdo Barnea/**
813a551c94aSIdo Barnea *  e1000_valid_led_default_i210 - Verify a valid default LED config
814a551c94aSIdo Barnea *  @hw: pointer to the HW structure
815a551c94aSIdo Barnea *  @data: pointer to the NVM (EEPROM)
816a551c94aSIdo Barnea *
817a551c94aSIdo Barnea *  Read the EEPROM for the current default LED configuration.  If the
818a551c94aSIdo Barnea *  LED configuration is not valid, set to a valid LED configuration.
819a551c94aSIdo Barnea **/
820a551c94aSIdo BarneaSTATIC s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
821a551c94aSIdo Barnea{
822a551c94aSIdo Barnea	s32 ret_val;
823a551c94aSIdo Barnea
824a551c94aSIdo Barnea	DEBUGFUNC("e1000_valid_led_default_i210");
825a551c94aSIdo Barnea
826a551c94aSIdo Barnea	ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
827a551c94aSIdo Barnea	if (ret_val) {
828a551c94aSIdo Barnea		DEBUGOUT("NVM Read Error\n");
829a551c94aSIdo Barnea		goto out;
830a551c94aSIdo Barnea	}
831a551c94aSIdo Barnea
832a551c94aSIdo Barnea	if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
833a551c94aSIdo Barnea		switch (hw->phy.media_type) {
834a551c94aSIdo Barnea		case e1000_media_type_internal_serdes:
835a551c94aSIdo Barnea			*data = ID_LED_DEFAULT_I210_SERDES;
836a551c94aSIdo Barnea			break;
837a551c94aSIdo Barnea		case e1000_media_type_copper:
838a551c94aSIdo Barnea		default:
839a551c94aSIdo Barnea			*data = ID_LED_DEFAULT_I210;
840a551c94aSIdo Barnea			break;
841a551c94aSIdo Barnea		}
842a551c94aSIdo Barnea	}
843a551c94aSIdo Barneaout:
844a551c94aSIdo Barnea	return ret_val;
845a551c94aSIdo Barnea}
846a551c94aSIdo Barnea
847a551c94aSIdo Barnea/**
848a551c94aSIdo Barnea *  __e1000_access_xmdio_reg - Read/write XMDIO register
849a551c94aSIdo Barnea *  @hw: pointer to the HW structure
850a551c94aSIdo Barnea *  @address: XMDIO address to program
851a551c94aSIdo Barnea *  @dev_addr: device address to program
852a551c94aSIdo Barnea *  @data: pointer to value to read/write from/to the XMDIO address
853a551c94aSIdo Barnea *  @read: boolean flag to indicate read or write
854a551c94aSIdo Barnea **/
855a551c94aSIdo BarneaSTATIC s32 __e1000_access_xmdio_reg(struct e1000_hw *hw, u16 address,
856a551c94aSIdo Barnea				    u8 dev_addr, u16 *data, bool read)
857a551c94aSIdo Barnea{
858a551c94aSIdo Barnea	s32 ret_val;
859a551c94aSIdo Barnea
860a551c94aSIdo Barnea	DEBUGFUNC("__e1000_access_xmdio_reg");
861a551c94aSIdo Barnea
862a551c94aSIdo Barnea	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
863a551c94aSIdo Barnea	if (ret_val)
864a551c94aSIdo Barnea		return ret_val;
865a551c94aSIdo Barnea
866a551c94aSIdo Barnea	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
867a551c94aSIdo Barnea	if (ret_val)
868a551c94aSIdo Barnea		return ret_val;
869a551c94aSIdo Barnea
870a551c94aSIdo Barnea	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
871a551c94aSIdo Barnea							 dev_addr);
872a551c94aSIdo Barnea	if (ret_val)
873a551c94aSIdo Barnea		return ret_val;
874a551c94aSIdo Barnea
875a551c94aSIdo Barnea	if (read)
876a551c94aSIdo Barnea		ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
877a551c94aSIdo Barnea	else
878a551c94aSIdo Barnea		ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
879a551c94aSIdo Barnea	if (ret_val)
880a551c94aSIdo Barnea		return ret_val;
881a551c94aSIdo Barnea
882a551c94aSIdo Barnea	/* Recalibrate the device back to 0 */
883a551c94aSIdo Barnea	ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
884a551c94aSIdo Barnea	if (ret_val)
885a551c94aSIdo Barnea		return ret_val;
886a551c94aSIdo Barnea
887a551c94aSIdo Barnea	return ret_val;
888a551c94aSIdo Barnea}
889a551c94aSIdo Barnea
890a551c94aSIdo Barnea/**
891a551c94aSIdo Barnea *  e1000_read_xmdio_reg - Read XMDIO register
892a551c94aSIdo Barnea *  @hw: pointer to the HW structure
893a551c94aSIdo Barnea *  @addr: XMDIO address to program
894a551c94aSIdo Barnea *  @dev_addr: device address to program
895a551c94aSIdo Barnea *  @data: value to be read from the EMI address
896a551c94aSIdo Barnea **/
897a551c94aSIdo Barneas32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
898a551c94aSIdo Barnea{
899a551c94aSIdo Barnea	DEBUGFUNC("e1000_read_xmdio_reg");
900a551c94aSIdo Barnea
901a551c94aSIdo Barnea	return __e1000_access_xmdio_reg(hw, addr, dev_addr, data, true);
902a551c94aSIdo Barnea}
903a551c94aSIdo Barnea
904a551c94aSIdo Barnea/**
905a551c94aSIdo Barnea *  e1000_write_xmdio_reg - Write XMDIO register
906a551c94aSIdo Barnea *  @hw: pointer to the HW structure
907a551c94aSIdo Barnea *  @addr: XMDIO address to program
908a551c94aSIdo Barnea *  @dev_addr: device address to program
909a551c94aSIdo Barnea *  @data: value to be written to the XMDIO address
910a551c94aSIdo Barnea **/
911a551c94aSIdo Barneas32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
912a551c94aSIdo Barnea{
913a551c94aSIdo Barnea	DEBUGFUNC("e1000_read_xmdio_reg");
914a551c94aSIdo Barnea
915a551c94aSIdo Barnea	return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, false);
916a551c94aSIdo Barnea}
917a551c94aSIdo Barnea
918a551c94aSIdo Barnea/**
919a551c94aSIdo Barnea * e1000_pll_workaround_i210
920a551c94aSIdo Barnea * @hw: pointer to the HW structure
921a551c94aSIdo Barnea *
922a551c94aSIdo Barnea * Works around an errata in the PLL circuit where it occasionally
923a551c94aSIdo Barnea * provides the wrong clock frequency after power up.
924a551c94aSIdo Barnea **/
925a551c94aSIdo BarneaSTATIC s32 e1000_pll_workaround_i210(struct e1000_hw *hw)
926a551c94aSIdo Barnea{
927a551c94aSIdo Barnea	s32 ret_val;
928a551c94aSIdo Barnea	u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
929a551c94aSIdo Barnea	u16 nvm_word, phy_word, pci_word, tmp_nvm;
930a551c94aSIdo Barnea	int i;
931a551c94aSIdo Barnea
932a551c94aSIdo Barnea	/* Get and set needed register values */
933a551c94aSIdo Barnea	wuc = E1000_READ_REG(hw, E1000_WUC);
934a551c94aSIdo Barnea	mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
935a551c94aSIdo Barnea	reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
936a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_MDICNFG, reg_val);
937a551c94aSIdo Barnea
938a551c94aSIdo Barnea	/* Get data from NVM, or set default */
939a551c94aSIdo Barnea	ret_val = e1000_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
940a551c94aSIdo Barnea					    &nvm_word);
941a551c94aSIdo Barnea	if (ret_val != E1000_SUCCESS)
942a551c94aSIdo Barnea		nvm_word = E1000_INVM_DEFAULT_AL;
943a551c94aSIdo Barnea	tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
944a551c94aSIdo Barnea	for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
945a551c94aSIdo Barnea		/* check current state directly from internal PHY */
946a551c94aSIdo Barnea		e1000_read_phy_reg_gs40g(hw, (E1000_PHY_PLL_FREQ_PAGE |
947a551c94aSIdo Barnea					 E1000_PHY_PLL_FREQ_REG), &phy_word);
948a551c94aSIdo Barnea		if ((phy_word & E1000_PHY_PLL_UNCONF)
949a551c94aSIdo Barnea		    != E1000_PHY_PLL_UNCONF) {
950a551c94aSIdo Barnea			ret_val = E1000_SUCCESS;
951a551c94aSIdo Barnea			break;
952a551c94aSIdo Barnea		} else {
953a551c94aSIdo Barnea			ret_val = -E1000_ERR_PHY;
954a551c94aSIdo Barnea		}
955a551c94aSIdo Barnea		/* directly reset the internal PHY */
956a551c94aSIdo Barnea		ctrl = E1000_READ_REG(hw, E1000_CTRL);
957a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);
958a551c94aSIdo Barnea
959a551c94aSIdo Barnea		ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
960a551c94aSIdo Barnea		ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
961a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
962a551c94aSIdo Barnea
963a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_WUC, 0);
964a551c94aSIdo Barnea		reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
965a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val);
966a551c94aSIdo Barnea
967a551c94aSIdo Barnea		e1000_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
968a551c94aSIdo Barnea		pci_word |= E1000_PCI_PMCSR_D3;
969a551c94aSIdo Barnea		e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
970a551c94aSIdo Barnea		msec_delay(1);
971a551c94aSIdo Barnea		pci_word &= ~E1000_PCI_PMCSR_D3;
972a551c94aSIdo Barnea		e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
973a551c94aSIdo Barnea		reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
974a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_EEARBC_I210, reg_val);
975a551c94aSIdo Barnea
976a551c94aSIdo Barnea		/* restore WUC register */
977a551c94aSIdo Barnea		E1000_WRITE_REG(hw, E1000_WUC, wuc);
978a551c94aSIdo Barnea	}
979a551c94aSIdo Barnea	/* restore MDICNFG setting */
980a551c94aSIdo Barnea	E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
981a551c94aSIdo Barnea	return ret_val;
982a551c94aSIdo Barnea}
983a551c94aSIdo Barnea
984a551c94aSIdo Barnea/**
985a551c94aSIdo Barnea *  e1000_get_cfg_done_i210 - Read config done bit
986a551c94aSIdo Barnea *  @hw: pointer to the HW structure
987a551c94aSIdo Barnea *
988a551c94aSIdo Barnea *  Read the management control register for the config done bit for
989a551c94aSIdo Barnea *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
990a551c94aSIdo Barnea *  to read the config done bit, so an error is *ONLY* logged and returns
991a551c94aSIdo Barnea *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
992a551c94aSIdo Barnea *  would not be able to be reset or change link.
993a551c94aSIdo Barnea **/
994a551c94aSIdo BarneaSTATIC s32 e1000_get_cfg_done_i210(struct e1000_hw *hw)
995a551c94aSIdo Barnea{
996a551c94aSIdo Barnea	s32 timeout = PHY_CFG_TIMEOUT;
997a551c94aSIdo Barnea	u32 mask = E1000_NVM_CFG_DONE_PORT_0;
998a551c94aSIdo Barnea
999a551c94aSIdo Barnea	DEBUGFUNC("e1000_get_cfg_done_i210");
1000a551c94aSIdo Barnea
1001a551c94aSIdo Barnea	while (timeout) {
1002a551c94aSIdo Barnea		if (E1000_READ_REG(hw, E1000_EEMNGCTL_I210) & mask)
1003a551c94aSIdo Barnea			break;
1004a551c94aSIdo Barnea		msec_delay(1);
1005a551c94aSIdo Barnea		timeout--;
1006a551c94aSIdo Barnea	}
1007a551c94aSIdo Barnea	if (!timeout)
1008a551c94aSIdo Barnea		DEBUGOUT("MNG configuration cycle has not completed.\n");
1009a551c94aSIdo Barnea
1010a551c94aSIdo Barnea	return E1000_SUCCESS;
1011a551c94aSIdo Barnea}
1012a551c94aSIdo Barnea
1013a551c94aSIdo Barnea/**
1014a551c94aSIdo Barnea *  e1000_init_hw_i210 - Init hw for I210/I211
1015a551c94aSIdo Barnea *  @hw: pointer to the HW structure
1016a551c94aSIdo Barnea *
1017a551c94aSIdo Barnea *  Called to initialize hw for i210 hw family.
1018a551c94aSIdo Barnea **/
1019a551c94aSIdo Barneas32 e1000_init_hw_i210(struct e1000_hw *hw)
1020a551c94aSIdo Barnea{
1021a551c94aSIdo Barnea	s32 ret_val;
1022a551c94aSIdo Barnea
1023a551c94aSIdo Barnea	DEBUGFUNC("e1000_init_hw_i210");
1024a551c94aSIdo Barnea	if ((hw->mac.type >= e1000_i210) &&
1025a551c94aSIdo Barnea	    !(e1000_get_flash_presence_i210(hw))) {
1026a551c94aSIdo Barnea		ret_val = e1000_pll_workaround_i210(hw);
1027a551c94aSIdo Barnea		if (ret_val != E1000_SUCCESS)
1028a551c94aSIdo Barnea			return ret_val;
1029a551c94aSIdo Barnea	}
1030a551c94aSIdo Barnea	hw->phy.ops.get_cfg_done = e1000_get_cfg_done_i210;
1031a551c94aSIdo Barnea	ret_val = e1000_init_hw_82575(hw);
1032a551c94aSIdo Barnea	return ret_val;
1033a551c94aSIdo Barnea}