1177867Sjfv/******************************************************************************
2169240Sjfv
3248292Sjfv  Copyright (c) 2001-2013, Intel Corporation
4169240Sjfv  All rights reserved.
5169240Sjfv
6169240Sjfv  Redistribution and use in source and binary forms, with or without
7169240Sjfv  modification, are permitted provided that the following conditions are met:
8169240Sjfv
9169240Sjfv   1. Redistributions of source code must retain the above copyright notice,
10169240Sjfv      this list of conditions and the following disclaimer.
11169240Sjfv
12169240Sjfv   2. Redistributions in binary form must reproduce the above copyright
13169240Sjfv      notice, this list of conditions and the following disclaimer in the
14169240Sjfv      documentation and/or other materials provided with the distribution.
15169240Sjfv
16169240Sjfv   3. Neither the name of the Intel Corporation nor the names of its
17169240Sjfv      contributors may be used to endorse or promote products derived from
18169240Sjfv      this software without specific prior written permission.
19169240Sjfv
20169240Sjfv  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21169240Sjfv  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22169240Sjfv  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23169240Sjfv  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24169240Sjfv  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25169240Sjfv  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26169240Sjfv  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27169240Sjfv  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28169240Sjfv  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29169240Sjfv  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30169240Sjfv  POSSIBILITY OF SUCH DAMAGE.
31169240Sjfv
32177867Sjfv******************************************************************************/
33177867Sjfv/*$FreeBSD$*/
34169240Sjfv
35169589Sjfv#include "e1000_api.h"
36169240Sjfv
37190872Sjfvstatic void e1000_reload_nvm_generic(struct e1000_hw *hw);
38190872Sjfv
39169240Sjfv/**
40177867Sjfv *  e1000_init_nvm_ops_generic - Initialize NVM function pointers
41177867Sjfv *  @hw: pointer to the HW structure
42177867Sjfv *
43177867Sjfv *  Setups up the function pointers to no-op functions
44177867Sjfv **/
45177867Sjfvvoid e1000_init_nvm_ops_generic(struct e1000_hw *hw)
46177867Sjfv{
47177867Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
48177867Sjfv	DEBUGFUNC("e1000_init_nvm_ops_generic");
49177867Sjfv
50177867Sjfv	/* Initialize function pointers */
51177867Sjfv	nvm->ops.init_params = e1000_null_ops_generic;
52177867Sjfv	nvm->ops.acquire = e1000_null_ops_generic;
53177867Sjfv	nvm->ops.read = e1000_null_read_nvm;
54177867Sjfv	nvm->ops.release = e1000_null_nvm_generic;
55177867Sjfv	nvm->ops.reload = e1000_reload_nvm_generic;
56177867Sjfv	nvm->ops.update = e1000_null_ops_generic;
57177867Sjfv	nvm->ops.valid_led_default = e1000_null_led_default;
58177867Sjfv	nvm->ops.validate = e1000_null_ops_generic;
59177867Sjfv	nvm->ops.write = e1000_null_write_nvm;
60177867Sjfv}
61177867Sjfv
62177867Sjfv/**
63177867Sjfv *  e1000_null_nvm_read - No-op function, return 0
64177867Sjfv *  @hw: pointer to the HW structure
65177867Sjfv **/
66177867Sjfvs32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
67177867Sjfv{
68177867Sjfv	DEBUGFUNC("e1000_null_read_nvm");
69177867Sjfv	return E1000_SUCCESS;
70177867Sjfv}
71177867Sjfv
72177867Sjfv/**
73177867Sjfv *  e1000_null_nvm_generic - No-op function, return void
74177867Sjfv *  @hw: pointer to the HW structure
75177867Sjfv **/
76177867Sjfvvoid e1000_null_nvm_generic(struct e1000_hw *hw)
77177867Sjfv{
78177867Sjfv	DEBUGFUNC("e1000_null_nvm_generic");
79177867Sjfv	return;
80177867Sjfv}
81177867Sjfv
82177867Sjfv/**
83177867Sjfv *  e1000_null_led_default - No-op function, return 0
84177867Sjfv *  @hw: pointer to the HW structure
85177867Sjfv **/
86177867Sjfvs32 e1000_null_led_default(struct e1000_hw *hw, u16 *data)
87177867Sjfv{
88177867Sjfv	DEBUGFUNC("e1000_null_led_default");
89177867Sjfv	return E1000_SUCCESS;
90177867Sjfv}
91177867Sjfv
92177867Sjfv/**
93177867Sjfv *  e1000_null_write_nvm - No-op function, return 0
94177867Sjfv *  @hw: pointer to the HW structure
95177867Sjfv **/
96177867Sjfvs32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c)
97177867Sjfv{
98177867Sjfv	DEBUGFUNC("e1000_null_write_nvm");
99177867Sjfv	return E1000_SUCCESS;
100177867Sjfv}
101177867Sjfv
102177867Sjfv/**
103169240Sjfv *  e1000_raise_eec_clk - Raise EEPROM clock
104169589Sjfv *  @hw: pointer to the HW structure
105169589Sjfv *  @eecd: pointer to the EEPROM
106169240Sjfv *
107169240Sjfv *  Enable/Raise the EEPROM clock bit.
108169240Sjfv **/
109173788Sjfvstatic void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
110169240Sjfv{
111169240Sjfv	*eecd = *eecd | E1000_EECD_SK;
112169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, *eecd);
113169240Sjfv	E1000_WRITE_FLUSH(hw);
114169240Sjfv	usec_delay(hw->nvm.delay_usec);
115169240Sjfv}
116169240Sjfv
117169240Sjfv/**
118169240Sjfv *  e1000_lower_eec_clk - Lower EEPROM clock
119169589Sjfv *  @hw: pointer to the HW structure
120169589Sjfv *  @eecd: pointer to the EEPROM
121169240Sjfv *
122169240Sjfv *  Clear/Lower the EEPROM clock bit.
123169240Sjfv **/
124173788Sjfvstatic void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
125169240Sjfv{
126169240Sjfv	*eecd = *eecd & ~E1000_EECD_SK;
127169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, *eecd);
128169240Sjfv	E1000_WRITE_FLUSH(hw);
129169240Sjfv	usec_delay(hw->nvm.delay_usec);
130169240Sjfv}
131169240Sjfv
132169240Sjfv/**
133169240Sjfv *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
134169589Sjfv *  @hw: pointer to the HW structure
135169589Sjfv *  @data: data to send to the EEPROM
136169589Sjfv *  @count: number of bits to shift out
137169240Sjfv *
138169240Sjfv *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
139169240Sjfv *  "data" parameter will be shifted out to the EEPROM one bit at a time.
140169240Sjfv *  In order to do this, "data" must be broken down into bits.
141169240Sjfv **/
142173788Sjfvstatic void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
143169240Sjfv{
144169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
145169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
146169240Sjfv	u32 mask;
147169240Sjfv
148169240Sjfv	DEBUGFUNC("e1000_shift_out_eec_bits");
149169240Sjfv
150169240Sjfv	mask = 0x01 << (count - 1);
151169240Sjfv	if (nvm->type == e1000_nvm_eeprom_microwire)
152169240Sjfv		eecd &= ~E1000_EECD_DO;
153185353Sjfv	else
154185353Sjfv	if (nvm->type == e1000_nvm_eeprom_spi)
155169240Sjfv		eecd |= E1000_EECD_DO;
156169240Sjfv
157169240Sjfv	do {
158169240Sjfv		eecd &= ~E1000_EECD_DI;
159169240Sjfv
160169240Sjfv		if (data & mask)
161169240Sjfv			eecd |= E1000_EECD_DI;
162169240Sjfv
163169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
164169240Sjfv		E1000_WRITE_FLUSH(hw);
165169240Sjfv
166169240Sjfv		usec_delay(nvm->delay_usec);
167169240Sjfv
168169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
169169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
170169240Sjfv
171169240Sjfv		mask >>= 1;
172169240Sjfv	} while (mask);
173169240Sjfv
174169240Sjfv	eecd &= ~E1000_EECD_DI;
175169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, eecd);
176169240Sjfv}
177169240Sjfv
178169240Sjfv/**
179169240Sjfv *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
180169589Sjfv *  @hw: pointer to the HW structure
181169589Sjfv *  @count: number of bits to shift in
182169240Sjfv *
183169240Sjfv *  In order to read a register from the EEPROM, we need to shift 'count' bits
184169240Sjfv *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
185169240Sjfv *  the EEPROM (setting the SK bit), and then reading the value of the data out
186169240Sjfv *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
187169240Sjfv *  always be clear.
188169240Sjfv **/
189173788Sjfvstatic u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
190169240Sjfv{
191169240Sjfv	u32 eecd;
192169240Sjfv	u32 i;
193169240Sjfv	u16 data;
194169240Sjfv
195169240Sjfv	DEBUGFUNC("e1000_shift_in_eec_bits");
196169240Sjfv
197169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
198169240Sjfv
199169240Sjfv	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
200169240Sjfv	data = 0;
201169240Sjfv
202169240Sjfv	for (i = 0; i < count; i++) {
203169240Sjfv		data <<= 1;
204169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
205169240Sjfv
206169240Sjfv		eecd = E1000_READ_REG(hw, E1000_EECD);
207169240Sjfv
208169240Sjfv		eecd &= ~E1000_EECD_DI;
209169240Sjfv		if (eecd & E1000_EECD_DO)
210169240Sjfv			data |= 1;
211169240Sjfv
212169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
213169240Sjfv	}
214169240Sjfv
215169240Sjfv	return data;
216169240Sjfv}
217169240Sjfv
218169240Sjfv/**
219169240Sjfv *  e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
220169589Sjfv *  @hw: pointer to the HW structure
221169589Sjfv *  @ee_reg: EEPROM flag for polling
222169240Sjfv *
223169240Sjfv *  Polls the EEPROM status bit for either read or write completion based
224169240Sjfv *  upon the value of 'ee_reg'.
225169240Sjfv **/
226173788Sjfvs32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
227169240Sjfv{
228169240Sjfv	u32 attempts = 100000;
229169240Sjfv	u32 i, reg = 0;
230169240Sjfv
231169240Sjfv	DEBUGFUNC("e1000_poll_eerd_eewr_done");
232169240Sjfv
233169240Sjfv	for (i = 0; i < attempts; i++) {
234169240Sjfv		if (ee_reg == E1000_NVM_POLL_READ)
235169240Sjfv			reg = E1000_READ_REG(hw, E1000_EERD);
236169240Sjfv		else
237169240Sjfv			reg = E1000_READ_REG(hw, E1000_EEWR);
238169240Sjfv
239248292Sjfv		if (reg & E1000_NVM_RW_REG_DONE)
240248292Sjfv			return E1000_SUCCESS;
241169240Sjfv
242169240Sjfv		usec_delay(5);
243169240Sjfv	}
244169240Sjfv
245248292Sjfv	return -E1000_ERR_NVM;
246169240Sjfv}
247169240Sjfv
248169240Sjfv/**
249169240Sjfv *  e1000_acquire_nvm_generic - Generic request for access to EEPROM
250169589Sjfv *  @hw: pointer to the HW structure
251169240Sjfv *
252169240Sjfv *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
253169240Sjfv *  Return successful if access grant bit set, else clear the request for
254169240Sjfv *  EEPROM access and return -E1000_ERR_NVM (-1).
255169240Sjfv **/
256173788Sjfvs32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
257169240Sjfv{
258169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
259169240Sjfv	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
260169240Sjfv
261169240Sjfv	DEBUGFUNC("e1000_acquire_nvm_generic");
262169240Sjfv
263169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ);
264169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
265169240Sjfv
266169240Sjfv	while (timeout) {
267169240Sjfv		if (eecd & E1000_EECD_GNT)
268169240Sjfv			break;
269169240Sjfv		usec_delay(5);
270169240Sjfv		eecd = E1000_READ_REG(hw, E1000_EECD);
271169240Sjfv		timeout--;
272169240Sjfv	}
273169240Sjfv
274169240Sjfv	if (!timeout) {
275169240Sjfv		eecd &= ~E1000_EECD_REQ;
276169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
277169240Sjfv		DEBUGOUT("Could not acquire NVM grant\n");
278248292Sjfv		return -E1000_ERR_NVM;
279169240Sjfv	}
280169240Sjfv
281248292Sjfv	return E1000_SUCCESS;
282169240Sjfv}
283169240Sjfv
284169240Sjfv/**
285169240Sjfv *  e1000_standby_nvm - Return EEPROM to standby state
286169589Sjfv *  @hw: pointer to the HW structure
287169240Sjfv *
288169240Sjfv *  Return the EEPROM to a standby state.
289169240Sjfv **/
290173788Sjfvstatic void e1000_standby_nvm(struct e1000_hw *hw)
291169240Sjfv{
292169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
293169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
294169240Sjfv
295169240Sjfv	DEBUGFUNC("e1000_standby_nvm");
296169240Sjfv
297169240Sjfv	if (nvm->type == e1000_nvm_eeprom_microwire) {
298169240Sjfv		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
299169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
300169240Sjfv		E1000_WRITE_FLUSH(hw);
301169240Sjfv		usec_delay(nvm->delay_usec);
302169240Sjfv
303169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
304169240Sjfv
305169240Sjfv		/* Select EEPROM */
306169240Sjfv		eecd |= E1000_EECD_CS;
307169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
308169240Sjfv		E1000_WRITE_FLUSH(hw);
309169240Sjfv		usec_delay(nvm->delay_usec);
310169240Sjfv
311169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
312235527Sjfv	} else if (nvm->type == e1000_nvm_eeprom_spi) {
313169240Sjfv		/* Toggle CS to flush commands */
314169240Sjfv		eecd |= E1000_EECD_CS;
315169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
316169240Sjfv		E1000_WRITE_FLUSH(hw);
317169240Sjfv		usec_delay(nvm->delay_usec);
318169240Sjfv		eecd &= ~E1000_EECD_CS;
319169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
320169240Sjfv		E1000_WRITE_FLUSH(hw);
321169240Sjfv		usec_delay(nvm->delay_usec);
322169240Sjfv	}
323169240Sjfv}
324169240Sjfv
325169240Sjfv/**
326169240Sjfv *  e1000_stop_nvm - Terminate EEPROM command
327169589Sjfv *  @hw: pointer to the HW structure
328169240Sjfv *
329169240Sjfv *  Terminates the current command by inverting the EEPROM's chip select pin.
330169240Sjfv **/
331173788Sjfvvoid e1000_stop_nvm(struct e1000_hw *hw)
332169240Sjfv{
333169240Sjfv	u32 eecd;
334169240Sjfv
335169240Sjfv	DEBUGFUNC("e1000_stop_nvm");
336169240Sjfv
337169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
338169240Sjfv	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
339169240Sjfv		/* Pull CS high */
340169240Sjfv		eecd |= E1000_EECD_CS;
341169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
342169240Sjfv	} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
343176667Sjfv		/* CS on Microwire is active-high */
344169240Sjfv		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
345169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
346169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
347169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
348169240Sjfv	}
349169240Sjfv}
350169240Sjfv
351169240Sjfv/**
352169240Sjfv *  e1000_release_nvm_generic - Release exclusive access to EEPROM
353169589Sjfv *  @hw: pointer to the HW structure
354169240Sjfv *
355169240Sjfv *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
356169240Sjfv **/
357173788Sjfvvoid e1000_release_nvm_generic(struct e1000_hw *hw)
358169240Sjfv{
359169240Sjfv	u32 eecd;
360169240Sjfv
361169240Sjfv	DEBUGFUNC("e1000_release_nvm_generic");
362169240Sjfv
363169240Sjfv	e1000_stop_nvm(hw);
364169240Sjfv
365169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
366169240Sjfv	eecd &= ~E1000_EECD_REQ;
367169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, eecd);
368169240Sjfv}
369169240Sjfv
370169240Sjfv/**
371169240Sjfv *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
372169589Sjfv *  @hw: pointer to the HW structure
373169240Sjfv *
374169240Sjfv *  Setups the EEPROM for reading and writing.
375169240Sjfv **/
376173788Sjfvstatic s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
377169240Sjfv{
378169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
379169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
380169240Sjfv	u8 spi_stat_reg;
381169240Sjfv
382169240Sjfv	DEBUGFUNC("e1000_ready_nvm_eeprom");
383169240Sjfv
384169240Sjfv	if (nvm->type == e1000_nvm_eeprom_microwire) {
385169240Sjfv		/* Clear SK and DI */
386169240Sjfv		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
387169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
388169240Sjfv		/* Set CS */
389169240Sjfv		eecd |= E1000_EECD_CS;
390169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
391235527Sjfv	} else if (nvm->type == e1000_nvm_eeprom_spi) {
392218530Sjfv		u16 timeout = NVM_MAX_RETRY_SPI;
393218530Sjfv
394169240Sjfv		/* Clear SK and CS */
395169240Sjfv		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
396169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
397235527Sjfv		E1000_WRITE_FLUSH(hw);
398169240Sjfv		usec_delay(1);
399169240Sjfv
400248292Sjfv		/* Read "Status Register" repeatedly until the LSB is cleared.
401169240Sjfv		 * The EEPROM will signal that the command has been completed
402169240Sjfv		 * by clearing bit 0 of the internal status register.  If it's
403173788Sjfv		 * not cleared within 'timeout', then error out.
404173788Sjfv		 */
405169240Sjfv		while (timeout) {
406169240Sjfv			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
407235527Sjfv						 hw->nvm.opcode_bits);
408169240Sjfv			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
409169240Sjfv			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
410169240Sjfv				break;
411169240Sjfv
412169240Sjfv			usec_delay(5);
413169240Sjfv			e1000_standby_nvm(hw);
414169240Sjfv			timeout--;
415169240Sjfv		}
416169240Sjfv
417169240Sjfv		if (!timeout) {
418169240Sjfv			DEBUGOUT("SPI NVM Status error\n");
419248292Sjfv			return -E1000_ERR_NVM;
420169240Sjfv		}
421169240Sjfv	}
422169240Sjfv
423248292Sjfv	return E1000_SUCCESS;
424169240Sjfv}
425169240Sjfv
426169240Sjfv/**
427169240Sjfv *  e1000_read_nvm_spi - Read EEPROM's using SPI
428169589Sjfv *  @hw: pointer to the HW structure
429169589Sjfv *  @offset: offset of word in the EEPROM to read
430169589Sjfv *  @words: number of words to read
431169589Sjfv *  @data: word read from the EEPROM
432169240Sjfv *
433169240Sjfv *  Reads a 16 bit word from the EEPROM.
434169240Sjfv **/
435173788Sjfvs32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
436169240Sjfv{
437169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
438169240Sjfv	u32 i = 0;
439169240Sjfv	s32 ret_val;
440169240Sjfv	u16 word_in;
441169240Sjfv	u8 read_opcode = NVM_READ_OPCODE_SPI;
442169240Sjfv
443169240Sjfv	DEBUGFUNC("e1000_read_nvm_spi");
444169240Sjfv
445248292Sjfv	/* A check for invalid values:  offset too large, too many words,
446173788Sjfv	 * and not enough words.
447173788Sjfv	 */
448169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
449169240Sjfv	    (words == 0)) {
450169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
451248292Sjfv		return -E1000_ERR_NVM;
452169240Sjfv	}
453169240Sjfv
454177867Sjfv	ret_val = nvm->ops.acquire(hw);
455169240Sjfv	if (ret_val)
456248292Sjfv		return ret_val;
457169240Sjfv
458169240Sjfv	ret_val = e1000_ready_nvm_eeprom(hw);
459169240Sjfv	if (ret_val)
460169240Sjfv		goto release;
461169240Sjfv
462169240Sjfv	e1000_standby_nvm(hw);
463169240Sjfv
464169240Sjfv	if ((nvm->address_bits == 8) && (offset >= 128))
465169240Sjfv		read_opcode |= NVM_A8_OPCODE_SPI;
466169240Sjfv
467169240Sjfv	/* Send the READ command (opcode + addr) */
468169240Sjfv	e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
469169240Sjfv	e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
470169240Sjfv
471248292Sjfv	/* Read the data.  SPI NVMs increment the address with each byte
472169240Sjfv	 * read and will roll over if reading beyond the end.  This allows
473173788Sjfv	 * us to read the whole NVM from any offset
474173788Sjfv	 */
475169240Sjfv	for (i = 0; i < words; i++) {
476169240Sjfv		word_in = e1000_shift_in_eec_bits(hw, 16);
477169240Sjfv		data[i] = (word_in >> 8) | (word_in << 8);
478169240Sjfv	}
479169240Sjfv
480169240Sjfvrelease:
481177867Sjfv	nvm->ops.release(hw);
482169240Sjfv
483169240Sjfv	return ret_val;
484169240Sjfv}
485169240Sjfv
486169240Sjfv/**
487169240Sjfv *  e1000_read_nvm_microwire - Reads EEPROM's using microwire
488169589Sjfv *  @hw: pointer to the HW structure
489169589Sjfv *  @offset: offset of word in the EEPROM to read
490169589Sjfv *  @words: number of words to read
491169589Sjfv *  @data: word read from the EEPROM
492169240Sjfv *
493169240Sjfv *  Reads a 16 bit word from the EEPROM.
494169240Sjfv **/
495173788Sjfvs32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
496235527Sjfv			     u16 *data)
497169240Sjfv{
498169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
499169240Sjfv	u32 i = 0;
500169240Sjfv	s32 ret_val;
501169240Sjfv	u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;
502169240Sjfv
503169240Sjfv	DEBUGFUNC("e1000_read_nvm_microwire");
504169240Sjfv
505248292Sjfv	/* A check for invalid values:  offset too large, too many words,
506173788Sjfv	 * and not enough words.
507173788Sjfv	 */
508169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
509169240Sjfv	    (words == 0)) {
510169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
511248292Sjfv		return -E1000_ERR_NVM;
512169240Sjfv	}
513169240Sjfv
514177867Sjfv	ret_val = nvm->ops.acquire(hw);
515169240Sjfv	if (ret_val)
516248292Sjfv		return ret_val;
517169240Sjfv
518169240Sjfv	ret_val = e1000_ready_nvm_eeprom(hw);
519169240Sjfv	if (ret_val)
520169240Sjfv		goto release;
521169240Sjfv
522169240Sjfv	for (i = 0; i < words; i++) {
523169240Sjfv		/* Send the READ command (opcode + addr) */
524169240Sjfv		e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
525169240Sjfv		e1000_shift_out_eec_bits(hw, (u16)(offset + i),
526169240Sjfv					nvm->address_bits);
527169240Sjfv
528248292Sjfv		/* Read the data.  For microwire, each word requires the
529173788Sjfv		 * overhead of setup and tear-down.
530173788Sjfv		 */
531169240Sjfv		data[i] = e1000_shift_in_eec_bits(hw, 16);
532169240Sjfv		e1000_standby_nvm(hw);
533169240Sjfv	}
534169240Sjfv
535169240Sjfvrelease:
536177867Sjfv	nvm->ops.release(hw);
537169240Sjfv
538169240Sjfv	return ret_val;
539169240Sjfv}
540169240Sjfv
541169240Sjfv/**
542169240Sjfv *  e1000_read_nvm_eerd - Reads EEPROM using EERD register
543169589Sjfv *  @hw: pointer to the HW structure
544169589Sjfv *  @offset: offset of word in the EEPROM to read
545169589Sjfv *  @words: number of words to read
546169589Sjfv *  @data: word read from the EEPROM
547169240Sjfv *
548169240Sjfv *  Reads a 16 bit word from the EEPROM using the EERD register.
549169240Sjfv **/
550173788Sjfvs32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
551169240Sjfv{
552169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
553169240Sjfv	u32 i, eerd = 0;
554169240Sjfv	s32 ret_val = E1000_SUCCESS;
555169240Sjfv
556169240Sjfv	DEBUGFUNC("e1000_read_nvm_eerd");
557169240Sjfv
558248292Sjfv	/* A check for invalid values:  offset too large, too many words,
559173788Sjfv	 * too many words for the offset, and not enough words.
560173788Sjfv	 */
561169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
562169240Sjfv	    (words == 0)) {
563169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
564248292Sjfv		return -E1000_ERR_NVM;
565169240Sjfv	}
566169240Sjfv
567169240Sjfv	for (i = 0; i < words; i++) {
568169240Sjfv		eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
569169240Sjfv		       E1000_NVM_RW_REG_START;
570169240Sjfv
571169240Sjfv		E1000_WRITE_REG(hw, E1000_EERD, eerd);
572169240Sjfv		ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
573169240Sjfv		if (ret_val)
574169240Sjfv			break;
575169240Sjfv
576173788Sjfv		data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
577235527Sjfv			   E1000_NVM_RW_REG_DATA);
578169240Sjfv	}
579169240Sjfv
580169240Sjfv	return ret_val;
581169240Sjfv}
582169240Sjfv
583169240Sjfv/**
584169240Sjfv *  e1000_write_nvm_spi - Write to EEPROM using SPI
585169589Sjfv *  @hw: pointer to the HW structure
586169589Sjfv *  @offset: offset within the EEPROM to be written to
587169589Sjfv *  @words: number of words to write
588169589Sjfv *  @data: 16 bit word(s) to be written to the EEPROM
589169240Sjfv *
590169240Sjfv *  Writes data to EEPROM at offset using SPI interface.
591169240Sjfv *
592169240Sjfv *  If e1000_update_nvm_checksum is not called after this function , the
593176667Sjfv *  EEPROM will most likely contain an invalid checksum.
594169240Sjfv **/
595173788Sjfvs32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
596169240Sjfv{
597169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
598248292Sjfv	s32 ret_val = -E1000_ERR_NVM;
599169240Sjfv	u16 widx = 0;
600169240Sjfv
601169240Sjfv	DEBUGFUNC("e1000_write_nvm_spi");
602169240Sjfv
603248292Sjfv	/* A check for invalid values:  offset too large, too many words,
604173788Sjfv	 * and not enough words.
605173788Sjfv	 */
606169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
607169240Sjfv	    (words == 0)) {
608169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
609248292Sjfv		return -E1000_ERR_NVM;
610169240Sjfv	}
611169240Sjfv
612169240Sjfv	while (widx < words) {
613169240Sjfv		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
614169240Sjfv
615248292Sjfv		ret_val = nvm->ops.acquire(hw);
616169240Sjfv		if (ret_val)
617248292Sjfv			return ret_val;
618169240Sjfv
619248292Sjfv		ret_val = e1000_ready_nvm_eeprom(hw);
620248292Sjfv		if (ret_val) {
621248292Sjfv			nvm->ops.release(hw);
622248292Sjfv			return ret_val;
623248292Sjfv		}
624248292Sjfv
625169240Sjfv		e1000_standby_nvm(hw);
626169240Sjfv
627169240Sjfv		/* Send the WRITE ENABLE command (8 bit opcode) */
628169240Sjfv		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
629235527Sjfv					 nvm->opcode_bits);
630169240Sjfv
631169240Sjfv		e1000_standby_nvm(hw);
632169240Sjfv
633248292Sjfv		/* Some SPI eeproms use the 8th address bit embedded in the
634173788Sjfv		 * opcode
635173788Sjfv		 */
636169240Sjfv		if ((nvm->address_bits == 8) && (offset >= 128))
637169240Sjfv			write_opcode |= NVM_A8_OPCODE_SPI;
638169240Sjfv
639169240Sjfv		/* Send the Write command (8-bit opcode + addr) */
640169240Sjfv		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
641169240Sjfv		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
642235527Sjfv					 nvm->address_bits);
643169240Sjfv
644169240Sjfv		/* Loop to allow for up to whole page write of eeprom */
645169240Sjfv		while (widx < words) {
646169240Sjfv			u16 word_out = data[widx];
647169240Sjfv			word_out = (word_out >> 8) | (word_out << 8);
648169240Sjfv			e1000_shift_out_eec_bits(hw, word_out, 16);
649169240Sjfv			widx++;
650169240Sjfv
651169240Sjfv			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
652169240Sjfv				e1000_standby_nvm(hw);
653169240Sjfv				break;
654169240Sjfv			}
655169240Sjfv		}
656248292Sjfv		msec_delay(10);
657248292Sjfv		nvm->ops.release(hw);
658169240Sjfv	}
659169240Sjfv
660169240Sjfv	return ret_val;
661169240Sjfv}
662169240Sjfv
663169240Sjfv/**
664169240Sjfv *  e1000_write_nvm_microwire - Writes EEPROM using microwire
665169589Sjfv *  @hw: pointer to the HW structure
666169589Sjfv *  @offset: offset within the EEPROM to be written to
667169589Sjfv *  @words: number of words to write
668169589Sjfv *  @data: 16 bit word(s) to be written to the EEPROM
669169240Sjfv *
670169240Sjfv *  Writes data to EEPROM at offset using microwire interface.
671169240Sjfv *
672169240Sjfv *  If e1000_update_nvm_checksum is not called after this function , the
673176667Sjfv *  EEPROM will most likely contain an invalid checksum.
674169240Sjfv **/
675173788Sjfvs32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
676235527Sjfv			      u16 *data)
677169240Sjfv{
678169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
679169240Sjfv	s32  ret_val;
680169240Sjfv	u32 eecd;
681169240Sjfv	u16 words_written = 0;
682169240Sjfv	u16 widx = 0;
683169240Sjfv
684169240Sjfv	DEBUGFUNC("e1000_write_nvm_microwire");
685169240Sjfv
686248292Sjfv	/* A check for invalid values:  offset too large, too many words,
687173788Sjfv	 * and not enough words.
688173788Sjfv	 */
689169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
690169240Sjfv	    (words == 0)) {
691169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
692248292Sjfv		return -E1000_ERR_NVM;
693169240Sjfv	}
694169240Sjfv
695177867Sjfv	ret_val = nvm->ops.acquire(hw);
696169240Sjfv	if (ret_val)
697248292Sjfv		return ret_val;
698169240Sjfv
699169240Sjfv	ret_val = e1000_ready_nvm_eeprom(hw);
700169240Sjfv	if (ret_val)
701169240Sjfv		goto release;
702169240Sjfv
703169240Sjfv	e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,
704235527Sjfv				 (u16)(nvm->opcode_bits + 2));
705169240Sjfv
706169240Sjfv	e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
707169240Sjfv
708169240Sjfv	e1000_standby_nvm(hw);
709169240Sjfv
710169240Sjfv	while (words_written < words) {
711169240Sjfv		e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,
712235527Sjfv					 nvm->opcode_bits);
713169240Sjfv
714169240Sjfv		e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
715235527Sjfv					 nvm->address_bits);
716169240Sjfv
717169240Sjfv		e1000_shift_out_eec_bits(hw, data[words_written], 16);
718169240Sjfv
719169240Sjfv		e1000_standby_nvm(hw);
720169240Sjfv
721169240Sjfv		for (widx = 0; widx < 200; widx++) {
722169240Sjfv			eecd = E1000_READ_REG(hw, E1000_EECD);
723169240Sjfv			if (eecd & E1000_EECD_DO)
724169240Sjfv				break;
725169240Sjfv			usec_delay(50);
726169240Sjfv		}
727169240Sjfv
728169240Sjfv		if (widx == 200) {
729169240Sjfv			DEBUGOUT("NVM Write did not complete\n");
730169240Sjfv			ret_val = -E1000_ERR_NVM;
731169240Sjfv			goto release;
732169240Sjfv		}
733169240Sjfv
734169240Sjfv		e1000_standby_nvm(hw);
735169240Sjfv
736169240Sjfv		words_written++;
737169240Sjfv	}
738169240Sjfv
739169240Sjfv	e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,
740235527Sjfv				 (u16)(nvm->opcode_bits + 2));
741169240Sjfv
742169240Sjfv	e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
743169240Sjfv
744169240Sjfvrelease:
745177867Sjfv	nvm->ops.release(hw);
746169240Sjfv
747169240Sjfv	return ret_val;
748169240Sjfv}
749169240Sjfv
750169240Sjfv/**
751213234Sjfv *  e1000_read_pba_string_generic - Read device part number
752213234Sjfv *  @hw: pointer to the HW structure
753213234Sjfv *  @pba_num: pointer to device part number
754213234Sjfv *  @pba_num_size: size of part number buffer
755213234Sjfv *
756213234Sjfv *  Reads the product board assembly (PBA) number from the EEPROM and stores
757213234Sjfv *  the value in pba_num.
758213234Sjfv **/
759218530Sjfvs32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
760235527Sjfv				  u32 pba_num_size)
761213234Sjfv{
762213234Sjfv	s32 ret_val;
763213234Sjfv	u16 nvm_data;
764213234Sjfv	u16 pba_ptr;
765213234Sjfv	u16 offset;
766213234Sjfv	u16 length;
767213234Sjfv
768213234Sjfv	DEBUGFUNC("e1000_read_pba_string_generic");
769213234Sjfv
770213234Sjfv	if (pba_num == NULL) {
771213234Sjfv		DEBUGOUT("PBA string buffer was null\n");
772248292Sjfv		return -E1000_ERR_INVALID_ARGUMENT;
773213234Sjfv	}
774213234Sjfv
775213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
776213234Sjfv	if (ret_val) {
777213234Sjfv		DEBUGOUT("NVM Read Error\n");
778248292Sjfv		return ret_val;
779213234Sjfv	}
780213234Sjfv
781213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
782213234Sjfv	if (ret_val) {
783213234Sjfv		DEBUGOUT("NVM Read Error\n");
784248292Sjfv		return ret_val;
785213234Sjfv	}
786213234Sjfv
787248292Sjfv	/* if nvm_data is not ptr guard the PBA must be in legacy format which
788213234Sjfv	 * means pba_ptr is actually our second data word for the PBA number
789213234Sjfv	 * and we can decode it into an ascii string
790213234Sjfv	 */
791213234Sjfv	if (nvm_data != NVM_PBA_PTR_GUARD) {
792213234Sjfv		DEBUGOUT("NVM PBA number is not stored as string\n");
793213234Sjfv
794248292Sjfv		/* make sure callers buffer is big enough to store the PBA */
795248292Sjfv		if (pba_num_size < E1000_PBANUM_LENGTH) {
796213234Sjfv			DEBUGOUT("PBA string buffer too small\n");
797213234Sjfv			return E1000_ERR_NO_SPACE;
798213234Sjfv		}
799213234Sjfv
800213234Sjfv		/* extract hex string from data and pba_ptr */
801213234Sjfv		pba_num[0] = (nvm_data >> 12) & 0xF;
802213234Sjfv		pba_num[1] = (nvm_data >> 8) & 0xF;
803213234Sjfv		pba_num[2] = (nvm_data >> 4) & 0xF;
804213234Sjfv		pba_num[3] = nvm_data & 0xF;
805213234Sjfv		pba_num[4] = (pba_ptr >> 12) & 0xF;
806213234Sjfv		pba_num[5] = (pba_ptr >> 8) & 0xF;
807213234Sjfv		pba_num[6] = '-';
808213234Sjfv		pba_num[7] = 0;
809213234Sjfv		pba_num[8] = (pba_ptr >> 4) & 0xF;
810213234Sjfv		pba_num[9] = pba_ptr & 0xF;
811213234Sjfv
812213234Sjfv		/* put a null character on the end of our string */
813213234Sjfv		pba_num[10] = '\0';
814213234Sjfv
815213234Sjfv		/* switch all the data but the '-' to hex char */
816213234Sjfv		for (offset = 0; offset < 10; offset++) {
817213234Sjfv			if (pba_num[offset] < 0xA)
818213234Sjfv				pba_num[offset] += '0';
819213234Sjfv			else if (pba_num[offset] < 0x10)
820213234Sjfv				pba_num[offset] += 'A' - 0xA;
821213234Sjfv		}
822213234Sjfv
823248292Sjfv		return E1000_SUCCESS;
824213234Sjfv	}
825213234Sjfv
826213234Sjfv	ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
827213234Sjfv	if (ret_val) {
828213234Sjfv		DEBUGOUT("NVM Read Error\n");
829248292Sjfv		return ret_val;
830213234Sjfv	}
831213234Sjfv
832213234Sjfv	if (length == 0xFFFF || length == 0) {
833213234Sjfv		DEBUGOUT("NVM PBA number section invalid length\n");
834248292Sjfv		return -E1000_ERR_NVM_PBA_SECTION;
835213234Sjfv	}
836213234Sjfv	/* check if pba_num buffer is big enough */
837213234Sjfv	if (pba_num_size < (((u32)length * 2) - 1)) {
838213234Sjfv		DEBUGOUT("PBA string buffer too small\n");
839248292Sjfv		return -E1000_ERR_NO_SPACE;
840213234Sjfv	}
841213234Sjfv
842213234Sjfv	/* trim pba length from start of string */
843213234Sjfv	pba_ptr++;
844213234Sjfv	length--;
845213234Sjfv
846213234Sjfv	for (offset = 0; offset < length; offset++) {
847213234Sjfv		ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
848213234Sjfv		if (ret_val) {
849213234Sjfv			DEBUGOUT("NVM Read Error\n");
850248292Sjfv			return ret_val;
851213234Sjfv		}
852213234Sjfv		pba_num[offset * 2] = (u8)(nvm_data >> 8);
853213234Sjfv		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
854213234Sjfv	}
855213234Sjfv	pba_num[offset * 2] = '\0';
856213234Sjfv
857248292Sjfv	return E1000_SUCCESS;
858213234Sjfv}
859213234Sjfv
860213234Sjfv/**
861213234Sjfv *  e1000_read_pba_length_generic - Read device part number length
862213234Sjfv *  @hw: pointer to the HW structure
863213234Sjfv *  @pba_num_size: size of part number buffer
864213234Sjfv *
865213234Sjfv *  Reads the product board assembly (PBA) number length from the EEPROM and
866213234Sjfv *  stores the value in pba_num_size.
867213234Sjfv **/
868213234Sjfvs32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
869213234Sjfv{
870213234Sjfv	s32 ret_val;
871213234Sjfv	u16 nvm_data;
872213234Sjfv	u16 pba_ptr;
873213234Sjfv	u16 length;
874213234Sjfv
875213234Sjfv	DEBUGFUNC("e1000_read_pba_length_generic");
876213234Sjfv
877213234Sjfv	if (pba_num_size == NULL) {
878213234Sjfv		DEBUGOUT("PBA buffer size was null\n");
879248292Sjfv		return -E1000_ERR_INVALID_ARGUMENT;
880213234Sjfv	}
881213234Sjfv
882213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
883213234Sjfv	if (ret_val) {
884213234Sjfv		DEBUGOUT("NVM Read Error\n");
885248292Sjfv		return ret_val;
886213234Sjfv	}
887213234Sjfv
888213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
889213234Sjfv	if (ret_val) {
890213234Sjfv		DEBUGOUT("NVM Read Error\n");
891248292Sjfv		return ret_val;
892213234Sjfv	}
893213234Sjfv
894213234Sjfv	 /* if data is not ptr guard the PBA must be in legacy format */
895213234Sjfv	if (nvm_data != NVM_PBA_PTR_GUARD) {
896248292Sjfv		*pba_num_size = E1000_PBANUM_LENGTH;
897248292Sjfv		return E1000_SUCCESS;
898213234Sjfv	}
899213234Sjfv
900213234Sjfv	ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
901213234Sjfv	if (ret_val) {
902213234Sjfv		DEBUGOUT("NVM Read Error\n");
903248292Sjfv		return ret_val;
904213234Sjfv	}
905213234Sjfv
906213234Sjfv	if (length == 0xFFFF || length == 0) {
907213234Sjfv		DEBUGOUT("NVM PBA number section invalid length\n");
908248292Sjfv		return -E1000_ERR_NVM_PBA_SECTION;
909213234Sjfv	}
910213234Sjfv
911248292Sjfv	/* Convert from length in u16 values to u8 chars, add 1 for NULL,
912213234Sjfv	 * and subtract 2 because length field is included in length.
913213234Sjfv	 */
914213234Sjfv	*pba_num_size = ((u32)length * 2) - 1;
915213234Sjfv
916248292Sjfv	return E1000_SUCCESS;
917213234Sjfv}
918213234Sjfv
919248292Sjfv
920213234Sjfv/**
921248292Sjfv *  e1000_read_pba_raw
922248292Sjfv *  @hw: pointer to the HW structure
923248292Sjfv *  @eeprom_buf: optional pointer to EEPROM image
924248292Sjfv *  @eeprom_buf_size: size of EEPROM image in words
925248292Sjfv *  @max_pba_block_size: PBA block size limit
926248292Sjfv *  @pba: pointer to output PBA structure
927248292Sjfv *
928248292Sjfv *  Reads PBA from EEPROM image when eeprom_buf is not NULL.
929248292Sjfv *  Reads PBA from physical EEPROM device when eeprom_buf is NULL.
930248292Sjfv *
931248292Sjfv **/
932248292Sjfvs32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
933248292Sjfv		       u32 eeprom_buf_size, u16 max_pba_block_size,
934248292Sjfv		       struct e1000_pba *pba)
935248292Sjfv{
936248292Sjfv	s32 ret_val;
937248292Sjfv	u16 pba_block_size;
938248292Sjfv
939248292Sjfv	if (pba == NULL)
940248292Sjfv		return -E1000_ERR_PARAM;
941248292Sjfv
942248292Sjfv	if (eeprom_buf == NULL) {
943248292Sjfv		ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2,
944248292Sjfv					 &pba->word[0]);
945248292Sjfv		if (ret_val)
946248292Sjfv			return ret_val;
947248292Sjfv	} else {
948248292Sjfv		if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
949248292Sjfv			pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
950248292Sjfv			pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
951248292Sjfv		} else {
952248292Sjfv			return -E1000_ERR_PARAM;
953248292Sjfv		}
954248292Sjfv	}
955248292Sjfv
956248292Sjfv	if (pba->word[0] == NVM_PBA_PTR_GUARD) {
957248292Sjfv		if (pba->pba_block == NULL)
958248292Sjfv			return -E1000_ERR_PARAM;
959248292Sjfv
960248292Sjfv		ret_val = e1000_get_pba_block_size(hw, eeprom_buf,
961248292Sjfv						   eeprom_buf_size,
962248292Sjfv						   &pba_block_size);
963248292Sjfv		if (ret_val)
964248292Sjfv			return ret_val;
965248292Sjfv
966248292Sjfv		if (pba_block_size > max_pba_block_size)
967248292Sjfv			return -E1000_ERR_PARAM;
968248292Sjfv
969248292Sjfv		if (eeprom_buf == NULL) {
970248292Sjfv			ret_val = e1000_read_nvm(hw, pba->word[1],
971248292Sjfv						 pba_block_size,
972248292Sjfv						 pba->pba_block);
973248292Sjfv			if (ret_val)
974248292Sjfv				return ret_val;
975248292Sjfv		} else {
976248292Sjfv			if (eeprom_buf_size > (u32)(pba->word[1] +
977248292Sjfv					      pba->pba_block[0])) {
978248292Sjfv				memcpy(pba->pba_block,
979248292Sjfv				       &eeprom_buf[pba->word[1]],
980248292Sjfv				       pba_block_size * sizeof(u16));
981248292Sjfv			} else {
982248292Sjfv				return -E1000_ERR_PARAM;
983248292Sjfv			}
984248292Sjfv		}
985248292Sjfv	}
986248292Sjfv
987248292Sjfv	return E1000_SUCCESS;
988248292Sjfv}
989248292Sjfv
990248292Sjfv/**
991248292Sjfv *  e1000_write_pba_raw
992248292Sjfv *  @hw: pointer to the HW structure
993248292Sjfv *  @eeprom_buf: optional pointer to EEPROM image
994248292Sjfv *  @eeprom_buf_size: size of EEPROM image in words
995248292Sjfv *  @pba: pointer to PBA structure
996248292Sjfv *
997248292Sjfv *  Writes PBA to EEPROM image when eeprom_buf is not NULL.
998248292Sjfv *  Writes PBA to physical EEPROM device when eeprom_buf is NULL.
999248292Sjfv *
1000248292Sjfv **/
1001248292Sjfvs32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
1002248292Sjfv			u32 eeprom_buf_size, struct e1000_pba *pba)
1003248292Sjfv{
1004248292Sjfv	s32 ret_val;
1005248292Sjfv
1006248292Sjfv	if (pba == NULL)
1007248292Sjfv		return -E1000_ERR_PARAM;
1008248292Sjfv
1009248292Sjfv	if (eeprom_buf == NULL) {
1010248292Sjfv		ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2,
1011248292Sjfv					  &pba->word[0]);
1012248292Sjfv		if (ret_val)
1013248292Sjfv			return ret_val;
1014248292Sjfv	} else {
1015248292Sjfv		if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1016248292Sjfv			eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0];
1017248292Sjfv			eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1];
1018248292Sjfv		} else {
1019248292Sjfv			return -E1000_ERR_PARAM;
1020248292Sjfv		}
1021248292Sjfv	}
1022248292Sjfv
1023248292Sjfv	if (pba->word[0] == NVM_PBA_PTR_GUARD) {
1024248292Sjfv		if (pba->pba_block == NULL)
1025248292Sjfv			return -E1000_ERR_PARAM;
1026248292Sjfv
1027248292Sjfv		if (eeprom_buf == NULL) {
1028248292Sjfv			ret_val = e1000_write_nvm(hw, pba->word[1],
1029248292Sjfv						  pba->pba_block[0],
1030248292Sjfv						  pba->pba_block);
1031248292Sjfv			if (ret_val)
1032248292Sjfv				return ret_val;
1033248292Sjfv		} else {
1034248292Sjfv			if (eeprom_buf_size > (u32)(pba->word[1] +
1035248292Sjfv					      pba->pba_block[0])) {
1036248292Sjfv				memcpy(&eeprom_buf[pba->word[1]],
1037248292Sjfv				       pba->pba_block,
1038248292Sjfv				       pba->pba_block[0] * sizeof(u16));
1039248292Sjfv			} else {
1040248292Sjfv				return -E1000_ERR_PARAM;
1041248292Sjfv			}
1042248292Sjfv		}
1043248292Sjfv	}
1044248292Sjfv
1045248292Sjfv	return E1000_SUCCESS;
1046248292Sjfv}
1047248292Sjfv
1048248292Sjfv/**
1049248292Sjfv *  e1000_get_pba_block_size
1050248292Sjfv *  @hw: pointer to the HW structure
1051248292Sjfv *  @eeprom_buf: optional pointer to EEPROM image
1052248292Sjfv *  @eeprom_buf_size: size of EEPROM image in words
1053248292Sjfv *  @pba_data_size: pointer to output variable
1054248292Sjfv *
1055248292Sjfv *  Returns the size of the PBA block in words. Function operates on EEPROM
1056248292Sjfv *  image if the eeprom_buf pointer is not NULL otherwise it accesses physical
1057248292Sjfv *  EEPROM device.
1058248292Sjfv *
1059248292Sjfv **/
1060248292Sjfvs32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
1061248292Sjfv			     u32 eeprom_buf_size, u16 *pba_block_size)
1062248292Sjfv{
1063248292Sjfv	s32 ret_val;
1064248292Sjfv	u16 pba_word[2];
1065248292Sjfv	u16 length;
1066248292Sjfv
1067248292Sjfv	DEBUGFUNC("e1000_get_pba_block_size");
1068248292Sjfv
1069248292Sjfv	if (eeprom_buf == NULL) {
1070248292Sjfv		ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]);
1071248292Sjfv		if (ret_val)
1072248292Sjfv			return ret_val;
1073248292Sjfv	} else {
1074248292Sjfv		if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1075248292Sjfv			pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
1076248292Sjfv			pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
1077248292Sjfv		} else {
1078248292Sjfv			return -E1000_ERR_PARAM;
1079248292Sjfv		}
1080248292Sjfv	}
1081248292Sjfv
1082248292Sjfv	if (pba_word[0] == NVM_PBA_PTR_GUARD) {
1083248292Sjfv		if (eeprom_buf == NULL) {
1084248292Sjfv			ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1,
1085248292Sjfv						 &length);
1086248292Sjfv			if (ret_val)
1087248292Sjfv				return ret_val;
1088248292Sjfv		} else {
1089248292Sjfv			if (eeprom_buf_size > pba_word[1])
1090248292Sjfv				length = eeprom_buf[pba_word[1] + 0];
1091248292Sjfv			else
1092248292Sjfv				return -E1000_ERR_PARAM;
1093248292Sjfv		}
1094248292Sjfv
1095248292Sjfv		if (length == 0xFFFF || length == 0)
1096248292Sjfv			return -E1000_ERR_NVM_PBA_SECTION;
1097248292Sjfv	} else {
1098248292Sjfv		/* PBA number in legacy format, there is no PBA Block. */
1099248292Sjfv		length = 0;
1100248292Sjfv	}
1101248292Sjfv
1102248292Sjfv	if (pba_block_size != NULL)
1103248292Sjfv		*pba_block_size = length;
1104248292Sjfv
1105248292Sjfv	return E1000_SUCCESS;
1106248292Sjfv}
1107248292Sjfv
1108248292Sjfv/**
1109169240Sjfv *  e1000_read_mac_addr_generic - Read device MAC address
1110169589Sjfv *  @hw: pointer to the HW structure
1111169240Sjfv *
1112169240Sjfv *  Reads the device MAC address from the EEPROM and stores the value.
1113169240Sjfv *  Since devices with two ports use the same EEPROM, we increment the
1114169240Sjfv *  last bit in the MAC address for the second port.
1115169240Sjfv **/
1116173788Sjfvs32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
1117169240Sjfv{
1118190872Sjfv	u32 rar_high;
1119190872Sjfv	u32 rar_low;
1120190872Sjfv	u16 i;
1121169240Sjfv
1122190872Sjfv	rar_high = E1000_READ_REG(hw, E1000_RAH(0));
1123190872Sjfv	rar_low = E1000_READ_REG(hw, E1000_RAL(0));
1124169240Sjfv
1125190872Sjfv	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
1126190872Sjfv		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
1127169240Sjfv
1128190872Sjfv	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
1129190872Sjfv		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
1130169240Sjfv
1131169240Sjfv	for (i = 0; i < ETH_ADDR_LEN; i++)
1132169240Sjfv		hw->mac.addr[i] = hw->mac.perm_addr[i];
1133169240Sjfv
1134190872Sjfv	return E1000_SUCCESS;
1135169240Sjfv}
1136169240Sjfv
1137169240Sjfv/**
1138169240Sjfv *  e1000_validate_nvm_checksum_generic - Validate EEPROM checksum
1139169589Sjfv *  @hw: pointer to the HW structure
1140169240Sjfv *
1141169240Sjfv *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
1142169240Sjfv *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
1143169240Sjfv **/
1144173788Sjfvs32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
1145169240Sjfv{
1146248292Sjfv	s32 ret_val;
1147169240Sjfv	u16 checksum = 0;
1148169240Sjfv	u16 i, nvm_data;
1149169240Sjfv
1150169240Sjfv	DEBUGFUNC("e1000_validate_nvm_checksum_generic");
1151169240Sjfv
1152169240Sjfv	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
1153177867Sjfv		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
1154169240Sjfv		if (ret_val) {
1155169240Sjfv			DEBUGOUT("NVM Read Error\n");
1156248292Sjfv			return ret_val;
1157169240Sjfv		}
1158169240Sjfv		checksum += nvm_data;
1159169240Sjfv	}
1160169240Sjfv
1161169240Sjfv	if (checksum != (u16) NVM_SUM) {
1162169240Sjfv		DEBUGOUT("NVM Checksum Invalid\n");
1163248292Sjfv		return -E1000_ERR_NVM;
1164169240Sjfv	}
1165169240Sjfv
1166248292Sjfv	return E1000_SUCCESS;
1167169240Sjfv}
1168169240Sjfv
1169169240Sjfv/**
1170169240Sjfv *  e1000_update_nvm_checksum_generic - Update EEPROM checksum
1171169589Sjfv *  @hw: pointer to the HW structure
1172169240Sjfv *
1173169240Sjfv *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
1174169240Sjfv *  up to the checksum.  Then calculates the EEPROM checksum and writes the
1175169240Sjfv *  value to the EEPROM.
1176169240Sjfv **/
1177173788Sjfvs32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
1178169240Sjfv{
1179213234Sjfv	s32 ret_val;
1180169240Sjfv	u16 checksum = 0;
1181169240Sjfv	u16 i, nvm_data;
1182169240Sjfv
1183169240Sjfv	DEBUGFUNC("e1000_update_nvm_checksum");
1184169240Sjfv
1185169240Sjfv	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
1186177867Sjfv		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
1187169240Sjfv		if (ret_val) {
1188169240Sjfv			DEBUGOUT("NVM Read Error while updating checksum.\n");
1189248292Sjfv			return ret_val;
1190169240Sjfv		}
1191169240Sjfv		checksum += nvm_data;
1192169240Sjfv	}
1193169240Sjfv	checksum = (u16) NVM_SUM - checksum;
1194177867Sjfv	ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
1195185353Sjfv	if (ret_val)
1196169240Sjfv		DEBUGOUT("NVM Write Error while updating checksum.\n");
1197169240Sjfv
1198169240Sjfv	return ret_val;
1199169240Sjfv}
1200169240Sjfv
1201169240Sjfv/**
1202169240Sjfv *  e1000_reload_nvm_generic - Reloads EEPROM
1203169589Sjfv *  @hw: pointer to the HW structure
1204169240Sjfv *
1205169240Sjfv *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
1206169240Sjfv *  extended control register.
1207169240Sjfv **/
1208190872Sjfvstatic void e1000_reload_nvm_generic(struct e1000_hw *hw)
1209169240Sjfv{
1210169240Sjfv	u32 ctrl_ext;
1211169240Sjfv
1212169240Sjfv	DEBUGFUNC("e1000_reload_nvm_generic");
1213169240Sjfv
1214169240Sjfv	usec_delay(10);
1215169240Sjfv	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
1216169240Sjfv	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
1217169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1218169240Sjfv	E1000_WRITE_FLUSH(hw);
1219169240Sjfv}
1220169240Sjfv
1221248292Sjfv
1222