1129794Stackerman/*******************************************************************************
2129794Stackerman
3129794Stackerman  Copyright (c) 2001-2004, Intel Corporation
4129794Stackerman  All rights reserved.
5129794Stackerman
6129794Stackerman  Redistribution and use in source and binary forms, with or without
7129794Stackerman  modification, are permitted provided that the following conditions are met:
8129794Stackerman
9129794Stackerman   1. Redistributions of source code must retain the above copyright notice,
10129794Stackerman      this list of conditions and the following disclaimer.
11129794Stackerman
12129794Stackerman   2. Redistributions in binary form must reproduce the above copyright
13129794Stackerman      notice, this list of conditions and the following disclaimer in the
14129794Stackerman      documentation and/or other materials provided with the distribution.
15129794Stackerman
16129794Stackerman   3. Neither the name of the Intel Corporation nor the names of its
17129794Stackerman      contributors may be used to endorse or promote products derived from
18129794Stackerman      this software without specific prior written permission.
19129794Stackerman
20129794Stackerman  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21129794Stackerman  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22129794Stackerman  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23129794Stackerman  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24129794Stackerman  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25129794Stackerman  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26129794Stackerman  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27129794Stackerman  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28129794Stackerman  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29129794Stackerman  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30129794Stackerman  POSSIBILITY OF SUCH DAMAGE.
31129794Stackerman
32129794Stackerman*******************************************************************************/
33129794Stackerman
34129794Stackerman/*$FreeBSD$*/
35129794Stackerman
36129794Stackerman#include <dev/ixgb/ixgb_hw.h>
37129794Stackerman#include <dev/ixgb/ixgb_ee.h>
38129794Stackerman
39129794Stackerman/* Local prototypes */
40129794Stackermanstatic uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
41129794Stackerman
42129794Stackermanstatic void ixgb_shift_out_bits(struct ixgb_hw *hw,
43129794Stackerman                                uint16_t data,
44129794Stackerman                                uint16_t count);
45129794Stackermanstatic void ixgb_standby_eeprom(struct ixgb_hw *hw);
46129794Stackerman
47129794Stackermanstatic boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
48129794Stackerman
49129794Stackermanstatic void ixgb_cleanup_eeprom(struct ixgb_hw *hw);
50129794Stackerman
51129794Stackerman/******************************************************************************
52129794Stackerman * Raises the EEPROM's clock input.
53129794Stackerman *
54129794Stackerman * hw - Struct containing variables accessed by shared code
55129794Stackerman * eecd_reg - EECD's current value
56129794Stackerman *****************************************************************************/
57129794Stackermanstatic void
58129794Stackermanixgb_raise_clock(struct ixgb_hw *hw,
59129794Stackerman                  uint32_t *eecd_reg)
60129794Stackerman{
61129794Stackerman    /* Raise the clock input to the EEPROM (by setting the SK bit), and then
62129794Stackerman     *  wait 50 microseconds.
63129794Stackerman     */
64129794Stackerman    *eecd_reg = *eecd_reg | IXGB_EECD_SK;
65129794Stackerman    IXGB_WRITE_REG(hw, EECD, *eecd_reg);
66129794Stackerman    usec_delay(50);
67129794Stackerman    return;
68129794Stackerman}
69129794Stackerman
70129794Stackerman/******************************************************************************
71129794Stackerman * Lowers the EEPROM's clock input.
72129794Stackerman *
73129794Stackerman * hw - Struct containing variables accessed by shared code
74129794Stackerman * eecd_reg - EECD's current value
75129794Stackerman *****************************************************************************/
76129794Stackermanstatic void
77129794Stackermanixgb_lower_clock(struct ixgb_hw *hw,
78129794Stackerman                  uint32_t *eecd_reg)
79129794Stackerman{
80129794Stackerman    /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
81129794Stackerman     * wait 50 microseconds.
82129794Stackerman     */
83129794Stackerman    *eecd_reg = *eecd_reg & ~IXGB_EECD_SK;
84129794Stackerman    IXGB_WRITE_REG(hw, EECD, *eecd_reg);
85129794Stackerman    usec_delay(50);
86129794Stackerman    return;
87129794Stackerman}
88129794Stackerman
89129794Stackerman/******************************************************************************
90129794Stackerman * Shift data bits out to the EEPROM.
91129794Stackerman *
92129794Stackerman * hw - Struct containing variables accessed by shared code
93129794Stackerman * data - data to send to the EEPROM
94129794Stackerman * count - number of bits to shift out
95129794Stackerman *****************************************************************************/
96129794Stackermanstatic void
97129794Stackermanixgb_shift_out_bits(struct ixgb_hw *hw,
98129794Stackerman                     uint16_t data,
99129794Stackerman                     uint16_t count)
100129794Stackerman{
101129794Stackerman    uint32_t eecd_reg;
102129794Stackerman    uint32_t mask;
103129794Stackerman
104129794Stackerman    /* We need to shift "count" bits out to the EEPROM. So, value in the
105129794Stackerman     * "data" parameter will be shifted out to the EEPROM one bit at a time.
106129794Stackerman     * In order to do this, "data" must be broken down into bits.
107129794Stackerman     */
108129794Stackerman    mask = 0x01 << (count - 1);
109129794Stackerman    eecd_reg = IXGB_READ_REG(hw, EECD);
110129794Stackerman    eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
111129794Stackerman    do {
112129794Stackerman        /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
113129794Stackerman         * and then raising and then lowering the clock (the SK bit controls
114129794Stackerman         * the clock input to the EEPROM).  A "0" is shifted out to the EEPROM
115129794Stackerman         * by setting "DI" to "0" and then raising and then lowering the clock.
116129794Stackerman         */
117129794Stackerman        eecd_reg &= ~IXGB_EECD_DI;
118129794Stackerman
119129794Stackerman        if(data & mask)
120129794Stackerman            eecd_reg |= IXGB_EECD_DI;
121129794Stackerman
122129794Stackerman        IXGB_WRITE_REG(hw, EECD, eecd_reg);
123129794Stackerman
124129794Stackerman        usec_delay(50);
125129794Stackerman
126129794Stackerman        ixgb_raise_clock(hw, &eecd_reg);
127129794Stackerman        ixgb_lower_clock(hw, &eecd_reg);
128129794Stackerman
129129794Stackerman        mask = mask >> 1;
130129794Stackerman
131129794Stackerman    } while(mask);
132129794Stackerman
133129794Stackerman    /* We leave the "DI" bit set to "0" when we leave this routine. */
134129794Stackerman    eecd_reg &= ~IXGB_EECD_DI;
135129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
136129794Stackerman    return;
137129794Stackerman}
138129794Stackerman
139129794Stackerman/******************************************************************************
140129794Stackerman * Shift data bits in from the EEPROM
141129794Stackerman *
142129794Stackerman * hw - Struct containing variables accessed by shared code
143129794Stackerman *****************************************************************************/
144129794Stackermanstatic uint16_t
145129794Stackermanixgb_shift_in_bits(struct ixgb_hw *hw)
146129794Stackerman{
147129794Stackerman    uint32_t eecd_reg;
148129794Stackerman    uint32_t i;
149129794Stackerman    uint16_t data;
150129794Stackerman
151129794Stackerman    /* In order to read a register from the EEPROM, we need to shift 16 bits
152129794Stackerman     * in from the EEPROM. Bits are "shifted in" by raising the clock input to
153129794Stackerman     * the EEPROM (setting the SK bit), and then reading the value of the "DO"
154129794Stackerman     * bit.  During this "shifting in" process the "DI" bit should always be
155129794Stackerman     * clear..
156129794Stackerman     */
157129794Stackerman
158129794Stackerman    eecd_reg = IXGB_READ_REG(hw, EECD);
159129794Stackerman
160129794Stackerman    eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
161129794Stackerman    data = 0;
162129794Stackerman
163129794Stackerman    for(i = 0; i < 16; i++) {
164129794Stackerman        data = data << 1;
165129794Stackerman        ixgb_raise_clock(hw, &eecd_reg);
166129794Stackerman
167129794Stackerman        eecd_reg = IXGB_READ_REG(hw, EECD);
168129794Stackerman
169129794Stackerman        eecd_reg &= ~(IXGB_EECD_DI);
170129794Stackerman        if(eecd_reg & IXGB_EECD_DO)
171129794Stackerman            data |= 1;
172129794Stackerman
173129794Stackerman        ixgb_lower_clock(hw, &eecd_reg);
174129794Stackerman    }
175129794Stackerman
176129794Stackerman    return data;
177129794Stackerman}
178129794Stackerman
179129794Stackerman/******************************************************************************
180129794Stackerman * Prepares EEPROM for access
181129794Stackerman *
182129794Stackerman * hw - Struct containing variables accessed by shared code
183129794Stackerman *
184129794Stackerman * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
185129794Stackerman * function should be called before issuing a command to the EEPROM.
186129794Stackerman *****************************************************************************/
187129794Stackermanstatic void
188129794Stackermanixgb_setup_eeprom(struct ixgb_hw *hw)
189129794Stackerman{
190129794Stackerman    uint32_t eecd_reg;
191129794Stackerman
192129794Stackerman    eecd_reg = IXGB_READ_REG(hw, EECD);
193129794Stackerman
194129794Stackerman    /*  Clear SK and DI  */
195129794Stackerman    eecd_reg &= ~(IXGB_EECD_SK | IXGB_EECD_DI);
196129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
197129794Stackerman
198129794Stackerman    /*  Set CS  */
199129794Stackerman    eecd_reg |= IXGB_EECD_CS;
200129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
201129794Stackerman    return;
202129794Stackerman}
203129794Stackerman
204129794Stackerman/******************************************************************************
205129794Stackerman * Returns EEPROM to a "standby" state
206129794Stackerman *
207129794Stackerman * hw - Struct containing variables accessed by shared code
208129794Stackerman *****************************************************************************/
209129794Stackermanstatic void
210129794Stackermanixgb_standby_eeprom(struct ixgb_hw *hw)
211129794Stackerman{
212129794Stackerman    uint32_t eecd_reg;
213129794Stackerman
214129794Stackerman    eecd_reg = IXGB_READ_REG(hw, EECD);
215129794Stackerman
216129794Stackerman    /*  Deselct EEPROM  */
217129794Stackerman    eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);
218129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
219129794Stackerman    usec_delay(50);
220129794Stackerman
221129794Stackerman    /*  Clock high  */
222129794Stackerman    eecd_reg |= IXGB_EECD_SK;
223129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
224129794Stackerman    usec_delay(50);
225129794Stackerman
226129794Stackerman    /*  Select EEPROM  */
227129794Stackerman    eecd_reg |= IXGB_EECD_CS;
228129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
229129794Stackerman    usec_delay(50);
230129794Stackerman
231129794Stackerman    /*  Clock low  */
232129794Stackerman    eecd_reg &= ~IXGB_EECD_SK;
233129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
234129794Stackerman    usec_delay(50);
235129794Stackerman    return;
236129794Stackerman}
237129794Stackerman
238129794Stackerman/******************************************************************************
239129794Stackerman * Raises then lowers the EEPROM's clock pin
240129794Stackerman *
241129794Stackerman * hw - Struct containing variables accessed by shared code
242129794Stackerman *****************************************************************************/
243129794Stackermanstatic void
244129794Stackermanixgb_clock_eeprom(struct ixgb_hw *hw)
245129794Stackerman{
246129794Stackerman    uint32_t eecd_reg;
247129794Stackerman
248129794Stackerman    eecd_reg = IXGB_READ_REG(hw, EECD);
249129794Stackerman
250129794Stackerman    /*  Rising edge of clock  */
251129794Stackerman    eecd_reg |= IXGB_EECD_SK;
252129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
253129794Stackerman    usec_delay(50);
254129794Stackerman
255129794Stackerman    /*  Falling edge of clock  */
256129794Stackerman    eecd_reg &= ~IXGB_EECD_SK;
257129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
258129794Stackerman    usec_delay(50);
259129794Stackerman    return;
260129794Stackerman}
261129794Stackerman
262129794Stackerman/******************************************************************************
263129794Stackerman * Terminates a command by lowering the EEPROM's chip select pin
264129794Stackerman *
265129794Stackerman * hw - Struct containing variables accessed by shared code
266129794Stackerman *****************************************************************************/
267129794Stackermanstatic void
268129794Stackermanixgb_cleanup_eeprom(struct ixgb_hw *hw)
269129794Stackerman{
270129794Stackerman    uint32_t eecd_reg;
271129794Stackerman
272129794Stackerman    eecd_reg = IXGB_READ_REG(hw, EECD);
273129794Stackerman
274129794Stackerman    eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_DI);
275129794Stackerman
276129794Stackerman    IXGB_WRITE_REG(hw, EECD, eecd_reg);
277129794Stackerman
278129794Stackerman    ixgb_clock_eeprom(hw);
279129794Stackerman    return;
280129794Stackerman}
281129794Stackerman
282129794Stackerman/******************************************************************************
283129794Stackerman * Waits for the EEPROM to finish the current command.
284129794Stackerman *
285129794Stackerman * hw - Struct containing variables accessed by shared code
286129794Stackerman *
287129794Stackerman * The command is done when the EEPROM's data out pin goes high.
288129794Stackerman *
289129794Stackerman * Returns:
290129794Stackerman *      TRUE: EEPROM data pin is high before timeout.
291129794Stackerman *      FALSE:  Time expired.
292129794Stackerman *****************************************************************************/
293129794Stackermanstatic boolean_t
294129794Stackermanixgb_wait_eeprom_command(struct ixgb_hw *hw)
295129794Stackerman{
296129794Stackerman    uint32_t eecd_reg;
297129794Stackerman    uint32_t i;
298129794Stackerman
299129794Stackerman
300129794Stackerman    /* Toggle the CS line.  This in effect tells to EEPROM to actually execute
301129794Stackerman     * the command in question.
302129794Stackerman     */
303129794Stackerman    ixgb_standby_eeprom(hw);
304129794Stackerman
305129794Stackerman    /* Now read DO repeatedly until is high (equal to '1').  The EEEPROM will
306129794Stackerman     * signal that the command has been completed by raising the DO signal.
307129794Stackerman     * If DO does not go high in 10 milliseconds, then error out.
308129794Stackerman     */
309129794Stackerman    for(i = 0; i < 200; i++) {
310129794Stackerman        eecd_reg = IXGB_READ_REG(hw, EECD);
311129794Stackerman
312129794Stackerman        if(eecd_reg & IXGB_EECD_DO)
313129794Stackerman            return (TRUE);
314129794Stackerman
315129794Stackerman        usec_delay(50);
316129794Stackerman    }
317129794Stackerman    ASSERT(0);
318129794Stackerman    return (FALSE);
319129794Stackerman}
320129794Stackerman
321129794Stackerman
322129794Stackerman/******************************************************************************
323129794Stackerman * Verifies that the EEPROM has a valid checksum
324129794Stackerman *
325129794Stackerman * hw - Struct containing variables accessed by shared code
326129794Stackerman *
327129794Stackerman * Reads the first 64 16 bit words of the EEPROM and sums the values read.
328218909Sbrucec * If the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
329129794Stackerman * valid.
330129794Stackerman *
331129794Stackerman * Returns:
332129794Stackerman *  TRUE: Checksum is valid
333129794Stackerman *  FALSE: Checksum is not valid.
334129794Stackerman *****************************************************************************/
335129794Stackermanboolean_t
336129794Stackermanixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
337129794Stackerman{
338129794Stackerman    uint16_t checksum = 0;
339129794Stackerman    uint16_t i;
340129794Stackerman
341129794Stackerman    for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
342129794Stackerman        checksum += ixgb_read_eeprom(hw, i);
343129794Stackerman
344129794Stackerman    if(checksum == (uint16_t) EEPROM_SUM)
345129794Stackerman        return (TRUE);
346129794Stackerman    else
347129794Stackerman        return (FALSE);
348129794Stackerman}
349129794Stackerman
350129794Stackerman/******************************************************************************
351129794Stackerman * Calculates the EEPROM checksum and writes it to the EEPROM
352129794Stackerman *
353129794Stackerman * hw - Struct containing variables accessed by shared code
354129794Stackerman *
355129794Stackerman * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
356129794Stackerman * Writes the difference to word offset 63 of the EEPROM.
357129794Stackerman *****************************************************************************/
358129794Stackermanvoid
359129794Stackermanixgb_update_eeprom_checksum(struct ixgb_hw *hw)
360129794Stackerman{
361129794Stackerman    uint16_t checksum = 0;
362129794Stackerman    uint16_t i;
363129794Stackerman
364129794Stackerman    for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
365129794Stackerman        checksum += ixgb_read_eeprom(hw, i);
366129794Stackerman
367129794Stackerman    checksum = (uint16_t) EEPROM_SUM - checksum;
368129794Stackerman
369129794Stackerman    ixgb_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum);
370129794Stackerman    return;
371129794Stackerman}
372129794Stackerman
373129794Stackerman/******************************************************************************
374129794Stackerman * Writes a 16 bit word to a given offset in the EEPROM.
375129794Stackerman *
376129794Stackerman * hw - Struct containing variables accessed by shared code
377129794Stackerman * reg - offset within the EEPROM to be written to
378298955Spfg * data - 16 bit word to be written to the EEPROM
379129794Stackerman *
380129794Stackerman * If ixgb_update_eeprom_checksum is not called after this function, the
381129794Stackerman * EEPROM will most likely contain an invalid checksum.
382129794Stackerman *
383129794Stackerman *****************************************************************************/
384129794Stackermanvoid
385129794Stackermanixgb_write_eeprom(struct ixgb_hw *hw,
386129794Stackerman                   uint16_t offset,
387129794Stackerman                   uint16_t data)
388129794Stackerman{
389129794Stackerman    /*  Prepare the EEPROM for writing  */
390129794Stackerman    ixgb_setup_eeprom(hw);
391129794Stackerman
392129794Stackerman    /*  Send the 9-bit EWEN (write enable) command to the EEPROM (5-bit opcode
393129794Stackerman     *  plus 4-bit dummy).  This puts the EEPROM into write/erase mode.
394129794Stackerman     */
395129794Stackerman    ixgb_shift_out_bits(hw, EEPROM_EWEN_OPCODE, 5);
396129794Stackerman    ixgb_shift_out_bits(hw, 0, 4);
397129794Stackerman
398129794Stackerman    /*  Prepare the EEPROM  */
399129794Stackerman    ixgb_standby_eeprom(hw);
400129794Stackerman
401129794Stackerman    /*  Send the Write command (3-bit opcode + 6-bit addr)  */
402129794Stackerman    ixgb_shift_out_bits(hw, EEPROM_WRITE_OPCODE, 3);
403129794Stackerman    ixgb_shift_out_bits(hw, offset, 6);
404129794Stackerman
405129794Stackerman    /*  Send the data  */
406129794Stackerman    ixgb_shift_out_bits(hw, data, 16);
407129794Stackerman
408129794Stackerman    ixgb_wait_eeprom_command(hw);
409129794Stackerman
410129794Stackerman    /*  Recover from write  */
411129794Stackerman    ixgb_standby_eeprom(hw);
412129794Stackerman
413129794Stackerman    /* Send the 9-bit EWDS (write disable) command to the EEPROM (5-bit
414129794Stackerman     * opcode plus 4-bit dummy).  This takes the EEPROM out of write/erase
415129794Stackerman     * mode.
416129794Stackerman     */
417129794Stackerman    ixgb_shift_out_bits(hw, EEPROM_EWDS_OPCODE, 5);
418129794Stackerman    ixgb_shift_out_bits(hw, 0, 4);
419129794Stackerman
420129794Stackerman    /*  Done with writing  */
421129794Stackerman    ixgb_cleanup_eeprom(hw);
422129794Stackerman
423129794Stackerman    return;
424129794Stackerman}
425129794Stackerman
426129794Stackerman/******************************************************************************
427129794Stackerman * Reads a 16 bit word from the EEPROM.
428129794Stackerman *
429129794Stackerman * hw - Struct containing variables accessed by shared code
430129794Stackerman * offset - offset of 16 bit word in the EEPROM to read
431129794Stackerman *
432129794Stackerman * Returns:
433129794Stackerman *  The 16-bit value read from the eeprom
434129794Stackerman *****************************************************************************/
435129794Stackermanuint16_t
436129794Stackermanixgb_read_eeprom(struct ixgb_hw *hw,
437129794Stackerman                  uint16_t offset)
438129794Stackerman{
439129794Stackerman    uint16_t data;
440129794Stackerman
441129794Stackerman    /*  Prepare the EEPROM for reading  */
442129794Stackerman    ixgb_setup_eeprom(hw);
443129794Stackerman
444129794Stackerman    /*  Send the READ command (opcode + addr)  */
445129794Stackerman    ixgb_shift_out_bits(hw, EEPROM_READ_OPCODE, 3);
446129794Stackerman    /*
447129794Stackerman     * We have a 64 word EEPROM, there are 6 address bits
448129794Stackerman     */
449129794Stackerman    ixgb_shift_out_bits(hw, offset, 6);
450129794Stackerman
451129794Stackerman    /*  Read the data  */
452129794Stackerman    data = ixgb_shift_in_bits(hw);
453129794Stackerman
454129794Stackerman    /*  End this read operation  */
455129794Stackerman    ixgb_standby_eeprom(hw);
456129794Stackerman
457129794Stackerman    return (data);
458129794Stackerman}
459129794Stackerman
460129794Stackerman/******************************************************************************
461129794Stackerman * Reads eeprom and stores data in shared structure.
462129794Stackerman * Validates eeprom checksum and eeprom signature.
463129794Stackerman *
464129794Stackerman * hw - Struct containing variables accessed by shared code
465129794Stackerman *
466129794Stackerman * Returns:
467129794Stackerman *      TRUE: if eeprom read is successful
468129794Stackerman *      FALSE: otherwise.
469129794Stackerman *****************************************************************************/
470129794Stackermanboolean_t
471129794Stackermanixgb_get_eeprom_data(struct ixgb_hw *hw)
472129794Stackerman{
473129794Stackerman    uint16_t i;
474129794Stackerman    uint16_t checksum = 0;
475129794Stackerman    struct ixgb_ee_map_type *ee_map;
476129794Stackerman
477129794Stackerman    DEBUGFUNC("ixgb_get_eeprom_data");
478129794Stackerman
479129794Stackerman    ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
480129794Stackerman
481129794Stackerman    DEBUGOUT("ixgb_ee: Reading eeprom data\n");
482129794Stackerman    for (i=0; i < IXGB_EEPROM_SIZE ; i++) {
483129794Stackerman        uint16_t ee_data;
484129794Stackerman        ee_data = ixgb_read_eeprom(hw, i);
485129794Stackerman        checksum += ee_data;
486129794Stackerman        hw->eeprom[i] = le16_to_cpu (ee_data);
487129794Stackerman    }
488129794Stackerman
489129794Stackerman    if (checksum != (uint16_t) EEPROM_SUM) {
490129794Stackerman        DEBUGOUT("ixgb_ee: Checksum invalid.\n");
491129794Stackerman        return (FALSE);
492129794Stackerman    }
493129794Stackerman
494129794Stackerman    if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
495129794Stackerman         != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
496129794Stackerman        DEBUGOUT("ixgb_ee: Signature invalid.\n");
497129794Stackerman        return(FALSE);
498129794Stackerman    }
499129794Stackerman
500129794Stackerman    return(TRUE);
501129794Stackerman}
502129794Stackerman
503129794Stackerman
504129794Stackerman/******************************************************************************
505129794Stackerman * Local function to check if the eeprom signature is good
506129794Stackerman * If the eeprom signature is good, calls ixgb)get_eeprom_data.
507129794Stackerman *
508129794Stackerman * hw - Struct containing variables accessed by shared code
509129794Stackerman *
510129794Stackerman * Returns:
511129794Stackerman *      TRUE: eeprom signature was good and the eeprom read was successful
512129794Stackerman *      FALSE: otherwise.
513129794Stackerman ******************************************************************************/
514129794Stackermanstatic boolean_t
515129794Stackermanixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
516129794Stackerman{
517129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
518129794Stackerman
519129794Stackerman
520129794Stackerman    if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
521129794Stackerman                                == le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
522129794Stackerman        return (TRUE);
523129794Stackerman    } else {
524129794Stackerman        return ixgb_get_eeprom_data(hw);
525129794Stackerman    }
526129794Stackerman}
527129794Stackerman
528129794Stackerman/******************************************************************************
529129794Stackerman * return a word from the eeprom
530129794Stackerman *
531129794Stackerman * hw - Struct containing variables accessed by shared code
532129794Stackerman * index - Offset of eeprom word
533129794Stackerman *
534129794Stackerman * Returns:
535129794Stackerman *          Word at indexed offset in eeprom, if valid, 0 otherwise.
536129794Stackerman ******************************************************************************/
537129794Stackermanuint16_t
538129794Stackermanixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index)
539129794Stackerman{
540129794Stackerman
541129794Stackerman    if ((index < IXGB_EEPROM_SIZE) &&
542129794Stackerman        (ixgb_check_and_get_eeprom_data (hw) == TRUE)) {
543129794Stackerman       return(hw->eeprom[index]);
544129794Stackerman    }
545129794Stackerman
546129794Stackerman    return(0);
547129794Stackerman}
548129794Stackerman
549129794Stackerman
550129794Stackerman/******************************************************************************
551129794Stackerman * return the mac address from EEPROM
552129794Stackerman *
553129794Stackerman * hw       - Struct containing variables accessed by shared code
554129794Stackerman * mac_addr - Ethernet Address if EEPROM contents are valid, 0 otherwise
555129794Stackerman *
556129794Stackerman * Returns: None.
557129794Stackerman ******************************************************************************/
558129794Stackermanvoid
559129794Stackermanixgb_get_ee_mac_addr(struct ixgb_hw *hw,
560129794Stackerman                        uint8_t *mac_addr)
561129794Stackerman{
562129794Stackerman    int i;
563129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
564129794Stackerman
565129794Stackerman    DEBUGFUNC("ixgb_get_ee_mac_addr");
566129794Stackerman
567129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE) {
568129794Stackerman        for (i = 0; i < IXGB_ETH_LENGTH_OF_ADDRESS; i++) {
569129794Stackerman            mac_addr[i] = ee_map->mac_addr[i];
570129794Stackerman            DEBUGOUT2("mac(%d) = %.2X\n", i, mac_addr[i]);
571129794Stackerman        }
572129794Stackerman    }
573129794Stackerman}
574129794Stackerman
575129794Stackerman/******************************************************************************
576129794Stackerman * return the compatibility flags from EEPROM
577129794Stackerman *
578129794Stackerman * hw - Struct containing variables accessed by shared code
579129794Stackerman *
580129794Stackerman * Returns:
581129794Stackerman *          compatibility flags if EEPROM contents are valid, 0 otherwise
582129794Stackerman ******************************************************************************/
583129794Stackermanuint16_t
584129794Stackermanixgb_get_ee_compatibility(struct ixgb_hw *hw)
585129794Stackerman{
586129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
587129794Stackerman
588129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
589129794Stackerman       return(ee_map->compatibility);
590129794Stackerman
591129794Stackerman    return(0);
592129794Stackerman}
593129794Stackerman
594129794Stackerman/******************************************************************************
595129794Stackerman * return the Printed Board Assembly number from EEPROM
596129794Stackerman *
597129794Stackerman * hw - Struct containing variables accessed by shared code
598129794Stackerman *
599129794Stackerman * Returns:
600129794Stackerman *          PBA number if EEPROM contents are valid, 0 otherwise
601129794Stackerman ******************************************************************************/
602129794Stackermanuint32_t
603129794Stackermanixgb_get_ee_pba_number(struct ixgb_hw *hw)
604129794Stackerman{
605129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
606129794Stackerman       return (   le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
607129794Stackerman               | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16));
608129794Stackerman
609129794Stackerman    return(0);
610129794Stackerman}
611129794Stackerman
612129794Stackerman/******************************************************************************
613129794Stackerman * return the Initialization Control Word 1 from EEPROM
614129794Stackerman *
615129794Stackerman * hw - Struct containing variables accessed by shared code
616129794Stackerman *
617129794Stackerman * Returns:
618129794Stackerman *          Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise
619129794Stackerman ******************************************************************************/
620129794Stackermanuint16_t
621129794Stackermanixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw)
622129794Stackerman{
623129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
624129794Stackerman
625129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
626129794Stackerman       return(ee_map->init_ctrl_reg_1);
627129794Stackerman
628129794Stackerman    return(0);
629129794Stackerman}
630129794Stackerman
631129794Stackerman/******************************************************************************
632129794Stackerman * return the Initialization Control Word 2 from EEPROM
633129794Stackerman *
634129794Stackerman * hw - Struct containing variables accessed by shared code
635129794Stackerman *
636129794Stackerman * Returns:
637129794Stackerman *          Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise
638129794Stackerman ******************************************************************************/
639129794Stackermanuint16_t
640129794Stackermanixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw)
641129794Stackerman{
642129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
643129794Stackerman
644129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
645129794Stackerman       return(ee_map->init_ctrl_reg_2);
646129794Stackerman
647129794Stackerman    return(0);
648129794Stackerman}
649129794Stackerman
650129794Stackerman/******************************************************************************
651129794Stackerman * return the Subsystem Id from EEPROM
652129794Stackerman *
653129794Stackerman * hw - Struct containing variables accessed by shared code
654129794Stackerman *
655129794Stackerman * Returns:
656129794Stackerman *          Subsystem Id if EEPROM contents are valid, 0 otherwise
657129794Stackerman ******************************************************************************/
658129794Stackermanuint16_t
659129794Stackermanixgb_get_ee_subsystem_id(struct ixgb_hw *hw)
660129794Stackerman{
661129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
662129794Stackerman
663129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
664129794Stackerman       return(ee_map->subsystem_id);
665129794Stackerman
666129794Stackerman    return(0);
667129794Stackerman}
668129794Stackerman
669129794Stackerman/******************************************************************************
670129794Stackerman * return the Sub Vendor Id from EEPROM
671129794Stackerman *
672129794Stackerman * hw - Struct containing variables accessed by shared code
673129794Stackerman *
674129794Stackerman * Returns:
675129794Stackerman *          Sub Vendor Id if EEPROM contents are valid, 0 otherwise
676129794Stackerman ******************************************************************************/
677129794Stackermanuint16_t
678129794Stackermanixgb_get_ee_subvendor_id(struct ixgb_hw *hw)
679129794Stackerman{
680129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
681129794Stackerman
682129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
683129794Stackerman       return(ee_map->subvendor_id);
684129794Stackerman
685129794Stackerman    return(0);
686129794Stackerman}
687129794Stackerman
688129794Stackerman/******************************************************************************
689129794Stackerman * return the Device Id from EEPROM
690129794Stackerman *
691129794Stackerman * hw - Struct containing variables accessed by shared code
692129794Stackerman *
693129794Stackerman * Returns:
694129794Stackerman *          Device Id if EEPROM contents are valid, 0 otherwise
695129794Stackerman ******************************************************************************/
696129794Stackermanuint16_t
697129794Stackermanixgb_get_ee_device_id(struct ixgb_hw *hw)
698129794Stackerman{
699129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
700129794Stackerman
701129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
702129794Stackerman       return(ee_map->device_id);
703129794Stackerman
704129794Stackerman    return(0);
705129794Stackerman}
706129794Stackerman
707129794Stackerman/******************************************************************************
708129794Stackerman * return the Vendor Id from EEPROM
709129794Stackerman *
710129794Stackerman * hw - Struct containing variables accessed by shared code
711129794Stackerman *
712129794Stackerman * Returns:
713129794Stackerman *          Device Id if EEPROM contents are valid, 0 otherwise
714129794Stackerman ******************************************************************************/
715129794Stackermanuint16_t
716129794Stackermanixgb_get_ee_vendor_id(struct ixgb_hw *hw)
717129794Stackerman{
718129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
719129794Stackerman
720129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
721129794Stackerman       return(ee_map->vendor_id);
722129794Stackerman
723129794Stackerman    return(0);
724129794Stackerman}
725129794Stackerman
726129794Stackerman/******************************************************************************
727129794Stackerman * return the Software Defined Pins Register from EEPROM
728129794Stackerman *
729129794Stackerman * hw - Struct containing variables accessed by shared code
730129794Stackerman *
731129794Stackerman * Returns:
732129794Stackerman *          SDP Register if EEPROM contents are valid, 0 otherwise
733129794Stackerman ******************************************************************************/
734129794Stackermanuint16_t
735129794Stackermanixgb_get_ee_swdpins_reg(struct ixgb_hw *hw)
736129794Stackerman{
737129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
738129794Stackerman
739129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
740129794Stackerman       return(ee_map->swdpins_reg);
741129794Stackerman
742129794Stackerman    return(0);
743129794Stackerman}
744129794Stackerman
745129794Stackerman/******************************************************************************
746129794Stackerman * return the D3 Power Management Bits from EEPROM
747129794Stackerman *
748129794Stackerman * hw - Struct containing variables accessed by shared code
749129794Stackerman *
750129794Stackerman * Returns:
751129794Stackerman *          D3 Power Management Bits if EEPROM contents are valid, 0 otherwise
752129794Stackerman ******************************************************************************/
753129794Stackermanuint8_t
754129794Stackermanixgb_get_ee_d3_power(struct ixgb_hw *hw)
755129794Stackerman{
756129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
757129794Stackerman
758129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
759129794Stackerman       return(ee_map->d3_power);
760129794Stackerman
761129794Stackerman    return(0);
762129794Stackerman}
763129794Stackerman
764129794Stackerman/******************************************************************************
765129794Stackerman * return the D0 Power Management Bits from EEPROM
766129794Stackerman *
767129794Stackerman * hw - Struct containing variables accessed by shared code
768129794Stackerman *
769129794Stackerman * Returns:
770129794Stackerman *          D0 Power Management Bits if EEPROM contents are valid, 0 otherwise
771129794Stackerman ******************************************************************************/
772129794Stackermanuint8_t
773129794Stackermanixgb_get_ee_d0_power(struct ixgb_hw *hw)
774129794Stackerman{
775129794Stackerman    struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *) hw->eeprom;
776129794Stackerman
777129794Stackerman    if (ixgb_check_and_get_eeprom_data (hw) == TRUE)
778129794Stackerman       return(ee_map->d0_power);
779129794Stackerman
780129794Stackerman    return(0);
781129794Stackerman}
782