1/*-
2 * Copyright 2021 Intel Corp
3 * Copyright 2021 Rubicon Communications, LLC (Netgate)
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <sys/cdefs.h>
8__FBSDID("$FreeBSD$");
9
10#include "igc_api.h"
11
12static void igc_reload_nvm_generic(struct igc_hw *hw);
13
14/**
15 *  igc_init_nvm_ops_generic - Initialize NVM function pointers
16 *  @hw: pointer to the HW structure
17 *
18 *  Setups up the function pointers to no-op functions
19 **/
20void igc_init_nvm_ops_generic(struct igc_hw *hw)
21{
22	struct igc_nvm_info *nvm = &hw->nvm;
23	DEBUGFUNC("igc_init_nvm_ops_generic");
24
25	/* Initialize function pointers */
26	nvm->ops.init_params = igc_null_ops_generic;
27	nvm->ops.acquire = igc_null_ops_generic;
28	nvm->ops.read = igc_null_read_nvm;
29	nvm->ops.release = igc_null_nvm_generic;
30	nvm->ops.reload = igc_reload_nvm_generic;
31	nvm->ops.update = igc_null_ops_generic;
32	nvm->ops.validate = igc_null_ops_generic;
33	nvm->ops.write = igc_null_write_nvm;
34}
35
36/**
37 *  igc_null_nvm_read - No-op function, return 0
38 *  @hw: pointer to the HW structure
39 *  @a: dummy variable
40 *  @b: dummy variable
41 *  @c: dummy variable
42 **/
43s32 igc_null_read_nvm(struct igc_hw IGC_UNUSEDARG *hw,
44			u16 IGC_UNUSEDARG a, u16 IGC_UNUSEDARG b,
45			u16 IGC_UNUSEDARG *c)
46{
47	DEBUGFUNC("igc_null_read_nvm");
48	return IGC_SUCCESS;
49}
50
51/**
52 *  igc_null_nvm_generic - No-op function, return void
53 *  @hw: pointer to the HW structure
54 **/
55void igc_null_nvm_generic(struct igc_hw IGC_UNUSEDARG *hw)
56{
57	DEBUGFUNC("igc_null_nvm_generic");
58	return;
59}
60
61/**
62 *  igc_null_write_nvm - No-op function, return 0
63 *  @hw: pointer to the HW structure
64 *  @a: dummy variable
65 *  @b: dummy variable
66 *  @c: dummy variable
67 **/
68s32 igc_null_write_nvm(struct igc_hw IGC_UNUSEDARG *hw,
69			 u16 IGC_UNUSEDARG a, u16 IGC_UNUSEDARG b,
70			 u16 IGC_UNUSEDARG *c)
71{
72	DEBUGFUNC("igc_null_write_nvm");
73	return IGC_SUCCESS;
74}
75
76/**
77 *  igc_raise_eec_clk - Raise EEPROM clock
78 *  @hw: pointer to the HW structure
79 *  @eecd: pointer to the EEPROM
80 *
81 *  Enable/Raise the EEPROM clock bit.
82 **/
83static void igc_raise_eec_clk(struct igc_hw *hw, u32 *eecd)
84{
85	*eecd = *eecd | IGC_EECD_SK;
86	IGC_WRITE_REG(hw, IGC_EECD, *eecd);
87	IGC_WRITE_FLUSH(hw);
88	usec_delay(hw->nvm.delay_usec);
89}
90
91/**
92 *  igc_lower_eec_clk - Lower EEPROM clock
93 *  @hw: pointer to the HW structure
94 *  @eecd: pointer to the EEPROM
95 *
96 *  Clear/Lower the EEPROM clock bit.
97 **/
98static void igc_lower_eec_clk(struct igc_hw *hw, u32 *eecd)
99{
100	*eecd = *eecd & ~IGC_EECD_SK;
101	IGC_WRITE_REG(hw, IGC_EECD, *eecd);
102	IGC_WRITE_FLUSH(hw);
103	usec_delay(hw->nvm.delay_usec);
104}
105
106/**
107 *  igc_shift_out_eec_bits - Shift data bits our to the EEPROM
108 *  @hw: pointer to the HW structure
109 *  @data: data to send to the EEPROM
110 *  @count: number of bits to shift out
111 *
112 *  We need to shift 'count' bits out to the EEPROM.  So, the value in the
113 *  "data" parameter will be shifted out to the EEPROM one bit at a time.
114 *  In order to do this, "data" must be broken down into bits.
115 **/
116static void igc_shift_out_eec_bits(struct igc_hw *hw, u16 data, u16 count)
117{
118	struct igc_nvm_info *nvm = &hw->nvm;
119	u32 eecd = IGC_READ_REG(hw, IGC_EECD);
120	u32 mask;
121
122	DEBUGFUNC("igc_shift_out_eec_bits");
123
124	mask = 0x01 << (count - 1);
125	if (nvm->type == igc_nvm_eeprom_spi)
126		eecd |= IGC_EECD_DO;
127
128	do {
129		eecd &= ~IGC_EECD_DI;
130
131		if (data & mask)
132			eecd |= IGC_EECD_DI;
133
134		IGC_WRITE_REG(hw, IGC_EECD, eecd);
135		IGC_WRITE_FLUSH(hw);
136
137		usec_delay(nvm->delay_usec);
138
139		igc_raise_eec_clk(hw, &eecd);
140		igc_lower_eec_clk(hw, &eecd);
141
142		mask >>= 1;
143	} while (mask);
144
145	eecd &= ~IGC_EECD_DI;
146	IGC_WRITE_REG(hw, IGC_EECD, eecd);
147}
148
149/**
150 *  igc_shift_in_eec_bits - Shift data bits in from the EEPROM
151 *  @hw: pointer to the HW structure
152 *  @count: number of bits to shift in
153 *
154 *  In order to read a register from the EEPROM, we need to shift 'count' bits
155 *  in from the EEPROM.  Bits are "shifted in" by raising the clock input to
156 *  the EEPROM (setting the SK bit), and then reading the value of the data out
157 *  "DO" bit.  During this "shifting in" process the data in "DI" bit should
158 *  always be clear.
159 **/
160static u16 igc_shift_in_eec_bits(struct igc_hw *hw, u16 count)
161{
162	u32 eecd;
163	u32 i;
164	u16 data;
165
166	DEBUGFUNC("igc_shift_in_eec_bits");
167
168	eecd = IGC_READ_REG(hw, IGC_EECD);
169
170	eecd &= ~(IGC_EECD_DO | IGC_EECD_DI);
171	data = 0;
172
173	for (i = 0; i < count; i++) {
174		data <<= 1;
175		igc_raise_eec_clk(hw, &eecd);
176
177		eecd = IGC_READ_REG(hw, IGC_EECD);
178
179		eecd &= ~IGC_EECD_DI;
180		if (eecd & IGC_EECD_DO)
181			data |= 1;
182
183		igc_lower_eec_clk(hw, &eecd);
184	}
185
186	return data;
187}
188
189/**
190 *  igc_poll_eerd_eewr_done - Poll for EEPROM read/write completion
191 *  @hw: pointer to the HW structure
192 *  @ee_reg: EEPROM flag for polling
193 *
194 *  Polls the EEPROM status bit for either read or write completion based
195 *  upon the value of 'ee_reg'.
196 **/
197s32 igc_poll_eerd_eewr_done(struct igc_hw *hw, int ee_reg)
198{
199	u32 attempts = 100000;
200	u32 i, reg = 0;
201
202	DEBUGFUNC("igc_poll_eerd_eewr_done");
203
204	for (i = 0; i < attempts; i++) {
205		if (ee_reg == IGC_NVM_POLL_READ)
206			reg = IGC_READ_REG(hw, IGC_EERD);
207		else
208			reg = IGC_READ_REG(hw, IGC_EEWR);
209
210		if (reg & IGC_NVM_RW_REG_DONE)
211			return IGC_SUCCESS;
212
213		usec_delay(5);
214	}
215
216	return -IGC_ERR_NVM;
217}
218
219/**
220 *  igc_acquire_nvm_generic - Generic request for access to EEPROM
221 *  @hw: pointer to the HW structure
222 *
223 *  Set the EEPROM access request bit and wait for EEPROM access grant bit.
224 *  Return successful if access grant bit set, else clear the request for
225 *  EEPROM access and return -IGC_ERR_NVM (-1).
226 **/
227s32 igc_acquire_nvm_generic(struct igc_hw *hw)
228{
229	u32 eecd = IGC_READ_REG(hw, IGC_EECD);
230	s32 timeout = IGC_NVM_GRANT_ATTEMPTS;
231
232	DEBUGFUNC("igc_acquire_nvm_generic");
233
234	IGC_WRITE_REG(hw, IGC_EECD, eecd | IGC_EECD_REQ);
235	eecd = IGC_READ_REG(hw, IGC_EECD);
236
237	while (timeout) {
238		if (eecd & IGC_EECD_GNT)
239			break;
240		usec_delay(5);
241		eecd = IGC_READ_REG(hw, IGC_EECD);
242		timeout--;
243	}
244
245	if (!timeout) {
246		eecd &= ~IGC_EECD_REQ;
247		IGC_WRITE_REG(hw, IGC_EECD, eecd);
248		DEBUGOUT("Could not acquire NVM grant\n");
249		return -IGC_ERR_NVM;
250	}
251
252	return IGC_SUCCESS;
253}
254
255/**
256 *  igc_standby_nvm - Return EEPROM to standby state
257 *  @hw: pointer to the HW structure
258 *
259 *  Return the EEPROM to a standby state.
260 **/
261static void igc_standby_nvm(struct igc_hw *hw)
262{
263	struct igc_nvm_info *nvm = &hw->nvm;
264	u32 eecd = IGC_READ_REG(hw, IGC_EECD);
265
266	DEBUGFUNC("igc_standby_nvm");
267
268	if (nvm->type == igc_nvm_eeprom_spi) {
269		/* Toggle CS to flush commands */
270		eecd |= IGC_EECD_CS;
271		IGC_WRITE_REG(hw, IGC_EECD, eecd);
272		IGC_WRITE_FLUSH(hw);
273		usec_delay(nvm->delay_usec);
274		eecd &= ~IGC_EECD_CS;
275		IGC_WRITE_REG(hw, IGC_EECD, eecd);
276		IGC_WRITE_FLUSH(hw);
277		usec_delay(nvm->delay_usec);
278	}
279}
280
281/**
282 *  igc_stop_nvm - Terminate EEPROM command
283 *  @hw: pointer to the HW structure
284 *
285 *  Terminates the current command by inverting the EEPROM's chip select pin.
286 **/
287static void igc_stop_nvm(struct igc_hw *hw)
288{
289	u32 eecd;
290
291	DEBUGFUNC("igc_stop_nvm");
292
293	eecd = IGC_READ_REG(hw, IGC_EECD);
294	if (hw->nvm.type == igc_nvm_eeprom_spi) {
295		/* Pull CS high */
296		eecd |= IGC_EECD_CS;
297		igc_lower_eec_clk(hw, &eecd);
298	}
299}
300
301/**
302 *  igc_release_nvm_generic - Release exclusive access to EEPROM
303 *  @hw: pointer to the HW structure
304 *
305 *  Stop any current commands to the EEPROM and clear the EEPROM request bit.
306 **/
307void igc_release_nvm_generic(struct igc_hw *hw)
308{
309	u32 eecd;
310
311	DEBUGFUNC("igc_release_nvm_generic");
312
313	igc_stop_nvm(hw);
314
315	eecd = IGC_READ_REG(hw, IGC_EECD);
316	eecd &= ~IGC_EECD_REQ;
317	IGC_WRITE_REG(hw, IGC_EECD, eecd);
318}
319
320/**
321 *  igc_ready_nvm_eeprom - Prepares EEPROM for read/write
322 *  @hw: pointer to the HW structure
323 *
324 *  Setups the EEPROM for reading and writing.
325 **/
326static s32 igc_ready_nvm_eeprom(struct igc_hw *hw)
327{
328	struct igc_nvm_info *nvm = &hw->nvm;
329	u32 eecd = IGC_READ_REG(hw, IGC_EECD);
330	u8 spi_stat_reg;
331
332	DEBUGFUNC("igc_ready_nvm_eeprom");
333
334	if (nvm->type == igc_nvm_eeprom_spi) {
335		u16 timeout = NVM_MAX_RETRY_SPI;
336
337		/* Clear SK and CS */
338		eecd &= ~(IGC_EECD_CS | IGC_EECD_SK);
339		IGC_WRITE_REG(hw, IGC_EECD, eecd);
340		IGC_WRITE_FLUSH(hw);
341		usec_delay(1);
342
343		/* Read "Status Register" repeatedly until the LSB is cleared.
344		 * The EEPROM will signal that the command has been completed
345		 * by clearing bit 0 of the internal status register.  If it's
346		 * not cleared within 'timeout', then error out.
347		 */
348		while (timeout) {
349			igc_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
350						 hw->nvm.opcode_bits);
351			spi_stat_reg = (u8)igc_shift_in_eec_bits(hw, 8);
352			if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
353				break;
354
355			usec_delay(5);
356			igc_standby_nvm(hw);
357			timeout--;
358		}
359
360		if (!timeout) {
361			DEBUGOUT("SPI NVM Status error\n");
362			return -IGC_ERR_NVM;
363		}
364	}
365
366	return IGC_SUCCESS;
367}
368
369/**
370 *  igc_read_nvm_eerd - Reads EEPROM using EERD register
371 *  @hw: pointer to the HW structure
372 *  @offset: offset of word in the EEPROM to read
373 *  @words: number of words to read
374 *  @data: word read from the EEPROM
375 *
376 *  Reads a 16 bit word from the EEPROM using the EERD register.
377 **/
378s32 igc_read_nvm_eerd(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
379{
380	struct igc_nvm_info *nvm = &hw->nvm;
381	u32 i, eerd = 0;
382	s32 ret_val = IGC_SUCCESS;
383
384	DEBUGFUNC("igc_read_nvm_eerd");
385
386	/* A check for invalid values:  offset too large, too many words,
387	 * too many words for the offset, and not enough words.
388	 */
389	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
390	    (words == 0)) {
391		DEBUGOUT("nvm parameter(s) out of bounds\n");
392		return -IGC_ERR_NVM;
393	}
394
395	for (i = 0; i < words; i++) {
396		eerd = ((offset + i) << IGC_NVM_RW_ADDR_SHIFT) +
397		       IGC_NVM_RW_REG_START;
398
399		IGC_WRITE_REG(hw, IGC_EERD, eerd);
400		ret_val = igc_poll_eerd_eewr_done(hw, IGC_NVM_POLL_READ);
401		if (ret_val)
402			break;
403
404		data[i] = (IGC_READ_REG(hw, IGC_EERD) >>
405			   IGC_NVM_RW_REG_DATA);
406	}
407
408	if (ret_val)
409		DEBUGOUT1("NVM read error: %d\n", ret_val);
410
411	return ret_val;
412}
413
414/**
415 *  igc_write_nvm_spi - Write to EEPROM using SPI
416 *  @hw: pointer to the HW structure
417 *  @offset: offset within the EEPROM to be written to
418 *  @words: number of words to write
419 *  @data: 16 bit word(s) to be written to the EEPROM
420 *
421 *  Writes data to EEPROM at offset using SPI interface.
422 *
423 *  If igc_update_nvm_checksum is not called after this function , the
424 *  EEPROM will most likely contain an invalid checksum.
425 **/
426s32 igc_write_nvm_spi(struct igc_hw *hw, u16 offset, u16 words, u16 *data)
427{
428	struct igc_nvm_info *nvm = &hw->nvm;
429	s32 ret_val = -IGC_ERR_NVM;
430	u16 widx = 0;
431
432	DEBUGFUNC("igc_write_nvm_spi");
433
434	/* A check for invalid values:  offset too large, too many words,
435	 * and not enough words.
436	 */
437	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
438	    (words == 0)) {
439		DEBUGOUT("nvm parameter(s) out of bounds\n");
440		return -IGC_ERR_NVM;
441	}
442
443	while (widx < words) {
444		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
445
446		ret_val = nvm->ops.acquire(hw);
447		if (ret_val)
448			return ret_val;
449
450		ret_val = igc_ready_nvm_eeprom(hw);
451		if (ret_val) {
452			nvm->ops.release(hw);
453			return ret_val;
454		}
455
456		igc_standby_nvm(hw);
457
458		/* Send the WRITE ENABLE command (8 bit opcode) */
459		igc_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI,
460					 nvm->opcode_bits);
461
462		igc_standby_nvm(hw);
463
464		/* Some SPI eeproms use the 8th address bit embedded in the
465		 * opcode
466		 */
467		if ((nvm->address_bits == 8) && (offset >= 128))
468			write_opcode |= NVM_A8_OPCODE_SPI;
469
470		/* Send the Write command (8-bit opcode + addr) */
471		igc_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
472		igc_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
473					 nvm->address_bits);
474
475		/* Loop to allow for up to whole page write of eeprom */
476		while (widx < words) {
477			u16 word_out = data[widx];
478			word_out = (word_out >> 8) | (word_out << 8);
479			igc_shift_out_eec_bits(hw, word_out, 16);
480			widx++;
481
482			if ((((offset + widx) * 2) % nvm->page_size) == 0) {
483				igc_standby_nvm(hw);
484				break;
485			}
486		}
487		msec_delay(10);
488		nvm->ops.release(hw);
489	}
490
491	return ret_val;
492}
493
494/**
495 *  igc_read_pba_string_generic - Read device part number
496 *  @hw: pointer to the HW structure
497 *  @pba_num: pointer to device part number
498 *  @pba_num_size: size of part number buffer
499 *
500 *  Reads the product board assembly (PBA) number from the EEPROM and stores
501 *  the value in pba_num.
502 **/
503s32 igc_read_pba_string_generic(struct igc_hw *hw, u8 *pba_num,
504				  u32 pba_num_size)
505{
506	s32 ret_val;
507	u16 nvm_data;
508	u16 pba_ptr;
509	u16 offset;
510	u16 length;
511
512	DEBUGFUNC("igc_read_pba_string_generic");
513
514	if (pba_num == NULL) {
515		DEBUGOUT("PBA string buffer was null\n");
516		return -IGC_ERR_INVALID_ARGUMENT;
517	}
518
519	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
520	if (ret_val) {
521		DEBUGOUT("NVM Read Error\n");
522		return ret_val;
523	}
524
525	ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
526	if (ret_val) {
527		DEBUGOUT("NVM Read Error\n");
528		return ret_val;
529	}
530
531	/* if nvm_data is not ptr guard the PBA must be in legacy format which
532	 * means pba_ptr is actually our second data word for the PBA number
533	 * and we can decode it into an ascii string
534	 */
535	if (nvm_data != NVM_PBA_PTR_GUARD) {
536		DEBUGOUT("NVM PBA number is not stored as string\n");
537
538		/* make sure callers buffer is big enough to store the PBA */
539		if (pba_num_size < IGC_PBANUM_LENGTH) {
540			DEBUGOUT("PBA string buffer too small\n");
541			return IGC_ERR_NO_SPACE;
542		}
543
544		/* extract hex string from data and pba_ptr */
545		pba_num[0] = (nvm_data >> 12) & 0xF;
546		pba_num[1] = (nvm_data >> 8) & 0xF;
547		pba_num[2] = (nvm_data >> 4) & 0xF;
548		pba_num[3] = nvm_data & 0xF;
549		pba_num[4] = (pba_ptr >> 12) & 0xF;
550		pba_num[5] = (pba_ptr >> 8) & 0xF;
551		pba_num[6] = '-';
552		pba_num[7] = 0;
553		pba_num[8] = (pba_ptr >> 4) & 0xF;
554		pba_num[9] = pba_ptr & 0xF;
555
556		/* put a null character on the end of our string */
557		pba_num[10] = '\0';
558
559		/* switch all the data but the '-' to hex char */
560		for (offset = 0; offset < 10; offset++) {
561			if (pba_num[offset] < 0xA)
562				pba_num[offset] += '0';
563			else if (pba_num[offset] < 0x10)
564				pba_num[offset] += 'A' - 0xA;
565		}
566
567		return IGC_SUCCESS;
568	}
569
570	ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
571	if (ret_val) {
572		DEBUGOUT("NVM Read Error\n");
573		return ret_val;
574	}
575
576	if (length == 0xFFFF || length == 0) {
577		DEBUGOUT("NVM PBA number section invalid length\n");
578		return -IGC_ERR_NVM_PBA_SECTION;
579	}
580	/* check if pba_num buffer is big enough */
581	if (pba_num_size < (((u32)length * 2) - 1)) {
582		DEBUGOUT("PBA string buffer too small\n");
583		return -IGC_ERR_NO_SPACE;
584	}
585
586	/* trim pba length from start of string */
587	pba_ptr++;
588	length--;
589
590	for (offset = 0; offset < length; offset++) {
591		ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
592		if (ret_val) {
593			DEBUGOUT("NVM Read Error\n");
594			return ret_val;
595		}
596		pba_num[offset * 2] = (u8)(nvm_data >> 8);
597		pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
598	}
599	pba_num[offset * 2] = '\0';
600
601	return IGC_SUCCESS;
602}
603
604
605
606
607
608/**
609 *  igc_read_mac_addr_generic - Read device MAC address
610 *  @hw: pointer to the HW structure
611 *
612 *  Reads the device MAC address from the EEPROM and stores the value.
613 *  Since devices with two ports use the same EEPROM, we increment the
614 *  last bit in the MAC address for the second port.
615 **/
616s32 igc_read_mac_addr_generic(struct igc_hw *hw)
617{
618	u32 rar_high;
619	u32 rar_low;
620	u16 i;
621
622	rar_high = IGC_READ_REG(hw, IGC_RAH(0));
623	rar_low = IGC_READ_REG(hw, IGC_RAL(0));
624
625	for (i = 0; i < IGC_RAL_MAC_ADDR_LEN; i++)
626		hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
627
628	for (i = 0; i < IGC_RAH_MAC_ADDR_LEN; i++)
629		hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
630
631	for (i = 0; i < ETH_ADDR_LEN; i++)
632		hw->mac.addr[i] = hw->mac.perm_addr[i];
633
634	return IGC_SUCCESS;
635}
636
637/**
638 *  igc_validate_nvm_checksum_generic - Validate EEPROM checksum
639 *  @hw: pointer to the HW structure
640 *
641 *  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
642 *  and then verifies that the sum of the EEPROM is equal to 0xBABA.
643 **/
644s32 igc_validate_nvm_checksum_generic(struct igc_hw *hw)
645{
646	s32 ret_val;
647	u16 checksum = 0;
648	u16 i, nvm_data;
649
650	DEBUGFUNC("igc_validate_nvm_checksum_generic");
651
652	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
653		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
654		if (ret_val) {
655			DEBUGOUT("NVM Read Error\n");
656			return ret_val;
657		}
658		checksum += nvm_data;
659	}
660
661	if (checksum != (u16) NVM_SUM) {
662		DEBUGOUT("NVM Checksum Invalid\n");
663		return -IGC_ERR_NVM;
664	}
665
666	return IGC_SUCCESS;
667}
668
669/**
670 *  igc_update_nvm_checksum_generic - Update EEPROM checksum
671 *  @hw: pointer to the HW structure
672 *
673 *  Updates the EEPROM checksum by reading/adding each word of the EEPROM
674 *  up to the checksum.  Then calculates the EEPROM checksum and writes the
675 *  value to the EEPROM.
676 **/
677s32 igc_update_nvm_checksum_generic(struct igc_hw *hw)
678{
679	s32 ret_val;
680	u16 checksum = 0;
681	u16 i, nvm_data;
682
683	DEBUGFUNC("igc_update_nvm_checksum");
684
685	for (i = 0; i < NVM_CHECKSUM_REG; i++) {
686		ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
687		if (ret_val) {
688			DEBUGOUT("NVM Read Error while updating checksum.\n");
689			return ret_val;
690		}
691		checksum += nvm_data;
692	}
693	checksum = (u16) NVM_SUM - checksum;
694	ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
695	if (ret_val)
696		DEBUGOUT("NVM Write Error while updating checksum.\n");
697
698	return ret_val;
699}
700
701/**
702 *  igc_reload_nvm_generic - Reloads EEPROM
703 *  @hw: pointer to the HW structure
704 *
705 *  Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
706 *  extended control register.
707 **/
708static void igc_reload_nvm_generic(struct igc_hw *hw)
709{
710	u32 ctrl_ext;
711
712	DEBUGFUNC("igc_reload_nvm_generic");
713
714	usec_delay(10);
715	ctrl_ext = IGC_READ_REG(hw, IGC_CTRL_EXT);
716	ctrl_ext |= IGC_CTRL_EXT_EE_RST;
717	IGC_WRITE_REG(hw, IGC_CTRL_EXT, ctrl_ext);
718	IGC_WRITE_FLUSH(hw);
719}
720
721
722