1 |
27 |
unneback |
//=============================================================================
|
2 |
|
|
//
|
3 |
|
|
// i82544.c.c - Diagnostic support for i82544 NIC
|
4 |
|
|
//
|
5 |
|
|
//=============================================================================
|
6 |
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
7 |
|
|
// -------------------------------------------
|
8 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
9 |
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
10 |
|
|
//
|
11 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
12 |
|
|
// the terms of the GNU General Public License as published by the Free
|
13 |
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
14 |
|
|
//
|
15 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
16 |
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
17 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
18 |
|
|
// for more details.
|
19 |
|
|
//
|
20 |
|
|
// You should have received a copy of the GNU General Public License along
|
21 |
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
22 |
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
23 |
|
|
//
|
24 |
|
|
// As a special exception, if other files instantiate templates or use macros
|
25 |
|
|
// or inline functions from this file, or you compile this file and link it
|
26 |
|
|
// with other works to produce a work based on this file, this file does not
|
27 |
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
28 |
|
|
// License. However the source code for this file must still be made available
|
29 |
|
|
// in accordance with section (3) of the GNU General Public License.
|
30 |
|
|
//
|
31 |
|
|
// This exception does not invalidate any other reasons why a work based on
|
32 |
|
|
// this file might be covered by the GNU General Public License.
|
33 |
|
|
//
|
34 |
|
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
35 |
|
|
// at http://sources.redhat.com/ecos/ecos-license/
|
36 |
|
|
// -------------------------------------------
|
37 |
|
|
//####ECOSGPLCOPYRIGHTEND####
|
38 |
|
|
//=============================================================================
|
39 |
|
|
//#####DESCRIPTIONBEGIN####
|
40 |
|
|
//
|
41 |
|
|
// Author(s): Mark Salter
|
42 |
|
|
// Contributors:
|
43 |
|
|
// Date: 2002-01-25
|
44 |
|
|
// Purpose:
|
45 |
|
|
// Description:
|
46 |
|
|
//
|
47 |
|
|
//####DESCRIPTIONEND####
|
48 |
|
|
//
|
49 |
|
|
//===========================================================================*/
|
50 |
|
|
|
51 |
|
|
#include <redboot.h>
|
52 |
|
|
#include <cyg/io/pci.h>
|
53 |
|
|
#include "test_menu.h"
|
54 |
|
|
|
55 |
|
|
extern int diag_ishex(char theChar);
|
56 |
|
|
extern int diag_hex2dec(char hex);
|
57 |
|
|
|
58 |
|
|
#define READMEM8( _reg_, _val_ ) ((CYG_BYTE)(_val_) = *((volatile CYG_BYTE *)(_reg_)))
|
59 |
|
|
#define WRITEMEM8( _reg_, _val_ ) (*((volatile CYG_BYTE *)(_reg_)) = (CYG_BYTE)(_val_))
|
60 |
|
|
#define READMEM16( _reg_, _val_ ) ((CYG_WORD16)(_val_) = *((volatile CYG_WORD16 *)(_reg_)))
|
61 |
|
|
#define WRITEMEM16( _reg_, _val_ ) (*((volatile CYG_WORD16 *)(_reg_)) = (CYG_WORD16)(_val_))
|
62 |
|
|
#define READMEM32( _reg_, _val_ ) ((CYG_WORD32)(_val_) = *((volatile CYG_WORD32 *)(_reg_)))
|
63 |
|
|
#define WRITEMEM32( _reg_, _val_ ) (*((volatile CYG_WORD32 *)(_reg_)) = (CYG_WORD32)(_val_))
|
64 |
|
|
#define READMEM64( _reg_, _val_ ) ((CYG_WORD64)(_val_) = *((volatile CYG_WORD64 *)(_reg_)))
|
65 |
|
|
#define WRITEMEM64( _reg_, _val_ ) (*((volatile CYG_WORD64 *)(_reg_)) = (CYG_WORD64)(_val_))
|
66 |
|
|
|
67 |
|
|
#define OUTL( _v_, _a_ ) WRITEMEM32( _a_, _v_ )
|
68 |
|
|
|
69 |
|
|
static inline cyg_uint32 INL(cyg_uint32 io_address)
|
70 |
|
|
{ cyg_uint32 _t_; READMEM32( io_address, _t_ ); return _t_; }
|
71 |
|
|
|
72 |
|
|
// ------------------------------------------------------------------------
|
73 |
|
|
//
|
74 |
|
|
// Serial EEPROM access - much like the other Intel ethernet
|
75 |
|
|
//
|
76 |
|
|
|
77 |
|
|
#define EE_SHIFT_CLK 0x01 // EEPROM shift clock.
|
78 |
|
|
#define EE_CS 0x02 // EEPROM chip select.
|
79 |
|
|
#define EE_DATA_WRITE 0x04 // EEPROM chip data in.
|
80 |
|
|
#define EE_DATA_READ 0x08 // EEPROM chip data out.
|
81 |
|
|
#define EE_ENB (0x10|EE_CS)
|
82 |
|
|
|
83 |
|
|
#define EE_DELAY() do { int z; for ( z = 0; z < 10000; z++ ) ; } while (0)
|
84 |
|
|
|
85 |
|
|
#if 0
|
86 |
|
|
# define EE_PRINTF diag_printf
|
87 |
|
|
# define EE_STUFF "%4s | %4s | %4s | %4s [%08x]\n", \
|
88 |
|
|
(l & EE_SHIFT_CLK) ? "CLK" : "clk", \
|
89 |
|
|
(l & EE_CS) ? "eeCS" : "--", \
|
90 |
|
|
(l & EE_DATA_WRITE) ? "eeDW" : "---", \
|
91 |
|
|
(l & EE_DATA_READ) ? "eeDR" : "---", \
|
92 |
|
|
l & 0xfffff
|
93 |
|
|
#else
|
94 |
|
|
# define EE_PRINTF( foo )
|
95 |
|
|
# define EE_STUFF
|
96 |
|
|
#endif
|
97 |
|
|
|
98 |
|
|
#define I82544_EECD 0x00010
|
99 |
|
|
|
100 |
|
|
static inline void
|
101 |
|
|
ee_select( int ioaddr )
|
102 |
|
|
{
|
103 |
|
|
cyg_uint32 l;
|
104 |
|
|
l = EE_ENB;
|
105 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
106 |
|
|
EE_DELAY();
|
107 |
|
|
l |= EE_CS;
|
108 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
109 |
|
|
l = INL( ioaddr + I82544_EECD );
|
110 |
|
|
EE_PRINTF( "ee_select : " EE_STUFF );
|
111 |
|
|
EE_DELAY();
|
112 |
|
|
}
|
113 |
|
|
|
114 |
|
|
static inline void
|
115 |
|
|
ee_deselect( int ioaddr )
|
116 |
|
|
{
|
117 |
|
|
cyg_uint32 l;
|
118 |
|
|
l = EE_ENB;
|
119 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
120 |
|
|
EE_PRINTF( "ee_deselect 1 : " EE_STUFF );
|
121 |
|
|
EE_DELAY();
|
122 |
|
|
EE_DELAY();
|
123 |
|
|
EE_DELAY();
|
124 |
|
|
l = EE_ENB & ~EE_CS;
|
125 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
126 |
|
|
l = INL( ioaddr + I82544_EECD );
|
127 |
|
|
EE_PRINTF( "ee_deselect 2 : " EE_STUFF );
|
128 |
|
|
EE_DELAY();
|
129 |
|
|
EE_DELAY();
|
130 |
|
|
EE_DELAY();
|
131 |
|
|
}
|
132 |
|
|
|
133 |
|
|
static inline void
|
134 |
|
|
ee_clock_up( int ioaddr )
|
135 |
|
|
{
|
136 |
|
|
cyg_uint32 l;
|
137 |
|
|
l = INL( ioaddr + I82544_EECD );
|
138 |
|
|
l |= EE_SHIFT_CLK;
|
139 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
140 |
|
|
EE_DELAY();
|
141 |
|
|
l = INL( ioaddr + I82544_EECD );
|
142 |
|
|
EE_PRINTF( "ee_clock_up : " EE_STUFF );
|
143 |
|
|
EE_DELAY();
|
144 |
|
|
}
|
145 |
|
|
|
146 |
|
|
static inline void
|
147 |
|
|
ee_clock_down( int ioaddr )
|
148 |
|
|
{
|
149 |
|
|
cyg_uint32 l;
|
150 |
|
|
l = INL( ioaddr + I82544_EECD );
|
151 |
|
|
l &=~ EE_SHIFT_CLK;
|
152 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
153 |
|
|
EE_DELAY();
|
154 |
|
|
l = INL( ioaddr + I82544_EECD );
|
155 |
|
|
EE_PRINTF( "ee_clock_down : " EE_STUFF );
|
156 |
|
|
EE_DELAY();
|
157 |
|
|
}
|
158 |
|
|
|
159 |
|
|
static inline int
|
160 |
|
|
ee_read_data_bit( int ioaddr )
|
161 |
|
|
{
|
162 |
|
|
cyg_uint32 l;
|
163 |
|
|
l = INL( ioaddr + I82544_EECD );
|
164 |
|
|
EE_PRINTF( "ee_read_data : " EE_STUFF );
|
165 |
|
|
return EE_DATA_READ == (EE_DATA_READ & l);
|
166 |
|
|
}
|
167 |
|
|
|
168 |
|
|
static inline void
|
169 |
|
|
ee_write_data_bit( int ioaddr, int databit )
|
170 |
|
|
{
|
171 |
|
|
cyg_uint32 l;
|
172 |
|
|
l = INL( ioaddr + I82544_EECD );
|
173 |
|
|
if ( databit )
|
174 |
|
|
l |= EE_DATA_WRITE;
|
175 |
|
|
else
|
176 |
|
|
l &= ~EE_DATA_WRITE;
|
177 |
|
|
OUTL( l, ioaddr + I82544_EECD );
|
178 |
|
|
l = INL( ioaddr + I82544_EECD );
|
179 |
|
|
EE_PRINTF( "ee_write_data : " EE_STUFF );
|
180 |
|
|
EE_DELAY();
|
181 |
|
|
}
|
182 |
|
|
|
183 |
|
|
// Pass ioaddr around "invisibly"
|
184 |
|
|
#define EE_SELECT() ee_select(ioaddr)
|
185 |
|
|
#define EE_DESELECT() ee_deselect(ioaddr)
|
186 |
|
|
#define EE_CLOCK_UP() ee_clock_up(ioaddr)
|
187 |
|
|
#define EE_CLOCK_DOWN() ee_clock_down(ioaddr)
|
188 |
|
|
#define EE_READ_DATA_BIT() ee_read_data_bit(ioaddr)
|
189 |
|
|
#define EE_WRITE_DATA_BIT( _d_ ) ee_write_data_bit(ioaddr,(_d_))
|
190 |
|
|
|
191 |
|
|
// ------------------------------------------------------------------------
|
192 |
|
|
|
193 |
|
|
static int
|
194 |
|
|
read_eeprom_word( cyg_uint32 ioaddr, int addrbits, int address )
|
195 |
|
|
{
|
196 |
|
|
int i, tmp;
|
197 |
|
|
|
198 |
|
|
// Should already be not-selected, but anyway:
|
199 |
|
|
EE_SELECT();
|
200 |
|
|
|
201 |
|
|
// Shift the read command bits out.
|
202 |
|
|
for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
|
203 |
|
|
tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
|
204 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
205 |
|
|
EE_CLOCK_UP();
|
206 |
|
|
EE_CLOCK_DOWN();
|
207 |
|
|
}
|
208 |
|
|
|
209 |
|
|
// Now clock out address
|
210 |
|
|
for ( i = addrbits - 1; i >= 0 ; i-- ) {
|
211 |
|
|
tmp = (address & (1<<i)) ? 1 : 0;
|
212 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
213 |
|
|
EE_CLOCK_UP();
|
214 |
|
|
tmp = EE_READ_DATA_BIT();
|
215 |
|
|
EE_CLOCK_DOWN();
|
216 |
|
|
|
217 |
|
|
// CYG_ASSERT( (0 == tmp) == (0 == i), "Looking for zero handshake bit" );
|
218 |
|
|
}
|
219 |
|
|
|
220 |
|
|
// read in the data
|
221 |
|
|
tmp = 0;
|
222 |
|
|
for (i = 15; i >= 0; i--) {
|
223 |
|
|
EE_CLOCK_UP();
|
224 |
|
|
if ( EE_READ_DATA_BIT() )
|
225 |
|
|
tmp |= (1<<i);
|
226 |
|
|
EE_CLOCK_DOWN();
|
227 |
|
|
}
|
228 |
|
|
|
229 |
|
|
// Terminate the EEPROM access.
|
230 |
|
|
EE_DESELECT();
|
231 |
|
|
|
232 |
|
|
#ifdef DEBUG_EE
|
233 |
|
|
// diag_printf( "eeprom address %4x: data %4x\n", address, tmp );
|
234 |
|
|
#endif
|
235 |
|
|
|
236 |
|
|
return tmp;
|
237 |
|
|
}
|
238 |
|
|
|
239 |
|
|
// ------------------------------------------------------------------------
|
240 |
|
|
static void
|
241 |
|
|
write_eeprom_word( cyg_uint32 ioaddr, int addrbits, int address, cyg_uint16 value)
|
242 |
|
|
{
|
243 |
|
|
int i, tmp;
|
244 |
|
|
|
245 |
|
|
// Should already be not-selected, but anyway:
|
246 |
|
|
EE_SELECT();
|
247 |
|
|
|
248 |
|
|
// Shift the write command bits out.
|
249 |
|
|
for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
|
250 |
|
|
tmp = (5 & (1 << i)) ? 1 : 0; // "5" is the "write" command.
|
251 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
252 |
|
|
EE_CLOCK_UP();
|
253 |
|
|
EE_CLOCK_DOWN();
|
254 |
|
|
}
|
255 |
|
|
|
256 |
|
|
// Now clock out address
|
257 |
|
|
for ( i = addrbits - 1; i >= 0 ; i-- ) {
|
258 |
|
|
tmp = (address & (1<<i)) ? 1 : 0;
|
259 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
260 |
|
|
EE_CLOCK_UP();
|
261 |
|
|
tmp = EE_READ_DATA_BIT();
|
262 |
|
|
EE_CLOCK_DOWN();
|
263 |
|
|
}
|
264 |
|
|
|
265 |
|
|
|
266 |
|
|
// write the data
|
267 |
|
|
for (i = 15; i >= 0; i--) {
|
268 |
|
|
tmp = (value & (1 << i)) ? 1 : 0;
|
269 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
270 |
|
|
EE_CLOCK_UP();
|
271 |
|
|
EE_CLOCK_DOWN();
|
272 |
|
|
}
|
273 |
|
|
|
274 |
|
|
// Terminate the EEPROM access.
|
275 |
|
|
EE_DESELECT();
|
276 |
|
|
|
277 |
|
|
CYGACC_CALL_IF_DELAY_US((cyg_int32)15*1000);
|
278 |
|
|
}
|
279 |
|
|
|
280 |
|
|
// ------------------------------------------------------------------------
|
281 |
|
|
static int
|
282 |
|
|
write_enable_eeprom(cyg_uint32 ioaddr, int addrbits)
|
283 |
|
|
{
|
284 |
|
|
int i, tmp;
|
285 |
|
|
|
286 |
|
|
// Should already be not-selected, but anyway:
|
287 |
|
|
EE_SELECT();
|
288 |
|
|
|
289 |
|
|
// Shift the EWEN command bits out.
|
290 |
|
|
for (i = 5; i >= 0; i--) { // Doc says to shift out a zero then:
|
291 |
|
|
tmp = (0x13 & (1 << i)) ? 1 : 0; // "0x13" is the "EWEN" command.
|
292 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
293 |
|
|
EE_CLOCK_UP();
|
294 |
|
|
EE_CLOCK_DOWN();
|
295 |
|
|
}
|
296 |
|
|
|
297 |
|
|
// Shift the rest of the address bits out. (ignored)
|
298 |
|
|
// Two bits were used for the EWEN command above.
|
299 |
|
|
tmp = 0;
|
300 |
|
|
for (i = (addrbits-3); i >= 0; i--) {
|
301 |
|
|
EE_WRITE_DATA_BIT(tmp);
|
302 |
|
|
EE_CLOCK_UP();
|
303 |
|
|
EE_CLOCK_DOWN();
|
304 |
|
|
}
|
305 |
|
|
|
306 |
|
|
// Terminate the EEPROM access.
|
307 |
|
|
EE_DESELECT();
|
308 |
|
|
}
|
309 |
|
|
|
310 |
|
|
|
311 |
|
|
// ------------------------------------------------------------------------
|
312 |
|
|
static void
|
313 |
|
|
program_eeprom(cyg_uint32 ioaddr, int addrbits, cyg_uint16 *data)
|
314 |
|
|
{
|
315 |
|
|
cyg_uint32 i;
|
316 |
|
|
cyg_uint16 checksum = 0;
|
317 |
|
|
|
318 |
|
|
// First enable erase/write operations on the eeprom.
|
319 |
|
|
// This is done through the EWEN instruction.
|
320 |
|
|
write_enable_eeprom(ioaddr, addrbits);
|
321 |
|
|
|
322 |
|
|
for (i = 0; i < 63; i++, data++) {
|
323 |
|
|
checksum += *data;
|
324 |
|
|
write_eeprom_word(ioaddr, addrbits, i, *data);
|
325 |
|
|
}
|
326 |
|
|
checksum = 0xBABA - checksum;
|
327 |
|
|
write_eeprom_word(ioaddr, addrbits, i, checksum);
|
328 |
|
|
}
|
329 |
|
|
|
330 |
|
|
// Get MAC address from user.
|
331 |
|
|
// Acceptable formats are:
|
332 |
|
|
// nn.nn.nn.nn.nn.nn
|
333 |
|
|
// nn:nn:nn:nn:nn:nn
|
334 |
|
|
// nn-nn-nn-nn-nn-nn
|
335 |
|
|
// nn nn nn nn nn nn
|
336 |
|
|
// nnnnnnnnnnnn
|
337 |
|
|
static void
|
338 |
|
|
get_mac_address(char *addr_buf)
|
339 |
|
|
{
|
340 |
|
|
char input[40], mac[6], *p;
|
341 |
|
|
int got, i;
|
342 |
|
|
|
343 |
|
|
do {
|
344 |
|
|
got = 0;
|
345 |
|
|
diag_printf ("\nCurrent MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
|
346 |
|
|
addr_buf[0], addr_buf[1], addr_buf[2],
|
347 |
|
|
addr_buf[3], addr_buf[4], addr_buf[5]);
|
348 |
|
|
diag_printf ("Enter desired MAC address: ");
|
349 |
|
|
while (_rb_gets(input, sizeof(input), 0) != _GETS_OK)
|
350 |
|
|
;
|
351 |
|
|
|
352 |
|
|
p = input;
|
353 |
|
|
while (*p && *p == ' ');
|
354 |
|
|
|
355 |
|
|
if (p[0] == '\0' || p[1] == '\0')
|
356 |
|
|
continue;
|
357 |
|
|
|
358 |
|
|
for (; got < 6; got++) {
|
359 |
|
|
if (!diag_ishex(p[0]) || !diag_ishex(p[1]))
|
360 |
|
|
break;
|
361 |
|
|
mac[got] = (diag_hex2dec(p[0]) * 16) + diag_hex2dec(p[1]);
|
362 |
|
|
p += 2;
|
363 |
|
|
if (*p == '.' || *p == ':' || *p == ' ' || *p == '-')
|
364 |
|
|
p++;
|
365 |
|
|
}
|
366 |
|
|
} while (got != 6);
|
367 |
|
|
|
368 |
|
|
for (i = 0; i < 6; i++)
|
369 |
|
|
*addr_buf++ = mac[i];
|
370 |
|
|
}
|
371 |
|
|
|
372 |
|
|
|
373 |
|
|
static cyg_uint16 eeprom_defaults[] = {
|
374 |
|
|
/* halfword addresses! */
|
375 |
|
|
/* 0: */ 0x0000, 0x0000, 0x0000, 0x0000,
|
376 |
|
|
/* 4: */ 0x0000, 0x0000, 0x0000, 0x0000,
|
377 |
|
|
/* 8: */ 0x0000, 0x0000, 0x4e0b, 0x1008,
|
378 |
|
|
/* C: */ 0x8086, 0x1008, 0x8086, 0xf02c,
|
379 |
|
|
/* 10: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
380 |
|
|
/* 14: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
381 |
|
|
/* 18: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
382 |
|
|
/* 1C: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
383 |
|
|
/* 20: */ 0xdfde, 0x0002, 0x1414, 0xffff,
|
384 |
|
|
/* 24: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
385 |
|
|
/* 28: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
386 |
|
|
/* 2C: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
387 |
|
|
/* 30: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
388 |
|
|
/* 34: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
389 |
|
|
/* 38: */ 0xffff, 0xffff, 0xffff, 0xffff,
|
390 |
|
|
/* 3C: */ 0xffff, 0xffff, 0xffff, 0x0000,
|
391 |
|
|
};
|
392 |
|
|
|
393 |
|
|
/* Setup Serial EEPROM for Ethernet Configuration */
|
394 |
|
|
void
|
395 |
|
|
enet_setup (MENU_ARG arg)
|
396 |
|
|
{
|
397 |
|
|
cyg_pci_device dev_info;
|
398 |
|
|
cyg_pci_device_id devid;
|
399 |
|
|
cyg_uint16 cksum;
|
400 |
|
|
cyg_uint16 eeprom_data[64];
|
401 |
|
|
cyg_uint32 nic_addr;
|
402 |
|
|
int i, bus;
|
403 |
|
|
|
404 |
|
|
// First, look for NIC at private and public addresses
|
405 |
|
|
|
406 |
|
|
bus = (*ATU_PCIXSR >> 8) & 0xff;
|
407 |
|
|
if (bus == 0xff)
|
408 |
|
|
bus = 0;
|
409 |
|
|
|
410 |
|
|
devid = CYG_PCI_DEV_MAKE_ID(bus, CYG_PCI_DEV_MAKE_DEVFN(__NIC_PUB, 0));
|
411 |
|
|
cyg_pci_get_device_info(devid, &dev_info);
|
412 |
|
|
|
413 |
|
|
if (dev_info.vendor != 0x8086) {
|
414 |
|
|
devid = CYG_PCI_DEV_MAKE_ID(bus, CYG_PCI_DEV_MAKE_DEVFN(__NIC_PRIV, 0));
|
415 |
|
|
cyg_pci_get_device_info(devid, &dev_info);
|
416 |
|
|
if (dev_info.vendor != 0x8086) {
|
417 |
|
|
diag_printf("No i82544 device found\n");
|
418 |
|
|
return;
|
419 |
|
|
}
|
420 |
|
|
}
|
421 |
|
|
|
422 |
|
|
nic_addr = dev_info.base_map[0];
|
423 |
|
|
|
424 |
|
|
// Now read complete EEPROM contents
|
425 |
|
|
for (i = cksum = 0; i < 64; i++) {
|
426 |
|
|
eeprom_data[i] = read_eeprom_word(nic_addr, 6, i);
|
427 |
|
|
cksum += eeprom_data[i];
|
428 |
|
|
}
|
429 |
|
|
|
430 |
|
|
// If not valid, initialize to defaults
|
431 |
|
|
if (cksum != 0xBABA || (eeprom_data[0x0a] & 0xC000) != 0x4000) {
|
432 |
|
|
diag_printf ("Current EEPROM contents invalid. Restoring defaults.\n");
|
433 |
|
|
for (i = 0; i < 63; i++)
|
434 |
|
|
eeprom_data[i] = eeprom_defaults[i];
|
435 |
|
|
}
|
436 |
|
|
|
437 |
|
|
get_mac_address((char *)eeprom_data);
|
438 |
|
|
|
439 |
|
|
// Now compute checksum on complete EEPROM contents
|
440 |
|
|
for (i = cksum = 0; i < 63; i++)
|
441 |
|
|
cksum += eeprom_data[i];
|
442 |
|
|
|
443 |
|
|
eeprom_data[63] = 0xBABA - cksum;
|
444 |
|
|
|
445 |
|
|
diag_printf ("Writing to the Serial EEPROM... ");
|
446 |
|
|
program_eeprom(nic_addr, 6, eeprom_data);
|
447 |
|
|
diag_printf ("Done\n");
|
448 |
|
|
|
449 |
|
|
/* now that we have finished writing the configuration data, we must ask the
|
450 |
|
|
operator to reset the board to have the configuration changes take effect.
|
451 |
|
|
After the reset, the standard Enet. port diagnostics can be run on the
|
452 |
|
|
board under test */
|
453 |
|
|
|
454 |
|
|
diag_printf ("\n******** Reset The Board To Have Changes Take Effect ********\n");
|
455 |
|
|
}
|
456 |
|
|
|
457 |
|
|
|