1177867Sjfv/******************************************************************************
2169240Sjfv
3269196Sjfv  Copyright (c) 2001-2014, 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 **/
66269196Sjfvs32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
67269196Sjfv			u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
68269196Sjfv			u16 E1000_UNUSEDARG *c)
69177867Sjfv{
70177867Sjfv	DEBUGFUNC("e1000_null_read_nvm");
71177867Sjfv	return E1000_SUCCESS;
72177867Sjfv}
73177867Sjfv
74177867Sjfv/**
75177867Sjfv *  e1000_null_nvm_generic - No-op function, return void
76177867Sjfv *  @hw: pointer to the HW structure
77177867Sjfv **/
78269196Sjfvvoid e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw)
79177867Sjfv{
80177867Sjfv	DEBUGFUNC("e1000_null_nvm_generic");
81177867Sjfv	return;
82177867Sjfv}
83177867Sjfv
84177867Sjfv/**
85177867Sjfv *  e1000_null_led_default - No-op function, return 0
86177867Sjfv *  @hw: pointer to the HW structure
87177867Sjfv **/
88269196Sjfvs32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw,
89269196Sjfv			   u16 E1000_UNUSEDARG *data)
90177867Sjfv{
91177867Sjfv	DEBUGFUNC("e1000_null_led_default");
92177867Sjfv	return E1000_SUCCESS;
93177867Sjfv}
94177867Sjfv
95177867Sjfv/**
96177867Sjfv *  e1000_null_write_nvm - No-op function, return 0
97177867Sjfv *  @hw: pointer to the HW structure
98177867Sjfv **/
99269196Sjfvs32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw,
100269196Sjfv			 u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b,
101269196Sjfv			 u16 E1000_UNUSEDARG *c)
102177867Sjfv{
103177867Sjfv	DEBUGFUNC("e1000_null_write_nvm");
104177867Sjfv	return E1000_SUCCESS;
105177867Sjfv}
106177867Sjfv
107177867Sjfv/**
108169240Sjfv *  e1000_raise_eec_clk - Raise EEPROM clock
109169589Sjfv *  @hw: pointer to the HW structure
110169589Sjfv *  @eecd: pointer to the EEPROM
111169240Sjfv *
112169240Sjfv *  Enable/Raise the EEPROM clock bit.
113169240Sjfv **/
114173788Sjfvstatic void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
115169240Sjfv{
116169240Sjfv	*eecd = *eecd | E1000_EECD_SK;
117169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, *eecd);
118169240Sjfv	E1000_WRITE_FLUSH(hw);
119169240Sjfv	usec_delay(hw->nvm.delay_usec);
120169240Sjfv}
121169240Sjfv
122169240Sjfv/**
123169240Sjfv *  e1000_lower_eec_clk - Lower EEPROM clock
124169589Sjfv *  @hw: pointer to the HW structure
125169589Sjfv *  @eecd: pointer to the EEPROM
126169240Sjfv *
127169240Sjfv *  Clear/Lower the EEPROM clock bit.
128169240Sjfv **/
129173788Sjfvstatic void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
130169240Sjfv{
131169240Sjfv	*eecd = *eecd & ~E1000_EECD_SK;
132169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, *eecd);
133169240Sjfv	E1000_WRITE_FLUSH(hw);
134169240Sjfv	usec_delay(hw->nvm.delay_usec);
135169240Sjfv}
136169240Sjfv
137169240Sjfv/**
138169240Sjfv *  e1000_shift_out_eec_bits - Shift data bits our to the EEPROM
139169589Sjfv *  @hw: pointer to the HW structure
140169589Sjfv *  @data: data to send to the EEPROM
141169589Sjfv *  @count: number of bits to shift out
142169240Sjfv *
143169240Sjfv *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
144169240Sjfv *  "data" parameter will be shifted out to the EEPROM one bit at a time.
145169240Sjfv *  In order to do this, "data" must be broken down into bits.
146169240Sjfv **/
147173788Sjfvstatic void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
148169240Sjfv{
149169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
150169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
151169240Sjfv	u32 mask;
152169240Sjfv
153169240Sjfv	DEBUGFUNC("e1000_shift_out_eec_bits");
154169240Sjfv
155169240Sjfv	mask = 0x01 << (count - 1);
156169240Sjfv	if (nvm->type == e1000_nvm_eeprom_microwire)
157169240Sjfv		eecd &= ~E1000_EECD_DO;
158185353Sjfv	else
159185353Sjfv	if (nvm->type == e1000_nvm_eeprom_spi)
160169240Sjfv		eecd |= E1000_EECD_DO;
161169240Sjfv
162169240Sjfv	do {
163169240Sjfv		eecd &= ~E1000_EECD_DI;
164169240Sjfv
165169240Sjfv		if (data & mask)
166169240Sjfv			eecd |= E1000_EECD_DI;
167169240Sjfv
168169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
169169240Sjfv		E1000_WRITE_FLUSH(hw);
170169240Sjfv
171169240Sjfv		usec_delay(nvm->delay_usec);
172169240Sjfv
173169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
174169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
175169240Sjfv
176169240Sjfv		mask >>= 1;
177169240Sjfv	} while (mask);
178169240Sjfv
179169240Sjfv	eecd &= ~E1000_EECD_DI;
180169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, eecd);
181169240Sjfv}
182169240Sjfv
183169240Sjfv/**
184169240Sjfv *  e1000_shift_in_eec_bits - Shift data bits in from the EEPROM
185169589Sjfv *  @hw: pointer to the HW structure
186169589Sjfv *  @count: number of bits to shift in
187169240Sjfv *
188169240Sjfv *  In order to read a register from the EEPROM, we need to shift 'count' bits
189169240Sjfv *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
190169240Sjfv *  the EEPROM (setting the SK bit), and then reading the value of the data out
191169240Sjfv *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
192169240Sjfv *  always be clear.
193169240Sjfv **/
194173788Sjfvstatic u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
195169240Sjfv{
196169240Sjfv	u32 eecd;
197169240Sjfv	u32 i;
198169240Sjfv	u16 data;
199169240Sjfv
200169240Sjfv	DEBUGFUNC("e1000_shift_in_eec_bits");
201169240Sjfv
202169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
203169240Sjfv
204169240Sjfv	eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
205169240Sjfv	data = 0;
206169240Sjfv
207169240Sjfv	for (i = 0; i < count; i++) {
208169240Sjfv		data <<= 1;
209169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
210169240Sjfv
211169240Sjfv		eecd = E1000_READ_REG(hw, E1000_EECD);
212169240Sjfv
213169240Sjfv		eecd &= ~E1000_EECD_DI;
214169240Sjfv		if (eecd & E1000_EECD_DO)
215169240Sjfv			data |= 1;
216169240Sjfv
217169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
218169240Sjfv	}
219169240Sjfv
220169240Sjfv	return data;
221169240Sjfv}
222169240Sjfv
223169240Sjfv/**
224169240Sjfv *  e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion
225169589Sjfv *  @hw: pointer to the HW structure
226169589Sjfv *  @ee_reg: EEPROM flag for polling
227169240Sjfv *
228169240Sjfv *  Polls the EEPROM status bit for either read or write completion based
229169240Sjfv *  upon the value of 'ee_reg'.
230169240Sjfv **/
231173788Sjfvs32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
232169240Sjfv{
233169240Sjfv	u32 attempts = 100000;
234169240Sjfv	u32 i, reg = 0;
235169240Sjfv
236169240Sjfv	DEBUGFUNC("e1000_poll_eerd_eewr_done");
237169240Sjfv
238169240Sjfv	for (i = 0; i < attempts; i++) {
239169240Sjfv		if (ee_reg == E1000_NVM_POLL_READ)
240169240Sjfv			reg = E1000_READ_REG(hw, E1000_EERD);
241169240Sjfv		else
242169240Sjfv			reg = E1000_READ_REG(hw, E1000_EEWR);
243169240Sjfv
244247064Sjfv		if (reg & E1000_NVM_RW_REG_DONE)
245247064Sjfv			return E1000_SUCCESS;
246169240Sjfv
247169240Sjfv		usec_delay(5);
248169240Sjfv	}
249169240Sjfv
250247064Sjfv	return -E1000_ERR_NVM;
251169240Sjfv}
252169240Sjfv
253169240Sjfv/**
254169240Sjfv *  e1000_acquire_nvm_generic - Generic request for access to EEPROM
255169589Sjfv *  @hw: pointer to the HW structure
256169240Sjfv *
257169240Sjfv *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
258169240Sjfv *  Return successful if access grant bit set, else clear the request for
259169240Sjfv *  EEPROM access and return -E1000_ERR_NVM (-1).
260169240Sjfv **/
261173788Sjfvs32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
262169240Sjfv{
263169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
264169240Sjfv	s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
265169240Sjfv
266169240Sjfv	DEBUGFUNC("e1000_acquire_nvm_generic");
267169240Sjfv
268169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ);
269169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
270169240Sjfv
271169240Sjfv	while (timeout) {
272169240Sjfv		if (eecd & E1000_EECD_GNT)
273169240Sjfv			break;
274169240Sjfv		usec_delay(5);
275169240Sjfv		eecd = E1000_READ_REG(hw, E1000_EECD);
276169240Sjfv		timeout--;
277169240Sjfv	}
278169240Sjfv
279169240Sjfv	if (!timeout) {
280169240Sjfv		eecd &= ~E1000_EECD_REQ;
281169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
282169240Sjfv		DEBUGOUT("Could not acquire NVM grant\n");
283247064Sjfv		return -E1000_ERR_NVM;
284169240Sjfv	}
285169240Sjfv
286247064Sjfv	return E1000_SUCCESS;
287169240Sjfv}
288169240Sjfv
289169240Sjfv/**
290169240Sjfv *  e1000_standby_nvm - Return EEPROM to standby state
291169589Sjfv *  @hw: pointer to the HW structure
292169240Sjfv *
293169240Sjfv *  Return the EEPROM to a standby state.
294169240Sjfv **/
295173788Sjfvstatic void e1000_standby_nvm(struct e1000_hw *hw)
296169240Sjfv{
297169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
298169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
299169240Sjfv
300169240Sjfv	DEBUGFUNC("e1000_standby_nvm");
301169240Sjfv
302169240Sjfv	if (nvm->type == e1000_nvm_eeprom_microwire) {
303169240Sjfv		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
304169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
305169240Sjfv		E1000_WRITE_FLUSH(hw);
306169240Sjfv		usec_delay(nvm->delay_usec);
307169240Sjfv
308169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
309169240Sjfv
310169240Sjfv		/* Select EEPROM */
311169240Sjfv		eecd |= E1000_EECD_CS;
312169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
313169240Sjfv		E1000_WRITE_FLUSH(hw);
314169240Sjfv		usec_delay(nvm->delay_usec);
315169240Sjfv
316169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
317228386Sjfv	} else if (nvm->type == e1000_nvm_eeprom_spi) {
318169240Sjfv		/* Toggle CS to flush commands */
319169240Sjfv		eecd |= E1000_EECD_CS;
320169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
321169240Sjfv		E1000_WRITE_FLUSH(hw);
322169240Sjfv		usec_delay(nvm->delay_usec);
323169240Sjfv		eecd &= ~E1000_EECD_CS;
324169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
325169240Sjfv		E1000_WRITE_FLUSH(hw);
326169240Sjfv		usec_delay(nvm->delay_usec);
327169240Sjfv	}
328169240Sjfv}
329169240Sjfv
330169240Sjfv/**
331169240Sjfv *  e1000_stop_nvm - Terminate EEPROM command
332169589Sjfv *  @hw: pointer to the HW structure
333169240Sjfv *
334169240Sjfv *  Terminates the current command by inverting the EEPROM's chip select pin.
335169240Sjfv **/
336173788Sjfvvoid e1000_stop_nvm(struct e1000_hw *hw)
337169240Sjfv{
338169240Sjfv	u32 eecd;
339169240Sjfv
340169240Sjfv	DEBUGFUNC("e1000_stop_nvm");
341169240Sjfv
342169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
343169240Sjfv	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
344169240Sjfv		/* Pull CS high */
345169240Sjfv		eecd |= E1000_EECD_CS;
346169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
347169240Sjfv	} else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
348176667Sjfv		/* CS on Microwire is active-high */
349169240Sjfv		eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
350169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
351169240Sjfv		e1000_raise_eec_clk(hw, &eecd);
352169240Sjfv		e1000_lower_eec_clk(hw, &eecd);
353169240Sjfv	}
354169240Sjfv}
355169240Sjfv
356169240Sjfv/**
357169240Sjfv *  e1000_release_nvm_generic - Release exclusive access to EEPROM
358169589Sjfv *  @hw: pointer to the HW structure
359169240Sjfv *
360169240Sjfv *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
361169240Sjfv **/
362173788Sjfvvoid e1000_release_nvm_generic(struct e1000_hw *hw)
363169240Sjfv{
364169240Sjfv	u32 eecd;
365169240Sjfv
366169240Sjfv	DEBUGFUNC("e1000_release_nvm_generic");
367169240Sjfv
368169240Sjfv	e1000_stop_nvm(hw);
369169240Sjfv
370169240Sjfv	eecd = E1000_READ_REG(hw, E1000_EECD);
371169240Sjfv	eecd &= ~E1000_EECD_REQ;
372169240Sjfv	E1000_WRITE_REG(hw, E1000_EECD, eecd);
373169240Sjfv}
374169240Sjfv
375169240Sjfv/**
376169240Sjfv *  e1000_ready_nvm_eeprom - Prepares EEPROM for read/write
377169589Sjfv *  @hw: pointer to the HW structure
378169240Sjfv *
379169240Sjfv *  Setups the EEPROM for reading and writing.
380169240Sjfv **/
381173788Sjfvstatic s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
382169240Sjfv{
383169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
384169240Sjfv	u32 eecd = E1000_READ_REG(hw, E1000_EECD);
385169240Sjfv	u8 spi_stat_reg;
386169240Sjfv
387169240Sjfv	DEBUGFUNC("e1000_ready_nvm_eeprom");
388169240Sjfv
389169240Sjfv	if (nvm->type == e1000_nvm_eeprom_microwire) {
390169240Sjfv		/* Clear SK and DI */
391169240Sjfv		eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
392169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
393169240Sjfv		/* Set CS */
394169240Sjfv		eecd |= E1000_EECD_CS;
395169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
396228386Sjfv	} else if (nvm->type == e1000_nvm_eeprom_spi) {
397218530Sjfv		u16 timeout = NVM_MAX_RETRY_SPI;
398218530Sjfv
399169240Sjfv		/* Clear SK and CS */
400169240Sjfv		eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
401169240Sjfv		E1000_WRITE_REG(hw, E1000_EECD, eecd);
402228386Sjfv		E1000_WRITE_FLUSH(hw);
403169240Sjfv		usec_delay(1);
404169240Sjfv
405247064Sjfv		/* Read "Status Register" repeatedly until the LSB is cleared.
406169240Sjfv		 * The EEPROM will signal that the command has been completed
407169240Sjfv		 * by clearing bit 0 of the internal status register.  If it's
408173788Sjfv		 * not cleared within 'timeout', then error out.
409173788Sjfv		 */
410169240Sjfv		while (timeout) {
411169240Sjfv			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
412228386Sjfv						 hw->nvm.opcode_bits);
413169240Sjfv			spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
414169240Sjfv			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
415169240Sjfv				break;
416169240Sjfv
417169240Sjfv			usec_delay(5);
418169240Sjfv			e1000_standby_nvm(hw);
419169240Sjfv			timeout--;
420169240Sjfv		}
421169240Sjfv
422169240Sjfv		if (!timeout) {
423169240Sjfv			DEBUGOUT("SPI NVM Status error\n");
424247064Sjfv			return -E1000_ERR_NVM;
425169240Sjfv		}
426169240Sjfv	}
427169240Sjfv
428247064Sjfv	return E1000_SUCCESS;
429169240Sjfv}
430169240Sjfv
431169240Sjfv/**
432169240Sjfv *  e1000_read_nvm_spi - Read EEPROM's using SPI
433169589Sjfv *  @hw: pointer to the HW structure
434169589Sjfv *  @offset: offset of word in the EEPROM to read
435169589Sjfv *  @words: number of words to read
436169589Sjfv *  @data: word read from the EEPROM
437169240Sjfv *
438169240Sjfv *  Reads a 16 bit word from the EEPROM.
439169240Sjfv **/
440173788Sjfvs32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
441169240Sjfv{
442169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
443169240Sjfv	u32 i = 0;
444169240Sjfv	s32 ret_val;
445169240Sjfv	u16 word_in;
446169240Sjfv	u8 read_opcode = NVM_READ_OPCODE_SPI;
447169240Sjfv
448169240Sjfv	DEBUGFUNC("e1000_read_nvm_spi");
449169240Sjfv
450247064Sjfv	/* A check for invalid values:  offset too large, too many words,
451173788Sjfv	 * and not enough words.
452173788Sjfv	 */
453169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
454169240Sjfv	    (words == 0)) {
455169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
456247064Sjfv		return -E1000_ERR_NVM;
457169240Sjfv	}
458169240Sjfv
459177867Sjfv	ret_val = nvm->ops.acquire(hw);
460169240Sjfv	if (ret_val)
461247064Sjfv		return ret_val;
462169240Sjfv
463169240Sjfv	ret_val = e1000_ready_nvm_eeprom(hw);
464169240Sjfv	if (ret_val)
465169240Sjfv		goto release;
466169240Sjfv
467169240Sjfv	e1000_standby_nvm(hw);
468169240Sjfv
469169240Sjfv	if ((nvm->address_bits == 8) && (offset >= 128))
470169240Sjfv		read_opcode |= NVM_A8_OPCODE_SPI;
471169240Sjfv
472169240Sjfv	/* Send the READ command (opcode + addr) */
473169240Sjfv	e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
474169240Sjfv	e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
475169240Sjfv
476247064Sjfv	/* Read the data.  SPI NVMs increment the address with each byte
477169240Sjfv	 * read and will roll over if reading beyond the end.  This allows
478173788Sjfv	 * us to read the whole NVM from any offset
479173788Sjfv	 */
480169240Sjfv	for (i = 0; i < words; i++) {
481169240Sjfv		word_in = e1000_shift_in_eec_bits(hw, 16);
482169240Sjfv		data[i] = (word_in >> 8) | (word_in << 8);
483169240Sjfv	}
484169240Sjfv
485169240Sjfvrelease:
486177867Sjfv	nvm->ops.release(hw);
487169240Sjfv
488169240Sjfv	return ret_val;
489169240Sjfv}
490169240Sjfv
491169240Sjfv/**
492169240Sjfv *  e1000_read_nvm_microwire - Reads EEPROM's using microwire
493169589Sjfv *  @hw: pointer to the HW structure
494169589Sjfv *  @offset: offset of word in the EEPROM to read
495169589Sjfv *  @words: number of words to read
496169589Sjfv *  @data: word read from the EEPROM
497169240Sjfv *
498169240Sjfv *  Reads a 16 bit word from the EEPROM.
499169240Sjfv **/
500173788Sjfvs32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
501228386Sjfv			     u16 *data)
502169240Sjfv{
503169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
504169240Sjfv	u32 i = 0;
505169240Sjfv	s32 ret_val;
506169240Sjfv	u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;
507169240Sjfv
508169240Sjfv	DEBUGFUNC("e1000_read_nvm_microwire");
509169240Sjfv
510247064Sjfv	/* A check for invalid values:  offset too large, too many words,
511173788Sjfv	 * and not enough words.
512173788Sjfv	 */
513169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
514169240Sjfv	    (words == 0)) {
515169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
516247064Sjfv		return -E1000_ERR_NVM;
517169240Sjfv	}
518169240Sjfv
519177867Sjfv	ret_val = nvm->ops.acquire(hw);
520169240Sjfv	if (ret_val)
521247064Sjfv		return ret_val;
522169240Sjfv
523169240Sjfv	ret_val = e1000_ready_nvm_eeprom(hw);
524169240Sjfv	if (ret_val)
525169240Sjfv		goto release;
526169240Sjfv
527169240Sjfv	for (i = 0; i < words; i++) {
528169240Sjfv		/* Send the READ command (opcode + addr) */
529169240Sjfv		e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
530169240Sjfv		e1000_shift_out_eec_bits(hw, (u16)(offset + i),
531169240Sjfv					nvm->address_bits);
532169240Sjfv
533247064Sjfv		/* Read the data.  For microwire, each word requires the
534173788Sjfv		 * overhead of setup and tear-down.
535173788Sjfv		 */
536169240Sjfv		data[i] = e1000_shift_in_eec_bits(hw, 16);
537169240Sjfv		e1000_standby_nvm(hw);
538169240Sjfv	}
539169240Sjfv
540169240Sjfvrelease:
541177867Sjfv	nvm->ops.release(hw);
542169240Sjfv
543169240Sjfv	return ret_val;
544169240Sjfv}
545169240Sjfv
546169240Sjfv/**
547169240Sjfv *  e1000_read_nvm_eerd - Reads EEPROM using EERD register
548169589Sjfv *  @hw: pointer to the HW structure
549169589Sjfv *  @offset: offset of word in the EEPROM to read
550169589Sjfv *  @words: number of words to read
551169589Sjfv *  @data: word read from the EEPROM
552169240Sjfv *
553169240Sjfv *  Reads a 16 bit word from the EEPROM using the EERD register.
554169240Sjfv **/
555173788Sjfvs32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
556169240Sjfv{
557169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
558169240Sjfv	u32 i, eerd = 0;
559169240Sjfv	s32 ret_val = E1000_SUCCESS;
560169240Sjfv
561169240Sjfv	DEBUGFUNC("e1000_read_nvm_eerd");
562169240Sjfv
563247064Sjfv	/* A check for invalid values:  offset too large, too many words,
564173788Sjfv	 * too many words for the offset, and not enough words.
565173788Sjfv	 */
566169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
567169240Sjfv	    (words == 0)) {
568169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
569247064Sjfv		return -E1000_ERR_NVM;
570169240Sjfv	}
571169240Sjfv
572169240Sjfv	for (i = 0; i < words; i++) {
573169240Sjfv		eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) +
574169240Sjfv		       E1000_NVM_RW_REG_START;
575169240Sjfv
576169240Sjfv		E1000_WRITE_REG(hw, E1000_EERD, eerd);
577169240Sjfv		ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ);
578169240Sjfv		if (ret_val)
579169240Sjfv			break;
580169240Sjfv
581173788Sjfv		data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
582228386Sjfv			   E1000_NVM_RW_REG_DATA);
583169240Sjfv	}
584169240Sjfv
585269196Sjfv	if (ret_val)
586269196Sjfv		DEBUGOUT1("NVM read error: %d\n", ret_val);
587269196Sjfv
588169240Sjfv	return ret_val;
589169240Sjfv}
590169240Sjfv
591169240Sjfv/**
592169240Sjfv *  e1000_write_nvm_spi - Write to EEPROM using SPI
593169589Sjfv *  @hw: pointer to the HW structure
594169589Sjfv *  @offset: offset within the EEPROM to be written to
595169589Sjfv *  @words: number of words to write
596169589Sjfv *  @data: 16 bit word(s) to be written to the EEPROM
597169240Sjfv *
598169240Sjfv *  Writes data to EEPROM at offset using SPI interface.
599169240Sjfv *
600169240Sjfv *  If e1000_update_nvm_checksum is not called after this function , the
601176667Sjfv *  EEPROM will most likely contain an invalid checksum.
602169240Sjfv **/
603173788Sjfvs32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
604169240Sjfv{
605169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
606247064Sjfv	s32 ret_val = -E1000_ERR_NVM;
607169240Sjfv	u16 widx = 0;
608169240Sjfv
609169240Sjfv	DEBUGFUNC("e1000_write_nvm_spi");
610169240Sjfv
611247064Sjfv	/* A check for invalid values:  offset too large, too many words,
612173788Sjfv	 * and not enough words.
613173788Sjfv	 */
614169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
615169240Sjfv	    (words == 0)) {
616169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
617247064Sjfv		return -E1000_ERR_NVM;
618169240Sjfv	}
619169240Sjfv
620169240Sjfv	while (widx < words) {
621169240Sjfv		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
622169240Sjfv
623247064Sjfv		ret_val = nvm->ops.acquire(hw);
624169240Sjfv		if (ret_val)
625247064Sjfv			return ret_val;
626169240Sjfv
627247064Sjfv		ret_val = e1000_ready_nvm_eeprom(hw);
628247064Sjfv		if (ret_val) {
629247064Sjfv			nvm->ops.release(hw);
630247064Sjfv			return ret_val;
631247064Sjfv		}
632247064Sjfv
633169240Sjfv		e1000_standby_nvm(hw);
634169240Sjfv
635169240Sjfv		/* Send the WRITE ENABLE command (8 bit opcode) */
636169240Sjfv		e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
637228386Sjfv					 nvm->opcode_bits);
638169240Sjfv
639169240Sjfv		e1000_standby_nvm(hw);
640169240Sjfv
641247064Sjfv		/* Some SPI eeproms use the 8th address bit embedded in the
642173788Sjfv		 * opcode
643173788Sjfv		 */
644169240Sjfv		if ((nvm->address_bits == 8) && (offset >= 128))
645169240Sjfv			write_opcode |= NVM_A8_OPCODE_SPI;
646169240Sjfv
647169240Sjfv		/* Send the Write command (8-bit opcode + addr) */
648169240Sjfv		e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
649169240Sjfv		e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
650228386Sjfv					 nvm->address_bits);
651169240Sjfv
652169240Sjfv		/* Loop to allow for up to whole page write of eeprom */
653169240Sjfv		while (widx < words) {
654169240Sjfv			u16 word_out = data[widx];
655169240Sjfv			word_out = (word_out >> 8) | (word_out << 8);
656169240Sjfv			e1000_shift_out_eec_bits(hw, word_out, 16);
657169240Sjfv			widx++;
658169240Sjfv
659169240Sjfv			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
660169240Sjfv				e1000_standby_nvm(hw);
661169240Sjfv				break;
662169240Sjfv			}
663169240Sjfv		}
664247064Sjfv		msec_delay(10);
665247064Sjfv		nvm->ops.release(hw);
666169240Sjfv	}
667169240Sjfv
668169240Sjfv	return ret_val;
669169240Sjfv}
670169240Sjfv
671169240Sjfv/**
672169240Sjfv *  e1000_write_nvm_microwire - Writes EEPROM using microwire
673169589Sjfv *  @hw: pointer to the HW structure
674169589Sjfv *  @offset: offset within the EEPROM to be written to
675169589Sjfv *  @words: number of words to write
676169589Sjfv *  @data: 16 bit word(s) to be written to the EEPROM
677169240Sjfv *
678169240Sjfv *  Writes data to EEPROM at offset using microwire interface.
679169240Sjfv *
680169240Sjfv *  If e1000_update_nvm_checksum is not called after this function , the
681176667Sjfv *  EEPROM will most likely contain an invalid checksum.
682169240Sjfv **/
683173788Sjfvs32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
684228386Sjfv			      u16 *data)
685169240Sjfv{
686169240Sjfv	struct e1000_nvm_info *nvm = &hw->nvm;
687169240Sjfv	s32  ret_val;
688169240Sjfv	u32 eecd;
689169240Sjfv	u16 words_written = 0;
690169240Sjfv	u16 widx = 0;
691169240Sjfv
692169240Sjfv	DEBUGFUNC("e1000_write_nvm_microwire");
693169240Sjfv
694247064Sjfv	/* A check for invalid values:  offset too large, too many words,
695173788Sjfv	 * and not enough words.
696173788Sjfv	 */
697169240Sjfv	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
698169240Sjfv	    (words == 0)) {
699169240Sjfv		DEBUGOUT("nvm parameter(s) out of bounds\n");
700247064Sjfv		return -E1000_ERR_NVM;
701169240Sjfv	}
702169240Sjfv
703177867Sjfv	ret_val = nvm->ops.acquire(hw);
704169240Sjfv	if (ret_val)
705247064Sjfv		return ret_val;
706169240Sjfv
707169240Sjfv	ret_val = e1000_ready_nvm_eeprom(hw);
708169240Sjfv	if (ret_val)
709169240Sjfv		goto release;
710169240Sjfv
711169240Sjfv	e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE,
712228386Sjfv				 (u16)(nvm->opcode_bits + 2));
713169240Sjfv
714169240Sjfv	e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
715169240Sjfv
716169240Sjfv	e1000_standby_nvm(hw);
717169240Sjfv
718169240Sjfv	while (words_written < words) {
719169240Sjfv		e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE,
720228386Sjfv					 nvm->opcode_bits);
721169240Sjfv
722169240Sjfv		e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
723228386Sjfv					 nvm->address_bits);
724169240Sjfv
725169240Sjfv		e1000_shift_out_eec_bits(hw, data[words_written], 16);
726169240Sjfv
727169240Sjfv		e1000_standby_nvm(hw);
728169240Sjfv
729169240Sjfv		for (widx = 0; widx < 200; widx++) {
730169240Sjfv			eecd = E1000_READ_REG(hw, E1000_EECD);
731169240Sjfv			if (eecd & E1000_EECD_DO)
732169240Sjfv				break;
733169240Sjfv			usec_delay(50);
734169240Sjfv		}
735169240Sjfv
736169240Sjfv		if (widx == 200) {
737169240Sjfv			DEBUGOUT("NVM Write did not complete\n");
738169240Sjfv			ret_val = -E1000_ERR_NVM;
739169240Sjfv			goto release;
740169240Sjfv		}
741169240Sjfv
742169240Sjfv		e1000_standby_nvm(hw);
743169240Sjfv
744169240Sjfv		words_written++;
745169240Sjfv	}
746169240Sjfv
747169240Sjfv	e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE,
748228386Sjfv				 (u16)(nvm->opcode_bits + 2));
749169240Sjfv
750169240Sjfv	e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
751169240Sjfv
752169240Sjfvrelease:
753177867Sjfv	nvm->ops.release(hw);
754169240Sjfv
755169240Sjfv	return ret_val;
756169240Sjfv}
757169240Sjfv
758169240Sjfv/**
759213234Sjfv *  e1000_read_pba_string_generic - Read device part number
760213234Sjfv *  @hw: pointer to the HW structure
761213234Sjfv *  @pba_num: pointer to device part number
762213234Sjfv *  @pba_num_size: size of part number buffer
763213234Sjfv *
764213234Sjfv *  Reads the product board assembly (PBA) number from the EEPROM and stores
765213234Sjfv *  the value in pba_num.
766213234Sjfv **/
767218530Sjfvs32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
768228386Sjfv				  u32 pba_num_size)
769213234Sjfv{
770213234Sjfv	s32 ret_val;
771213234Sjfv	u16 nvm_data;
772213234Sjfv	u16 pba_ptr;
773213234Sjfv	u16 offset;
774213234Sjfv	u16 length;
775213234Sjfv
776213234Sjfv	DEBUGFUNC("e1000_read_pba_string_generic");
777213234Sjfv
778269196Sjfv	if ((hw->mac.type >= e1000_i210) &&
779269196Sjfv	    !e1000_get_flash_presence_i210(hw)) {
780269196Sjfv		DEBUGOUT("Flashless no PBA string\n");
781269196Sjfv		return -E1000_ERR_NVM_PBA_SECTION;
782269196Sjfv	}
783269196Sjfv
784213234Sjfv	if (pba_num == NULL) {
785213234Sjfv		DEBUGOUT("PBA string buffer was null\n");
786247064Sjfv		return -E1000_ERR_INVALID_ARGUMENT;
787213234Sjfv	}
788213234Sjfv
789213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
790213234Sjfv	if (ret_val) {
791213234Sjfv		DEBUGOUT("NVM Read Error\n");
792247064Sjfv		return ret_val;
793213234Sjfv	}
794213234Sjfv
795213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
796213234Sjfv	if (ret_val) {
797213234Sjfv		DEBUGOUT("NVM Read Error\n");
798247064Sjfv		return ret_val;
799213234Sjfv	}
800213234Sjfv
801247064Sjfv	/* if nvm_data is not ptr guard the PBA must be in legacy format which
802213234Sjfv	 * means pba_ptr is actually our second data word for the PBA number
803213234Sjfv	 * and we can decode it into an ascii string
804213234Sjfv	 */
805213234Sjfv	if (nvm_data != NVM_PBA_PTR_GUARD) {
806213234Sjfv		DEBUGOUT("NVM PBA number is not stored as string\n");
807213234Sjfv
808247064Sjfv		/* make sure callers buffer is big enough to store the PBA */
809247064Sjfv		if (pba_num_size < E1000_PBANUM_LENGTH) {
810213234Sjfv			DEBUGOUT("PBA string buffer too small\n");
811213234Sjfv			return E1000_ERR_NO_SPACE;
812213234Sjfv		}
813213234Sjfv
814213234Sjfv		/* extract hex string from data and pba_ptr */
815213234Sjfv		pba_num[0] = (nvm_data >> 12) & 0xF;
816213234Sjfv		pba_num[1] = (nvm_data >> 8) & 0xF;
817213234Sjfv		pba_num[2] = (nvm_data >> 4) & 0xF;
818213234Sjfv		pba_num[3] = nvm_data & 0xF;
819213234Sjfv		pba_num[4] = (pba_ptr >> 12) & 0xF;
820213234Sjfv		pba_num[5] = (pba_ptr >> 8) & 0xF;
821213234Sjfv		pba_num[6] = '-';
822213234Sjfv		pba_num[7] = 0;
823213234Sjfv		pba_num[8] = (pba_ptr >> 4) & 0xF;
824213234Sjfv		pba_num[9] = pba_ptr & 0xF;
825213234Sjfv
826213234Sjfv		/* put a null character on the end of our string */
827213234Sjfv		pba_num[10] = '\0';
828213234Sjfv
829213234Sjfv		/* switch all the data but the '-' to hex char */
830213234Sjfv		for (offset = 0; offset < 10; offset++) {
831213234Sjfv			if (pba_num[offset] < 0xA)
832213234Sjfv				pba_num[offset] += '0';
833213234Sjfv			else if (pba_num[offset] < 0x10)
834213234Sjfv				pba_num[offset] += 'A' - 0xA;
835213234Sjfv		}
836213234Sjfv
837247064Sjfv		return E1000_SUCCESS;
838213234Sjfv	}
839213234Sjfv
840213234Sjfv	ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
841213234Sjfv	if (ret_val) {
842213234Sjfv		DEBUGOUT("NVM Read Error\n");
843247064Sjfv		return ret_val;
844213234Sjfv	}
845213234Sjfv
846213234Sjfv	if (length == 0xFFFF || length == 0) {
847213234Sjfv		DEBUGOUT("NVM PBA number section invalid length\n");
848247064Sjfv		return -E1000_ERR_NVM_PBA_SECTION;
849213234Sjfv	}
850213234Sjfv	/* check if pba_num buffer is big enough */
851213234Sjfv	if (pba_num_size < (((u32)length * 2) - 1)) {
852213234Sjfv		DEBUGOUT("PBA string buffer too small\n");
853247064Sjfv		return -E1000_ERR_NO_SPACE;
854213234Sjfv	}
855213234Sjfv
856213234Sjfv	/* trim pba length from start of string */
857213234Sjfv	pba_ptr++;
858213234Sjfv	length--;
859213234Sjfv
860213234Sjfv	for (offset = 0; offset < length; offset++) {
861213234Sjfv		ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
862213234Sjfv		if (ret_val) {
863213234Sjfv			DEBUGOUT("NVM Read Error\n");
864247064Sjfv			return ret_val;
865213234Sjfv		}
866213234Sjfv		pba_num[offset * 2] = (u8)(nvm_data >> 8);
867213234Sjfv		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
868213234Sjfv	}
869213234Sjfv	pba_num[offset * 2] = '\0';
870213234Sjfv
871247064Sjfv	return E1000_SUCCESS;
872213234Sjfv}
873213234Sjfv
874213234Sjfv/**
875213234Sjfv *  e1000_read_pba_length_generic - Read device part number length
876213234Sjfv *  @hw: pointer to the HW structure
877213234Sjfv *  @pba_num_size: size of part number buffer
878213234Sjfv *
879213234Sjfv *  Reads the product board assembly (PBA) number length from the EEPROM and
880213234Sjfv *  stores the value in pba_num_size.
881213234Sjfv **/
882213234Sjfvs32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
883213234Sjfv{
884213234Sjfv	s32 ret_val;
885213234Sjfv	u16 nvm_data;
886213234Sjfv	u16 pba_ptr;
887213234Sjfv	u16 length;
888213234Sjfv
889213234Sjfv	DEBUGFUNC("e1000_read_pba_length_generic");
890213234Sjfv
891213234Sjfv	if (pba_num_size == NULL) {
892213234Sjfv		DEBUGOUT("PBA buffer size was null\n");
893247064Sjfv		return -E1000_ERR_INVALID_ARGUMENT;
894213234Sjfv	}
895213234Sjfv
896213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
897213234Sjfv	if (ret_val) {
898213234Sjfv		DEBUGOUT("NVM Read Error\n");
899247064Sjfv		return ret_val;
900213234Sjfv	}
901213234Sjfv
902213234Sjfv	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
903213234Sjfv	if (ret_val) {
904213234Sjfv		DEBUGOUT("NVM Read Error\n");
905247064Sjfv		return ret_val;
906213234Sjfv	}
907213234Sjfv
908213234Sjfv	 /* if data is not ptr guard the PBA must be in legacy format */
909213234Sjfv	if (nvm_data != NVM_PBA_PTR_GUARD) {
910247064Sjfv		*pba_num_size = E1000_PBANUM_LENGTH;
911247064Sjfv		return E1000_SUCCESS;
912213234Sjfv	}
913213234Sjfv
914213234Sjfv	ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
915213234Sjfv	if (ret_val) {
916213234Sjfv		DEBUGOUT("NVM Read Error\n");
917247064Sjfv		return ret_val;
918213234Sjfv	}
919213234Sjfv
920213234Sjfv	if (length == 0xFFFF || length == 0) {
921213234Sjfv		DEBUGOUT("NVM PBA number section invalid length\n");
922247064Sjfv		return -E1000_ERR_NVM_PBA_SECTION;
923213234Sjfv	}
924213234Sjfv
925247064Sjfv	/* Convert from length in u16 values to u8 chars, add 1 for NULL,
926213234Sjfv	 * and subtract 2 because length field is included in length.
927213234Sjfv	 */
928213234Sjfv	*pba_num_size = ((u32)length * 2) - 1;
929213234Sjfv
930247064Sjfv	return E1000_SUCCESS;
931213234Sjfv}
932213234Sjfv
933247064Sjfv
934213234Sjfv/**
935247064Sjfv *  e1000_read_pba_raw
936247064Sjfv *  @hw: pointer to the HW structure
937247064Sjfv *  @eeprom_buf: optional pointer to EEPROM image
938247064Sjfv *  @eeprom_buf_size: size of EEPROM image in words
939247064Sjfv *  @max_pba_block_size: PBA block size limit
940247064Sjfv *  @pba: pointer to output PBA structure
941247064Sjfv *
942247064Sjfv *  Reads PBA from EEPROM image when eeprom_buf is not NULL.
943247064Sjfv *  Reads PBA from physical EEPROM device when eeprom_buf is NULL.
944247064Sjfv *
945247064Sjfv **/
946247064Sjfvs32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
947247064Sjfv		       u32 eeprom_buf_size, u16 max_pba_block_size,
948247064Sjfv		       struct e1000_pba *pba)
949247064Sjfv{
950247064Sjfv	s32 ret_val;
951247064Sjfv	u16 pba_block_size;
952247064Sjfv
953247064Sjfv	if (pba == NULL)
954247064Sjfv		return -E1000_ERR_PARAM;
955247064Sjfv
956247064Sjfv	if (eeprom_buf == NULL) {
957247064Sjfv		ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2,
958247064Sjfv					 &pba->word[0]);
959247064Sjfv		if (ret_val)
960247064Sjfv			return ret_val;
961247064Sjfv	} else {
962247064Sjfv		if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
963247064Sjfv			pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
964247064Sjfv			pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
965247064Sjfv		} else {
966247064Sjfv			return -E1000_ERR_PARAM;
967247064Sjfv		}
968247064Sjfv	}
969247064Sjfv
970247064Sjfv	if (pba->word[0] == NVM_PBA_PTR_GUARD) {
971247064Sjfv		if (pba->pba_block == NULL)
972247064Sjfv			return -E1000_ERR_PARAM;
973247064Sjfv
974247064Sjfv		ret_val = e1000_get_pba_block_size(hw, eeprom_buf,
975247064Sjfv						   eeprom_buf_size,
976247064Sjfv						   &pba_block_size);
977247064Sjfv		if (ret_val)
978247064Sjfv			return ret_val;
979247064Sjfv
980247064Sjfv		if (pba_block_size > max_pba_block_size)
981247064Sjfv			return -E1000_ERR_PARAM;
982247064Sjfv
983247064Sjfv		if (eeprom_buf == NULL) {
984247064Sjfv			ret_val = e1000_read_nvm(hw, pba->word[1],
985247064Sjfv						 pba_block_size,
986247064Sjfv						 pba->pba_block);
987247064Sjfv			if (ret_val)
988247064Sjfv				return ret_val;
989247064Sjfv		} else {
990247064Sjfv			if (eeprom_buf_size > (u32)(pba->word[1] +
991269196Sjfv					      pba_block_size)) {
992247064Sjfv				memcpy(pba->pba_block,
993247064Sjfv				       &eeprom_buf[pba->word[1]],
994247064Sjfv				       pba_block_size * sizeof(u16));
995247064Sjfv			} else {
996247064Sjfv				return -E1000_ERR_PARAM;
997247064Sjfv			}
998247064Sjfv		}
999247064Sjfv	}
1000247064Sjfv
1001247064Sjfv	return E1000_SUCCESS;
1002247064Sjfv}
1003247064Sjfv
1004247064Sjfv/**
1005247064Sjfv *  e1000_write_pba_raw
1006247064Sjfv *  @hw: pointer to the HW structure
1007247064Sjfv *  @eeprom_buf: optional pointer to EEPROM image
1008247064Sjfv *  @eeprom_buf_size: size of EEPROM image in words
1009247064Sjfv *  @pba: pointer to PBA structure
1010247064Sjfv *
1011247064Sjfv *  Writes PBA to EEPROM image when eeprom_buf is not NULL.
1012247064Sjfv *  Writes PBA to physical EEPROM device when eeprom_buf is NULL.
1013247064Sjfv *
1014247064Sjfv **/
1015247064Sjfvs32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
1016247064Sjfv			u32 eeprom_buf_size, struct e1000_pba *pba)
1017247064Sjfv{
1018247064Sjfv	s32 ret_val;
1019247064Sjfv
1020247064Sjfv	if (pba == NULL)
1021247064Sjfv		return -E1000_ERR_PARAM;
1022247064Sjfv
1023247064Sjfv	if (eeprom_buf == NULL) {
1024247064Sjfv		ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2,
1025247064Sjfv					  &pba->word[0]);
1026247064Sjfv		if (ret_val)
1027247064Sjfv			return ret_val;
1028247064Sjfv	} else {
1029247064Sjfv		if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1030247064Sjfv			eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0];
1031247064Sjfv			eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1];
1032247064Sjfv		} else {
1033247064Sjfv			return -E1000_ERR_PARAM;
1034247064Sjfv		}
1035247064Sjfv	}
1036247064Sjfv
1037247064Sjfv	if (pba->word[0] == NVM_PBA_PTR_GUARD) {
1038247064Sjfv		if (pba->pba_block == NULL)
1039247064Sjfv			return -E1000_ERR_PARAM;
1040247064Sjfv
1041247064Sjfv		if (eeprom_buf == NULL) {
1042247064Sjfv			ret_val = e1000_write_nvm(hw, pba->word[1],
1043247064Sjfv						  pba->pba_block[0],
1044247064Sjfv						  pba->pba_block);
1045247064Sjfv			if (ret_val)
1046247064Sjfv				return ret_val;
1047247064Sjfv		} else {
1048247064Sjfv			if (eeprom_buf_size > (u32)(pba->word[1] +
1049247064Sjfv					      pba->pba_block[0])) {
1050247064Sjfv				memcpy(&eeprom_buf[pba->word[1]],
1051247064Sjfv				       pba->pba_block,
1052247064Sjfv				       pba->pba_block[0] * sizeof(u16));
1053247064Sjfv			} else {
1054247064Sjfv				return -E1000_ERR_PARAM;
1055247064Sjfv			}
1056247064Sjfv		}
1057247064Sjfv	}
1058247064Sjfv
1059247064Sjfv	return E1000_SUCCESS;
1060247064Sjfv}
1061247064Sjfv
1062247064Sjfv/**
1063247064Sjfv *  e1000_get_pba_block_size
1064247064Sjfv *  @hw: pointer to the HW structure
1065247064Sjfv *  @eeprom_buf: optional pointer to EEPROM image
1066247064Sjfv *  @eeprom_buf_size: size of EEPROM image in words
1067247064Sjfv *  @pba_data_size: pointer to output variable
1068247064Sjfv *
1069247064Sjfv *  Returns the size of the PBA block in words. Function operates on EEPROM
1070247064Sjfv *  image if the eeprom_buf pointer is not NULL otherwise it accesses physical
1071247064Sjfv *  EEPROM device.
1072247064Sjfv *
1073247064Sjfv **/
1074247064Sjfvs32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
1075247064Sjfv			     u32 eeprom_buf_size, u16 *pba_block_size)
1076247064Sjfv{
1077247064Sjfv	s32 ret_val;
1078247064Sjfv	u16 pba_word[2];
1079247064Sjfv	u16 length;
1080247064Sjfv
1081247064Sjfv	DEBUGFUNC("e1000_get_pba_block_size");
1082247064Sjfv
1083247064Sjfv	if (eeprom_buf == NULL) {
1084247064Sjfv		ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]);
1085247064Sjfv		if (ret_val)
1086247064Sjfv			return ret_val;
1087247064Sjfv	} else {
1088247064Sjfv		if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1089247064Sjfv			pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
1090247064Sjfv			pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
1091247064Sjfv		} else {
1092247064Sjfv			return -E1000_ERR_PARAM;
1093247064Sjfv		}
1094247064Sjfv	}
1095247064Sjfv
1096247064Sjfv	if (pba_word[0] == NVM_PBA_PTR_GUARD) {
1097247064Sjfv		if (eeprom_buf == NULL) {
1098247064Sjfv			ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1,
1099247064Sjfv						 &length);
1100247064Sjfv			if (ret_val)
1101247064Sjfv				return ret_val;
1102247064Sjfv		} else {
1103247064Sjfv			if (eeprom_buf_size > pba_word[1])
1104247064Sjfv				length = eeprom_buf[pba_word[1] + 0];
1105247064Sjfv			else
1106247064Sjfv				return -E1000_ERR_PARAM;
1107247064Sjfv		}
1108247064Sjfv
1109247064Sjfv		if (length == 0xFFFF || length == 0)
1110247064Sjfv			return -E1000_ERR_NVM_PBA_SECTION;
1111247064Sjfv	} else {
1112247064Sjfv		/* PBA number in legacy format, there is no PBA Block. */
1113247064Sjfv		length = 0;
1114247064Sjfv	}
1115247064Sjfv
1116247064Sjfv	if (pba_block_size != NULL)
1117247064Sjfv		*pba_block_size = length;
1118247064Sjfv
1119247064Sjfv	return E1000_SUCCESS;
1120247064Sjfv}
1121247064Sjfv
1122247064Sjfv/**
1123169240Sjfv *  e1000_read_mac_addr_generic - Read device MAC address
1124169589Sjfv *  @hw: pointer to the HW structure
1125169240Sjfv *
1126169240Sjfv *  Reads the device MAC address from the EEPROM and stores the value.
1127169240Sjfv *  Since devices with two ports use the same EEPROM, we increment the
1128169240Sjfv *  last bit in the MAC address for the second port.
1129169240Sjfv **/
1130173788Sjfvs32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
1131169240Sjfv{
1132190872Sjfv	u32 rar_high;
1133190872Sjfv	u32 rar_low;
1134190872Sjfv	u16 i;
1135169240Sjfv
1136190872Sjfv	rar_high = E1000_READ_REG(hw, E1000_RAH(0));
1137190872Sjfv	rar_low = E1000_READ_REG(hw, E1000_RAL(0));
1138169240Sjfv
1139190872Sjfv	for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
1140190872Sjfv		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
1141169240Sjfv
1142190872Sjfv	for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
1143190872Sjfv		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
1144169240Sjfv
1145169240Sjfv	for (i = 0; i < ETH_ADDR_LEN; i++)
1146169240Sjfv		hw->mac.addr[i] = hw->mac.perm_addr[i];
1147169240Sjfv
1148190872Sjfv	return E1000_SUCCESS;
1149169240Sjfv}
1150169240Sjfv
1151169240Sjfv/**
1152169240Sjfv *  e1000_validate_nvm_checksum_generic - Validate EEPROM checksum
1153169589Sjfv *  @hw: pointer to the HW structure
1154169240Sjfv *
1155169240Sjfv *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
1156169240Sjfv *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
1157169240Sjfv **/
1158173788Sjfvs32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
1159169240Sjfv{
1160247064Sjfv	s32 ret_val;
1161169240Sjfv	u16 checksum = 0;
1162169240Sjfv	u16 i, nvm_data;
1163169240Sjfv
1164169240Sjfv	DEBUGFUNC("e1000_validate_nvm_checksum_generic");
1165169240Sjfv
1166169240Sjfv	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
1167177867Sjfv		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
1168169240Sjfv		if (ret_val) {
1169169240Sjfv			DEBUGOUT("NVM Read Error\n");
1170247064Sjfv			return ret_val;
1171169240Sjfv		}
1172169240Sjfv		checksum += nvm_data;
1173169240Sjfv	}
1174169240Sjfv
1175169240Sjfv	if (checksum != (u16) NVM_SUM) {
1176169240Sjfv		DEBUGOUT("NVM Checksum Invalid\n");
1177247064Sjfv		return -E1000_ERR_NVM;
1178169240Sjfv	}
1179169240Sjfv
1180247064Sjfv	return E1000_SUCCESS;
1181169240Sjfv}
1182169240Sjfv
1183169240Sjfv/**
1184169240Sjfv *  e1000_update_nvm_checksum_generic - Update EEPROM checksum
1185169589Sjfv *  @hw: pointer to the HW structure
1186169240Sjfv *
1187169240Sjfv *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
1188169240Sjfv *  up to the checksum.  Then calculates the EEPROM checksum and writes the
1189169240Sjfv *  value to the EEPROM.
1190169240Sjfv **/
1191173788Sjfvs32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
1192169240Sjfv{
1193213234Sjfv	s32 ret_val;
1194169240Sjfv	u16 checksum = 0;
1195169240Sjfv	u16 i, nvm_data;
1196169240Sjfv
1197169240Sjfv	DEBUGFUNC("e1000_update_nvm_checksum");
1198169240Sjfv
1199169240Sjfv	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
1200177867Sjfv		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
1201169240Sjfv		if (ret_val) {
1202169240Sjfv			DEBUGOUT("NVM Read Error while updating checksum.\n");
1203247064Sjfv			return ret_val;
1204169240Sjfv		}
1205169240Sjfv		checksum += nvm_data;
1206169240Sjfv	}
1207169240Sjfv	checksum = (u16) NVM_SUM - checksum;
1208177867Sjfv	ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
1209185353Sjfv	if (ret_val)
1210169240Sjfv		DEBUGOUT("NVM Write Error while updating checksum.\n");
1211169240Sjfv
1212169240Sjfv	return ret_val;
1213169240Sjfv}
1214169240Sjfv
1215169240Sjfv/**
1216169240Sjfv *  e1000_reload_nvm_generic - Reloads EEPROM
1217169589Sjfv *  @hw: pointer to the HW structure
1218169240Sjfv *
1219169240Sjfv *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
1220169240Sjfv *  extended control register.
1221169240Sjfv **/
1222190872Sjfvstatic void e1000_reload_nvm_generic(struct e1000_hw *hw)
1223169240Sjfv{
1224169240Sjfv	u32 ctrl_ext;
1225169240Sjfv
1226169240Sjfv	DEBUGFUNC("e1000_reload_nvm_generic");
1227169240Sjfv
1228169240Sjfv	usec_delay(10);
1229169240Sjfv	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
1230169240Sjfv	ctrl_ext |= E1000_CTRL_EXT_EE_RST;
1231169240Sjfv	E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1232169240Sjfv	E1000_WRITE_FLUSH(hw);
1233169240Sjfv}
1234169240Sjfv
1235247064Sjfv
1236