FreeBSD kernel E1000 device code
e1000_nvm.c
Go to the documentation of this file.
1/******************************************************************************
2 SPDX-License-Identifier: BSD-3-Clause
3
4 Copyright (c) 2001-2020, Intel Corporation
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 3. Neither the name of the Intel Corporation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.
32
33******************************************************************************/
34/*$FreeBSD$*/
35
36#include "e1000_api.h"
37
38static void e1000_reload_nvm_generic(struct e1000_hw *hw);
39
47{
48 struct e1000_nvm_info *nvm = &hw->nvm;
49 DEBUGFUNC("e1000_init_nvm_ops_generic");
50
51 /* Initialize function pointers */
61}
62
73{
74 DEBUGFUNC("e1000_null_read_nvm");
75 return E1000_SUCCESS;
76}
77
83{
84 DEBUGFUNC("e1000_null_nvm_generic");
85 return;
86}
87
94 u16 E1000_UNUSEDARG *data)
95{
96 DEBUGFUNC("e1000_null_led_default");
97 return E1000_SUCCESS;
98}
99
110{
111 DEBUGFUNC("e1000_null_write_nvm");
112 return E1000_SUCCESS;
113}
114
122static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
123{
124 *eecd = *eecd | E1000_EECD_SK;
125 E1000_WRITE_REG(hw, E1000_EECD, *eecd);
128}
129
137static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
138{
139 *eecd = *eecd & ~E1000_EECD_SK;
140 E1000_WRITE_REG(hw, E1000_EECD, *eecd);
143}
144
155static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
156{
157 struct e1000_nvm_info *nvm = &hw->nvm;
158 u32 eecd = E1000_READ_REG(hw, E1000_EECD);
159 u32 mask;
160
161 DEBUGFUNC("e1000_shift_out_eec_bits");
162
163 mask = 0x01 << (count - 1);
165 eecd &= ~E1000_EECD_DO;
166 else
167 if (nvm->type == e1000_nvm_eeprom_spi)
168 eecd |= E1000_EECD_DO;
169
170 do {
171 eecd &= ~E1000_EECD_DI;
172
173 if (data & mask)
174 eecd |= E1000_EECD_DI;
175
176 E1000_WRITE_REG(hw, E1000_EECD, eecd);
178
180
181 e1000_raise_eec_clk(hw, &eecd);
182 e1000_lower_eec_clk(hw, &eecd);
183
184 mask >>= 1;
185 } while (mask);
186
187 eecd &= ~E1000_EECD_DI;
188 E1000_WRITE_REG(hw, E1000_EECD, eecd);
189}
190
202static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
203{
204 u32 eecd;
205 u32 i;
206 u16 data;
207
208 DEBUGFUNC("e1000_shift_in_eec_bits");
209
210 eecd = E1000_READ_REG(hw, E1000_EECD);
211
212 eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
213 data = 0;
214
215 for (i = 0; i < count; i++) {
216 data <<= 1;
217 e1000_raise_eec_clk(hw, &eecd);
218
219 eecd = E1000_READ_REG(hw, E1000_EECD);
220
221 eecd &= ~E1000_EECD_DI;
222 if (eecd & E1000_EECD_DO)
223 data |= 1;
224
225 e1000_lower_eec_clk(hw, &eecd);
226 }
227
228 return data;
229}
230
240{
241 u32 attempts = 100000;
242 u32 i, reg = 0;
243
244 DEBUGFUNC("e1000_poll_eerd_eewr_done");
245
246 for (i = 0; i < attempts; i++) {
247 if (ee_reg == E1000_NVM_POLL_READ)
248 reg = E1000_READ_REG(hw, E1000_EERD);
249 else
250 reg = E1000_READ_REG(hw, E1000_EEWR);
251
252 if (reg & E1000_NVM_RW_REG_DONE)
253 return E1000_SUCCESS;
254
255 usec_delay(5);
256 }
257
258 return -E1000_ERR_NVM;
259}
260
270{
271 u32 eecd = E1000_READ_REG(hw, E1000_EECD);
273
274 DEBUGFUNC("e1000_acquire_nvm_generic");
275
277 eecd = E1000_READ_REG(hw, E1000_EECD);
278
279 while (timeout) {
280 if (eecd & E1000_EECD_GNT)
281 break;
282 usec_delay(5);
283 eecd = E1000_READ_REG(hw, E1000_EECD);
284 timeout--;
285 }
286
287 if (!timeout) {
288 eecd &= ~E1000_EECD_REQ;
289 E1000_WRITE_REG(hw, E1000_EECD, eecd);
290 DEBUGOUT("Could not acquire NVM grant\n");
291 return -E1000_ERR_NVM;
292 }
293
294 return E1000_SUCCESS;
295}
296
303static void e1000_standby_nvm(struct e1000_hw *hw)
304{
305 struct e1000_nvm_info *nvm = &hw->nvm;
306 u32 eecd = E1000_READ_REG(hw, E1000_EECD);
307
308 DEBUGFUNC("e1000_standby_nvm");
309
310 if (nvm->type == e1000_nvm_eeprom_microwire) {
311 eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
312 E1000_WRITE_REG(hw, E1000_EECD, eecd);
315
316 e1000_raise_eec_clk(hw, &eecd);
317
318 /* Select EEPROM */
319 eecd |= E1000_EECD_CS;
320 E1000_WRITE_REG(hw, E1000_EECD, eecd);
323
324 e1000_lower_eec_clk(hw, &eecd);
325 } else if (nvm->type == e1000_nvm_eeprom_spi) {
326 /* Toggle CS to flush commands */
327 eecd |= E1000_EECD_CS;
328 E1000_WRITE_REG(hw, E1000_EECD, eecd);
331 eecd &= ~E1000_EECD_CS;
332 E1000_WRITE_REG(hw, E1000_EECD, eecd);
335 }
336}
337
344void e1000_stop_nvm(struct e1000_hw *hw)
345{
346 u32 eecd;
347
348 DEBUGFUNC("e1000_stop_nvm");
349
350 eecd = E1000_READ_REG(hw, E1000_EECD);
351 if (hw->nvm.type == e1000_nvm_eeprom_spi) {
352 /* Pull CS high */
353 eecd |= E1000_EECD_CS;
354 e1000_lower_eec_clk(hw, &eecd);
355 } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) {
356 /* CS on Microwire is active-high */
357 eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
358 E1000_WRITE_REG(hw, E1000_EECD, eecd);
359 e1000_raise_eec_clk(hw, &eecd);
360 e1000_lower_eec_clk(hw, &eecd);
361 }
362}
363
371{
372 u32 eecd;
373
374 DEBUGFUNC("e1000_release_nvm_generic");
375
376 e1000_stop_nvm(hw);
377
378 eecd = E1000_READ_REG(hw, E1000_EECD);
379 eecd &= ~E1000_EECD_REQ;
380 E1000_WRITE_REG(hw, E1000_EECD, eecd);
381}
382
390{
391 struct e1000_nvm_info *nvm = &hw->nvm;
392 u32 eecd = E1000_READ_REG(hw, E1000_EECD);
393 u8 spi_stat_reg;
394
395 DEBUGFUNC("e1000_ready_nvm_eeprom");
396
397 if (nvm->type == e1000_nvm_eeprom_microwire) {
398 /* Clear SK and DI */
399 eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
400 E1000_WRITE_REG(hw, E1000_EECD, eecd);
401 /* Set CS */
402 eecd |= E1000_EECD_CS;
403 E1000_WRITE_REG(hw, E1000_EECD, eecd);
404 } else if (nvm->type == e1000_nvm_eeprom_spi) {
405 u16 timeout = NVM_MAX_RETRY_SPI;
406
407 /* Clear SK and CS */
408 eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
409 E1000_WRITE_REG(hw, E1000_EECD, eecd);
411 usec_delay(1);
412
413 /* Read "Status Register" repeatedly until the LSB is cleared.
414 * The EEPROM will signal that the command has been completed
415 * by clearing bit 0 of the internal status register. If it's
416 * not cleared within 'timeout', then error out.
417 */
418 while (timeout) {
420 hw->nvm.opcode_bits);
421 spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8);
422 if (!(spi_stat_reg & NVM_STATUS_RDY_SPI))
423 break;
424
425 usec_delay(5);
427 timeout--;
428 }
429
430 if (!timeout) {
431 DEBUGOUT("SPI NVM Status error\n");
432 return -E1000_ERR_NVM;
433 }
434 }
435
436 return E1000_SUCCESS;
437}
438
448s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
449{
450 struct e1000_nvm_info *nvm = &hw->nvm;
451 u32 i = 0;
452 s32 ret_val;
453 u16 word_in;
454 u8 read_opcode = NVM_READ_OPCODE_SPI;
455
456 DEBUGFUNC("e1000_read_nvm_spi");
457
458 /* A check for invalid values: offset too large, too many words,
459 * and not enough words.
460 */
461 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
462 (words == 0)) {
463 DEBUGOUT("nvm parameter(s) out of bounds\n");
464 return -E1000_ERR_NVM;
465 }
466
467 ret_val = nvm->ops.acquire(hw);
468 if (ret_val)
469 return ret_val;
470
471 ret_val = e1000_ready_nvm_eeprom(hw);
472 if (ret_val)
473 goto release;
474
476
477 if ((nvm->address_bits == 8) && (offset >= 128))
478 read_opcode |= NVM_A8_OPCODE_SPI;
479
480 /* Send the READ command (opcode + addr) */
481 e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
482 e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
483
484 /* Read the data. SPI NVMs increment the address with each byte
485 * read and will roll over if reading beyond the end. This allows
486 * us to read the whole NVM from any offset
487 */
488 for (i = 0; i < words; i++) {
489 word_in = e1000_shift_in_eec_bits(hw, 16);
490 data[i] = (word_in >> 8) | (word_in << 8);
491 }
492
493release:
494 nvm->ops.release(hw);
495
496 return ret_val;
497}
498
508s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
509 u16 *data)
510{
511 struct e1000_nvm_info *nvm = &hw->nvm;
512 u32 i = 0;
513 s32 ret_val;
514 u8 read_opcode = NVM_READ_OPCODE_MICROWIRE;
515
516 DEBUGFUNC("e1000_read_nvm_microwire");
517
518 /* A check for invalid values: offset too large, too many words,
519 * and not enough words.
520 */
521 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
522 (words == 0)) {
523 DEBUGOUT("nvm parameter(s) out of bounds\n");
524 return -E1000_ERR_NVM;
525 }
526
527 ret_val = nvm->ops.acquire(hw);
528 if (ret_val)
529 return ret_val;
530
531 ret_val = e1000_ready_nvm_eeprom(hw);
532 if (ret_val)
533 goto release;
534
535 for (i = 0; i < words; i++) {
536 /* Send the READ command (opcode + addr) */
537 e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
538 e1000_shift_out_eec_bits(hw, (u16)(offset + i),
539 nvm->address_bits);
540
541 /* Read the data. For microwire, each word requires the
542 * overhead of setup and tear-down.
543 */
544 data[i] = e1000_shift_in_eec_bits(hw, 16);
546 }
547
548release:
549 nvm->ops.release(hw);
550
551 return ret_val;
552}
553
563s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
564{
565 struct e1000_nvm_info *nvm = &hw->nvm;
566 u32 i, eerd = 0;
567 s32 ret_val = E1000_SUCCESS;
568
569 DEBUGFUNC("e1000_read_nvm_eerd");
570
571 /* A check for invalid values: offset too large, too many words,
572 * too many words for the offset, and not enough words.
573 */
574 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
575 (words == 0)) {
576 DEBUGOUT("nvm parameter(s) out of bounds\n");
577 return -E1000_ERR_NVM;
578 }
579
580 for (i = 0; i < words; i++) {
581 eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) +
583
584 E1000_WRITE_REG(hw, E1000_EERD, eerd);
586 if (ret_val)
587 break;
588
589 data[i] = (E1000_READ_REG(hw, E1000_EERD) >>
591 }
592
593 if (ret_val)
594 DEBUGOUT1("NVM read error: %d\n", ret_val);
595
596 return ret_val;
597}
598
611s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
612{
613 struct e1000_nvm_info *nvm = &hw->nvm;
614 s32 ret_val = -E1000_ERR_NVM;
615 u16 widx = 0;
616
617 DEBUGFUNC("e1000_write_nvm_spi");
618
619 /* A check for invalid values: offset too large, too many words,
620 * and not enough words.
621 */
622 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
623 (words == 0)) {
624 DEBUGOUT("nvm parameter(s) out of bounds\n");
625 return -E1000_ERR_NVM;
626 }
627
628 while (widx < words) {
629 u8 write_opcode = NVM_WRITE_OPCODE_SPI;
630
631 ret_val = nvm->ops.acquire(hw);
632 if (ret_val)
633 return ret_val;
634
635 ret_val = e1000_ready_nvm_eeprom(hw);
636 if (ret_val) {
637 nvm->ops.release(hw);
638 return ret_val;
639 }
640
642
643 /* Send the WRITE ENABLE command (8 bit opcode) */
645 nvm->opcode_bits);
646
648
649 /* Some SPI eeproms use the 8th address bit embedded in the
650 * opcode
651 */
652 if ((nvm->address_bits == 8) && (offset >= 128))
653 write_opcode |= NVM_A8_OPCODE_SPI;
654
655 /* Send the Write command (8-bit opcode + addr) */
656 e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits);
657 e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2),
658 nvm->address_bits);
659
660 /* Loop to allow for up to whole page write of eeprom */
661 while (widx < words) {
662 u16 word_out = data[widx];
663 word_out = (word_out >> 8) | (word_out << 8);
664 e1000_shift_out_eec_bits(hw, word_out, 16);
665 widx++;
666
667 if ((((offset + widx) * 2) % nvm->page_size) == 0) {
669 break;
670 }
671 }
672 msec_delay(10);
673 nvm->ops.release(hw);
674 }
675
676 return ret_val;
677}
678
691s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
692 u16 *data)
693{
694 struct e1000_nvm_info *nvm = &hw->nvm;
695 s32 ret_val;
696 u32 eecd;
697 u16 words_written = 0;
698 u16 widx = 0;
699
700 DEBUGFUNC("e1000_write_nvm_microwire");
701
702 /* A check for invalid values: offset too large, too many words,
703 * and not enough words.
704 */
705 if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
706 (words == 0)) {
707 DEBUGOUT("nvm parameter(s) out of bounds\n");
708 return -E1000_ERR_NVM;
709 }
710
711 ret_val = nvm->ops.acquire(hw);
712 if (ret_val)
713 return ret_val;
714
715 ret_val = e1000_ready_nvm_eeprom(hw);
716 if (ret_val)
717 goto release;
718
720 (u16)(nvm->opcode_bits + 2));
721
722 e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
723
725
726 while (words_written < words) {
728 nvm->opcode_bits);
729
730 e1000_shift_out_eec_bits(hw, (u16)(offset + words_written),
731 nvm->address_bits);
732
733 e1000_shift_out_eec_bits(hw, data[words_written], 16);
734
736
737 for (widx = 0; widx < 200; widx++) {
738 eecd = E1000_READ_REG(hw, E1000_EECD);
739 if (eecd & E1000_EECD_DO)
740 break;
741 usec_delay(50);
742 }
743
744 if (widx == 200) {
745 DEBUGOUT("NVM Write did not complete\n");
746 ret_val = -E1000_ERR_NVM;
747 goto release;
748 }
749
751
752 words_written++;
753 }
754
756 (u16)(nvm->opcode_bits + 2));
757
758 e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2));
759
760release:
761 nvm->ops.release(hw);
762
763 return ret_val;
764}
765
776 u32 pba_num_size)
777{
778 s32 ret_val;
779 u16 nvm_data;
780 u16 pba_ptr;
781 u16 offset;
782 u16 length;
783
784 DEBUGFUNC("e1000_read_pba_string_generic");
785
786 if ((hw->mac.type == e1000_i210 ||
787 hw->mac.type == e1000_i211) &&
789 DEBUGOUT("Flashless no PBA string\n");
791 }
792
793 if (pba_num == NULL) {
794 DEBUGOUT("PBA string buffer was null\n");
796 }
797
798 ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
799 if (ret_val) {
800 DEBUGOUT("NVM Read Error\n");
801 return ret_val;
802 }
803
804 ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
805 if (ret_val) {
806 DEBUGOUT("NVM Read Error\n");
807 return ret_val;
808 }
809
810 /* if nvm_data is not ptr guard the PBA must be in legacy format which
811 * means pba_ptr is actually our second data word for the PBA number
812 * and we can decode it into an ascii string
813 */
814 if (nvm_data != NVM_PBA_PTR_GUARD) {
815 DEBUGOUT("NVM PBA number is not stored as string\n");
816
817 /* make sure callers buffer is big enough to store the PBA */
818 if (pba_num_size < E1000_PBANUM_LENGTH) {
819 DEBUGOUT("PBA string buffer too small\n");
820 return E1000_ERR_NO_SPACE;
821 }
822
823 /* extract hex string from data and pba_ptr */
824 pba_num[0] = (nvm_data >> 12) & 0xF;
825 pba_num[1] = (nvm_data >> 8) & 0xF;
826 pba_num[2] = (nvm_data >> 4) & 0xF;
827 pba_num[3] = nvm_data & 0xF;
828 pba_num[4] = (pba_ptr >> 12) & 0xF;
829 pba_num[5] = (pba_ptr >> 8) & 0xF;
830 pba_num[6] = '-';
831 pba_num[7] = 0;
832 pba_num[8] = (pba_ptr >> 4) & 0xF;
833 pba_num[9] = pba_ptr & 0xF;
834
835 /* put a null character on the end of our string */
836 pba_num[10] = '\0';
837
838 /* switch all the data but the '-' to hex char */
839 for (offset = 0; offset < 10; offset++) {
840 if (pba_num[offset] < 0xA)
841 pba_num[offset] += '0';
842 else if (pba_num[offset] < 0x10)
843 pba_num[offset] += 'A' - 0xA;
844 }
845
846 return E1000_SUCCESS;
847 }
848
849 ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
850 if (ret_val) {
851 DEBUGOUT("NVM Read Error\n");
852 return ret_val;
853 }
854
855 if (length == 0xFFFF || length == 0) {
856 DEBUGOUT("NVM PBA number section invalid length\n");
858 }
859 /* check if pba_num buffer is big enough */
860 if (pba_num_size < (((u32)length * 2) - 1)) {
861 DEBUGOUT("PBA string buffer too small\n");
862 return -E1000_ERR_NO_SPACE;
863 }
864
865 /* trim pba length from start of string */
866 pba_ptr++;
867 length--;
868
869 for (offset = 0; offset < length; offset++) {
870 ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
871 if (ret_val) {
872 DEBUGOUT("NVM Read Error\n");
873 return ret_val;
874 }
875 pba_num[offset * 2] = (u8)(nvm_data >> 8);
876 pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
877 }
878 pba_num[offset * 2] = '\0';
879
880 return E1000_SUCCESS;
881}
882
892{
893 s32 ret_val;
894 u16 nvm_data;
895 u16 pba_ptr;
896 u16 length;
897
898 DEBUGFUNC("e1000_read_pba_length_generic");
899
900 if (pba_num_size == NULL) {
901 DEBUGOUT("PBA buffer size was null\n");
903 }
904
905 ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
906 if (ret_val) {
907 DEBUGOUT("NVM Read Error\n");
908 return ret_val;
909 }
910
911 ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
912 if (ret_val) {
913 DEBUGOUT("NVM Read Error\n");
914 return ret_val;
915 }
916
917 /* if data is not ptr guard the PBA must be in legacy format */
918 if (nvm_data != NVM_PBA_PTR_GUARD) {
919 *pba_num_size = E1000_PBANUM_LENGTH;
920 return E1000_SUCCESS;
921 }
922
923 ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
924 if (ret_val) {
925 DEBUGOUT("NVM Read Error\n");
926 return ret_val;
927 }
928
929 if (length == 0xFFFF || length == 0) {
930 DEBUGOUT("NVM PBA number section invalid length\n");
932 }
933
934 /* Convert from length in u16 values to u8 chars, add 1 for NULL,
935 * and subtract 2 because length field is included in length.
936 */
937 *pba_num_size = ((u32)length * 2) - 1;
938
939 return E1000_SUCCESS;
940}
941
951{
952 s32 ret_val;
953 u16 nvm_data;
954
955 DEBUGFUNC("e1000_read_pba_num_generic");
956
957 ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
958 if (ret_val) {
959 DEBUGOUT("NVM Read Error\n");
960 return ret_val;
961 } else if (nvm_data == NVM_PBA_PTR_GUARD) {
962 DEBUGOUT("NVM Not Supported\n");
963 return -E1000_NOT_IMPLEMENTED;
964 }
965 *pba_num = (u32)(nvm_data << 16);
966
967 ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data);
968 if (ret_val) {
969 DEBUGOUT("NVM Read Error\n");
970 return ret_val;
971 }
972 *pba_num |= nvm_data;
973
974 return E1000_SUCCESS;
975}
976
977
990s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
991 u32 eeprom_buf_size, u16 max_pba_block_size,
992 struct e1000_pba *pba)
993{
994 s32 ret_val;
995 u16 pba_block_size;
996
997 if (pba == NULL)
998 return -E1000_ERR_PARAM;
999
1000 if (eeprom_buf == NULL) {
1001 ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2,
1002 &pba->word[0]);
1003 if (ret_val)
1004 return ret_val;
1005 } else {
1006 if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1007 pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
1008 pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
1009 } else {
1010 return -E1000_ERR_PARAM;
1011 }
1012 }
1013
1014 if (pba->word[0] == NVM_PBA_PTR_GUARD) {
1015 if (pba->pba_block == NULL)
1016 return -E1000_ERR_PARAM;
1017
1018 ret_val = e1000_get_pba_block_size(hw, eeprom_buf,
1019 eeprom_buf_size,
1020 &pba_block_size);
1021 if (ret_val)
1022 return ret_val;
1023
1024 if (pba_block_size > max_pba_block_size)
1025 return -E1000_ERR_PARAM;
1026
1027 if (eeprom_buf == NULL) {
1028 ret_val = e1000_read_nvm(hw, pba->word[1],
1029 pba_block_size,
1030 pba->pba_block);
1031 if (ret_val)
1032 return ret_val;
1033 } else {
1034 if (eeprom_buf_size > (u32)(pba->word[1] +
1035 pba_block_size)) {
1036 memcpy(pba->pba_block,
1037 &eeprom_buf[pba->word[1]],
1038 pba_block_size * sizeof(u16));
1039 } else {
1040 return -E1000_ERR_PARAM;
1041 }
1042 }
1043 }
1044
1045 return E1000_SUCCESS;
1046}
1047
1059s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
1060 u32 eeprom_buf_size, struct e1000_pba *pba)
1061{
1062 s32 ret_val;
1063
1064 if (pba == NULL)
1065 return -E1000_ERR_PARAM;
1066
1067 if (eeprom_buf == NULL) {
1068 ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2,
1069 &pba->word[0]);
1070 if (ret_val)
1071 return ret_val;
1072 } else {
1073 if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1074 eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0];
1075 eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1];
1076 } else {
1077 return -E1000_ERR_PARAM;
1078 }
1079 }
1080
1081 if (pba->word[0] == NVM_PBA_PTR_GUARD) {
1082 if (pba->pba_block == NULL)
1083 return -E1000_ERR_PARAM;
1084
1085 if (eeprom_buf == NULL) {
1086 ret_val = e1000_write_nvm(hw, pba->word[1],
1087 pba->pba_block[0],
1088 pba->pba_block);
1089 if (ret_val)
1090 return ret_val;
1091 } else {
1092 if (eeprom_buf_size > (u32)(pba->word[1] +
1093 pba->pba_block[0])) {
1094 memcpy(&eeprom_buf[pba->word[1]],
1095 pba->pba_block,
1096 pba->pba_block[0] * sizeof(u16));
1097 } else {
1098 return -E1000_ERR_PARAM;
1099 }
1100 }
1101 }
1102
1103 return E1000_SUCCESS;
1104}
1105
1119 u32 eeprom_buf_size, u16 *pba_block_size)
1120{
1121 s32 ret_val;
1122 u16 pba_word[2];
1123 u16 length;
1124
1125 DEBUGFUNC("e1000_get_pba_block_size");
1126
1127 if (eeprom_buf == NULL) {
1128 ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]);
1129 if (ret_val)
1130 return ret_val;
1131 } else {
1132 if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
1133 pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
1134 pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
1135 } else {
1136 return -E1000_ERR_PARAM;
1137 }
1138 }
1139
1140 if (pba_word[0] == NVM_PBA_PTR_GUARD) {
1141 if (eeprom_buf == NULL) {
1142 ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1,
1143 &length);
1144 if (ret_val)
1145 return ret_val;
1146 } else {
1147 if (eeprom_buf_size > pba_word[1])
1148 length = eeprom_buf[pba_word[1] + 0];
1149 else
1150 return -E1000_ERR_PARAM;
1151 }
1152
1153 if (length == 0xFFFF || length == 0)
1155 } else {
1156 /* PBA number in legacy format, there is no PBA Block. */
1157 length = 0;
1158 }
1159
1160 if (pba_block_size != NULL)
1161 *pba_block_size = length;
1162
1163 return E1000_SUCCESS;
1164}
1165
1175{
1176 u32 rar_high;
1177 u32 rar_low;
1178 u16 i;
1179
1180 rar_high = E1000_READ_REG(hw, E1000_RAH(0));
1181 rar_low = E1000_READ_REG(hw, E1000_RAL(0));
1182
1183 for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
1184 hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));
1185
1186 for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
1187 hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));
1188
1189 for (i = 0; i < ETHER_ADDR_LEN; i++)
1190 hw->mac.addr[i] = hw->mac.perm_addr[i];
1191
1192 return E1000_SUCCESS;
1193}
1194
1203{
1204 s32 ret_val;
1205 u16 checksum = 0;
1206 u16 i, nvm_data;
1207
1208 DEBUGFUNC("e1000_validate_nvm_checksum_generic");
1209
1210 for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
1211 ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
1212 if (ret_val) {
1213 DEBUGOUT("NVM Read Error\n");
1214 return ret_val;
1215 }
1216 checksum += nvm_data;
1217 }
1218
1219 if (checksum != (u16) NVM_SUM) {
1220 DEBUGOUT("NVM Checksum Invalid\n");
1221 return -E1000_ERR_NVM;
1222 }
1223
1224 return E1000_SUCCESS;
1225}
1226
1236{
1237 s32 ret_val;
1238 u16 checksum = 0;
1239 u16 i, nvm_data;
1240
1241 DEBUGFUNC("e1000_update_nvm_checksum");
1242
1243 for (i = 0; i < NVM_CHECKSUM_REG; i++) {
1244 ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
1245 if (ret_val) {
1246 DEBUGOUT("NVM Read Error while updating checksum.\n");
1247 return ret_val;
1248 }
1249 checksum += nvm_data;
1250 }
1251 checksum = (u16) NVM_SUM - checksum;
1252 ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum);
1253 if (ret_val)
1254 DEBUGOUT("NVM Write Error while updating checksum.\n");
1255
1256 return ret_val;
1257}
1258
1266static void e1000_reload_nvm_generic(struct e1000_hw *hw)
1267{
1268 u32 ctrl_ext;
1269
1270 DEBUGFUNC("e1000_reload_nvm_generic");
1271
1272 usec_delay(10);
1273 ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
1274 ctrl_ext |= E1000_CTRL_EXT_EE_RST;
1275 E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
1277}
1278
1286void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
1287{
1288 u16 eeprom_verh, eeprom_verl, etrack_test, fw_version;
1289 u8 q, hval, rem, result;
1290 u16 comb_verh, comb_verl, comb_offset;
1291
1292 memset(fw_vers, 0, sizeof(struct e1000_fw_version));
1293
1294 /* basic eeprom version numbers, bits used vary by part and by tool
1295 * used to create the nvm images */
1296 /* Check which data format we have */
1297 switch (hw->mac.type) {
1298 case e1000_i211:
1299 e1000_read_invm_version(hw, fw_vers);
1300 return;
1301 case e1000_82575:
1302 case e1000_82576:
1303 case e1000_82580:
1304 case e1000_i354:
1305 hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
1306 /* Use this format, unless EETRACK ID exists,
1307 * then use alternate format
1308 */
1309 if ((etrack_test & NVM_MAJOR_MASK) != NVM_ETRACK_VALID) {
1310 hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
1311 fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
1312 >> NVM_MAJOR_SHIFT;
1313 fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK)
1314 >> NVM_MINOR_SHIFT;
1315 fw_vers->eep_build = (fw_version & NVM_IMAGE_ID_MASK);
1316 goto etrack_id;
1317 }
1318 break;
1319 case e1000_i210:
1320 if (!(e1000_get_flash_presence_i210(hw))) {
1321 e1000_read_invm_version(hw, fw_vers);
1322 return;
1323 }
1324 /* FALLTHROUGH */
1325 case e1000_i350:
1326 hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
1327 /* find combo image version */
1328 hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
1329 if ((comb_offset != 0x0) &&
1330 (comb_offset != NVM_VER_INVALID)) {
1331
1332 hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
1333 + 1), 1, &comb_verh);
1334 hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
1335 1, &comb_verl);
1336
1337 /* get Option Rom version if it exists and is valid */
1338 if ((comb_verh && comb_verl) &&
1339 ((comb_verh != NVM_VER_INVALID) &&
1340 (comb_verl != NVM_VER_INVALID))) {
1341
1342 fw_vers->or_valid = true;
1343 fw_vers->or_major =
1344 comb_verl >> NVM_COMB_VER_SHFT;
1345 fw_vers->or_build =
1346 (comb_verl << NVM_COMB_VER_SHFT)
1347 | (comb_verh >> NVM_COMB_VER_SHFT);
1348 fw_vers->or_patch =
1349 comb_verh & NVM_COMB_VER_MASK;
1350 }
1351 }
1352 break;
1353 default:
1354 hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
1355 return;
1356 }
1357 hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
1358 fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK)
1359 >> NVM_MAJOR_SHIFT;
1360
1361 /* check for old style version format in newer images*/
1362 if ((fw_version & NVM_NEW_DEC_MASK) == 0x0) {
1363 eeprom_verl = (fw_version & NVM_COMB_VER_MASK);
1364 } else {
1365 eeprom_verl = (fw_version & NVM_MINOR_MASK)
1366 >> NVM_MINOR_SHIFT;
1367 }
1368 /* Convert minor value to hex before assigning to output struct
1369 * Val to be converted will not be higher than 99, per tool output
1370 */
1371 q = eeprom_verl / NVM_HEX_CONV;
1372 hval = q * NVM_HEX_TENS;
1373 rem = eeprom_verl % NVM_HEX_CONV;
1374 result = hval + rem;
1375 fw_vers->eep_minor = result;
1376
1377etrack_id:
1378 if ((etrack_test & NVM_MAJOR_MASK) == NVM_ETRACK_VALID) {
1379 hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
1380 hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
1381 fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT)
1382 | eeprom_verl;
1383 } else if ((etrack_test & NVM_ETRACK_VALID) == 0) {
1384 hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh);
1385 hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl);
1386 fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) |
1387 eeprom_verl;
1388 }
1389}
1390
1391
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_api.c:1358
s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_api.c:1340
#define NVM_ETRACK_VALID
#define NVM_READ_OPCODE_SPI
#define E1000_NVM_RW_REG_DONE
#define E1000_ERR_PARAM
#define NVM_COMB_VER_MASK
#define NVM_HEX_CONV
#define E1000_PBANUM_LENGTH
#define NVM_MAJOR_MASK
#define E1000_NVM_GRANT_ATTEMPTS
#define NVM_HEX_TENS
#define NVM_MAX_RETRY_SPI
#define NVM_VERSION
#define NVM_MINOR_MASK
#define NVM_PBA_OFFSET_1
#define NVM_PBA_PTR_GUARD
#define E1000_EECD_DI
#define NVM_WRITE_OPCODE_MICROWIRE
#define NVM_EWEN_OPCODE_MICROWIRE
#define E1000_EECD_CS
#define NVM_ETRACK_HIWORD
#define E1000_ERR_NVM_PBA_SECTION
#define NVM_READ_OPCODE_MICROWIRE
#define NVM_VER_INVALID
#define E1000_EECD_GNT
#define E1000_NVM_RW_REG_DATA
#define E1000_NVM_RW_ADDR_SHIFT
#define E1000_ERR_NO_SPACE
#define NVM_ETRACK_SHIFT
#define NVM_STATUS_RDY_SPI
#define NVM_IMAGE_ID_MASK
#define E1000_NVM_RW_REG_START
#define NVM_COMB_VER_OFF
#define NVM_RDSR_OPCODE_SPI
#define NVM_COMB_VER_SHFT
#define E1000_EECD_REQ
#define E1000_RAH_MAC_ADDR_LEN
#define NVM_MINOR_SHIFT
#define E1000_EECD_DO
#define E1000_ERR_INVALID_ARGUMENT
#define NVM_WRITE_OPCODE_SPI
#define NVM_CHECKSUM_REG
#define E1000_NVM_POLL_READ
#define NVM_WREN_OPCODE_SPI
#define NVM_SUM
#define NVM_PBA_OFFSET_0
#define NVM_ETRACK_WORD
#define NVM_EWDS_OPCODE_MICROWIRE
#define NVM_MAJOR_SHIFT
#define E1000_SUCCESS
#define E1000_UNUSEDARG
#define E1000_CTRL_EXT_EE_RST
Definition: e1000_defines.h:78
#define NVM_COMB_VER_PTR
#define NVM_A8_OPCODE_SPI
#define E1000_ERR_NVM
#define E1000_EECD_SK
#define E1000_RAL_MAC_ADDR_LEN
#define E1000_NOT_IMPLEMENTED
#define NVM_NEW_DEC_MASK
@ e1000_82580
Definition: e1000_hw.h:271
@ e1000_i354
Definition: e1000_hw.h:273
@ e1000_i210
Definition: e1000_hw.h:274
@ e1000_i350
Definition: e1000_hw.h:272
@ e1000_82575
Definition: e1000_hw.h:269
@ e1000_82576
Definition: e1000_hw.h:270
@ e1000_i211
Definition: e1000_hw.h:275
@ e1000_nvm_eeprom_spi
Definition: e1000_hw.h:292
@ e1000_nvm_eeprom_microwire
Definition: e1000_hw.h:293
bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
Definition: e1000_i210.c:552
s32 e1000_read_invm_version(struct e1000_hw *hw, struct e1000_fw_version *invm_ver)
Definition: e1000_i210.c:355
s32 e1000_null_ops_generic(struct e1000_hw E1000_UNUSEDARG *hw)
Definition: e1000_mac.c:88
void e1000_null_nvm_generic(struct e1000_hw E1000_UNUSEDARG *hw)
Definition: e1000_nvm.c:82
static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count)
Definition: e1000_nvm.c:155
static void e1000_standby_nvm(struct e1000_hw *hw)
Definition: e1000_nvm.c:303
s32 e1000_null_led_default(struct e1000_hw E1000_UNUSEDARG *hw, u16 E1000_UNUSEDARG *data)
Definition: e1000_nvm.c:93
s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, u32 eeprom_buf_size, struct e1000_pba *pba)
Definition: e1000_nvm.c:1059
s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num)
Definition: e1000_nvm.c:950
static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
Definition: e1000_nvm.c:389
static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd)
Definition: e1000_nvm.c:122
void e1000_stop_nvm(struct e1000_hw *hw)
Definition: e1000_nvm.c:344
s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:1235
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_nvm.c:508
s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:1174
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_nvm.c:611
s32 e1000_null_write_nvm(struct e1000_hw E1000_UNUSEDARG *hw, u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b, u16 E1000_UNUSEDARG *c)
Definition: e1000_nvm.c:107
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size)
Definition: e1000_nvm.c:775
static void e1000_reload_nvm_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:1266
s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_nvm.c:563
s32 e1000_null_read_nvm(struct e1000_hw E1000_UNUSEDARG *hw, u16 E1000_UNUSEDARG a, u16 E1000_UNUSEDARG b, u16 E1000_UNUSEDARG *c)
Definition: e1000_nvm.c:70
void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
Definition: e1000_nvm.c:1286
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_nvm.c:448
s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
Definition: e1000_nvm.c:891
s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
Definition: e1000_nvm.c:691
s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf, u32 eeprom_buf_size, u16 max_pba_block_size, struct e1000_pba *pba)
Definition: e1000_nvm.c:990
void e1000_release_nvm_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:370
static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd)
Definition: e1000_nvm.c:137
static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count)
Definition: e1000_nvm.c:202
s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
Definition: e1000_nvm.c:239
s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:269
void e1000_init_nvm_ops_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:46
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
Definition: e1000_nvm.c:1202
s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf, u32 eeprom_buf_size, u16 *pba_block_size)
Definition: e1000_nvm.c:1118
#define DEBUGOUT1(...)
Definition: e1000_osdep.h:111
#define msec_delay(x)
Definition: e1000_osdep.h:103
#define usec_delay(x)
Definition: e1000_osdep.h:101
uint8_t u8
Definition: e1000_osdep.h:124
#define DEBUGFUNC(F)
Definition: e1000_osdep.h:115
#define E1000_WRITE_FLUSH(a)
Definition: e1000_osdep.h:177
#define E1000_WRITE_REG(hw, reg, value)
Definition: e1000_osdep.h:196
uint16_t u16
Definition: e1000_osdep.h:123
#define DEBUGOUT(...)
Definition: e1000_osdep.h:109
#define E1000_READ_REG(hw, reg)
Definition: e1000_osdep.h:191
int32_t s32
Definition: e1000_osdep.h:126
uint32_t u32
Definition: e1000_osdep.h:122
#define E1000_RAH(_i)
Definition: e1000_regs.h:292
#define E1000_EERD
Definition: e1000_regs.h:43
#define E1000_EEWR
Definition: e1000_regs.h:124
#define E1000_EECD
Definition: e1000_regs.h:42
#define E1000_RAL(_i)
Definition: e1000_regs.h:290
#define E1000_CTRL_EXT
Definition: e1000_regs.h:44
struct e1000_mac_info mac
Definition: e1000_hw.h:1028
struct e1000_nvm_info nvm
Definition: e1000_hw.h:1031
enum e1000_mac_type type
Definition: e1000_hw.h:815
u8 addr[ETHER_ADDR_LEN]
Definition: e1000_hw.h:812
u8 perm_addr[ETHER_ADDR_LEN]
Definition: e1000_hw.h:813
struct e1000_nvm_operations ops
Definition: e1000_hw.h:889
enum e1000_nvm_type type
Definition: e1000_hw.h:890
u16 address_bits
Definition: e1000_hw.h:898
void(* release)(struct e1000_hw *)
Definition: e1000_hw.h:802
s32(* init_params)(struct e1000_hw *)
Definition: e1000_hw.h:799
s32(* write)(struct e1000_hw *, u16, u16, u16 *)
Definition: e1000_hw.h:807
void(* reload)(struct e1000_hw *)
Definition: e1000_hw.h:803
s32(* validate)(struct e1000_hw *)
Definition: e1000_hw.h:806
s32(* update)(struct e1000_hw *)
Definition: e1000_hw.h:804
s32(* read)(struct e1000_hw *, u16, u16, u16 *)
Definition: e1000_hw.h:801
s32(* acquire)(struct e1000_hw *)
Definition: e1000_hw.h:800
s32(* valid_led_default)(struct e1000_hw *, u16 *)
Definition: e1000_hw.h:805
u16 word[2]
Definition: e1000_nvm.h:40
u16 * pba_block
Definition: e1000_nvm.h:41