xref: /openbsd/sys/dev/pci/ixgb_ee.c (revision 54fbbda3)
1 /*******************************************************************************
2 
3   Copyright (c) 2001-2005, Intel Corporation
4   All rights reserved.
5 
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8 
9    1. Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11 
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15 
16    3. Neither the name of the Intel Corporation nor the names of its
17       contributors may be used to endorse or promote products derived from
18       this software without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE.
31 
32 *******************************************************************************/
33 
34 /* $OpenBSD: ixgb_ee.c,v 1.10 2024/09/01 03:08:59 jsg Exp $ */
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
39 
40 #include <net/if.h>
41 #include <net/if_media.h>
42 
43 #include <netinet/in.h>
44 #include <netinet/if_ether.h>
45 
46 #include <uvm/uvm_extern.h>
47 
48 #include <dev/pci/pcireg.h>
49 #include <dev/pci/pcivar.h>
50 
51 #include <dev/pci/ixgb_hw.h>
52 #include <dev/pci/ixgb_ee.h>
53 
54 /* Local prototypes */
55 static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
56 
57 static void ixgb_shift_out_bits(struct ixgb_hw *hw, uint16_t data,
58                                 uint16_t count);
59 static void ixgb_standby_eeprom(struct ixgb_hw *hw);
60 
61 static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
62 
63 static void ixgb_cleanup_eeprom(struct ixgb_hw *hw);
64 
65 /******************************************************************************
66  * Raises the EEPROM's clock input.
67  *
68  * hw - Struct containing variables accessed by shared code
69  * eecd_reg - EECD's current value
70  *****************************************************************************/
71 static void
ixgb_raise_clock(struct ixgb_hw * hw,uint32_t * eecd_reg)72 ixgb_raise_clock(struct ixgb_hw *hw, uint32_t *eecd_reg)
73 {
74 	/* Raise the clock input to the EEPROM (by setting the SK bit), and
75 	 * then wait 50 microseconds. */
76 	*eecd_reg = *eecd_reg | IXGB_EECD_SK;
77 	IXGB_WRITE_REG(hw, EECD, *eecd_reg);
78 	usec_delay(50);
79 	return;
80 }
81 
82 /******************************************************************************
83  * Lowers the EEPROM's clock input.
84  *
85  * hw - Struct containing variables accessed by shared code
86  * eecd_reg - EECD's current value
87  *****************************************************************************/
88 static void
ixgb_lower_clock(struct ixgb_hw * hw,uint32_t * eecd_reg)89 ixgb_lower_clock(struct ixgb_hw *hw, uint32_t *eecd_reg)
90 {
91 	/* Lower the clock input to the EEPROM (by clearing the SK bit), and
92 	 * then wait 50 microseconds. */
93 	*eecd_reg = *eecd_reg & ~IXGB_EECD_SK;
94 	IXGB_WRITE_REG(hw, EECD, *eecd_reg);
95 	usec_delay(50);
96 	return;
97 }
98 
99 /******************************************************************************
100  * Shift data bits out to the EEPROM.
101  *
102  * hw - Struct containing variables accessed by shared code
103  * data - data to send to the EEPROM
104  * count - number of bits to shift out
105  *****************************************************************************/
106 static void
ixgb_shift_out_bits(struct ixgb_hw * hw,uint16_t data,uint16_t count)107 ixgb_shift_out_bits(struct ixgb_hw *hw, uint16_t data, uint16_t count)
108 {
109 	uint32_t eecd_reg;
110 	uint32_t mask;
111 
112 	/* We need to shift "count" bits out to the EEPROM. So, value in the
113 	 * "data" parameter will be shifted out to the EEPROM one bit at a
114 	 * time. In order to do this, "data" must be broken down into bits. */
115 	mask = 0x01 << (count - 1);
116 	eecd_reg = IXGB_READ_REG(hw, EECD);
117 	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
118 	do {
119 		/* A "1" is shifted out to the EEPROM by setting bit "DI" to a
120 		 * "1", and then raising and then lowering the clock (the SK
121 		 * bit controls the clock input to the EEPROM).  A "0" is
122 		 * shifted out to the EEPROM by setting "DI" to "0" and then
123 		 * raising and then lowering the clock. */
124 		eecd_reg &= ~IXGB_EECD_DI;
125 
126 		if(data & mask)
127 			eecd_reg |= IXGB_EECD_DI;
128 
129 		IXGB_WRITE_REG(hw, EECD, eecd_reg);
130 
131 		usec_delay(50);
132 
133 		ixgb_raise_clock(hw, &eecd_reg);
134 		ixgb_lower_clock(hw, &eecd_reg);
135 
136 		mask = mask >> 1;
137 
138 	} while(mask);
139 
140 	/* We leave the "DI" bit set to "0" when we leave this routine. */
141 	eecd_reg &= ~IXGB_EECD_DI;
142 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
143 	return;
144 }
145 
146 /******************************************************************************
147  * Shift data bits in from the EEPROM
148  *
149  * hw - Struct containing variables accessed by shared code
150  *****************************************************************************/
151 static uint16_t
ixgb_shift_in_bits(struct ixgb_hw * hw)152 ixgb_shift_in_bits(struct ixgb_hw *hw)
153 {
154 	uint32_t eecd_reg;
155 	uint32_t i;
156 	uint16_t data;
157 
158 	/* In order to read a register from the EEPROM, we need to shift 16
159 	 * bits in from the EEPROM. Bits are "shifted in" by raising the clock
160 	 * input to the EEPROM (setting the SK bit), and then reading the value
161 	 * of the "DO" bit.  During this "shifting in" process the "DI" bit
162 	 * should always be clear.. */
163 
164 	eecd_reg = IXGB_READ_REG(hw, EECD);
165 
166 	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
167 	data = 0;
168 
169 	for(i = 0; i < 16; i++) {
170 		data = data << 1;
171 		ixgb_raise_clock(hw, &eecd_reg);
172 
173 		eecd_reg = IXGB_READ_REG(hw, EECD);
174 
175 		eecd_reg &= ~(IXGB_EECD_DI);
176 		if(eecd_reg & IXGB_EECD_DO)
177 			data |= 1;
178 
179 		ixgb_lower_clock(hw, &eecd_reg);
180 	}
181 
182 	return data;
183 }
184 
185 /******************************************************************************
186  * Prepares EEPROM for access
187  *
188  * hw - Struct containing variables accessed by shared code
189  *
190  * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
191  * function should be called before issuing a command to the EEPROM.
192  *****************************************************************************/
193 static void
ixgb_setup_eeprom(struct ixgb_hw * hw)194 ixgb_setup_eeprom(struct ixgb_hw *hw)
195 {
196 	uint32_t eecd_reg;
197 
198 	eecd_reg = IXGB_READ_REG(hw, EECD);
199 
200 	/* Clear SK and DI */
201 	eecd_reg &= ~(IXGB_EECD_SK | IXGB_EECD_DI);
202 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
203 
204 	/* Set CS */
205 	eecd_reg |= IXGB_EECD_CS;
206 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
207 	return;
208 }
209 
210 /******************************************************************************
211  * Returns EEPROM to a "standby" state
212  *
213  * hw - Struct containing variables accessed by shared code
214  *****************************************************************************/
215 static void
ixgb_standby_eeprom(struct ixgb_hw * hw)216 ixgb_standby_eeprom(struct ixgb_hw *hw)
217 {
218 	uint32_t eecd_reg;
219 
220 	eecd_reg = IXGB_READ_REG(hw, EECD);
221 
222 	/* Deselect EEPROM */
223 	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);
224 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
225 	usec_delay(50);
226 
227 	/* Clock high */
228 	eecd_reg |= IXGB_EECD_SK;
229 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
230 	usec_delay(50);
231 
232 	/* Select EEPROM */
233 	eecd_reg |= IXGB_EECD_CS;
234 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
235 	usec_delay(50);
236 
237 	/* Clock low */
238 	eecd_reg &= ~IXGB_EECD_SK;
239 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
240 	usec_delay(50);
241 	return;
242 }
243 
244 /******************************************************************************
245  * Raises then lowers the EEPROM's clock pin
246  *
247  * hw - Struct containing variables accessed by shared code
248  *****************************************************************************/
249 static void
ixgb_clock_eeprom(struct ixgb_hw * hw)250 ixgb_clock_eeprom(struct ixgb_hw *hw)
251 {
252 	uint32_t eecd_reg;
253 
254 	eecd_reg = IXGB_READ_REG(hw, EECD);
255 
256 	/* Rising edge of clock */
257 	eecd_reg |= IXGB_EECD_SK;
258 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
259 	usec_delay(50);
260 
261 	/* Falling edge of clock */
262 	eecd_reg &= ~IXGB_EECD_SK;
263 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
264 	usec_delay(50);
265 	return;
266 }
267 
268 /******************************************************************************
269  * Terminates a command by lowering the EEPROM's chip select pin
270  *
271  * hw - Struct containing variables accessed by shared code
272  *****************************************************************************/
273 static void
ixgb_cleanup_eeprom(struct ixgb_hw * hw)274 ixgb_cleanup_eeprom(struct ixgb_hw *hw)
275 {
276 	uint32_t eecd_reg;
277 
278 	eecd_reg = IXGB_READ_REG(hw, EECD);
279 
280 	eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_DI);
281 
282 	IXGB_WRITE_REG(hw, EECD, eecd_reg);
283 
284 	ixgb_clock_eeprom(hw);
285 	return;
286 }
287 
288 /******************************************************************************
289  * Waits for the EEPROM to finish the current command.
290  *
291  * hw - Struct containing variables accessed by shared code
292  *
293  * The command is done when the EEPROM's data out pin goes high.
294  *
295  * Returns:
296  *      TRUE: EEPROM data pin is high before timeout.
297  *      FALSE:  Time expired.
298  *****************************************************************************/
299 static boolean_t
ixgb_wait_eeprom_command(struct ixgb_hw * hw)300 ixgb_wait_eeprom_command(struct ixgb_hw *hw)
301 {
302 	uint32_t eecd_reg;
303 	uint32_t i;
304 
305 	/* Toggle the CS line.  This in effect tells to EEPROM to actually
306 	 * execute the command in question. */
307 	ixgb_standby_eeprom(hw);
308 
309 	/* Now read DO repeatedly until is high (equal to '1').  The EEPROM
310 	 * will signal that the command has been completed by raising the DO
311 	 * signal. If DO does not go high in 10 milliseconds, then error out. */
312 	for(i = 0; i < 200; i++) {
313 		eecd_reg = IXGB_READ_REG(hw, EECD);
314 
315 		if(eecd_reg & IXGB_EECD_DO)
316 			return (TRUE);
317 
318 		usec_delay(50);
319 	}
320 	ASSERT(0);
321 	return (FALSE);
322 }
323 
324 /******************************************************************************
325  * Verifies that the EEPROM has a valid checksum
326  *
327  * hw - Struct containing variables accessed by shared code
328  *
329  * Reads the first 64 16 bit words of the EEPROM and sums the values read.
330  * If the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
331  * valid.
332  *
333  * Returns:
334  *  TRUE: Checksum is valid
335  *  FALSE: Checksum is not valid.
336  *****************************************************************************/
337 boolean_t
ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)338 ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
339 {
340 	uint16_t checksum = 0;
341 	uint16_t i;
342 
343 	for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
344 		checksum += ixgb_read_eeprom(hw, i);
345 
346 	if(checksum == (uint16_t)EEPROM_SUM)
347 		return (TRUE);
348 	else
349 		return (FALSE);
350 }
351 
352 /******************************************************************************
353  * Calculates the EEPROM checksum and writes it to the EEPROM
354  *
355  * hw - Struct containing variables accessed by shared code
356  *
357  * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
358  * Writes the difference to word offset 63 of the EEPROM.
359  *****************************************************************************/
360 void
ixgb_update_eeprom_checksum(struct ixgb_hw * hw)361 ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
362 {
363 	uint16_t checksum = 0;
364 	uint16_t i;
365 
366 	for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
367 		checksum += ixgb_read_eeprom(hw, i);
368 
369 	checksum = (uint16_t)EEPROM_SUM - checksum;
370 
371 	ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum);
372 	return;
373 }
374 
375 /******************************************************************************
376  * Writes a 16 bit word to a given offset in the EEPROM.
377  *
378  * hw - Struct containing variables accessed by shared code
379  * reg - offset within the EEPROM to be written to
380  * data - 16 bit word to be written to the EEPROM
381  *
382  * If ixgb_update_eeprom_checksum is not called after this function, the
383  * EEPROM will most likely contain an invalid checksum.
384  *
385  *****************************************************************************/
386 void
ixgb_write_eeprom(struct ixgb_hw * hw,uint16_t offset,uint16_t data)387 ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
388 {
389 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
390 
391 	/* Prepare the EEPROM for writing */
392 	ixgb_setup_eeprom(hw);
393 
394 	/* Send the 9-bit EWEN (write enable) command to the EEPROM (5-bit
395 	 * opcode plus 4-bit dummy).  This puts the EEPROM into write/erase
396 	 * mode. */
397 	ixgb_shift_out_bits(hw, EEPROM_EWEN_OPCODE, 5);
398 	ixgb_shift_out_bits(hw, 0, 4);
399 
400 	/* Prepare the EEPROM */
401 	ixgb_standby_eeprom(hw);
402 
403 	/* Send the Write command (3-bit opcode + 6-bit addr) */
404 	ixgb_shift_out_bits(hw, EEPROM_WRITE_OPCODE, 3);
405 	ixgb_shift_out_bits(hw, offset, 6);
406 
407 	/* Send the data */
408 	ixgb_shift_out_bits(hw, data, 16);
409 
410 	ixgb_wait_eeprom_command(hw);
411 
412 	/* Recover from write */
413 	ixgb_standby_eeprom(hw);
414 
415 	/* Send the 9-bit EWDS (write disable) command to the EEPROM (5-bit
416 	 * opcode plus 4-bit dummy).  This takes the EEPROM out of write/erase
417 	 * mode. */
418 	ixgb_shift_out_bits(hw, EEPROM_EWDS_OPCODE, 5);
419 	ixgb_shift_out_bits(hw, 0, 4);
420 
421 	/* Done with writing */
422 	ixgb_cleanup_eeprom(hw);
423 
424 	/* clear the init_ctrl_reg_1 to signify that the cache is invalidated */
425 	ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR);
426 
427 	return;
428 }
429 
430 /******************************************************************************
431  * Reads a 16 bit word from the EEPROM.
432  *
433  * hw - Struct containing variables accessed by shared code
434  * offset - offset of 16 bit word in the EEPROM to read
435  *
436  * Returns:
437  *  The 16-bit value read from the eeprom
438  *****************************************************************************/
439 uint16_t
ixgb_read_eeprom(struct ixgb_hw * hw,uint16_t offset)440 ixgb_read_eeprom(struct ixgb_hw *hw, uint16_t offset)
441 {
442 	uint16_t data;
443 
444 	/* Prepare the EEPROM for reading */
445 	ixgb_setup_eeprom(hw);
446 
447 	/* Send the READ command (opcode + addr) */
448 	ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3);
449 	/*
450 	 * We have a 64 word EEPROM, there are 6 address bits
451 	 */
452 	ixgb_shift_out_bits(hw, offset, 6);
453 
454 	/* Read the data */
455 	data = ixgb_shift_in_bits(hw);
456 
457 	/* End this read operation */
458 	ixgb_standby_eeprom(hw);
459 
460 	return (data);
461 }
462 
463 /******************************************************************************
464  * Reads eeprom and stores data in shared structure.
465  * Validates eeprom checksum and eeprom signature.
466  *
467  * hw - Struct containing variables accessed by shared code
468  *
469  * Returns:
470  *      TRUE: if eeprom read is successful
471  *      FALSE: otherwise.
472  *****************************************************************************/
473 boolean_t
ixgb_get_eeprom_data(struct ixgb_hw * hw)474 ixgb_get_eeprom_data(struct ixgb_hw *hw)
475 {
476 	uint16_t i;
477 	uint16_t checksum = 0;
478 	struct ixgb_ee_map_type *ee_map;
479 
480 	DEBUGFUNC("ixgb_get_eeprom_data");
481 
482 	ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
483 
484 	DEBUGOUT("ixgb_ee: Reading eeprom data\n");
485 	for(i = 0; i < IXGB_EEPROM_SIZE; i++) {
486 		uint16_t ee_data;
487 
488 		ee_data = ixgb_read_eeprom(hw, i);
489 		checksum += ee_data;
490 		hw->eeprom[i] = le16_to_cpu(ee_data);
491 	}
492 
493 	if(checksum != (uint16_t)EEPROM_SUM) {
494 		DEBUGOUT("ixgb_ee: Checksum invalid.\n");
495 		/* clear the init_ctrl_reg_1 to signify that the cache is
496 		 * invalidated */
497 		ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR);
498 		return (FALSE);
499 	}
500 
501 	if((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
502 	   != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
503 		DEBUGOUT("ixgb_ee: Signature invalid.\n");
504 		return (FALSE);
505 	}
506 
507 	return (TRUE);
508 }
509 
510 /******************************************************************************
511  * Local function to check if the eeprom signature is good
512  * If the eeprom signature is good, calls ixgb)get_eeprom_data.
513  *
514  * hw - Struct containing variables accessed by shared code
515  *
516  * Returns:
517  *      TRUE: eeprom signature was good and the eeprom read was successful
518  *      FALSE: otherwise.
519  ******************************************************************************/
520 static boolean_t
ixgb_check_and_get_eeprom_data(struct ixgb_hw * hw)521 ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
522 {
523 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
524 
525 	if((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
526 	   == le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
527 		return (TRUE);
528 	} else {
529 		return ixgb_get_eeprom_data(hw);
530 	}
531 }
532 
533 /******************************************************************************
534  * return a word from the eeprom
535  *
536  * hw - Struct containing variables accessed by shared code
537  * index - Offset of eeprom word
538  *
539  * Returns:
540  *          Word at indexed offset in eeprom, if valid, 0 otherwise.
541  ******************************************************************************/
542 uint16_t
ixgb_get_eeprom_word(struct ixgb_hw * hw,uint16_t index)543 ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index)
544 {
545 
546 	if((index < IXGB_EEPROM_SIZE) &&
547 	   (ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
548 		return (hw->eeprom[index]);
549 	}
550 
551 	return (0);
552 }
553 
554 /******************************************************************************
555  * return the mac address from EEPROM
556  *
557  * hw       - Struct containing variables accessed by shared code
558  * mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise
559  *
560  * Returns: None.
561  ******************************************************************************/
562 void
ixgb_get_ee_mac_addr(struct ixgb_hw * hw,uint8_t * mac_addr)563 ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr)
564 {
565 	int i;
566 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
567 
568 	DEBUGFUNC("ixgb_get_ee_mac_addr");
569 
570 	if(ixgb_check_and_get_eeprom_data(hw) == TRUE) {
571 		for(i = 0; i < IXGB_ETH_LENGTH_OF_ADDRESS; i++) {
572 			mac_addr[i] = ee_map->mac_addr[i];
573 			DEBUGOUT2("mac(%d) = %.2X\n", i, mac_addr[i]);
574 		}
575 	}
576 }
577 
578 
579 /******************************************************************************
580  * return the Printed Board Assembly number from EEPROM
581  *
582  * hw - Struct containing variables accessed by shared code
583  *
584  * Returns:
585  *          PBA number if EEPROM contents are valid, 0 otherwise
586  ******************************************************************************/
587 uint32_t
ixgb_get_ee_pba_number(struct ixgb_hw * hw)588 ixgb_get_ee_pba_number(struct ixgb_hw *hw)
589 {
590 	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
591 		return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
592 			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG]) << 16));
593 
594 	return (0);
595 }
596 
597 
598 /******************************************************************************
599  * return the Device Id from EEPROM
600  *
601  * hw - Struct containing variables accessed by shared code
602  *
603  * Returns:
604  *          Device Id if EEPROM contents are valid, 0 otherwise
605  ******************************************************************************/
606 uint16_t
ixgb_get_ee_device_id(struct ixgb_hw * hw)607 ixgb_get_ee_device_id(struct ixgb_hw *hw)
608 {
609 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
610 
611 	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
612 		return (le16_to_cpu(ee_map->device_id));
613 
614 	return (0);
615 }
616 
617