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