board/csky: fixup gdb instructions in readme.txt
[buildroot-gz.git] / boot / grub / grub.400-nic_update2.patch
blob5e3c16d46c7b95651267b4f9f051a0fc1dc5da34
1 Submitted By: Jim Gifford (patches at jg555 dot com)
2 Date: 2005-08-31
3 Initial Package Version: 0.97
4 Origin: OpenSolaris, Joe Ciccone, Jim Gifford
5 Upstream Status: N/A
6 Description: Adds support for Forcedeth and other NIC's
7 Fixes for GCC 4.x
8 Removal of bad network drivers
10 Index: b/configure
11 ===================================================================
12 --- a/configure
13 +++ b/configure
14 @@ -872,47 +872,32 @@
15 --disable-packet-retransmission
16 turn off packet retransmission
17 --enable-pci-direct access PCI directly instead of using BIOS
18 - --enable-3c509 enable 3Com509 driver
19 - --enable-3c529 enable 3Com529 driver
20 --enable-3c595 enable 3Com595 driver
21 --enable-3c90x enable 3Com90x driver
22 - --enable-cs89x0 enable CS89x0 driver
23 --enable-davicom enable Davicom driver
24 - --enable-depca enable DEPCA and EtherWORKS driver
25 - --enable-eepro enable Etherexpress Pro/10 driver
26 + --enable-e1000 enable Etherexpress Pro/1000 driver
27 --enable-eepro100 enable Etherexpress Pro/100 driver
28 --enable-epic100 enable SMC 83c170 EPIC/100 driver
29 - --enable-3c507 enable 3Com507 driver
30 - --enable-exos205 enable EXOS205 driver
31 - --enable-ni5210 enable Racal-Interlan NI5210 driver
32 - --enable-lance enable Lance PCI PCNet/32 driver
33 - --enable-ne2100 enable Novell NE2100 driver
34 - --enable-ni6510 enable Racal-Interlan NI6510 driver
35 + --enable-forcedeth enable Nvidia Geforce driver
36 --enable-natsemi enable NatSemi DP8381x driver
37 - --enable-ni5010 enable Racal-Interlan NI5010 driver
38 - --enable-3c503 enable 3Com503 driver
39 - --enable-ne enable NE1000/2000 ISA driver
40 + --enable-ns83820 enable NS83820 driver
41 --enable-ns8390 enable NE2000 PCI driver
42 - --enable-wd enable WD8003/8013, SMC8216/8416 driver
43 - --enable-otulip enable old Tulip driver
44 + --enable-pcnet32 enable AMD Lance/PCI PCNet/32 driver
45 + --enable-pnic enable Bochs Pseudo Nic driver
46 --enable-rtl8139 enable Realtek 8139 driver
47 + --enable-r8169 enable Realtek 8169 driver
48 --enable-sis900 enable SIS 900 and SIS 7016 driver
49 - --enable-sk-g16 enable Schneider and Koch G16 driver
50 - --enable-smc9000 enable SMC9000 driver
51 - --enable-tiara enable Tiara driver
52 + --enable-tg3 enable Broadcom Tigon3 driver
53 --enable-tulip enable Tulip driver
54 + --enable-tlan enable TI ThunderLAN driver
55 + --enable-undi enable PXE UNDI driver
56 --enable-via-rhine enable Rhine-I/II driver
57 - --enable-w89c840 enable Winbond W89c840, Compex RL100-ATX driver
58 - --enable-3c503-shmem use 3c503 shared memory mode
59 - --enable-3c503-aui use AUI by default on 3c503 cards
60 + --enable-w89c840 enable Winbond W89c840 driver
61 --enable-compex-rl2000-fix
62 specify this if you have a Compex RL2000 PCI
63 - --enable-smc9000-scan=LIST
64 - probe for SMC9000 I/O addresses using LIST
65 --enable-ne-scan=LIST probe for NE base address using LIST
66 --enable-wd-default-mem=MEM
67 set the default memory location for WD/SMC
68 - --enable-cs-scan=LIST probe for CS89x0 base address using LIST
69 --enable-diskless enable diskless support
70 --disable-graphics disable graphics terminal support
71 --disable-hercules disable hercules terminal support
72 @@ -5537,7 +5522,7 @@
74 fi;
75 if test "x$enable_packet_retransmission" != xno; then
76 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1"
77 + NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1 -DCONFIG_PCI"
80 # Check whether --enable-pci-direct or --disable-pci-direct was given.
81 @@ -5549,26 +5534,6 @@
82 NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONFIG_PCI_DIRECT=1"
85 -# Check whether --enable-3c509 or --disable-3c509 was given.
86 -if test "${enable_3c509+set}" = set; then
87 - enableval="$enable_3c509"
89 -fi;
90 -if test "x$enable_3c509" = xyes; then
91 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C509"
92 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c509.o"
93 -fi
95 -# Check whether --enable-3c529 or --disable-3c529 was given.
96 -if test "${enable_3c529+set}" = set; then
97 - enableval="$enable_3c529"
99 -fi;
100 -if test "x$enable_3c529" = xyes; then
101 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C529=1"
102 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
105 # Check whether --enable-3c595 or --disable-3c595 was given.
106 if test "${enable_3c595+set}" = set; then
107 enableval="$enable_3c595"
108 @@ -5589,16 +5554,6 @@
109 NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c90x.o"
112 -# Check whether --enable-cs89x0 or --disable-cs89x0 was given.
113 -if test "${enable_cs89x0+set}" = set; then
114 - enableval="$enable_cs89x0"
116 -fi;
117 -if test "x$enable_cs89x0" = xyes; then
118 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS89X0=1"
119 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
122 # Check whether --enable-davicom or --disable-davicom was given.
123 if test "${enable_davicom+set}" = set; then
124 enableval="$enable_davicom"
125 @@ -5609,24 +5564,14 @@
126 NETBOOT_DRIVERS="$NETBOOT_DRIVERS davicom.o"
129 -# Check whether --enable-depca or --disable-depca was given.
130 -if test "${enable_depca+set}" = set; then
131 - enableval="$enable_depca"
132 +# Check whether --enable-e1000 or --disable-e1000 was given.
133 +if test "${enable_e1000+set}" = set; then
134 + enableval="$enable_e1000"
137 -if test "x$enable_depca" = xyes; then
138 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DEPCA=1"
139 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS depca.o"
142 -# Check whether --enable-eepro or --disable-eepro was given.
143 -if test "${enable_eepro+set}" = set; then
144 - enableval="$enable_eepro"
146 -fi;
147 -if test "x$enable_eepro" = xyes; then
148 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO=1"
149 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro.o"
150 +if test "x$enable_e1000" = xyes; then
151 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_E1000=1"
152 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS e1000.o"
155 # Check whether --enable-eepro100 or --disable-eepro100 was given.
156 @@ -5649,64 +5594,14 @@
157 NETBOOT_DRIVERS="$NETBOOT_DRIVERS epic100.o"
160 -# Check whether --enable-3c507 or --disable-3c507 was given.
161 -if test "${enable_3c507+set}" = set; then
162 - enableval="$enable_3c507"
164 -fi;
165 -if test "x$enable_3c507" = xyes; then
166 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C507=1"
167 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c507.o"
170 -# Check whether --enable-exos205 or --disable-exos205 was given.
171 -if test "${enable_exos205+set}" = set; then
172 - enableval="$enable_exos205"
174 -fi;
175 -if test "x$enable_exos205" = xyes; then
176 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EXOS205=1"
177 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS exos205.o"
180 -# Check whether --enable-ni5210 or --disable-ni5210 was given.
181 -if test "${enable_ni5210+set}" = set; then
182 - enableval="$enable_ni5210"
184 -fi;
185 -if test "x$enable_ni5210" = xyes; then
186 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5210=1"
187 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
190 -# Check whether --enable-lance or --disable-lance was given.
191 -if test "${enable_lance+set}" = set; then
192 - enableval="$enable_lance"
194 -fi;
195 -if test "x$enable_lance" = xyes; then
196 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
197 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS lance.o"
200 -# Check whether --enable-ne2100 or --disable-ne2100 was given.
201 -if test "${enable_ne2100+set}" = set; then
202 - enableval="$enable_ne2100"
204 -fi;
205 -if test "x$enable_ne2100" = xyes; then
206 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE2100=1"
207 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne2100.o"
210 -# Check whether --enable-ni6510 or --disable-ni6510 was given.
211 -if test "${enable_ni6510+set}" = set; then
212 - enableval="$enable_ni6510"
213 +# Check whether --enable-forcedeth or --disable-forcedeth was given.
214 +if test "${enable_forcedeth+set}" = set; then
215 + enableval="$enable_forcedeth"
218 -if test "x$enable_ni6510" = xyes; then
219 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI6510=1"
220 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni6510.o"
221 +if test "x$enable_forcedeth" = xyes; then
222 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_FORCEDETH=1"
223 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS forcedeth.o"
226 # Check whether --enable-natsemi or --disable-natsemi was given.
227 @@ -5719,34 +5614,14 @@
228 NETBOOT_DRIVERS="$NETBOOT_DRIVERS natsemi.o"
231 -# Check whether --enable-ni5010 or --disable-ni5010 was given.
232 -if test "${enable_ni5010+set}" = set; then
233 - enableval="$enable_ni5010"
234 +# Check whether --enable-ns83820 or --disable-ns83820 was given.
235 +if test "${enable_ns83820+set}" = set; then
236 + enableval="$enable_ns83820"
239 -if test "x$enable_ni5010" = xyes; then
240 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5010=1"
241 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5010.o"
244 -# Check whether --enable-3c503 or --disable-3c503 was given.
245 -if test "${enable_3c503+set}" = set; then
246 - enableval="$enable_3c503"
248 -fi;
249 -if test "x$enable_3c503" = xyes; then
250 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C503=1"
251 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c503.o"
254 -# Check whether --enable-ne or --disable-ne was given.
255 -if test "${enable_ne+set}" = set; then
256 - enableval="$enable_ne"
258 -fi;
259 -if test "x$enable_ne" = xyes; then
260 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
261 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
262 +if test "x$enable_ns83820" = xyes; then
263 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NS83820=1"
264 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns83820.o"
267 # Check whether --enable-ns8390 or --disable-ns8390 was given.
268 @@ -5759,24 +5634,24 @@
269 NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns8390.o"
272 -# Check whether --enable-wd or --disable-wd was given.
273 -if test "${enable_wd+set}" = set; then
274 - enableval="$enable_wd"
275 +# Check whether --enable-pcnet32 or --disable-pcnet32 was given.
276 +if test "${enable_pcnet32+set}" = set; then
277 + enableval="$enable_pcnet32"
280 -if test "x$enable_wd" = xyes; then
281 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
282 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
283 +if test "x$enable_pcnet32" = xyes; then
284 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_PCNET32=1"
285 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS pcnet32.o"
288 -# Check whether --enable-otulip or --disable-otulip was given.
289 -if test "${enable_otulip+set}" = set; then
290 - enableval="$enable_otulip"
291 +# Check whether --enable-pnic or --disable-pnic was given.
292 +if test "${enable_pnic+set}" = set; then
293 + enableval="$enable_pnic"
296 -if test "x$enable_otulip" = xyes; then
297 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_OTULIP=1"
298 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS otulip.o"
299 +if test "x$enable_pnic" = xyes; then
300 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_PNIC=1"
301 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS pnic.o"
304 # Check whether --enable-rtl8139 or --disable-rtl8139 was given.
305 @@ -5789,6 +5664,16 @@
306 NETBOOT_DRIVERS="$NETBOOT_DRIVERS rtl8139.o"
309 +# Check whether --enable-r8169 or --disable-r8169 was given.
310 +if test "${enable_r8169+set}" = set; then
311 + enableval="$enable_r8169"
313 +fi;
314 +if test "x$enable_r8169" = xyes; then
315 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_R8169=1"
316 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS r8169.o"
319 # Check whether --enable-sis900 or --disable-sis900 was given.
320 if test "${enable_sis900+set}" = set; then
321 enableval="$enable_sis900"
322 @@ -5799,34 +5684,14 @@
323 NETBOOT_DRIVERS="$NETBOOT_DRIVERS sis900.o"
326 -# Check whether --enable-sk-g16 or --disable-sk-g16 was given.
327 -if test "${enable_sk_g16+set}" = set; then
328 - enableval="$enable_sk_g16"
330 -fi;
331 -if test "x$enable_sk_g16" = xyes; then
332 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SK_G16=1"
333 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS sk_g16.o"
336 -# Check whether --enable-smc9000 or --disable-smc9000 was given.
337 -if test "${enable_smc9000+set}" = set; then
338 - enableval="$enable_smc9000"
340 -fi;
341 -if test "x$enable_smc9000" = xyes; then
342 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SMC9000=1"
343 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS smc9000.o"
346 -# Check whether --enable-tiara or --disable-tiara was given.
347 -if test "${enable_tiara+set}" = set; then
348 - enableval="$enable_tiara"
349 +# Check whether --enable-tg3 or --disable-tg3 was given.
350 +if test "${enable_tg3+set}" = set; then
351 + enableval="$enable_tg3"
354 -if test "x$enable_tiara" = xyes; then
355 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TIARA=1"
356 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS tiara.o"
357 +if test "x$enable_tg3" = xyes; then
358 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TG3=1"
359 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS tg3.o"
362 # Check whether --enable-tulip or --disable-tulip was given.
363 @@ -5839,6 +5704,16 @@
364 NETBOOT_DRIVERS="$NETBOOT_DRIVERS tulip.o"
367 +# Check whether --enable-tlan or --disable-tlan was given.
368 +if test "${enable_tlan+set}" = set; then
369 + enableval="$enable_tlan"
371 +fi;
372 +if test "x$enable_tlan" = xyes; then
373 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TLAN=1"
374 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS tlan.o"
377 # Check whether --enable-via-rhine or --disable-via-rhine was given.
378 if test "${enable_via_rhine+set}" = set; then
379 enableval="$enable_via_rhine"
380 @@ -5873,24 +5748,6 @@
381 FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
384 -# Check whether --enable-3c503-shmem or --disable-3c503-shmem was given.
385 -if test "${enable_3c503_shmem+set}" = set; then
386 - enableval="$enable_3c503_shmem"
388 -fi;
389 -if test "x$enable_3c503_shmem" = xyes; then
390 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_SHMEM=1"
393 -# Check whether --enable-3c503-aui or --disable-3c503-aui was given.
394 -if test "${enable_3c503_aui+set}" = set; then
395 - enableval="$enable_3c503_aui"
397 -fi;
398 -if test "x$enable_3c503_aui" = xyes; then
399 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_AUI=1"
402 # Check whether --enable-compex-rl2000-fix or --disable-compex-rl2000-fix was given.
403 if test "${enable_compex_rl2000_fix+set}" = set; then
404 enableval="$enable_compex_rl2000_fix"
405 @@ -5900,12 +5757,6 @@
406 NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
409 -# Check whether --enable-smc9000-scan or --disable-smc9000-scan was given.
410 -if test "${enable_smc9000_scan+set}" = set; then
411 - enableval="$enable_smc9000_scan"
412 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"
413 -fi;
415 # Check whether --enable-ne-scan or --disable-ne-scan was given.
416 if test "${enable_ne_scan+set}" = set; then
417 enableval="$enable_ne_scan"
418 @@ -5922,12 +5773,6 @@
419 NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"
422 -# Check whether --enable-cs-scan or --disable-cs-scan was given.
423 -if test "${enable_cs_scan+set}" = set; then
424 - enableval="$enable_cs_scan"
425 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"
426 -fi;
428 # Check whether --enable-diskless or --disable-diskless was given.
429 if test "${enable_diskless+set}" = set; then
430 enableval="$enable_diskless"
431 Index: b/configure.ac
432 ===================================================================
433 --- a/configure.ac
434 +++ b/configure.ac
435 @@ -344,7 +344,7 @@
436 [ --disable-packet-retransmission
437 turn off packet retransmission])
438 if test "x$enable_packet_retransmission" != xno; then
439 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1"
440 + NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1 -DCONFIG_PCI"
443 AC_ARG_ENABLE(pci-direct,
444 @@ -354,20 +354,6 @@
447 dnl Device drivers.
448 -AC_ARG_ENABLE(3c509,
449 - [ --enable-3c509 enable 3Com509 driver])
450 -if test "x$enable_3c509" = xyes; then
451 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C509"
452 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c509.o"
455 -AC_ARG_ENABLE(3c529,
456 - [ --enable-3c529 enable 3Com529 driver])
457 -if test "x$enable_3c529" = xyes; then
458 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C529=1"
459 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
462 AC_ARG_ENABLE(3c595,
463 [ --enable-3c595 enable 3Com595 driver])
464 if test "x$enable_3c595" = xyes; then
465 @@ -382,13 +368,6 @@
466 NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c90x.o"
469 -AC_ARG_ENABLE(cs89x0,
470 - [ --enable-cs89x0 enable CS89x0 driver])
471 -if test "x$enable_cs89x0" = xyes; then
472 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS89X0=1"
473 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
476 AC_ARG_ENABLE(davicom,
477 [ --enable-davicom enable Davicom driver])
478 if test "x$enable_davicom" = xyes; then
479 @@ -396,18 +375,11 @@
480 NETBOOT_DRIVERS="$NETBOOT_DRIVERS davicom.o"
483 -AC_ARG_ENABLE(depca,
484 - [ --enable-depca enable DEPCA and EtherWORKS driver])
485 -if test "x$enable_depca" = xyes; then
486 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DEPCA=1"
487 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS depca.o"
490 -AC_ARG_ENABLE(eepro,
491 - [ --enable-eepro enable Etherexpress Pro/10 driver])
492 -if test "x$enable_eepro" = xyes; then
493 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO=1"
494 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro.o"
495 +AC_ARG_ENABLE(e1000,
496 + [ --enable-e1000 enable Etherexpress Pro/1000 driver])
497 +if test "x$enable_e1000" = xyes; then
498 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_E1000=1"
499 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS e1000.o"
502 AC_ARG_ENABLE(eepro100,
503 @@ -424,46 +396,11 @@
504 NETBOOT_DRIVERS="$NETBOOT_DRIVERS epic100.o"
507 -AC_ARG_ENABLE(3c507,
508 - [ --enable-3c507 enable 3Com507 driver])
509 -if test "x$enable_3c507" = xyes; then
510 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C507=1"
511 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c507.o"
514 -AC_ARG_ENABLE(exos205,
515 - [ --enable-exos205 enable EXOS205 driver])
516 -if test "x$enable_exos205" = xyes; then
517 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EXOS205=1"
518 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS exos205.o"
521 -AC_ARG_ENABLE(ni5210,
522 - [ --enable-ni5210 enable Racal-Interlan NI5210 driver])
523 -if test "x$enable_ni5210" = xyes; then
524 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5210=1"
525 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
528 -AC_ARG_ENABLE(lance,
529 - [ --enable-lance enable Lance PCI PCNet/32 driver])
530 -if test "x$enable_lance" = xyes; then
531 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
532 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS lance.o"
535 -AC_ARG_ENABLE(ne2100,
536 - [ --enable-ne2100 enable Novell NE2100 driver])
537 -if test "x$enable_ne2100" = xyes; then
538 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE2100=1"
539 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne2100.o"
542 -AC_ARG_ENABLE(ni6510,
543 - [ --enable-ni6510 enable Racal-Interlan NI6510 driver])
544 -if test "x$enable_ni6510" = xyes; then
545 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI6510=1"
546 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni6510.o"
547 +AC_ARG_ENABLE(forcedeth,
548 + [ --enable-forcedeth enable Nvidia Geforce driver])
549 +if test "x$enable_forcedeth" = xyes; then
550 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_FORCEDETH=1"
551 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS forcedeth.o"
554 AC_ARG_ENABLE(natsemi,
555 @@ -473,25 +410,11 @@
556 NETBOOT_DRIVERS="$NETBOOT_DRIVERS natsemi.o"
559 -AC_ARG_ENABLE(ni5010,
560 - [ --enable-ni5010 enable Racal-Interlan NI5010 driver])
561 -if test "x$enable_ni5010" = xyes; then
562 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5010=1"
563 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5010.o"
566 -AC_ARG_ENABLE(3c503,
567 - [ --enable-3c503 enable 3Com503 driver])
568 -if test "x$enable_3c503" = xyes; then
569 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C503=1"
570 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c503.o"
573 -AC_ARG_ENABLE(ne,
574 - [ --enable-ne enable NE1000/2000 ISA driver])
575 -if test "x$enable_ne" = xyes; then
576 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
577 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
578 +AC_ARG_ENABLE(ns83820,
579 + [ --enable-ns83820 enable NS83820 driver])
580 +if test "x$enable_ns83820" = xyes; then
581 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NS83820=1"
582 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns83820.o"
585 AC_ARG_ENABLE(ns8390,
586 @@ -501,18 +424,18 @@
587 NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns8390.o"
590 -AC_ARG_ENABLE(wd,
591 - [ --enable-wd enable WD8003/8013, SMC8216/8416 driver])
592 -if test "x$enable_wd" = xyes; then
593 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
594 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
595 +AC_ARG_ENABLE(pcnet32,
596 + [ --enable-pcnet32 enable AMD Lance/PCI PCNet/32 driver])
597 +if test "x$enable_pcnet32" = xyes; then
598 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_PCNET32=1"
599 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS pcnet32.o"
602 -AC_ARG_ENABLE(otulip,
603 - [ --enable-otulip enable old Tulip driver])
604 -if test "x$enable_otulip" = xyes; then
605 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_OTULIP=1"
606 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS otulip.o"
607 +AC_ARG_ENABLE(pnic,
608 + [ --enable-pnic enable Bochs Pseudo Nic driver])
609 +if test "x$enable_pnic" = xyes; then
610 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_PNIC=1"
611 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS pnic.o"
614 AC_ARG_ENABLE(rtl8139,
615 @@ -522,6 +445,13 @@
616 NETBOOT_DRIVERS="$NETBOOT_DRIVERS rtl8139.o"
619 +AC_ARG_ENABLE(r8169,
620 + [ --enable-r8169 enable Realtek 8169 driver])
621 +if test "x$enable_r8169" = xyes; then
622 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_R8169=1"
623 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS r8169.o"
626 AC_ARG_ENABLE(sis900,
627 [ --enable-sis900 enable SIS 900 and SIS 7016 driver])
628 if test "x$enable_sis900" = xyes; then
629 @@ -529,25 +459,11 @@
630 NETBOOT_DRIVERS="$NETBOOT_DRIVERS sis900.o"
633 -AC_ARG_ENABLE(sk-g16,
634 - [ --enable-sk-g16 enable Schneider and Koch G16 driver])
635 -if test "x$enable_sk_g16" = xyes; then
636 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SK_G16=1"
637 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS sk_g16.o"
640 -AC_ARG_ENABLE(smc9000,
641 - [ --enable-smc9000 enable SMC9000 driver])
642 -if test "x$enable_smc9000" = xyes; then
643 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SMC9000=1"
644 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS smc9000.o"
647 -AC_ARG_ENABLE(tiara,
648 - [ --enable-tiara enable Tiara driver])
649 -if test "x$enable_tiara" = xyes; then
650 - NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TIARA=1"
651 - NETBOOT_DRIVERS="$NETBOOT_DRIVERS tiara.o"
652 +AC_ARG_ENABLE(tg3,
653 + [ --enable-tg3 enable Broadcom Tigon3 driver])
654 +if test "x$enable_tg3" = xyes; then
655 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TG3=1"
656 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS tg3.o"
659 AC_ARG_ENABLE(tulip,
660 @@ -557,6 +473,13 @@
661 NETBOOT_DRIVERS="$NETBOOT_DRIVERS tulip.o"
664 +AC_ARG_ENABLE(tlan,
665 + [ --enable-tlan enable TI ThunderLAN driver])
666 +if test "x$enable_tlan" = xyes; then
667 + NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TLAN=1"
668 + NETBOOT_DRIVERS="$NETBOOT_DRIVERS tlan.o"
671 AC_ARG_ENABLE(via-rhine,
672 [ --enable-via-rhine enable Rhine-I/II driver])
673 if test "x$enable_via_rhine" = xyes; then
674 @@ -565,7 +488,7 @@
677 AC_ARG_ENABLE(w89c840,
678 - [ --enable-w89c840 enable Winbond W89c840, Compex RL100-ATX driver])
679 + [ --enable-w89c840 enable Winbond W89c840 driver])
680 if test "x$enable_w89c840" = xyes; then
681 NET_CFLAGS="$NET_CFLAGS -DINCLUDE_W89C840=1"
682 NETBOOT_DRIVERS="$NETBOOT_DRIVERS w89c840.o"
683 @@ -577,19 +500,7 @@
684 FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
687 -dnl Extra options.
688 -AC_ARG_ENABLE(3c503-shmem,
689 - [ --enable-3c503-shmem use 3c503 shared memory mode])
690 -if test "x$enable_3c503_shmem" = xyes; then
691 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_SHMEM=1"
694 -AC_ARG_ENABLE(3c503-aui,
695 - [ --enable-3c503-aui use AUI by default on 3c503 cards])
696 -if test "x$enable_3c503_aui" = xyes; then
697 - NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_AUI=1"
700 +dnl extra flag for ns8390.c
701 AC_ARG_ENABLE(compex-rl2000-fix,
702 [ --enable-compex-rl2000-fix
703 specify this if you have a Compex RL2000 PCI])
704 @@ -597,11 +508,6 @@
705 NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
708 -AC_ARG_ENABLE(smc9000-scan,
709 - [ --enable-smc9000-scan=LIST
710 - probe for SMC9000 I/O addresses using LIST],
711 - [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"])
713 AC_ARG_ENABLE(ne-scan,
714 [ --enable-ne-scan=LIST probe for NE base address using LIST],
715 [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"],
716 @@ -613,10 +519,6 @@
717 [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"],
718 [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"])
720 -AC_ARG_ENABLE(cs-scan,
721 - [ --enable-cs-scan=LIST probe for CS89x0 base address using LIST],
722 - [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"])
724 dnl Diskless
725 AC_ARG_ENABLE(diskless,
726 [ --enable-diskless enable diskless support])
727 Index: b/netboot/3c509.h
728 ===================================================================
729 --- a/netboot/3c509.h
730 +++ /dev/null
731 @@ -1,397 +0,0 @@
733 - * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
735 - * Redistribution and use in source and binary forms, with or without
736 - * modification, are permitted provided that the following conditions are
737 - * met: 1. Redistributions of source code must retain the above copyright
738 - * notice, this list of conditions and the following disclaimer. 2. The name
739 - * of the author may not be used to endorse or promote products derived from
740 - * this software withough specific prior written permission
742 - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
743 - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
744 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
745 - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
746 - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
747 - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
748 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
749 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
750 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
751 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
753 - * if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by:
755 - October 2, 1994
757 - Modified by: Andres Vega Garcia
759 - INRIA - Sophia Antipolis, France
760 - e-mail: avega@sophia.inria.fr
761 - finger: avega@pax.inria.fr
763 - */
766 - * Ethernet software status per interface.
767 - */
769 - * Some global constants
770 - */
772 -#define TX_INIT_RATE 16
773 -#define TX_INIT_MAX_RATE 64
774 -#define RX_INIT_LATENCY 64
775 -#define RX_INIT_EARLY_THRESH 64
776 -#define MIN_RX_EARLY_THRESHF 16 /* not less than ether_header */
777 -#define MIN_RX_EARLY_THRESHL 4
779 -#define EEPROMSIZE 0x40
780 -#define MAX_EEPROMBUSY 1000
781 -#define EP_LAST_TAG 0xd7
782 -#define EP_MAX_BOARDS 16
783 -#define EP_ID_PORT 0x100
786 - * some macros to acces long named fields
787 - */
788 -#define IS_BASE (eth_nic_base)
789 -#define BASE (eth_nic_base)
792 - * Commands to read/write EEPROM trough EEPROM command register (Window 0,
793 - * Offset 0xa)
794 - */
795 -#define EEPROM_CMD_RD 0x0080 /* Read: Address required (5 bits) */
796 -#define EEPROM_CMD_WR 0x0040 /* Write: Address required (5 bits) */
797 -#define EEPROM_CMD_ERASE 0x00c0 /* Erase: Address required (5 bits) */
798 -#define EEPROM_CMD_EWEN 0x0030 /* Erase/Write Enable: No data required */
800 -#define EEPROM_BUSY (1<<15)
801 -#define EEPROM_TST_MODE (1<<14)
804 - * Some short functions, worth to let them be a macro
805 - */
806 -#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
807 -#define GO_WINDOW(x) outw(WINDOW_SELECT|(x), BASE+EP_COMMAND)
809 -/**************************************************************************
811 - * These define the EEPROM data structure. They are used in the probe
812 - * function to verify the existance of the adapter after having sent
813 - * the ID_Sequence.
815 - * There are others but only the ones we use are defined here.
817 - **************************************************************************/
819 -#define EEPROM_NODE_ADDR_0 0x0 /* Word */
820 -#define EEPROM_NODE_ADDR_1 0x1 /* Word */
821 -#define EEPROM_NODE_ADDR_2 0x2 /* Word */
822 -#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
823 -#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
824 -#define EEPROM_ADDR_CFG 0x8 /* Base addr */
825 -#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
827 -/**************************************************************************
829 - * These are the registers for the 3Com 3c509 and their bit patterns when
830 - * applicable. They have been taken out the the "EtherLink III Parallel
831 - * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual
832 - * from 3com.
834 - **************************************************************************/
836 -#define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a
837 - * command reg. */
838 -#define EP_STATUS 0x0e /* Read. BASE+0x0e is always status
839 - * reg. */
840 -#define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window
841 - * reg. */
843 - * Window 0 registers. Setup.
844 - */
845 -/* Write */
846 -#define EP_W0_EEPROM_DATA 0x0c
847 -#define EP_W0_EEPROM_COMMAND 0x0a
848 -#define EP_W0_RESOURCE_CFG 0x08
849 -#define EP_W0_ADDRESS_CFG 0x06
850 -#define EP_W0_CONFIG_CTRL 0x04
851 -/* Read */
852 -#define EP_W0_PRODUCT_ID 0x02
853 -#define EP_W0_MFG_ID 0x00
856 - * Window 1 registers. Operating Set.
857 - */
858 -/* Write */
859 -#define EP_W1_TX_PIO_WR_2 0x02
860 -#define EP_W1_TX_PIO_WR_1 0x00
861 -/* Read */
862 -#define EP_W1_FREE_TX 0x0c
863 -#define EP_W1_TX_STATUS 0x0b /* byte */
864 -#define EP_W1_TIMER 0x0a /* byte */
865 -#define EP_W1_RX_STATUS 0x08
866 -#define EP_W1_RX_PIO_RD_2 0x02
867 -#define EP_W1_RX_PIO_RD_1 0x00
870 - * Window 2 registers. Station Address Setup/Read
871 - */
872 -/* Read/Write */
873 -#define EP_W2_ADDR_5 0x05
874 -#define EP_W2_ADDR_4 0x04
875 -#define EP_W2_ADDR_3 0x03
876 -#define EP_W2_ADDR_2 0x02
877 -#define EP_W2_ADDR_1 0x01
878 -#define EP_W2_ADDR_0 0x00
881 - * Window 3 registers. FIFO Management.
882 - */
883 -/* Read */
884 -#define EP_W3_FREE_TX 0x0c
885 -#define EP_W3_FREE_RX 0x0a
888 - * Window 4 registers. Diagnostics.
889 - */
890 -/* Read/Write */
891 -#define EP_W4_MEDIA_TYPE 0x0a
892 -#define EP_W4_CTRLR_STATUS 0x08
893 -#define EP_W4_NET_DIAG 0x06
894 -#define EP_W4_FIFO_DIAG 0x04
895 -#define EP_W4_HOST_DIAG 0x02
896 -#define EP_W4_TX_DIAG 0x00
899 - * Window 5 Registers. Results and Internal status.
900 - */
901 -/* Read */
902 -#define EP_W5_READ_0_MASK 0x0c
903 -#define EP_W5_INTR_MASK 0x0a
904 -#define EP_W5_RX_FILTER 0x08
905 -#define EP_W5_RX_EARLY_THRESH 0x06
906 -#define EP_W5_TX_AVAIL_THRESH 0x02
907 -#define EP_W5_TX_START_THRESH 0x00
910 - * Window 6 registers. Statistics.
911 - */
912 -/* Read/Write */
913 -#define TX_TOTAL_OK 0x0c
914 -#define RX_TOTAL_OK 0x0a
915 -#define TX_DEFERRALS 0x08
916 -#define RX_FRAMES_OK 0x07
917 -#define TX_FRAMES_OK 0x06
918 -#define RX_OVERRUNS 0x05
919 -#define TX_COLLISIONS 0x04
920 -#define TX_AFTER_1_COLLISION 0x03
921 -#define TX_AFTER_X_COLLISIONS 0x02
922 -#define TX_NO_SQE 0x01
923 -#define TX_CD_LOST 0x00
925 -/****************************************
927 - * Register definitions.
929 - ****************************************/
932 - * Command register. All windows.
934 - * 16 bit register.
935 - * 15-11: 5-bit code for command to be executed.
936 - * 10-0: 11-bit arg if any. For commands with no args;
937 - * this can be set to anything.
938 - */
939 -#define GLOBAL_RESET (unsigned short) 0x0000 /* Wait at least 1ms
940 - * after issuing */
941 -#define WINDOW_SELECT (unsigned short) (0x1<<11)
942 -#define START_TRANSCEIVER (unsigned short) (0x2<<11) /* Read ADDR_CFG reg to
943 - * determine whether
944 - * this is needed. If
945 - * so; wait 800 uSec
946 - * before using trans-
947 - * ceiver. */
948 -#define RX_DISABLE (unsigned short) (0x3<<11) /* state disabled on
949 - * power-up */
950 -#define RX_ENABLE (unsigned short) (0x4<<11)
951 -#define RX_RESET (unsigned short) (0x5<<11)
952 -#define RX_DISCARD_TOP_PACK (unsigned short) (0x8<<11)
953 -#define TX_ENABLE (unsigned short) (0x9<<11)
954 -#define TX_DISABLE (unsigned short) (0xa<<11)
955 -#define TX_RESET (unsigned short) (0xb<<11)
956 -#define REQ_INTR (unsigned short) (0xc<<11)
957 -#define SET_INTR_MASK (unsigned short) (0xe<<11)
958 -#define SET_RD_0_MASK (unsigned short) (0xf<<11)
959 -#define SET_RX_FILTER (unsigned short) (0x10<<11)
960 -#define FIL_INDIVIDUAL (unsigned short) (0x1)
961 -#define FIL_GROUP (unsigned short) (0x2)
962 -#define FIL_BRDCST (unsigned short) (0x4)
963 -#define FIL_ALL (unsigned short) (0x8)
964 -#define SET_RX_EARLY_THRESH (unsigned short) (0x11<<11)
965 -#define SET_TX_AVAIL_THRESH (unsigned short) (0x12<<11)
966 -#define SET_TX_START_THRESH (unsigned short) (0x13<<11)
967 -#define STATS_ENABLE (unsigned short) (0x15<<11)
968 -#define STATS_DISABLE (unsigned short) (0x16<<11)
969 -#define STOP_TRANSCEIVER (unsigned short) (0x17<<11)
971 - * The following C_* acknowledge the various interrupts. Some of them don't
972 - * do anything. See the manual.
973 - */
974 -#define ACK_INTR (unsigned short) (0x6800)
975 -#define C_INTR_LATCH (unsigned short) (ACK_INTR|0x1)
976 -#define C_CARD_FAILURE (unsigned short) (ACK_INTR|0x2)
977 -#define C_TX_COMPLETE (unsigned short) (ACK_INTR|0x4)
978 -#define C_TX_AVAIL (unsigned short) (ACK_INTR|0x8)
979 -#define C_RX_COMPLETE (unsigned short) (ACK_INTR|0x10)
980 -#define C_RX_EARLY (unsigned short) (ACK_INTR|0x20)
981 -#define C_INT_RQD (unsigned short) (ACK_INTR|0x40)
982 -#define C_UPD_STATS (unsigned short) (ACK_INTR|0x80)
985 - * Status register. All windows.
987 - * 15-13: Window number(0-7).
988 - * 12: Command_in_progress.
989 - * 11: reserved.
990 - * 10: reserved.
991 - * 9: reserved.
992 - * 8: reserved.
993 - * 7: Update Statistics.
994 - * 6: Interrupt Requested.
995 - * 5: RX Early.
996 - * 4: RX Complete.
997 - * 3: TX Available.
998 - * 2: TX Complete.
999 - * 1: Adapter Failure.
1000 - * 0: Interrupt Latch.
1001 - */
1002 -#define S_INTR_LATCH (unsigned short) (0x1)
1003 -#define S_CARD_FAILURE (unsigned short) (0x2)
1004 -#define S_TX_COMPLETE (unsigned short) (0x4)
1005 -#define S_TX_AVAIL (unsigned short) (0x8)
1006 -#define S_RX_COMPLETE (unsigned short) (0x10)
1007 -#define S_RX_EARLY (unsigned short) (0x20)
1008 -#define S_INT_RQD (unsigned short) (0x40)
1009 -#define S_UPD_STATS (unsigned short) (0x80)
1010 -#define S_5_INTS (S_CARD_FAILURE|S_TX_COMPLETE|\
1011 - S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
1012 -#define S_COMMAND_IN_PROGRESS (unsigned short) (0x1000)
1015 - * FIFO Registers.
1016 - * RX Status. Window 1/Port 08
1018 - * 15: Incomplete or FIFO empty.
1019 - * 14: 1: Error in RX Packet 0: Incomplete or no error.
1020 - * 13-11: Type of error.
1021 - * 1000 = Overrun.
1022 - * 1011 = Run Packet Error.
1023 - * 1100 = Alignment Error.
1024 - * 1101 = CRC Error.
1025 - * 1001 = Oversize Packet Error (>1514 bytes)
1026 - * 0010 = Dribble Bits.
1027 - * (all other error codes, no errors.)
1029 - * 10-0: RX Bytes (0-1514)
1030 - */
1031 -#define ERR_RX_INCOMPLETE (unsigned short) (0x1<<15)
1032 -#define ERR_RX (unsigned short) (0x1<<14)
1033 -#define ERR_RX_OVERRUN (unsigned short) (0x8<<11)
1034 -#define ERR_RX_RUN_PKT (unsigned short) (0xb<<11)
1035 -#define ERR_RX_ALIGN (unsigned short) (0xc<<11)
1036 -#define ERR_RX_CRC (unsigned short) (0xd<<11)
1037 -#define ERR_RX_OVERSIZE (unsigned short) (0x9<<11)
1038 -#define ERR_RX_DRIBBLE (unsigned short) (0x2<<11)
1041 - * FIFO Registers.
1042 - * TX Status. Window 1/Port 0B
1044 - * Reports the transmit status of a completed transmission. Writing this
1045 - * register pops the transmit completion stack.
1047 - * Window 1/Port 0x0b.
1049 - * 7: Complete
1050 - * 6: Interrupt on successful transmission requested.
1051 - * 5: Jabber Error (TP Only, TX Reset required. )
1052 - * 4: Underrun (TX Reset required. )
1053 - * 3: Maximum Collisions.
1054 - * 2: TX Status Overflow.
1055 - * 1-0: Undefined.
1057 - */
1058 -#define TXS_COMPLETE 0x80
1059 -#define TXS_SUCCES_INTR_REQ 0x40
1060 -#define TXS_JABBER 0x20
1061 -#define TXS_UNDERRUN 0x10
1062 -#define TXS_MAX_COLLISION 0x8
1063 -#define TXS_STATUS_OVERFLOW 0x4
1066 - * Configuration control register.
1067 - * Window 0/Port 04
1068 - */
1069 -/* Read */
1070 -#define IS_AUI (1<<13)
1071 -#define IS_BNC (1<<12)
1072 -#define IS_UTP (1<<9)
1073 -/* Write */
1074 -#define ENABLE_DRQ_IRQ 0x0001
1075 -#define W0_P4_CMD_RESET_ADAPTER 0x4
1076 -#define W0_P4_CMD_ENABLE_ADAPTER 0x1
1078 - * Media type and status.
1079 - * Window 4/Port 0A
1080 - */
1081 -#define ENABLE_UTP 0xc0
1082 -#define DISABLE_UTP 0x0
1085 - * Resource control register
1086 - */
1088 -#define SET_IRQ(i) ( ((i)<<12) | 0xF00) /* set IRQ i */
1091 - * Receive status register
1092 - */
1094 -#define RX_BYTES_MASK (unsigned short) (0x07ff)
1095 -#define RX_ERROR 0x4000
1096 -#define RX_INCOMPLETE 0x8000
1100 - * Misc defines for various things.
1101 - */
1102 -#define ACTIVATE_ADAPTER_TO_CONFIG 0xff /* to the id_port */
1103 -#define MFG_ID 0x6d50 /* in EEPROM and W0 ADDR_CONFIG */
1104 -#define PROD_ID 0x9150
1106 -#define AUI 0x1
1107 -#define BNC 0x2
1108 -#define UTP 0x4
1110 -#define RX_BYTES_MASK (unsigned short) (0x07ff)
1112 - /* EISA support */
1113 -#define EP_EISA_START 0x1000
1114 -#define EP_EISA_W0 0x0c80
1116 -#ifdef INCLUDE_3C529
1117 - /* MCA support */
1118 -#define MCA_MOTHERBOARD_SETUP_REG 0x94
1119 -#define MCA_ADAPTER_SETUP_REG 0x96
1120 -#define MCA_MAX_SLOT_NR 8
1121 -#define MCA_POS_REG(n) (0x100+(n))
1122 -#endif
1125 - * Local variables:
1126 - * c-basic-offset: 8
1127 - * End:
1128 - */
1129 Index: b/netboot/3c595.c
1130 ===================================================================
1131 --- a/netboot/3c595.c
1132 +++ b/netboot/3c595.c
1133 @@ -20,6 +20,7 @@
1135 * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
1137 +* timlegge 08-24-2003 Add Multicast Support
1140 /* #define EDEBUG */
1141 @@ -30,7 +31,7 @@
1142 #include "3c595.h"
1143 #include "timer.h"
1145 -static unsigned short eth_nic_base, eth_asic_base;
1146 +static unsigned short eth_nic_base;
1147 static unsigned short vx_connector, vx_connectors;
1149 static struct connector_entry {
1150 @@ -57,14 +58,12 @@
1151 static void vxgetlink(void);
1152 static void vxsetlink(void);
1154 -#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
1156 /**************************************************************************
1157 ETH_RESET - Reset adapter
1158 ***************************************************************************/
1159 static void t595_reset(struct nic *nic)
1161 - int i, j;
1162 + int i;
1164 /***********************************************************
1165 Reset 3Com 595 card
1166 @@ -133,7 +132,7 @@
1167 outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
1169 outw(SET_RX_FILTER | FIL_INDIVIDUAL |
1170 - FIL_BRDCST, BASE + VX_COMMAND);
1171 + FIL_BRDCST|FIL_MULTICAST, BASE + VX_COMMAND);
1173 vxsetlink();
1175 @@ -225,10 +224,9 @@
1176 /**************************************************************************
1177 ETH_POLL - Wait for a frame
1178 ***************************************************************************/
1179 -static int t595_poll(struct nic *nic)
1180 +static int t595_poll(struct nic *nic, int retrieve)
1182 /* common variables */
1183 - unsigned short type = 0; /* used by EDEBUG */
1184 /* variables for 3C595 */
1185 short status, cst;
1186 register short rx_fifo;
1187 @@ -262,6 +260,8 @@
1188 if (rx_fifo==0)
1189 return 0;
1191 + if ( ! retrieve ) return 1;
1193 /* read packet */
1194 #ifdef EDEBUG
1195 printf("[l=%d",rx_fifo);
1196 @@ -300,12 +300,15 @@
1197 outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
1198 while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
1199 #ifdef EDEBUG
1201 + unsigned short type = 0; /* used by EDEBUG */
1202 type = (nic->packet[12]<<8) | nic->packet[13];
1203 if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
1204 nic->packet[5] == 0xFF*ETH_ALEN)
1205 printf(",t=%hX,b]",type);
1206 else
1207 printf(",t=%hX]",type);
1209 #endif
1210 return 1;
1212 @@ -382,9 +385,8 @@
1213 static void
1214 vxsetlink(void)
1216 - int i, j, k;
1217 + int i, j;
1218 char *reason, *warning;
1219 - static short prev_flags;
1220 static char prev_conn = -1;
1222 if (prev_conn == -1) {
1223 @@ -438,28 +440,47 @@
1224 GO_WINDOW(1);
1227 -static void t595_disable(struct nic *nic)
1228 +static void t595_disable(struct dev *dev)
1230 - outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
1231 - udelay(8000);
1232 - GO_WINDOW(4);
1233 - outw(0, BASE + VX_W4_MEDIA_TYPE);
1234 - GO_WINDOW(1);
1235 + struct nic *nic = (struct nic *)dev;
1236 + t595_reset(nic);
1238 + outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
1239 + udelay(8000);
1240 + GO_WINDOW(4);
1241 + outw(0, BASE + VX_W4_MEDIA_TYPE);
1242 + GO_WINDOW(1);
1245 +static void t595_irq(struct nic *nic __unused, irq_action_t action __unused)
1247 + switch ( action ) {
1248 + case DISABLE :
1249 + break;
1250 + case ENABLE :
1251 + break;
1252 + case FORCE :
1253 + break;
1257 /**************************************************************************
1258 ETH_PROBE - Look for an adapter
1259 ***************************************************************************/
1260 -struct nic *t595_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
1261 +static int t595_probe(struct dev *dev, struct pci_device *pci)
1263 + struct nic *nic = (struct nic *)dev;
1264 int i;
1265 unsigned short *p;
1267 - if (probeaddrs == 0 || probeaddrs[0] == 0)
1268 + if (pci->ioaddr == 0)
1269 return 0;
1270 /* eth_nic_base = probeaddrs[0] & ~3; */
1271 eth_nic_base = pci->ioaddr;
1273 + nic->irqno = 0;
1274 + nic->ioaddr = pci->ioaddr & ~3;
1276 GO_WINDOW(0);
1277 outw(GLOBAL_RESET, BASE + VX_COMMAND);
1278 VX_BUSY_WAIT;
1279 @@ -487,14 +508,40 @@
1280 printf("Ethernet address: %!\n", nic->node_addr);
1282 t595_reset(nic);
1283 - nic->reset = t595_reset;
1284 - nic->poll = t595_poll;
1285 + dev->disable = t595_disable;
1286 + nic->poll = t595_poll;
1287 nic->transmit = t595_transmit;
1288 - nic->disable = t595_disable;
1289 - return nic;
1290 + nic->irq = t595_irq;
1291 + return 1;
1295 +static struct pci_id t595_nics[] = {
1296 +PCI_ROM(0x10b7, 0x5900, "3c590", "3Com590"), /* Vortex 10Mbps */
1297 +PCI_ROM(0x10b7, 0x5950, "3c595", "3Com595"), /* Vortex 100baseTx */
1298 +PCI_ROM(0x10b7, 0x5951, "3c595-1", "3Com595"), /* Vortex 100baseT4 */
1299 +PCI_ROM(0x10b7, 0x5952, "3c595-2", "3Com595"), /* Vortex 100base-MII */
1300 +PCI_ROM(0x10b7, 0x9000, "3c900-tpo", "3Com900-TPO"), /* 10 Base TPO */
1301 +PCI_ROM(0x10b7, 0x9001, "3c900-t4", "3Com900-Combo"), /* 10/100 T4 */
1302 +PCI_ROM(0x10b7, 0x9004, "3c900b-tpo", "3Com900B-TPO"), /* 10 Base TPO */
1303 +PCI_ROM(0x10b7, 0x9005, "3c900b-combo", "3Com900B-Combo"), /* 10 Base Combo */
1304 +PCI_ROM(0x10b7, 0x9006, "3c900b-tpb2", "3Com900B-2/T"), /* 10 Base TP and Base2 */
1305 +PCI_ROM(0x10b7, 0x900a, "3c900b-fl", "3Com900B-FL"), /* 10 Base F */
1306 +PCI_ROM(0x10b7, 0x9800, "3c980-cyclone-1", "3Com980-Cyclone"), /* Cyclone */
1307 +PCI_ROM(0x10b7, 0x9805, "3c9805-1", "3Com9805"), /* Dual Port Server Cyclone */
1308 +PCI_ROM(0x10b7, 0x7646, "3csoho100-tx-1", "3CSOHO100-TX"), /* Hurricane */
1309 +PCI_ROM(0x10b7, 0x4500, "3c450-1", "3Com450 HomePNA Tornado"),
1312 +struct pci_driver t595_driver = {
1313 + .type = NIC_DRIVER,
1314 + .name = "3C595",
1315 + .probe = t595_probe,
1316 + .ids = t595_nics,
1317 + .id_count = sizeof(t595_nics)/sizeof(t595_nics[0]),
1318 + .class = 0,
1322 * Local variables:
1323 * c-basic-offset: 8
1324 Index: b/netboot/3c90x.c
1325 ===================================================================
1326 --- a/netboot/3c90x.c
1327 +++ b/netboot/3c90x.c
1328 @@ -1,7 +1,7 @@
1330 * 3c90x.c -- This file implements the 3c90x driver for etherboot. Written
1331 * by Greg Beeley, Greg.Beeley@LightSys.org. Modified by Steve Smith,
1332 - * Steve.Smith@Juno.Com
1333 + * Steve.Smith@Juno.Com. Alignment bug fix Neil Newell (nn@icenoir.net).
1335 * This program Copyright (C) 1999 LightSys Technology Services, Inc.
1336 * Portions Copyright (C) 1999 Steve Smith
1337 @@ -31,13 +31,15 @@
1338 * Re-wrote poll and transmit for
1339 * better error recovery and heavy
1340 * network traffic operation
1341 + * v2.01 5-26-2003 NN Fixed driver alignment issue which
1342 + * caused system lockups if driver structures
1343 + * not 8-byte aligned.
1347 #include "etherboot.h"
1348 #include "nic.h"
1349 #include "pci.h"
1350 -#include "cards.h"
1351 #include "timer.h"
1353 #define XCVR_MAGIC (0x5A00)
1354 @@ -47,9 +49,6 @@
1356 #define XMIT_RETRIES 250
1358 -#undef virt_to_bus
1359 -#define virt_to_bus(x) ((unsigned long)x)
1361 /*** Register definitions for the 3c905 ***/
1362 enum Registers
1364 @@ -225,7 +224,7 @@
1365 unsigned int DataAddr;
1366 unsigned int DataLength;
1368 - TXD;
1369 + TXD __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */
1371 /*** RX descriptor ***/
1372 typedef struct
1373 @@ -235,7 +234,7 @@
1374 unsigned int DataAddr;
1375 unsigned int DataLength;
1377 - RXD;
1378 + RXD __attribute__ ((aligned(8))); /* 64-bit aligned for bus mastering */
1380 /*** Global variables ***/
1381 static struct
1382 @@ -311,6 +310,7 @@
1386 +#if 0
1387 /*** a3c90x_internal_WriteEepromWord - write a physical word of
1388 *** data to the onboard serial eeprom (not the BIOS prom, but the
1389 *** nvram in the card that stores, among other things, the MAC
1390 @@ -344,8 +344,9 @@
1392 return 0;
1394 +#endif
1397 +#if 0
1398 /*** a3c90x_internal_WriteEeprom - write data to the serial eeprom,
1399 *** and re-compute the eeprom checksum.
1400 ***/
1401 @@ -384,8 +385,7 @@
1403 return 0;
1407 +#endif
1409 /*** a3c90x_reset: exported function that resets the card to its default
1410 *** state. This is so the Linux driver can re-set the card up the way
1411 @@ -393,12 +393,10 @@
1412 *** not alter the selected transceiver that we used to download the boot
1413 *** image.
1414 ***/
1415 -static void
1416 -a3c90x_reset(struct nic *nic)
1417 +static void a3c90x_reset(void)
1419 - int cfg;
1421 #ifdef CFG_3C90X_PRESERVE_XCVR
1422 + int cfg;
1423 /** Read the current InternalConfig value. **/
1424 a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
1425 cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
1426 @@ -473,7 +471,7 @@
1427 *** p - the pointer to the packet data itself.
1428 ***/
1429 static void
1430 -a3c90x_transmit(struct nic *nic, const char *d, unsigned int t,
1431 +a3c90x_transmit(struct nic *nic __unused, const char *d, unsigned int t,
1432 unsigned int s, const char *p)
1435 @@ -553,7 +551,7 @@
1436 if (status & 0x02)
1438 printf("3C90X: Tx Reclaim Error (%hhX)\n", status);
1439 - a3c90x_reset(NULL);
1440 + a3c90x_reset();
1442 else if (status & 0x04)
1444 @@ -572,18 +570,18 @@
1445 else if (status & 0x10)
1447 printf("3C90X: Tx Underrun (%hhX)\n", status);
1448 - a3c90x_reset(NULL);
1449 + a3c90x_reset();
1451 else if (status & 0x20)
1453 printf("3C90X: Tx Jabber (%hhX)\n", status);
1454 - a3c90x_reset(NULL);
1455 + a3c90x_reset();
1457 else if ((status & 0x80) != 0x80)
1459 printf("3C90X: Internal Error - Incomplete Transmission (%hhX)\n",
1460 status);
1461 - a3c90x_reset(NULL);
1462 + a3c90x_reset();
1466 @@ -601,7 +599,7 @@
1467 *** in nic->packetlen. Return 1 if a packet was found.
1468 ***/
1469 static int
1470 -a3c90x_poll(struct nic *nic)
1471 +a3c90x_poll(struct nic *nic, int retrieve)
1473 int i, errcode;
1475 @@ -610,6 +608,8 @@
1476 return 0;
1479 + if ( ! retrieve ) return 1;
1481 /** we don't need to acknowledge rxComplete -- the upload engine
1482 ** does it for us.
1484 @@ -663,34 +663,51 @@
1485 *** [Ken]
1486 ***/
1487 static void
1488 -a3c90x_disable(struct nic *nic)
1490 +a3c90x_disable(struct dev *dev __unused)
1492 + /* reset and disable merge */
1493 + a3c90x_reset();
1494 /* Disable the receiver and transmitter. */
1495 outw(cmdRxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
1496 outw(cmdTxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
1501 +static void a3c90x_irq(struct nic *nic __unused, irq_action_t action __unused)
1503 + switch ( action ) {
1504 + case DISABLE :
1505 + break;
1506 + case ENABLE :
1507 + break;
1508 + case FORCE :
1509 + break;
1513 /*** a3c90x_probe: exported routine to probe for the 3c905 card and perform
1514 *** initialization. If this routine is called, the pci functions did find the
1515 *** card. We just have to init it here.
1516 ***/
1517 -struct nic*
1518 -a3c90x_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
1520 +static int a3c90x_probe(struct dev *dev, struct pci_device *pci)
1522 + struct nic *nic = (struct nic *)dev;
1523 int i, c;
1524 unsigned short eeprom[0x21];
1525 unsigned int cfg;
1526 unsigned int mopt;
1527 + unsigned int mstat;
1528 unsigned short linktype;
1529 +#define HWADDR_OFFSET 10
1531 - if (probeaddrs == 0 || probeaddrs[0] == 0)
1532 + if (pci->ioaddr == 0)
1533 return 0;
1535 adjust_pci_device(pci);
1537 - INF_3C90X.IOAddr = probeaddrs[0] & ~3;
1538 + nic->ioaddr = pci->ioaddr & ~3;
1539 + nic->irqno = 0;
1541 + INF_3C90X.IOAddr = pci->ioaddr & ~3;
1542 INF_3C90X.CurrentWindow = 255;
1543 switch (a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, 0x03))
1545 @@ -756,30 +773,45 @@
1546 "Copyright 1999 LightSys Technology Services, Inc.\n"
1547 "Portions Copyright 1999 Steve Smith\n");
1548 printf("Provided with ABSOLUTELY NO WARRANTY.\n");
1549 +#ifdef CFG_3C90X_BOOTROM_FIX
1550 + if (INF_3C90X.isBrev)
1552 + printf("NOTE: 3c905b bootrom fix enabled; has side "
1553 + "effects. See 3c90x.txt for info.\n");
1555 +#endif
1556 printf("-------------------------------------------------------"
1557 "------------------------\n");
1559 /** Retrieve the Hardware address and print it on the screen. **/
1560 - INF_3C90X.HWAddr[0] = eeprom[0]>>8;
1561 - INF_3C90X.HWAddr[1] = eeprom[0]&0xFF;
1562 - INF_3C90X.HWAddr[2] = eeprom[1]>>8;
1563 - INF_3C90X.HWAddr[3] = eeprom[1]&0xFF;
1564 - INF_3C90X.HWAddr[4] = eeprom[2]>>8;
1565 - INF_3C90X.HWAddr[5] = eeprom[2]&0xFF;
1566 + INF_3C90X.HWAddr[0] = eeprom[HWADDR_OFFSET + 0]>>8;
1567 + INF_3C90X.HWAddr[1] = eeprom[HWADDR_OFFSET + 0]&0xFF;
1568 + INF_3C90X.HWAddr[2] = eeprom[HWADDR_OFFSET + 1]>>8;
1569 + INF_3C90X.HWAddr[3] = eeprom[HWADDR_OFFSET + 1]&0xFF;
1570 + INF_3C90X.HWAddr[4] = eeprom[HWADDR_OFFSET + 2]>>8;
1571 + INF_3C90X.HWAddr[5] = eeprom[HWADDR_OFFSET + 2]&0xFF;
1572 printf("MAC Address = %!\n", INF_3C90X.HWAddr);
1574 + /* Test if the link is good, if not continue */
1575 + a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winDiagnostics4);
1576 + mstat = inw(INF_3C90X.IOAddr + regMediaStatus_4_w);
1577 + if((mstat & (1<<11)) == 0) {
1578 + printf("Valid link not established\n");
1579 + return 0;
1582 /** Program the MAC address into the station address registers **/
1583 a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
1584 - outw(htons(eeprom[0]), INF_3C90X.IOAddr + regStationAddress_2_3w);
1585 - outw(htons(eeprom[1]), INF_3C90X.IOAddr + regStationAddress_2_3w+2);
1586 - outw(htons(eeprom[2]), INF_3C90X.IOAddr + regStationAddress_2_3w+4);
1587 + outw(htons(eeprom[HWADDR_OFFSET + 0]), INF_3C90X.IOAddr + regStationAddress_2_3w);
1588 + outw(htons(eeprom[HWADDR_OFFSET + 1]), INF_3C90X.IOAddr + regStationAddress_2_3w+2);
1589 + outw(htons(eeprom[HWADDR_OFFSET + 2]), INF_3C90X.IOAddr + regStationAddress_2_3w+4);
1590 outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
1591 outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
1592 outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
1594 /** Fill in our entry in the etherboot arp table **/
1595 for(i=0;i<ETH_ALEN;i++)
1596 - nic->node_addr[i] = (eeprom[i/2] >> (8*((i&1)^1))) & 0xff;
1597 + nic->node_addr[i] = (eeprom[HWADDR_OFFSET + i/2] >> (8*((i&1)^1))) & 0xff;
1599 /** Read the media options register, print a message and set default
1600 ** xcvr.
1601 @@ -903,8 +935,8 @@
1602 while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
1605 - /** Set the RX filter = receive only individual pkts & bcast. **/
1606 - a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetRxFilter, 0x01 + 0x04);
1607 + /** Set the RX filter = receive only individual pkts & multicast & bcast. **/
1608 + a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetRxFilter, 0x01 + 0x02 + 0x04);
1609 a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
1612 @@ -918,12 +950,46 @@
1613 cmdAcknowledgeInterrupt, 0x661);
1615 /** Set our exported functions **/
1616 - nic->reset = a3c90x_reset;
1617 + dev->disable = a3c90x_disable;
1618 nic->poll = a3c90x_poll;
1619 nic->transmit = a3c90x_transmit;
1620 - nic->disable = a3c90x_disable;
1621 + nic->irq = a3c90x_irq;
1623 - return nic;
1625 + return 1;
1629 +static struct pci_id a3c90x_nics[] = {
1630 +/* Original 90x revisions: */
1631 +PCI_ROM(0x10b7, 0x9000, "3c905-tpo", "3Com900-TPO"), /* 10 Base TPO */
1632 +PCI_ROM(0x10b7, 0x9001, "3c905-t4", "3Com900-Combo"), /* 10/100 T4 */
1633 +PCI_ROM(0x10b7, 0x9050, "3c905-tpo100", "3Com905-TX"), /* 100 Base TX / 10/100 TPO */
1634 +PCI_ROM(0x10b7, 0x9051, "3c905-combo", "3Com905-T4"), /* 100 Base T4 / 10 Base Combo */
1635 +/* Newer 90xB revisions: */
1636 +PCI_ROM(0x10b7, 0x9004, "3c905b-tpo", "3Com900B-TPO"), /* 10 Base TPO */
1637 +PCI_ROM(0x10b7, 0x9005, "3c905b-combo", "3Com900B-Combo"), /* 10 Base Combo */
1638 +PCI_ROM(0x10b7, 0x9006, "3c905b-tpb2", "3Com900B-2/T"), /* 10 Base TP and Base2 */
1639 +PCI_ROM(0x10b7, 0x900a, "3c905b-fl", "3Com900B-FL"), /* 10 Base FL */
1640 +PCI_ROM(0x10b7, 0x9055, "3c905b-tpo100", "3Com905B-TX"), /* 10/100 TPO */
1641 +PCI_ROM(0x10b7, 0x9056, "3c905b-t4", "3Com905B-T4"), /* 10/100 T4 */
1642 +PCI_ROM(0x10b7, 0x9058, "3c905b-9058", "3Com905B-9058"), /* Cyclone 10/100/BNC */
1643 +PCI_ROM(0x10b7, 0x905a, "3c905b-fx", "3Com905B-FL"), /* 100 Base FX / 10 Base FX */
1644 +/* Newer 90xC revision: */
1645 +PCI_ROM(0x10b7, 0x9200, "3c905c-tpo", "3Com905C-TXM"), /* 10/100 TPO (3C905C-TXM) */
1646 +PCI_ROM(0x10b7, 0x9210, "3c920b-emb-wnm","3Com20B-EMB WNM"),
1647 +PCI_ROM(0x10b7, 0x9800, "3c980", "3Com980-Cyclone"), /* Cyclone */
1648 +PCI_ROM(0x10b7, 0x9805, "3c9805", "3Com9805"), /* Dual Port Server Cyclone */
1649 +PCI_ROM(0x10b7, 0x7646, "3csoho100-tx", "3CSOHO100-TX"), /* Hurricane */
1650 +PCI_ROM(0x10b7, 0x4500, "3c450", "3Com450 HomePNA Tornado"),
1651 +PCI_ROM(0x10b7, 0x1201, "3c982a", "3Com982A"),
1652 +PCI_ROM(0x10b7, 0x1202, "3c982b", "3Com982B"),
1655 +struct pci_driver a3c90x_driver = {
1656 + .type = NIC_DRIVER,
1657 + .name = "3C90X",
1658 + .probe = a3c90x_probe,
1659 + .ids = a3c90x_nics,
1660 + .id_count = sizeof(a3c90x_nics)/sizeof(a3c90x_nics[0]),
1661 + .class = 0,
1663 Index: b/netboot/3c90x.txt
1664 ===================================================================
1665 --- a/netboot/3c90x.txt
1666 +++ /dev/null
1667 @@ -1,307 +0,0 @@
1669 - Instructions for use of the 3C90X driver for EtherBoot
1671 - Original 3C905B support by:
1672 - Greg Beeley (Greg.Beeley@LightSys.org),
1673 - LightSys Technology Services, Inc.
1674 - February 11, 1999
1676 - Updates for 3C90X family by:
1677 - Steve Smith (steve.smith@juno.com)
1678 - October 1, 1999
1680 - Minor documentation updates by
1681 - Greg Beeley (Greg.Beeley@LightSys.org)
1682 - March 29, 2000
1684 --------------------------------------------------------------------------------
1686 -I OVERVIEW
1688 - The 3c90X series ethernet cards are a group of high-performance busmaster
1689 - DMA cards from 3Com. This particular driver supports both the 3c90x and
1690 - the 3c90xB revision cards. 3C90xC family support has been tested to some
1691 - degree but not extensively.
1693 - Here's the licensing information:
1695 - This program Copyright (C) 1999 LightSys Technology Services, Inc.
1696 - Portions Copyright (C) 1999 Steve Smith.
1698 - This program may be re-distributed in source or binary form, modified,
1699 - sold, or copied for any purpose, provided that the above copyright message
1700 - and this text are included with all source copies or derivative works, and
1701 - provided that the above copyright message and this text are included in the
1702 - documentation of any binary-only distributions. This program is
1703 - distributed WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR
1704 - A PARTICULAR PURPOSE or MERCHANTABILITY. Please read the associated
1705 - documentation "3c90x.txt" before compiling and using this driver.
1708 -II FLASH PROMS
1710 - The 3c90xB cards, according to the 3Com documentation, only accept the
1711 - following flash memory chips:
1713 - Atmel AT29C512 (64 kilobyte)
1714 - Atmel AT29C010 (128 kilobyte)
1716 - The 3c90x cards, according to the 3Com documentation, accept the
1717 - following flash memory chips capacities:
1719 - 64 kb (8 kB)
1720 - 128 kb (16 kB)
1721 - 256 kb (32 kB) and
1722 - 512 kb (64 kB)
1724 - Atmel AT29C512 (64 kilobyte) chips are specifically listed for both
1725 - adapters, but flashing on the 3c905b cards would only be supported
1726 - through the Atmel parts. Any device, of the supported size, should
1727 - be supported when programmed by a dedicated PROM programmer (e.g.
1728 - not the card).
1730 - To use this driver in such a PROM, visit Atmel's web site and download
1731 - their .PDF file containing a list of their distributors. Contact the
1732 - distributors for pricing information. The prices are quite reasonable
1733 - (about $3 US each for the 64 kB part), and are comparable to what one would
1734 - expect for similarly sized standard EPROMs. And, the flash chips are much
1735 - easier to work with, as they don't need to be UV-erased to be reprogrammed.
1736 - The 3C905B card actually provides a method to program the flash memory
1737 - while it is resident on board the card itself; if someone would like to
1738 - write a small DOS program to do the programming, I can provide the
1739 - information about the registers and so forth.
1741 - A utility program, 3c90xutil, is provided with Etherboot in the 'contrib'
1742 - directory that allows for the on-board flashing of the ROM while Linux
1743 - is running. The program has been successfully used under Linux, but I
1744 - have heard problem reports of its use under FreeBSD. Anyone willing to
1745 - make it work under FreeBSD is more than welcome to do so!
1747 - You also have the option of using EPROM chips - the 3C905B-TX-NM has been
1748 - successfully tested with 27C256 (32kB) and 27C512 (64kB) chips with a
1749 - specified access time of 100ns and faster.
1752 -III GENERAL USE
1754 - Normally, the basic procedure for using this driver is as follows:
1756 - 1. Run the 3c90xcfg program on the driver diskette to enable the
1757 - boot PROM and set it to 64k or 128k, as appropriate.
1758 - 2. Build the appropriate 3c90x.fd0 or 3c90x.fd0 floppy image with
1759 - possibly the value CFG_3C90X_XCVR defined to the transceiver type that
1760 - you want to use (i.e., 10/100 rj45, AUI, coax, MII).
1761 - 3. Run the floppy image on the PC to be network booted, to get
1762 - it configured, and to verify that it will boot properly.
1763 - 4. Build the 3c90x.rom or 3c90x.lzrom PROM image and program
1764 - it into the flash or EPROM memory chip.
1765 - 5. Put the PROM in the ethernet card, boot and enable 'boot from
1766 - network first' in the system BIOS, save and reboot.
1768 - Here are some issues to be aware of:
1770 - 1. If you experience crashes or different behaviour when using the
1771 - boot PROM, add the setting CFG_3C90X_BOOTROM_FIX and go through the
1772 - steps 2-5 above. This works around a bug in some 3c905B cards (see
1773 - below), but has some side-effects which may not be desirable.
1774 - Please note that you have to boot off a floppy (not PROM!) once for
1775 - this fix to take effect.
1776 - 2. The possible need to manually set the CFG_3C90X_XCVR value to
1777 - configure the transceiver type. Values are listed below.
1778 - 3. The possible need to define CFG_3C90X_PRESERVE_XCVR for use in
1779 - operating systems that don't intelligently determine the
1780 - transceiver type.
1782 - Some things that are on the 'To-Do' list, perhaps for me, but perhaps
1783 - for any other volunteers out there:
1785 - 1. Extend the driver to fully implement the auto-select
1786 - algorithm if the card has multiple media ports.
1787 - 2. Fix any bugs in the code <grin>....
1788 - 3. Extend the driver to support the 3c905c revision cards
1789 - "officially". Right now, the support has been primarily empirical
1790 - and not based on 3c905C documentation.
1792 - Now for the details....
1794 - This driver has been tested on roughly 300 systems. The main two
1795 - configuration issues to contend with are:
1797 - 1. Ensure that PCI Busmastering is enabled for the adapter (configured
1798 - in the CMOS setup)
1799 - 2. Some systems don't work properly with the adapter when plug and
1800 - play OS is enabled; I always set it to "No" or "Disabled" -- this makes
1801 - it easier and really doesn't adversely affect anything.
1803 - Roughly 95% of the systems worked when configured properly. A few
1804 - have issues with booting locally once the boot PROM has been installed
1805 - (this number has been less than 2%). Other configuration issues that
1806 - to check:
1808 - 1. Newer BIOS's actually work correctly with the network boot order.
1809 - Set the network adapter first. Most older BIOS's automatically go to
1810 - the network boot PROM first.
1811 - 2. For systems where the adapter was already installed and is just
1812 - having the PROM installed, try setting the "reset configuration data"
1813 - to yes in the CMOS setup if the BIOS isn't seen at first. If your BIOS
1814 - doesn't have this option, remove the card, start the system, shut down,
1815 - install the card and restart (or switch to a different PCI slot).
1816 - 3. Make sure the CMOS security settings aren't preventing a boot.
1818 - The 3c905B cards have a significant 'bug' that relates to the flash prom:
1819 - unless the card is set internally to the MII transceiver, it will only
1820 - read the first 8k of the PROM image. Don't ask why -- it seems really
1821 - obscure, but it has to do with the way they mux'd the address lines
1822 - from the PCI bus to the ROM. Unfortunately, most of us are not using
1823 - MII transceivers, and even the .lzrom image ends up being just a little
1824 - bit larger than 8k. Note that the workaround for this is disabled by
1825 - default, because the Windows NT 4.0 driver does not like it (no packets
1826 - are transmitted).
1828 - So, the solution that I've used is to internally set the card's nvram
1829 - configuration to use MII when it boots. The 3c905b driver does this
1830 - automatically. This way, the 16k prom image can be loaded into memory,
1831 - and then the 3c905b driver can set the temporary configuration of the
1832 - card to an appropriate value, either configurable by the user or chosen
1833 - by the driver.
1835 - To enable the 3c905B bugfix, which is necessary for these cards when
1836 - booting from the Flash ROM, define -DCFG_3C90X_BOOTROM_FIX when building,
1837 - create a floppy image and boot it once.
1838 - Thereafter, the card should accept the larger prom image.
1840 - The driver should choose an appropriate transceiver on the card. However,
1841 - if it doesn't on your card or if you need to, for instance, set your
1842 - card to 10mbps when connected to an unmanaged 10/100 hub, you can specify
1843 - which transceiver you want to use. To do this, build the 3c905b.fd0
1844 - image with -DCFG_3C90X_XCVR=x, where 'x' is one of the following
1845 - values:
1847 - 0 10Base-T
1848 - 1 10mbps AUI
1849 - 3 10Base-2 (thinnet/coax)
1850 - 4 100Base-TX
1851 - 5 100Base-FX
1852 - 6 MII
1853 - 8 Auto-negotiation 10Base-T / 100Base-TX (usually the default)
1854 - 9 MII External MAC Mode
1855 - 255 Allow driver to choose an 'appropriate' media port.
1857 - Then proceed from step 2 in the above 'general use' instructions. The
1858 - .rom image can be built with CFG_3C90X_XCVR set to a value, but you
1859 - normally don't want to do this, since it is easier to change the
1860 - transceiver type by rebuilding a new floppy, changing the BIOS to floppy
1861 - boot, booting, and then changing the BIOS back to network boot. If
1862 - CFG_3C90X_XCVR is not set in a particular build, it just uses the
1863 - current configuration (either its 'best guess' or whatever the stored
1864 - CFG_3C90X_XCVR value was from the last time it was set).
1866 - [[ Note for the more technically inclined: The CFG_3C90X_XCVR value is
1867 - programmed into a register in the card's NVRAM that was reserved for
1868 - LanWorks PROM images to use. When the driver boots, the card comes
1869 - up in MII mode, and the driver checks the LanWorks register to find
1870 - out if the user specified a transceiver type. If it finds that
1871 - information, it uses that, otherwise it picks a transceiver that the
1872 - card has based on the 3c905b's MediaOptions register. This driver isn't
1873 - quite smart enough to always determine which media port is actually
1874 - _connected_; maybe someone else would like to take on that task (it
1875 - actually involves sending a self-directed packet and seeing if it
1876 - comes back. IF it does, that port is connected). ]]
1878 - Another issue to keep in mind is that it is possible that some OS'es
1879 - might not be happy with the way I've handled the PROM-image hack with
1880 - setting MII mode on bootup. Linux 2.0.35 does not have this problem.
1881 - Behavior of other systems may vary. The 3com documentation specifically
1882 - says that, at least with the card that I have, the device driver in the
1883 - OS should auto-select the media port, so other drivers should work fine
1884 - with this 'hack'. However, if yours doesn't seem to, you can try defining
1885 - CFG_3C90X_PRESERVE_XCVR when building to cause Etherboot to keep the
1886 - working setting (that allowed the bootp/tftp process) across the eth_reset
1887 - operation.
1890 -IV FOR DEVELOPERS....
1892 - If you would like to fix/extend/etc. this driver, feel free to do so; just
1893 - be sure you can test the modified version on the 3c905B-TX cards that the
1894 - driver was originally designed for. This section of this document gives
1895 - some information that might be relevant to a programmer.
1897 - A. Main Entry Point
1899 - a3c90x_probe is the main entry point for this driver. It is referred
1900 - to in an array in 'config.c'.
1902 - B. Other Important Functions
1904 - The functions a3c90x_transmit, a3c90x_poll, a3c90x_reset, and
1905 - a3c90x_disable are static functions that EtherBoot finds out about
1906 - as a result of a3c90x_probe setting entries in the nic structure
1907 - for them. The EtherBoot framework does not use interrupts. It is
1908 - polled. All transmit and receive operations are initiated by the
1909 - etherboot framework, not by an interrupt or by the driver.
1911 - C. Internal Functions
1913 - The following functions are internal to the driver:
1915 - a3c90x_internal_IssueCommand - sends a command to the 3c905b card.
1916 - a3c90x_internal_SetWindow - shifts between one of eight register
1917 - windows onboard the 3c90x. The bottom 16 bytes of the card's
1918 - I/O space are multiplexed among 128 bytes, only 16 of which are
1919 - visible at any one time. This SetWindow function selects one of
1920 - the eight sets.
1921 - a3c90x_internal_ReadEeprom - reads a word (16 bits) from the
1922 - card's onboard nvram. This is NOT the BIOS boot rom. This is
1923 - where the card stores such things as its hardware address.
1924 - a3c90x_internal_WriteEeprom - writes a word (16 bits) to the
1925 - card's nvram, and recomputes the eeprom checksum.
1926 - a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
1927 - card's nvram. Used by the above routine.
1928 - a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
1929 - card's nvram. Used by the above routine.
1931 - D. Globals
1933 - All global variables are inside a global structure named INF_3C90X.
1934 - So, wherever you see that structure referenced, you know the variable
1935 - is a global. Just keeps things a little neater.
1937 - E. Enumerations
1939 - There are quite a few enumerated type definitions for registers and
1940 - so forth, many for registers that I didn't even touch in the driver.
1941 - Register types start with 'reg', window numbers (for SetWindow)
1942 - start with 'win', and commands (for IssueCommand) start with 'cmd'.
1943 - Register offsets also include an indication in the name as to the
1944 - size of the register (_b = byte, _w = word, _l = long), and which
1945 - window the register is in, if it is windowed (0-7).
1947 - F. Why the 'a3c90x' name?
1949 - I had to come up with a letter at the beginning of all of the
1950 - identifiers, since 3com so conveniently had their name start with a
1951 - number. Another driver used 't' (for 'three'?); I chose 'a' for
1952 - no reason at all.
1954 -Addendum by Jorge L. deLyra <delyra@latt.if.usp.br>, 22Nov2000 re
1955 -working around the 3C905 hardware bug mentioned above:
1957 -Use this floppy to fix any 3COM model 3C905B PCI 10/100 Ethernet cards
1958 -that fail to load and run the boot program the first time around. If
1959 -they have a "Lucent" rather than a "Broadcom" chipset these cards have
1960 -a configuration bug that causes a hang when trying to load the boot
1961 -program from the PROM, if you try to use them right out of the box.
1963 -The boot program in this floppy is the file named 3c905b-tpo100.rom
1964 -from Etherboot version 4.6.10, compiled with the bugfix parameter
1966 - CFG_3C90X_BOOTROM_FIX
1968 -You have to take the chip off the card and boot the system once using
1969 -this floppy. Once loaded from the floppy, the boot program will access
1970 -the card and change some setting in it, correcting the problem. After
1971 -that you may use either this boot program or the normal one, compiled
1972 -without this bugfix parameter, to boot the machine from the PROM chip.
1974 -[Any recent Etherboot version should do, not just 4.6.10 - Ed.]
1975 Index: b/netboot/Makefile.am
1976 ===================================================================
1977 --- a/netboot/Makefile.am
1978 +++ b/netboot/Makefile.am
1979 @@ -10,58 +10,72 @@
1981 noinst_LIBRARIES = $(LIBDRIVERS)
1983 -libdrivers_a_SOURCES = cards.h config.c etherboot.h \
1984 - fsys_tftp.c linux-asm-io.h linux-asm-string.h \
1985 - main.c misc.c nic.h osdep.h pci.c pci.h timer.c timer.h
1986 -EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
1987 - cs89x0.c cs89x0.h davicom.c depca.c eepro.c eepro100.c \
1988 - epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
1989 - ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
1990 - sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
1991 - tiara.c tlan.c tulip.c via-rhine.c w89c840.c
1992 +libdrivers_a_SOURCES = big_bswap.h bootp.h byteswap.h config.c cpu.h \
1993 + dev.h elf.h endian.h etherboot.h fsys_tftp.c grub.h \
1994 + i386_byteswap.h i386_elf.h i386_endian.h i386_timer.c \
1995 + if_arp.h if_ether.h igmp.h in.h io.h ip.h isa.h latch.h \
1996 + little_bswap.h misc.c nic.c nic.h osdep.h pci.c pci.h \
1997 + pci_ids.h pci_io.c stdint.h tftp.h timer.c timer.h \
1998 + types.h udp.h mii.h pic8259.c pic8259.h pxe.h basemem.c segoff.h
1999 +EXTRA_libdrivers_a_SOURCES = 3c595.c 3c595.h 3c90x.c davicom.c \
2000 + e1000.c e1000_hw.h eepro100.c epic100.c epic100.h natsemi.c \
2001 + ns8390.c ns8390.h pcnet32.c rtl8139.c sis900.c sis900.h \
2002 + sundance.c tg3.c tg3.h tlan.c tlan.h tulip.c via-rhine.c \
2003 + w89c840.c r8169.c forcedeth.c ns83820.c pnic.c pnic_api.c \
2004 + undi.c undi.h
2005 libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2006 -DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
2007 # Filled by configure.
2008 libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
2009 libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
2011 -EXTRA_DIST = README.netboot 3c90x.txt cs89x0.txt sis900.txt tulip.txt
2012 +EXTRA_DIST = README.netboot
2014 # These below are several special rules for the device drivers.
2015 # We cannot use a simple rule for them...
2017 # What objects are derived from a driver?
2018 -3c509_drivers = 3c509.o 3c529.o
2019 +#3c509_drivers = 3c509.o 3c529.o
2020 3c595_drivers = 3c595.o
2021 3c90x_drivers = 3c90x.o
2022 -cs89x0_drivers = cs89x0.o
2023 +#cs89x0_drivers = cs89x0.o
2024 davicom_drivers = davicom.o
2025 -depca_drivers = depca.o
2026 -eepro_drivers = eepro.o
2027 +#depca_drivers = depca.o
2028 +#eepro_drivers = eepro.o
2029 +e1000_drivers = e1000.o
2030 eepro100_drivers = eepro100.o
2031 epic100_drivers = epic100.o
2032 #fa311_drivers = fa311.o
2033 -i82586_drivers = 3c507.o exos205.o ni5210.o
2034 -lance_drivers = lance.o ne2100.o ni6510.o
2035 +forcedeth_drivers = forcedeth.o
2036 +#i82586_drivers = 3c507.o exos205.o ni5210.o
2037 +#lance_drivers = lance.o ne2100.o ni6510.o
2038 natsemi_drivers = natsemi.o
2039 -ni5010_drivers = ni5010.o
2040 +#ni5010_drivers = ni5010.o
2041 +ns83820_drivers = ns83820.o
2042 ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
2043 -otulip_drivers = otulip.o
2044 +#otulip_drivers = otulip.o
2045 +pcnet32_drivers = pcnet32.o
2046 +pnic_drivers = pnic.o
2047 +r8169_drivers = r8169.o
2048 rtl8139_drivers = rtl8139.o
2049 sis900_drivers = sis900.o
2050 -sk_g16_drivers = sk_g16.o
2051 -smc9000_drivers = smc9000.o
2052 -tiara_drivers = tiara.o
2053 -#tlan_drivers = tlan.o
2054 +#sk_g16_drivers = sk_g16.o
2055 +sundance_driver = sundance.o
2056 +#smc9000_drivers = smc9000.o
2057 +tg3_drivers = tg3.o
2058 +#tiara_drivers = tiara.o
2059 +tlan_drivers = tlan.o
2060 tulip_drivers = tulip.o
2061 +undi_drivers = undi.o
2062 via_rhine_drivers = via_rhine.o
2063 w89c840_drivers = w89c840.o
2066 # Is it really necessary to specify dependecies explicitly?
2067 -$(3c509_drivers): 3c509.c 3c509.h
2068 -$(3c509_drivers): %.o: 3c509.c
2069 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2070 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2071 +#$(3c509_drivers): 3c509.c 3c509.h
2072 +#$(3c509_drivers): %.o: 3c509.c
2073 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2074 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2076 $(3c595_drivers): 3c595.c 3c595.h
2077 $(3c595_drivers): %.o: 3c595.c
2078 @@ -73,23 +87,28 @@
2079 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2080 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2082 -$(cs89x0_drivers): cs89x0.c cs89x0.h
2083 -$(cs89x0_drivers): %.o: cs89x0.c
2084 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2085 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2086 +#$(cs89x0_drivers): cs89x0.c cs89x0.h
2087 +#$(cs89x0_drivers): %.o: cs89x0.c
2088 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2089 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2091 $(davicom_drivers): davicom.c
2092 $(davicom_drivers): %.o: davicom.c
2093 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2094 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2096 -$(depca_drivers): depca.c
2097 -$(depca_drivers): %.o: depca.c
2098 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2099 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2100 +#$(depca_drivers): depca.c
2101 +#$(depca_drivers): %.o: depca.c
2102 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2103 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2105 +#$(eepro_drivers): eepro.c
2106 +#$(eepro_drivers): %.o: eepro.c
2107 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2108 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2110 -$(eepro_drivers): eepro.c
2111 -$(eepro_drivers): %.o: eepro.c
2112 +$(e1000_drivers): e1000.c e1000_hw.h
2113 +$(e1000_drivers): %.o: e1000.c
2114 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2115 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2117 @@ -103,28 +122,38 @@
2118 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2119 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2121 +$(forcedeth_drivers): forcedeth.c
2122 +$(forcedeth_drivers): %.o: forcedeth.c
2123 + $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2124 + $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2126 #$(fa311_drivers): fa311.c
2127 #$(fa311_drivers): %.o: fa311.c
2128 # $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2129 # $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2131 -$(i82586_drivers): i82586.c
2132 -$(i82586_drivers): %.o: i82586.c
2133 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2134 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2135 +#$(i82586_drivers): i82586.c
2136 +#$(i82586_drivers): %.o: i82586.c
2137 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2138 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2140 -$(lance_drivers): lance.c
2141 -$(lance_drivers): %.o: lance.c
2142 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2143 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2144 +#$(lance_drivers): lance.c
2145 +#$(lance_drivers): %.o: lance.c
2146 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2147 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2149 $(natsemi_drivers): natsemi.c
2150 $(natsemi_drivers): %.o: natsemi.c
2151 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2152 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2154 -$(ni5010_drivers): ni5010.c
2155 -$(ni5010_drivers): %.o: ni5010.c
2156 +#$(ni5010_drivers): ni5010.c
2157 +#$(ni5010_drivers): %.o: ni5010.c
2158 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2159 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2161 +$(ns83820_drivers): ns83820.c
2162 +$(ns83820_drivers): %.o: ns83820.c
2163 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2164 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2166 @@ -133,8 +162,18 @@
2167 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2168 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2170 -$(otulip_drivers): otulip.c otulip.h
2171 -$(otulip_drivers): %.o: otulip.c
2172 +#$(otulip_drivers): otulip.c otulip.h
2173 +#$(otulip_drivers): %.o: otulip.c
2174 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2175 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2177 +$(pcnet32_drivers): pcnet32.c
2178 +$(pcnet32_drivers): %.o: pcnet32.c
2179 + $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2180 + $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2182 +$(pnic_drivers): pnic.c
2183 +$(pnic_drivers): %.o: pnic.c pnic_api.h
2184 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2185 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2187 @@ -143,36 +182,56 @@
2188 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2189 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2191 -$(sis900_drivers): sis900.c
2192 -$(sis900_drivers): %.o: sis900.c sis900.h
2193 +$(r8169_drivers): r8169.c
2194 +$(r8169_drivers): %.o: r8169.c
2195 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2196 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2198 -$(sk_g16_drivers): sk_g16.c sk_g16.h
2199 -$(sk_g16_drivers): %.o: sk_g16.c
2200 +$(sis900_drivers): sis900.c sis900.h
2201 +$(sis900_drivers): %.o: sis900.c
2202 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2203 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2205 -$(smc9000_drivers): smc9000.c smc9000.h
2206 -$(smc9000_drivers): %.o: smc9000.c
2207 +#$(sk_g16_drivers): sk_g16.c sk_g16.h
2208 +#$(sk_g16_drivers): %.o: sk_g16.c
2209 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2210 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2212 +#$(smc9000_drivers): smc9000.c smc9000.h
2213 +#$(smc9000_drivers): %.o: smc9000.c
2214 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2215 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2217 +$(sundance_drivers): sundance.c
2218 +$(sundance_drivers): %.o: sundance.c
2219 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2220 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2222 -$(tiara_drivers): tiara.c
2223 -$(tiara_drivers): %.o: tiara.c
2224 +$(tg3_drivers): tg3.c tg3.h
2225 +$(tg3_drivers): %.o: tg3.c
2226 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2227 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2229 -#$(tlan_drivers): tlan.c
2230 -#$(tlan_drivers): %.o: tlan.c
2231 +#$(tiara_drivers): tiara.c
2232 +#$(tiara_drivers): %.o: tiara.c
2233 # $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2234 # $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2236 +$(tlan_drivers): tlan.c tlan.h
2237 +$(tlan_drivers): %.o: tlan.c
2238 + $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2239 + $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2241 $(tulip_drivers): tulip.c
2242 $(tulip_drivers): %.o: tulip.c
2243 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2244 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2246 +$(undi_drivers): undi.c undi.h
2247 +$(undi_drivers): %.o: undi.c
2248 + $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2249 + $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2251 $(via_rhine_drivers): via-rhine.c
2252 $(via_rhine_drivers): %.o: via-rhine.c
2253 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2254 @@ -184,36 +243,45 @@
2255 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
2257 # Per-object flags.
2258 -3c509_o_CFLAGS = -DINCLUDE_3C509=1
2259 -3c529_o_CFLAGS = -DINCLUDE_3C529=1
2260 +#3c509_o_CFLAGS = -DINCLUDE_3C509=1
2261 +#3c529_o_CFLAGS = -DINCLUDE_3C529=1
2262 3c595_o_CFLAGS = -DINCLUDE_3C595=1
2263 3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
2264 -cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
2265 +#cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
2266 davicom_o_CFLAGS = -DINCLUDE_DAVICOM=1
2267 -depca_o_CFLAGS = -DINCLUDE_DEPCA=1
2268 -eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
2269 +#depca_o_CFLAGS = -DINCLUDE_DEPCA=1
2270 +#eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
2271 +e1000_o_CFLAGS = -DINCLUDE_E1000=1
2272 eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
2273 epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
2274 #fa311_o_CFLAGS = -DINCLUDE_FA311=1
2275 -3c507_o_CFLAGS = -DINCLUDE_3C507=1
2276 -exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
2277 -ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
2278 -lance_o_CFLAGS = -DINCLUDE_LANCE=1
2279 -ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
2280 -ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
2281 +forcedeth_o_CFLAGS = -DINCLUDE_FORCEDETH=1
2282 +#3c507_o_CFLAGS = -DINCLUDE_3C507=1
2283 +#exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
2284 +#ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
2285 +#lance_o_CFLAGS = -DINCLUDE_LANCE=1
2286 +#ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
2287 +#ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
2288 natsemi_o_CFLAGS = -DINCLUDE_NATSEMI=1
2289 -ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
2290 -3c503_o_CFLAGS = -DINCLUDE_3C503=1
2291 -ne_o_CFLAGS = -DINCLUDE_NE=1
2292 +#ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
2293 +#3c503_o_CFLAGS = -DINCLUDE_3C503=1
2294 +#ne_o_CFLAGS = -DINCLUDE_NE=1
2295 +ns83820_o_CFLAGS = -DINCLUDE_NS83820=1
2296 ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
2297 -wd_o_CFLAGS = -DINCLUDE_WD=1
2298 -otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
2299 +#wd_o_CFLAGS = -DINCLUDE_WD=1
2300 +#otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
2301 +pcnet32_o_CFLAGS = -DINCLUDE_PCNET32=1
2302 +pnic_o_CFLAGS = -DINCLUDE_PNIC=1
2303 +r8169_o_CFLAGS = -DINCLUDE_R8169=1
2304 rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
2305 sis900_o_CFLAGS = -DINCLUDE_SIS900=1
2306 -sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
2307 -smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
2308 -tiara_o_CFLAGS = -DINCLUDE_TIARA=1
2309 -#tlan_o_CFLAGS = -DINCLUDE_TLAN=1
2310 +#sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
2311 +#smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
2312 +sundance_o_CFLAGS = -DINCLUDE_SUNDANCE=1
2313 +#tiara_o_CFLAGS = -DINCLUDE_TIARA=1
2314 +tg3_o_CFLAGS = -DINCLUDE_TG3=1
2315 +tlan_o_CFLAGS = -DINCLUDE_TLAN=1
2316 tulip_o_CFLAGS = -DINCLUDE_TULIP=1
2317 +undi_o_CFLAGS = -DINCLUDE_UNDI=1
2318 via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
2319 w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
2320 Index: b/netboot/Makefile.in
2321 ===================================================================
2322 --- a/netboot/Makefile.in
2323 +++ b/netboot/Makefile.in
2324 @@ -46,18 +46,51 @@
2325 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
2326 CONFIG_HEADER = $(top_builddir)/config.h
2327 CONFIG_CLEAN_FILES =
2328 -LIBRARIES = $(noinst_LIBRARIES)
2329 AR = ar
2330 ARFLAGS = cru
2331 +LIBRARIES = $(noinst_LIBRARIES)
2332 libdrivers_a_AR = $(AR) $(ARFLAGS)
2333 am_libdrivers_a_OBJECTS = libdrivers_a-config.$(OBJEXT) \
2334 - libdrivers_a-fsys_tftp.$(OBJEXT) libdrivers_a-main.$(OBJEXT) \
2335 - libdrivers_a-misc.$(OBJEXT) libdrivers_a-pci.$(OBJEXT) \
2336 - libdrivers_a-timer.$(OBJEXT)
2337 + libdrivers_a-fsys_tftp.$(OBJEXT) \
2338 + libdrivers_a-i386_timer.$(OBJEXT) libdrivers_a-misc.$(OBJEXT) \
2339 + libdrivers_a-nic.$(OBJEXT) libdrivers_a-pci.$(OBJEXT) \
2340 + libdrivers_a-pci_io.$(OBJEXT) libdrivers_a-timer.$(OBJEXT) \
2341 + libdrivers_a-pic8259.$(OBJEXT) libdrivers_a-basemem.$(OBJEXT)
2342 libdrivers_a_OBJECTS = $(am_libdrivers_a_OBJECTS)
2343 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
2344 depcomp = $(SHELL) $(top_srcdir)/depcomp
2345 am__depfiles_maybe = depfiles
2346 +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/libdrivers_a-3c595.Po \
2347 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-3c90x.Po \
2348 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-basemem.Po \
2349 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-config.Po \
2350 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-davicom.Po \
2351 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-e1000.Po \
2352 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-eepro100.Po \
2353 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-epic100.Po \
2354 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-forcedeth.Po \
2355 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-fsys_tftp.Po \
2356 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-i386_timer.Po \
2357 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-misc.Po \
2358 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-natsemi.Po \
2359 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-nic.Po \
2360 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-ns83820.Po \
2361 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-ns8390.Po \
2362 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-pci.Po \
2363 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-pci_io.Po \
2364 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-pcnet32.Po \
2365 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-pic8259.Po \
2366 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-pnic.Po \
2367 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-pnic_api.Po \
2368 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-r8169.Po \
2369 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-rtl8139.Po \
2370 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-sis900.Po \
2371 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-tg3.Po \
2372 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-timer.Po \
2373 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-tlan.Po \
2374 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-tulip.Po \
2375 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-via-rhine.Po \
2376 +@AMDEP_TRUE@ ./$(DEPDIR)/libdrivers_a-w89c840.Po
2377 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
2378 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
2379 CCLD = $(CC)
2380 @@ -148,8 +181,6 @@
2381 am__include = @am__include@
2382 am__leading_dot = @am__leading_dot@
2383 am__quote = @am__quote@
2384 -am__tar = @am__tar@
2385 -am__untar = @am__untar@
2386 bindir = @bindir@
2387 build = @build@
2388 build_alias = @build_alias@
2389 @@ -186,16 +217,19 @@
2390 # Don't build the netboot support by default.
2391 @NETBOOT_SUPPORT_TRUE@LIBDRIVERS = libdrivers.a
2392 noinst_LIBRARIES = $(LIBDRIVERS)
2393 -libdrivers_a_SOURCES = cards.h config.c etherboot.h \
2394 - fsys_tftp.c linux-asm-io.h linux-asm-string.h \
2395 - main.c misc.c nic.h osdep.h pci.c pci.h timer.c timer.h
2397 -EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
2398 - cs89x0.c cs89x0.h davicom.c depca.c eepro.c eepro100.c \
2399 - epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
2400 - ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
2401 - sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
2402 - tiara.c tlan.c tulip.c via-rhine.c w89c840.c
2403 +libdrivers_a_SOURCES = big_bswap.h bootp.h byteswap.h config.c cpu.h \
2404 + dev.h elf.h endian.h etherboot.h fsys_tftp.c grub.h \
2405 + i386_byteswap.h i386_elf.h i386_endian.h i386_timer.c \
2406 + if_arp.h if_ether.h igmp.h in.h io.h ip.h isa.h latch.h \
2407 + little_bswap.h misc.c nic.c nic.h osdep.h pci.c pci.h \
2408 + pci_ids.h pci_io.c stdint.h tftp.h timer.c timer.h \
2409 + types.h udp.h mii.h pic8259.c pic8259.h pxe.h basemem.c segoff.h
2411 +EXTRA_libdrivers_a_SOURCES = 3c595.c 3c595.h 3c90x.c davicom.c \
2412 + e1000.c e1000_hw.h eepro100.c epic100.c epic100.h natsemi.c \
2413 + ns8390.c ns8390.h pcnet32.c rtl8139.c sis900.c sis900.h \
2414 + tg3.c tg3.h tlan.c tlan.h tulip.c via-rhine.c \
2415 + w89c840.c r8169.c forcedeth.c ns83820.c pnic.c pnic_api.c
2417 libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
2418 -DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
2419 @@ -203,69 +237,83 @@
2420 # Filled by configure.
2421 libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
2422 libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
2423 -EXTRA_DIST = README.netboot 3c90x.txt cs89x0.txt sis900.txt tulip.txt
2424 +EXTRA_DIST = README.netboot
2426 # These below are several special rules for the device drivers.
2427 # We cannot use a simple rule for them...
2429 # What objects are derived from a driver?
2430 -3c509_drivers = 3c509.o 3c529.o
2431 +#3c509_drivers = 3c509.o 3c529.o
2432 3c595_drivers = 3c595.o
2433 3c90x_drivers = 3c90x.o
2434 -cs89x0_drivers = cs89x0.o
2435 +#cs89x0_drivers = cs89x0.o
2436 davicom_drivers = davicom.o
2437 -depca_drivers = depca.o
2438 -eepro_drivers = eepro.o
2439 +#depca_drivers = depca.o
2440 +#eepro_drivers = eepro.o
2441 +e1000_drivers = e1000.o
2442 eepro100_drivers = eepro100.o
2443 epic100_drivers = epic100.o
2444 #fa311_drivers = fa311.o
2445 -i82586_drivers = 3c507.o exos205.o ni5210.o
2446 -lance_drivers = lance.o ne2100.o ni6510.o
2447 +forcedeth_drivers = forcedeth.o
2448 +#i82586_drivers = 3c507.o exos205.o ni5210.o
2449 +#lance_drivers = lance.o ne2100.o ni6510.o
2450 natsemi_drivers = natsemi.o
2451 -ni5010_drivers = ni5010.o
2452 +#ni5010_drivers = ni5010.o
2453 +ns83820_drivers = ns83820.o
2454 ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
2455 -otulip_drivers = otulip.o
2456 +#otulip_drivers = otulip.o
2457 +pcnet32_drivers = pcnet32.o
2458 +pnic_drivers = pnic.o
2459 +r8169_drivers = r8169.o
2460 rtl8139_drivers = rtl8139.o
2461 sis900_drivers = sis900.o
2462 -sk_g16_drivers = sk_g16.o
2463 -smc9000_drivers = smc9000.o
2464 -tiara_drivers = tiara.o
2465 -#tlan_drivers = tlan.o
2466 +#sk_g16_drivers = sk_g16.o
2467 +#smc9000_drivers = smc9000.o
2468 +tg3_drivers = tg3.o
2469 +#tiara_drivers = tiara.o
2470 +tlan_drivers = tlan.o
2471 tulip_drivers = tulip.o
2472 via_rhine_drivers = via_rhine.o
2473 w89c840_drivers = w89c840.o
2475 # Per-object flags.
2476 -3c509_o_CFLAGS = -DINCLUDE_3C509=1
2477 -3c529_o_CFLAGS = -DINCLUDE_3C529=1
2478 +#3c509_o_CFLAGS = -DINCLUDE_3C509=1
2479 +#3c529_o_CFLAGS = -DINCLUDE_3C529=1
2480 3c595_o_CFLAGS = -DINCLUDE_3C595=1
2481 3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
2482 -cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
2483 +#cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
2484 davicom_o_CFLAGS = -DINCLUDE_DAVICOM=1
2485 -depca_o_CFLAGS = -DINCLUDE_DEPCA=1
2486 -eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
2487 +#depca_o_CFLAGS = -DINCLUDE_DEPCA=1
2488 +#eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
2489 +e1000_o_CFLAGS = -DINCLUDE_E1000=1
2490 eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
2491 epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
2492 #fa311_o_CFLAGS = -DINCLUDE_FA311=1
2493 -3c507_o_CFLAGS = -DINCLUDE_3C507=1
2494 -exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
2495 -ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
2496 -lance_o_CFLAGS = -DINCLUDE_LANCE=1
2497 -ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
2498 -ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
2499 +forcedeth_o_CFLAGS = -DINCLUDE_FORCEDETH=1
2500 +#3c507_o_CFLAGS = -DINCLUDE_3C507=1
2501 +#exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
2502 +#ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
2503 +#lance_o_CFLAGS = -DINCLUDE_LANCE=1
2504 +#ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
2505 +#ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
2506 natsemi_o_CFLAGS = -DINCLUDE_NATSEMI=1
2507 -ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
2508 -3c503_o_CFLAGS = -DINCLUDE_3C503=1
2509 -ne_o_CFLAGS = -DINCLUDE_NE=1
2510 +#ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
2511 +#3c503_o_CFLAGS = -DINCLUDE_3C503=1
2512 +#ne_o_CFLAGS = -DINCLUDE_NE=1
2513 +ns83820_o_CFLAGS = -DINCLUDE_NS83820=1
2514 ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
2515 -wd_o_CFLAGS = -DINCLUDE_WD=1
2516 -otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
2517 +#wd_o_CFLAGS = -DINCLUDE_WD=1
2518 +#otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
2519 +pcnet32_o_CFLAGS = -DINCLUDE_PCNET32=1
2520 +pnic_o_CFLAGS = -DINCLUDE_PNIC=1
2521 +r8169_o_CFLAGS = -DINCLUDE_R8169=1
2522 rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
2523 sis900_o_CFLAGS = -DINCLUDE_SIS900=1
2524 -sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
2525 -smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
2526 -tiara_o_CFLAGS = -DINCLUDE_TIARA=1
2527 -#tlan_o_CFLAGS = -DINCLUDE_TLAN=1
2528 +#sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
2529 +#smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
2530 +#tiara_o_CFLAGS = -DINCLUDE_TIARA=1
2531 +tg3_o_CFLAGS = -DINCLUDE_TG3=1
2532 +tlan_o_CFLAGS = -DINCLUDE_TLAN=1
2533 tulip_o_CFLAGS = -DINCLUDE_TULIP=1
2534 via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
2535 w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
2536 @@ -316,32 +364,32 @@
2537 distclean-compile:
2538 -rm -f *.tab.c
2540 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c509.Po@am__quote@
2541 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c595.Po@am__quote@
2542 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c90x.Po@am__quote@
2543 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-basemem.Po@am__quote@
2544 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-config.Po@am__quote@
2545 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-cs89x0.Po@am__quote@
2546 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-davicom.Po@am__quote@
2547 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-depca.Po@am__quote@
2548 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-eepro.Po@am__quote@
2549 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-e1000.Po@am__quote@
2550 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-eepro100.Po@am__quote@
2551 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-epic100.Po@am__quote@
2552 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-fa311.Po@am__quote@
2553 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-forcedeth.Po@am__quote@
2554 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-fsys_tftp.Po@am__quote@
2555 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-i82586.Po@am__quote@
2556 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-lance.Po@am__quote@
2557 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-main.Po@am__quote@
2558 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-i386_timer.Po@am__quote@
2559 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-misc.Po@am__quote@
2560 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-natsemi.Po@am__quote@
2561 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-ni5010.Po@am__quote@
2562 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-nic.Po@am__quote@
2563 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-ns83820.Po@am__quote@
2564 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-ns8390.Po@am__quote@
2565 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-otulip.Po@am__quote@
2566 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pci.Po@am__quote@
2567 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pci_io.Po@am__quote@
2568 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pcnet32.Po@am__quote@
2569 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pic8259.Po@am__quote@
2570 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pnic.Po@am__quote@
2571 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pnic_api.Po@am__quote@
2572 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-r8169.Po@am__quote@
2573 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-rtl8139.Po@am__quote@
2574 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-sis900.Po@am__quote@
2575 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-sk_g16.Po@am__quote@
2576 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-smc9000.Po@am__quote@
2577 -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tiara.Po@am__quote@
2578 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tg3.Po@am__quote@
2579 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-timer.Po@am__quote@
2580 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tlan.Po@am__quote@
2581 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tulip.Po@am__quote@
2582 @@ -352,450 +400,513 @@
2583 @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
2584 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
2585 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
2586 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2587 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
2588 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2589 @am__fastdepCC_FALSE@ $(COMPILE) -c $<
2591 .c.obj:
2592 @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
2593 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
2594 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
2595 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2596 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
2597 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2598 @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
2600 libdrivers_a-config.o: config.c
2601 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-config.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-config.Tpo" -c -o libdrivers_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c; \
2602 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-config.Tpo" "$(DEPDIR)/libdrivers_a-config.Po"; else rm -f "$(DEPDIR)/libdrivers_a-config.Tpo"; exit 1; fi
2603 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config.c' object='libdrivers_a-config.o' libtool=no @AMDEPBACKSLASH@
2604 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2605 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-config.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-config.TPo' @AMDEPBACKSLASH@
2606 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2607 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
2609 libdrivers_a-config.obj: config.c
2610 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-config.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-config.Tpo" -c -o libdrivers_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`; \
2611 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-config.Tpo" "$(DEPDIR)/libdrivers_a-config.Po"; else rm -f "$(DEPDIR)/libdrivers_a-config.Tpo"; exit 1; fi
2612 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config.c' object='libdrivers_a-config.obj' libtool=no @AMDEPBACKSLASH@
2613 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2614 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-config.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-config.TPo' @AMDEPBACKSLASH@
2615 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2616 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
2618 libdrivers_a-fsys_tftp.o: fsys_tftp.c
2619 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fsys_tftp.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" -c -o libdrivers_a-fsys_tftp.o `test -f 'fsys_tftp.c' || echo '$(srcdir)/'`fsys_tftp.c; \
2620 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" "$(DEPDIR)/libdrivers_a-fsys_tftp.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo"; exit 1; fi
2621 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fsys_tftp.c' object='libdrivers_a-fsys_tftp.o' libtool=no @AMDEPBACKSLASH@
2622 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2623 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-fsys_tftp.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-fsys_tftp.TPo' @AMDEPBACKSLASH@
2624 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2625 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fsys_tftp.o `test -f 'fsys_tftp.c' || echo '$(srcdir)/'`fsys_tftp.c
2627 libdrivers_a-fsys_tftp.obj: fsys_tftp.c
2628 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fsys_tftp.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" -c -o libdrivers_a-fsys_tftp.obj `if test -f 'fsys_tftp.c'; then $(CYGPATH_W) 'fsys_tftp.c'; else $(CYGPATH_W) '$(srcdir)/fsys_tftp.c'; fi`; \
2629 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" "$(DEPDIR)/libdrivers_a-fsys_tftp.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo"; exit 1; fi
2630 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fsys_tftp.c' object='libdrivers_a-fsys_tftp.obj' libtool=no @AMDEPBACKSLASH@
2631 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2632 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-fsys_tftp.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-fsys_tftp.TPo' @AMDEPBACKSLASH@
2633 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2634 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fsys_tftp.obj `if test -f 'fsys_tftp.c'; then $(CYGPATH_W) 'fsys_tftp.c'; else $(CYGPATH_W) '$(srcdir)/fsys_tftp.c'; fi`
2636 -libdrivers_a-main.o: main.c
2637 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-main.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-main.Tpo" -c -o libdrivers_a-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c; \
2638 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-main.Tpo" "$(DEPDIR)/libdrivers_a-main.Po"; else rm -f "$(DEPDIR)/libdrivers_a-main.Tpo"; exit 1; fi
2639 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='libdrivers_a-main.o' libtool=no @AMDEPBACKSLASH@
2640 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2641 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
2643 -libdrivers_a-main.obj: main.c
2644 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-main.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-main.Tpo" -c -o libdrivers_a-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`; \
2645 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-main.Tpo" "$(DEPDIR)/libdrivers_a-main.Po"; else rm -f "$(DEPDIR)/libdrivers_a-main.Tpo"; exit 1; fi
2646 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='main.c' object='libdrivers_a-main.obj' libtool=no @AMDEPBACKSLASH@
2647 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2648 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
2649 +libdrivers_a-i386_timer.o: i386_timer.c
2650 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-i386_timer.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-i386_timer.Tpo" -c -o libdrivers_a-i386_timer.o `test -f 'i386_timer.c' || echo '$(srcdir)/'`i386_timer.c; \
2651 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-i386_timer.Tpo" "$(DEPDIR)/libdrivers_a-i386_timer.Po"; else rm -f "$(DEPDIR)/libdrivers_a-i386_timer.Tpo"; exit 1; fi
2652 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i386_timer.c' object='libdrivers_a-i386_timer.o' libtool=no @AMDEPBACKSLASH@
2653 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-i386_timer.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-i386_timer.TPo' @AMDEPBACKSLASH@
2654 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2655 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-i386_timer.o `test -f 'i386_timer.c' || echo '$(srcdir)/'`i386_timer.c
2657 +libdrivers_a-i386_timer.obj: i386_timer.c
2658 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-i386_timer.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-i386_timer.Tpo" -c -o libdrivers_a-i386_timer.obj `if test -f 'i386_timer.c'; then $(CYGPATH_W) 'i386_timer.c'; else $(CYGPATH_W) '$(srcdir)/i386_timer.c'; fi`; \
2659 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-i386_timer.Tpo" "$(DEPDIR)/libdrivers_a-i386_timer.Po"; else rm -f "$(DEPDIR)/libdrivers_a-i386_timer.Tpo"; exit 1; fi
2660 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i386_timer.c' object='libdrivers_a-i386_timer.obj' libtool=no @AMDEPBACKSLASH@
2661 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-i386_timer.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-i386_timer.TPo' @AMDEPBACKSLASH@
2662 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2663 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-i386_timer.obj `if test -f 'i386_timer.c'; then $(CYGPATH_W) 'i386_timer.c'; else $(CYGPATH_W) '$(srcdir)/i386_timer.c'; fi`
2665 libdrivers_a-misc.o: misc.c
2666 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-misc.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-misc.Tpo" -c -o libdrivers_a-misc.o `test -f 'misc.c' || echo '$(srcdir)/'`misc.c; \
2667 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-misc.Tpo" "$(DEPDIR)/libdrivers_a-misc.Po"; else rm -f "$(DEPDIR)/libdrivers_a-misc.Tpo"; exit 1; fi
2668 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc.c' object='libdrivers_a-misc.o' libtool=no @AMDEPBACKSLASH@
2669 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2670 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-misc.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-misc.TPo' @AMDEPBACKSLASH@
2671 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2672 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-misc.o `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
2674 libdrivers_a-misc.obj: misc.c
2675 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-misc.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-misc.Tpo" -c -o libdrivers_a-misc.obj `if test -f 'misc.c'; then $(CYGPATH_W) 'misc.c'; else $(CYGPATH_W) '$(srcdir)/misc.c'; fi`; \
2676 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-misc.Tpo" "$(DEPDIR)/libdrivers_a-misc.Po"; else rm -f "$(DEPDIR)/libdrivers_a-misc.Tpo"; exit 1; fi
2677 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc.c' object='libdrivers_a-misc.obj' libtool=no @AMDEPBACKSLASH@
2678 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2679 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-misc.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-misc.TPo' @AMDEPBACKSLASH@
2680 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2681 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-misc.obj `if test -f 'misc.c'; then $(CYGPATH_W) 'misc.c'; else $(CYGPATH_W) '$(srcdir)/misc.c'; fi`
2683 +libdrivers_a-nic.o: nic.c
2684 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-nic.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-nic.Tpo" -c -o libdrivers_a-nic.o `test -f 'nic.c' || echo '$(srcdir)/'`nic.c; \
2685 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-nic.Tpo" "$(DEPDIR)/libdrivers_a-nic.Po"; else rm -f "$(DEPDIR)/libdrivers_a-nic.Tpo"; exit 1; fi
2686 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic.c' object='libdrivers_a-nic.o' libtool=no @AMDEPBACKSLASH@
2687 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-nic.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-nic.TPo' @AMDEPBACKSLASH@
2688 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2689 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-nic.o `test -f 'nic.c' || echo '$(srcdir)/'`nic.c
2691 +libdrivers_a-nic.obj: nic.c
2692 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-nic.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-nic.Tpo" -c -o libdrivers_a-nic.obj `if test -f 'nic.c'; then $(CYGPATH_W) 'nic.c'; else $(CYGPATH_W) '$(srcdir)/nic.c'; fi`; \
2693 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-nic.Tpo" "$(DEPDIR)/libdrivers_a-nic.Po"; else rm -f "$(DEPDIR)/libdrivers_a-nic.Tpo"; exit 1; fi
2694 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nic.c' object='libdrivers_a-nic.obj' libtool=no @AMDEPBACKSLASH@
2695 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-nic.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-nic.TPo' @AMDEPBACKSLASH@
2696 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2697 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-nic.obj `if test -f 'nic.c'; then $(CYGPATH_W) 'nic.c'; else $(CYGPATH_W) '$(srcdir)/nic.c'; fi`
2699 libdrivers_a-pci.o: pci.c
2700 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pci.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pci.Tpo" -c -o libdrivers_a-pci.o `test -f 'pci.c' || echo '$(srcdir)/'`pci.c; \
2701 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pci.Tpo" "$(DEPDIR)/libdrivers_a-pci.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pci.Tpo"; exit 1; fi
2702 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pci.c' object='libdrivers_a-pci.o' libtool=no @AMDEPBACKSLASH@
2703 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2704 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pci.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pci.TPo' @AMDEPBACKSLASH@
2705 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2706 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pci.o `test -f 'pci.c' || echo '$(srcdir)/'`pci.c
2708 libdrivers_a-pci.obj: pci.c
2709 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pci.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pci.Tpo" -c -o libdrivers_a-pci.obj `if test -f 'pci.c'; then $(CYGPATH_W) 'pci.c'; else $(CYGPATH_W) '$(srcdir)/pci.c'; fi`; \
2710 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pci.Tpo" "$(DEPDIR)/libdrivers_a-pci.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pci.Tpo"; exit 1; fi
2711 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pci.c' object='libdrivers_a-pci.obj' libtool=no @AMDEPBACKSLASH@
2712 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2713 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pci.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pci.TPo' @AMDEPBACKSLASH@
2714 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2715 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pci.obj `if test -f 'pci.c'; then $(CYGPATH_W) 'pci.c'; else $(CYGPATH_W) '$(srcdir)/pci.c'; fi`
2717 +libdrivers_a-pci_io.o: pci_io.c
2718 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pci_io.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pci_io.Tpo" -c -o libdrivers_a-pci_io.o `test -f 'pci_io.c' || echo '$(srcdir)/'`pci_io.c; \
2719 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pci_io.Tpo" "$(DEPDIR)/libdrivers_a-pci_io.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pci_io.Tpo"; exit 1; fi
2720 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pci_io.c' object='libdrivers_a-pci_io.o' libtool=no @AMDEPBACKSLASH@
2721 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pci_io.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pci_io.TPo' @AMDEPBACKSLASH@
2722 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2723 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pci_io.o `test -f 'pci_io.c' || echo '$(srcdir)/'`pci_io.c
2725 +libdrivers_a-pci_io.obj: pci_io.c
2726 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pci_io.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pci_io.Tpo" -c -o libdrivers_a-pci_io.obj `if test -f 'pci_io.c'; then $(CYGPATH_W) 'pci_io.c'; else $(CYGPATH_W) '$(srcdir)/pci_io.c'; fi`; \
2727 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pci_io.Tpo" "$(DEPDIR)/libdrivers_a-pci_io.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pci_io.Tpo"; exit 1; fi
2728 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pci_io.c' object='libdrivers_a-pci_io.obj' libtool=no @AMDEPBACKSLASH@
2729 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pci_io.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pci_io.TPo' @AMDEPBACKSLASH@
2730 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2731 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pci_io.obj `if test -f 'pci_io.c'; then $(CYGPATH_W) 'pci_io.c'; else $(CYGPATH_W) '$(srcdir)/pci_io.c'; fi`
2733 libdrivers_a-timer.o: timer.c
2734 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-timer.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-timer.Tpo" -c -o libdrivers_a-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c; \
2735 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-timer.Tpo" "$(DEPDIR)/libdrivers_a-timer.Po"; else rm -f "$(DEPDIR)/libdrivers_a-timer.Tpo"; exit 1; fi
2736 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timer.c' object='libdrivers_a-timer.o' libtool=no @AMDEPBACKSLASH@
2737 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2738 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-timer.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-timer.TPo' @AMDEPBACKSLASH@
2739 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2740 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
2742 libdrivers_a-timer.obj: timer.c
2743 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-timer.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-timer.Tpo" -c -o libdrivers_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`; \
2744 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-timer.Tpo" "$(DEPDIR)/libdrivers_a-timer.Po"; else rm -f "$(DEPDIR)/libdrivers_a-timer.Tpo"; exit 1; fi
2745 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timer.c' object='libdrivers_a-timer.obj' libtool=no @AMDEPBACKSLASH@
2746 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2747 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-timer.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-timer.TPo' @AMDEPBACKSLASH@
2748 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2749 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
2751 -libdrivers_a-3c509.o: 3c509.c
2752 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c509.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c509.Tpo" -c -o libdrivers_a-3c509.o `test -f '3c509.c' || echo '$(srcdir)/'`3c509.c; \
2753 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-3c509.Tpo" "$(DEPDIR)/libdrivers_a-3c509.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c509.Tpo"; exit 1; fi
2754 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='3c509.c' object='libdrivers_a-3c509.o' libtool=no @AMDEPBACKSLASH@
2755 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2756 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c509.o `test -f '3c509.c' || echo '$(srcdir)/'`3c509.c
2758 -libdrivers_a-3c509.obj: 3c509.c
2759 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c509.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c509.Tpo" -c -o libdrivers_a-3c509.obj `if test -f '3c509.c'; then $(CYGPATH_W) '3c509.c'; else $(CYGPATH_W) '$(srcdir)/3c509.c'; fi`; \
2760 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-3c509.Tpo" "$(DEPDIR)/libdrivers_a-3c509.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c509.Tpo"; exit 1; fi
2761 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='3c509.c' object='libdrivers_a-3c509.obj' libtool=no @AMDEPBACKSLASH@
2762 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2763 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c509.obj `if test -f '3c509.c'; then $(CYGPATH_W) '3c509.c'; else $(CYGPATH_W) '$(srcdir)/3c509.c'; fi`
2764 +libdrivers_a-pic8259.o: pic8259.c
2765 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pic8259.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pic8259.Tpo" -c -o libdrivers_a-pic8259.o `test -f 'pic8259.c' || echo '$(srcdir)/'`pic8259.c; \
2766 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pic8259.Tpo" "$(DEPDIR)/libdrivers_a-pic8259.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pic8259.Tpo"; exit 1; fi
2767 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pic8259.c' object='libdrivers_a-pic8259.o' libtool=no @AMDEPBACKSLASH@
2768 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pic8259.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pic8259.TPo' @AMDEPBACKSLASH@
2769 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2770 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pic8259.o `test -f 'pic8259.c' || echo '$(srcdir)/'`pic8259.c
2772 +libdrivers_a-pic8259.obj: pic8259.c
2773 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pic8259.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pic8259.Tpo" -c -o libdrivers_a-pic8259.obj `if test -f 'pic8259.c'; then $(CYGPATH_W) 'pic8259.c'; else $(CYGPATH_W) '$(srcdir)/pic8259.c'; fi`; \
2774 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pic8259.Tpo" "$(DEPDIR)/libdrivers_a-pic8259.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pic8259.Tpo"; exit 1; fi
2775 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pic8259.c' object='libdrivers_a-pic8259.obj' libtool=no @AMDEPBACKSLASH@
2776 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pic8259.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pic8259.TPo' @AMDEPBACKSLASH@
2777 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2778 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pic8259.obj `if test -f 'pic8259.c'; then $(CYGPATH_W) 'pic8259.c'; else $(CYGPATH_W) '$(srcdir)/pic8259.c'; fi`
2780 +libdrivers_a-basemem.o: basemem.c
2781 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-basemem.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-basemem.Tpo" -c -o libdrivers_a-basemem.o `test -f 'basemem.c' || echo '$(srcdir)/'`basemem.c; \
2782 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-basemem.Tpo" "$(DEPDIR)/libdrivers_a-basemem.Po"; else rm -f "$(DEPDIR)/libdrivers_a-basemem.Tpo"; exit 1; fi
2783 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='basemem.c' object='libdrivers_a-basemem.o' libtool=no @AMDEPBACKSLASH@
2784 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-basemem.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-basemem.TPo' @AMDEPBACKSLASH@
2785 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2786 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-basemem.o `test -f 'basemem.c' || echo '$(srcdir)/'`basemem.c
2788 +libdrivers_a-basemem.obj: basemem.c
2789 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-basemem.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-basemem.Tpo" -c -o libdrivers_a-basemem.obj `if test -f 'basemem.c'; then $(CYGPATH_W) 'basemem.c'; else $(CYGPATH_W) '$(srcdir)/basemem.c'; fi`; \
2790 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-basemem.Tpo" "$(DEPDIR)/libdrivers_a-basemem.Po"; else rm -f "$(DEPDIR)/libdrivers_a-basemem.Tpo"; exit 1; fi
2791 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='basemem.c' object='libdrivers_a-basemem.obj' libtool=no @AMDEPBACKSLASH@
2792 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-basemem.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-basemem.TPo' @AMDEPBACKSLASH@
2793 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2794 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-basemem.obj `if test -f 'basemem.c'; then $(CYGPATH_W) 'basemem.c'; else $(CYGPATH_W) '$(srcdir)/basemem.c'; fi`
2796 libdrivers_a-3c595.o: 3c595.c
2797 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c595.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c595.Tpo" -c -o libdrivers_a-3c595.o `test -f '3c595.c' || echo '$(srcdir)/'`3c595.c; \
2798 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-3c595.Tpo" "$(DEPDIR)/libdrivers_a-3c595.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c595.Tpo"; exit 1; fi
2799 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='3c595.c' object='libdrivers_a-3c595.o' libtool=no @AMDEPBACKSLASH@
2800 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2801 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-3c595.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-3c595.TPo' @AMDEPBACKSLASH@
2802 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2803 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c595.o `test -f '3c595.c' || echo '$(srcdir)/'`3c595.c
2805 libdrivers_a-3c595.obj: 3c595.c
2806 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c595.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c595.Tpo" -c -o libdrivers_a-3c595.obj `if test -f '3c595.c'; then $(CYGPATH_W) '3c595.c'; else $(CYGPATH_W) '$(srcdir)/3c595.c'; fi`; \
2807 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-3c595.Tpo" "$(DEPDIR)/libdrivers_a-3c595.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c595.Tpo"; exit 1; fi
2808 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='3c595.c' object='libdrivers_a-3c595.obj' libtool=no @AMDEPBACKSLASH@
2809 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2810 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-3c595.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-3c595.TPo' @AMDEPBACKSLASH@
2811 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2812 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c595.obj `if test -f '3c595.c'; then $(CYGPATH_W) '3c595.c'; else $(CYGPATH_W) '$(srcdir)/3c595.c'; fi`
2814 libdrivers_a-3c90x.o: 3c90x.c
2815 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c90x.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c90x.Tpo" -c -o libdrivers_a-3c90x.o `test -f '3c90x.c' || echo '$(srcdir)/'`3c90x.c; \
2816 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo" "$(DEPDIR)/libdrivers_a-3c90x.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo"; exit 1; fi
2817 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='3c90x.c' object='libdrivers_a-3c90x.o' libtool=no @AMDEPBACKSLASH@
2818 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2819 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-3c90x.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-3c90x.TPo' @AMDEPBACKSLASH@
2820 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2821 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c90x.o `test -f '3c90x.c' || echo '$(srcdir)/'`3c90x.c
2823 libdrivers_a-3c90x.obj: 3c90x.c
2824 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c90x.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c90x.Tpo" -c -o libdrivers_a-3c90x.obj `if test -f '3c90x.c'; then $(CYGPATH_W) '3c90x.c'; else $(CYGPATH_W) '$(srcdir)/3c90x.c'; fi`; \
2825 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo" "$(DEPDIR)/libdrivers_a-3c90x.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo"; exit 1; fi
2826 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='3c90x.c' object='libdrivers_a-3c90x.obj' libtool=no @AMDEPBACKSLASH@
2827 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2828 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-3c90x.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-3c90x.TPo' @AMDEPBACKSLASH@
2829 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2830 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c90x.obj `if test -f '3c90x.c'; then $(CYGPATH_W) '3c90x.c'; else $(CYGPATH_W) '$(srcdir)/3c90x.c'; fi`
2832 -libdrivers_a-cs89x0.o: cs89x0.c
2833 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-cs89x0.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" -c -o libdrivers_a-cs89x0.o `test -f 'cs89x0.c' || echo '$(srcdir)/'`cs89x0.c; \
2834 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" "$(DEPDIR)/libdrivers_a-cs89x0.Po"; else rm -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo"; exit 1; fi
2835 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cs89x0.c' object='libdrivers_a-cs89x0.o' libtool=no @AMDEPBACKSLASH@
2836 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2837 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-cs89x0.o `test -f 'cs89x0.c' || echo '$(srcdir)/'`cs89x0.c
2839 -libdrivers_a-cs89x0.obj: cs89x0.c
2840 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-cs89x0.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" -c -o libdrivers_a-cs89x0.obj `if test -f 'cs89x0.c'; then $(CYGPATH_W) 'cs89x0.c'; else $(CYGPATH_W) '$(srcdir)/cs89x0.c'; fi`; \
2841 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" "$(DEPDIR)/libdrivers_a-cs89x0.Po"; else rm -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo"; exit 1; fi
2842 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cs89x0.c' object='libdrivers_a-cs89x0.obj' libtool=no @AMDEPBACKSLASH@
2843 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2844 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-cs89x0.obj `if test -f 'cs89x0.c'; then $(CYGPATH_W) 'cs89x0.c'; else $(CYGPATH_W) '$(srcdir)/cs89x0.c'; fi`
2846 libdrivers_a-davicom.o: davicom.c
2847 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-davicom.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-davicom.Tpo" -c -o libdrivers_a-davicom.o `test -f 'davicom.c' || echo '$(srcdir)/'`davicom.c; \
2848 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-davicom.Tpo" "$(DEPDIR)/libdrivers_a-davicom.Po"; else rm -f "$(DEPDIR)/libdrivers_a-davicom.Tpo"; exit 1; fi
2849 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='davicom.c' object='libdrivers_a-davicom.o' libtool=no @AMDEPBACKSLASH@
2850 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2851 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-davicom.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-davicom.TPo' @AMDEPBACKSLASH@
2852 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2853 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-davicom.o `test -f 'davicom.c' || echo '$(srcdir)/'`davicom.c
2855 libdrivers_a-davicom.obj: davicom.c
2856 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-davicom.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-davicom.Tpo" -c -o libdrivers_a-davicom.obj `if test -f 'davicom.c'; then $(CYGPATH_W) 'davicom.c'; else $(CYGPATH_W) '$(srcdir)/davicom.c'; fi`; \
2857 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-davicom.Tpo" "$(DEPDIR)/libdrivers_a-davicom.Po"; else rm -f "$(DEPDIR)/libdrivers_a-davicom.Tpo"; exit 1; fi
2858 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='davicom.c' object='libdrivers_a-davicom.obj' libtool=no @AMDEPBACKSLASH@
2859 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2860 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-davicom.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-davicom.TPo' @AMDEPBACKSLASH@
2861 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2862 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-davicom.obj `if test -f 'davicom.c'; then $(CYGPATH_W) 'davicom.c'; else $(CYGPATH_W) '$(srcdir)/davicom.c'; fi`
2864 -libdrivers_a-depca.o: depca.c
2865 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-depca.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-depca.Tpo" -c -o libdrivers_a-depca.o `test -f 'depca.c' || echo '$(srcdir)/'`depca.c; \
2866 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-depca.Tpo" "$(DEPDIR)/libdrivers_a-depca.Po"; else rm -f "$(DEPDIR)/libdrivers_a-depca.Tpo"; exit 1; fi
2867 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='depca.c' object='libdrivers_a-depca.o' libtool=no @AMDEPBACKSLASH@
2868 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2869 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-depca.o `test -f 'depca.c' || echo '$(srcdir)/'`depca.c
2871 -libdrivers_a-depca.obj: depca.c
2872 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-depca.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-depca.Tpo" -c -o libdrivers_a-depca.obj `if test -f 'depca.c'; then $(CYGPATH_W) 'depca.c'; else $(CYGPATH_W) '$(srcdir)/depca.c'; fi`; \
2873 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-depca.Tpo" "$(DEPDIR)/libdrivers_a-depca.Po"; else rm -f "$(DEPDIR)/libdrivers_a-depca.Tpo"; exit 1; fi
2874 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='depca.c' object='libdrivers_a-depca.obj' libtool=no @AMDEPBACKSLASH@
2875 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2876 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-depca.obj `if test -f 'depca.c'; then $(CYGPATH_W) 'depca.c'; else $(CYGPATH_W) '$(srcdir)/depca.c'; fi`
2878 -libdrivers_a-eepro.o: eepro.c
2879 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro.Tpo" -c -o libdrivers_a-eepro.o `test -f 'eepro.c' || echo '$(srcdir)/'`eepro.c; \
2880 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-eepro.Tpo" "$(DEPDIR)/libdrivers_a-eepro.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro.Tpo"; exit 1; fi
2881 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eepro.c' object='libdrivers_a-eepro.o' libtool=no @AMDEPBACKSLASH@
2882 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2883 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro.o `test -f 'eepro.c' || echo '$(srcdir)/'`eepro.c
2885 -libdrivers_a-eepro.obj: eepro.c
2886 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro.Tpo" -c -o libdrivers_a-eepro.obj `if test -f 'eepro.c'; then $(CYGPATH_W) 'eepro.c'; else $(CYGPATH_W) '$(srcdir)/eepro.c'; fi`; \
2887 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-eepro.Tpo" "$(DEPDIR)/libdrivers_a-eepro.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro.Tpo"; exit 1; fi
2888 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eepro.c' object='libdrivers_a-eepro.obj' libtool=no @AMDEPBACKSLASH@
2889 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2890 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro.obj `if test -f 'eepro.c'; then $(CYGPATH_W) 'eepro.c'; else $(CYGPATH_W) '$(srcdir)/eepro.c'; fi`
2891 +libdrivers_a-e1000.o: e1000.c
2892 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-e1000.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-e1000.Tpo" -c -o libdrivers_a-e1000.o `test -f 'e1000.c' || echo '$(srcdir)/'`e1000.c; \
2893 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-e1000.Tpo" "$(DEPDIR)/libdrivers_a-e1000.Po"; else rm -f "$(DEPDIR)/libdrivers_a-e1000.Tpo"; exit 1; fi
2894 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='e1000.c' object='libdrivers_a-e1000.o' libtool=no @AMDEPBACKSLASH@
2895 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-e1000.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-e1000.TPo' @AMDEPBACKSLASH@
2896 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2897 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-e1000.o `test -f 'e1000.c' || echo '$(srcdir)/'`e1000.c
2899 +libdrivers_a-e1000.obj: e1000.c
2900 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-e1000.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-e1000.Tpo" -c -o libdrivers_a-e1000.obj `if test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; fi`; \
2901 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-e1000.Tpo" "$(DEPDIR)/libdrivers_a-e1000.Po"; else rm -f "$(DEPDIR)/libdrivers_a-e1000.Tpo"; exit 1; fi
2902 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='e1000.c' object='libdrivers_a-e1000.obj' libtool=no @AMDEPBACKSLASH@
2903 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-e1000.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-e1000.TPo' @AMDEPBACKSLASH@
2904 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2905 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-e1000.obj `if test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; fi`
2907 libdrivers_a-eepro100.o: eepro100.c
2908 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro100.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro100.Tpo" -c -o libdrivers_a-eepro100.o `test -f 'eepro100.c' || echo '$(srcdir)/'`eepro100.c; \
2909 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo" "$(DEPDIR)/libdrivers_a-eepro100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo"; exit 1; fi
2910 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eepro100.c' object='libdrivers_a-eepro100.o' libtool=no @AMDEPBACKSLASH@
2911 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2912 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-eepro100.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-eepro100.TPo' @AMDEPBACKSLASH@
2913 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2914 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro100.o `test -f 'eepro100.c' || echo '$(srcdir)/'`eepro100.c
2916 libdrivers_a-eepro100.obj: eepro100.c
2917 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro100.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro100.Tpo" -c -o libdrivers_a-eepro100.obj `if test -f 'eepro100.c'; then $(CYGPATH_W) 'eepro100.c'; else $(CYGPATH_W) '$(srcdir)/eepro100.c'; fi`; \
2918 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo" "$(DEPDIR)/libdrivers_a-eepro100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo"; exit 1; fi
2919 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eepro100.c' object='libdrivers_a-eepro100.obj' libtool=no @AMDEPBACKSLASH@
2920 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2921 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-eepro100.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-eepro100.TPo' @AMDEPBACKSLASH@
2922 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2923 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro100.obj `if test -f 'eepro100.c'; then $(CYGPATH_W) 'eepro100.c'; else $(CYGPATH_W) '$(srcdir)/eepro100.c'; fi`
2925 libdrivers_a-epic100.o: epic100.c
2926 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-epic100.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-epic100.Tpo" -c -o libdrivers_a-epic100.o `test -f 'epic100.c' || echo '$(srcdir)/'`epic100.c; \
2927 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-epic100.Tpo" "$(DEPDIR)/libdrivers_a-epic100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-epic100.Tpo"; exit 1; fi
2928 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='epic100.c' object='libdrivers_a-epic100.o' libtool=no @AMDEPBACKSLASH@
2929 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2930 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-epic100.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-epic100.TPo' @AMDEPBACKSLASH@
2931 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2932 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-epic100.o `test -f 'epic100.c' || echo '$(srcdir)/'`epic100.c
2934 libdrivers_a-epic100.obj: epic100.c
2935 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-epic100.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-epic100.Tpo" -c -o libdrivers_a-epic100.obj `if test -f 'epic100.c'; then $(CYGPATH_W) 'epic100.c'; else $(CYGPATH_W) '$(srcdir)/epic100.c'; fi`; \
2936 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-epic100.Tpo" "$(DEPDIR)/libdrivers_a-epic100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-epic100.Tpo"; exit 1; fi
2937 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='epic100.c' object='libdrivers_a-epic100.obj' libtool=no @AMDEPBACKSLASH@
2938 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2939 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-epic100.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-epic100.TPo' @AMDEPBACKSLASH@
2940 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2941 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-epic100.obj `if test -f 'epic100.c'; then $(CYGPATH_W) 'epic100.c'; else $(CYGPATH_W) '$(srcdir)/epic100.c'; fi`
2943 -libdrivers_a-fa311.o: fa311.c
2944 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fa311.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-fa311.Tpo" -c -o libdrivers_a-fa311.o `test -f 'fa311.c' || echo '$(srcdir)/'`fa311.c; \
2945 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-fa311.Tpo" "$(DEPDIR)/libdrivers_a-fa311.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fa311.Tpo"; exit 1; fi
2946 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fa311.c' object='libdrivers_a-fa311.o' libtool=no @AMDEPBACKSLASH@
2947 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2948 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fa311.o `test -f 'fa311.c' || echo '$(srcdir)/'`fa311.c
2950 -libdrivers_a-fa311.obj: fa311.c
2951 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fa311.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-fa311.Tpo" -c -o libdrivers_a-fa311.obj `if test -f 'fa311.c'; then $(CYGPATH_W) 'fa311.c'; else $(CYGPATH_W) '$(srcdir)/fa311.c'; fi`; \
2952 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-fa311.Tpo" "$(DEPDIR)/libdrivers_a-fa311.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fa311.Tpo"; exit 1; fi
2953 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fa311.c' object='libdrivers_a-fa311.obj' libtool=no @AMDEPBACKSLASH@
2954 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2955 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fa311.obj `if test -f 'fa311.c'; then $(CYGPATH_W) 'fa311.c'; else $(CYGPATH_W) '$(srcdir)/fa311.c'; fi`
2957 -libdrivers_a-i82586.o: i82586.c
2958 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-i82586.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-i82586.Tpo" -c -o libdrivers_a-i82586.o `test -f 'i82586.c' || echo '$(srcdir)/'`i82586.c; \
2959 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-i82586.Tpo" "$(DEPDIR)/libdrivers_a-i82586.Po"; else rm -f "$(DEPDIR)/libdrivers_a-i82586.Tpo"; exit 1; fi
2960 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i82586.c' object='libdrivers_a-i82586.o' libtool=no @AMDEPBACKSLASH@
2961 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2962 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-i82586.o `test -f 'i82586.c' || echo '$(srcdir)/'`i82586.c
2964 -libdrivers_a-i82586.obj: i82586.c
2965 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-i82586.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-i82586.Tpo" -c -o libdrivers_a-i82586.obj `if test -f 'i82586.c'; then $(CYGPATH_W) 'i82586.c'; else $(CYGPATH_W) '$(srcdir)/i82586.c'; fi`; \
2966 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-i82586.Tpo" "$(DEPDIR)/libdrivers_a-i82586.Po"; else rm -f "$(DEPDIR)/libdrivers_a-i82586.Tpo"; exit 1; fi
2967 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i82586.c' object='libdrivers_a-i82586.obj' libtool=no @AMDEPBACKSLASH@
2968 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2969 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-i82586.obj `if test -f 'i82586.c'; then $(CYGPATH_W) 'i82586.c'; else $(CYGPATH_W) '$(srcdir)/i82586.c'; fi`
2971 -libdrivers_a-lance.o: lance.c
2972 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-lance.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-lance.Tpo" -c -o libdrivers_a-lance.o `test -f 'lance.c' || echo '$(srcdir)/'`lance.c; \
2973 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-lance.Tpo" "$(DEPDIR)/libdrivers_a-lance.Po"; else rm -f "$(DEPDIR)/libdrivers_a-lance.Tpo"; exit 1; fi
2974 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lance.c' object='libdrivers_a-lance.o' libtool=no @AMDEPBACKSLASH@
2975 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2976 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-lance.o `test -f 'lance.c' || echo '$(srcdir)/'`lance.c
2978 -libdrivers_a-lance.obj: lance.c
2979 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-lance.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-lance.Tpo" -c -o libdrivers_a-lance.obj `if test -f 'lance.c'; then $(CYGPATH_W) 'lance.c'; else $(CYGPATH_W) '$(srcdir)/lance.c'; fi`; \
2980 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-lance.Tpo" "$(DEPDIR)/libdrivers_a-lance.Po"; else rm -f "$(DEPDIR)/libdrivers_a-lance.Tpo"; exit 1; fi
2981 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lance.c' object='libdrivers_a-lance.obj' libtool=no @AMDEPBACKSLASH@
2982 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2983 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-lance.obj `if test -f 'lance.c'; then $(CYGPATH_W) 'lance.c'; else $(CYGPATH_W) '$(srcdir)/lance.c'; fi`
2985 libdrivers_a-natsemi.o: natsemi.c
2986 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-natsemi.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-natsemi.Tpo" -c -o libdrivers_a-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c; \
2987 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo" "$(DEPDIR)/libdrivers_a-natsemi.Po"; else rm -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo"; exit 1; fi
2988 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='natsemi.c' object='libdrivers_a-natsemi.o' libtool=no @AMDEPBACKSLASH@
2989 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2990 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-natsemi.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-natsemi.TPo' @AMDEPBACKSLASH@
2991 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2992 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c
2994 libdrivers_a-natsemi.obj: natsemi.c
2995 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-natsemi.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-natsemi.Tpo" -c -o libdrivers_a-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi`; \
2996 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo" "$(DEPDIR)/libdrivers_a-natsemi.Po"; else rm -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo"; exit 1; fi
2997 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='natsemi.c' object='libdrivers_a-natsemi.obj' libtool=no @AMDEPBACKSLASH@
2998 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2999 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-natsemi.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-natsemi.TPo' @AMDEPBACKSLASH@
3000 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3001 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi`
3003 -libdrivers_a-ni5010.o: ni5010.c
3004 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ni5010.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-ni5010.Tpo" -c -o libdrivers_a-ni5010.o `test -f 'ni5010.c' || echo '$(srcdir)/'`ni5010.c; \
3005 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo" "$(DEPDIR)/libdrivers_a-ni5010.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo"; exit 1; fi
3006 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ni5010.c' object='libdrivers_a-ni5010.o' libtool=no @AMDEPBACKSLASH@
3007 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3008 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ni5010.o `test -f 'ni5010.c' || echo '$(srcdir)/'`ni5010.c
3010 -libdrivers_a-ni5010.obj: ni5010.c
3011 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ni5010.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-ni5010.Tpo" -c -o libdrivers_a-ni5010.obj `if test -f 'ni5010.c'; then $(CYGPATH_W) 'ni5010.c'; else $(CYGPATH_W) '$(srcdir)/ni5010.c'; fi`; \
3012 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo" "$(DEPDIR)/libdrivers_a-ni5010.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo"; exit 1; fi
3013 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ni5010.c' object='libdrivers_a-ni5010.obj' libtool=no @AMDEPBACKSLASH@
3014 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3015 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ni5010.obj `if test -f 'ni5010.c'; then $(CYGPATH_W) 'ni5010.c'; else $(CYGPATH_W) '$(srcdir)/ni5010.c'; fi`
3017 libdrivers_a-ns8390.o: ns8390.c
3018 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ns8390.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-ns8390.Tpo" -c -o libdrivers_a-ns8390.o `test -f 'ns8390.c' || echo '$(srcdir)/'`ns8390.c; \
3019 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo" "$(DEPDIR)/libdrivers_a-ns8390.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo"; exit 1; fi
3020 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ns8390.c' object='libdrivers_a-ns8390.o' libtool=no @AMDEPBACKSLASH@
3021 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3022 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-ns8390.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-ns8390.TPo' @AMDEPBACKSLASH@
3023 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3024 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ns8390.o `test -f 'ns8390.c' || echo '$(srcdir)/'`ns8390.c
3026 libdrivers_a-ns8390.obj: ns8390.c
3027 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ns8390.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-ns8390.Tpo" -c -o libdrivers_a-ns8390.obj `if test -f 'ns8390.c'; then $(CYGPATH_W) 'ns8390.c'; else $(CYGPATH_W) '$(srcdir)/ns8390.c'; fi`; \
3028 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo" "$(DEPDIR)/libdrivers_a-ns8390.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo"; exit 1; fi
3029 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ns8390.c' object='libdrivers_a-ns8390.obj' libtool=no @AMDEPBACKSLASH@
3030 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3031 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-ns8390.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-ns8390.TPo' @AMDEPBACKSLASH@
3032 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3033 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ns8390.obj `if test -f 'ns8390.c'; then $(CYGPATH_W) 'ns8390.c'; else $(CYGPATH_W) '$(srcdir)/ns8390.c'; fi`
3035 -libdrivers_a-otulip.o: otulip.c
3036 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-otulip.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-otulip.Tpo" -c -o libdrivers_a-otulip.o `test -f 'otulip.c' || echo '$(srcdir)/'`otulip.c; \
3037 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-otulip.Tpo" "$(DEPDIR)/libdrivers_a-otulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-otulip.Tpo"; exit 1; fi
3038 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='otulip.c' object='libdrivers_a-otulip.o' libtool=no @AMDEPBACKSLASH@
3039 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3040 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-otulip.o `test -f 'otulip.c' || echo '$(srcdir)/'`otulip.c
3042 -libdrivers_a-otulip.obj: otulip.c
3043 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-otulip.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-otulip.Tpo" -c -o libdrivers_a-otulip.obj `if test -f 'otulip.c'; then $(CYGPATH_W) 'otulip.c'; else $(CYGPATH_W) '$(srcdir)/otulip.c'; fi`; \
3044 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-otulip.Tpo" "$(DEPDIR)/libdrivers_a-otulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-otulip.Tpo"; exit 1; fi
3045 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='otulip.c' object='libdrivers_a-otulip.obj' libtool=no @AMDEPBACKSLASH@
3046 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3047 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-otulip.obj `if test -f 'otulip.c'; then $(CYGPATH_W) 'otulip.c'; else $(CYGPATH_W) '$(srcdir)/otulip.c'; fi`
3048 +libdrivers_a-pcnet32.o: pcnet32.c
3049 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pcnet32.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pcnet32.Tpo" -c -o libdrivers_a-pcnet32.o `test -f 'pcnet32.c' || echo '$(srcdir)/'`pcnet32.c; \
3050 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pcnet32.Tpo" "$(DEPDIR)/libdrivers_a-pcnet32.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pcnet32.Tpo"; exit 1; fi
3051 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pcnet32.c' object='libdrivers_a-pcnet32.o' libtool=no @AMDEPBACKSLASH@
3052 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pcnet32.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pcnet32.TPo' @AMDEPBACKSLASH@
3053 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3054 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pcnet32.o `test -f 'pcnet32.c' || echo '$(srcdir)/'`pcnet32.c
3056 +libdrivers_a-pcnet32.obj: pcnet32.c
3057 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pcnet32.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pcnet32.Tpo" -c -o libdrivers_a-pcnet32.obj `if test -f 'pcnet32.c'; then $(CYGPATH_W) 'pcnet32.c'; else $(CYGPATH_W) '$(srcdir)/pcnet32.c'; fi`; \
3058 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pcnet32.Tpo" "$(DEPDIR)/libdrivers_a-pcnet32.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pcnet32.Tpo"; exit 1; fi
3059 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pcnet32.c' object='libdrivers_a-pcnet32.obj' libtool=no @AMDEPBACKSLASH@
3060 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pcnet32.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pcnet32.TPo' @AMDEPBACKSLASH@
3061 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3062 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pcnet32.obj `if test -f 'pcnet32.c'; then $(CYGPATH_W) 'pcnet32.c'; else $(CYGPATH_W) '$(srcdir)/pcnet32.c'; fi`
3064 libdrivers_a-rtl8139.o: rtl8139.c
3065 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-rtl8139.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" -c -o libdrivers_a-rtl8139.o `test -f 'rtl8139.c' || echo '$(srcdir)/'`rtl8139.c; \
3066 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" "$(DEPDIR)/libdrivers_a-rtl8139.Po"; else rm -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo"; exit 1; fi
3067 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtl8139.c' object='libdrivers_a-rtl8139.o' libtool=no @AMDEPBACKSLASH@
3068 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3069 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-rtl8139.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-rtl8139.TPo' @AMDEPBACKSLASH@
3070 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3071 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-rtl8139.o `test -f 'rtl8139.c' || echo '$(srcdir)/'`rtl8139.c
3073 libdrivers_a-rtl8139.obj: rtl8139.c
3074 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-rtl8139.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" -c -o libdrivers_a-rtl8139.obj `if test -f 'rtl8139.c'; then $(CYGPATH_W) 'rtl8139.c'; else $(CYGPATH_W) '$(srcdir)/rtl8139.c'; fi`; \
3075 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" "$(DEPDIR)/libdrivers_a-rtl8139.Po"; else rm -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo"; exit 1; fi
3076 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rtl8139.c' object='libdrivers_a-rtl8139.obj' libtool=no @AMDEPBACKSLASH@
3077 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3078 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-rtl8139.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-rtl8139.TPo' @AMDEPBACKSLASH@
3079 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3080 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-rtl8139.obj `if test -f 'rtl8139.c'; then $(CYGPATH_W) 'rtl8139.c'; else $(CYGPATH_W) '$(srcdir)/rtl8139.c'; fi`
3082 libdrivers_a-sis900.o: sis900.c
3083 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sis900.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-sis900.Tpo" -c -o libdrivers_a-sis900.o `test -f 'sis900.c' || echo '$(srcdir)/'`sis900.c; \
3084 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-sis900.Tpo" "$(DEPDIR)/libdrivers_a-sis900.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sis900.Tpo"; exit 1; fi
3085 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sis900.c' object='libdrivers_a-sis900.o' libtool=no @AMDEPBACKSLASH@
3086 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3087 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-sis900.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-sis900.TPo' @AMDEPBACKSLASH@
3088 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3089 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sis900.o `test -f 'sis900.c' || echo '$(srcdir)/'`sis900.c
3091 libdrivers_a-sis900.obj: sis900.c
3092 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sis900.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-sis900.Tpo" -c -o libdrivers_a-sis900.obj `if test -f 'sis900.c'; then $(CYGPATH_W) 'sis900.c'; else $(CYGPATH_W) '$(srcdir)/sis900.c'; fi`; \
3093 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-sis900.Tpo" "$(DEPDIR)/libdrivers_a-sis900.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sis900.Tpo"; exit 1; fi
3094 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sis900.c' object='libdrivers_a-sis900.obj' libtool=no @AMDEPBACKSLASH@
3095 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3096 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-sis900.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-sis900.TPo' @AMDEPBACKSLASH@
3097 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3098 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sis900.obj `if test -f 'sis900.c'; then $(CYGPATH_W) 'sis900.c'; else $(CYGPATH_W) '$(srcdir)/sis900.c'; fi`
3100 -libdrivers_a-sk_g16.o: sk_g16.c
3101 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sk_g16.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" -c -o libdrivers_a-sk_g16.o `test -f 'sk_g16.c' || echo '$(srcdir)/'`sk_g16.c; \
3102 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" "$(DEPDIR)/libdrivers_a-sk_g16.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo"; exit 1; fi
3103 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sk_g16.c' object='libdrivers_a-sk_g16.o' libtool=no @AMDEPBACKSLASH@
3104 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3105 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sk_g16.o `test -f 'sk_g16.c' || echo '$(srcdir)/'`sk_g16.c
3107 -libdrivers_a-sk_g16.obj: sk_g16.c
3108 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sk_g16.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" -c -o libdrivers_a-sk_g16.obj `if test -f 'sk_g16.c'; then $(CYGPATH_W) 'sk_g16.c'; else $(CYGPATH_W) '$(srcdir)/sk_g16.c'; fi`; \
3109 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" "$(DEPDIR)/libdrivers_a-sk_g16.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo"; exit 1; fi
3110 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sk_g16.c' object='libdrivers_a-sk_g16.obj' libtool=no @AMDEPBACKSLASH@
3111 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3112 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sk_g16.obj `if test -f 'sk_g16.c'; then $(CYGPATH_W) 'sk_g16.c'; else $(CYGPATH_W) '$(srcdir)/sk_g16.c'; fi`
3114 -libdrivers_a-smc9000.o: smc9000.c
3115 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-smc9000.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-smc9000.Tpo" -c -o libdrivers_a-smc9000.o `test -f 'smc9000.c' || echo '$(srcdir)/'`smc9000.c; \
3116 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo" "$(DEPDIR)/libdrivers_a-smc9000.Po"; else rm -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo"; exit 1; fi
3117 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='smc9000.c' object='libdrivers_a-smc9000.o' libtool=no @AMDEPBACKSLASH@
3118 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3119 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-smc9000.o `test -f 'smc9000.c' || echo '$(srcdir)/'`smc9000.c
3121 -libdrivers_a-smc9000.obj: smc9000.c
3122 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-smc9000.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-smc9000.Tpo" -c -o libdrivers_a-smc9000.obj `if test -f 'smc9000.c'; then $(CYGPATH_W) 'smc9000.c'; else $(CYGPATH_W) '$(srcdir)/smc9000.c'; fi`; \
3123 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo" "$(DEPDIR)/libdrivers_a-smc9000.Po"; else rm -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo"; exit 1; fi
3124 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='smc9000.c' object='libdrivers_a-smc9000.obj' libtool=no @AMDEPBACKSLASH@
3125 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3126 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-smc9000.obj `if test -f 'smc9000.c'; then $(CYGPATH_W) 'smc9000.c'; else $(CYGPATH_W) '$(srcdir)/smc9000.c'; fi`
3128 -libdrivers_a-tiara.o: tiara.c
3129 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tiara.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tiara.Tpo" -c -o libdrivers_a-tiara.o `test -f 'tiara.c' || echo '$(srcdir)/'`tiara.c; \
3130 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tiara.Tpo" "$(DEPDIR)/libdrivers_a-tiara.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tiara.Tpo"; exit 1; fi
3131 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tiara.c' object='libdrivers_a-tiara.o' libtool=no @AMDEPBACKSLASH@
3132 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3133 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tiara.o `test -f 'tiara.c' || echo '$(srcdir)/'`tiara.c
3135 -libdrivers_a-tiara.obj: tiara.c
3136 -@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tiara.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tiara.Tpo" -c -o libdrivers_a-tiara.obj `if test -f 'tiara.c'; then $(CYGPATH_W) 'tiara.c'; else $(CYGPATH_W) '$(srcdir)/tiara.c'; fi`; \
3137 -@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tiara.Tpo" "$(DEPDIR)/libdrivers_a-tiara.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tiara.Tpo"; exit 1; fi
3138 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tiara.c' object='libdrivers_a-tiara.obj' libtool=no @AMDEPBACKSLASH@
3139 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3140 -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tiara.obj `if test -f 'tiara.c'; then $(CYGPATH_W) 'tiara.c'; else $(CYGPATH_W) '$(srcdir)/tiara.c'; fi`
3141 +libdrivers_a-tg3.o: tg3.c
3142 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tg3.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tg3.Tpo" -c -o libdrivers_a-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c; \
3143 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tg3.Tpo" "$(DEPDIR)/libdrivers_a-tg3.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tg3.Tpo"; exit 1; fi
3144 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tg3.c' object='libdrivers_a-tg3.o' libtool=no @AMDEPBACKSLASH@
3145 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-tg3.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-tg3.TPo' @AMDEPBACKSLASH@
3146 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3147 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c
3149 +libdrivers_a-tg3.obj: tg3.c
3150 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tg3.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tg3.Tpo" -c -o libdrivers_a-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi`; \
3151 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tg3.Tpo" "$(DEPDIR)/libdrivers_a-tg3.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tg3.Tpo"; exit 1; fi
3152 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tg3.c' object='libdrivers_a-tg3.obj' libtool=no @AMDEPBACKSLASH@
3153 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-tg3.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-tg3.TPo' @AMDEPBACKSLASH@
3154 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3155 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi`
3157 libdrivers_a-tlan.o: tlan.c
3158 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tlan.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tlan.Tpo" -c -o libdrivers_a-tlan.o `test -f 'tlan.c' || echo '$(srcdir)/'`tlan.c; \
3159 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tlan.Tpo" "$(DEPDIR)/libdrivers_a-tlan.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tlan.Tpo"; exit 1; fi
3160 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tlan.c' object='libdrivers_a-tlan.o' libtool=no @AMDEPBACKSLASH@
3161 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3162 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-tlan.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-tlan.TPo' @AMDEPBACKSLASH@
3163 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3164 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tlan.o `test -f 'tlan.c' || echo '$(srcdir)/'`tlan.c
3166 libdrivers_a-tlan.obj: tlan.c
3167 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tlan.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tlan.Tpo" -c -o libdrivers_a-tlan.obj `if test -f 'tlan.c'; then $(CYGPATH_W) 'tlan.c'; else $(CYGPATH_W) '$(srcdir)/tlan.c'; fi`; \
3168 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tlan.Tpo" "$(DEPDIR)/libdrivers_a-tlan.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tlan.Tpo"; exit 1; fi
3169 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tlan.c' object='libdrivers_a-tlan.obj' libtool=no @AMDEPBACKSLASH@
3170 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3171 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-tlan.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-tlan.TPo' @AMDEPBACKSLASH@
3172 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3173 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tlan.obj `if test -f 'tlan.c'; then $(CYGPATH_W) 'tlan.c'; else $(CYGPATH_W) '$(srcdir)/tlan.c'; fi`
3175 libdrivers_a-tulip.o: tulip.c
3176 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tulip.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tulip.Tpo" -c -o libdrivers_a-tulip.o `test -f 'tulip.c' || echo '$(srcdir)/'`tulip.c; \
3177 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tulip.Tpo" "$(DEPDIR)/libdrivers_a-tulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tulip.Tpo"; exit 1; fi
3178 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tulip.c' object='libdrivers_a-tulip.o' libtool=no @AMDEPBACKSLASH@
3179 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3180 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-tulip.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-tulip.TPo' @AMDEPBACKSLASH@
3181 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3182 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tulip.o `test -f 'tulip.c' || echo '$(srcdir)/'`tulip.c
3184 libdrivers_a-tulip.obj: tulip.c
3185 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tulip.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tulip.Tpo" -c -o libdrivers_a-tulip.obj `if test -f 'tulip.c'; then $(CYGPATH_W) 'tulip.c'; else $(CYGPATH_W) '$(srcdir)/tulip.c'; fi`; \
3186 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-tulip.Tpo" "$(DEPDIR)/libdrivers_a-tulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tulip.Tpo"; exit 1; fi
3187 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tulip.c' object='libdrivers_a-tulip.obj' libtool=no @AMDEPBACKSLASH@
3188 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3189 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-tulip.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-tulip.TPo' @AMDEPBACKSLASH@
3190 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3191 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tulip.obj `if test -f 'tulip.c'; then $(CYGPATH_W) 'tulip.c'; else $(CYGPATH_W) '$(srcdir)/tulip.c'; fi`
3193 libdrivers_a-via-rhine.o: via-rhine.c
3194 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-via-rhine.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" -c -o libdrivers_a-via-rhine.o `test -f 'via-rhine.c' || echo '$(srcdir)/'`via-rhine.c; \
3195 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" "$(DEPDIR)/libdrivers_a-via-rhine.Po"; else rm -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo"; exit 1; fi
3196 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='via-rhine.c' object='libdrivers_a-via-rhine.o' libtool=no @AMDEPBACKSLASH@
3197 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3198 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-via-rhine.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-via-rhine.TPo' @AMDEPBACKSLASH@
3199 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3200 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-via-rhine.o `test -f 'via-rhine.c' || echo '$(srcdir)/'`via-rhine.c
3202 libdrivers_a-via-rhine.obj: via-rhine.c
3203 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-via-rhine.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" -c -o libdrivers_a-via-rhine.obj `if test -f 'via-rhine.c'; then $(CYGPATH_W) 'via-rhine.c'; else $(CYGPATH_W) '$(srcdir)/via-rhine.c'; fi`; \
3204 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" "$(DEPDIR)/libdrivers_a-via-rhine.Po"; else rm -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo"; exit 1; fi
3205 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='via-rhine.c' object='libdrivers_a-via-rhine.obj' libtool=no @AMDEPBACKSLASH@
3206 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3207 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-via-rhine.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-via-rhine.TPo' @AMDEPBACKSLASH@
3208 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3209 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-via-rhine.obj `if test -f 'via-rhine.c'; then $(CYGPATH_W) 'via-rhine.c'; else $(CYGPATH_W) '$(srcdir)/via-rhine.c'; fi`
3211 libdrivers_a-w89c840.o: w89c840.c
3212 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-w89c840.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-w89c840.Tpo" -c -o libdrivers_a-w89c840.o `test -f 'w89c840.c' || echo '$(srcdir)/'`w89c840.c; \
3213 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo" "$(DEPDIR)/libdrivers_a-w89c840.Po"; else rm -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo"; exit 1; fi
3214 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='w89c840.c' object='libdrivers_a-w89c840.o' libtool=no @AMDEPBACKSLASH@
3215 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3216 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-w89c840.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-w89c840.TPo' @AMDEPBACKSLASH@
3217 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3218 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-w89c840.o `test -f 'w89c840.c' || echo '$(srcdir)/'`w89c840.c
3220 libdrivers_a-w89c840.obj: w89c840.c
3221 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-w89c840.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-w89c840.Tpo" -c -o libdrivers_a-w89c840.obj `if test -f 'w89c840.c'; then $(CYGPATH_W) 'w89c840.c'; else $(CYGPATH_W) '$(srcdir)/w89c840.c'; fi`; \
3222 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo" "$(DEPDIR)/libdrivers_a-w89c840.Po"; else rm -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo"; exit 1; fi
3223 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='w89c840.c' object='libdrivers_a-w89c840.obj' libtool=no @AMDEPBACKSLASH@
3224 -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3225 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-w89c840.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-w89c840.TPo' @AMDEPBACKSLASH@
3226 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3227 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-w89c840.obj `if test -f 'w89c840.c'; then $(CYGPATH_W) 'w89c840.c'; else $(CYGPATH_W) '$(srcdir)/w89c840.c'; fi`
3228 -uninstall-info-am:
3230 +libdrivers_a-r8169.o: r8169.c
3231 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-r8169.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-r8169.Tpo" -c -o libdrivers_a-r8169.o `test -f 'r8169.c' || echo '$(srcdir)/'`r8169.c; \
3232 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-r8169.Tpo" "$(DEPDIR)/libdrivers_a-r8169.Po"; else rm -f "$(DEPDIR)/libdrivers_a-r8169.Tpo"; exit 1; fi
3233 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='r8169.c' object='libdrivers_a-r8169.o' libtool=no @AMDEPBACKSLASH@
3234 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-r8169.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-r8169.TPo' @AMDEPBACKSLASH@
3235 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3236 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-r8169.o `test -f 'r8169.c' || echo '$(srcdir)/'`r8169.c
3238 +libdrivers_a-r8169.obj: r8169.c
3239 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-r8169.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-r8169.Tpo" -c -o libdrivers_a-r8169.obj `if test -f 'r8169.c'; then $(CYGPATH_W) 'r8169.c'; else $(CYGPATH_W) '$(srcdir)/r8169.c'; fi`; \
3240 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-r8169.Tpo" "$(DEPDIR)/libdrivers_a-r8169.Po"; else rm -f "$(DEPDIR)/libdrivers_a-r8169.Tpo"; exit 1; fi
3241 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='r8169.c' object='libdrivers_a-r8169.obj' libtool=no @AMDEPBACKSLASH@
3242 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-r8169.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-r8169.TPo' @AMDEPBACKSLASH@
3243 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3244 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-r8169.obj `if test -f 'r8169.c'; then $(CYGPATH_W) 'r8169.c'; else $(CYGPATH_W) '$(srcdir)/r8169.c'; fi`
3246 +libdrivers_a-forcedeth.o: forcedeth.c
3247 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-forcedeth.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-forcedeth.Tpo" -c -o libdrivers_a-forcedeth.o `test -f 'forcedeth.c' || echo '$(srcdir)/'`forcedeth.c; \
3248 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-forcedeth.Tpo" "$(DEPDIR)/libdrivers_a-forcedeth.Po"; else rm -f "$(DEPDIR)/libdrivers_a-forcedeth.Tpo"; exit 1; fi
3249 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='forcedeth.c' object='libdrivers_a-forcedeth.o' libtool=no @AMDEPBACKSLASH@
3250 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-forcedeth.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-forcedeth.TPo' @AMDEPBACKSLASH@
3251 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3252 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-forcedeth.o `test -f 'forcedeth.c' || echo '$(srcdir)/'`forcedeth.c
3254 +libdrivers_a-forcedeth.obj: forcedeth.c
3255 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-forcedeth.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-forcedeth.Tpo" -c -o libdrivers_a-forcedeth.obj `if test -f 'forcedeth.c'; then $(CYGPATH_W) 'forcedeth.c'; else $(CYGPATH_W) '$(srcdir)/forcedeth.c'; fi`; \
3256 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-forcedeth.Tpo" "$(DEPDIR)/libdrivers_a-forcedeth.Po"; else rm -f "$(DEPDIR)/libdrivers_a-forcedeth.Tpo"; exit 1; fi
3257 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='forcedeth.c' object='libdrivers_a-forcedeth.obj' libtool=no @AMDEPBACKSLASH@
3258 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-forcedeth.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-forcedeth.TPo' @AMDEPBACKSLASH@
3259 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3260 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-forcedeth.obj `if test -f 'forcedeth.c'; then $(CYGPATH_W) 'forcedeth.c'; else $(CYGPATH_W) '$(srcdir)/forcedeth.c'; fi`
3262 +libdrivers_a-ns83820.o: ns83820.c
3263 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ns83820.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-ns83820.Tpo" -c -o libdrivers_a-ns83820.o `test -f 'ns83820.c' || echo '$(srcdir)/'`ns83820.c; \
3264 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-ns83820.Tpo" "$(DEPDIR)/libdrivers_a-ns83820.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ns83820.Tpo"; exit 1; fi
3265 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ns83820.c' object='libdrivers_a-ns83820.o' libtool=no @AMDEPBACKSLASH@
3266 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-ns83820.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-ns83820.TPo' @AMDEPBACKSLASH@
3267 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3268 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ns83820.o `test -f 'ns83820.c' || echo '$(srcdir)/'`ns83820.c
3270 +libdrivers_a-ns83820.obj: ns83820.c
3271 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ns83820.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-ns83820.Tpo" -c -o libdrivers_a-ns83820.obj `if test -f 'ns83820.c'; then $(CYGPATH_W) 'ns83820.c'; else $(CYGPATH_W) '$(srcdir)/ns83820.c'; fi`; \
3272 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-ns83820.Tpo" "$(DEPDIR)/libdrivers_a-ns83820.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ns83820.Tpo"; exit 1; fi
3273 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ns83820.c' object='libdrivers_a-ns83820.obj' libtool=no @AMDEPBACKSLASH@
3274 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-ns83820.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-ns83820.TPo' @AMDEPBACKSLASH@
3275 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3276 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ns83820.obj `if test -f 'ns83820.c'; then $(CYGPATH_W) 'ns83820.c'; else $(CYGPATH_W) '$(srcdir)/ns83820.c'; fi`
3278 +libdrivers_a-pnic.o: pnic.c
3279 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pnic.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pnic.Tpo" -c -o libdrivers_a-pnic.o `test -f 'pnic.c' || echo '$(srcdir)/'`pnic.c; \
3280 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pnic.Tpo" "$(DEPDIR)/libdrivers_a-pnic.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pnic.Tpo"; exit 1; fi
3281 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pnic.c' object='libdrivers_a-pnic.o' libtool=no @AMDEPBACKSLASH@
3282 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pnic.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pnic.TPo' @AMDEPBACKSLASH@
3283 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3284 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pnic.o `test -f 'pnic.c' || echo '$(srcdir)/'`pnic.c
3286 +libdrivers_a-pnic.obj: pnic.c
3287 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pnic.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pnic.Tpo" -c -o libdrivers_a-pnic.obj `if test -f 'pnic.c'; then $(CYGPATH_W) 'pnic.c'; else $(CYGPATH_W) '$(srcdir)/pnic.c'; fi`; \
3288 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pnic.Tpo" "$(DEPDIR)/libdrivers_a-pnic.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pnic.Tpo"; exit 1; fi
3289 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pnic.c' object='libdrivers_a-pnic.obj' libtool=no @AMDEPBACKSLASH@
3290 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pnic.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pnic.TPo' @AMDEPBACKSLASH@
3291 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3292 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pnic.obj `if test -f 'pnic.c'; then $(CYGPATH_W) 'pnic.c'; else $(CYGPATH_W) '$(srcdir)/pnic.c'; fi`
3294 +libdrivers_a-pnic_api.o: pnic_api.c
3295 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pnic_api.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pnic_api.Tpo" -c -o libdrivers_a-pnic_api.o `test -f 'pnic_api.c' || echo '$(srcdir)/'`pnic_api.c; \
3296 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pnic_api.Tpo" "$(DEPDIR)/libdrivers_a-pnic_api.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pnic_api.Tpo"; exit 1; fi
3297 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pnic_api.c' object='libdrivers_a-pnic_api.o' libtool=no @AMDEPBACKSLASH@
3298 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pnic_api.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pnic_api.TPo' @AMDEPBACKSLASH@
3299 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3300 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pnic_api.o `test -f 'pnic_api.c' || echo '$(srcdir)/'`pnic_api.c
3302 +libdrivers_a-pnic_api.obj: pnic_api.c
3303 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pnic_api.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pnic_api.Tpo" -c -o libdrivers_a-pnic_api.obj `if test -f 'pnic_api.c'; then $(CYGPATH_W) 'pnic_api.c'; else $(CYGPATH_W) '$(srcdir)/pnic_api.c'; fi`; \
3304 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libdrivers_a-pnic_api.Tpo" "$(DEPDIR)/libdrivers_a-pnic_api.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pnic_api.Tpo"; exit 1; fi
3305 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pnic_api.c' object='libdrivers_a-pnic_api.obj' libtool=no @AMDEPBACKSLASH@
3306 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libdrivers_a-pnic_api.Po' tmpdepfile='$(DEPDIR)/libdrivers_a-pnic_api.TPo' @AMDEPBACKSLASH@
3307 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
3308 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pnic_api.obj `if test -f 'pnic_api.c'; then $(CYGPATH_W) 'pnic_api.c'; else $(CYGPATH_W) '$(srcdir)/pnic_api.c'; fi`
3310 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
3311 list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
3312 @@ -817,11 +928,9 @@
3313 done | \
3314 $(AWK) ' { files[$$0] = 1; } \
3315 END { for (i in files) print i; }'`; \
3316 - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
3317 - test -n "$$unique" || unique=$$empty_fix; \
3318 - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
3319 - $$tags $$unique; \
3320 - fi
3321 + test -z "$(ETAGS_ARGS)$$tags$$unique" \
3322 + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
3323 + $$tags $$unique
3324 ctags: CTAGS
3325 CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
3326 $(TAGS_FILES) $(LISP)
3327 @@ -895,7 +1004,7 @@
3328 clean-generic:
3330 distclean-generic:
3331 - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
3332 + -rm -f $(CONFIG_CLEAN_FILES)
3334 maintainer-clean-generic:
3335 @echo "This command is intended for maintainers to use"
3336 @@ -962,10 +1071,10 @@
3339 # Is it really necessary to specify dependecies explicitly?
3340 -$(3c509_drivers): 3c509.c 3c509.h
3341 -$(3c509_drivers): %.o: 3c509.c
3342 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3343 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3344 +#$(3c509_drivers): 3c509.c 3c509.h
3345 +#$(3c509_drivers): %.o: 3c509.c
3346 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3347 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3349 $(3c595_drivers): 3c595.c 3c595.h
3350 $(3c595_drivers): %.o: 3c595.c
3351 @@ -977,23 +1086,28 @@
3352 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3353 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3355 -$(cs89x0_drivers): cs89x0.c cs89x0.h
3356 -$(cs89x0_drivers): %.o: cs89x0.c
3357 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3358 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3359 +#$(cs89x0_drivers): cs89x0.c cs89x0.h
3360 +#$(cs89x0_drivers): %.o: cs89x0.c
3361 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3362 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3364 $(davicom_drivers): davicom.c
3365 $(davicom_drivers): %.o: davicom.c
3366 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3367 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3369 -$(depca_drivers): depca.c
3370 -$(depca_drivers): %.o: depca.c
3371 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3372 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3373 +#$(depca_drivers): depca.c
3374 +#$(depca_drivers): %.o: depca.c
3375 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3376 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3378 -$(eepro_drivers): eepro.c
3379 -$(eepro_drivers): %.o: eepro.c
3380 +#$(eepro_drivers): eepro.c
3381 +#$(eepro_drivers): %.o: eepro.c
3382 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3383 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3385 +$(e1000_drivers): e1000.c e1000_hw.h
3386 +$(e1000_drivers): %.o: e1000.c
3387 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3388 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3390 @@ -1007,28 +1121,38 @@
3391 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3392 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3394 +$(forcedeth_drivers): forcedeth.c
3395 +$(forcedeth_drivers): %.o: forcedeth.c
3396 + $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3397 + $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3399 #$(fa311_drivers): fa311.c
3400 #$(fa311_drivers): %.o: fa311.c
3401 # $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3402 # $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3404 -$(i82586_drivers): i82586.c
3405 -$(i82586_drivers): %.o: i82586.c
3406 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3407 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3408 +#$(i82586_drivers): i82586.c
3409 +#$(i82586_drivers): %.o: i82586.c
3410 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3411 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3413 -$(lance_drivers): lance.c
3414 -$(lance_drivers): %.o: lance.c
3415 - $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3416 - $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3417 +#$(lance_drivers): lance.c
3418 +#$(lance_drivers): %.o: lance.c
3419 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3420 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3422 $(natsemi_drivers): natsemi.c
3423 $(natsemi_drivers): %.o: natsemi.c
3424 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3425 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3427 -$(ni5010_drivers): ni5010.c
3428 -$(ni5010_drivers): %.o: ni5010.c
3429 +#$(ni5010_drivers): ni5010.c
3430 +#$(ni5010_drivers): %.o: ni5010.c
3431 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3432 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3434 +$(ns83820_drivers): ns83820.c
3435 +$(ns83820_drivers): %.o: ns83820.c
3436 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3437 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3439 @@ -1037,41 +1161,62 @@
3440 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3441 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3443 -$(otulip_drivers): otulip.c otulip.h
3444 -$(otulip_drivers): %.o: otulip.c
3445 +#$(otulip_drivers): otulip.c otulip.h
3446 +#$(otulip_drivers): %.o: otulip.c
3447 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3448 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3450 +$(pcnet32_drivers): pcnet32.c
3451 +$(pcnet32_drivers): %.o: pcnet32.c
3452 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3453 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3455 -$(rtl8139_drivers): rtl8139.c
3456 -$(rtl8139_drivers): %.o: rtl8139.c
3457 +$(pnic_drivers): pnic.c
3458 +$(pnic_drivers): %.o: pnic.c pnic_api.h
3459 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3460 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3462 -$(sis900_drivers): sis900.c
3463 -$(sis900_drivers): %.o: sis900.c sis900.h
3464 +$(rtl8139_drivers): rtl8139.c
3465 +$(rtl8139_drivers): %.o: rtl8139.c
3466 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3467 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3469 -$(sk_g16_drivers): sk_g16.c sk_g16.h
3470 -$(sk_g16_drivers): %.o: sk_g16.c
3471 +$(r8169_drivers): r8169.c
3472 +$(r8169_drivers): %.o: r8169.c
3473 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3474 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3476 -$(smc9000_drivers): smc9000.c smc9000.h
3477 -$(smc9000_drivers): %.o: smc9000.c
3478 +$(sis900_drivers): sis900.c sis900.h
3479 +$(sis900_drivers): %.o: sis900.c
3480 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3481 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3483 -$(tiara_drivers): tiara.c
3484 -$(tiara_drivers): %.o: tiara.c
3485 +#$(sk_g16_drivers): sk_g16.c sk_g16.h
3486 +#$(sk_g16_drivers): %.o: sk_g16.c
3487 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3488 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3490 +#$(smc9000_drivers): smc9000.c smc9000.h
3491 +#$(smc9000_drivers): %.o: smc9000.c
3492 +# $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3493 +# $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3496 +$(tg3_drivers): tg3.c tg3.h
3497 +$(tg3_drivers): %.o: tg3.c
3498 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3499 $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3501 -#$(tlan_drivers): tlan.c
3502 -#$(tlan_drivers): %.o: tlan.c
3503 +#$(tiara_drivers): tiara.c
3504 +#$(tiara_drivers): %.o: tiara.c
3505 # $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3506 # $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3508 +$(tlan_drivers): tlan.c tlan.h
3509 +$(tlan_drivers): %.o: tlan.c
3510 + $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3511 + $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
3513 $(tulip_drivers): tulip.c
3514 $(tulip_drivers): %.o: tulip.c
3515 $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
3516 Index: b/netboot/basemem.c
3517 ===================================================================
3518 --- /dev/null
3519 +++ b/netboot/basemem.c
3520 @@ -0,0 +1,178 @@
3521 +#include "etherboot.h"
3522 +#define DEBUG_BASEMEM
3523 +/* Routines to allocate base memory in a BIOS-compatible way, by
3524 + * updating the Free Base Memory Size counter at 40:13h.
3526 + * Michael Brown <mbrown@fensystems.co.uk> (mcb30)
3527 + * $Id: grub-0.95-diskless-patch-2-undi.patch,v 1.1.1.1 2005/06/14 08:18:50 wesolows Exp $
3528 + */
3530 +#define fbms ( ( uint16_t * ) phys_to_virt ( 0x413 ) )
3531 +#define BASE_MEMORY_MAX ( 640 )
3532 +#define FREE_BLOCK_MAGIC ( ('!'<<0) + ('F'<<8) + ('R'<<16) + ('E'<<24) )
3534 +typedef struct free_base_memory_block {
3535 + uint32_t magic;
3536 + uint16_t size_kb;
3537 +} free_base_memory_block_t;
3539 +/* Return amount of free base memory in bytes
3540 + */
3542 +uint32_t get_free_base_memory ( void ) {
3543 + return *fbms << 10;
3546 +/* Adjust the real mode stack pointer. We keep the real mode stack at
3547 + * the top of free base memory, rather than allocating space for it.
3548 + */
3550 +inline void adjust_real_mode_stack ( void ) {
3551 +/* real_mode_stack = ( *fbms << 10 ); */
3554 +/* Allocate N bytes of base memory. Amount allocated will be rounded
3555 + * up to the nearest kB, since that's the granularity of the BIOS FBMS
3556 + * counter. Returns NULL if memory cannot be allocated.
3557 + */
3559 +void * allot_base_memory ( size_t size ) {
3560 + uint16_t size_kb = ( size + 1023 ) >> 10;
3561 + void *ptr = NULL;
3563 +#ifdef DEBUG_BASEMEM
3564 + printf ( "Trying to allocate %d kB of base memory, %d kB free\n",
3565 + size_kb, *fbms );
3566 +#endif
3568 + /* Free up any unused memory before we start */
3569 + free_unused_base_memory();
3571 + /* Check available base memory */
3572 + if ( size_kb > *fbms ) { return NULL; }
3574 + /* Reduce available base memory */
3575 + *fbms -= size_kb;
3577 + /* Calculate address of memory allocated */
3578 + ptr = phys_to_virt ( *fbms << 10 );
3580 +#ifdef DEBUG_BASEMEM
3581 + /* Zero out memory. We do this so that allocation of
3582 + * already-used space will show up in the form of a crash as
3583 + * soon as possible.
3584 + */
3585 + memset ( ptr, 0, size_kb << 10 );
3586 +#endif
3588 + /* Adjust real mode stack pointer */
3589 + adjust_real_mode_stack ();
3591 + return ptr;
3594 +/* Free base memory allocated by allot_base_memory. The BIOS provides
3595 + * nothing better than a LIFO mechanism for freeing memory (i.e. it
3596 + * just has the single "total free memory" counter), but we improve
3597 + * upon this slightly; as long as you free all the allotted blocks, it
3598 + * doesn't matter what order you free them in. (This will only work
3599 + * for blocks that are freed via forget_base_memory()).
3601 + * Yes, it's annoying that you have to remember the size of the blocks
3602 + * you've allotted. However, since our granularity of allocation is
3603 + * 1K, the alternative is to risk wasting the occasional kB of base
3604 + * memory, which is a Bad Thing. Really, you should be using as
3605 + * little base memory as possible, so consider the awkwardness of the
3606 + * API to be a feature! :-)
3607 + */
3609 +void forget_base_memory ( void *ptr, size_t size ) {
3610 + uint16_t remainder = virt_to_phys(ptr) & 1023;
3611 + uint16_t size_kb = ( size + remainder + 1023 ) >> 10;
3612 + free_base_memory_block_t *free_block =
3613 + ( free_base_memory_block_t * ) ( ptr - remainder );
3615 + if ( ( ptr == NULL ) || ( size == 0 ) ) { return; }
3617 +#ifdef DEBUG_BASEMEM
3618 + printf ( "Trying to free %d bytes base memory at 0x%x\n",
3619 + size, virt_to_phys ( ptr ) );
3620 + if ( remainder > 0 ) {
3621 + printf ( "WARNING: destructively expanding free block "
3622 + "downwards to 0x%x\n",
3623 + virt_to_phys ( ptr - remainder ) );
3625 +#endif
3627 + /* Mark every kilobyte within this block as free. This is
3628 + * overkill for normal purposes, but helps when something has
3629 + * allocated base memory with a granularity finer than the
3630 + * BIOS granularity of 1kB. PXE ROMs tend to do this when
3631 + * they allocate their own memory. This method allows us to
3632 + * free their blocks (admittedly in a rather dangerous,
3633 + * tread-on-anything-either-side sort of way, but there's no
3634 + * other way to do it).
3636 + * Since we're marking every kB as free, there's actually no
3637 + * need for recording the size of the blocks. However, we
3638 + * keep this in so that debug messages are friendlier. It
3639 + * probably adds around 8 bytes to the overall code size.
3640 + */
3641 + while ( size_kb > 0 ) {
3642 + /* Mark this block as unused */
3643 + free_block->magic = FREE_BLOCK_MAGIC;
3644 + free_block->size_kb = size_kb;
3645 + /* Move up by 1 kB */
3646 + (void *)(free_block += ( 1 << 10 ));
3647 + size_kb--;
3650 + /* Free up unused base memory */
3651 + free_unused_base_memory();
3654 +/* Do the actual freeing of memory. This is split out from
3655 + * forget_base_memory() so that it may be called separately. It
3656 + * should be called whenever base memory is deallocated by an external
3657 + * entity (if we can detect that it has done so) so that we get the
3658 + * chance to free up our own blocks.
3659 + */
3660 +void free_unused_base_memory ( void ) {
3661 + free_base_memory_block_t *free_block = NULL;
3663 + /* Try to release memory back to the BIOS. Free all
3664 + * consecutive blocks marked as free.
3665 + */
3666 + while ( 1 ) {
3667 + /* Calculate address of next potential free block */
3668 + free_block = ( free_base_memory_block_t * )
3669 + phys_to_virt ( *fbms << 10 );
3671 + /* Stop processing if we're all the way up to 640K or
3672 + * if this is not a free block
3673 + */
3674 + if ( ( *fbms == BASE_MEMORY_MAX ) ||
3675 + ( free_block->magic != FREE_BLOCK_MAGIC ) ) {
3676 + break;
3679 + /* Return memory to BIOS */
3680 + *fbms += free_block->size_kb;
3682 +#ifdef DEBUG_BASEMEM
3683 + printf ( "Freed %d kB base memory, %d kB now free\n",
3684 + free_block->size_kb, *fbms );
3686 + /* Zero out freed block. We do this in case
3687 + * the block contained any structures that
3688 + * might be located by scanning through
3689 + * memory.
3690 + */
3691 + memset ( free_block, 0, free_block->size_kb << 10 );
3692 +#endif
3695 + /* Adjust real mode stack pointer */
3696 + adjust_real_mode_stack ();
3699 Index: b/netboot/big_bswap.h
3700 ===================================================================
3701 --- /dev/null
3702 +++ b/netboot/big_bswap.h
3703 @@ -0,0 +1,17 @@
3704 +#ifndef ETHERBOOT_BIG_BSWAP_H
3705 +#define ETHERBOOT_BIG_BSWAP_H
3707 +#define ntohl(x) (x)
3708 +#define htonl(x) (x)
3709 +#define ntohs(x) (x)
3710 +#define htons(x) (x)
3711 +#define cpu_to_le32(x) __bswap_32(x)
3712 +#define cpu_to_le16(x) __bswap_16(x)
3713 +#define cpu_to_be32(x) (x)
3714 +#define cpu_to_be16(x) (x)
3715 +#define le32_to_cpu(x) __bswap_32(x)
3716 +#define le16_to_cpu(x) __bswap_16(x)
3717 +#define be32_to_cpu(x) (x)
3718 +#define be16_to_cpu(x) (x)
3720 +#endif /* ETHERBOOT_BIG_BSWAP_H */
3721 Index: b/netboot/bootp.h
3722 ===================================================================
3723 --- /dev/null
3724 +++ b/netboot/bootp.h
3725 @@ -0,0 +1,182 @@
3726 +#ifndef _BOOTP_H
3727 +#define _BOOTP_H
3729 +#include "if_ether.h"
3730 +#include "ip.h"
3731 +#include "udp.h"
3733 +#ifndef MAX_BOOTP_RETRIES
3734 +#define MAX_BOOTP_RETRIES 20
3735 +#endif
3737 +#ifdef ALTERNATE_DHCP_PORTS_1067_1068
3738 +#undef NON_STANDARD_BOOTP_SERVER
3739 +#define NON_STANDARD_BOOTP_SERVER 1067
3740 +#undef NON_STANDARD_BOOTP_CLIENT
3741 +#define NON_STANDARD_BOOTP_CLIENT 1068
3742 +#endif
3744 +#ifdef NON_STANDARD_BOOTP_SERVER
3745 +#define BOOTP_SERVER NON_STANDARD_BOOTP_SERVER
3746 +#else
3747 +#define BOOTP_SERVER 67
3748 +#endif
3749 +#ifdef NON_STANDARD_BOOTP_CLIENT
3750 +#define BOOTP_CLIENT NON_STANDARD_BOOTP_CLIENT
3751 +#else
3752 +#define BOOTP_CLIENT 68
3753 +#endif
3755 +#define BOOTP_REQUEST 1
3756 +#define BOOTP_REPLY 2
3758 +#define TAG_LEN(p) (*((p)+1))
3759 +#define RFC1533_COOKIE 99, 130, 83, 99
3760 +#define RFC1533_PAD 0
3761 +#define RFC1533_NETMASK 1
3762 +#define RFC1533_TIMEOFFSET 2
3763 +#define RFC1533_GATEWAY 3
3764 +#define RFC1533_TIMESERVER 4
3765 +#define RFC1533_IEN116NS 5
3766 +#define RFC1533_DNS 6
3767 +#define RFC1533_LOGSERVER 7
3768 +#define RFC1533_COOKIESERVER 8
3769 +#define RFC1533_LPRSERVER 9
3770 +#define RFC1533_IMPRESSSERVER 10
3771 +#define RFC1533_RESOURCESERVER 11
3772 +#define RFC1533_HOSTNAME 12
3773 +#define RFC1533_BOOTFILESIZE 13
3774 +#define RFC1533_MERITDUMPFILE 14
3775 +#define RFC1533_DOMAINNAME 15
3776 +#define RFC1533_SWAPSERVER 16
3777 +#define RFC1533_ROOTPATH 17
3778 +#define RFC1533_EXTENSIONPATH 18
3779 +#define RFC1533_IPFORWARDING 19
3780 +#define RFC1533_IPSOURCEROUTING 20
3781 +#define RFC1533_IPPOLICYFILTER 21
3782 +#define RFC1533_IPMAXREASSEMBLY 22
3783 +#define RFC1533_IPTTL 23
3784 +#define RFC1533_IPMTU 24
3785 +#define RFC1533_IPMTUPLATEAU 25
3786 +#define RFC1533_INTMTU 26
3787 +#define RFC1533_INTLOCALSUBNETS 27
3788 +#define RFC1533_INTBROADCAST 28
3789 +#define RFC1533_INTICMPDISCOVER 29
3790 +#define RFC1533_INTICMPRESPOND 30
3791 +#define RFC1533_INTROUTEDISCOVER 31
3792 +#define RFC1533_INTROUTESOLICIT 32
3793 +#define RFC1533_INTSTATICROUTES 33
3794 +#define RFC1533_LLTRAILERENCAP 34
3795 +#define RFC1533_LLARPCACHETMO 35
3796 +#define RFC1533_LLETHERNETENCAP 36
3797 +#define RFC1533_TCPTTL 37
3798 +#define RFC1533_TCPKEEPALIVETMO 38
3799 +#define RFC1533_TCPKEEPALIVEGB 39
3800 +#define RFC1533_NISDOMAIN 40
3801 +#define RFC1533_NISSERVER 41
3802 +#define RFC1533_NTPSERVER 42
3803 +#define RFC1533_VENDOR 43
3804 +#define RFC1533_NBNS 44
3805 +#define RFC1533_NBDD 45
3806 +#define RFC1533_NBNT 46
3807 +#define RFC1533_NBSCOPE 47
3808 +#define RFC1533_XFS 48
3809 +#define RFC1533_XDM 49
3810 +#ifndef NO_DHCP_SUPPORT
3811 +#define RFC2132_REQ_ADDR 50
3812 +#define RFC2132_MSG_TYPE 53
3813 +#define RFC2132_SRV_ID 54
3814 +#define RFC2132_PARAM_LIST 55
3815 +#define RFC2132_MAX_SIZE 57
3816 +#define RFC2132_VENDOR_CLASS_ID 60
3818 +#define DHCPDISCOVER 1
3819 +#define DHCPOFFER 2
3820 +#define DHCPREQUEST 3
3821 +#define DHCPACK 5
3822 +#endif /* NO_DHCP_SUPPORT */
3824 +#define RFC1533_VENDOR_MAJOR 0
3825 +#define RFC1533_VENDOR_MINOR 0
3827 +#define RFC1533_VENDOR_MAGIC 128
3828 +#define RFC1533_VENDOR_ADDPARM 129
3829 +#define RFC1533_VENDOR_ETHDEV 130
3830 +#ifdef IMAGE_FREEBSD
3831 +#define RFC1533_VENDOR_HOWTO 132
3832 +#define RFC1533_VENDOR_KERNEL_ENV 133
3833 +#endif
3834 +#define RFC1533_VENDOR_ETHERBOOT_ENCAP 150
3835 +#define RFC1533_VENDOR_MNUOPTS 160
3836 +#define RFC1533_VENDOR_NIC_DEV_ID 175
3837 +#define RFC1533_VENDOR_SELECTION 176
3838 +#define RFC1533_VENDOR_ARCH 177
3839 +#define RFC1533_VENDOR_MOTD 184
3840 +#define RFC1533_VENDOR_NUMOFMOTD 8
3841 +#define RFC1533_VENDOR_IMG 192
3842 +#define RFC1533_VENDOR_NUMOFIMG 16
3844 +#define RFC1533_VENDOR_CONFIGFILE 150
3846 +#define RFC1533_END 255
3848 +#define BOOTP_VENDOR_LEN 64
3850 +#define DHCP_OPT_LEN 312
3852 +/* Format of a bootp packet */
3853 +struct bootp_t {
3854 + uint8_t bp_op;
3855 + uint8_t bp_htype;
3856 + uint8_t bp_hlen;
3857 + uint8_t bp_hops;
3858 + uint32_t bp_xid;
3859 + uint16_t bp_secs;
3860 + uint16_t unused;
3861 + in_addr bp_ciaddr;
3862 + in_addr bp_yiaddr;
3863 + in_addr bp_siaddr;
3864 + in_addr bp_giaddr;
3865 + uint8_t bp_hwaddr[16];
3866 + uint8_t bp_sname[64];
3867 + char bp_file[128];
3868 + uint8_t bp_vend[BOOTP_VENDOR_LEN];
3871 +struct dhcp_t {
3872 + uint8_t bp_op;
3873 + uint8_t bp_htype;
3874 + uint8_t bp_hlen;
3875 + uint8_t bp_hops;
3876 + uint32_t bp_xid;
3877 + uint16_t bp_secs;
3878 + uint16_t bp_flag;
3879 + in_addr bp_ciaddr;
3880 + in_addr bp_yiaddr;
3881 + in_addr bp_siaddr;
3882 + in_addr bp_giaddr;
3883 + uint8_t bp_hwaddr[16];
3884 + uint8_t bp_sname[64];
3885 + char bp_file[128];
3886 + uint8_t bp_vend[DHCP_OPT_LEN];
3889 +/* Format of a bootp IP packet */
3890 +struct bootpip_t
3892 + struct iphdr ip;
3893 + struct udphdr udp;
3894 + struct bootp_t bp;
3896 +struct dhcpip_t
3898 + struct iphdr ip;
3899 + struct udphdr udp;
3900 + struct dhcp_t bp;
3903 +#define MAX_RFC1533_VENDLEN (ETH_MAX_MTU - sizeof(struct bootpip_t) + BOOTP_VENDOR_LEN)
3905 +#define BOOTP_DATA_ADDR (&bootp_data)
3907 +#endif /* _BOOTP_H */
3908 Index: b/netboot/byteswap.h
3909 ===================================================================
3910 --- /dev/null
3911 +++ b/netboot/byteswap.h
3912 @@ -0,0 +1,20 @@
3913 +#ifndef ETHERBOOT_BYTESWAP_H
3914 +#define ETHERBOOT_BYTESWAP_H
3916 +#include "endian.h"
3917 +#include "i386_byteswap.h"
3919 +#if __BYTE_ORDER == __LITTLE_ENDIAN
3920 +#include "little_bswap.h"
3921 +#endif
3922 +#if __BYTE_ORDER == __BIG_ENDIAN
3923 +#include "big_bswap.h"
3924 +#endif
3926 +/* Make routines available to all */
3927 +#define swap32(x) __bswap_32(x)
3928 +#define swap16(x) __bswap_16(x)
3929 +#define bswap_32(x) __bswap_32(x)
3930 +#define bswap_16(x) __bswap_16(x)
3932 +#endif /* ETHERBOOT_BYTESWAP_H */
3933 Index: b/netboot/cards.h
3934 ===================================================================
3935 --- a/netboot/cards.h
3936 +++ /dev/null
3937 @@ -1,183 +0,0 @@
3938 -#ifndef CARDS_H
3939 -#define CARDS_H
3942 - * This program is free software; you can redistribute it and/or
3943 - * modify it under the terms of the GNU General Public License as
3944 - * published by the Free Software Foundation; either version 2, or (at
3945 - * your option) any later version.
3946 - */
3948 -#include "nic.h"
3950 -/* OK, this is how the PCI support hack works: if pci.h is included before
3951 - * this file is included, assume that the driver supports PCI. This means that
3952 - * this file is usually included last. */
3954 -#ifdef PCI_H
3955 -#define PCI_ARG(x) ,x
3956 -#else
3957 -#define PCI_ARG(x)
3958 -#endif
3960 -#ifdef INCLUDE_WD
3961 -extern struct nic *wd_probe(struct nic *, unsigned short *
3962 - PCI_ARG(struct pci_device *));
3963 -#endif
3965 -#ifdef INCLUDE_3C503
3966 -extern struct nic *t503_probe(struct nic *, unsigned short *
3967 - PCI_ARG(struct pci_device *));
3968 -#endif
3970 -#ifdef INCLUDE_VIA_RHINE
3971 -extern struct nic *rhine_probe(struct nic *, unsigned short *
3972 - PCI_ARG(struct pci_device *));
3973 -#endif
3975 -#ifdef INCLUDE_NE
3976 -extern struct nic *ne_probe(struct nic *, unsigned short *
3977 - PCI_ARG(struct pci_device *));
3978 -#endif
3980 -#ifdef INCLUDE_NS8390
3981 -extern struct nic *nepci_probe(struct nic *, unsigned short *
3982 - PCI_ARG(struct pci_device *));
3983 -#endif
3985 -#ifdef INCLUDE_3C509
3986 -extern struct nic *t509_probe(struct nic *, unsigned short *
3987 - PCI_ARG(struct pci_device *));
3988 -#endif
3990 -#ifdef INCLUDE_3C529
3991 -extern struct nic *t529_probe(struct nic *, unsigned short *
3992 - PCI_ARG(struct pci_device *));
3993 -#endif
3995 -#ifdef INCLUDE_3C595
3996 -extern struct nic *t595_probe(struct nic *, unsigned short *
3997 - PCI_ARG(struct pci_device *));
3998 -#endif
4000 -#ifdef INCLUDE_3C90X
4001 -extern struct nic *a3c90x_probe(struct nic *, unsigned short *
4002 - PCI_ARG(struct pci_device *));
4003 -#endif
4005 -#ifdef INCLUDE_EEPRO
4006 -extern struct nic *eepro_probe(struct nic *, unsigned short *
4007 - PCI_ARG(struct pci_device *));
4008 -#endif
4010 -#ifdef INCLUDE_EEPRO100
4011 -extern struct nic *eepro100_probe(struct nic *, unsigned short *
4012 - PCI_ARG(struct pci_device *));
4013 -#endif
4015 -#ifdef INCLUDE_EPIC100
4016 -extern struct nic *epic100_probe(struct nic *, unsigned short *
4017 - PCI_ARG(struct pci_device *));
4018 -#endif
4020 -#ifdef INCLUDE_OTULIP
4021 -extern struct nic *otulip_probe(struct nic *, unsigned short *
4022 - PCI_ARG(struct pci_device *));
4023 -#endif
4025 -#ifdef INCLUDE_TULIP
4026 -extern struct nic *tulip_probe(struct nic *, unsigned short *
4027 - PCI_ARG(struct pci_device *));
4028 -#endif
4030 -#ifdef INCLUDE_DAVICOM
4031 -extern struct nic *davicom_probe(struct nic *, unsigned short *
4032 - PCI_ARG(struct pci_device *));
4033 -#endif
4035 -#ifdef INCLUDE_CS89X0
4036 -extern struct nic *cs89x0_probe(struct nic *, unsigned short *
4037 - PCI_ARG(struct pci_device *));
4038 -#endif
4040 -#ifdef INCLUDE_LANCE
4041 -extern struct nic *lancepci_probe(struct nic *, unsigned short *
4042 - PCI_ARG(struct pci_device *));
4043 -#endif
4045 -#ifdef INCLUDE_NE2100
4046 -extern struct nic *ne2100_probe(struct nic *, unsigned short *
4047 - PCI_ARG(struct pci_device *));
4048 -#endif
4050 -#ifdef INCLUDE_NI6510
4051 -extern struct nic *ni6510_probe(struct nic *, unsigned short *
4052 - PCI_ARG(struct pci_device *));
4053 -#endif
4055 -#ifdef INCLUDE_SK_G16
4056 -extern struct nic *SK_probe(struct nic *, unsigned short *
4057 - PCI_ARG(struct pci_device *));
4058 -#endif
4060 -#ifdef INCLUDE_3C507
4061 -extern struct nic *t507_probe(struct nic *, unsigned short *
4062 - PCI_ARG(struct pci_device *));
4063 -#endif
4065 -#ifdef INCLUDE_NI5010
4066 -extern struct nic *ni5010_probe(struct nic *, unsigned short *
4067 - PCI_ARG(struct pci_device *));
4068 -#endif
4070 -#ifdef INCLUDE_NI5210
4071 -extern struct nic *ni5210_probe(struct nic *, unsigned short *
4072 - PCI_ARG(struct pci_device *));
4073 -#endif
4075 -#ifdef INCLUDE_EXOS205
4076 -extern struct nic *exos205_probe(struct nic *, unsigned short *
4077 - PCI_ARG(struct pci_device *));
4078 -#endif
4080 -#ifdef INCLUDE_SMC9000
4081 -extern struct nic *smc9000_probe(struct nic *, unsigned short *
4082 - PCI_ARG(struct pci_device *));
4083 -#endif
4085 -#ifdef INCLUDE_TIARA
4086 -extern struct nic *tiara_probe(struct nic *, unsigned short *
4087 - PCI_ARG(struct pci_device *));
4088 -#endif
4090 -#ifdef INCLUDE_DEPCA
4091 -extern struct nic *depca_probe(struct nic *, unsigned short *
4092 - PCI_ARG(struct pci_device *));
4093 -#endif
4095 -#ifdef INCLUDE_RTL8139
4096 -extern struct nic *rtl8139_probe(struct nic *, unsigned short *
4097 - PCI_ARG(struct pci_device *));
4098 -#endif
4100 -#ifdef INCLUDE_W89C840
4101 -extern struct nic *w89c840_probe(struct nic *, unsigned short *
4102 - PCI_ARG(struct pci_device *));
4103 -#endif
4105 -#ifdef INCLUDE_SIS900
4106 -extern struct nic *sis900_probe(struct nic *, unsigned short *
4107 - PCI_ARG(struct pci_device *));
4108 -#endif
4110 -#ifdef INCLUDE_NATSEMI
4111 -extern struct nic *natsemi_probe(struct nic *, unsigned short *
4112 - PCI_ARG(struct pci_device *));
4113 -#endif
4115 -#ifdef INCLUDE_TLAN
4116 -extern struct nic *tlan_probe(struct nic *, unsigned short *
4117 - PCI_ARG(struct pci_device *));
4118 -#endif
4120 -#endif /* CARDS_H */
4121 Index: b/netboot/config.c
4122 ===================================================================
4123 --- a/netboot/config.c
4124 +++ b/netboot/config.c
4125 @@ -1,598 +1,165 @@
4127 - * GRUB -- GRand Unified Bootloader
4128 - * Copyright (C) 2001,2002 Free Software Foundation, Inc.
4130 - * This program is free software; you can redistribute it and/or modify
4131 - * it under the terms of the GNU General Public License as published by
4132 - * the Free Software Foundation; either version 2 of the License, or
4133 - * (at your option) any later version.
4135 - * This program is distributed in the hope that it will be useful,
4136 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4137 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4138 - * GNU General Public License for more details.
4140 - * You should have received a copy of the GNU General Public License
4141 - * along with this program; if not, write to the Free Software
4142 - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
4143 - */
4145 -/* Based on "src/config.c" in etherboot-5.0.5. */
4148 * This program is free software; you can redistribute it and/or
4149 * modify it under the terms of the GNU General Public License as
4150 * published by the Free Software Foundation; either version 2, or (at
4151 * your option) any later version.
4154 -#define GRUB 1
4155 -#include <etherboot.h>
4156 -#include <nic.h>
4157 +#include "grub.h"
4158 +#include "pci.h"
4159 +#include "isa.h"
4160 +#include "nic.h"
4162 -#undef INCLUDE_PCI
4163 -#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI) || defined(INCLUDE_TLAN)
4164 - /* || others later */
4165 -# define INCLUDE_PCI
4166 -# include <pci.h>
4167 -static unsigned short pci_ioaddrs[16];
4169 -static struct pci_device pci_nic_list[] =
4170 +#ifdef CONFIG_PCI
4171 +static int pci_probe(struct dev *dev, const char *type_name)
4173 -#ifdef INCLUDE_NS8390
4174 - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029,
4175 - "Realtek 8029", 0, 0, 0, 0},
4176 - { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940,
4177 - "Winbond NE2000-PCI", 0, 0, 0, 0},
4178 - { PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000,
4179 - "Compex ReadyLink 2000", 0, 0, 0, 0},
4180 - { PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2,
4181 - "KTI ET32P2", 0, 0, 0, 0},
4182 - { PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC,
4183 - "NetVin NV5000SC", 0, 0, 0, 0},
4184 - { PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_HT80232,
4185 - "Holtek HT80232", 0, 0, 0, 0},
4186 -#endif
4187 -#ifdef INCLUDE_3C90X
4188 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
4189 - "3Com900-TPO", 0, 0, 0, 0},
4190 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
4191 - "3Com900-Combo", 0, 0, 0, 0},
4192 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX,
4193 - "3Com905-TX", 0, 0, 0, 0},
4194 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4,
4195 - "3Com905-T4", 0, 0, 0, 0},
4196 - { PCI_VENDOR_ID_3COM, 0x9004,
4197 - "3Com900B-TPO", 0, 0, 0, 0},
4198 - { PCI_VENDOR_ID_3COM, 0x9005,
4199 - "3Com900B-Combo", 0, 0, 0, 0},
4200 - { PCI_VENDOR_ID_3COM, 0x9006,
4201 - "3Com900B-2/T", 0, 0, 0, 0},
4202 - { PCI_VENDOR_ID_3COM, 0x900A,
4203 - "3Com900B-FL", 0, 0, 0, 0},
4204 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX,
4205 - "3Com905B-TX", 0, 0, 0, 0},
4206 - { PCI_VENDOR_ID_3COM, 0x9056,
4207 - "3Com905B-T4", 0, 0, 0, 0},
4208 - { PCI_VENDOR_ID_3COM, 0x905A,
4209 - "3Com905B-FL", 0, 0, 0, 0},
4210 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM,
4211 - "3Com905C-TXM", 0, 0, 0, 0},
4212 - { PCI_VENDOR_ID_3COM, 0x9800,
4213 - "3Com980-Cyclone", 0, 0, 0, 0},
4214 - { PCI_VENDOR_ID_3COM, 0x9805,
4215 - "3Com9805", 0, 0, 0, 0},
4216 - { PCI_VENDOR_ID_3COM, 0x7646,
4217 - "3CSOHO100-TX", 0, 0, 0, 0},
4218 -#endif
4219 -#ifdef INCLUDE_3C595
4220 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590,
4221 - "3Com590", 0, 0, 0, 0},
4222 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595,
4223 - "3Com595", 0, 0, 0, 0},
4224 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_1,
4225 - "3Com595", 0, 0, 0, 0},
4226 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_2,
4227 - "3Com595", 0, 0, 0, 0},
4228 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO,
4229 - "3Com900-TPO", 0, 0, 0, 0},
4230 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO,
4231 - "3Com900-Combo", 0, 0, 0, 0},
4232 - { PCI_VENDOR_ID_3COM, 0x9004,
4233 - "3Com900B-TPO", 0, 0, 0, 0},
4234 - { PCI_VENDOR_ID_3COM, 0x9005,
4235 - "3Com900B-Combo", 0, 0, 0, 0},
4236 - { PCI_VENDOR_ID_3COM, 0x9006,
4237 - "3Com900B-2/T", 0, 0, 0, 0},
4238 - { PCI_VENDOR_ID_3COM, 0x900A,
4239 - "3Com900B-FL", 0, 0, 0, 0},
4240 - { PCI_VENDOR_ID_3COM, 0x9800,
4241 - "3Com980-Cyclone", 0, 0, 0, 0},
4242 - { PCI_VENDOR_ID_3COM, 0x9805,
4243 - "3Com9805", 0, 0, 0, 0},
4244 - { PCI_VENDOR_ID_3COM, 0x7646,
4245 - "3CSOHO100-TX", 0, 0, 0, 0},
4246 -#endif
4247 -#ifdef INCLUDE_EEPRO100
4248 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557,
4249 - "Intel EtherExpressPro100", 0, 0, 0, 0},
4250 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER,
4251 - "Intel EtherExpressPro100 82559ER", 0, 0, 0, 0},
4252 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029,
4253 - "Intel EtherExpressPro100 ID1029", 0, 0, 0, 0},
4254 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030,
4255 - "Intel Corporation 82559 InBusiness 10/100", 0, 0, 0, 0},
4256 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562,
4257 - "Intel EtherExpressPro100 82562EM", 0, 0, 0, 0},
4258 -#endif
4259 -#ifdef INCLUDE_EPIC100
4260 - { PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100,
4261 - "SMC EtherPowerII", 0, 0, 0, 0},
4262 -#endif
4263 -#ifdef INCLUDE_LANCE
4264 - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
4265 - "AMD Lance/PCI", 0, 0, 0, 0},
4266 - { PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA,
4267 - "AMD Lance/HomePNA", 0, 0, 0, 0},
4268 -#endif
4269 -#ifdef INCLUDE_RTL8139
4270 - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
4271 - "Realtek 8139", 0, 0, 0, 0},
4272 - { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DFE530TXP,
4273 - "DFE530TX+/DFE538TX", 0, 0, 0, 0},
4274 - { PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211,
4275 - "SMC EZ10/100", 0, 0, 0, 0},
4276 -#endif
4277 -#ifdef INCLUDE_OTULIP
4278 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
4279 - "Digital Tulip", 0, 0, 0, 0},
4280 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
4281 - "Digital Tulip Fast", 0, 0, 0, 0},
4282 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
4283 - "Digital Tulip+", 0, 0, 0, 0},
4284 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
4285 - "Digital Tulip 21142", 0, 0, 0, 0},
4286 -#endif
4287 -#ifdef INCLUDE_TULIP
4288 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP,
4289 - "Digital Tulip", 0, 0, 0, 0},
4290 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST,
4291 - "Digital Tulip Fast", 0, 0, 0, 0},
4292 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS,
4293 - "Digital Tulip+", 0, 0, 0, 0},
4294 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
4295 - "Digital Tulip 21142", 0, 0, 0, 0},
4296 - { PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5,
4297 - "Macronix MX987x5", 0, 0, 0, 0},
4298 - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115,
4299 - "LinkSys LNE100TX", 0, 0, 0, 0},
4300 - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP,
4301 - "Netgear FA310TX", 0, 0, 0, 0},
4302 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102,
4303 - "Davicom 9102", 0, 0, 0, 0},
4304 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009,
4305 - "Davicom 9009", 0, 0, 0, 0},
4306 - { PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_0985,
4307 - "ADMtek Centaur-P", 0, 0, 0, 0},
4308 - { PCI_VENDOR_ID_ADMTEK, 0x0981,
4309 - "ADMtek AN981 Comet", 0, 0, 0, 0},
4310 - { 0x125B, 0x1400,
4311 - "ASIX AX88140", 0, 0, 0, 0 },
4312 - { 0x11F6, 0x9881,
4313 - "Compex RL100-TX", 0, 0, 0, 0 },
4314 -#endif
4315 -#ifdef INCLUDE_DAVICOM
4316 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102,
4317 - "Davicom 9102", 0, 0, 0, 0},
4318 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009,
4319 - "Davicom 9009", 0, 0, 0, 0},
4320 -#endif
4321 -#ifdef INCLUDE_VIA_RHINE
4322 - { PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_VT6102,
4323 - "VIA 6102", 0, 0, 0, 0},
4324 - { PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I,
4325 - "VIA 3043", 0, 0, 0, 0},
4326 - { PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A,
4327 - "VIA 86C100A", 0, 0, 0, 0},
4328 -#endif
4329 -#ifdef INCLUDE_W89C840
4330 - { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840,
4331 - "Winbond W89C840F", 0, 0, 0, 0},
4332 - { PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL100ATX,
4333 - "Compex RL100ATX", 0, 0, 0, 0},
4334 -#endif
4335 -#ifdef INCLUDE_SIS900
4336 - { PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
4337 - "SIS900", 0, 0, 0, 0},
4338 - { PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
4339 - "SIS7016", 0, 0, 0, 0},
4340 -#endif
4342 -#ifdef INCLUDE_NATSEMI
4343 - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP83815,
4344 - "DP83815", 0, 0, 0, 0},
4345 -#endif
4347 -#ifdef INCLUDE_TLAN
4348 - { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
4349 - "OC2326", 0, 0, 0, 0},
4351 + * NIC probing is in pci device order, followed by the
4352 + * link order of the drivers. A driver that matches
4353 + * on vendor and device id will supersede a driver
4354 + * that matches on pci class.
4356 + * If you want to probe for another device behind the same pci
4357 + * device just increment index. And the previous probe call
4358 + * will be repeated.
4359 + */
4360 + struct pci_probe_state *state = &dev->state.pci;
4361 + printf("Probing pci %s...\n", type_name);
4362 + if (dev->how_probe == PROBE_FIRST) {
4363 + state->advance = 1;
4364 + state->dev.driver = 0;
4365 + state->dev.bus = 0;
4366 + state->dev.devfn = 0;
4367 + dev->index = -1;
4369 + for(;;) {
4370 + if ((dev->how_probe != PROBE_AWAKE) && state->advance) {
4371 + find_pci(dev->type, &state->dev);
4372 + dev->index = -1;
4374 + state->advance = 1;
4376 + if (state->dev.driver == 0)
4377 + break;
4379 +#if 0
4380 + /* FIXME the romaddr code needs a total rethought to be useful */
4381 + if (state->dev.romaddr != ((unsigned long) rom.rom_segment << 4)) {
4382 + continue;
4384 +#endif
4385 + if (dev->how_probe != PROBE_AWAKE) {
4386 + dev->type_index++;
4388 + dev->devid.bus_type = PCI_BUS_TYPE;
4389 + dev->devid.vendor_id = htons(state->dev.vendor);
4390 + dev->devid.device_id = htons(state->dev.dev_id);
4391 + /* FIXME how do I handle dev->index + PROBE_AGAIN?? */
4393 + printf("[%s]", state->dev.name);
4394 + if (state->dev.driver->probe(dev, &state->dev)) {
4395 + state->advance = (dev->index == -1);
4396 + return PROBE_WORKED;
4398 + putchar('\n');
4400 + return PROBE_FAILED;
4402 #endif
4404 - /* other PCI NICs go here */
4405 - {0, 0, NULL, 0, 0, 0, 0}
4407 -#endif /* INCLUDE_*PCI */
4409 -#include <cards.h>
4411 -#ifdef INCLUDE_PCI
4412 -struct pci_dispatch_table
4413 +#ifdef CONFIG_ISA
4414 +static int isa_probe(struct dev *dev, const char *type_name)
4416 - unsigned short vendor;
4417 - unsigned short dev_id;
4418 - struct nic *(*eth_probe) (struct nic *, unsigned short *,
4419 - struct pci_device *);
4422 -static struct pci_dispatch_table PCI_NIC[] =
4424 -# ifdef INCLUDE_NS8390
4425 - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8029, nepci_probe },
4426 - { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940, nepci_probe },
4427 - { PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL2000, nepci_probe },
4428 - { PCI_VENDOR_ID_KTI, PCI_DEVICE_ID_KTI_ET32P2, nepci_probe },
4429 - { PCI_VENDOR_ID_NETVIN, PCI_DEVICE_ID_NETVIN_NV5000SC, nepci_probe },
4430 - { PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_HT80232, nepci_probe },
4431 -# endif /* INCLUDE_NS8390 */
4432 -# ifdef INCLUDE_3C90X
4433 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO, a3c90x_probe },
4434 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO, a3c90x_probe },
4435 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905TX, a3c90x_probe },
4436 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905T4, a3c90x_probe },
4437 - { PCI_VENDOR_ID_3COM, 0x9004, a3c90x_probe },
4438 - { PCI_VENDOR_ID_3COM, 0x9005, a3c90x_probe },
4439 - { PCI_VENDOR_ID_3COM, 0x9006, a3c90x_probe },
4440 - { PCI_VENDOR_ID_3COM, 0x900A, a3c90x_probe },
4441 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905B_TX, a3c90x_probe },
4442 - { PCI_VENDOR_ID_3COM, 0x9056, a3c90x_probe },
4443 - { PCI_VENDOR_ID_3COM, 0x905A, a3c90x_probe },
4444 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C905C_TXM, a3c90x_probe },
4445 - { PCI_VENDOR_ID_3COM, 0x9800, a3c90x_probe },
4446 - { PCI_VENDOR_ID_3COM, 0x9805, a3c90x_probe },
4447 - { PCI_VENDOR_ID_3COM, 0x7646, a3c90x_probe },
4448 -# endif /* INCLUDE_3C90X */
4449 -# ifdef INCLUDE_3C595
4450 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C590, t595_probe },
4451 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595, t595_probe },
4452 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_1, t595_probe },
4453 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C595_2, t595_probe },
4454 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900TPO, t595_probe },
4455 - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C900COMBO, t595_probe },
4456 - { PCI_VENDOR_ID_3COM, 0x9004, t595_probe },
4457 - { PCI_VENDOR_ID_3COM, 0x9005, t595_probe },
4458 - { PCI_VENDOR_ID_3COM, 0x9006, t595_probe },
4459 - { PCI_VENDOR_ID_3COM, 0x900A, t595_probe },
4460 - { PCI_VENDOR_ID_3COM, 0x9800, t595_probe },
4461 - { PCI_VENDOR_ID_3COM, 0x9805, t595_probe },
4462 - { PCI_VENDOR_ID_3COM, 0x7646, t595_probe },
4463 -# endif /* INCLUDE_3C595 */
4464 -# ifdef INCLUDE_EEPRO100
4465 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557, eepro100_probe },
4466 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER, eepro100_probe },
4467 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1029, eepro100_probe },
4468 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1030, eepro100_probe },
4469 - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, eepro100_probe },
4470 -# endif /* INCLUDE_EEPRO100 */
4471 -# ifdef INCLUDE_EPIC100
4472 - { PCI_VENDOR_ID_SMC, PCI_DEVICE_ID_SMC_EPIC100, epic100_probe },
4473 -# endif /* INCLUDE_EPIC100 */
4474 -# ifdef INCLUDE_LANCE
4475 - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE, lancepci_probe },
4476 - { PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA, lancepci_probe },
4477 -# endif /* INCLUDE_LANCE */
4478 -# ifdef INCLUDE_RTL8139
4479 - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139, rtl8139_probe },
4480 - { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DFE530TXP, rtl8139_probe },
4481 - { PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211, rtl8139_probe },
4482 -# endif /* INCLUDE_RTL8139 */
4483 -# ifdef INCLUDE_OTULIP
4484 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, otulip_probe },
4485 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, otulip_probe },
4486 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, otulip_probe },
4487 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, otulip_probe },
4488 -# endif /* INCLUDE_OTULIP */
4489 -# ifdef INCLUDE_TULIP
4490 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP, tulip_probe },
4491 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_FAST, tulip_probe },
4492 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TULIP_PLUS, tulip_probe },
4493 - { PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, tulip_probe },
4494 - { PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5, tulip_probe },
4495 - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LC82C115, tulip_probe },
4496 - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_DEC_TULIP, tulip_probe },
4497 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102, tulip_probe },
4498 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009, tulip_probe },
4499 - { PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_0985, tulip_probe },
4500 - { PCI_VENDOR_ID_ADMTEK, 0x0981, tulip_probe },
4501 - { 0x125B, 0x1400, tulip_probe },
4502 - { 0x11F6, 0x9881, tulip_probe },
4503 -# endif /* INCLUDE_TULIP */
4504 -# ifdef INCLUDE_DAVICOM
4505 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9102, davicom_probe },
4506 - { PCI_VENDOR_ID_DAVICOM, PCI_DEVICE_ID_DM9009, davicom_probe },
4507 -# endif /* INCLUDE_DAVICOM */
4508 -# ifdef INCLUDE_VIA_RHINE
4509 - { PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_VT6102, rhine_probe },
4510 - { PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_RHINE_I, rhine_probe },
4511 - { PCI_VENDOR_ID_VIATEC, PCI_DEVICE_ID_VIA_86C100A, rhine_probe },
4512 -# endif /* INCLUDE_VIA_RHINE */
4513 -# ifdef INCLUDE_W89C840
4514 - { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840, w89c840_probe },
4515 - { PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_RL100ATX, w89c840_probe },
4516 -# endif /* INCLUDE_W89C840 */
4517 -# ifdef INCLUDE_SIS900
4518 - { PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900, sis900_probe },
4519 - { PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016, sis900_probe },
4520 -# endif /* INCLUDE_SIS900 */
4521 -# ifdef INCLUDE_NATSEMI
4522 - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_DP83815, natsemi_probe },
4523 -# endif /* INCLUDE_NATSEMI */
4524 -# ifdef INCLUDE_TLAN
4525 - { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326, tlan_probe },
4526 -# endif /* INCLUDE_TLAN */
4527 - { 0, 0, 0 }
4529 -#endif /* GRUB && INCLUDE_PCI */
4531 -struct dispatch_table
4533 - const char *nic_name;
4534 -#ifdef INCLUDE_PCI
4535 - struct nic *(*eth_probe) (struct nic *, unsigned short *,
4536 - struct pci_device *);
4537 -#else
4538 - struct nic *(*eth_probe) (struct nic *, unsigned short *);
4539 -#endif /* INCLUDE_PCI */
4540 - unsigned short *probe_ioaddrs; /* for probe overrides */
4544 - * NIC probing is in order of appearance in this table.
4545 + * NIC probing is in the order the drivers were linked togeter.
4546 * If for some reason you want to change the order,
4547 - * just rearrange the entries (bracketed by the #ifdef/#endif)
4548 + * just change the order you list the drivers in.
4550 -static struct dispatch_table NIC[] =
4552 -#ifdef INCLUDE_RTL8139
4553 - { "RTL8139", rtl8139_probe, pci_ioaddrs },
4554 -#endif
4555 -#ifdef INCLUDE_SIS900
4556 - { "SIS900", sis900_probe, pci_ioaddrs },
4557 -#endif
4558 -#ifdef INCLUDE_NATSEMI
4559 - { "NATSEMI", natsemi_probe, pci_ioaddrs },
4560 -#endif
4561 -#ifdef INCLUDE_WD
4562 - { "WD", wd_probe, 0 },
4563 -#endif
4564 -#ifdef INCLUDE_3C503
4565 - { "3C503", t503_probe, 0 },
4566 -#endif
4567 -#ifdef INCLUDE_NE
4568 - { "NE*000", ne_probe, 0 },
4569 -#endif
4570 -#ifdef INCLUDE_3C509
4571 - { "3C5x9", t509_probe, 0 },
4572 -#endif
4573 -#ifdef INCLUDE_3C529
4574 - { "3C5x9", t529_probe, 0 },
4575 -#endif
4576 -#ifdef INCLUDE_3C595
4577 - { "3C595", t595_probe, pci_ioaddrs },
4578 -#endif
4579 -#ifdef INCLUDE_3C90X
4580 - { "3C90X", a3c90x_probe, pci_ioaddrs },
4581 -#endif
4582 -#ifdef INCLUDE_EEPRO
4583 - { "EEPRO", eepro_probe, 0 },
4584 -#endif
4585 -#ifdef INCLUDE_EEPRO100
4586 - { "EEPRO100", eepro100_probe, pci_ioaddrs },
4587 -#endif
4588 -#ifdef INCLUDE_EPIC100
4589 - { "EPIC100", epic100_probe, pci_ioaddrs },
4590 -#endif
4591 -#ifdef INCLUDE_OTULIP
4592 - { "OTulip", otulip_probe, pci_ioaddrs },
4593 -#endif
4594 -#ifdef INCLUDE_TULIP
4595 - { "Tulip", tulip_probe, pci_ioaddrs },
4596 -#endif
4597 -#ifdef INCLUDE_DAVICOM
4598 - { "DAVICOM", davicom_probe, pci_ioaddrs },
4599 -#endif
4600 -#ifdef INCLUDE_CS89X0
4601 - { "CS89x0", cs89x0_probe, 0 },
4602 -#endif
4603 -#ifdef INCLUDE_NE2100
4604 - { "NE2100", ne2100_probe, 0 },
4605 -#endif
4606 -#ifdef INCLUDE_NI6510
4607 - { "NI6510", ni6510_probe, 0 },
4608 -#endif
4609 -#ifdef INCLUDE_SK_G16
4610 - { "SK_G16", SK_probe, 0 },
4611 -#endif
4612 -#ifdef INCLUDE_3C507
4613 - { "3C507", t507_probe, 0 },
4614 -#endif
4615 -#ifdef INCLUDE_NI5010
4616 - { "NI5010", ni5010_probe, 0 },
4617 -#endif
4618 -#ifdef INCLUDE_NI5210
4619 - { "NI5210", ni5210_probe, 0 },
4620 -#endif
4621 -#ifdef INCLUDE_EXOS205
4622 - { "EXOS205", exos205_probe, 0 },
4623 -#endif
4624 -#ifdef INCLUDE_SMC9000
4625 - { "SMC9000", smc9000_probe, 0 },
4626 -#endif
4627 -#ifdef INCLUDE_TIARA
4628 - { "TIARA", tiara_probe, 0 },
4629 -#endif
4630 -#ifdef INCLUDE_DEPCA
4631 - { "DEPCA", depca_probe, 0 },
4632 -#endif
4633 -#ifdef INCLUDE_NS8390
4634 - { "NE2000/PCI", nepci_probe, pci_ioaddrs },
4635 -#endif
4636 -#ifdef INCLUDE_LANCE
4637 - { "LANCE/PCI", lancepci_probe, pci_ioaddrs },
4638 -#endif
4639 -#ifdef INCLUDE_VIA_RHINE
4640 - { "VIA 86C100", rhine_probe, pci_ioaddrs },
4641 -#endif
4642 -#ifdef INCLUDE_W89C840
4643 - { "W89C840F", w89c840_probe, pci_ioaddrs },
4644 -#endif
4645 -#ifdef INCLUDE_TLAN
4646 - { "Olicom 2326", tlan_probe, pci_ioaddrs },
4647 -#endif
4648 - /* this entry must always be last to mark the end of list */
4649 - { 0, 0, 0 }
4652 -#define NIC_TABLE_SIZE (sizeof (NIC) / sizeof (NIC[0]))
4654 -static int
4655 -eth_dummy (struct nic *dummy)
4657 - return 0;
4658 + struct isa_probe_state *state = &dev->state.isa;
4659 + printf("Probing isa %s...\n", type_name);
4660 + if (dev->how_probe == PROBE_FIRST) {
4661 + state->advance = 0;
4662 + state->driver = isa_drivers;
4663 + dev->index = -1;
4665 + for(;;)
4667 + if ((dev->how_probe != PROBE_AWAKE) && state->advance) {
4668 + state->driver++;
4669 + dev->index = -1;
4671 + state->advance = 1;
4673 + if (state->driver >= isa_drivers_end)
4674 + break;
4676 + if (state->driver->type != dev->type)
4677 + continue;
4679 + if (dev->how_probe != PROBE_AWAKE) {
4680 + dev->type_index++;
4682 + printf("[%s]", state->driver->name);
4683 + dev->devid.bus_type = ISA_BUS_TYPE;
4684 + /* FIXME how do I handle dev->index + PROBE_AGAIN?? */
4685 + /* driver will fill in vendor and device IDs */
4686 + if (state->driver->probe(dev, state->driver->ioaddrs)) {
4687 + state->advance = (dev->index == -1);
4688 + return PROBE_WORKED;
4690 + putchar('\n');
4692 + return PROBE_FAILED;
4695 -static char packet[ETH_FRAME_LEN];
4697 -struct nic nic =
4699 - (void (*) (struct nic *)) eth_dummy, /* reset */
4700 - eth_dummy, /* poll */
4701 - (void (*) (struct nic *, const char *,
4702 - unsigned int, unsigned int,
4703 - const char *)) eth_dummy, /* transmit */
4704 - (void (*) (struct nic *)) eth_dummy, /* disable */
4705 -#ifdef T503_AUI
4706 - 1, /* aui */
4707 #else
4708 - 0, /* no aui */
4709 +#define isa_probe(d,tn) (PROBE_FAILED)
4710 #endif
4711 - &rom, /* rom_info */
4712 - arptable[ARP_CLIENT].node, /* node_addr */
4713 - packet, /* packet */
4714 - 0, /* packetlen */
4715 - 0, /* priv_data */
4716 +static const char *driver_name[] = {
4717 + "nic",
4718 + "disk",
4719 + "floppy",
4722 -void
4723 -eth_reset (void)
4724 +int probe(struct dev *dev)
4726 - (*nic.reset) (&nic);
4728 + const char *type_name;
4730 -int
4731 -eth_probe (void)
4733 - struct pci_device *p;
4734 - const struct dispatch_table *t;
4735 - static int probed = 0;
4736 + EnterFunction("probe");
4738 - /* If already probed, don't try to probe it any longer. */
4739 - if (probed)
4740 - return 1;
4742 - /* Clear the ready flag. */
4743 - network_ready = 0;
4744 - /* Clear the ARP table. */
4745 - grub_memset ((char *) arptable, 0,
4746 - MAX_ARP * sizeof (struct arptable_t));
4748 - p = 0;
4750 -#ifdef INCLUDE_PCI
4751 - /* In GRUB, the ROM info is initialized here. */
4752 - rom = *((struct rom_info *) ROM_INFO_LOCATION);
4754 - eth_pci_init(pci_nic_list);
4755 - pci_ioaddrs[0] = 0;
4756 - pci_ioaddrs[1] = 0;
4757 - /* at this point we have a list of possible PCI candidates
4758 - we just pick the first one with a non-zero ioaddr */
4759 - for (p = pci_nic_list; p->vendor != 0; ++p)
4761 - if (p->ioaddr != 0)
4763 - pci_ioaddrs[0] = p->ioaddr;
4764 - break;
4765 + type_name = "";
4766 + if ((dev->type >= 0) &&
4767 + (dev->type < sizeof(driver_name)/sizeof(driver_name[0]))) {
4768 + type_name = driver_name[dev->type];
4771 -#endif
4773 - etherboot_printf("Probing...");
4775 -#ifdef INCLUDE_PCI
4776 - if (p->vendor)
4778 - struct pci_dispatch_table *pt;
4780 - for (pt = PCI_NIC; pt->eth_probe != 0; pt++)
4781 - if (p->vendor == pt->vendor && p->dev_id == pt->dev_id)
4783 - etherboot_printf ("[%s]", p->name);
4784 - if ((pt->eth_probe) (&nic, pci_ioaddrs, p))
4786 - probed = 1;
4787 - return 1;
4791 -#endif /* INCLUDE_PCI */
4793 - for (t = NIC; t->nic_name != 0; ++t)
4795 - etherboot_printf("[%s]", t->nic_name);
4796 -#ifdef INCLUDE_PCI
4797 - if ((*t->eth_probe) (&nic, t->probe_ioaddrs, p))
4799 - probed = 1;
4800 - return 1;
4801 + if (dev->how_probe == PROBE_FIRST) {
4802 + dev->to_probe = PROBE_PCI;
4803 + memset(&dev->state, 0, sizeof(dev->state));
4805 -#else
4806 - if ((*t->eth_probe) (&nic, t->probe_ioaddrs))
4808 - probed = 1;
4809 - return 1;
4810 + if (dev->to_probe == PROBE_PCI) {
4811 + dev->how_probe = pci_probe(dev, type_name);
4812 + if (dev->how_probe == PROBE_FAILED) {
4813 + dev->to_probe = PROBE_ISA;
4816 + if (dev->to_probe == PROBE_ISA) {
4817 + dev->how_probe = isa_probe(dev, type_name);
4818 + if (dev->how_probe == PROBE_FAILED) {
4819 + dev->to_probe = PROBE_NONE;
4822 + if ((dev->to_probe != PROBE_PCI) &&
4823 + (dev->to_probe != PROBE_ISA)) {
4824 + dev->how_probe = PROBE_FAILED;
4827 -#endif /* INCLUDE_PCI */
4830 - return 0;
4833 -int
4834 -eth_poll (void)
4836 - return ((*nic.poll) (&nic));
4839 -void
4840 -eth_transmit (const char *d, unsigned int t, unsigned int s, const void *p)
4842 - (*nic.transmit) (&nic, d, t, s, p);
4843 - if (t == IP)
4844 - twiddle ();
4845 + LeaveFunction("probe");
4846 + return dev->how_probe;
4849 -void
4850 -eth_disable (void)
4851 +void disable(struct dev *dev)
4853 - (*nic.disable) (&nic);
4854 + if (dev->disable) {
4855 + dev->disable(dev);
4856 + dev->disable = 0;
4859 Index: b/netboot/cpu.h
4860 ===================================================================
4861 --- /dev/null
4862 +++ b/netboot/cpu.h
4863 @@ -0,0 +1,243 @@
4864 +#ifndef I386_BITS_CPU_H
4865 +#define I386_BITS_CPU_H
4868 +/* Sample usage: CPU_FEATURE_P(cpu.x86_capability, FPU) */
4869 +#define CPU_FEATURE_P(CAP, FEATURE) \
4870 + (!!(CAP[(X86_FEATURE_##FEATURE)/32] & ((X86_FEATURE_##FEATURE) & 0x1f)))
4872 +#define NCAPINTS 4 /* Currently we have 4 32-bit words worth of info */
4874 +/* Intel-defined CPU features, CPUID level 0x00000001, word 0 */
4875 +#define X86_FEATURE_FPU (0*32+ 0) /* Onboard FPU */
4876 +#define X86_FEATURE_VME (0*32+ 1) /* Virtual Mode Extensions */
4877 +#define X86_FEATURE_DE (0*32+ 2) /* Debugging Extensions */
4878 +#define X86_FEATURE_PSE (0*32+ 3) /* Page Size Extensions */
4879 +#define X86_FEATURE_TSC (0*32+ 4) /* Time Stamp Counter */
4880 +#define X86_FEATURE_MSR (0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
4881 +#define X86_FEATURE_PAE (0*32+ 6) /* Physical Address Extensions */
4882 +#define X86_FEATURE_MCE (0*32+ 7) /* Machine Check Architecture */
4883 +#define X86_FEATURE_CX8 (0*32+ 8) /* CMPXCHG8 instruction */
4884 +#define X86_FEATURE_APIC (0*32+ 9) /* Onboard APIC */
4885 +#define X86_FEATURE_SEP (0*32+11) /* SYSENTER/SYSEXIT */
4886 +#define X86_FEATURE_MTRR (0*32+12) /* Memory Type Range Registers */
4887 +#define X86_FEATURE_PGE (0*32+13) /* Page Global Enable */
4888 +#define X86_FEATURE_MCA (0*32+14) /* Machine Check Architecture */
4889 +#define X86_FEATURE_CMOV (0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
4890 +#define X86_FEATURE_PAT (0*32+16) /* Page Attribute Table */
4891 +#define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */
4892 +#define X86_FEATURE_PN (0*32+18) /* Processor serial number */
4893 +#define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */
4894 +#define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */
4895 +#define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */
4896 +#define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */
4897 +#define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
4898 + /* of FPU context), and CR4.OSFXSR available */
4899 +#define X86_FEATURE_XMM (0*32+25) /* Streaming SIMD Extensions */
4900 +#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */
4901 +#define X86_FEATURE_SELFSNOOP (0*32+27) /* CPU self snoop */
4902 +#define X86_FEATURE_HT (0*32+28) /* Hyper-Threading */
4903 +#define X86_FEATURE_ACC (0*32+29) /* Automatic clock control */
4904 +#define X86_FEATURE_IA64 (0*32+30) /* IA-64 processor */
4906 +/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
4907 +/* Don't duplicate feature flags which are redundant with Intel! */
4908 +#define X86_FEATURE_SYSCALL (1*32+11) /* SYSCALL/SYSRET */
4909 +#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
4910 +#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
4911 +#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
4912 +#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
4914 +/* Transmeta-defined CPU features, CPUID level 0x80860001, word 2 */
4915 +#define X86_FEATURE_RECOVERY (2*32+ 0) /* CPU in recovery mode */
4916 +#define X86_FEATURE_LONGRUN (2*32+ 1) /* Longrun power control */
4917 +#define X86_FEATURE_LRTI (2*32+ 3) /* LongRun table interface */
4919 +/* Other features, Linux-defined mapping, word 3 */
4920 +/* This range is used for feature bits which conflict or are synthesized */
4921 +#define X86_FEATURE_CXMMX (3*32+ 0) /* Cyrix MMX extensions */
4922 +#define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */
4923 +#define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */
4924 +#define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */
4926 +#define MAX_X86_VENDOR_ID 16
4927 +struct cpuinfo_x86 {
4928 + uint8_t x86; /* CPU family */
4929 + uint8_t x86_model;
4930 + uint8_t x86_mask;
4932 + int cpuid_level; /* Maximum supported CPUID level, -1=no CPUID */
4933 + unsigned x86_capability[NCAPINTS];
4934 + char x86_vendor_id[MAX_X86_VENDOR_ID];
4938 +#define X86_VENDOR_INTEL 0
4939 +#define X86_VENDOR_CYRIX 1
4940 +#define X86_VENDOR_AMD 2
4941 +#define X86_VENDOR_UMC 3
4942 +#define X86_VENDOR_NEXGEN 4
4943 +#define X86_VENDOR_CENTAUR 5
4944 +#define X86_VENDOR_RISE 6
4945 +#define X86_VENDOR_TRANSMETA 7
4946 +#define X86_VENDOR_NSC 8
4947 +#define X86_VENDOR_UNKNOWN 0xff
4950 + * EFLAGS bits
4951 + */
4952 +#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
4953 +#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
4954 +#define X86_EFLAGS_AF 0x00000010 /* Auxillary carry Flag */
4955 +#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
4956 +#define X86_EFLAGS_SF 0x00000080 /* Sign Flag */
4957 +#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */
4958 +#define X86_EFLAGS_IF 0x00000200 /* Interrupt Flag */
4959 +#define X86_EFLAGS_DF 0x00000400 /* Direction Flag */
4960 +#define X86_EFLAGS_OF 0x00000800 /* Overflow Flag */
4961 +#define X86_EFLAGS_IOPL 0x00003000 /* IOPL mask */
4962 +#define X86_EFLAGS_NT 0x00004000 /* Nested Task */
4963 +#define X86_EFLAGS_RF 0x00010000 /* Resume Flag */
4964 +#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
4965 +#define X86_EFLAGS_AC 0x00040000 /* Alignment Check */
4966 +#define X86_EFLAGS_VIF 0x00080000 /* Virtual Interrupt Flag */
4967 +#define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */
4968 +#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
4971 + * Generic CPUID function
4972 + */
4973 +static inline void cpuid(int op,
4974 + unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
4976 + __asm__("cpuid"
4977 + : "=a" (*eax),
4978 + "=b" (*ebx),
4979 + "=c" (*ecx),
4980 + "=d" (*edx)
4981 + : "0" (op));
4985 + * CPUID functions returning a single datum
4986 + */
4987 +static inline unsigned int cpuid_eax(unsigned int op)
4989 + unsigned int eax;
4991 + __asm__("cpuid"
4992 + : "=a" (eax)
4993 + : "0" (op)
4994 + : "bx", "cx", "dx");
4995 + return eax;
4997 +static inline unsigned int cpuid_ebx(unsigned int op)
4999 + unsigned int eax, ebx;
5001 + __asm__("cpuid"
5002 + : "=a" (eax), "=b" (ebx)
5003 + : "0" (op)
5004 + : "cx", "dx" );
5005 + return ebx;
5007 +static inline unsigned int cpuid_ecx(unsigned int op)
5009 + unsigned int eax, ecx;
5011 + __asm__("cpuid"
5012 + : "=a" (eax), "=c" (ecx)
5013 + : "0" (op)
5014 + : "bx", "dx" );
5015 + return ecx;
5017 +static inline unsigned int cpuid_edx(unsigned int op)
5019 + unsigned int eax, edx;
5021 + __asm__("cpuid"
5022 + : "=a" (eax), "=d" (edx)
5023 + : "0" (op)
5024 + : "bx", "cx");
5025 + return edx;
5029 + * Intel CPU features in CR4
5030 + */
5031 +#define X86_CR4_VME 0x0001 /* enable vm86 extensions */
5032 +#define X86_CR4_PVI 0x0002 /* virtual interrupts flag enable */
5033 +#define X86_CR4_TSD 0x0004 /* disable time stamp at ipl 3 */
5034 +#define X86_CR4_DE 0x0008 /* enable debugging extensions */
5035 +#define X86_CR4_PSE 0x0010 /* enable page size extensions */
5036 +#define X86_CR4_PAE 0x0020 /* enable physical address extensions */
5037 +#define X86_CR4_MCE 0x0040 /* Machine check enable */
5038 +#define X86_CR4_PGE 0x0080 /* enable global pages */
5039 +#define X86_CR4_PCE 0x0100 /* enable performance counters at ipl 3 */
5040 +#define X86_CR4_OSFXSR 0x0200 /* enable fast FPU save and restore */
5041 +#define X86_CR4_OSXMMEXCPT 0x0400 /* enable unmasked SSE exceptions */
5044 +#define MSR_K6_EFER 0xC0000080
5045 +/* EFER bits: */
5046 +#define _EFER_SCE 0 /* SYSCALL/SYSRET */
5047 +#define _EFER_LME 8 /* Long mode enable */
5048 +#define _EFER_LMA 10 /* Long mode active (read-only) */
5049 +#define _EFER_NX 11 /* No execute enable */
5051 +#define EFER_SCE (1<<_EFER_SCE)
5052 +#define EFER_LME (1<<EFER_LME)
5053 +#define EFER_LMA (1<<EFER_LMA)
5054 +#define EFER_NX (1<<_EFER_NX)
5056 +#define rdmsr(msr,val1,val2) \
5057 + __asm__ __volatile__("rdmsr" \
5058 + : "=a" (val1), "=d" (val2) \
5059 + : "c" (msr))
5061 +#define wrmsr(msr,val1,val2) \
5062 + __asm__ __volatile__("wrmsr" \
5063 + : /* no outputs */ \
5064 + : "c" (msr), "a" (val1), "d" (val2))
5067 +#define read_cr0() ({ \
5068 + unsigned int __dummy; \
5069 + __asm__( \
5070 + "movl %%cr0, %0\n\t" \
5071 + :"=r" (__dummy)); \
5072 + __dummy; \
5074 +#define write_cr0(x) \
5075 + __asm__("movl %0,%%cr0": :"r" (x));
5077 +#define read_cr3() ({ \
5078 + unsigned int __dummy; \
5079 + __asm__( \
5080 + "movl %%cr3, %0\n\t" \
5081 + :"=r" (__dummy)); \
5082 + __dummy; \
5084 +#define write_cr3x(x) \
5085 + __asm__("movl %0,%%cr3": :"r" (x));
5088 +#define read_cr4() ({ \
5089 + unsigned int __dummy; \
5090 + __asm__( \
5091 + "movl %%cr4, %0\n\t" \
5092 + :"=r" (__dummy)); \
5093 + __dummy; \
5095 +#define write_cr4x(x) \
5096 + __asm__("movl %0,%%cr4": :"r" (x));
5099 +extern struct cpuinfo_x86 cpu_info;
5100 +#ifdef CONFIG_X86_64
5101 +extern void cpu_setup(void);
5102 +#else
5103 +#define cpu_setup() do {} while(0)
5104 +#endif
5106 +#endif /* I386_BITS_CPU_H */
5107 Index: b/netboot/cs89x0.c
5108 ===================================================================
5109 --- a/netboot/cs89x0.c
5110 +++ b/netboot/cs89x0.c
5111 @@ -16,662 +16,3 @@
5112 -- quote from email
5115 -/* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
5117 - Permission is granted to distribute the enclosed cs89x0.[ch] driver
5118 - only in conjunction with the Etherboot package. The code is
5119 - ordinarily distributed under the GPL.
5121 - Russ Nelson, January 2000
5123 - ChangeLog:
5125 - Thu Dec 6 22:40:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
5127 - * disabled all "advanced" features; this should make the code more reliable
5129 - * reorganized the reset function
5131 - * always reset the address port, so that autoprobing will continue working
5133 - * some cosmetic changes
5135 - * 2.5
5137 - Thu Dec 5 21:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
5139 - * tested the code against a CS8900 card
5141 - * lots of minor bug fixes and adjustments
5143 - * this is the first release, that actually works! it still requires some
5144 - changes in order to be more tolerant to different environments
5146 - * 4
5148 - Fri Nov 22 23:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
5150 - * read the manuals for the CS89x0 chipsets and took note of all the
5151 - changes that will be neccessary in order to adapt Russel Nelson's code
5152 - to the requirements of a BOOT-Prom
5154 - * 6
5156 - Thu Nov 19 22:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
5158 - * Synched with Russel Nelson's current code (v1.00)
5160 - * 2
5162 - Thu Nov 12 18:00:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
5164 - * Cleaned up some of the code and tried to optimize the code size.
5166 - * 1.5
5168 - Sun Nov 10 16:30:00 1996 Markus Gutschke <gutschk@math.uni-muenster.de>
5170 - * First experimental release. This code compiles fine, but I
5171 - have no way of testing whether it actually works.
5173 - * I did not (yet) bother to make the code 16bit aware, so for
5174 - the time being, it will only work for Etherboot/32.
5176 - * 12
5178 - */
5180 -#include "etherboot.h"
5181 -#include "nic.h"
5182 -#include "cards.h"
5183 -#include "cs89x0.h"
5185 -static unsigned short eth_nic_base;
5186 -static unsigned long eth_mem_start;
5187 -static unsigned short eth_irq;
5188 -static unsigned short eth_cs_type; /* one of: CS8900, CS8920, CS8920M */
5189 -static unsigned short eth_auto_neg_cnf;
5190 -static unsigned short eth_adapter_cnf;
5191 -static unsigned short eth_linectl;
5193 -/*************************************************************************
5194 - CS89x0 - specific routines
5195 -**************************************************************************/
5197 -static inline int readreg(int portno)
5199 - outw(portno, eth_nic_base + ADD_PORT);
5200 - return inw(eth_nic_base + DATA_PORT);
5203 -static inline void writereg(int portno, int value)
5205 - outw(portno, eth_nic_base + ADD_PORT);
5206 - outw(value, eth_nic_base + DATA_PORT);
5207 - return;
5210 -/*************************************************************************
5211 -EEPROM access
5212 -**************************************************************************/
5214 -static int wait_eeprom_ready(void)
5216 - unsigned long tmo = currticks() + 4*TICKS_PER_SEC;
5218 - /* check to see if the EEPROM is ready, a timeout is used -
5219 - just in case EEPROM is ready when SI_BUSY in the
5220 - PP_SelfST is clear */
5221 - while(readreg(PP_SelfST) & SI_BUSY) {
5222 - if (currticks() >= tmo)
5223 - return -1; }
5224 - return 0;
5227 -static int get_eeprom_data(int off, int len, unsigned short *buffer)
5229 - int i;
5231 -#ifdef EDEBUG
5232 - printf("\ncs: EEPROM data from %hX for %hX:",off,len);
5233 -#endif
5234 - for (i = 0; i < len; i++) {
5235 - if (wait_eeprom_ready() < 0)
5236 - return -1;
5237 - /* Now send the EEPROM read command and EEPROM location
5238 - to read */
5239 - writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
5240 - if (wait_eeprom_ready() < 0)
5241 - return -1;
5242 - buffer[i] = readreg(PP_EEData);
5243 -#ifdef EDEBUG
5244 - if (!(i%10))
5245 - printf("\ncs: ");
5246 - printf("%hX ", buffer[i]);
5247 -#endif
5249 -#ifdef EDEBUG
5250 - putchar('\n');
5251 -#endif
5253 - return(0);
5256 -static int get_eeprom_chksum(int off, int len, unsigned short *buffer)
5258 - int i, cksum;
5260 - cksum = 0;
5261 - for (i = 0; i < len; i++)
5262 - cksum += buffer[i];
5263 - cksum &= 0xffff;
5264 - if (cksum == 0)
5265 - return 0;
5266 - return -1;
5269 -/*************************************************************************
5270 -Activate all of the available media and probe for network
5271 -**************************************************************************/
5273 -static void clrline(void)
5275 - int i;
5277 - putchar('\r');
5278 - for (i = 79; i--; ) putchar(' ');
5279 - printf("\rcs: ");
5280 - return;
5283 -static void control_dc_dc(int on_not_off)
5285 - unsigned int selfcontrol;
5286 - unsigned long tmo = currticks() + TICKS_PER_SEC;
5288 - /* control the DC to DC convertor in the SelfControl register. */
5289 - selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
5290 - if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
5291 - selfcontrol |= HCB1;
5292 - else
5293 - selfcontrol &= ~HCB1;
5294 - writereg(PP_SelfCTL, selfcontrol);
5296 - /* Wait for the DC/DC converter to power up - 1000ms */
5297 - while (currticks() < tmo);
5299 - return;
5302 -static int detect_tp(void)
5304 - unsigned long tmo;
5306 - /* Turn on the chip auto detection of 10BT/ AUI */
5308 - clrline(); printf("attempting %s:","TP");
5310 - /* If connected to another full duplex capable 10-Base-T card
5311 - the link pulses seem to be lost when the auto detect bit in
5312 - the LineCTL is set. To overcome this the auto detect bit
5313 - will be cleared whilst testing the 10-Base-T interface.
5314 - This would not be necessary for the sparrow chip but is
5315 - simpler to do it anyway. */
5316 - writereg(PP_LineCTL, eth_linectl &~ AUI_ONLY);
5317 - control_dc_dc(0);
5319 - /* Delay for the hardware to work out if the TP cable is
5320 - present - 150ms */
5321 - for (tmo = currticks() + 4; currticks() < tmo; );
5323 - if ((readreg(PP_LineST) & LINK_OK) == 0)
5324 - return 0;
5326 - if (eth_cs_type != CS8900) {
5328 - writereg(PP_AutoNegCTL, eth_auto_neg_cnf & AUTO_NEG_MASK);
5330 - if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
5331 - printf(" negotiating duplex... ");
5332 - while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
5333 - if (currticks() - tmo > 40*TICKS_PER_SEC) {
5334 - printf("time out ");
5335 - break;
5339 - if (readreg(PP_AutoNegST) & FDX_ACTIVE)
5340 - printf("using full duplex");
5341 - else
5342 - printf("using half duplex");
5345 - return A_CNF_MEDIA_10B_T;
5348 -/* send a test packet - return true if carrier bits are ok */
5349 -static int send_test_pkt(struct nic *nic)
5351 - static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
5352 - 0, 46, /*A 46 in network order */
5353 - 0, 0, /*DSAP=0 & SSAP=0 fields */
5354 - 0xf3,0 /*Control (Test Req+P bit set)*/ };
5355 - unsigned long tmo;
5357 - writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
5359 - memcpy(testpacket, nic->node_addr, ETH_ALEN);
5360 - memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);
5362 - outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
5363 - outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT);
5365 - /* Test to see if the chip has allocated memory for the packet */
5366 - for (tmo = currticks() + 2;
5367 - (readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
5368 - if (currticks() >= tmo)
5369 - return(0);
5371 - /* Write the contents of the packet */
5372 - outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
5373 - (ETH_ZLEN+1)>>1);
5375 - printf(" sending test packet ");
5376 - /* wait a couple of timer ticks for packet to be received */
5377 - for (tmo = currticks() + 2; currticks() < tmo; );
5379 - if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
5380 - printf("succeeded");
5381 - return 1;
5383 - printf("failed");
5384 - return 0;
5388 -static int detect_aui(struct nic *nic)
5390 - clrline(); printf("attempting %s:","AUI");
5391 - control_dc_dc(0);
5393 - writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
5395 - if (send_test_pkt(nic)) {
5396 - return A_CNF_MEDIA_AUI; }
5397 - else
5398 - return 0;
5401 -static int detect_bnc(struct nic *nic)
5403 - clrline(); printf("attempting %s:","BNC");
5404 - control_dc_dc(1);
5406 - writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
5408 - if (send_test_pkt(nic)) {
5409 - return A_CNF_MEDIA_10B_2; }
5410 - else
5411 - return 0;
5414 -/**************************************************************************
5415 -ETH_RESET - Reset adapter
5416 -***************************************************************************/
5418 -static void cs89x0_reset(struct nic *nic)
5420 - int i;
5421 - unsigned long reset_tmo;
5423 - writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
5425 - /* wait for two ticks; that is 2*55ms */
5426 - for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
5428 - if (eth_cs_type != CS8900) {
5429 - /* Hardware problem requires PNP registers to be reconfigured
5430 - after a reset */
5431 - if (eth_irq != 0xFFFF) {
5432 - outw(PP_CS8920_ISAINT, eth_nic_base + ADD_PORT);
5433 - outb(eth_irq, eth_nic_base + DATA_PORT);
5434 - outb(0, eth_nic_base + DATA_PORT + 1); }
5436 - if (eth_mem_start) {
5437 - outw(PP_CS8920_ISAMemB, eth_nic_base + ADD_PORT);
5438 - outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
5439 - outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }
5441 - /* Wait until the chip is reset */
5442 - for (reset_tmo = currticks() + 2;
5443 - (readreg(PP_SelfST) & INIT_DONE) == 0 &&
5444 - currticks() < reset_tmo; );
5446 - /* disable interrupts and memory accesses */
5447 - writereg(PP_BusCTL, 0);
5449 - /* set the ethernet address */
5450 - for (i=0; i < ETH_ALEN/2; i++)
5451 - writereg(PP_IA+i*2,
5452 - nic->node_addr[i*2] |
5453 - (nic->node_addr[i*2+1] << 8));
5455 - /* receive only error free packets addressed to this card */
5456 - writereg(PP_RxCTL, DEF_RX_ACCEPT);
5458 - /* do not generate any interrupts on receive operations */
5459 - writereg(PP_RxCFG, 0);
5461 - /* do not generate any interrupts on transmit operations */
5462 - writereg(PP_TxCFG, 0);
5464 - /* do not generate any interrupts on buffer operations */
5465 - writereg(PP_BufCFG, 0);
5467 - /* reset address port, so that autoprobing will keep working */
5468 - outw(PP_ChipID, eth_nic_base + ADD_PORT);
5470 - return;
5473 -/**************************************************************************
5474 -ETH_TRANSMIT - Transmit a frame
5475 -***************************************************************************/
5477 -static void cs89x0_transmit(
5478 - struct nic *nic,
5479 - const char *d, /* Destination */
5480 - unsigned int t, /* Type */
5481 - unsigned int s, /* size */
5482 - const char *p) /* Packet */
5484 - unsigned long tmo;
5485 - int sr;
5487 - /* does this size have to be rounded??? please,
5488 - somebody have a look in the specs */
5489 - if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
5490 - sr = ETH_ZLEN;
5492 -retry:
5493 - /* initiate a transmit sequence */
5494 - outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
5495 - outw(sr, eth_nic_base + TX_LEN_PORT);
5497 - /* Test to see if the chip has allocated memory for the packet */
5498 - if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
5499 - /* Oops... this should not happen! */
5500 - printf("cs: unable to send packet; retrying...\n");
5501 - for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
5502 - cs89x0_reset(nic);
5503 - goto retry; }
5505 - /* Write the contents of the packet */
5506 - outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);
5507 - outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
5508 - ETH_ALEN/2);
5509 - outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
5510 - outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
5511 - for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr-- > 0;
5512 - outw(0, eth_nic_base + TX_FRAME_PORT));
5514 - /* wait for transfer to succeed */
5515 - for (tmo = currticks()+5*TICKS_PER_SEC;
5516 - (s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
5517 - /* nothing */ ;
5518 - if ((s & TX_SEND_OK_BITS) != TX_OK) {
5519 - printf("\ntransmission error %#hX\n", s);
5522 - return;
5525 -/**************************************************************************
5526 -ETH_POLL - Wait for a frame
5527 -***************************************************************************/
5529 -static int cs89x0_poll(struct nic *nic)
5531 - int status;
5533 - status = readreg(PP_RxEvent);
5535 - if ((status & RX_OK) == 0)
5536 - return(0);
5538 - status = inw(eth_nic_base + RX_FRAME_PORT);
5539 - nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);
5540 - insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);
5541 - if (nic->packetlen & 1)
5542 - nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);
5543 - return 1;
5546 -static void cs89x0_disable(struct nic *nic)
5548 - cs89x0_reset(nic);
5551 -/**************************************************************************
5552 -ETH_PROBE - Look for an adapter
5553 -***************************************************************************/
5555 -struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
5557 - static const unsigned int netcard_portlist[] = {
5558 -#ifdef CS_SCAN
5559 - CS_SCAN,
5560 -#else /* use "conservative" default values for autoprobing */
5561 - 0x300,0x320,0x340,0x200,0x220,0x240,
5562 - 0x260,0x280,0x2a0,0x2c0,0x2e0,
5563 - /* if that did not work, then be more aggressive */
5564 - 0x301,0x321,0x341,0x201,0x221,0x241,
5565 - 0x261,0x281,0x2a1,0x2c1,0x2e1,
5566 -#endif
5567 - 0};
5569 - int i, result = -1;
5570 - unsigned rev_type = 0, ioaddr, ioidx, isa_cnf, cs_revision;
5571 - unsigned short eeprom_buff[CHKSUM_LEN];
5574 - for (ioidx = 0; (ioaddr=netcard_portlist[ioidx++]) != 0; ) {
5575 - /* if they give us an odd I/O address, then do ONE write to
5576 - the address port, to get it back to address zero, where we
5577 - expect to find the EISA signature word. */
5578 - if (ioaddr & 1) {
5579 - ioaddr &= ~1;
5580 - if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
5581 - continue;
5582 - outw(PP_ChipID, ioaddr + ADD_PORT);
5585 - if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
5586 - continue;
5587 - eth_nic_base = ioaddr;
5589 - /* get the chip type */
5590 - rev_type = readreg(PRODUCT_ID_ADD);
5591 - eth_cs_type = rev_type &~ REVISON_BITS;
5592 - cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
5594 - printf("\ncs: cs89%c0%s rev %c, base %#hX",
5595 - eth_cs_type==CS8900?'0':'2',
5596 - eth_cs_type==CS8920M?"M":"",
5597 - cs_revision,
5598 - eth_nic_base);
5600 - /* First check to see if an EEPROM is attached*/
5601 - if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
5602 - printf("\ncs: no EEPROM...\n");
5603 - outw(PP_ChipID, eth_nic_base + ADD_PORT);
5604 - continue; }
5605 - else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
5606 - eeprom_buff) < 0) {
5607 - printf("\ncs: EEPROM read failed...\n");
5608 - outw(PP_ChipID, eth_nic_base + ADD_PORT);
5609 - continue; }
5610 - else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
5611 - eeprom_buff) < 0) {
5612 - printf("\ncs: EEPROM checksum bad...\n");
5613 - outw(PP_ChipID, eth_nic_base + ADD_PORT);
5614 - continue; }
5616 - /* get transmission control word but keep the
5617 - autonegotiation bits */
5618 - eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
5619 - /* Store adapter configuration */
5620 - eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
5621 - /* Store ISA configuration */
5622 - isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
5624 - /* store the initial memory base address */
5625 - eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
5627 - printf("%s%s%s, addr ",
5628 - (eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
5629 - (eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
5630 - (eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
5632 - /* If this is a CS8900 then no pnp soft */
5633 - if (eth_cs_type != CS8900 &&
5634 - /* Check if the ISA IRQ has been set */
5635 - (i = readreg(PP_CS8920_ISAINT) & 0xff,
5636 - (i != 0 && i < CS8920_NO_INTS)))
5637 - eth_irq = i;
5638 - else {
5639 - i = isa_cnf & INT_NO_MASK;
5640 - if (eth_cs_type == CS8900) {
5641 - /* the table that follows is dependent
5642 - upon how you wired up your cs8900
5643 - in your system. The table is the
5644 - same as the cs8900 engineering demo
5645 - board. irq_map also depends on the
5646 - contents of the table. Also see
5647 - write_irq, which is the reverse
5648 - mapping of the table below. */
5649 - if (i < 4) i = "\012\013\014\005"[i];
5650 - else printf("\ncs: BUG: isa_config is %d\n", i); }
5651 - eth_irq = i; }
5653 - /* Retrieve and print the ethernet address. */
5654 - for (i=0; i<ETH_ALEN; i++) {
5655 - nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
5657 - printf("%!\n", nic->node_addr);
5659 - /* Set the LineCTL quintuplet based on adapter
5660 - configuration read from EEPROM */
5661 - if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&
5662 - (eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))
5663 - eth_linectl = LOW_RX_SQUELCH;
5664 - else
5665 - eth_linectl = 0;
5667 - /* check to make sure that they have the "right"
5668 - hardware available */
5669 - switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
5670 - case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;
5671 - break;
5672 - case A_CNF_MEDIA_AUI: result = eth_adapter_cnf & A_CNF_AUI;
5673 - break;
5674 - case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;
5675 - break;
5676 - default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
5677 - A_CNF_10B_2);
5679 - if (!result) {
5680 - printf("cs: EEPROM is configured for unavailable media\n");
5681 - error:
5682 - writereg(PP_LineCTL, readreg(PP_LineCTL) &
5683 - ~(SERIAL_TX_ON | SERIAL_RX_ON));
5684 - outw(PP_ChipID, eth_nic_base + ADD_PORT);
5685 - continue;
5688 - /* Initialize the card for probing of the attached media */
5689 - cs89x0_reset(nic);
5691 - /* set the hardware to the configured choice */
5692 - switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
5693 - case A_CNF_MEDIA_10B_T:
5694 - result = detect_tp();
5695 - if (!result) {
5696 - clrline();
5697 - printf("10Base-T (RJ-45%s",
5698 - ") has no cable\n"); }
5699 - /* check "ignore missing media" bit */
5700 - if (eth_auto_neg_cnf & IMM_BIT)
5701 - /* Yes! I don't care if I see a link pulse */
5702 - result = A_CNF_MEDIA_10B_T;
5703 - break;
5704 - case A_CNF_MEDIA_AUI:
5705 - result = detect_aui(nic);
5706 - if (!result) {
5707 - clrline();
5708 - printf("10Base-5 (AUI%s",
5709 - ") has no cable\n"); }
5710 - /* check "ignore missing media" bit */
5711 - if (eth_auto_neg_cnf & IMM_BIT)
5712 - /* Yes! I don't care if I see a carrrier */
5713 - result = A_CNF_MEDIA_AUI;
5714 - break;
5715 - case A_CNF_MEDIA_10B_2:
5716 - result = detect_bnc(nic);
5717 - if (!result) {
5718 - clrline();
5719 - printf("10Base-2 (BNC%s",
5720 - ") has no cable\n"); }
5721 - /* check "ignore missing media" bit */
5722 - if (eth_auto_neg_cnf & IMM_BIT)
5723 - /* Yes! I don't care if I can xmit a packet */
5724 - result = A_CNF_MEDIA_10B_2;
5725 - break;
5726 - case A_CNF_MEDIA_AUTO:
5727 - writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);
5728 - if (eth_adapter_cnf & A_CNF_10B_T)
5729 - if ((result = detect_tp()) != 0)
5730 - break;
5731 - if (eth_adapter_cnf & A_CNF_AUI)
5732 - if ((result = detect_aui(nic)) != 0)
5733 - break;
5734 - if (eth_adapter_cnf & A_CNF_10B_2)
5735 - if ((result = detect_bnc(nic)) != 0)
5736 - break;
5737 - clrline(); printf("no media detected\n");
5738 - goto error;
5740 - clrline();
5741 - switch(result) {
5742 - case 0: printf("no network cable attached to configured media\n");
5743 - goto error;
5744 - case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
5745 - break;
5746 - case A_CNF_MEDIA_AUI: printf("using 10Base-5 (AUI)\n");
5747 - break;
5748 - case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
5749 - break;
5752 - /* Turn on both receive and transmit operations */
5753 - writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
5754 - SERIAL_TX_ON);
5756 - break;
5759 - if (ioaddr == 0)
5760 - return (0);
5761 - nic->reset = cs89x0_reset;
5762 - nic->poll = cs89x0_poll;
5763 - nic->transmit = cs89x0_transmit;
5764 - nic->disable = cs89x0_disable;
5765 - return (nic);
5769 - * Local variables:
5770 - * c-basic-offset: 8
5771 - * End:
5772 - */
5774 Index: b/netboot/cs89x0.h
5775 ===================================================================
5776 --- a/netboot/cs89x0.h
5777 +++ b/netboot/cs89x0.h
5778 @@ -16,464 +16,3 @@
5779 -- quote from email
5782 -/* Copyright, 1988-1992, Russell Nelson, Crynwr Software
5784 - This program is free software; you can redistribute it and/or modify
5785 - it under the terms of the GNU General Public License as published by
5786 - the Free Software Foundation, version 1.
5788 - This program is distributed in the hope that it will be useful,
5789 - but WITHOUT ANY WARRANTY; without even the implied warranty of
5790 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5791 - GNU General Public License for more details.
5793 - You should have received a copy of the GNU General Public License
5794 - along with this program; if not, write to the Free Software
5795 - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
5797 -#define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */
5798 - /* offset 2h -> Model/Product Number */
5799 - /* offset 3h -> Chip Revision Number */
5801 -#define PP_ISAIOB 0x0020 /* IO base address */
5802 -#define PP_CS8900_ISAINT 0x0022 /* ISA interrupt select */
5803 -#define PP_CS8920_ISAINT 0x0370 /* ISA interrupt select */
5804 -#define PP_CS8900_ISADMA 0x0024 /* ISA Rec DMA channel */
5805 -#define PP_CS8920_ISADMA 0x0374 /* ISA Rec DMA channel */
5806 -#define PP_ISASOF 0x0026 /* ISA DMA offset */
5807 -#define PP_DmaFrameCnt 0x0028 /* ISA DMA Frame count */
5808 -#define PP_DmaByteCnt 0x002A /* ISA DMA Byte count */
5809 -#define PP_CS8900_ISAMemB 0x002C /* Memory base */
5810 -#define PP_CS8920_ISAMemB 0x0348 /* */
5812 -#define PP_ISABootBase 0x0030 /* Boot Prom base */
5813 -#define PP_ISABootMask 0x0034 /* Boot Prom Mask */
5815 -/* EEPROM data and command registers */
5816 -#define PP_EECMD 0x0040 /* NVR Interface Command register */
5817 -#define PP_EEData 0x0042 /* NVR Interface Data Register */
5818 -#define PP_DebugReg 0x0044 /* Debug Register */
5820 -#define PP_RxCFG 0x0102 /* Rx Bus config */
5821 -#define PP_RxCTL 0x0104 /* Receive Control Register */
5822 -#define PP_TxCFG 0x0106 /* Transmit Config Register */
5823 -#define PP_TxCMD 0x0108 /* Transmit Command Register */
5824 -#define PP_BufCFG 0x010A /* Bus configuration Register */
5825 -#define PP_LineCTL 0x0112 /* Line Config Register */
5826 -#define PP_SelfCTL 0x0114 /* Self Command Register */
5827 -#define PP_BusCTL 0x0116 /* ISA bus control Register */
5828 -#define PP_TestCTL 0x0118 /* Test Register */
5829 -#define PP_AutoNegCTL 0x011C /* Auto Negotiation Ctrl */
5831 -#define PP_ISQ 0x0120 /* Interrupt Status */
5832 -#define PP_RxEvent 0x0124 /* Rx Event Register */
5833 -#define PP_TxEvent 0x0128 /* Tx Event Register */
5834 -#define PP_BufEvent 0x012C /* Bus Event Register */
5835 -#define PP_RxMiss 0x0130 /* Receive Miss Count */
5836 -#define PP_TxCol 0x0132 /* Transmit Collision Count */
5837 -#define PP_LineST 0x0134 /* Line State Register */
5838 -#define PP_SelfST 0x0136 /* Self State register */
5839 -#define PP_BusST 0x0138 /* Bus Status */
5840 -#define PP_TDR 0x013C /* Time Domain Reflectometry */
5841 -#define PP_AutoNegST 0x013E /* Auto Neg Status */
5842 -#define PP_TxCommand 0x0144 /* Tx Command */
5843 -#define PP_TxLength 0x0146 /* Tx Length */
5844 -#define PP_LAF 0x0150 /* Hash Table */
5845 -#define PP_IA 0x0158 /* Physical Address Register */
5847 -#define PP_RxStatus 0x0400 /* Receive start of frame */
5848 -#define PP_RxLength 0x0402 /* Receive Length of frame */
5849 -#define PP_RxFrame 0x0404 /* Receive frame pointer */
5850 -#define PP_TxFrame 0x0A00 /* Transmit frame pointer */
5852 -/* Primary I/O Base Address. If no I/O base is supplied by the user, then this */
5853 -/* can be used as the default I/O base to access the PacketPage Area. */
5854 -#define DEFAULTIOBASE 0x0300
5855 -#define FIRST_IO 0x020C /* First I/O port to check */
5856 -#define LAST_IO 0x037C /* Last I/O port to check (+10h) */
5857 -#define ADD_MASK 0x3000 /* Mask it use of the ADD_PORT register */
5858 -#define ADD_SIG 0x3000 /* Expected ID signature */
5860 -#define CHIP_EISA_ID_SIG 0x630E /* Product ID Code for Crystal Chip (CS8900 spec 4.3) */
5862 -#ifdef IBMEIPKT
5863 -#define EISA_ID_SIG 0x4D24 /* IBM */
5864 -#define PART_NO_SIG 0x1010 /* IBM */
5865 -#define MONGOOSE_BIT 0x0000 /* IBM */
5866 -#else
5867 -#define EISA_ID_SIG 0x630E /* PnP Vendor ID (same as chip id for Crystal board) */
5868 -#define PART_NO_SIG 0x4000 /* ID code CS8920 board (PnP Vendor Product code) */
5869 -#define MONGOOSE_BIT 0x2000 /* PART_NO_SIG + MONGOOSE_BUT => ID of mongoose */
5870 -#endif
5872 -#define PRODUCT_ID_ADD 0x0002 /* Address of product ID */
5874 -/* Mask to find out the types of registers */
5875 -#define REG_TYPE_MASK 0x001F
5877 -/* Eeprom Commands */
5878 -#define ERSE_WR_ENBL 0x00F0
5879 -#define ERSE_WR_DISABLE 0x0000
5881 -/* Defines Control/Config register quintuplet numbers */
5882 -#define RX_BUF_CFG 0x0003
5883 -#define RX_CONTROL 0x0005
5884 -#define TX_CFG 0x0007
5885 -#define TX_COMMAND 0x0009
5886 -#define BUF_CFG 0x000B
5887 -#define LINE_CONTROL 0x0013
5888 -#define SELF_CONTROL 0x0015
5889 -#define BUS_CONTROL 0x0017
5890 -#define TEST_CONTROL 0x0019
5892 -/* Defines Status/Count registers quintuplet numbers */
5893 -#define RX_EVENT 0x0004
5894 -#define TX_EVENT 0x0008
5895 -#define BUF_EVENT 0x000C
5896 -#define RX_MISS_COUNT 0x0010
5897 -#define TX_COL_COUNT 0x0012
5898 -#define LINE_STATUS 0x0014
5899 -#define SELF_STATUS 0x0016
5900 -#define BUS_STATUS 0x0018
5901 -#define TDR 0x001C
5903 -/* PP_RxCFG - Receive Configuration and Interrupt Mask bit definition - Read/write */
5904 -#define SKIP_1 0x0040
5905 -#define RX_STREAM_ENBL 0x0080
5906 -#define RX_OK_ENBL 0x0100
5907 -#define RX_DMA_ONLY 0x0200
5908 -#define AUTO_RX_DMA 0x0400
5909 -#define BUFFER_CRC 0x0800
5910 -#define RX_CRC_ERROR_ENBL 0x1000
5911 -#define RX_RUNT_ENBL 0x2000
5912 -#define RX_EXTRA_DATA_ENBL 0x4000
5914 -/* PP_RxCTL - Receive Control bit definition - Read/write */
5915 -#define RX_IA_HASH_ACCEPT 0x0040
5916 -#define RX_PROM_ACCEPT 0x0080
5917 -#define RX_OK_ACCEPT 0x0100
5918 -#define RX_MULTCAST_ACCEPT 0x0200
5919 -#define RX_IA_ACCEPT 0x0400
5920 -#define RX_BROADCAST_ACCEPT 0x0800
5921 -#define RX_BAD_CRC_ACCEPT 0x1000
5922 -#define RX_RUNT_ACCEPT 0x2000
5923 -#define RX_EXTRA_DATA_ACCEPT 0x4000
5924 -#define RX_ALL_ACCEPT (RX_PROM_ACCEPT|RX_BAD_CRC_ACCEPT|RX_RUNT_ACCEPT|RX_EXTRA_DATA_ACCEPT)
5925 -/* Default receive mode - individually addressed, broadcast, and error free */
5926 -#define DEF_RX_ACCEPT (RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | RX_OK_ACCEPT)
5928 -/* PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write */
5929 -#define TX_LOST_CRS_ENBL 0x0040
5930 -#define TX_SQE_ERROR_ENBL 0x0080
5931 -#define TX_OK_ENBL 0x0100
5932 -#define TX_LATE_COL_ENBL 0x0200
5933 -#define TX_JBR_ENBL 0x0400
5934 -#define TX_ANY_COL_ENBL 0x0800
5935 -#define TX_16_COL_ENBL 0x8000
5937 -/* PP_TxCMD - Transmit Command bit definition - Read-only */
5938 -#define TX_START_4_BYTES 0x0000
5939 -#define TX_START_64_BYTES 0x0040
5940 -#define TX_START_128_BYTES 0x0080
5941 -#define TX_START_ALL_BYTES 0x00C0
5942 -#define TX_FORCE 0x0100
5943 -#define TX_ONE_COL 0x0200
5944 -#define TX_TWO_PART_DEFF_DISABLE 0x0400
5945 -#define TX_NO_CRC 0x1000
5946 -#define TX_RUNT 0x2000
5948 -/* PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write */
5949 -#define GENERATE_SW_INTERRUPT 0x0040
5950 -#define RX_DMA_ENBL 0x0080
5951 -#define READY_FOR_TX_ENBL 0x0100
5952 -#define TX_UNDERRUN_ENBL 0x0200
5953 -#define RX_MISS_ENBL 0x0400
5954 -#define RX_128_BYTE_ENBL 0x0800
5955 -#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000
5956 -#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000
5957 -#define RX_DEST_MATCH_ENBL 0x8000
5959 -/* PP_LineCTL - Line Control bit definition - Read/write */
5960 -#define SERIAL_RX_ON 0x0040
5961 -#define SERIAL_TX_ON 0x0080
5962 -#define AUI_ONLY 0x0100
5963 -#define AUTO_AUI_10BASET 0x0200
5964 -#define MODIFIED_BACKOFF 0x0800
5965 -#define NO_AUTO_POLARITY 0x1000
5966 -#define TWO_PART_DEFDIS 0x2000
5967 -#define LOW_RX_SQUELCH 0x4000
5969 -/* PP_SelfCTL - Software Self Control bit definition - Read/write */
5970 -#define POWER_ON_RESET 0x0040
5971 -#define SW_STOP 0x0100
5972 -#define SLEEP_ON 0x0200
5973 -#define AUTO_WAKEUP 0x0400
5974 -#define HCB0_ENBL 0x1000
5975 -#define HCB1_ENBL 0x2000
5976 -#define HCB0 0x4000
5977 -#define HCB1 0x8000
5979 -/* PP_BusCTL - ISA Bus Control bit definition - Read/write */
5980 -#define RESET_RX_DMA 0x0040
5981 -#define MEMORY_ON 0x0400
5982 -#define DMA_BURST_MODE 0x0800
5983 -#define IO_CHANNEL_READY_ON 0x1000
5984 -#define RX_DMA_SIZE_64K 0x2000
5985 -#define ENABLE_IRQ 0x8000
5987 -/* PP_TestCTL - Test Control bit definition - Read/write */
5988 -#define LINK_OFF 0x0080
5989 -#define ENDEC_LOOPBACK 0x0200
5990 -#define AUI_LOOPBACK 0x0400
5991 -#define BACKOFF_OFF 0x0800
5992 -#define FAST_TEST 0x8000
5994 -/* PP_RxEvent - Receive Event Bit definition - Read-only */
5995 -#define RX_IA_HASHED 0x0040
5996 -#define RX_DRIBBLE 0x0080
5997 -#define RX_OK 0x0100
5998 -#define RX_HASHED 0x0200
5999 -#define RX_IA 0x0400
6000 -#define RX_BROADCAST 0x0800
6001 -#define RX_CRC_ERROR 0x1000
6002 -#define RX_RUNT 0x2000
6003 -#define RX_EXTRA_DATA 0x4000
6005 -#define HASH_INDEX_MASK 0x0FC00
6007 -/* PP_TxEvent - Transmit Event Bit definition - Read-only */
6008 -#define TX_LOST_CRS 0x0040
6009 -#define TX_SQE_ERROR 0x0080
6010 -#define TX_OK 0x0100
6011 -#define TX_LATE_COL 0x0200
6012 -#define TX_JBR 0x0400
6013 -#define TX_16_COL 0x8000
6014 -#define TX_SEND_OK_BITS (TX_OK|TX_LOST_CRS)
6015 -#define TX_COL_COUNT_MASK 0x7800
6017 -/* PP_BufEvent - Buffer Event Bit definition - Read-only */
6018 -#define SW_INTERRUPT 0x0040
6019 -#define RX_DMA 0x0080
6020 -#define READY_FOR_TX 0x0100
6021 -#define TX_UNDERRUN 0x0200
6022 -#define RX_MISS 0x0400
6023 -#define RX_128_BYTE 0x0800
6024 -#define TX_COL_OVRFLW 0x1000
6025 -#define RX_MISS_OVRFLW 0x2000
6026 -#define RX_DEST_MATCH 0x8000
6028 -/* PP_LineST - Ethernet Line Status bit definition - Read-only */
6029 -#define LINK_OK 0x0080
6030 -#define AUI_ON 0x0100
6031 -#define TENBASET_ON 0x0200
6032 -#define POLARITY_OK 0x1000
6033 -#define CRS_OK 0x4000
6035 -/* PP_SelfST - Chip Software Status bit definition */
6036 -#define ACTIVE_33V 0x0040
6037 -#define INIT_DONE 0x0080
6038 -#define SI_BUSY 0x0100
6039 -#define EEPROM_PRESENT 0x0200
6040 -#define EEPROM_OK 0x0400
6041 -#define EL_PRESENT 0x0800
6042 -#define EE_SIZE_64 0x1000
6044 -/* PP_BusST - ISA Bus Status bit definition */
6045 -#define TX_BID_ERROR 0x0080
6046 -#define READY_FOR_TX_NOW 0x0100
6048 -/* PP_AutoNegCTL - Auto Negotiation Control bit definition */
6049 -#define RE_NEG_NOW 0x0040
6050 -#define ALLOW_FDX 0x0080
6051 -#define AUTO_NEG_ENABLE 0x0100
6052 -#define NLP_ENABLE 0x0200
6053 -#define FORCE_FDX 0x8000
6054 -#define AUTO_NEG_BITS (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE)
6055 -#define AUTO_NEG_MASK (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE|ALLOW_FDX|RE_NEG_NOW)
6057 -/* PP_AutoNegST - Auto Negotiation Status bit definition */
6058 -#define AUTO_NEG_BUSY 0x0080
6059 -#define FLP_LINK 0x0100
6060 -#define FLP_LINK_GOOD 0x0800
6061 -#define LINK_FAULT 0x1000
6062 -#define HDX_ACTIVE 0x4000
6063 -#define FDX_ACTIVE 0x8000
6065 -/* The following block defines the ISQ event types */
6066 -#define ISQ_RECEIVER_EVENT 0x04
6067 -#define ISQ_TRANSMITTER_EVENT 0x08
6068 -#define ISQ_BUFFER_EVENT 0x0c
6069 -#define ISQ_RX_MISS_EVENT 0x10
6070 -#define ISQ_TX_COL_EVENT 0x12
6072 -#define ISQ_EVENT_MASK 0x003F /* ISQ mask to find out type of event */
6073 -#define ISQ_HIST 16 /* small history buffer */
6074 -#define AUTOINCREMENT 0x8000 /* Bit mask to set bit-15 for autoincrement */
6076 -#define TXRXBUFSIZE 0x0600
6077 -#define RXDMABUFSIZE 0x8000
6078 -#define RXDMASIZE 0x4000
6079 -#define TXRX_LENGTH_MASK 0x07FF
6081 -/* rx options bits */
6082 -#define RCV_WITH_RXON 1 /* Set SerRx ON */
6083 -#define RCV_COUNTS 2 /* Use Framecnt1 */
6084 -#define RCV_PONG 4 /* Pong respondent */
6085 -#define RCV_DONG 8 /* Dong operation */
6086 -#define RCV_POLLING 0x10 /* Poll RxEvent */
6087 -#define RCV_ISQ 0x20 /* Use ISQ, int */
6088 -#define RCV_AUTO_DMA 0x100 /* Set AutoRxDMAE */
6089 -#define RCV_DMA 0x200 /* Set RxDMA only */
6090 -#define RCV_DMA_ALL 0x400 /* Copy all DMA'ed */
6091 -#define RCV_FIXED_DATA 0x800 /* Every frame same */
6092 -#define RCV_IO 0x1000 /* Use ISA IO only */
6093 -#define RCV_MEMORY 0x2000 /* Use ISA Memory */
6095 -#define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */
6096 -#define PKT_START PP_TxFrame /* Start of packet RAM */
6098 -#define RX_FRAME_PORT 0x0000
6099 -#define TX_FRAME_PORT RX_FRAME_PORT
6100 -#define TX_CMD_PORT 0x0004
6101 -#define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */
6102 -#define TX_AFTER_381 0x0020 /* Tx packet after 381 bytes copied */
6103 -#define TX_AFTER_ALL 0x0060 /* Tx packet after all bytes copied */
6104 -#define TX_LEN_PORT 0x0006
6105 -#define ISQ_PORT 0x0008
6106 -#define ADD_PORT 0x000A
6107 -#define DATA_PORT 0x000C
6109 -#define EEPROM_WRITE_EN 0x00F0
6110 -#define EEPROM_WRITE_DIS 0x0000
6111 -#define EEPROM_WRITE_CMD 0x0100
6112 -#define EEPROM_READ_CMD 0x0200
6114 -/* Receive Header */
6115 -/* Description of header of each packet in receive area of memory */
6116 -#define RBUF_EVENT_LOW 0 /* Low byte of RxEvent - status of received frame */
6117 -#define RBUF_EVENT_HIGH 1 /* High byte of RxEvent - status of received frame */
6118 -#define RBUF_LEN_LOW 2 /* Length of received data - low byte */
6119 -#define RBUF_LEN_HI 3 /* Length of received data - high byte */
6120 -#define RBUF_HEAD_LEN 4 /* Length of this header */
6122 -#define CHIP_READ 0x1 /* Used to mark state of the repins code (chip or dma) */
6123 -#define DMA_READ 0x2 /* Used to mark state of the repins code (chip or dma) */
6125 -/* for bios scan */
6126 -/* */
6127 -#ifdef CSDEBUG
6128 -/* use these values for debugging bios scan */
6129 -#define BIOS_START_SEG 0x00000
6130 -#define BIOS_OFFSET_INC 0x0010
6131 -#else
6132 -#define BIOS_START_SEG 0x0c000
6133 -#define BIOS_OFFSET_INC 0x0200
6134 -#endif
6136 -#define BIOS_LAST_OFFSET 0x0fc00
6138 -/* Byte offsets into the EEPROM configuration buffer */
6139 -#define ISA_CNF_OFFSET 0x6
6140 -#define TX_CTL_OFFSET (ISA_CNF_OFFSET + 8) /* 8900 eeprom */
6141 -#define AUTO_NEG_CNF_OFFSET (ISA_CNF_OFFSET + 8) /* 8920 eeprom */
6143 - /* the assumption here is that the bits in the eeprom are generally */
6144 - /* in the same position as those in the autonegctl register. */
6145 - /* Of course the IMM bit is not in that register so it must be */
6146 - /* masked out */
6147 -#define EE_FORCE_FDX 0x8000
6148 -#define EE_NLP_ENABLE 0x0200
6149 -#define EE_AUTO_NEG_ENABLE 0x0100
6150 -#define EE_ALLOW_FDX 0x0080
6151 -#define EE_AUTO_NEG_CNF_MASK (EE_FORCE_FDX|EE_NLP_ENABLE|EE_AUTO_NEG_ENABLE|EE_ALLOW_FDX)
6153 -#define IMM_BIT 0x0040 /* ignore missing media */
6155 -#define ADAPTER_CNF_OFFSET (AUTO_NEG_CNF_OFFSET + 2)
6156 -#define A_CNF_10B_T 0x0001
6157 -#define A_CNF_AUI 0x0002
6158 -#define A_CNF_10B_2 0x0004
6159 -#define A_CNF_MEDIA_TYPE 0x0060
6160 -#define A_CNF_MEDIA_AUTO 0x0000
6161 -#define A_CNF_MEDIA_10B_T 0x0020
6162 -#define A_CNF_MEDIA_AUI 0x0040
6163 -#define A_CNF_MEDIA_10B_2 0x0060
6164 -#define A_CNF_DC_DC_POLARITY 0x0080
6165 -#define A_CNF_NO_AUTO_POLARITY 0x2000
6166 -#define A_CNF_LOW_RX_SQUELCH 0x4000
6167 -#define A_CNF_EXTND_10B_2 0x8000
6169 -#define PACKET_PAGE_OFFSET 0x8
6171 -/* Bit definitions for the ISA configuration word from the EEPROM */
6172 -#define INT_NO_MASK 0x000F
6173 -#define DMA_NO_MASK 0x0070
6174 -#define ISA_DMA_SIZE 0x0200
6175 -#define ISA_AUTO_RxDMA 0x0400
6176 -#define ISA_RxDMA 0x0800
6177 -#define DMA_BURST 0x1000
6178 -#define STREAM_TRANSFER 0x2000
6179 -#define ANY_ISA_DMA (ISA_AUTO_RxDMA | ISA_RxDMA)
6181 -/* DMA controller registers */
6182 -#define DMA_BASE 0x00 /* DMA controller base */
6183 -#define DMA_BASE_2 0x0C0 /* DMA controller base */
6185 -#define DMA_STAT 0x0D0 /* DMA controller status register */
6186 -#define DMA_MASK 0x0D4 /* DMA controller mask register */
6187 -#define DMA_MODE 0x0D6 /* DMA controller mode register */
6188 -#define DMA_RESETFF 0x0D8 /* DMA controller first/last flip flop */
6190 -/* DMA data */
6191 -#define DMA_DISABLE 0x04 /* Disable channel n */
6192 -#define DMA_ENABLE 0x00 /* Enable channel n */
6193 -/* Demand transfers, incr. address, auto init, writes, ch. n */
6194 -#define DMA_RX_MODE 0x14
6195 -/* Demand transfers, incr. address, auto init, reads, ch. n */
6196 -#define DMA_TX_MODE 0x18
6198 -#define DMA_SIZE (16*1024) /* Size of dma buffer - 16k */
6200 -#define CS8900 0x0000
6201 -#define CS8920 0x4000
6202 -#define CS8920M 0x6000
6203 -#define REVISON_BITS 0x1F00
6204 -#define EEVER_NUMBER 0x12
6205 -#define CHKSUM_LEN 0x14
6206 -#define CHKSUM_VAL 0x0000
6207 -#define START_EEPROM_DATA 0x001c /* Offset into eeprom for start of data */
6208 -#define IRQ_MAP_EEPROM_DATA 0x0046 /* Offset into eeprom for the IRQ map */
6209 -#define IRQ_MAP_LEN 0x0004 /* No of bytes to read for the IRQ map */
6210 -#define PNP_IRQ_FRMT 0x0022 /* PNP small item IRQ format */
6211 -#define CS8900_IRQ_MAP 0x1c20 /* This IRQ map is fixed */
6213 -#define CS8920_NO_INTS 0x0F /* Max CS8920 interrupt select # */
6215 -#define PNP_ADD_PORT 0x0279
6216 -#define PNP_WRITE_PORT 0x0A79
6218 -#define GET_PNP_ISA_STRUCT 0x40
6219 -#define PNP_ISA_STRUCT_LEN 0x06
6220 -#define PNP_CSN_CNT_OFF 0x01
6221 -#define PNP_RD_PORT_OFF 0x02
6222 -#define PNP_FUNCTION_OK 0x00
6223 -#define PNP_WAKE 0x03
6224 -#define PNP_RSRC_DATA 0x04
6225 -#define PNP_RSRC_READY 0x01
6226 -#define PNP_STATUS 0x05
6227 -#define PNP_ACTIVATE 0x30
6228 -#define PNP_CNF_IO_H 0x60
6229 -#define PNP_CNF_IO_L 0x61
6230 -#define PNP_CNF_INT 0x70
6231 -#define PNP_CNF_DMA 0x74
6232 -#define PNP_CNF_MEM 0x48
6234 -#define BIT0 1
6235 -#define BIT15 0x8000
6238 - * Local variables:
6239 - * c-basic-offset: 8
6240 - * End:
6241 - */
6243 Index: b/netboot/cs89x0.txt
6244 ===================================================================
6245 --- a/netboot/cs89x0.txt
6246 +++ /dev/null
6247 @@ -1,26 +0,0 @@
6248 -Permission is granted to distribute the enclosed cs89x0.[ch] driver
6249 -only in conjunction with the Etherboot package. The code is
6250 -ordinarily distributed under the GPL.
6252 -Russ Nelson, January 2000
6254 -CREDITS
6256 -I want to thank
6258 - Mike Cruse <mcruse@cti-ltd.com>
6259 - for providing an evaluation NIC and for sponsoring the
6260 - development of this driver.
6262 - Randall Sears <sears@crystal.cirrus.com>
6263 - Deva Bodas <bodas@crystal.cirrus.com>
6264 - Andreas Kraemer <akraemer@crystal.cirrus.com>
6265 - Wolfgang Krause <100303.2673@compuserve.com>
6266 - for excellent technical support and for providing the required
6267 - programming information. I appreciate Crystal Semiconductor's
6268 - commitment towards free software.
6270 - Russell Nelson <nelson@crynwr.com>
6271 - for writing the Linux device driver for the CS89x0
6272 - chipset. Russel's code is very well designed and simplified my
6273 - job a lot.
6274 Index: b/netboot/davicom.c
6275 ===================================================================
6276 --- a/netboot/davicom.c
6277 +++ b/netboot/davicom.c
6278 @@ -1,12 +1,12 @@
6279 +#ifdef ALLMULTI
6280 +#error multicast support is not yet implemented
6281 +#endif
6283 DAVICOM DM9009/DM9102/DM9102A Etherboot Driver V1.00
6285 - This driver was ported from Marty Conner's Tulip Etherboot driver.
6286 - Thanks Marty Connor (mdc@thinguin.org)
6287 - You can get Tulip driver source file from this URL:
6288 + This driver was ported from Marty Connor's Tulip Etherboot driver.
6289 + Thanks Marty Connor (mdc@etherboot.org)
6291 - "http://etherboot.sourceforge..net/#Distribution"
6293 This davicom etherboot driver supports DM9009/DM9102/DM9102A/
6294 DM9102A+DM9801/DM9102A+DM9802 NICs.
6296 @@ -36,7 +36,6 @@
6297 register(CR6)
6301 /*********************************************************************/
6302 /* Declarations */
6303 /*********************************************************************/
6304 @@ -44,7 +43,6 @@
6305 #include "etherboot.h"
6306 #include "nic.h"
6307 #include "pci.h"
6308 -#include "cards.h"
6310 #undef DAVICOM_DEBUG
6311 #undef DAVICOM_DEBUG_WHERE
6312 @@ -99,8 +97,10 @@
6313 #define eeprom_delay() inl(ee_addr)
6315 /* helpful macro if on a big_endian machine for changing byte order.
6316 - not strictly needed on Intel */
6317 + not strictly needed on Intel
6318 + Already defined in Etherboot includes
6319 #define le16_to_cpu(val) (val)
6322 /* transmit and receive descriptor format */
6323 struct txdesc {
6324 @@ -138,20 +138,12 @@
6325 /* transmit descriptor and buffer */
6326 #define NTXD 2
6327 static struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
6328 -#ifdef USE_LOWMEM_BUFFER
6329 -#define txb ((char *)0x10000 - BUFLEN)
6330 -#else
6331 static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
6332 -#endif
6334 /* receive descriptor(s) and buffer(s) */
6335 #define NRXD 4
6336 static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
6337 -#ifdef USE_LOWMEM_BUFFER
6338 -#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
6339 -#else
6340 static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
6341 -#endif
6342 static int rxd_tail;
6343 static int TxPtr;
6345 @@ -161,15 +153,13 @@
6346 /*********************************************************************/
6347 static void whereami(const char *str);
6348 static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
6349 -struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
6350 - struct pci_device *pci);
6351 +static int davicom_probe(struct dev *dev, struct pci_device *pci);
6352 static void davicom_init_chain(struct nic *nic); /* Sten 10/9 */
6353 static void davicom_reset(struct nic *nic);
6354 static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
6355 unsigned int s, const char *p);
6356 -static int davicom_poll(struct nic *nic);
6357 -static void davicom_disable(struct nic *nic);
6358 -static void whereami (const char *str);
6359 +static int davicom_poll(struct nic *nic, int retrieve);
6360 +static void davicom_disable(struct dev *dev);
6361 #ifdef DAVICOM_DEBUG
6362 static void davicom_more(void);
6363 #endif /* DAVICOM_DEBUG */
6364 @@ -184,13 +174,10 @@
6365 /*********************************************************************/
6366 /* Utility Routines */
6367 /*********************************************************************/
6369 -static inline void whereami (const char *str)
6370 +static inline void whereami(const char *str)
6372 -#ifdef DAVICOM_DEBUG_WHERE
6373 printf("%s\n", str);
6374 /* sleep(2); */
6375 -#endif
6378 #ifdef DAVICOM_DEBUG
6379 @@ -360,7 +347,7 @@
6381 Sense media mode and set CR6
6383 -static void davicom_media_chk(struct nic * nic)
6384 +static void davicom_media_chk(struct nic * nic __unused)
6386 unsigned long to, csr6;
6388 @@ -446,8 +433,8 @@
6389 /* Sten: Set 2 TX descriptor but use one TX buffer because
6390 it transmit a packet and wait complete every time. */
6391 for (i=0; i<NTXD; i++) {
6392 - txd[i].buf1addr = &txb[0]; /* Used same TX buffer */
6393 - txd[i].buf2addr = (unsigned char *)&txd[i+1]; /* Point to Next TX desc */
6394 + txd[i].buf1addr = (void *)virt_to_bus(&txb[0]); /* Used same TX buffer */
6395 + txd[i].buf2addr = (void *)virt_to_bus(&txd[i+1]); /* Point to Next TX desc */
6396 txd[i].buf1sz = 0;
6397 txd[i].buf2sz = 0;
6398 txd[i].control = 0x184; /* Begin/End/Chain */
6399 @@ -466,8 +453,8 @@
6401 /* setup receive descriptor */
6402 for (i=0; i<NRXD; i++) {
6403 - rxd[i].buf1addr = &rxb[i * BUFLEN];
6404 - rxd[i].buf2addr = (unsigned char *)&rxd[i+1]; /* Point to Next RX desc */
6405 + rxd[i].buf1addr = (void *)virt_to_bus(&rxb[i * BUFLEN]);
6406 + rxd[i].buf2addr = (void *)virt_to_bus(&rxd[i+1]); /* Point to Next RX desc */
6407 rxd[i].buf1sz = BUFLEN;
6408 rxd[i].buf2sz = 0; /* not used */
6409 rxd[i].control = 0x4; /* Chain Structure */
6410 @@ -475,8 +462,8 @@
6413 /* Chain the last descriptor to first */
6414 - txd[NTXD - 1].buf2addr = (unsigned char *)&txd[0];
6415 - rxd[NRXD - 1].buf2addr = (unsigned char *)&rxd[0];
6416 + txd[NTXD - 1].buf2addr = (void *)virt_to_bus(&txd[0]);
6417 + rxd[NRXD - 1].buf2addr = (void *)virt_to_bus(&rxd[0]);
6418 TxPtr = 0;
6419 rxd_tail = 0;
6421 @@ -488,7 +475,6 @@
6422 static void davicom_reset(struct nic *nic)
6424 unsigned long to;
6425 - u32 addr_low, addr_high;
6427 whereami("davicom_reset\n");
6429 @@ -507,8 +493,8 @@
6430 davicom_init_chain(nic); /* Sten 10/9 */
6432 /* Point to receive descriptor */
6433 - outl((unsigned long)&rxd[0], ioaddr + CSR3);
6434 - outl((unsigned long)&txd[0], ioaddr + CSR4); /* Sten 10/9 */
6435 + outl(virt_to_bus(&rxd[0]), ioaddr + CSR3);
6436 + outl(virt_to_bus(&txd[0]), ioaddr + CSR4); /* Sten 10/9 */
6438 /* According phyxcer media mode to set CR6,
6439 DM9102/A phyxcer can auto-detect media mode */
6440 @@ -591,13 +577,15 @@
6441 /*********************************************************************/
6442 /* eth_poll - Wait for a frame */
6443 /*********************************************************************/
6444 -static int davicom_poll(struct nic *nic)
6445 +static int davicom_poll(struct nic *nic, int retrieve)
6447 whereami("davicom_poll\n");
6449 if (rxd[rxd_tail].status & 0x80000000)
6450 return 0;
6452 + if ( ! retrieve ) return 1;
6454 whereami("davicom_poll got one\n");
6456 nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
6457 @@ -627,10 +615,13 @@
6458 /*********************************************************************/
6459 /* eth_disable - Disable the interface */
6460 /*********************************************************************/
6461 -static void davicom_disable(struct nic *nic)
6462 +static void davicom_disable(struct dev *dev)
6464 + struct nic *nic = (struct nic *)dev;
6465 whereami("davicom_disable\n");
6467 + davicom_reset(nic);
6469 /* disable interrupts */
6470 outl(0x00000000, ioaddr + CSR7);
6472 @@ -640,24 +631,43 @@
6473 /* Clear the missed-packet counter. */
6474 (volatile unsigned long)inl(ioaddr + CSR8);
6478 +/*********************************************************************/
6479 +/* eth_irq - enable, disable and force interrupts */
6480 +/*********************************************************************/
6481 +static void davicom_irq(struct nic *nic __unused, irq_action_t action __unused)
6483 + switch ( action ) {
6484 + case DISABLE :
6485 + break;
6486 + case ENABLE :
6487 + break;
6488 + case FORCE :
6489 + break;
6494 /*********************************************************************/
6495 /* eth_probe - Look for an adapter */
6496 /*********************************************************************/
6497 -struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
6498 - struct pci_device *pci)
6499 +static int davicom_probe(struct dev *dev, struct pci_device *pci)
6501 + struct nic *nic = (struct nic *)dev;
6502 unsigned int i;
6503 - u32 l1, l2;
6505 whereami("davicom_probe\n");
6507 - if (io_addrs == 0 || *io_addrs == 0)
6508 + if (pci->ioaddr == 0)
6509 return 0;
6511 vendor = pci->vendor;
6512 dev_id = pci->dev_id;
6513 - ioaddr = *io_addrs;
6514 + ioaddr = pci->ioaddr & ~3;
6516 + nic->irqno = 0;
6517 + nic->ioaddr = pci->ioaddr & ~3;
6519 /* wakeup chip */
6520 pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
6521 @@ -683,10 +693,26 @@
6522 /* initialize device */
6523 davicom_reset(nic);
6525 - nic->reset = davicom_reset;
6526 + dev->disable = davicom_disable;
6527 nic->poll = davicom_poll;
6528 nic->transmit = davicom_transmit;
6529 - nic->disable = davicom_disable;
6530 + nic->irq = davicom_irq;
6532 - return nic;
6533 + return 1;
6536 +static struct pci_id davicom_nics[] = {
6537 +PCI_ROM(0x1282, 0x9100, "davicom9100", "Davicom 9100"),
6538 +PCI_ROM(0x1282, 0x9102, "davicom9102", "Davicom 9102"),
6539 +PCI_ROM(0x1282, 0x9009, "davicom9009", "Davicom 9009"),
6540 +PCI_ROM(0x1282, 0x9132, "davicom9132", "Davicom 9132"), /* Needs probably some fixing */
6543 +struct pci_driver davicom_driver = {
6544 + .type = NIC_DRIVER,
6545 + .name = "DAVICOM",
6546 + .probe = davicom_probe,
6547 + .ids = davicom_nics,
6548 + .id_count = sizeof(davicom_nics)/sizeof(davicom_nics[0]),
6549 + .class = 0,
6551 Index: b/netboot/depca.c
6552 ===================================================================
6553 --- a/netboot/depca.c
6554 +++ /dev/null
6555 @@ -1,752 +0,0 @@
6556 -/* Etherboot: depca.h merged, comments from Linux driver retained */
6557 -/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
6559 - Written 1994, 1995 by David C. Davies.
6562 - Copyright 1994 David C. Davies
6563 - and
6564 - United States Government
6565 - (as represented by the Director, National Security Agency).
6567 - Copyright 1995 Digital Equipment Corporation.
6570 - This software may be used and distributed according to the terms of
6571 - the GNU Public License, incorporated herein by reference.
6573 - This driver is written for the Digital Equipment Corporation series
6574 - of DEPCA and EtherWORKS ethernet cards:
6576 - DEPCA (the original)
6577 - DE100
6578 - DE101
6579 - DE200 Turbo
6580 - DE201 Turbo
6581 - DE202 Turbo (TP BNC)
6582 - DE210
6583 - DE422 (EISA)
6585 - The driver has been tested on DE100, DE200 and DE202 cards in a
6586 - relatively busy network. The DE422 has been tested a little.
6588 - This driver will NOT work for the DE203, DE204 and DE205 series of
6589 - cards, since they have a new custom ASIC in place of the AMD LANCE
6590 - chip. See the 'ewrk3.c' driver in the Linux source tree for running
6591 - those cards.
6593 - I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
6594 - a DECstation 5000/200.
6596 - The author may be reached at davies@maniac.ultranet.com
6598 - =========================================================================
6600 - The driver was originally based on the 'lance.c' driver from Donald
6601 - Becker which is included with the standard driver distribution for
6602 - linux. V0.4 is a complete re-write with only the kernel interface
6603 - remaining from the original code.
6605 - 1) Lance.c code in /linux/drivers/net/
6606 - 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
6607 - AMD, 1992 [(800) 222-9323].
6608 - 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
6609 - AMD, Pub. #17881, May 1993.
6610 - 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
6611 - AMD, Pub. #16907, May 1992
6612 - 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
6613 - Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
6614 - 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
6615 - Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
6616 - 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
6617 - Digital Equipment Corporation, 1989
6618 - 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
6619 - Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
6622 - Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
6623 - driver.
6625 - The original DEPCA card requires that the ethernet ROM address counter
6626 - be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
6627 - only done when a 0x08 is read as the first address octet (to minimise
6628 - the chances of writing over some other hardware's I/O register). The
6629 - NICSR accesses have been changed to byte accesses for all the cards
6630 - supported by this driver, since there is only one useful bit in the MSB
6631 - (remote boot timeout) and it is not used. Also, there is a maximum of
6632 - only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
6633 - help debugging all this (and holding my feet to the fire until I got it
6634 - right).
6636 - The DE200 series boards have on-board 64kB RAM for use as a shared
6637 - memory network buffer. Only the DE100 cards make use of a 2kB buffer
6638 - mode which has not been implemented in this driver (only the 32kB and
6639 - 64kB modes are supported [16kB/48kB for the original DEPCA]).
6641 - At the most only 2 DEPCA cards can be supported on the ISA bus because
6642 - there is only provision for two I/O base addresses on each card (0x300
6643 - and 0x200). The I/O address is detected by searching for a byte sequence
6644 - in the Ethernet station address PROM at the expected I/O address for the
6645 - Ethernet PROM. The shared memory base address is 'autoprobed' by
6646 - looking for the self test PROM and detecting the card name. When a
6647 - second DEPCA is detected, information is placed in the base_addr
6648 - variable of the next device structure (which is created if necessary),
6649 - thus enabling ethif_probe initialization for the device. More than 2
6650 - EISA cards can be supported, but care will be needed assigning the
6651 - shared memory to ensure that each slot has the correct IRQ, I/O address
6652 - and shared memory address assigned.
6654 - ************************************************************************
6656 - NOTE: If you are using two ISA DEPCAs, it is important that you assign
6657 - the base memory addresses correctly. The driver autoprobes I/O 0x300
6658 - then 0x200. The base memory address for the first device must be less
6659 - than that of the second so that the auto probe will correctly assign the
6660 - I/O and memory addresses on the same card. I can't think of a way to do
6661 - this unambiguously at the moment, since there is nothing on the cards to
6662 - tie I/O and memory information together.
6664 - I am unable to test 2 cards together for now, so this code is
6665 - unchecked. All reports, good or bad, are welcome.
6667 - ************************************************************************
6669 - The board IRQ setting must be at an unused IRQ which is auto-probed
6670 - using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
6671 - {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
6672 - really IRQ9 in machines with 16 IRQ lines.
6674 - No 16MB memory limitation should exist with this driver as DMA is not
6675 - used and the common memory area is in low memory on the network card (my
6676 - current system has 20MB and I've not had problems yet).
6678 - The ability to load this driver as a loadable module has been added. To
6679 - utilise this ability, you have to do <8 things:
6681 - 0) have a copy of the loadable modules code installed on your system.
6682 - 1) copy depca.c from the /linux/drivers/net directory to your favourite
6683 - temporary directory.
6684 - 2) if you wish, edit the source code near line 1530 to reflect the I/O
6685 - address and IRQ you're using (see also 5).
6686 - 3) compile depca.c, but include -DMODULE in the command line to ensure
6687 - that the correct bits are compiled (see end of source code).
6688 - 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
6689 - kernel with the depca configuration turned off and reboot.
6690 - 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
6691 - [Alan Cox: Changed the code to allow command line irq/io assignments]
6692 - [Dave Davies: Changed the code to allow command line mem/name
6693 - assignments]
6694 - 6) run the net startup bits for your eth?? interface manually
6695 - (usually /etc/rc.inet[12] at boot time).
6696 - 7) enjoy!
6698 - Note that autoprobing is not allowed in loadable modules - the system is
6699 - already up and running and you're messing with interrupts.
6701 - To unload a module, turn off the associated interface
6702 - 'ifconfig eth?? down' then 'rmmod depca'.
6704 - To assign a base memory address for the shared memory when running as a
6705 - loadable module, see 5 above. To include the adapter name (if you have
6706 - no PROM but know the card name) also see 5 above. Note that this last
6707 - option will not work with kernel built-in depca's.
6709 - The shared memory assignment for a loadable module makes sense to avoid
6710 - the 'memory autoprobe' picking the wrong shared memory (for the case of
6711 - 2 depca's in a PC).
6713 - ************************************************************************
6714 - Support for MCA EtherWORKS cards added 11-3-98.
6715 - Verified to work with up to 2 DE212 cards in a system (although not
6716 - fully stress-tested).
6718 - Currently known bugs/limitations:
6720 - Note: with the MCA stuff as a module, it trusts the MCA configuration,
6721 - not the command line for IRQ and memory address. You can
6722 - specify them if you want, but it will throw your values out.
6723 - You still have to pass the IO address it was configured as
6724 - though.
6726 - ************************************************************************
6727 - TO DO:
6728 - ------
6731 - Revision History
6732 - ----------------
6734 - Version Date Description
6736 - 0.1 25-jan-94 Initial writing.
6737 - 0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
6738 - 0.3 1-feb-94 Added multiple DEPCA support.
6739 - 0.31 4-feb-94 Added DE202 recognition.
6740 - 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
6741 - 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
6742 - Add jabber packet fix from murf@perftech.com
6743 - and becker@super.org
6744 - 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
6745 - 0.35 8-mar-94 Added DE201 recognition. Tidied up.
6746 - 0.351 30-apr-94 Added EISA support. Added DE422 recognition.
6747 - 0.36 16-may-94 DE422 fix released.
6748 - 0.37 22-jul-94 Added MODULE support
6749 - 0.38 15-aug-94 Added DBR ROM switch in depca_close().
6750 - Multi DEPCA bug fix.
6751 - 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
6752 - 0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
6753 - 0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
6754 - 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
6755 - <stromain@alf.dec.com>
6756 - 0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
6757 - 0.385 3-apr-95 Fix a recognition bug reported by
6758 - <ryan.niemi@lastfrontier.com>
6759 - 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
6760 - 0.40 25-May-95 Rewrite for portability & updated.
6761 - ALPHA support from <jestabro@amt.tay1.dec.com>
6762 - 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
6763 - suggestion by <heiko@colossus.escape.de>
6764 - 0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
6765 - modules.
6766 - Add 'adapter_name' for loadable modules when no PROM.
6767 - Both above from a suggestion by
6768 - <pchen@woodruffs121.residence.gatech.edu>.
6769 - Add new multicasting code.
6770 - 0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
6771 - 0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
6772 - 0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
6773 - 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
6774 - 0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug
6775 - reported by <mmogilvi@elbert.uccs.edu>
6776 - 0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards
6777 - by <tymm@computer.org>
6778 - 0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
6779 - 0.5 14-Nov-98 Re-spin for 2.1.x kernels.
6780 - 0.51 27-Jun-99 Correct received packet length for CRC from
6781 - report by <worm@dkik.dk>
6783 - =========================================================================
6786 -#include "etherboot.h"
6787 -#include "nic.h"
6788 -#include "cards.h"
6791 -** I/O addresses. Note that the 2k buffer option is not supported in
6792 -** this driver.
6794 -#define DEPCA_NICSR ioaddr+0x00 /* Network interface CSR */
6795 -#define DEPCA_RBI ioaddr+0x02 /* RAM buffer index (2k buffer mode) */
6796 -#define DEPCA_DATA ioaddr+0x04 /* LANCE registers' data port */
6797 -#define DEPCA_ADDR ioaddr+0x06 /* LANCE registers' address port */
6798 -#define DEPCA_HBASE ioaddr+0x08 /* EISA high memory base address reg. */
6799 -#define DEPCA_PROM ioaddr+0x0c /* Ethernet address ROM data port */
6800 -#define DEPCA_CNFG ioaddr+0x0c /* EISA Configuration port */
6801 -#define DEPCA_RBSA ioaddr+0x0e /* RAM buffer starting address (2k buff.) */
6804 -** These are LANCE registers addressable through DEPCA_ADDR
6806 -#define CSR0 0
6807 -#define CSR1 1
6808 -#define CSR2 2
6809 -#define CSR3 3
6811 -/*
6812 -** NETWORK INTERFACE CSR (NI_CSR) bit definitions
6815 -#define TO 0x0100 /* Time Out for remote boot */
6816 -#define SHE 0x0080 /* SHadow memory Enable */
6817 -#define BS 0x0040 /* Bank Select */
6818 -#define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */
6819 -#define RBE 0x0010 /* Remote Boot Enable (1->net boot) */
6820 -#define AAC 0x0008 /* Address ROM Address Counter (1->enable) */
6821 -#define _128KB 0x0008 /* 128kB Network RAM (1->enable) */
6822 -#define IM 0x0004 /* Interrupt Mask (1->mask) */
6823 -#define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */
6824 -#define LED 0x0001 /* LED control */
6826 -/*
6827 -** Control and Status Register 0 (CSR0) bit definitions
6830 -#define ERR 0x8000 /* Error summary */
6831 -#define BABL 0x4000 /* Babble transmitter timeout error */
6832 -#define CERR 0x2000 /* Collision Error */
6833 -#define MISS 0x1000 /* Missed packet */
6834 -#define MERR 0x0800 /* Memory Error */
6835 -#define RINT 0x0400 /* Receiver Interrupt */
6836 -#define TINT 0x0200 /* Transmit Interrupt */
6837 -#define IDON 0x0100 /* Initialization Done */
6838 -#define INTR 0x0080 /* Interrupt Flag */
6839 -#define INEA 0x0040 /* Interrupt Enable */
6840 -#define RXON 0x0020 /* Receiver on */
6841 -#define TXON 0x0010 /* Transmitter on */
6842 -#define TDMD 0x0008 /* Transmit Demand */
6843 -#define STOP 0x0004 /* Stop */
6844 -#define STRT 0x0002 /* Start */
6845 -#define INIT 0x0001 /* Initialize */
6846 -#define INTM 0xff00 /* Interrupt Mask */
6847 -#define INTE 0xfff0 /* Interrupt Enable */
6850 -** CONTROL AND STATUS REGISTER 3 (CSR3)
6853 -#define BSWP 0x0004 /* Byte SWaP */
6854 -#define ACON 0x0002 /* ALE control */
6855 -#define BCON 0x0001 /* Byte CONtrol */
6858 -** Initialization Block Mode Register
6861 -#define PROM 0x8000 /* Promiscuous Mode */
6862 -#define EMBA 0x0080 /* Enable Modified Back-off Algorithm */
6863 -#define INTL 0x0040 /* Internal Loopback */
6864 -#define DRTY 0x0020 /* Disable Retry */
6865 -#define COLL 0x0010 /* Force Collision */
6866 -#define DTCR 0x0008 /* Disable Transmit CRC */
6867 -#define LOOP 0x0004 /* Loopback */
6868 -#define DTX 0x0002 /* Disable the Transmitter */
6869 -#define DRX 0x0001 /* Disable the Receiver */
6872 -** Receive Message Descriptor 1 (RMD1) bit definitions.
6875 -#define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
6876 -#define R_ERR 0x4000 /* Error Summary */
6877 -#define R_FRAM 0x2000 /* Framing Error */
6878 -#define R_OFLO 0x1000 /* Overflow Error */
6879 -#define R_CRC 0x0800 /* CRC Error */
6880 -#define R_BUFF 0x0400 /* Buffer Error */
6881 -#define R_STP 0x0200 /* Start of Packet */
6882 -#define R_ENP 0x0100 /* End of Packet */
6885 -** Transmit Message Descriptor 1 (TMD1) bit definitions.
6888 -#define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
6889 -#define T_ERR 0x4000 /* Error Summary */
6890 -#define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */
6891 -#define T_MORE 0x1000 /* >1 retry to transmit packet */
6892 -#define T_ONE 0x0800 /* 1 try needed to transmit the packet */
6893 -#define T_DEF 0x0400 /* Deferred */
6894 -#define T_STP 0x02000000 /* Start of Packet */
6895 -#define T_ENP 0x01000000 /* End of Packet */
6896 -#define T_FLAGS 0xff000000 /* TX Flags Field */
6899 -** Transmit Message Descriptor 3 (TMD3) bit definitions.
6902 -#define TMD3_BUFF 0x8000 /* BUFFer error */
6903 -#define TMD3_UFLO 0x4000 /* UnderFLOw error */
6904 -#define TMD3_RES 0x2000 /* REServed */
6905 -#define TMD3_LCOL 0x1000 /* Late COLlision */
6906 -#define TMD3_LCAR 0x0800 /* Loss of CARrier */
6907 -#define TMD3_RTRY 0x0400 /* ReTRY error */
6910 -** Ethernet PROM defines
6912 -#define PROBE_LENGTH 32
6915 -** Set the number of Tx and Rx buffers. Ensure that the memory requested
6916 -** here is <= to the amount of shared memory set up by the board switches.
6917 -** The number of descriptors MUST BE A POWER OF 2.
6919 -** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
6921 -#define NUM_RX_DESC 2 /* Number of RX descriptors */
6922 -#define NUM_TX_DESC 2 /* Number of TX descriptors */
6923 -#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
6924 -#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
6927 -** ISA Bus defines
6929 -#define DEPCA_IO_PORTS {0x300, 0x200, 0}
6931 -#ifndef DEPCA_MODEL
6932 -#define DEPCA_MODEL DEPCA
6933 -#endif
6935 -static enum {
6936 - DEPCA, DE100, DE101, DE200, DE201, DE202, DE210, DE212, DE422, unknown
6937 -} adapter = DEPCA_MODEL;
6940 -** Name <-> Adapter mapping
6943 -static char *adapter_name[] = {
6944 - "DEPCA",
6945 - "DE100","DE101",
6946 - "DE200","DE201","DE202",
6947 - "DE210","DE212",
6948 - "DE422",
6949 - ""
6952 -#ifndef DEPCA_RAM_BASE
6953 -#define DEPCA_RAM_BASE 0xd0000
6954 -#endif
6957 -** Memory Alignment. Each descriptor is 4 longwords long. To force a
6958 -** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
6959 -** DESC_ALIGN. ALIGN aligns the start address of the private memory area
6960 -** and hence the RX descriptor ring's first entry.
6962 -#define ALIGN4 ((u32)4 - 1) /* 1 longword align */
6963 -#define ALIGN8 ((u32)8 - 1) /* 2 longword (quadword) align */
6964 -#define ALIGN ALIGN8 /* Keep the LANCE happy... */
6966 -typedef long s32;
6967 -typedef unsigned long u32;
6968 -typedef short s16;
6969 -typedef unsigned short u16;
6970 -typedef char s8;
6971 -typedef unsigned char u8;
6974 -** The DEPCA Rx and Tx ring descriptors.
6976 -struct depca_rx_desc {
6977 - volatile s32 base;
6978 - s16 buf_length; /* This length is negative 2's complement! */
6979 - s16 msg_length; /* This length is "normal". */
6982 -struct depca_tx_desc {
6983 - volatile s32 base;
6984 - s16 length; /* This length is negative 2's complement! */
6985 - s16 misc; /* Errors and TDR info */
6988 -#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
6989 - to LANCE memory address space */
6992 -** The Lance initialization block, described in databook, in common memory.
6994 -struct depca_init {
6995 - u16 mode; /* Mode register */
6996 - u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
6997 - u8 mcast_table[8]; /* Multicast Hash Table. */
6998 - u32 rx_ring; /* Rx ring base pointer & ring length */
6999 - u32 tx_ring; /* Tx ring base pointer & ring length */
7002 -struct depca_private {
7003 - struct depca_rx_desc *rx_ring;
7004 - struct depca_tx_desc *tx_ring;
7005 - struct depca_init init_block; /* Shadow init block */
7006 - char *rx_memcpy[NUM_RX_DESC];
7007 - char *tx_memcpy[NUM_TX_DESC];
7008 - u32 bus_offset; /* ISA bus address offset */
7009 - u32 sh_mem; /* address of shared mem */
7010 - u32 dma_buffs; /* Rx & Tx buffer start */
7011 - int rx_cur, tx_cur; /* Next free ring entry */
7012 - int txRingMask, rxRingMask;
7013 - s32 rx_rlen, tx_rlen;
7014 - /* log2([rt]xRingMask+1) for the descriptors */
7017 -static Address mem_start = DEPCA_RAM_BASE;
7018 -static Address mem_len, offset;
7019 -static unsigned short ioaddr = 0;
7020 -static struct depca_private lp;
7023 -** Miscellaneous defines...
7025 -#define STOP_DEPCA \
7026 - outw(CSR0, DEPCA_ADDR);\
7027 - outw(STOP, DEPCA_DATA)
7029 -/* Initialize the lance Rx and Tx descriptor rings. */
7030 -static void depca_init_ring(struct nic *nic)
7032 - int i;
7033 - u32 p;
7035 - lp.rx_cur = lp.tx_cur = 0;
7036 - /* Initialize the base addresses and length of each buffer in the ring */
7037 - for (i = 0; i <= lp.rxRingMask; i++) {
7038 - writel((p = lp.dma_buffs + i * RX_BUFF_SZ) | R_OWN, &lp.rx_ring[i].base);
7039 - writew(-RX_BUFF_SZ, &lp.rx_ring[i].buf_length);
7040 - lp.rx_memcpy[i] = (char *) (p + lp.bus_offset);
7042 - for (i = 0; i <= lp.txRingMask; i++) {
7043 - writel((p = lp.dma_buffs + (i + lp.txRingMask + 1) * TX_BUFF_SZ) & 0x00ffffff, &lp.tx_ring[i].base);
7044 - lp.tx_memcpy[i] = (char *) (p + lp.bus_offset);
7047 - /* Set up the initialization block */
7048 - lp.init_block.rx_ring = ((u32) ((u32) lp.rx_ring) & LA_MASK) | lp.rx_rlen;
7049 - lp.init_block.tx_ring = ((u32) ((u32) lp.tx_ring) & LA_MASK) | lp.tx_rlen;
7050 - for (i = 0; i < ETH_ALEN; i++)
7051 - lp.init_block.phys_addr[i] = nic->node_addr[i];
7052 - lp.init_block.mode = 0x0000; /* Enable the Tx and Rx */
7053 - memset(lp.init_block.mcast_table, 0, sizeof(lp.init_block.mcast_table));
7056 -static void LoadCSRs(void)
7058 - outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
7059 - outw((u16) (lp.sh_mem & LA_MASK), DEPCA_DATA);
7060 - outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
7061 - outw((u16) ((lp.sh_mem & LA_MASK) >> 16), DEPCA_DATA);
7062 - outw(CSR3, DEPCA_ADDR); /* ALE control */
7063 - outw(ACON, DEPCA_DATA);
7064 - outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
7067 -static int InitRestartDepca(void)
7069 - int i;
7071 - /* Copy the shadow init_block to shared memory */
7072 - memcpy_toio((char *)lp.sh_mem, &lp.init_block, sizeof(struct depca_init));
7073 - outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
7074 - outw(INIT, DEPCA_DATA); /* initialise DEPCA */
7076 - for (i = 0; i < 100 && !(inw(DEPCA_DATA) & IDON); i++)
7078 - if (i < 100) {
7079 - /* clear IDON by writing a 1, and start LANCE */
7080 - outw(IDON | STRT, DEPCA_DATA);
7081 - } else {
7082 - printf("DEPCA not initialised\n");
7083 - return (1);
7085 - return (0);
7088 -/**************************************************************************
7089 -RESET - Reset adapter
7090 -***************************************************************************/
7091 -static void depca_reset(struct nic *nic)
7093 - s16 nicsr;
7094 - int i, j;
7096 - STOP_DEPCA;
7097 - nicsr = inb(DEPCA_NICSR);
7098 - nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
7099 - outb(nicsr, DEPCA_NICSR);
7100 - if (inw(DEPCA_DATA) != STOP)
7102 - printf("depca: Cannot stop NIC\n");
7103 - return;
7106 - /* Initialisation block */
7107 - lp.sh_mem = mem_start;
7108 - mem_start += sizeof(struct depca_init);
7109 - /* Tx & Rx descriptors (aligned to a quadword boundary) */
7110 - mem_start = (mem_start + ALIGN) & ~ALIGN;
7111 - lp.rx_ring = (struct depca_rx_desc *) mem_start;
7112 - mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
7113 - lp.tx_ring = (struct depca_tx_desc *) mem_start;
7114 - mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
7116 - lp.bus_offset = mem_start & 0x00ff0000;
7117 - /* LANCE re-mapped start address */
7118 - lp.dma_buffs = mem_start & LA_MASK;
7120 - /* Finish initialising the ring information. */
7121 - lp.rxRingMask = NUM_RX_DESC - 1;
7122 - lp.txRingMask = NUM_TX_DESC - 1;
7124 - /* Calculate Tx/Rx RLEN size for the descriptors. */
7125 - for (i = 0, j = lp.rxRingMask; j > 0; i++) {
7126 - j >>= 1;
7128 - lp.rx_rlen = (s32) (i << 29);
7129 - for (i = 0, j = lp.txRingMask; j > 0; i++) {
7130 - j >>= 1;
7132 - lp.tx_rlen = (s32) (i << 29);
7134 - /* Load the initialisation block */
7135 - depca_init_ring(nic);
7136 - LoadCSRs();
7137 - InitRestartDepca();
7140 -/**************************************************************************
7141 -POLL - Wait for a frame
7142 -***************************************************************************/
7143 -static int depca_poll(struct nic *nic)
7145 - int entry;
7146 - u32 status;
7148 - entry = lp.rx_cur;
7149 - if ((status = readl(&lp.rx_ring[entry].base) & R_OWN))
7150 - return (0);
7151 - memcpy(nic->packet, lp.rx_memcpy[entry], nic->packetlen = lp.rx_ring[entry].msg_length);
7152 - lp.rx_ring[entry].base |= R_OWN;
7153 - lp.rx_cur = (++lp.rx_cur) & lp.rxRingMask;
7154 - return (1);
7157 -/**************************************************************************
7158 -TRANSMIT - Transmit a frame
7159 -***************************************************************************/
7160 -static void depca_transmit(
7161 - struct nic *nic,
7162 - const char *d, /* Destination */
7163 - unsigned int t, /* Type */
7164 - unsigned int s, /* size */
7165 - const char *p) /* Packet */
7167 - int entry, len;
7168 - char *mem;
7170 - /* send the packet to destination */
7171 - /*
7172 - ** Caution: the right order is important here... dont
7173 - ** setup the ownership rights until all the other
7174 - ** information is in place
7175 - */
7176 - mem = lp.tx_memcpy[entry = lp.tx_cur];
7177 - memcpy_toio(mem, d, ETH_ALEN);
7178 - memcpy_toio(mem + ETH_ALEN, nic->node_addr, ETH_ALEN);
7179 - mem[ETH_ALEN * 2] = t >> 8;
7180 - mem[ETH_ALEN * 2 + 1] = t;
7181 - memcpy_toio(mem + ETH_HLEN, p, s);
7182 - s += ETH_HLEN;
7183 - len = (s < ETH_ZLEN ? ETH_ZLEN : s);
7184 - /* clean out flags */
7185 - writel(readl(&lp.tx_ring[entry].base) & ~T_FLAGS, &lp.tx_ring[entry].base);
7186 - /* clears other error flags */
7187 - writew(0x0000, &lp.tx_ring[entry].misc);
7188 - /* packet length in buffer */
7189 - writew(-len, &lp.tx_ring[entry].length);
7190 - /* start and end of packet, ownership */
7191 - writel(readl(&lp.tx_ring[entry].base) | (T_STP|T_ENP|T_OWN), &lp.tx_ring[entry].base);
7192 - /* update current pointers */
7193 - lp.tx_cur = (++lp.tx_cur) & lp.txRingMask;
7196 -/**************************************************************************
7197 -DISABLE - Turn off ethernet interface
7198 -***************************************************************************/
7199 -static void depca_disable(struct nic *nic)
7201 - STOP_DEPCA;
7205 -** Look for a special sequence in the Ethernet station address PROM that
7206 -** is common across all DEPCA products. Note that the original DEPCA needs
7207 -** its ROM address counter to be initialized and enabled. Only enable
7208 -** if the first address octet is a 0x08 - this minimises the chances of
7209 -** messing around with some other hardware, but it assumes that this DEPCA
7210 -** card initialized itself correctly.
7212 -** Search the Ethernet address ROM for the signature. Since the ROM address
7213 -** counter can start at an arbitrary point, the search must include the entire
7214 -** probe sequence length plus the (length_of_the_signature - 1).
7215 -** Stop the search IMMEDIATELY after the signature is found so that the
7216 -** PROM address counter is correctly positioned at the start of the
7217 -** ethernet address for later read out.
7219 -static int depca_probe1(struct nic *nic)
7221 - u8 data, nicsr;
7222 - /* This is only correct for little endian machines, but then
7223 - Etherboot doesn't work on anything but a PC */
7224 - u8 sig[] = { 0xFF, 0x00, 0x55, 0xAA, 0xFF, 0x00, 0x55, 0xAA };
7225 - int i, j;
7226 - long sum, chksum;
7228 - data = inb(DEPCA_PROM); /* clear counter on DEPCA */
7229 - data = inb(DEPCA_PROM); /* read data */
7230 - if (data == 0x8) {
7231 - nicsr = inb(DEPCA_NICSR);
7232 - nicsr |= AAC;
7233 - outb(nicsr, DEPCA_NICSR);
7235 - for (i = 0, j = 0; j < (int)sizeof(sig) && i < PROBE_LENGTH+((int)sizeof(sig))-1; ++i) {
7236 - data = inb(DEPCA_PROM);
7237 - if (data == sig[j]) /* track signature */
7238 - ++j;
7239 - else
7240 - j = (data == sig[0]) ? 1 : 0;
7242 - if (j != sizeof(sig))
7243 - return (0);
7244 - /* put the card in its initial state */
7245 - STOP_DEPCA;
7246 - nicsr = ((inb(DEPCA_NICSR) & ~SHE & ~RBE & ~IEN) | IM);
7247 - outb(nicsr, DEPCA_NICSR);
7248 - if (inw(DEPCA_DATA) != STOP)
7249 - return (0);
7250 - memcpy((char *)mem_start, sig, sizeof(sig));
7251 - if (memcmp((char *)mem_start, sig, sizeof(sig)) != 0)
7252 - return (0);
7253 - for (i = 0, j = 0, sum = 0; j < 3; j++) {
7254 - sum <<= 1;
7255 - if (sum > 0xFFFF)
7256 - sum -= 0xFFFF;
7257 - sum += (u8)(nic->node_addr[i++] = inb(DEPCA_PROM));
7258 - sum += (u16)((nic->node_addr[i++] = inb(DEPCA_PROM)) << 8);
7259 - if (sum > 0xFFFF)
7260 - sum -= 0xFFFF;
7262 - if (sum == 0xFFFF)
7263 - sum = 0;
7264 - chksum = (u8)inb(DEPCA_PROM);
7265 - chksum |= (u16)(inb(DEPCA_PROM) << 8);
7266 - mem_len = (adapter == DEPCA) ? (48 << 10) : (64 << 10);
7267 - offset = 0;
7268 - if (nicsr & BUF) {
7269 - offset = 0x8000;
7270 - nicsr &= ~BS;
7271 - mem_len -= (32 << 10);
7273 - if (adapter != DEPCA) /* enable shadow RAM */
7274 - outb(nicsr |= SHE, DEPCA_NICSR);
7275 - printf("%s base %#hX, memory [%#hX-%#hX], addr %!",
7276 - adapter_name[adapter], ioaddr, mem_start, mem_start + mem_len,
7277 - nic->node_addr);
7278 - if (sum != chksum)
7279 - printf(" (bad checksum)");
7280 - putchar('\n');
7281 - return (1);
7284 -/**************************************************************************
7285 -PROBE - Look for an adapter, this routine's visible to the outside
7286 -***************************************************************************/
7287 -struct nic *depca_probe(struct nic *nic, unsigned short *probe_addrs)
7289 - static unsigned short base[] = DEPCA_IO_PORTS;
7290 - int i;
7292 - if (probe_addrs == 0 || probe_addrs[0] == 0)
7293 - probe_addrs = base; /* Use defaults */
7294 - for (i = 0; (ioaddr = base[i]) != 0; ++i) {
7295 - if (depca_probe1(nic))
7296 - break;
7298 - if (ioaddr == 0)
7299 - return (0);
7300 - depca_reset(nic);
7301 - /* point to NIC specific routines */
7302 - nic->reset = depca_reset;
7303 - nic->poll = depca_poll;
7304 - nic->transmit = depca_transmit;
7305 - nic->disable = depca_disable;
7306 - return (nic);
7308 Index: b/netboot/dev.h
7309 ===================================================================
7310 --- /dev/null
7311 +++ b/netboot/dev.h
7312 @@ -0,0 +1,83 @@
7313 +#ifndef _DEV_H
7314 +#define _DEV_H
7316 +#include "isa.h"
7317 +#include "pci.h"
7319 +/* Need to check the packing of this struct if Etherboot is ported */
7320 +struct dev_id
7322 + unsigned short vendor_id;
7323 + unsigned short device_id;
7324 + unsigned char bus_type;
7325 +#define PCI_BUS_TYPE 1
7326 +#define ISA_BUS_TYPE 2
7329 +/* Dont use sizeof, that will include the padding */
7330 +#define DEV_ID_SIZE 8
7333 +struct pci_probe_state
7335 +#ifdef CONFIG_PCI
7336 + struct pci_device dev;
7337 + int advance;
7338 +#else
7339 + int dummy;
7340 +#endif
7342 +struct isa_probe_state
7344 +#ifdef CONFIG_ISA
7345 + const struct isa_driver *driver;
7346 + int advance;
7347 +#else
7348 + int dummy;
7349 +#endif
7352 +union probe_state
7354 + struct pci_probe_state pci;
7355 + struct isa_probe_state isa;
7358 +struct dev
7360 + void (*disable)P((struct dev *));
7361 + struct dev_id devid; /* device ID string (sent to DHCP server) */
7362 + int index; /* Index of next device on this controller to probe */
7363 + int type; /* Type of device I am probing for */
7364 + int how_probe; /* First, next or awake */
7365 + int to_probe; /* Flavor of device I am probing */
7366 + int failsafe; /* Failsafe probe requested */
7367 + int type_index; /* Index of this device (within type) */
7368 +#define PROBE_NONE 0
7369 +#define PROBE_PCI 1
7370 +#define PROBE_ISA 2
7371 + union probe_state state;
7375 +#define NIC_DRIVER 0
7376 +#define DISK_DRIVER 1
7377 +#define FLOPPY_DRIVER 2
7379 +#define BRIDGE_DRIVER 1000
7381 +#define PROBE_FIRST (-1)
7382 +#define PROBE_NEXT 0
7383 +#define PROBE_AWAKE 1 /* After calling disable bring up the same device */
7385 +/* The probe result codes are selected
7386 + * to allow them to be fed back into the probe
7387 + * routine and get a successful probe.
7388 + */
7389 +#define PROBE_FAILED PROBE_FIRST
7390 +#define PROBE_WORKED PROBE_NEXT
7392 +extern int probe(struct dev *dev);
7393 +extern void disable(struct dev *dev);
7395 +#endif /* _DEV_H */
7396 Index: b/netboot/e1000.c
7397 ===================================================================
7398 --- /dev/null
7399 +++ b/netboot/e1000.c
7400 @@ -0,0 +1,3682 @@
7401 +/**************************************************************************
7402 +Etherboot - BOOTP/TFTP Bootstrap Program
7403 +Inter Pro 1000 for Etherboot
7404 +Drivers are port from Intel's Linux driver e1000-4.3.15
7406 +***************************************************************************/
7407 +/*******************************************************************************
7410 + Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
7412 + This program is free software; you can redistribute it and/or modify it
7413 + under the terms of the GNU General Public License as published by the Free
7414 + Software Foundation; either version 2 of the License, or (at your option)
7415 + any later version.
7417 + This program is distributed in the hope that it will be useful, but WITHOUT
7418 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7419 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7420 + more details.
7422 + You should have received a copy of the GNU General Public License along with
7423 + this program; if not, write to the Free Software Foundation, Inc., 59
7424 + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
7426 + The full GNU General Public License is included in this distribution in the
7427 + file called LICENSE.
7429 + Contact Information:
7430 + Linux NICS <linux.nics@intel.com>
7431 + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
7433 +*******************************************************************************/
7435 + * Copyright (C) Archway Digital Solutions.
7437 + * written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina dot org>
7438 + * 2/9/2002
7440 + * Copyright (C) Linux Networx.
7441 + * Massive upgrade to work with the new intel gigabit NICs.
7442 + * <ebiederman at lnxi dot com>
7444 + * Support for 82541ei & 82547ei chips from Intel's Linux driver 5.1.13 added by
7445 + * Georg Baum <gbaum@users.sf.net>, sponsored by PetaMem GmbH and linkLINE Communications, Inc.
7447 + * 01/2004: Updated to Linux driver 5.2.22 by Georg Baum <gbaum@users.sf.net>
7448 + */
7450 +/* to get some global routines like printf */
7451 +#include "etherboot.h"
7452 +/* to get the interface to the body of the program */
7453 +#include "nic.h"
7454 +/* to get the PCI support functions, if this is a PCI NIC */
7455 +#include "pci.h"
7456 +#include "timer.h"
7458 +typedef unsigned char *dma_addr_t;
7460 +typedef enum {
7461 + FALSE = 0,
7462 + TRUE = 1
7463 +} boolean_t;
7465 +#define DEBUG 0
7468 +/* Some pieces of code are disabled with #if 0 ... #endif.
7469 + * They are not deleted to show where the etherboot driver differs
7470 + * from the linux driver below the function level.
7471 + * Some member variables of the hw struct have been eliminated
7472 + * and the corresponding inplace checks inserted instead.
7473 + * Pieces such as LED handling that we definitely don't need are deleted.
7475 + * The following defines should not be needed normally,
7476 + * but may be helpful for debugging purposes. */
7478 +/* Define this if you want to program the transmission control register
7479 + * the way the Linux driver does it. */
7480 +#undef LINUX_DRIVER_TCTL
7482 +/* Define this to behave more like the Linux driver. */
7483 +#undef LINUX_DRIVER
7485 +#include "e1000_hw.h"
7487 +/* NIC specific static variables go here */
7488 +static struct e1000_hw hw;
7489 +static char tx_pool[128 + 16];
7490 +static char rx_pool[128 + 16];
7491 +static char packet[2096];
7493 +static struct e1000_tx_desc *tx_base;
7494 +static struct e1000_rx_desc *rx_base;
7496 +static int tx_tail;
7497 +static int rx_tail, rx_last;
7499 +/* Function forward declarations */
7500 +static int e1000_setup_link(struct e1000_hw *hw);
7501 +static int e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
7502 +static int e1000_setup_copper_link(struct e1000_hw *hw);
7503 +static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
7504 +static void e1000_config_collision_dist(struct e1000_hw *hw);
7505 +static int e1000_config_mac_to_phy(struct e1000_hw *hw);
7506 +static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
7507 +static int e1000_check_for_link(struct e1000_hw *hw);
7508 +static int e1000_wait_autoneg(struct e1000_hw *hw);
7509 +static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, uint16_t *duplex);
7510 +static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
7511 +static int e1000_read_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
7512 +static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data);
7513 +static int e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr, uint16_t phy_data);
7514 +static void e1000_phy_hw_reset(struct e1000_hw *hw);
7515 +static int e1000_phy_reset(struct e1000_hw *hw);
7516 +static int e1000_detect_gig_phy(struct e1000_hw *hw);
7518 +/* Printing macros... */
7520 +#define E1000_ERR(args...) printf("e1000: " args)
7522 +#if DEBUG >= 3
7523 +#define E1000_DBG(args...) printf("e1000: " args)
7524 +#else
7525 +#define E1000_DBG(args...)
7526 +#endif
7528 +#define MSGOUT(S, A, B) printk(S "\n", A, B)
7529 +#if DEBUG >= 2
7530 +#define DEBUGFUNC(F) DEBUGOUT(F "\n");
7531 +#else
7532 +#define DEBUGFUNC(F)
7533 +#endif
7534 +#if DEBUG >= 1
7535 +#define DEBUGOUT(S) printf(S)
7536 +#define DEBUGOUT1(S,A) printf(S,A)
7537 +#define DEBUGOUT2(S,A,B) printf(S,A,B)
7538 +#define DEBUGOUT3(S,A,B,C) printf(S,A,B,C)
7539 +#define DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S,A,B,C,D,E,F,G)
7540 +#else
7541 +#define DEBUGOUT(S)
7542 +#define DEBUGOUT1(S,A)
7543 +#define DEBUGOUT2(S,A,B)
7544 +#define DEBUGOUT3(S,A,B,C)
7545 +#define DEBUGOUT7(S,A,B,C,D,E,F,G)
7546 +#endif
7548 +#define E1000_WRITE_REG(a, reg, value) ( \
7549 + ((a)->mac_type >= e1000_82543) ? \
7550 + (writel((value), ((a)->hw_addr + E1000_##reg))) : \
7551 + (writel((value), ((a)->hw_addr + E1000_82542_##reg))))
7553 +#define E1000_READ_REG(a, reg) ( \
7554 + ((a)->mac_type >= e1000_82543) ? \
7555 + readl((a)->hw_addr + E1000_##reg) : \
7556 + readl((a)->hw_addr + E1000_82542_##reg))
7558 +#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
7559 + ((a)->mac_type >= e1000_82543) ? \
7560 + writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) : \
7561 + writel((value), ((a)->hw_addr + E1000_82542_##reg + ((offset) << 2))))
7563 +#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
7564 + ((a)->mac_type >= e1000_82543) ? \
7565 + readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \
7566 + readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))
7568 +#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
7570 +uint32_t
7571 +e1000_io_read(struct e1000_hw *hw __unused, uint32_t port)
7573 + return inl(port);
7576 +void
7577 +e1000_io_write(struct e1000_hw *hw __unused, uint32_t port, uint32_t value)
7579 + outl(value, port);
7582 +static inline void e1000_pci_set_mwi(struct e1000_hw *hw)
7584 + pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
7587 +static inline void e1000_pci_clear_mwi(struct e1000_hw *hw)
7589 + pci_write_config_word(hw->pdev, PCI_COMMAND,
7590 + hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
7593 +/******************************************************************************
7594 + * Raises the EEPROM's clock input.
7596 + * hw - Struct containing variables accessed by shared code
7597 + * eecd - EECD's current value
7598 + *****************************************************************************/
7599 +static void
7600 +e1000_raise_ee_clk(struct e1000_hw *hw,
7601 + uint32_t *eecd)
7603 + /* Raise the clock input to the EEPROM (by setting the SK bit), and then
7604 + * wait <delay> microseconds.
7605 + */
7606 + *eecd = *eecd | E1000_EECD_SK;
7607 + E1000_WRITE_REG(hw, EECD, *eecd);
7608 + E1000_WRITE_FLUSH(hw);
7609 + udelay(hw->eeprom.delay_usec);
7612 +/******************************************************************************
7613 + * Lowers the EEPROM's clock input.
7615 + * hw - Struct containing variables accessed by shared code
7616 + * eecd - EECD's current value
7617 + *****************************************************************************/
7618 +static void
7619 +e1000_lower_ee_clk(struct e1000_hw *hw,
7620 + uint32_t *eecd)
7622 + /* Lower the clock input to the EEPROM (by clearing the SK bit), and then
7623 + * wait 50 microseconds.
7624 + */
7625 + *eecd = *eecd & ~E1000_EECD_SK;
7626 + E1000_WRITE_REG(hw, EECD, *eecd);
7627 + E1000_WRITE_FLUSH(hw);
7628 + udelay(hw->eeprom.delay_usec);
7631 +/******************************************************************************
7632 + * Shift data bits out to the EEPROM.
7634 + * hw - Struct containing variables accessed by shared code
7635 + * data - data to send to the EEPROM
7636 + * count - number of bits to shift out
7637 + *****************************************************************************/
7638 +static void
7639 +e1000_shift_out_ee_bits(struct e1000_hw *hw,
7640 + uint16_t data,
7641 + uint16_t count)
7643 + struct e1000_eeprom_info *eeprom = &hw->eeprom;
7644 + uint32_t eecd;
7645 + uint32_t mask;
7647 + /* We need to shift "count" bits out to the EEPROM. So, value in the
7648 + * "data" parameter will be shifted out to the EEPROM one bit at a time.
7649 + * In order to do this, "data" must be broken down into bits.
7650 + */
7651 + mask = 0x01 << (count - 1);
7652 + eecd = E1000_READ_REG(hw, EECD);
7653 + if (eeprom->type == e1000_eeprom_microwire) {
7654 + eecd &= ~E1000_EECD_DO;
7655 + } else if (eeprom->type == e1000_eeprom_spi) {
7656 + eecd |= E1000_EECD_DO;
7658 + do {
7659 + /* A "1" is shifted out to the EEPROM by setting bit "DI" to a "1",
7660 + * and then raising and then lowering the clock (the SK bit controls
7661 + * the clock input to the EEPROM). A "0" is shifted out to the EEPROM
7662 + * by setting "DI" to "0" and then raising and then lowering the clock.
7663 + */
7664 + eecd &= ~E1000_EECD_DI;
7666 + if(data & mask)
7667 + eecd |= E1000_EECD_DI;
7669 + E1000_WRITE_REG(hw, EECD, eecd);
7670 + E1000_WRITE_FLUSH(hw);
7672 + udelay(eeprom->delay_usec);
7674 + e1000_raise_ee_clk(hw, &eecd);
7675 + e1000_lower_ee_clk(hw, &eecd);
7677 + mask = mask >> 1;
7679 + } while(mask);
7681 + /* We leave the "DI" bit set to "0" when we leave this routine. */
7682 + eecd &= ~E1000_EECD_DI;
7683 + E1000_WRITE_REG(hw, EECD, eecd);
7686 +/******************************************************************************
7687 + * Shift data bits in from the EEPROM
7689 + * hw - Struct containing variables accessed by shared code
7690 + *****************************************************************************/
7691 +static uint16_t
7692 +e1000_shift_in_ee_bits(struct e1000_hw *hw,
7693 + uint16_t count)
7695 + uint32_t eecd;
7696 + uint32_t i;
7697 + uint16_t data;
7699 + /* In order to read a register from the EEPROM, we need to shift 'count'
7700 + * bits in from the EEPROM. Bits are "shifted in" by raising the clock
7701 + * input to the EEPROM (setting the SK bit), and then reading the value of
7702 + * the "DO" bit. During this "shifting in" process the "DI" bit should
7703 + * always be clear.
7704 + */
7706 + eecd = E1000_READ_REG(hw, EECD);
7708 + eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
7709 + data = 0;
7711 + for(i = 0; i < count; i++) {
7712 + data = data << 1;
7713 + e1000_raise_ee_clk(hw, &eecd);
7715 + eecd = E1000_READ_REG(hw, EECD);
7717 + eecd &= ~(E1000_EECD_DI);
7718 + if(eecd & E1000_EECD_DO)
7719 + data |= 1;
7721 + e1000_lower_ee_clk(hw, &eecd);
7724 + return data;
7727 +/******************************************************************************
7728 + * Prepares EEPROM for access
7730 + * hw - Struct containing variables accessed by shared code
7732 + * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
7733 + * function should be called before issuing a command to the EEPROM.
7734 + *****************************************************************************/
7735 +static int32_t
7736 +e1000_acquire_eeprom(struct e1000_hw *hw)
7738 + struct e1000_eeprom_info *eeprom = &hw->eeprom;
7739 + uint32_t eecd, i=0;
7741 + eecd = E1000_READ_REG(hw, EECD);
7743 + /* Request EEPROM Access */
7744 + if(hw->mac_type > e1000_82544) {
7745 + eecd |= E1000_EECD_REQ;
7746 + E1000_WRITE_REG(hw, EECD, eecd);
7747 + eecd = E1000_READ_REG(hw, EECD);
7748 + while((!(eecd & E1000_EECD_GNT)) &&
7749 + (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
7750 + i++;
7751 + udelay(5);
7752 + eecd = E1000_READ_REG(hw, EECD);
7754 + if(!(eecd & E1000_EECD_GNT)) {
7755 + eecd &= ~E1000_EECD_REQ;
7756 + E1000_WRITE_REG(hw, EECD, eecd);
7757 + DEBUGOUT("Could not acquire EEPROM grant\n");
7758 + return -E1000_ERR_EEPROM;
7762 + /* Setup EEPROM for Read/Write */
7764 + if (eeprom->type == e1000_eeprom_microwire) {
7765 + /* Clear SK and DI */
7766 + eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
7767 + E1000_WRITE_REG(hw, EECD, eecd);
7769 + /* Set CS */
7770 + eecd |= E1000_EECD_CS;
7771 + E1000_WRITE_REG(hw, EECD, eecd);
7772 + } else if (eeprom->type == e1000_eeprom_spi) {
7773 + /* Clear SK and CS */
7774 + eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
7775 + E1000_WRITE_REG(hw, EECD, eecd);
7776 + udelay(1);
7779 + return E1000_SUCCESS;
7782 +/******************************************************************************
7783 + * Returns EEPROM to a "standby" state
7784 + *
7785 + * hw - Struct containing variables accessed by shared code
7786 + *****************************************************************************/
7787 +static void
7788 +e1000_standby_eeprom(struct e1000_hw *hw)
7790 + struct e1000_eeprom_info *eeprom = &hw->eeprom;
7791 + uint32_t eecd;
7793 + eecd = E1000_READ_REG(hw, EECD);
7795 + if(eeprom->type == e1000_eeprom_microwire) {
7797 + /* Deselect EEPROM */
7798 + eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
7799 + E1000_WRITE_REG(hw, EECD, eecd);
7800 + E1000_WRITE_FLUSH(hw);
7801 + udelay(eeprom->delay_usec);
7803 + /* Clock high */
7804 + eecd |= E1000_EECD_SK;
7805 + E1000_WRITE_REG(hw, EECD, eecd);
7806 + E1000_WRITE_FLUSH(hw);
7807 + udelay(eeprom->delay_usec);
7809 + /* Select EEPROM */
7810 + eecd |= E1000_EECD_CS;
7811 + E1000_WRITE_REG(hw, EECD, eecd);
7812 + E1000_WRITE_FLUSH(hw);
7813 + udelay(eeprom->delay_usec);
7815 + /* Clock low */
7816 + eecd &= ~E1000_EECD_SK;
7817 + E1000_WRITE_REG(hw, EECD, eecd);
7818 + E1000_WRITE_FLUSH(hw);
7819 + udelay(eeprom->delay_usec);
7820 + } else if(eeprom->type == e1000_eeprom_spi) {
7821 + /* Toggle CS to flush commands */
7822 + eecd |= E1000_EECD_CS;
7823 + E1000_WRITE_REG(hw, EECD, eecd);
7824 + E1000_WRITE_FLUSH(hw);
7825 + udelay(eeprom->delay_usec);
7826 + eecd &= ~E1000_EECD_CS;
7827 + E1000_WRITE_REG(hw, EECD, eecd);
7828 + E1000_WRITE_FLUSH(hw);
7829 + udelay(eeprom->delay_usec);
7833 +/******************************************************************************
7834 + * Terminates a command by inverting the EEPROM's chip select pin
7836 + * hw - Struct containing variables accessed by shared code
7837 + *****************************************************************************/
7838 +static void
7839 +e1000_release_eeprom(struct e1000_hw *hw)
7841 + uint32_t eecd;
7843 + eecd = E1000_READ_REG(hw, EECD);
7845 + if (hw->eeprom.type == e1000_eeprom_spi) {
7846 + eecd |= E1000_EECD_CS; /* Pull CS high */
7847 + eecd &= ~E1000_EECD_SK; /* Lower SCK */
7849 + E1000_WRITE_REG(hw, EECD, eecd);
7851 + udelay(hw->eeprom.delay_usec);
7852 + } else if(hw->eeprom.type == e1000_eeprom_microwire) {
7853 + /* cleanup eeprom */
7855 + /* CS on Microwire is active-high */
7856 + eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
7858 + E1000_WRITE_REG(hw, EECD, eecd);
7860 + /* Rising edge of clock */
7861 + eecd |= E1000_EECD_SK;
7862 + E1000_WRITE_REG(hw, EECD, eecd);
7863 + E1000_WRITE_FLUSH(hw);
7864 + udelay(hw->eeprom.delay_usec);
7866 + /* Falling edge of clock */
7867 + eecd &= ~E1000_EECD_SK;
7868 + E1000_WRITE_REG(hw, EECD, eecd);
7869 + E1000_WRITE_FLUSH(hw);
7870 + udelay(hw->eeprom.delay_usec);
7873 + /* Stop requesting EEPROM access */
7874 + if(hw->mac_type > e1000_82544) {
7875 + eecd &= ~E1000_EECD_REQ;
7876 + E1000_WRITE_REG(hw, EECD, eecd);
7880 +/******************************************************************************
7881 + * Reads a 16 bit word from the EEPROM.
7883 + * hw - Struct containing variables accessed by shared code
7884 + *****************************************************************************/
7885 +static int32_t
7886 +e1000_spi_eeprom_ready(struct e1000_hw *hw)
7888 + uint16_t retry_count = 0;
7889 + uint8_t spi_stat_reg;
7891 + /* Read "Status Register" repeatedly until the LSB is cleared. The
7892 + * EEPROM will signal that the command has been completed by clearing
7893 + * bit 0 of the internal status register. If it's not cleared within
7894 + * 5 milliseconds, then error out.
7895 + */
7896 + retry_count = 0;
7897 + do {
7898 + e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
7899 + hw->eeprom.opcode_bits);
7900 + spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
7901 + if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
7902 + break;
7904 + udelay(5);
7905 + retry_count += 5;
7907 + } while(retry_count < EEPROM_MAX_RETRY_SPI);
7909 + /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
7910 + * only 0-5mSec on 5V devices)
7911 + */
7912 + if(retry_count >= EEPROM_MAX_RETRY_SPI) {
7913 + DEBUGOUT("SPI EEPROM Status error\n");
7914 + return -E1000_ERR_EEPROM;
7917 + return E1000_SUCCESS;
7920 +/******************************************************************************
7921 + * Reads a 16 bit word from the EEPROM.
7923 + * hw - Struct containing variables accessed by shared code
7924 + * offset - offset of word in the EEPROM to read
7925 + * data - word read from the EEPROM
7926 + * words - number of words to read
7927 + *****************************************************************************/
7928 +static int
7929 +e1000_read_eeprom(struct e1000_hw *hw,
7930 + uint16_t offset,
7931 + uint16_t words,
7932 + uint16_t *data)
7934 + struct e1000_eeprom_info *eeprom = &hw->eeprom;
7935 + uint32_t i = 0;
7937 + DEBUGFUNC("e1000_read_eeprom");
7939 + /* A check for invalid values: offset too large, too many words, and not
7940 + * enough words.
7941 + */
7942 + if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
7943 + (words == 0)) {
7944 + DEBUGOUT("\"words\" parameter out of bounds\n");
7945 + return -E1000_ERR_EEPROM;
7948 + /* Prepare the EEPROM for reading */
7949 + if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
7950 + return -E1000_ERR_EEPROM;
7952 + if(eeprom->type == e1000_eeprom_spi) {
7953 + uint16_t word_in;
7954 + uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
7956 + if(e1000_spi_eeprom_ready(hw)) {
7957 + e1000_release_eeprom(hw);
7958 + return -E1000_ERR_EEPROM;
7961 + e1000_standby_eeprom(hw);
7963 + /* Some SPI eeproms use the 8th address bit embedded in the opcode */
7964 + if((eeprom->address_bits == 8) && (offset >= 128))
7965 + read_opcode |= EEPROM_A8_OPCODE_SPI;
7967 + /* Send the READ command (opcode + addr) */
7968 + e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
7969 + e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), eeprom->address_bits);
7971 + /* Read the data. The address of the eeprom internally increments with
7972 + * each byte (spi) being read, saving on the overhead of eeprom setup
7973 + * and tear-down. The address counter will roll over if reading beyond
7974 + * the size of the eeprom, thus allowing the entire memory to be read
7975 + * starting from any offset. */
7976 + for (i = 0; i < words; i++) {
7977 + word_in = e1000_shift_in_ee_bits(hw, 16);
7978 + data[i] = (word_in >> 8) | (word_in << 8);
7980 + } else if(eeprom->type == e1000_eeprom_microwire) {
7981 + for (i = 0; i < words; i++) {
7982 + /* Send the READ command (opcode + addr) */
7983 + e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
7984 + eeprom->opcode_bits);
7985 + e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
7986 + eeprom->address_bits);
7988 + /* Read the data. For microwire, each word requires the overhead
7989 + * of eeprom setup and tear-down. */
7990 + data[i] = e1000_shift_in_ee_bits(hw, 16);
7991 + e1000_standby_eeprom(hw);
7995 + /* End this read operation */
7996 + e1000_release_eeprom(hw);
7998 + return E1000_SUCCESS;
8001 +/******************************************************************************
8002 + * Verifies that the EEPROM has a valid checksum
8003 + *
8004 + * hw - Struct containing variables accessed by shared code
8006 + * Reads the first 64 16 bit words of the EEPROM and sums the values read.
8007 + * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
8008 + * valid.
8009 + *****************************************************************************/
8010 +static int
8011 +e1000_validate_eeprom_checksum(struct e1000_hw *hw)
8013 + uint16_t checksum = 0;
8014 + uint16_t i, eeprom_data;
8016 + DEBUGFUNC("e1000_validate_eeprom_checksum");
8018 + for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
8019 + if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
8020 + DEBUGOUT("EEPROM Read Error\n");
8021 + return -E1000_ERR_EEPROM;
8023 + checksum += eeprom_data;
8026 + if(checksum == (uint16_t) EEPROM_SUM)
8027 + return E1000_SUCCESS;
8028 + else {
8029 + DEBUGOUT("EEPROM Checksum Invalid\n");
8030 + return -E1000_ERR_EEPROM;
8034 +/******************************************************************************
8035 + * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
8036 + * second function of dual function devices
8038 + * hw - Struct containing variables accessed by shared code
8039 + *****************************************************************************/
8040 +static int
8041 +e1000_read_mac_addr(struct e1000_hw *hw)
8043 + uint16_t offset;
8044 + uint16_t eeprom_data;
8045 + int i;
8047 + DEBUGFUNC("e1000_read_mac_addr");
8049 + for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
8050 + offset = i >> 1;
8051 + if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
8052 + DEBUGOUT("EEPROM Read Error\n");
8053 + return -E1000_ERR_EEPROM;
8055 + hw->mac_addr[i] = eeprom_data & 0xff;
8056 + hw->mac_addr[i+1] = (eeprom_data >> 8) & 0xff;
8058 + if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
8059 + (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
8060 + /* Invert the last bit if this is the second device */
8061 + hw->mac_addr[5] ^= 1;
8062 + return E1000_SUCCESS;
8065 +/******************************************************************************
8066 + * Initializes receive address filters.
8068 + * hw - Struct containing variables accessed by shared code
8070 + * Places the MAC address in receive address register 0 and clears the rest
8071 + * of the receive addresss registers. Clears the multicast table. Assumes
8072 + * the receiver is in reset when the routine is called.
8073 + *****************************************************************************/
8074 +static void
8075 +e1000_init_rx_addrs(struct e1000_hw *hw)
8077 + uint32_t i;
8078 + uint32_t addr_low;
8079 + uint32_t addr_high;
8081 + DEBUGFUNC("e1000_init_rx_addrs");
8083 + /* Setup the receive address. */
8084 + DEBUGOUT("Programming MAC Address into RAR[0]\n");
8085 + addr_low = (hw->mac_addr[0] |
8086 + (hw->mac_addr[1] << 8) |
8087 + (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24));
8089 + addr_high = (hw->mac_addr[4] |
8090 + (hw->mac_addr[5] << 8) | E1000_RAH_AV);
8092 + E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
8093 + E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
8095 + /* Zero out the other 15 receive addresses. */
8096 + DEBUGOUT("Clearing RAR[1-15]\n");
8097 + for(i = 1; i < E1000_RAR_ENTRIES; i++) {
8098 + E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
8099 + E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
8103 +/******************************************************************************
8104 + * Clears the VLAN filer table
8106 + * hw - Struct containing variables accessed by shared code
8107 + *****************************************************************************/
8108 +static void
8109 +e1000_clear_vfta(struct e1000_hw *hw)
8111 + uint32_t offset;
8113 + for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
8114 + E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
8117 +/******************************************************************************
8118 +* Writes a value to one of the devices registers using port I/O (as opposed to
8119 +* memory mapped I/O). Only 82544 and newer devices support port I/O. *
8120 +* hw - Struct containing variables accessed by shared code
8121 +* offset - offset to write to * value - value to write
8122 +*****************************************************************************/
8123 +void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value){
8124 + uint32_t io_addr = hw->io_base;
8125 + uint32_t io_data = hw->io_base + 4;
8126 + e1000_io_write(hw, io_addr, offset);
8127 + e1000_io_write(hw, io_data, value);
8130 +/******************************************************************************
8131 + * Set the phy type member in the hw struct.
8133 + * hw - Struct containing variables accessed by shared code
8134 + *****************************************************************************/
8135 +static int32_t
8136 +e1000_set_phy_type(struct e1000_hw *hw)
8138 + DEBUGFUNC("e1000_set_phy_type");
8140 + switch(hw->phy_id) {
8141 + case M88E1000_E_PHY_ID:
8142 + case M88E1000_I_PHY_ID:
8143 + case M88E1011_I_PHY_ID:
8144 + hw->phy_type = e1000_phy_m88;
8145 + break;
8146 + case IGP01E1000_I_PHY_ID:
8147 + hw->phy_type = e1000_phy_igp;
8148 + break;
8149 + default:
8150 + /* Should never have loaded on this device */
8151 + hw->phy_type = e1000_phy_undefined;
8152 + return -E1000_ERR_PHY_TYPE;
8155 + return E1000_SUCCESS;
8158 +/******************************************************************************
8159 + * IGP phy init script - initializes the GbE PHY
8161 + * hw - Struct containing variables accessed by shared code
8162 + *****************************************************************************/
8163 +static void
8164 +e1000_phy_init_script(struct e1000_hw *hw)
8166 + DEBUGFUNC("e1000_phy_init_script");
8168 +#if 0
8169 + /* See e1000_sw_init() of the Linux driver */
8170 + if(hw->phy_init_script) {
8171 +#else
8172 + if((hw->mac_type == e1000_82541) ||
8173 + (hw->mac_type == e1000_82547) ||
8174 + (hw->mac_type == e1000_82541_rev_2) ||
8175 + (hw->mac_type == e1000_82547_rev_2)) {
8176 +#endif
8177 + mdelay(20);
8179 + e1000_write_phy_reg(hw,0x0000,0x0140);
8181 + mdelay(5);
8183 + if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
8184 + e1000_write_phy_reg(hw, 0x1F95, 0x0001);
8186 + e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
8188 + e1000_write_phy_reg(hw, 0x1F79, 0x0018);
8190 + e1000_write_phy_reg(hw, 0x1F30, 0x1600);
8192 + e1000_write_phy_reg(hw, 0x1F31, 0x0014);
8194 + e1000_write_phy_reg(hw, 0x1F32, 0x161C);
8196 + e1000_write_phy_reg(hw, 0x1F94, 0x0003);
8198 + e1000_write_phy_reg(hw, 0x1F96, 0x003F);
8200 + e1000_write_phy_reg(hw, 0x2010, 0x0008);
8201 + } else {
8202 + e1000_write_phy_reg(hw, 0x1F73, 0x0099);
8205 + e1000_write_phy_reg(hw, 0x0000, 0x3300);
8208 + if(hw->mac_type == e1000_82547) {
8209 + uint16_t fused, fine, coarse;
8211 + /* Move to analog registers page */
8212 + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
8214 + if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
8215 + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
8217 + fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
8218 + coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
8220 + if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
8221 + coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
8222 + fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
8223 + } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
8224 + fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
8226 + fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
8227 + (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) |
8228 + (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK);
8230 + e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused);
8231 + e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS,
8232 + IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
8238 +/******************************************************************************
8239 + * Set the mac type member in the hw struct.
8240 + *
8241 + * hw - Struct containing variables accessed by shared code
8242 + *****************************************************************************/
8243 +static int
8244 +e1000_set_mac_type(struct e1000_hw *hw)
8246 + DEBUGFUNC("e1000_set_mac_type");
8248 + switch (hw->device_id) {
8249 + case E1000_DEV_ID_82542:
8250 + switch (hw->revision_id) {
8251 + case E1000_82542_2_0_REV_ID:
8252 + hw->mac_type = e1000_82542_rev2_0;
8253 + break;
8254 + case E1000_82542_2_1_REV_ID:
8255 + hw->mac_type = e1000_82542_rev2_1;
8256 + break;
8257 + default:
8258 + /* Invalid 82542 revision ID */
8259 + return -E1000_ERR_MAC_TYPE;
8261 + break;
8262 + case E1000_DEV_ID_82543GC_FIBER:
8263 + case E1000_DEV_ID_82543GC_COPPER:
8264 + hw->mac_type = e1000_82543;
8265 + break;
8266 + case E1000_DEV_ID_82544EI_COPPER:
8267 + case E1000_DEV_ID_82544EI_FIBER:
8268 + case E1000_DEV_ID_82544GC_COPPER:
8269 + case E1000_DEV_ID_82544GC_LOM:
8270 + hw->mac_type = e1000_82544;
8271 + break;
8272 + case E1000_DEV_ID_82540EM:
8273 + case E1000_DEV_ID_82540EM_LOM:
8274 + case E1000_DEV_ID_82540EP:
8275 + case E1000_DEV_ID_82540EP_LOM:
8276 + case E1000_DEV_ID_82540EP_LP:
8277 + hw->mac_type = e1000_82540;
8278 + break;
8279 + case E1000_DEV_ID_82545EM_COPPER:
8280 + case E1000_DEV_ID_82545EM_FIBER:
8281 + hw->mac_type = e1000_82545;
8282 + break;
8283 + case E1000_DEV_ID_82545GM_COPPER:
8284 + case E1000_DEV_ID_82545GM_FIBER:
8285 + case E1000_DEV_ID_82545GM_SERDES:
8286 + hw->mac_type = e1000_82545_rev_3;
8287 + break;
8288 + case E1000_DEV_ID_82546EB_COPPER:
8289 + case E1000_DEV_ID_82546EB_FIBER:
8290 + case E1000_DEV_ID_82546EB_QUAD_COPPER:
8291 + hw->mac_type = e1000_82546;
8292 + break;
8293 + case E1000_DEV_ID_82546GB_COPPER:
8294 + case E1000_DEV_ID_82546GB_FIBER:
8295 + case E1000_DEV_ID_82546GB_SERDES:
8296 + hw->mac_type = e1000_82546_rev_3;
8297 + break;
8298 + case E1000_DEV_ID_82541EI:
8299 + case E1000_DEV_ID_82541EI_MOBILE:
8300 + hw->mac_type = e1000_82541;
8301 + break;
8302 + case E1000_DEV_ID_82541ER:
8303 + case E1000_DEV_ID_82541GI:
8304 + case E1000_DEV_ID_82541GI_MOBILE:
8305 + hw->mac_type = e1000_82541_rev_2;
8306 + break;
8307 + case E1000_DEV_ID_82547EI:
8308 + hw->mac_type = e1000_82547;
8309 + break;
8310 + case E1000_DEV_ID_82547GI:
8311 + hw->mac_type = e1000_82547_rev_2;
8312 + break;
8313 + default:
8314 + /* Should never have loaded on this device */
8315 + return -E1000_ERR_MAC_TYPE;
8318 + return E1000_SUCCESS;
8321 +/*****************************************************************************
8322 + * Set media type and TBI compatibility.
8324 + * hw - Struct containing variables accessed by shared code
8325 + * **************************************************************************/
8326 +static void
8327 +e1000_set_media_type(struct e1000_hw *hw)
8329 + uint32_t status;
8331 + DEBUGFUNC("e1000_set_media_type");
8333 + if(hw->mac_type != e1000_82543) {
8334 + /* tbi_compatibility is only valid on 82543 */
8335 + hw->tbi_compatibility_en = FALSE;
8338 + switch (hw->device_id) {
8339 + case E1000_DEV_ID_82545GM_SERDES:
8340 + case E1000_DEV_ID_82546GB_SERDES:
8341 + hw->media_type = e1000_media_type_internal_serdes;
8342 + break;
8343 + default:
8344 + if(hw->mac_type >= e1000_82543) {
8345 + status = E1000_READ_REG(hw, STATUS);
8346 + if(status & E1000_STATUS_TBIMODE) {
8347 + hw->media_type = e1000_media_type_fiber;
8348 + /* tbi_compatibility not valid on fiber */
8349 + hw->tbi_compatibility_en = FALSE;
8350 + } else {
8351 + hw->media_type = e1000_media_type_copper;
8353 + } else {
8354 + /* This is an 82542 (fiber only) */
8355 + hw->media_type = e1000_media_type_fiber;
8360 +/******************************************************************************
8361 + * Reset the transmit and receive units; mask and clear all interrupts.
8363 + * hw - Struct containing variables accessed by shared code
8364 + *****************************************************************************/
8365 +static void
8366 +e1000_reset_hw(struct e1000_hw *hw)
8368 + uint32_t ctrl;
8369 + uint32_t ctrl_ext;
8370 + uint32_t icr;
8371 + uint32_t manc;
8373 + DEBUGFUNC("e1000_reset_hw");
8375 + /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
8376 + if(hw->mac_type == e1000_82542_rev2_0) {
8377 + DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
8378 + e1000_pci_clear_mwi(hw);
8381 + /* Clear interrupt mask to stop board from generating interrupts */
8382 + DEBUGOUT("Masking off all interrupts\n");
8383 + E1000_WRITE_REG(hw, IMC, 0xffffffff);
8385 + /* Disable the Transmit and Receive units. Then delay to allow
8386 + * any pending transactions to complete before we hit the MAC with
8387 + * the global reset.
8388 + */
8389 + E1000_WRITE_REG(hw, RCTL, 0);
8390 + E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
8391 + E1000_WRITE_FLUSH(hw);
8393 + /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
8394 + hw->tbi_compatibility_on = FALSE;
8396 + /* Delay to allow any outstanding PCI transactions to complete before
8397 + * resetting the device
8398 + */
8399 + mdelay(10);
8401 + ctrl = E1000_READ_REG(hw, CTRL);
8403 + /* Must reset the PHY before resetting the MAC */
8404 + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
8405 + E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
8406 + mdelay(5);
8409 + /* Issue a global reset to the MAC. This will reset the chip's
8410 + * transmit, receive, DMA, and link units. It will not effect
8411 + * the current PCI configuration. The global reset bit is self-
8412 + * clearing, and should clear within a microsecond.
8413 + */
8414 + DEBUGOUT("Issuing a global reset to MAC\n");
8416 + switch(hw->mac_type) {
8417 + case e1000_82544:
8418 + case e1000_82540:
8419 + case e1000_82545:
8420 + case e1000_82546:
8421 + case e1000_82541:
8422 + case e1000_82541_rev_2:
8423 + /* These controllers can't ack the 64-bit write when issuing the
8424 + * reset, so use IO-mapping as a workaround to issue the reset */
8425 + E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
8426 + break;
8427 + case e1000_82545_rev_3:
8428 + case e1000_82546_rev_3:
8429 + /* Reset is performed on a shadow of the control register */
8430 + E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
8431 + break;
8432 + default:
8433 + E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
8434 + break;
8437 + /* After MAC reset, force reload of EEPROM to restore power-on settings to
8438 + * device. Later controllers reload the EEPROM automatically, so just wait
8439 + * for reload to complete.
8440 + */
8441 + switch(hw->mac_type) {
8442 + case e1000_82542_rev2_0:
8443 + case e1000_82542_rev2_1:
8444 + case e1000_82543:
8445 + case e1000_82544:
8446 + /* Wait for reset to complete */
8447 + udelay(10);
8448 + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
8449 + ctrl_ext |= E1000_CTRL_EXT_EE_RST;
8450 + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
8451 + E1000_WRITE_FLUSH(hw);
8452 + /* Wait for EEPROM reload */
8453 + mdelay(2);
8454 + break;
8455 + case e1000_82541:
8456 + case e1000_82541_rev_2:
8457 + case e1000_82547:
8458 + case e1000_82547_rev_2:
8459 + /* Wait for EEPROM reload */
8460 + mdelay(20);
8461 + break;
8462 + default:
8463 + /* Wait for EEPROM reload (it happens automatically) */
8464 + mdelay(5);
8465 + break;
8468 + /* Disable HW ARPs on ASF enabled adapters */
8469 + if(hw->mac_type >= e1000_82540) {
8470 + manc = E1000_READ_REG(hw, MANC);
8471 + manc &= ~(E1000_MANC_ARP_EN);
8472 + E1000_WRITE_REG(hw, MANC, manc);
8475 + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
8476 + e1000_phy_init_script(hw);
8479 + /* Clear interrupt mask to stop board from generating interrupts */
8480 + DEBUGOUT("Masking off all interrupts\n");
8481 + E1000_WRITE_REG(hw, IMC, 0xffffffff);
8483 + /* Clear any pending interrupt events. */
8484 + icr = E1000_READ_REG(hw, ICR);
8486 + /* If MWI was previously enabled, reenable it. */
8487 + if(hw->mac_type == e1000_82542_rev2_0) {
8488 +#ifdef LINUX_DRIVER
8489 + if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
8490 +#endif
8491 + e1000_pci_set_mwi(hw);
8495 +/******************************************************************************
8496 + * Performs basic configuration of the adapter.
8498 + * hw - Struct containing variables accessed by shared code
8499 + *
8500 + * Assumes that the controller has previously been reset and is in a
8501 + * post-reset uninitialized state. Initializes the receive address registers,
8502 + * multicast table, and VLAN filter table. Calls routines to setup link
8503 + * configuration and flow control settings. Clears all on-chip counters. Leaves
8504 + * the transmit and receive units disabled and uninitialized.
8505 + *****************************************************************************/
8506 +static int
8507 +e1000_init_hw(struct e1000_hw *hw)
8509 + uint32_t ctrl, status;
8510 + uint32_t i;
8511 + int32_t ret_val;
8512 + uint16_t pcix_cmd_word;
8513 + uint16_t pcix_stat_hi_word;
8514 + uint16_t cmd_mmrbc;
8515 + uint16_t stat_mmrbc;
8516 + e1000_bus_type bus_type = e1000_bus_type_unknown;
8518 + DEBUGFUNC("e1000_init_hw");
8520 + /* Set the media type and TBI compatibility */
8521 + e1000_set_media_type(hw);
8523 + /* Disabling VLAN filtering. */
8524 + DEBUGOUT("Initializing the IEEE VLAN\n");
8525 + E1000_WRITE_REG(hw, VET, 0);
8527 + e1000_clear_vfta(hw);
8529 + /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
8530 + if(hw->mac_type == e1000_82542_rev2_0) {
8531 + DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
8532 + e1000_pci_clear_mwi(hw);
8533 + E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
8534 + E1000_WRITE_FLUSH(hw);
8535 + mdelay(5);
8538 + /* Setup the receive address. This involves initializing all of the Receive
8539 + * Address Registers (RARs 0 - 15).
8540 + */
8541 + e1000_init_rx_addrs(hw);
8543 + /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
8544 + if(hw->mac_type == e1000_82542_rev2_0) {
8545 + E1000_WRITE_REG(hw, RCTL, 0);
8546 + E1000_WRITE_FLUSH(hw);
8547 + mdelay(1);
8548 +#ifdef LINUX_DRIVER
8549 + if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
8550 +#endif
8551 + e1000_pci_set_mwi(hw);
8554 + /* Zero out the Multicast HASH table */
8555 + DEBUGOUT("Zeroing the MTA\n");
8556 + for(i = 0; i < E1000_MC_TBL_SIZE; i++)
8557 + E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
8559 +#if 0
8560 + /* Set the PCI priority bit correctly in the CTRL register. This
8561 + * determines if the adapter gives priority to receives, or if it
8562 + * gives equal priority to transmits and receives.
8563 + */
8564 + if(hw->dma_fairness) {
8565 + ctrl = E1000_READ_REG(hw, CTRL);
8566 + E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
8568 +#endif
8570 + switch(hw->mac_type) {
8571 + case e1000_82545_rev_3:
8572 + case e1000_82546_rev_3:
8573 + break;
8574 + default:
8575 + if (hw->mac_type >= e1000_82543) {
8576 + /* See e1000_get_bus_info() of the Linux driver */
8577 + status = E1000_READ_REG(hw, STATUS);
8578 + bus_type = (status & E1000_STATUS_PCIX_MODE) ?
8579 + e1000_bus_type_pcix : e1000_bus_type_pci;
8582 + /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
8583 + if(bus_type == e1000_bus_type_pcix) {
8584 + pci_read_config_word(hw->pdev, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
8585 + pci_read_config_word(hw->pdev, PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
8586 + cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
8587 + PCIX_COMMAND_MMRBC_SHIFT;
8588 + stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
8589 + PCIX_STATUS_HI_MMRBC_SHIFT;
8590 + if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
8591 + stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
8592 + if(cmd_mmrbc > stat_mmrbc) {
8593 + pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
8594 + pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
8595 + pci_write_config_word(hw->pdev, PCIX_COMMAND_REGISTER, pcix_cmd_word);
8598 + break;
8601 + /* Call a subroutine to configure the link and setup flow control. */
8602 + ret_val = e1000_setup_link(hw);
8604 + /* Set the transmit descriptor write-back policy */
8605 + if(hw->mac_type > e1000_82544) {
8606 + ctrl = E1000_READ_REG(hw, TXDCTL);
8607 + ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
8608 + E1000_WRITE_REG(hw, TXDCTL, ctrl);
8611 +#if 0
8612 + /* Clear all of the statistics registers (clear on read). It is
8613 + * important that we do this after we have tried to establish link
8614 + * because the symbol error count will increment wildly if there
8615 + * is no link.
8616 + */
8617 + e1000_clear_hw_cntrs(hw);
8618 +#endif
8620 + return ret_val;
8623 +/******************************************************************************
8624 + * Adjust SERDES output amplitude based on EEPROM setting.
8626 + * hw - Struct containing variables accessed by shared code.
8627 + *****************************************************************************/
8628 +static int32_t
8629 +e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
8631 + uint16_t eeprom_data;
8632 + int32_t ret_val;
8634 + DEBUGFUNC("e1000_adjust_serdes_amplitude");
8636 + if(hw->media_type != e1000_media_type_internal_serdes)
8637 + return E1000_SUCCESS;
8639 + switch(hw->mac_type) {
8640 + case e1000_82545_rev_3:
8641 + case e1000_82546_rev_3:
8642 + break;
8643 + default:
8644 + return E1000_SUCCESS;
8647 + if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
8648 + &eeprom_data))) {
8649 + return ret_val;
8652 + if(eeprom_data != EEPROM_RESERVED_WORD) {
8653 + /* Adjust SERDES output amplitude only. */
8654 + eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
8655 + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
8656 + eeprom_data)))
8657 + return ret_val;
8660 + return E1000_SUCCESS;
8663 +/******************************************************************************
8664 + * Configures flow control and link settings.
8665 + *
8666 + * hw - Struct containing variables accessed by shared code
8667 + *
8668 + * Determines which flow control settings to use. Calls the apropriate media-
8669 + * specific link configuration function. Configures the flow control settings.
8670 + * Assuming the adapter has a valid link partner, a valid link should be
8671 + * established. Assumes the hardware has previously been reset and the
8672 + * transmitter and receiver are not enabled.
8673 + *****************************************************************************/
8674 +static int
8675 +e1000_setup_link(struct e1000_hw *hw)
8677 + uint32_t ctrl_ext;
8678 + int32_t ret_val;
8679 + uint16_t eeprom_data;
8681 + DEBUGFUNC("e1000_setup_link");
8683 + /* Read and store word 0x0F of the EEPROM. This word contains bits
8684 + * that determine the hardware's default PAUSE (flow control) mode,
8685 + * a bit that determines whether the HW defaults to enabling or
8686 + * disabling auto-negotiation, and the direction of the
8687 + * SW defined pins. If there is no SW over-ride of the flow
8688 + * control setting, then the variable hw->fc will
8689 + * be initialized based on a value in the EEPROM.
8690 + */
8691 + if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) {
8692 + DEBUGOUT("EEPROM Read Error\n");
8693 + return -E1000_ERR_EEPROM;
8696 + if(hw->fc == e1000_fc_default) {
8697 + if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
8698 + hw->fc = e1000_fc_none;
8699 + else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
8700 + EEPROM_WORD0F_ASM_DIR)
8701 + hw->fc = e1000_fc_tx_pause;
8702 + else
8703 + hw->fc = e1000_fc_full;
8706 + /* We want to save off the original Flow Control configuration just
8707 + * in case we get disconnected and then reconnected into a different
8708 + * hub or switch with different Flow Control capabilities.
8709 + */
8710 + if(hw->mac_type == e1000_82542_rev2_0)
8711 + hw->fc &= (~e1000_fc_tx_pause);
8713 +#if 0
8714 + /* See e1000_sw_init() of the Linux driver */
8715 + if((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
8716 +#else
8717 + if((hw->mac_type < e1000_82543) && (hw->mac_type >= e1000_82543))
8718 +#endif
8719 + hw->fc &= (~e1000_fc_rx_pause);
8721 +#if 0
8722 + hw->original_fc = hw->fc;
8723 +#endif
8725 + DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc);
8727 + /* Take the 4 bits from EEPROM word 0x0F that determine the initial
8728 + * polarity value for the SW controlled pins, and setup the
8729 + * Extended Device Control reg with that info.
8730 + * This is needed because one of the SW controlled pins is used for
8731 + * signal detection. So this should be done before e1000_setup_pcs_link()
8732 + * or e1000_phy_setup() is called.
8733 + */
8734 + if(hw->mac_type == e1000_82543) {
8735 + ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
8736 + SWDPIO__EXT_SHIFT);
8737 + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
8740 + /* Call the necessary subroutine to configure the link. */
8741 + ret_val = (hw->media_type == e1000_media_type_copper) ?
8742 + e1000_setup_copper_link(hw) :
8743 + e1000_setup_fiber_serdes_link(hw);
8744 + if (ret_val < 0) {
8745 + return ret_val;
8748 + /* Initialize the flow control address, type, and PAUSE timer
8749 + * registers to their default values. This is done even if flow
8750 + * control is disabled, because it does not hurt anything to
8751 + * initialize these registers.
8752 + */
8753 + DEBUGOUT("Initializing the Flow Control address, type and timer regs\n");
8755 + E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
8756 + E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
8757 + E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
8758 +#if 0
8759 + E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
8760 +#else
8761 + E1000_WRITE_REG(hw, FCTTV, FC_DEFAULT_TX_TIMER);
8762 +#endif
8764 + /* Set the flow control receive threshold registers. Normally,
8765 + * these registers will be set to a default threshold that may be
8766 + * adjusted later by the driver's runtime code. However, if the
8767 + * ability to transmit pause frames in not enabled, then these
8768 + * registers will be set to 0.
8769 + */
8770 + if(!(hw->fc & e1000_fc_tx_pause)) {
8771 + E1000_WRITE_REG(hw, FCRTL, 0);
8772 + E1000_WRITE_REG(hw, FCRTH, 0);
8773 + } else {
8774 + /* We need to set up the Receive Threshold high and low water marks
8775 + * as well as (optionally) enabling the transmission of XON frames.
8776 + */
8777 +#if 0
8778 + if(hw->fc_send_xon) {
8779 + E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
8780 + E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
8781 + } else {
8782 + E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
8783 + E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
8785 +#else
8786 + E1000_WRITE_REG(hw, FCRTL, (FC_DEFAULT_LO_THRESH | E1000_FCRTL_XONE));
8787 + E1000_WRITE_REG(hw, FCRTH, FC_DEFAULT_HI_THRESH);
8788 +#endif
8790 + return ret_val;
8793 +/******************************************************************************
8794 + * Sets up link for a fiber based or serdes based adapter
8796 + * hw - Struct containing variables accessed by shared code
8798 + * Manipulates Physical Coding Sublayer functions in order to configure
8799 + * link. Assumes the hardware has been previously reset and the transmitter
8800 + * and receiver are not enabled.
8801 + *****************************************************************************/
8802 +static int
8803 +e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
8805 + uint32_t ctrl;
8806 + uint32_t status;
8807 + uint32_t txcw = 0;
8808 + uint32_t i;
8809 + uint32_t signal = 0;
8810 + int32_t ret_val;
8812 + DEBUGFUNC("e1000_setup_fiber_serdes_link");
8814 + /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
8815 + * set when the optics detect a signal. On older adapters, it will be
8816 + * cleared when there is a signal. This applies to fiber media only.
8817 + * If we're on serdes media, adjust the output amplitude to value set in
8818 + * the EEPROM.
8819 + */
8820 + ctrl = E1000_READ_REG(hw, CTRL);
8821 + if(hw->media_type == e1000_media_type_fiber)
8822 + signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
8824 + if((ret_val = e1000_adjust_serdes_amplitude(hw)))
8825 + return ret_val;
8827 + /* Take the link out of reset */
8828 + ctrl &= ~(E1000_CTRL_LRST);
8830 +#if 0
8831 + /* Adjust VCO speed to improve BER performance */
8832 + if((ret_val = e1000_set_vco_speed(hw)))
8833 + return ret_val;
8834 +#endif
8836 + e1000_config_collision_dist(hw);
8838 + /* Check for a software override of the flow control settings, and setup
8839 + * the device accordingly. If auto-negotiation is enabled, then software
8840 + * will have to set the "PAUSE" bits to the correct value in the Tranmsit
8841 + * Config Word Register (TXCW) and re-start auto-negotiation. However, if
8842 + * auto-negotiation is disabled, then software will have to manually
8843 + * configure the two flow control enable bits in the CTRL register.
8845 + * The possible values of the "fc" parameter are:
8846 + * 0: Flow control is completely disabled
8847 + * 1: Rx flow control is enabled (we can receive pause frames, but
8848 + * not send pause frames).
8849 + * 2: Tx flow control is enabled (we can send pause frames but we do
8850 + * not support receiving pause frames).
8851 + * 3: Both Rx and TX flow control (symmetric) are enabled.
8852 + */
8853 + switch (hw->fc) {
8854 + case e1000_fc_none:
8855 + /* Flow control is completely disabled by a software over-ride. */
8856 + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
8857 + break;
8858 + case e1000_fc_rx_pause:
8859 + /* RX Flow control is enabled and TX Flow control is disabled by a
8860 + * software over-ride. Since there really isn't a way to advertise
8861 + * that we are capable of RX Pause ONLY, we will advertise that we
8862 + * support both symmetric and asymmetric RX PAUSE. Later, we will
8863 + * disable the adapter's ability to send PAUSE frames.
8864 + */
8865 + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
8866 + break;
8867 + case e1000_fc_tx_pause:
8868 + /* TX Flow control is enabled, and RX Flow control is disabled, by a
8869 + * software over-ride.
8870 + */
8871 + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
8872 + break;
8873 + case e1000_fc_full:
8874 + /* Flow control (both RX and TX) is enabled by a software over-ride. */
8875 + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
8876 + break;
8877 + default:
8878 + DEBUGOUT("Flow control param set incorrectly\n");
8879 + return -E1000_ERR_CONFIG;
8880 + break;
8883 + /* Since auto-negotiation is enabled, take the link out of reset (the link
8884 + * will be in reset, because we previously reset the chip). This will
8885 + * restart auto-negotiation. If auto-neogtiation is successful then the
8886 + * link-up status bit will be set and the flow control enable bits (RFCE
8887 + * and TFCE) will be set according to their negotiated value.
8888 + */
8889 + DEBUGOUT("Auto-negotiation enabled\n");
8891 + E1000_WRITE_REG(hw, TXCW, txcw);
8892 + E1000_WRITE_REG(hw, CTRL, ctrl);
8893 + E1000_WRITE_FLUSH(hw);
8895 + hw->txcw = txcw;
8896 + mdelay(1);
8898 + /* If we have a signal (the cable is plugged in) then poll for a "Link-Up"
8899 + * indication in the Device Status Register. Time-out if a link isn't
8900 + * seen in 500 milliseconds seconds (Auto-negotiation should complete in
8901 + * less than 500 milliseconds even if the other end is doing it in SW).
8902 + * For internal serdes, we just assume a signal is present, then poll.
8903 + */
8904 + if(hw->media_type == e1000_media_type_internal_serdes ||
8905 + (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
8906 + DEBUGOUT("Looking for Link\n");
8907 + for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
8908 + mdelay(10);
8909 + status = E1000_READ_REG(hw, STATUS);
8910 + if(status & E1000_STATUS_LU) break;
8912 + if(i == (LINK_UP_TIMEOUT / 10)) {
8913 + DEBUGOUT("Never got a valid link from auto-neg!!!\n");
8914 + hw->autoneg_failed = 1;
8915 + /* AutoNeg failed to achieve a link, so we'll call
8916 + * e1000_check_for_link. This routine will force the link up if
8917 + * we detect a signal. This will allow us to communicate with
8918 + * non-autonegotiating link partners.
8919 + */
8920 + if((ret_val = e1000_check_for_link(hw))) {
8921 + DEBUGOUT("Error while checking for link\n");
8922 + return ret_val;
8924 + hw->autoneg_failed = 0;
8925 + } else {
8926 + hw->autoneg_failed = 0;
8927 + DEBUGOUT("Valid Link Found\n");
8929 + } else {
8930 + DEBUGOUT("No Signal Detected\n");
8932 + return E1000_SUCCESS;
8935 +/******************************************************************************
8936 +* Detects which PHY is present and the speed and duplex
8938 +* hw - Struct containing variables accessed by shared code
8939 +******************************************************************************/
8940 +static int
8941 +e1000_setup_copper_link(struct e1000_hw *hw)
8943 + uint32_t ctrl;
8944 + int32_t ret_val;
8945 + uint16_t i;
8946 + uint16_t phy_data;
8948 + DEBUGFUNC("e1000_setup_copper_link");
8950 + ctrl = E1000_READ_REG(hw, CTRL);
8951 + /* With 82543, we need to force speed and duplex on the MAC equal to what
8952 + * the PHY speed and duplex configuration is. In addition, we need to
8953 + * perform a hardware reset on the PHY to take it out of reset.
8954 + */
8955 + if(hw->mac_type > e1000_82543) {
8956 + ctrl |= E1000_CTRL_SLU;
8957 + ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
8958 + E1000_WRITE_REG(hw, CTRL, ctrl);
8959 + } else {
8960 + ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
8961 + E1000_WRITE_REG(hw, CTRL, ctrl);
8962 + e1000_phy_hw_reset(hw);
8965 + /* Make sure we have a valid PHY */
8966 + if((ret_val = e1000_detect_gig_phy(hw))) {
8967 + DEBUGOUT("Error, did not detect valid phy.\n");
8968 + return ret_val;
8970 + DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
8972 + if(hw->mac_type <= e1000_82543 ||
8973 + hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
8974 +#if 0
8975 + hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
8976 + hw->phy_reset_disable = FALSE;
8978 + if(!hw->phy_reset_disable) {
8979 +#else
8980 + hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) {
8981 +#endif
8982 + if (hw->phy_type == e1000_phy_igp) {
8984 + if((ret_val = e1000_phy_reset(hw))) {
8985 + DEBUGOUT("Error Resetting the PHY\n");
8986 + return ret_val;
8989 + /* Wait 10ms for MAC to configure PHY from eeprom settings */
8990 + mdelay(15);
8992 +#if 0
8993 + /* disable lplu d3 during driver init */
8994 + if((ret_val = e1000_set_d3_lplu_state(hw, FALSE))) {
8995 + DEBUGOUT("Error Disabling LPLU D3\n");
8996 + return ret_val;
8999 + /* Configure mdi-mdix settings */
9000 + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
9001 + &phy_data)))
9002 + return ret_val;
9004 + if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
9005 + hw->dsp_config_state = e1000_dsp_config_disabled;
9006 + /* Force MDI for IGP B-0 PHY */
9007 + phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
9008 + IGP01E1000_PSCR_FORCE_MDI_MDIX);
9009 + hw->mdix = 1;
9011 + } else {
9012 + hw->dsp_config_state = e1000_dsp_config_enabled;
9013 + phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
9015 + switch (hw->mdix) {
9016 + case 1:
9017 + phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
9018 + break;
9019 + case 2:
9020 + phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
9021 + break;
9022 + case 0:
9023 + default:
9024 + phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
9025 + break;
9028 + if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
9029 + phy_data)))
9030 + return ret_val;
9032 + /* set auto-master slave resolution settings */
9033 + e1000_ms_type phy_ms_setting = hw->master_slave;
9035 + if(hw->ffe_config_state == e1000_ffe_config_active)
9036 + hw->ffe_config_state = e1000_ffe_config_enabled;
9038 + if(hw->dsp_config_state == e1000_dsp_config_activated)
9039 + hw->dsp_config_state = e1000_dsp_config_enabled;
9040 +#endif
9042 + /* when autonegotiation advertisment is only 1000Mbps then we
9043 + * should disable SmartSpeed and enable Auto MasterSlave
9044 + * resolution as hardware default. */
9045 + if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
9046 + /* Disable SmartSpeed */
9047 + if((ret_val = e1000_read_phy_reg(hw,
9048 + IGP01E1000_PHY_PORT_CONFIG,
9049 + &phy_data)))
9050 + return ret_val;
9051 + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
9052 + if((ret_val = e1000_write_phy_reg(hw,
9053 + IGP01E1000_PHY_PORT_CONFIG,
9054 + phy_data)))
9055 + return ret_val;
9056 + /* Set auto Master/Slave resolution process */
9057 + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
9058 + &phy_data)))
9059 + return ret_val;
9060 + phy_data &= ~CR_1000T_MS_ENABLE;
9061 + if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
9062 + phy_data)))
9063 + return ret_val;
9066 + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
9067 + &phy_data)))
9068 + return ret_val;
9070 +#if 0
9071 + /* load defaults for future use */
9072 + hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
9073 + ((phy_data & CR_1000T_MS_VALUE) ?
9074 + e1000_ms_force_master :
9075 + e1000_ms_force_slave) :
9076 + e1000_ms_auto;
9078 + switch (phy_ms_setting) {
9079 + case e1000_ms_force_master:
9080 + phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
9081 + break;
9082 + case e1000_ms_force_slave:
9083 + phy_data |= CR_1000T_MS_ENABLE;
9084 + phy_data &= ~(CR_1000T_MS_VALUE);
9085 + break;
9086 + case e1000_ms_auto:
9087 + phy_data &= ~CR_1000T_MS_ENABLE;
9088 + default:
9089 + break;
9091 +#endif
9093 + if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
9094 + phy_data)))
9095 + return ret_val;
9096 + } else {
9097 + /* Enable CRS on TX. This must be set for half-duplex operation. */
9098 + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
9099 + &phy_data)))
9100 + return ret_val;
9102 + phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
9104 + /* Options:
9105 + * MDI/MDI-X = 0 (default)
9106 + * 0 - Auto for all speeds
9107 + * 1 - MDI mode
9108 + * 2 - MDI-X mode
9109 + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
9110 + */
9111 +#if 0
9112 + phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
9114 + switch (hw->mdix) {
9115 + case 1:
9116 + phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
9117 + break;
9118 + case 2:
9119 + phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
9120 + break;
9121 + case 3:
9122 + phy_data |= M88E1000_PSCR_AUTO_X_1000T;
9123 + break;
9124 + case 0:
9125 + default:
9126 +#endif
9127 + phy_data |= M88E1000_PSCR_AUTO_X_MODE;
9128 +#if 0
9129 + break;
9131 +#endif
9133 + /* Options:
9134 + * disable_polarity_correction = 0 (default)
9135 + * Automatic Correction for Reversed Cable Polarity
9136 + * 0 - Disabled
9137 + * 1 - Enabled
9138 + */
9139 + phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
9140 + if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
9141 + phy_data)))
9142 + return ret_val;
9144 + /* Force TX_CLK in the Extended PHY Specific Control Register
9145 + * to 25MHz clock.
9146 + */
9147 + if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
9148 + &phy_data)))
9149 + return ret_val;
9151 + phy_data |= M88E1000_EPSCR_TX_CLK_25;
9153 +#ifdef LINUX_DRIVER
9154 + if (hw->phy_revision < M88E1011_I_REV_4) {
9155 +#endif
9156 + /* Configure Master and Slave downshift values */
9157 + phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
9158 + M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
9159 + phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
9160 + M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
9161 + if((ret_val = e1000_write_phy_reg(hw,
9162 + M88E1000_EXT_PHY_SPEC_CTRL,
9163 + phy_data)))
9164 + return ret_val;
9167 + /* SW Reset the PHY so all changes take effect */
9168 + if((ret_val = e1000_phy_reset(hw))) {
9169 + DEBUGOUT("Error Resetting the PHY\n");
9170 + return ret_val;
9171 +#ifdef LINUX_DRIVER
9173 +#endif
9176 + /* Options:
9177 + * autoneg = 1 (default)
9178 + * PHY will advertise value(s) parsed from
9179 + * autoneg_advertised and fc
9180 + * autoneg = 0
9181 + * PHY will be set to 10H, 10F, 100H, or 100F
9182 + * depending on value parsed from forced_speed_duplex.
9183 + */
9185 + /* Is autoneg enabled? This is enabled by default or by software
9186 + * override. If so, call e1000_phy_setup_autoneg routine to parse the
9187 + * autoneg_advertised and fc options. If autoneg is NOT enabled, then
9188 + * the user should have provided a speed/duplex override. If so, then
9189 + * call e1000_phy_force_speed_duplex to parse and set this up.
9190 + */
9191 + /* Perform some bounds checking on the hw->autoneg_advertised
9192 + * parameter. If this variable is zero, then set it to the default.
9193 + */
9194 + hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
9196 + /* If autoneg_advertised is zero, we assume it was not defaulted
9197 + * by the calling code so we set to advertise full capability.
9198 + */
9199 + if(hw->autoneg_advertised == 0)
9200 + hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
9202 + DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
9203 + if((ret_val = e1000_phy_setup_autoneg(hw))) {
9204 + DEBUGOUT("Error Setting up Auto-Negotiation\n");
9205 + return ret_val;
9207 + DEBUGOUT("Restarting Auto-Neg\n");
9209 + /* Restart auto-negotiation by setting the Auto Neg Enable bit and
9210 + * the Auto Neg Restart bit in the PHY control register.
9211 + */
9212 + if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
9213 + return ret_val;
9215 + phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
9216 + if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
9217 + return ret_val;
9219 +#if 0
9220 + /* Does the user want to wait for Auto-Neg to complete here, or
9221 + * check at a later time (for example, callback routine).
9222 + */
9223 + if(hw->wait_autoneg_complete) {
9224 + if((ret_val = e1000_wait_autoneg(hw))) {
9225 + DEBUGOUT("Error while waiting for autoneg to complete\n");
9226 + return ret_val;
9229 +#else
9230 + /* If we do not wait for autonegotiation to complete I
9231 + * do not see a valid link status.
9232 + */
9233 + if((ret_val = e1000_wait_autoneg(hw))) {
9234 + DEBUGOUT("Error while waiting for autoneg to complete\n");
9235 + return ret_val;
9237 +#endif
9238 + } /* !hw->phy_reset_disable */
9240 + /* Check link status. Wait up to 100 microseconds for link to become
9241 + * valid.
9242 + */
9243 + for(i = 0; i < 10; i++) {
9244 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
9245 + return ret_val;
9246 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
9247 + return ret_val;
9249 + if(phy_data & MII_SR_LINK_STATUS) {
9250 + /* We have link, so we need to finish the config process:
9251 + * 1) Set up the MAC to the current PHY speed/duplex
9252 + * if we are on 82543. If we
9253 + * are on newer silicon, we only need to configure
9254 + * collision distance in the Transmit Control Register.
9255 + * 2) Set up flow control on the MAC to that established with
9256 + * the link partner.
9257 + */
9258 + if(hw->mac_type >= e1000_82544) {
9259 + e1000_config_collision_dist(hw);
9260 + } else {
9261 + if((ret_val = e1000_config_mac_to_phy(hw))) {
9262 + DEBUGOUT("Error configuring MAC to PHY settings\n");
9263 + return ret_val;
9266 + if((ret_val = e1000_config_fc_after_link_up(hw))) {
9267 + DEBUGOUT("Error Configuring Flow Control\n");
9268 + return ret_val;
9270 +#if 0
9271 + if(hw->phy_type == e1000_phy_igp) {
9272 + if((ret_val = e1000_config_dsp_after_link_change(hw, TRUE))) {
9273 + DEBUGOUT("Error Configuring DSP after link up\n");
9274 + return ret_val;
9277 +#endif
9278 + DEBUGOUT("Valid link established!!!\n");
9279 + return E1000_SUCCESS;
9281 + udelay(10);
9284 + DEBUGOUT("Unable to establish link!!!\n");
9285 + return -E1000_ERR_NOLINK;
9288 +/******************************************************************************
9289 +* Configures PHY autoneg and flow control advertisement settings
9291 +* hw - Struct containing variables accessed by shared code
9292 +******************************************************************************/
9293 +static int
9294 +e1000_phy_setup_autoneg(struct e1000_hw *hw)
9296 + int32_t ret_val;
9297 + uint16_t mii_autoneg_adv_reg;
9298 + uint16_t mii_1000t_ctrl_reg;
9300 + DEBUGFUNC("e1000_phy_setup_autoneg");
9302 + /* Read the MII Auto-Neg Advertisement Register (Address 4). */
9303 + if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
9304 + &mii_autoneg_adv_reg)))
9305 + return ret_val;
9307 + /* Read the MII 1000Base-T Control Register (Address 9). */
9308 + if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg)))
9309 + return ret_val;
9311 + /* Need to parse both autoneg_advertised and fc and set up
9312 + * the appropriate PHY registers. First we will parse for
9313 + * autoneg_advertised software override. Since we can advertise
9314 + * a plethora of combinations, we need to check each bit
9315 + * individually.
9316 + */
9318 + /* First we clear all the 10/100 mb speed bits in the Auto-Neg
9319 + * Advertisement Register (Address 4) and the 1000 mb speed bits in
9320 + * the 1000Base-T Control Register (Address 9).
9321 + */
9322 + mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
9323 + mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
9325 + DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);
9327 + /* Do we want to advertise 10 Mb Half Duplex? */
9328 + if(hw->autoneg_advertised & ADVERTISE_10_HALF) {
9329 + DEBUGOUT("Advertise 10mb Half duplex\n");
9330 + mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
9333 + /* Do we want to advertise 10 Mb Full Duplex? */
9334 + if(hw->autoneg_advertised & ADVERTISE_10_FULL) {
9335 + DEBUGOUT("Advertise 10mb Full duplex\n");
9336 + mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
9339 + /* Do we want to advertise 100 Mb Half Duplex? */
9340 + if(hw->autoneg_advertised & ADVERTISE_100_HALF) {
9341 + DEBUGOUT("Advertise 100mb Half duplex\n");
9342 + mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
9345 + /* Do we want to advertise 100 Mb Full Duplex? */
9346 + if(hw->autoneg_advertised & ADVERTISE_100_FULL) {
9347 + DEBUGOUT("Advertise 100mb Full duplex\n");
9348 + mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
9351 + /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
9352 + if(hw->autoneg_advertised & ADVERTISE_1000_HALF) {
9353 + DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n");
9356 + /* Do we want to advertise 1000 Mb Full Duplex? */
9357 + if(hw->autoneg_advertised & ADVERTISE_1000_FULL) {
9358 + DEBUGOUT("Advertise 1000mb Full duplex\n");
9359 + mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
9362 + /* Check for a software override of the flow control settings, and
9363 + * setup the PHY advertisement registers accordingly. If
9364 + * auto-negotiation is enabled, then software will have to set the
9365 + * "PAUSE" bits to the correct value in the Auto-Negotiation
9366 + * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto-negotiation.
9368 + * The possible values of the "fc" parameter are:
9369 + * 0: Flow control is completely disabled
9370 + * 1: Rx flow control is enabled (we can receive pause frames
9371 + * but not send pause frames).
9372 + * 2: Tx flow control is enabled (we can send pause frames
9373 + * but we do not support receiving pause frames).
9374 + * 3: Both Rx and TX flow control (symmetric) are enabled.
9375 + * other: No software override. The flow control configuration
9376 + * in the EEPROM is used.
9377 + */
9378 + switch (hw->fc) {
9379 + case e1000_fc_none: /* 0 */
9380 + /* Flow control (RX & TX) is completely disabled by a
9381 + * software over-ride.
9382 + */
9383 + mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
9384 + break;
9385 + case e1000_fc_rx_pause: /* 1 */
9386 + /* RX Flow control is enabled, and TX Flow control is
9387 + * disabled, by a software over-ride.
9388 + */
9389 + /* Since there really isn't a way to advertise that we are
9390 + * capable of RX Pause ONLY, we will advertise that we
9391 + * support both symmetric and asymmetric RX PAUSE. Later
9392 + * (in e1000_config_fc_after_link_up) we will disable the
9393 + *hw's ability to send PAUSE frames.
9394 + */
9395 + mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
9396 + break;
9397 + case e1000_fc_tx_pause: /* 2 */
9398 + /* TX Flow control is enabled, and RX Flow control is
9399 + * disabled, by a software over-ride.
9400 + */
9401 + mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
9402 + mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
9403 + break;
9404 + case e1000_fc_full: /* 3 */
9405 + /* Flow control (both RX and TX) is enabled by a software
9406 + * over-ride.
9407 + */
9408 + mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
9409 + break;
9410 + default:
9411 + DEBUGOUT("Flow control param set incorrectly\n");
9412 + return -E1000_ERR_CONFIG;
9415 + if((ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV,
9416 + mii_autoneg_adv_reg)))
9417 + return ret_val;
9419 + DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
9421 + if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg)))
9422 + return ret_val;
9424 + return E1000_SUCCESS;
9427 +/******************************************************************************
9428 +* Sets the collision distance in the Transmit Control register
9430 +* hw - Struct containing variables accessed by shared code
9432 +* Link should have been established previously. Reads the speed and duplex
9433 +* information from the Device Status register.
9434 +******************************************************************************/
9435 +static void
9436 +e1000_config_collision_dist(struct e1000_hw *hw)
9438 + uint32_t tctl;
9440 + tctl = E1000_READ_REG(hw, TCTL);
9442 + tctl &= ~E1000_TCTL_COLD;
9443 + tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
9445 + E1000_WRITE_REG(hw, TCTL, tctl);
9446 + E1000_WRITE_FLUSH(hw);
9449 +/******************************************************************************
9450 +* Sets MAC speed and duplex settings to reflect the those in the PHY
9452 +* hw - Struct containing variables accessed by shared code
9453 +* mii_reg - data to write to the MII control register
9455 +* The contents of the PHY register containing the needed information need to
9456 +* be passed in.
9457 +******************************************************************************/
9458 +static int
9459 +e1000_config_mac_to_phy(struct e1000_hw *hw)
9461 + uint32_t ctrl;
9462 + int32_t ret_val;
9463 + uint16_t phy_data;
9465 + DEBUGFUNC("e1000_config_mac_to_phy");
9467 + /* Read the Device Control Register and set the bits to Force Speed
9468 + * and Duplex.
9469 + */
9470 + ctrl = E1000_READ_REG(hw, CTRL);
9471 + ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
9472 + ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
9474 + /* Set up duplex in the Device Control and Transmit Control
9475 + * registers depending on negotiated values.
9476 + */
9477 + if (hw->phy_type == e1000_phy_igp) {
9478 + if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
9479 + &phy_data)))
9480 + return ret_val;
9482 + if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
9483 + else ctrl &= ~E1000_CTRL_FD;
9485 + e1000_config_collision_dist(hw);
9487 + /* Set up speed in the Device Control register depending on
9488 + * negotiated values.
9489 + */
9490 + if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
9491 + IGP01E1000_PSSR_SPEED_1000MBPS)
9492 + ctrl |= E1000_CTRL_SPD_1000;
9493 + else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
9494 + IGP01E1000_PSSR_SPEED_100MBPS)
9495 + ctrl |= E1000_CTRL_SPD_100;
9496 + } else {
9497 + if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
9498 + &phy_data)))
9499 + return ret_val;
9501 + if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
9502 + else ctrl &= ~E1000_CTRL_FD;
9504 + e1000_config_collision_dist(hw);
9506 + /* Set up speed in the Device Control register depending on
9507 + * negotiated values.
9508 + */
9509 + if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
9510 + ctrl |= E1000_CTRL_SPD_1000;
9511 + else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
9512 + ctrl |= E1000_CTRL_SPD_100;
9514 + /* Write the configured values back to the Device Control Reg. */
9515 + E1000_WRITE_REG(hw, CTRL, ctrl);
9516 + return E1000_SUCCESS;
9519 +/******************************************************************************
9520 + * Forces the MAC's flow control settings.
9521 + *
9522 + * hw - Struct containing variables accessed by shared code
9524 + * Sets the TFCE and RFCE bits in the device control register to reflect
9525 + * the adapter settings. TFCE and RFCE need to be explicitly set by
9526 + * software when a Copper PHY is used because autonegotiation is managed
9527 + * by the PHY rather than the MAC. Software must also configure these
9528 + * bits when link is forced on a fiber connection.
9529 + *****************************************************************************/
9530 +static int
9531 +e1000_force_mac_fc(struct e1000_hw *hw)
9533 + uint32_t ctrl;
9535 + DEBUGFUNC("e1000_force_mac_fc");
9537 + /* Get the current configuration of the Device Control Register */
9538 + ctrl = E1000_READ_REG(hw, CTRL);
9540 + /* Because we didn't get link via the internal auto-negotiation
9541 + * mechanism (we either forced link or we got link via PHY
9542 + * auto-neg), we have to manually enable/disable transmit an
9543 + * receive flow control.
9545 + * The "Case" statement below enables/disable flow control
9546 + * according to the "hw->fc" parameter.
9548 + * The possible values of the "fc" parameter are:
9549 + * 0: Flow control is completely disabled
9550 + * 1: Rx flow control is enabled (we can receive pause
9551 + * frames but not send pause frames).
9552 + * 2: Tx flow control is enabled (we can send pause frames
9553 + * frames but we do not receive pause frames).
9554 + * 3: Both Rx and TX flow control (symmetric) is enabled.
9555 + * other: No other values should be possible at this point.
9556 + */
9558 + switch (hw->fc) {
9559 + case e1000_fc_none:
9560 + ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
9561 + break;
9562 + case e1000_fc_rx_pause:
9563 + ctrl &= (~E1000_CTRL_TFCE);
9564 + ctrl |= E1000_CTRL_RFCE;
9565 + break;
9566 + case e1000_fc_tx_pause:
9567 + ctrl &= (~E1000_CTRL_RFCE);
9568 + ctrl |= E1000_CTRL_TFCE;
9569 + break;
9570 + case e1000_fc_full:
9571 + ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
9572 + break;
9573 + default:
9574 + DEBUGOUT("Flow control param set incorrectly\n");
9575 + return -E1000_ERR_CONFIG;
9578 + /* Disable TX Flow Control for 82542 (rev 2.0) */
9579 + if(hw->mac_type == e1000_82542_rev2_0)
9580 + ctrl &= (~E1000_CTRL_TFCE);
9582 + E1000_WRITE_REG(hw, CTRL, ctrl);
9583 + return E1000_SUCCESS;
9586 +/******************************************************************************
9587 + * Configures flow control settings after link is established
9588 + *
9589 + * hw - Struct containing variables accessed by shared code
9591 + * Should be called immediately after a valid link has been established.
9592 + * Forces MAC flow control settings if link was forced. When in MII/GMII mode
9593 + * and autonegotiation is enabled, the MAC flow control settings will be set
9594 + * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
9595 + * and RFCE bits will be automaticaly set to the negotiated flow control mode.
9596 + *****************************************************************************/
9597 +static int
9598 +e1000_config_fc_after_link_up(struct e1000_hw *hw)
9600 + int32_t ret_val;
9601 + uint16_t mii_status_reg;
9602 + uint16_t mii_nway_adv_reg;
9603 + uint16_t mii_nway_lp_ability_reg;
9604 + uint16_t speed;
9605 + uint16_t duplex;
9607 + DEBUGFUNC("e1000_config_fc_after_link_up");
9609 + /* Check for the case where we have fiber media and auto-neg failed
9610 + * so we had to force link. In this case, we need to force the
9611 + * configuration of the MAC to match the "fc" parameter.
9612 + */
9613 + if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
9614 + ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed))) {
9615 + if((ret_val = e1000_force_mac_fc(hw))) {
9616 + DEBUGOUT("Error forcing flow control settings\n");
9617 + return ret_val;
9621 + /* Check for the case where we have copper media and auto-neg is
9622 + * enabled. In this case, we need to check and see if Auto-Neg
9623 + * has completed, and if so, how the PHY and link partner has
9624 + * flow control configured.
9625 + */
9626 + if(hw->media_type == e1000_media_type_copper) {
9627 + /* Read the MII Status Register and check to see if AutoNeg
9628 + * has completed. We read this twice because this reg has
9629 + * some "sticky" (latched) bits.
9630 + */
9631 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
9632 + return ret_val;
9633 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg)))
9634 + return ret_val;
9636 + if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
9637 + /* The AutoNeg process has completed, so we now need to
9638 + * read both the Auto Negotiation Advertisement Register
9639 + * (Address 4) and the Auto_Negotiation Base Page Ability
9640 + * Register (Address 5) to determine how flow control was
9641 + * negotiated.
9642 + */
9643 + if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
9644 + &mii_nway_adv_reg)))
9645 + return ret_val;
9646 + if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
9647 + &mii_nway_lp_ability_reg)))
9648 + return ret_val;
9650 + /* Two bits in the Auto Negotiation Advertisement Register
9651 + * (Address 4) and two bits in the Auto Negotiation Base
9652 + * Page Ability Register (Address 5) determine flow control
9653 + * for both the PHY and the link partner. The following
9654 + * table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
9655 + * 1999, describes these PAUSE resolution bits and how flow
9656 + * control is determined based upon these settings.
9657 + * NOTE: DC = Don't Care
9659 + * LOCAL DEVICE | LINK PARTNER
9660 + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
9661 + *-------|---------|-------|---------|--------------------
9662 + * 0 | 0 | DC | DC | e1000_fc_none
9663 + * 0 | 1 | 0 | DC | e1000_fc_none
9664 + * 0 | 1 | 1 | 0 | e1000_fc_none
9665 + * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
9666 + * 1 | 0 | 0 | DC | e1000_fc_none
9667 + * 1 | DC | 1 | DC | e1000_fc_full
9668 + * 1 | 1 | 0 | 0 | e1000_fc_none
9669 + * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
9671 + */
9672 + /* Are both PAUSE bits set to 1? If so, this implies
9673 + * Symmetric Flow Control is enabled at both ends. The
9674 + * ASM_DIR bits are irrelevant per the spec.
9676 + * For Symmetric Flow Control:
9678 + * LOCAL DEVICE | LINK PARTNER
9679 + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
9680 + *-------|---------|-------|---------|--------------------
9681 + * 1 | DC | 1 | DC | e1000_fc_full
9683 + */
9684 + if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
9685 + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
9686 + /* Now we need to check if the user selected RX ONLY
9687 + * of pause frames. In this case, we had to advertise
9688 + * FULL flow control because we could not advertise RX
9689 + * ONLY. Hence, we must now check to see if we need to
9690 + * turn OFF the TRANSMISSION of PAUSE frames.
9691 + */
9692 +#if 0
9693 + if(hw->original_fc == e1000_fc_full) {
9694 + hw->fc = e1000_fc_full;
9695 +#else
9696 + if(hw->fc == e1000_fc_full) {
9697 +#endif
9698 + DEBUGOUT("Flow Control = FULL.\r\n");
9699 + } else {
9700 + hw->fc = e1000_fc_rx_pause;
9701 + DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
9704 + /* For receiving PAUSE frames ONLY.
9706 + * LOCAL DEVICE | LINK PARTNER
9707 + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
9708 + *-------|---------|-------|---------|--------------------
9709 + * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
9711 + */
9712 + else if(!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
9713 + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
9714 + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
9715 + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
9716 + hw->fc = e1000_fc_tx_pause;
9717 + DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n");
9719 + /* For transmitting PAUSE frames ONLY.
9721 + * LOCAL DEVICE | LINK PARTNER
9722 + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
9723 + *-------|---------|-------|---------|--------------------
9724 + * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
9726 + */
9727 + else if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
9728 + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
9729 + !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
9730 + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
9731 + hw->fc = e1000_fc_rx_pause;
9732 + DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
9734 + /* Per the IEEE spec, at this point flow control should be
9735 + * disabled. However, we want to consider that we could
9736 + * be connected to a legacy switch that doesn't advertise
9737 + * desired flow control, but can be forced on the link
9738 + * partner. So if we advertised no flow control, that is
9739 + * what we will resolve to. If we advertised some kind of
9740 + * receive capability (Rx Pause Only or Full Flow Control)
9741 + * and the link partner advertised none, we will configure
9742 + * ourselves to enable Rx Flow Control only. We can do
9743 + * this safely for two reasons: If the link partner really
9744 + * didn't want flow control enabled, and we enable Rx, no
9745 + * harm done since we won't be receiving any PAUSE frames
9746 + * anyway. If the intent on the link partner was to have
9747 + * flow control enabled, then by us enabling RX only, we
9748 + * can at least receive pause frames and process them.
9749 + * This is a good idea because in most cases, since we are
9750 + * predominantly a server NIC, more times than not we will
9751 + * be asked to delay transmission of packets than asking
9752 + * our link partner to pause transmission of frames.
9753 + */
9754 +#if 0
9755 + else if(hw->original_fc == e1000_fc_none ||
9756 + hw->original_fc == e1000_fc_tx_pause) {
9757 +#else
9758 + else if(hw->fc == e1000_fc_none)
9759 + DEBUGOUT("Flow Control = NONE.\r\n");
9760 + else if(hw->fc == e1000_fc_tx_pause) {
9761 +#endif
9762 + hw->fc = e1000_fc_none;
9763 + DEBUGOUT("Flow Control = NONE.\r\n");
9764 + } else {
9765 + hw->fc = e1000_fc_rx_pause;
9766 + DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
9769 + /* Now we need to do one last check... If we auto-
9770 + * negotiated to HALF DUPLEX, flow control should not be
9771 + * enabled per IEEE 802.3 spec.
9772 + */
9773 + e1000_get_speed_and_duplex(hw, &speed, &duplex);
9775 + if(duplex == HALF_DUPLEX)
9776 + hw->fc = e1000_fc_none;
9778 + /* Now we call a subroutine to actually force the MAC
9779 + * controller to use the correct flow control settings.
9780 + */
9781 + if((ret_val = e1000_force_mac_fc(hw))) {
9782 + DEBUGOUT("Error forcing flow control settings\n");
9783 + return ret_val;
9785 + } else {
9786 + DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
9789 + return E1000_SUCCESS;
9792 +/******************************************************************************
9793 + * Checks to see if the link status of the hardware has changed.
9795 + * hw - Struct containing variables accessed by shared code
9797 + * Called by any function that needs to check the link status of the adapter.
9798 + *****************************************************************************/
9799 +static int
9800 +e1000_check_for_link(struct e1000_hw *hw)
9802 + uint32_t rxcw;
9803 + uint32_t ctrl;
9804 + uint32_t status;
9805 + uint32_t rctl;
9806 + uint32_t signal = 0;
9807 + int32_t ret_val;
9808 + uint16_t phy_data;
9809 + uint16_t lp_capability;
9811 + DEBUGFUNC("e1000_check_for_link");
9813 + /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
9814 + * set when the optics detect a signal. On older adapters, it will be
9815 + * cleared when there is a signal. This applies to fiber media only.
9816 + */
9817 + if(hw->media_type == e1000_media_type_fiber)
9818 + signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
9820 + ctrl = E1000_READ_REG(hw, CTRL);
9821 + status = E1000_READ_REG(hw, STATUS);
9822 + rxcw = E1000_READ_REG(hw, RXCW);
9824 + /* If we have a copper PHY then we only want to go out to the PHY
9825 + * registers to see if Auto-Neg has completed and/or if our link
9826 + * status has changed. The get_link_status flag will be set if we
9827 + * receive a Link Status Change interrupt or we have Rx Sequence
9828 + * Errors.
9829 + */
9830 +#if 0
9831 + if((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
9832 +#else
9833 + if(hw->media_type == e1000_media_type_copper) {
9834 +#endif
9835 + /* First we want to see if the MII Status Register reports
9836 + * link. If so, then we want to get the current speed/duplex
9837 + * of the PHY.
9838 + * Read the register twice since the link bit is sticky.
9839 + */
9840 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
9841 + return ret_val;
9842 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
9843 + return ret_val;
9845 + if(phy_data & MII_SR_LINK_STATUS) {
9846 +#if 0
9847 + hw->get_link_status = FALSE;
9848 +#endif
9849 + } else {
9850 + /* No link detected */
9851 + return -E1000_ERR_NOLINK;
9854 + /* We have a M88E1000 PHY and Auto-Neg is enabled. If we
9855 + * have Si on board that is 82544 or newer, Auto
9856 + * Speed Detection takes care of MAC speed/duplex
9857 + * configuration. So we only need to configure Collision
9858 + * Distance in the MAC. Otherwise, we need to force
9859 + * speed/duplex on the MAC to the current PHY speed/duplex
9860 + * settings.
9861 + */
9862 + if(hw->mac_type >= e1000_82544)
9863 + e1000_config_collision_dist(hw);
9864 + else {
9865 + if((ret_val = e1000_config_mac_to_phy(hw))) {
9866 + DEBUGOUT("Error configuring MAC to PHY settings\n");
9867 + return ret_val;
9871 + /* Configure Flow Control now that Auto-Neg has completed. First, we
9872 + * need to restore the desired flow control settings because we may
9873 + * have had to re-autoneg with a different link partner.
9874 + */
9875 + if((ret_val = e1000_config_fc_after_link_up(hw))) {
9876 + DEBUGOUT("Error configuring flow control\n");
9877 + return ret_val;
9880 + /* At this point we know that we are on copper and we have
9881 + * auto-negotiated link. These are conditions for checking the link
9882 + * parter capability register. We use the link partner capability to
9883 + * determine if TBI Compatibility needs to be turned on or off. If
9884 + * the link partner advertises any speed in addition to Gigabit, then
9885 + * we assume that they are GMII-based, and TBI compatibility is not
9886 + * needed. If no other speeds are advertised, we assume the link
9887 + * partner is TBI-based, and we turn on TBI Compatibility.
9888 + */
9889 + if(hw->tbi_compatibility_en) {
9890 + if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
9891 + &lp_capability)))
9892 + return ret_val;
9893 + if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
9894 + NWAY_LPAR_10T_FD_CAPS |
9895 + NWAY_LPAR_100TX_HD_CAPS |
9896 + NWAY_LPAR_100TX_FD_CAPS |
9897 + NWAY_LPAR_100T4_CAPS)) {
9898 + /* If our link partner advertises anything in addition to
9899 + * gigabit, we do not need to enable TBI compatibility.
9900 + */
9901 + if(hw->tbi_compatibility_on) {
9902 + /* If we previously were in the mode, turn it off. */
9903 + rctl = E1000_READ_REG(hw, RCTL);
9904 + rctl &= ~E1000_RCTL_SBP;
9905 + E1000_WRITE_REG(hw, RCTL, rctl);
9906 + hw->tbi_compatibility_on = FALSE;
9908 + } else {
9909 + /* If TBI compatibility is was previously off, turn it on. For
9910 + * compatibility with a TBI link partner, we will store bad
9911 + * packets. Some frames have an additional byte on the end and
9912 + * will look like CRC errors to to the hardware.
9913 + */
9914 + if(!hw->tbi_compatibility_on) {
9915 + hw->tbi_compatibility_on = TRUE;
9916 + rctl = E1000_READ_REG(hw, RCTL);
9917 + rctl |= E1000_RCTL_SBP;
9918 + E1000_WRITE_REG(hw, RCTL, rctl);
9923 + /* If we don't have link (auto-negotiation failed or link partner cannot
9924 + * auto-negotiate), the cable is plugged in (we have signal), and our
9925 + * link partner is not trying to auto-negotiate with us (we are receiving
9926 + * idles or data), we need to force link up. We also need to give
9927 + * auto-negotiation time to complete, in case the cable was just plugged
9928 + * in. The autoneg_failed flag does this.
9929 + */
9930 + else if((((hw->media_type == e1000_media_type_fiber) &&
9931 + ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
9932 + (hw->media_type == e1000_media_type_internal_serdes)) &&
9933 + (!(status & E1000_STATUS_LU)) &&
9934 + (!(rxcw & E1000_RXCW_C))) {
9935 + if(hw->autoneg_failed == 0) {
9936 + hw->autoneg_failed = 1;
9937 + return 0;
9939 + DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
9941 + /* Disable auto-negotiation in the TXCW register */
9942 + E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
9944 + /* Force link-up and also force full-duplex. */
9945 + ctrl = E1000_READ_REG(hw, CTRL);
9946 + ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
9947 + E1000_WRITE_REG(hw, CTRL, ctrl);
9949 + /* Configure Flow Control after forcing link up. */
9950 + if((ret_val = e1000_config_fc_after_link_up(hw))) {
9951 + DEBUGOUT("Error configuring flow control\n");
9952 + return ret_val;
9955 + /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
9956 + * auto-negotiation in the TXCW register and disable forced link in the
9957 + * Device Control register in an attempt to auto-negotiate with our link
9958 + * partner.
9959 + */
9960 + else if(((hw->media_type == e1000_media_type_fiber) ||
9961 + (hw->media_type == e1000_media_type_internal_serdes)) &&
9962 + (ctrl & E1000_CTRL_SLU) &&
9963 + (rxcw & E1000_RXCW_C)) {
9964 + DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
9965 + E1000_WRITE_REG(hw, TXCW, hw->txcw);
9966 + E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
9968 +#if 0
9969 + /* If we force link for non-auto-negotiation switch, check link status
9970 + * based on MAC synchronization for internal serdes media type.
9971 + */
9972 + else if((hw->media_type == e1000_media_type_internal_serdes) &&
9973 + !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
9974 + /* SYNCH bit and IV bit are sticky. */
9975 + udelay(10);
9976 + if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
9977 + if(!(rxcw & E1000_RXCW_IV)) {
9978 + hw->serdes_link_down = FALSE;
9979 + DEBUGOUT("SERDES: Link is up.\n");
9981 + } else {
9982 + hw->serdes_link_down = TRUE;
9983 + DEBUGOUT("SERDES: Link is down.\n");
9986 +#endif
9987 + return E1000_SUCCESS;
9990 +/******************************************************************************
9991 + * Detects the current speed and duplex settings of the hardware.
9993 + * hw - Struct containing variables accessed by shared code
9994 + * speed - Speed of the connection
9995 + * duplex - Duplex setting of the connection
9996 + *****************************************************************************/
9997 +static void
9998 +e1000_get_speed_and_duplex(struct e1000_hw *hw,
9999 + uint16_t *speed,
10000 + uint16_t *duplex)
10002 + uint32_t status;
10004 + DEBUGFUNC("e1000_get_speed_and_duplex");
10006 + if(hw->mac_type >= e1000_82543) {
10007 + status = E1000_READ_REG(hw, STATUS);
10008 + if(status & E1000_STATUS_SPEED_1000) {
10009 + *speed = SPEED_1000;
10010 + DEBUGOUT("1000 Mbs, ");
10011 + } else if(status & E1000_STATUS_SPEED_100) {
10012 + *speed = SPEED_100;
10013 + DEBUGOUT("100 Mbs, ");
10014 + } else {
10015 + *speed = SPEED_10;
10016 + DEBUGOUT("10 Mbs, ");
10019 + if(status & E1000_STATUS_FD) {
10020 + *duplex = FULL_DUPLEX;
10021 + DEBUGOUT("Full Duplex\r\n");
10022 + } else {
10023 + *duplex = HALF_DUPLEX;
10024 + DEBUGOUT(" Half Duplex\r\n");
10026 + } else {
10027 + DEBUGOUT("1000 Mbs, Full Duplex\r\n");
10028 + *speed = SPEED_1000;
10029 + *duplex = FULL_DUPLEX;
10033 +/******************************************************************************
10034 +* Blocks until autoneg completes or times out (~4.5 seconds)
10036 +* hw - Struct containing variables accessed by shared code
10037 +******************************************************************************/
10038 +static int
10039 +e1000_wait_autoneg(struct e1000_hw *hw)
10041 + int32_t ret_val;
10042 + uint16_t i;
10043 + uint16_t phy_data;
10045 + DEBUGFUNC("e1000_wait_autoneg");
10046 + DEBUGOUT("Waiting for Auto-Neg to complete.\n");
10048 + /* We will wait for autoneg to complete or 4.5 seconds to expire. */
10049 + for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
10050 + /* Read the MII Status Register and wait for Auto-Neg
10051 + * Complete bit to be set.
10052 + */
10053 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
10054 + return ret_val;
10055 + if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
10056 + return ret_val;
10057 + if(phy_data & MII_SR_AUTONEG_COMPLETE) {
10058 + DEBUGOUT("Auto-Neg complete.\n");
10059 + return E1000_SUCCESS;
10061 + mdelay(100);
10063 + DEBUGOUT("Auto-Neg timedout.\n");
10064 + return -E1000_ERR_TIMEOUT;
10067 +/******************************************************************************
10068 +* Raises the Management Data Clock
10070 +* hw - Struct containing variables accessed by shared code
10071 +* ctrl - Device control register's current value
10072 +******************************************************************************/
10073 +static void
10074 +e1000_raise_mdi_clk(struct e1000_hw *hw,
10075 + uint32_t *ctrl)
10077 + /* Raise the clock input to the Management Data Clock (by setting the MDC
10078 + * bit), and then delay 10 microseconds.
10079 + */
10080 + E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
10081 + E1000_WRITE_FLUSH(hw);
10082 + udelay(10);
10085 +/******************************************************************************
10086 +* Lowers the Management Data Clock
10088 +* hw - Struct containing variables accessed by shared code
10089 +* ctrl - Device control register's current value
10090 +******************************************************************************/
10091 +static void
10092 +e1000_lower_mdi_clk(struct e1000_hw *hw,
10093 + uint32_t *ctrl)
10095 + /* Lower the clock input to the Management Data Clock (by clearing the MDC
10096 + * bit), and then delay 10 microseconds.
10097 + */
10098 + E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
10099 + E1000_WRITE_FLUSH(hw);
10100 + udelay(10);
10103 +/******************************************************************************
10104 +* Shifts data bits out to the PHY
10106 +* hw - Struct containing variables accessed by shared code
10107 +* data - Data to send out to the PHY
10108 +* count - Number of bits to shift out
10110 +* Bits are shifted out in MSB to LSB order.
10111 +******************************************************************************/
10112 +static void
10113 +e1000_shift_out_mdi_bits(struct e1000_hw *hw,
10114 + uint32_t data,
10115 + uint16_t count)
10117 + uint32_t ctrl;
10118 + uint32_t mask;
10120 + /* We need to shift "count" number of bits out to the PHY. So, the value
10121 + * in the "data" parameter will be shifted out to the PHY one bit at a
10122 + * time. In order to do this, "data" must be broken down into bits.
10123 + */
10124 + mask = 0x01;
10125 + mask <<= (count - 1);
10127 + ctrl = E1000_READ_REG(hw, CTRL);
10129 + /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
10130 + ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
10132 + while(mask) {
10133 + /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
10134 + * then raising and lowering the Management Data Clock. A "0" is
10135 + * shifted out to the PHY by setting the MDIO bit to "0" and then
10136 + * raising and lowering the clock.
10137 + */
10138 + if(data & mask) ctrl |= E1000_CTRL_MDIO;
10139 + else ctrl &= ~E1000_CTRL_MDIO;
10141 + E1000_WRITE_REG(hw, CTRL, ctrl);
10142 + E1000_WRITE_FLUSH(hw);
10144 + udelay(10);
10146 + e1000_raise_mdi_clk(hw, &ctrl);
10147 + e1000_lower_mdi_clk(hw, &ctrl);
10149 + mask = mask >> 1;
10153 +/******************************************************************************
10154 +* Shifts data bits in from the PHY
10156 +* hw - Struct containing variables accessed by shared code
10158 +* Bits are shifted in in MSB to LSB order.
10159 +******************************************************************************/
10160 +static uint16_t
10161 +e1000_shift_in_mdi_bits(struct e1000_hw *hw)
10163 + uint32_t ctrl;
10164 + uint16_t data = 0;
10165 + uint8_t i;
10167 + /* In order to read a register from the PHY, we need to shift in a total
10168 + * of 18 bits from the PHY. The first two bit (turnaround) times are used
10169 + * to avoid contention on the MDIO pin when a read operation is performed.
10170 + * These two bits are ignored by us and thrown away. Bits are "shifted in"
10171 + * by raising the input to the Management Data Clock (setting the MDC bit),
10172 + * and then reading the value of the MDIO bit.
10173 + */
10174 + ctrl = E1000_READ_REG(hw, CTRL);
10176 + /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as input. */
10177 + ctrl &= ~E1000_CTRL_MDIO_DIR;
10178 + ctrl &= ~E1000_CTRL_MDIO;
10180 + E1000_WRITE_REG(hw, CTRL, ctrl);
10181 + E1000_WRITE_FLUSH(hw);
10183 + /* Raise and Lower the clock before reading in the data. This accounts for
10184 + * the turnaround bits. The first clock occurred when we clocked out the
10185 + * last bit of the Register Address.
10186 + */
10187 + e1000_raise_mdi_clk(hw, &ctrl);
10188 + e1000_lower_mdi_clk(hw, &ctrl);
10190 + for(data = 0, i = 0; i < 16; i++) {
10191 + data = data << 1;
10192 + e1000_raise_mdi_clk(hw, &ctrl);
10193 + ctrl = E1000_READ_REG(hw, CTRL);
10194 + /* Check to see if we shifted in a "1". */
10195 + if(ctrl & E1000_CTRL_MDIO) data |= 1;
10196 + e1000_lower_mdi_clk(hw, &ctrl);
10199 + e1000_raise_mdi_clk(hw, &ctrl);
10200 + e1000_lower_mdi_clk(hw, &ctrl);
10202 + return data;
10205 +/*****************************************************************************
10206 +* Reads the value from a PHY register, if the value is on a specific non zero
10207 +* page, sets the page first.
10209 +* hw - Struct containing variables accessed by shared code
10210 +* reg_addr - address of the PHY register to read
10211 +******************************************************************************/
10212 +static int
10213 +e1000_read_phy_reg(struct e1000_hw *hw,
10214 + uint32_t reg_addr,
10215 + uint16_t *phy_data)
10217 + uint32_t ret_val;
10219 + DEBUGFUNC("e1000_read_phy_reg");
10221 + if(hw->phy_type == e1000_phy_igp &&
10222 + (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
10223 + if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
10224 + (uint16_t)reg_addr)))
10225 + return ret_val;
10228 + ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
10229 + phy_data);
10231 + return ret_val;
10234 +static int
10235 +e1000_read_phy_reg_ex(struct e1000_hw *hw,
10236 + uint32_t reg_addr,
10237 + uint16_t *phy_data)
10239 + uint32_t i;
10240 + uint32_t mdic = 0;
10241 + const uint32_t phy_addr = 1;
10243 + DEBUGFUNC("e1000_read_phy_reg_ex");
10245 + if(reg_addr > MAX_PHY_REG_ADDRESS) {
10246 + DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
10247 + return -E1000_ERR_PARAM;
10250 + if(hw->mac_type > e1000_82543) {
10251 + /* Set up Op-code, Phy Address, and register address in the MDI
10252 + * Control register. The MAC will take care of interfacing with the
10253 + * PHY to retrieve the desired data.
10254 + */
10255 + mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
10256 + (phy_addr << E1000_MDIC_PHY_SHIFT) |
10257 + (E1000_MDIC_OP_READ));
10259 + E1000_WRITE_REG(hw, MDIC, mdic);
10261 + /* Poll the ready bit to see if the MDI read completed */
10262 + for(i = 0; i < 64; i++) {
10263 + udelay(50);
10264 + mdic = E1000_READ_REG(hw, MDIC);
10265 + if(mdic & E1000_MDIC_READY) break;
10267 + if(!(mdic & E1000_MDIC_READY)) {
10268 + DEBUGOUT("MDI Read did not complete\n");
10269 + return -E1000_ERR_PHY;
10271 + if(mdic & E1000_MDIC_ERROR) {
10272 + DEBUGOUT("MDI Error\n");
10273 + return -E1000_ERR_PHY;
10275 + *phy_data = (uint16_t) mdic;
10276 + } else {
10277 + /* We must first send a preamble through the MDIO pin to signal the
10278 + * beginning of an MII instruction. This is done by sending 32
10279 + * consecutive "1" bits.
10280 + */
10281 + e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
10283 + /* Now combine the next few fields that are required for a read
10284 + * operation. We use this method instead of calling the
10285 + * e1000_shift_out_mdi_bits routine five different times. The format of
10286 + * a MII read instruction consists of a shift out of 14 bits and is
10287 + * defined as follows:
10288 + * <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
10289 + * followed by a shift in of 18 bits. This first two bits shifted in
10290 + * are TurnAround bits used to avoid contention on the MDIO pin when a
10291 + * READ operation is performed. These two bits are thrown away
10292 + * followed by a shift in of 16 bits which contains the desired data.
10293 + */
10294 + mdic = ((reg_addr) | (phy_addr << 5) |
10295 + (PHY_OP_READ << 10) | (PHY_SOF << 12));
10297 + e1000_shift_out_mdi_bits(hw, mdic, 14);
10299 + /* Now that we've shifted out the read command to the MII, we need to
10300 + * "shift in" the 16-bit value (18 total bits) of the requested PHY
10301 + * register address.
10302 + */
10303 + *phy_data = e1000_shift_in_mdi_bits(hw);
10305 + return E1000_SUCCESS;
10308 +/******************************************************************************
10309 +* Writes a value to a PHY register
10311 +* hw - Struct containing variables accessed by shared code
10312 +* reg_addr - address of the PHY register to write
10313 +* data - data to write to the PHY
10314 +******************************************************************************/
10315 +static int
10316 +e1000_write_phy_reg(struct e1000_hw *hw,
10317 + uint32_t reg_addr,
10318 + uint16_t phy_data)
10320 + uint32_t ret_val;
10322 + DEBUGFUNC("e1000_write_phy_reg");
10324 + if(hw->phy_type == e1000_phy_igp &&
10325 + (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
10326 + if((ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
10327 + (uint16_t)reg_addr)))
10328 + return ret_val;
10331 + ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
10332 + phy_data);
10334 + return ret_val;
10337 +static int
10338 +e1000_write_phy_reg_ex(struct e1000_hw *hw,
10339 + uint32_t reg_addr,
10340 + uint16_t phy_data)
10342 + uint32_t i;
10343 + uint32_t mdic = 0;
10344 + const uint32_t phy_addr = 1;
10346 + DEBUGFUNC("e1000_write_phy_reg_ex");
10348 + if(reg_addr > MAX_PHY_REG_ADDRESS) {
10349 + DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
10350 + return -E1000_ERR_PARAM;
10353 + if(hw->mac_type > e1000_82543) {
10354 + /* Set up Op-code, Phy Address, register address, and data intended
10355 + * for the PHY register in the MDI Control register. The MAC will take
10356 + * care of interfacing with the PHY to send the desired data.
10357 + */
10358 + mdic = (((uint32_t) phy_data) |
10359 + (reg_addr << E1000_MDIC_REG_SHIFT) |
10360 + (phy_addr << E1000_MDIC_PHY_SHIFT) |
10361 + (E1000_MDIC_OP_WRITE));
10363 + E1000_WRITE_REG(hw, MDIC, mdic);
10365 + /* Poll the ready bit to see if the MDI read completed */
10366 + for(i = 0; i < 640; i++) {
10367 + udelay(5);
10368 + mdic = E1000_READ_REG(hw, MDIC);
10369 + if(mdic & E1000_MDIC_READY) break;
10371 + if(!(mdic & E1000_MDIC_READY)) {
10372 + DEBUGOUT("MDI Write did not complete\n");
10373 + return -E1000_ERR_PHY;
10375 + } else {
10376 + /* We'll need to use the SW defined pins to shift the write command
10377 + * out to the PHY. We first send a preamble to the PHY to signal the
10378 + * beginning of the MII instruction. This is done by sending 32
10379 + * consecutive "1" bits.
10380 + */
10381 + e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
10383 + /* Now combine the remaining required fields that will indicate a
10384 + * write operation. We use this method instead of calling the
10385 + * e1000_shift_out_mdi_bits routine for each field in the command. The
10386 + * format of a MII write instruction is as follows:
10387 + * <Preamble><SOF><Op Code><Phy Addr><Reg Addr><Turnaround><Data>.
10388 + */
10389 + mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
10390 + (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
10391 + mdic <<= 16;
10392 + mdic |= (uint32_t) phy_data;
10394 + e1000_shift_out_mdi_bits(hw, mdic, 32);
10397 + return E1000_SUCCESS;
10400 +/******************************************************************************
10401 +* Returns the PHY to the power-on reset state
10403 +* hw - Struct containing variables accessed by shared code
10404 +******************************************************************************/
10405 +static void
10406 +e1000_phy_hw_reset(struct e1000_hw *hw)
10408 + uint32_t ctrl, ctrl_ext;
10410 + DEBUGFUNC("e1000_phy_hw_reset");
10412 + DEBUGOUT("Resetting Phy...\n");
10414 + if(hw->mac_type > e1000_82543) {
10415 + /* Read the device control register and assert the E1000_CTRL_PHY_RST
10416 + * bit. Then, take it out of reset.
10417 + */
10418 + ctrl = E1000_READ_REG(hw, CTRL);
10419 + E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
10420 + E1000_WRITE_FLUSH(hw);
10421 + mdelay(10);
10422 + E1000_WRITE_REG(hw, CTRL, ctrl);
10423 + E1000_WRITE_FLUSH(hw);
10424 + } else {
10425 + /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
10426 + * bit to put the PHY into reset. Then, take it out of reset.
10427 + */
10428 + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
10429 + ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
10430 + ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
10431 + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
10432 + E1000_WRITE_FLUSH(hw);
10433 + mdelay(10);
10434 + ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
10435 + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
10436 + E1000_WRITE_FLUSH(hw);
10438 + udelay(150);
10441 +/******************************************************************************
10442 +* Resets the PHY
10444 +* hw - Struct containing variables accessed by shared code
10446 +* Sets bit 15 of the MII Control regiser
10447 +******************************************************************************/
10448 +static int
10449 +e1000_phy_reset(struct e1000_hw *hw)
10451 + int32_t ret_val;
10452 + uint16_t phy_data;
10454 + DEBUGFUNC("e1000_phy_reset");
10456 + if(hw->mac_type != e1000_82541_rev_2) {
10457 + if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
10458 + return ret_val;
10460 + phy_data |= MII_CR_RESET;
10461 + if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
10462 + return ret_val;
10464 + udelay(1);
10465 + } else e1000_phy_hw_reset(hw);
10467 + if(hw->phy_type == e1000_phy_igp)
10468 + e1000_phy_init_script(hw);
10470 + return E1000_SUCCESS;
10473 +/******************************************************************************
10474 +* Probes the expected PHY address for known PHY IDs
10476 +* hw - Struct containing variables accessed by shared code
10477 +******************************************************************************/
10478 +static int
10479 +e1000_detect_gig_phy(struct e1000_hw *hw)
10481 + int32_t phy_init_status, ret_val;
10482 + uint16_t phy_id_high, phy_id_low;
10483 + boolean_t match = FALSE;
10485 + DEBUGFUNC("e1000_detect_gig_phy");
10487 + /* Read the PHY ID Registers to identify which PHY is onboard. */
10488 + if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
10489 + return ret_val;
10491 + hw->phy_id = (uint32_t) (phy_id_high << 16);
10492 + udelay(20);
10493 + if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
10494 + return ret_val;
10496 + hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
10497 +#ifdef LINUX_DRIVER
10498 + hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
10499 +#endif
10501 + switch(hw->mac_type) {
10502 + case e1000_82543:
10503 + if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
10504 + break;
10505 + case e1000_82544:
10506 + if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
10507 + break;
10508 + case e1000_82540:
10509 + case e1000_82545:
10510 + case e1000_82545_rev_3:
10511 + case e1000_82546:
10512 + case e1000_82546_rev_3:
10513 + if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
10514 + break;
10515 + case e1000_82541:
10516 + case e1000_82541_rev_2:
10517 + case e1000_82547:
10518 + case e1000_82547_rev_2:
10519 + if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
10520 + break;
10521 + default:
10522 + DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
10523 + return -E1000_ERR_CONFIG;
10525 + phy_init_status = e1000_set_phy_type(hw);
10527 + if ((match) && (phy_init_status == E1000_SUCCESS)) {
10528 + DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
10529 + return E1000_SUCCESS;
10531 + DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
10532 + return -E1000_ERR_PHY;
10535 +/******************************************************************************
10536 + * Sets up eeprom variables in the hw struct. Must be called after mac_type
10537 + * is configured.
10539 + * hw - Struct containing variables accessed by shared code
10540 + *****************************************************************************/
10541 +static void
10542 +e1000_init_eeprom_params(struct e1000_hw *hw)
10544 + struct e1000_eeprom_info *eeprom = &hw->eeprom;
10545 + uint32_t eecd = E1000_READ_REG(hw, EECD);
10546 + uint16_t eeprom_size;
10548 + DEBUGFUNC("e1000_init_eeprom_params");
10550 + switch (hw->mac_type) {
10551 + case e1000_82542_rev2_0:
10552 + case e1000_82542_rev2_1:
10553 + case e1000_82543:
10554 + case e1000_82544:
10555 + eeprom->type = e1000_eeprom_microwire;
10556 + eeprom->word_size = 64;
10557 + eeprom->opcode_bits = 3;
10558 + eeprom->address_bits = 6;
10559 + eeprom->delay_usec = 50;
10560 + break;
10561 + case e1000_82540:
10562 + case e1000_82545:
10563 + case e1000_82545_rev_3:
10564 + case e1000_82546:
10565 + case e1000_82546_rev_3:
10566 + eeprom->type = e1000_eeprom_microwire;
10567 + eeprom->opcode_bits = 3;
10568 + eeprom->delay_usec = 50;
10569 + if(eecd & E1000_EECD_SIZE) {
10570 + eeprom->word_size = 256;
10571 + eeprom->address_bits = 8;
10572 + } else {
10573 + eeprom->word_size = 64;
10574 + eeprom->address_bits = 6;
10576 + break;
10577 + case e1000_82541:
10578 + case e1000_82541_rev_2:
10579 + case e1000_82547:
10580 + case e1000_82547_rev_2:
10581 + if (eecd & E1000_EECD_TYPE) {
10582 + eeprom->type = e1000_eeprom_spi;
10583 + if (eecd & E1000_EECD_ADDR_BITS) {
10584 + eeprom->page_size = 32;
10585 + eeprom->address_bits = 16;
10586 + } else {
10587 + eeprom->page_size = 8;
10588 + eeprom->address_bits = 8;
10590 + } else {
10591 + eeprom->type = e1000_eeprom_microwire;
10592 + eeprom->opcode_bits = 3;
10593 + eeprom->delay_usec = 50;
10594 + if (eecd & E1000_EECD_ADDR_BITS) {
10595 + eeprom->word_size = 256;
10596 + eeprom->address_bits = 8;
10597 + } else {
10598 + eeprom->word_size = 64;
10599 + eeprom->address_bits = 6;
10602 + break;
10603 + default:
10604 + eeprom->type = e1000_eeprom_spi;
10605 + if (eecd & E1000_EECD_ADDR_BITS) {
10606 + eeprom->page_size = 32;
10607 + eeprom->address_bits = 16;
10608 + } else {
10609 + eeprom->page_size = 8;
10610 + eeprom->address_bits = 8;
10612 + break;
10615 + if (eeprom->type == e1000_eeprom_spi) {
10616 + eeprom->opcode_bits = 8;
10617 + eeprom->delay_usec = 1;
10618 + eeprom->word_size = 64;
10619 + if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
10620 + eeprom_size &= EEPROM_SIZE_MASK;
10622 + switch (eeprom_size) {
10623 + case EEPROM_SIZE_16KB:
10624 + eeprom->word_size = 8192;
10625 + break;
10626 + case EEPROM_SIZE_8KB:
10627 + eeprom->word_size = 4096;
10628 + break;
10629 + case EEPROM_SIZE_4KB:
10630 + eeprom->word_size = 2048;
10631 + break;
10632 + case EEPROM_SIZE_2KB:
10633 + eeprom->word_size = 1024;
10634 + break;
10635 + case EEPROM_SIZE_1KB:
10636 + eeprom->word_size = 512;
10637 + break;
10638 + case EEPROM_SIZE_512B:
10639 + eeprom->word_size = 256;
10640 + break;
10641 + case EEPROM_SIZE_128B:
10642 + default:
10643 + break;
10649 +/**
10650 + * e1000_reset - Reset the adapter
10651 + */
10653 +static int
10654 +e1000_reset(struct e1000_hw *hw)
10656 + uint32_t pba;
10657 + /* Repartition Pba for greater than 9k mtu
10658 + * To take effect CTRL.RST is required.
10659 + */
10661 + if(hw->mac_type < e1000_82547) {
10662 + pba = E1000_PBA_48K;
10663 + } else {
10664 + pba = E1000_PBA_30K;
10666 + E1000_WRITE_REG(hw, PBA, pba);
10668 + /* flow control settings */
10669 +#if 0
10670 + hw->fc_high_water = FC_DEFAULT_HI_THRESH;
10671 + hw->fc_low_water = FC_DEFAULT_LO_THRESH;
10672 + hw->fc_pause_time = FC_DEFAULT_TX_TIMER;
10673 + hw->fc_send_xon = 1;
10674 + hw->fc = hw->original_fc;
10675 +#endif
10677 + e1000_reset_hw(hw);
10678 + if(hw->mac_type >= e1000_82544)
10679 + E1000_WRITE_REG(hw, WUC, 0);
10680 + return e1000_init_hw(hw);
10683 +/**
10684 + * e1000_sw_init - Initialize general software structures (struct e1000_adapter)
10685 + * @adapter: board private structure to initialize
10687 + * e1000_sw_init initializes the Adapter private data structure.
10688 + * Fields are initialized based on PCI device information and
10689 + * OS network device settings (MTU size).
10690 + **/
10692 +static int
10693 +e1000_sw_init(struct pci_device *pdev, struct e1000_hw *hw)
10695 + int result;
10697 + /* PCI config space info */
10698 + pci_read_config_word(pdev, PCI_VENDOR_ID, &hw->vendor_id);
10699 + pci_read_config_word(pdev, PCI_DEVICE_ID, &hw->device_id);
10700 + pci_read_config_byte(pdev, PCI_REVISION, &hw->revision_id);
10701 +#if 0
10702 + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID,
10703 + &hw->subsystem_vendor_id);
10704 + pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
10705 +#endif
10707 + pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
10709 + /* identify the MAC */
10711 + result = e1000_set_mac_type(hw);
10712 + if (result) {
10713 + E1000_ERR("Unknown MAC Type\n");
10714 + return result;
10717 + /* initialize eeprom parameters */
10719 + e1000_init_eeprom_params(hw);
10721 +#if 0
10722 + if((hw->mac_type == e1000_82541) ||
10723 + (hw->mac_type == e1000_82547) ||
10724 + (hw->mac_type == e1000_82541_rev_2) ||
10725 + (hw->mac_type == e1000_82547_rev_2))
10726 + hw->phy_init_script = 1;
10727 +#endif
10729 + e1000_set_media_type(hw);
10731 +#if 0
10732 + if(hw->mac_type < e1000_82543)
10733 + hw->report_tx_early = 0;
10734 + else
10735 + hw->report_tx_early = 1;
10737 + hw->wait_autoneg_complete = FALSE;
10738 +#endif
10739 + hw->tbi_compatibility_en = TRUE;
10740 +#if 0
10741 + hw->adaptive_ifs = TRUE;
10743 + /* Copper options */
10745 + if(hw->media_type == e1000_media_type_copper) {
10746 + hw->mdix = AUTO_ALL_MODES;
10747 + hw->disable_polarity_correction = FALSE;
10748 + hw->master_slave = E1000_MASTER_SLAVE;
10750 +#endif
10751 + return E1000_SUCCESS;
10754 +static void fill_rx (void)
10756 + struct e1000_rx_desc *rd;
10757 + rx_last = rx_tail;
10758 + rd = rx_base + rx_tail;
10759 + rx_tail = (rx_tail + 1) % 8;
10760 + memset (rd, 0, 16);
10761 + rd->buffer_addr = virt_to_bus(&packet);
10762 + E1000_WRITE_REG (&hw, RDT, rx_tail);
10765 +static void init_descriptor (void)
10767 + unsigned long ptr;
10768 + unsigned long tctl;
10770 + ptr = virt_to_phys(tx_pool);
10771 + if (ptr & 0xf)
10772 + ptr = (ptr + 0x10) & (~0xf);
10774 + tx_base = phys_to_virt(ptr);
10776 + E1000_WRITE_REG (&hw, TDBAL, virt_to_bus(tx_base));
10777 + E1000_WRITE_REG (&hw, TDBAH, 0);
10778 + E1000_WRITE_REG (&hw, TDLEN, 128);
10780 + /* Setup the HW Tx Head and Tail descriptor pointers */
10782 + E1000_WRITE_REG (&hw, TDH, 0);
10783 + E1000_WRITE_REG (&hw, TDT, 0);
10784 + tx_tail = 0;
10786 + /* Program the Transmit Control Register */
10788 +#ifdef LINUX_DRIVER_TCTL
10789 + tctl = E1000_READ_REG(&hw, TCTL);
10791 + tctl &= ~E1000_TCTL_CT;
10792 + tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
10793 + (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
10794 +#else
10795 + tctl = E1000_TCTL_PSP | E1000_TCTL_EN |
10796 + (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT) |
10797 + (E1000_HDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
10798 +#endif
10800 + E1000_WRITE_REG (&hw, TCTL, tctl);
10802 + e1000_config_collision_dist(&hw);
10805 + rx_tail = 0;
10806 + /* disable receive */
10807 + E1000_WRITE_REG (&hw, RCTL, 0);
10808 + ptr = virt_to_phys(rx_pool);
10809 + if (ptr & 0xf)
10810 + ptr = (ptr + 0x10) & (~0xf);
10811 + rx_base = phys_to_virt(ptr);
10813 + /* Setup the Base and Length of the Rx Descriptor Ring */
10815 + E1000_WRITE_REG (&hw, RDBAL, virt_to_bus(rx_base));
10816 + E1000_WRITE_REG (&hw, RDBAH, 0);
10818 + E1000_WRITE_REG (&hw, RDLEN, 128);
10820 + /* Setup the HW Rx Head and Tail Descriptor Pointers */
10821 + E1000_WRITE_REG (&hw, RDH, 0);
10822 + E1000_WRITE_REG (&hw, RDT, 0);
10824 + E1000_WRITE_REG (&hw, RCTL,
10825 + E1000_RCTL_EN |
10826 + E1000_RCTL_BAM |
10827 + E1000_RCTL_SZ_2048 |
10828 + E1000_RCTL_MPE);
10829 + fill_rx();
10834 +/**************************************************************************
10835 +POLL - Wait for a frame
10836 +***************************************************************************/
10837 +static int
10838 +e1000_poll (struct nic *nic, int retrieve)
10840 + /* return true if there's an ethernet packet ready to read */
10841 + /* nic->packet should contain data on return */
10842 + /* nic->packetlen should contain length of data */
10843 + struct e1000_rx_desc *rd;
10845 + rd = rx_base + rx_last;
10846 + if (!rd->status & E1000_RXD_STAT_DD)
10847 + return 0;
10849 + if ( ! retrieve ) return 1;
10851 + // printf("recv: packet %! -> %! len=%d \n", packet+6, packet,rd->Length);
10852 + memcpy (nic->packet, packet, rd->length);
10853 + nic->packetlen = rd->length;
10854 + fill_rx ();
10855 + return 1;
10858 +/**************************************************************************
10859 +TRANSMIT - Transmit a frame
10860 +***************************************************************************/
10861 +static void
10862 +e1000_transmit (struct nic *nic, const char *d, /* Destination */
10863 + unsigned int type, /* Type */
10864 + unsigned int size, /* size */
10865 + const char *p) /* Packet */
10867 + /* send the packet to destination */
10868 + struct eth_hdr {
10869 + unsigned char dst_addr[ETH_ALEN];
10870 + unsigned char src_addr[ETH_ALEN];
10871 + unsigned short type;
10872 + } hdr;
10873 + struct e1000_tx_desc *txhd; /* header */
10874 + struct e1000_tx_desc *txp; /* payload */
10875 + DEBUGFUNC("send");
10877 + memcpy (&hdr.dst_addr, d, ETH_ALEN);
10878 + memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
10880 + hdr.type = htons (type);
10881 + txhd = tx_base + tx_tail;
10882 + tx_tail = (tx_tail + 1) % 8;
10883 + txp = tx_base + tx_tail;
10884 + tx_tail = (tx_tail + 1) % 8;
10886 + txhd->buffer_addr = virt_to_bus (&hdr);
10887 + txhd->lower.data = sizeof (hdr);
10888 + txhd->upper.data = 0;
10890 + txp->buffer_addr = virt_to_bus(p);
10891 + txp->lower.data = E1000_TXD_CMD_RPS | E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS | size;
10892 + txp->upper.data = 0;
10894 + E1000_WRITE_REG (&hw, TDT, tx_tail);
10895 + while (!(txp->upper.data & E1000_TXD_STAT_DD)) {
10896 + udelay(10); /* give the nic a chance to write to the register */
10897 + poll_interruptions();
10899 + DEBUGFUNC("send end");
10903 +/**************************************************************************
10904 +DISABLE - Turn off ethernet interface
10905 +***************************************************************************/
10906 +static void e1000_disable (struct dev *dev __unused)
10908 + /* Clear the transmit ring */
10909 + E1000_WRITE_REG (&hw, TDH, 0);
10910 + E1000_WRITE_REG (&hw, TDT, 0);
10912 + /* Clear the receive ring */
10913 + E1000_WRITE_REG (&hw, RDH, 0);
10914 + E1000_WRITE_REG (&hw, RDT, 0);
10916 + /* put the card in its initial state */
10917 + E1000_WRITE_REG (&hw, CTRL, E1000_CTRL_RST);
10919 + /* Turn off the ethernet interface */
10920 + E1000_WRITE_REG (&hw, RCTL, 0);
10921 + E1000_WRITE_REG (&hw, TCTL, 0);
10922 + mdelay (10);
10924 + /* Unmap my window to the device */
10925 + iounmap(hw.hw_addr);
10928 +/**************************************************************************
10929 +IRQ - Enable, Disable, or Force interrupts
10930 +***************************************************************************/
10931 +static void e1000_irq(struct nic *nic __unused, irq_action_t action __unused)
10933 + switch ( action ) {
10934 + case DISABLE :
10935 + break;
10936 + case ENABLE :
10937 + break;
10938 + case FORCE :
10939 + break;
10943 +#define IORESOURCE_IO 0x00000100 /* Resource type */
10944 +#define BAR_0 0
10945 +#define BAR_1 1
10946 +#define BAR_5 5
10948 +/**************************************************************************
10949 +PROBE - Look for an adapter, this routine's visible to the outside
10950 +You should omit the last argument struct pci_device * for a non-PCI NIC
10951 +***************************************************************************/
10952 +static int e1000_probe(struct dev *dev, struct pci_device *p)
10954 + struct nic *nic = (struct nic *)dev;
10955 + unsigned long mmio_start, mmio_len;
10956 + int ret_val, i;
10958 + if (p == 0)
10959 + return 0;
10960 + /* Initialize hw with default values */
10961 + memset(&hw, 0, sizeof(hw));
10962 + hw.pdev = p;
10964 +#if 1
10965 + /* Are these variables needed? */
10966 + hw.fc = e1000_fc_none;
10967 +#if 0
10968 + hw.original_fc = e1000_fc_none;
10969 +#endif
10970 + hw.autoneg_failed = 0;
10971 +#if 0
10972 + hw.get_link_status = TRUE;
10973 +#endif
10974 +#endif
10976 + mmio_start = pci_bar_start(p, PCI_BASE_ADDRESS_0);
10977 + mmio_len = pci_bar_size(p, PCI_BASE_ADDRESS_0);
10978 + hw.hw_addr = ioremap(mmio_start, mmio_len);
10980 + for(i = BAR_1; i <= BAR_5; i++) {
10981 + if(pci_bar_size(p, i) == 0)
10982 + continue;
10983 + if(pci_find_capability(p, i) & IORESOURCE_IO) {
10984 + hw.io_base = pci_bar_start(p, i);
10985 + break;
10986 + }
10989 + adjust_pci_device(p);
10991 + nic->ioaddr = p->ioaddr & ~3;
10992 + nic->irqno = 0;
10994 + /* From Matt Hortman <mbhortman@acpthinclient.com> */
10995 + /* MAC and Phy settings */
10997 + /* setup the private structure */
10998 + if (e1000_sw_init(p, &hw) < 0) {
10999 + iounmap(hw.hw_addr);
11000 + return 0;
11003 + /* make sure the EEPROM is good */
11005 + if (e1000_validate_eeprom_checksum(&hw) < 0) {
11006 + printf ("The EEPROM Checksum Is Not Valid\n");
11007 + iounmap(hw.hw_addr);
11008 + return 0;
11011 + /* copy the MAC address out of the EEPROM */
11013 + e1000_read_mac_addr(&hw);
11014 + memcpy (nic->node_addr, hw.mac_addr, ETH_ALEN);
11016 + printf("Ethernet addr: %!\n", nic->node_addr);
11018 + /* reset the hardware with the new settings */
11020 + ret_val = e1000_reset(&hw);
11021 + if (ret_val < 0) {
11022 + if ((ret_val == -E1000_ERR_NOLINK) ||
11023 + (ret_val == -E1000_ERR_TIMEOUT)) {
11024 + E1000_ERR("Valid Link not detected\n");
11025 + } else {
11026 + E1000_ERR("Hardware Initialization Failed\n");
11028 + iounmap(hw.hw_addr);
11029 + return 0;
11031 + init_descriptor();
11033 + /* point to NIC specific routines */
11034 + dev->disable = e1000_disable;
11035 + nic->poll = e1000_poll;
11036 + nic->transmit = e1000_transmit;
11037 + nic->irq = e1000_irq;
11039 + return 1;
11042 +static struct pci_id e1000_nics[] = {
11043 +PCI_ROM(0x8086, 0x1000, "e1000-82542", "Intel EtherExpressPro1000"),
11044 +PCI_ROM(0x8086, 0x1001, "e1000-82543gc-fiber", "Intel EtherExpressPro1000 82543GC Fiber"),
11045 +PCI_ROM(0x8086, 0x1004, "e1000-82543gc-copper", "Intel EtherExpressPro1000 82543GC Copper"),
11046 +PCI_ROM(0x8086, 0x1008, "e1000-82544ei-copper", "Intel EtherExpressPro1000 82544EI Copper"),
11047 +PCI_ROM(0x8086, 0x1009, "e1000-82544ei-fiber", "Intel EtherExpressPro1000 82544EI Fiber"),
11048 +PCI_ROM(0x8086, 0x100C, "e1000-82544gc-copper", "Intel EtherExpressPro1000 82544GC Copper"),
11049 +PCI_ROM(0x8086, 0x100D, "e1000-82544gc-lom", "Intel EtherExpressPro1000 82544GC LOM"),
11050 +PCI_ROM(0x8086, 0x100E, "e1000-82540em", "Intel EtherExpressPro1000 82540EM"),
11051 +PCI_ROM(0x8086, 0x100F, "e1000-82545em-copper", "Intel EtherExpressPro1000 82545EM Copper"),
11052 +PCI_ROM(0x8086, 0x1010, "e1000-82546eb-copper", "Intel EtherExpressPro1000 82546EB Copper"),
11053 +PCI_ROM(0x8086, 0x1011, "e1000-82545em-fiber", "Intel EtherExpressPro1000 82545EM Fiber"),
11054 +PCI_ROM(0x8086, 0x1012, "e1000-82546eb-fiber", "Intel EtherExpressPro1000 82546EB Copper"),
11055 +PCI_ROM(0x8086, 0x1013, "e1000-82541ei", "Intel EtherExpressPro1000 82541EI"),
11056 +PCI_ROM(0x8086, 0x1015, "e1000-82540em-lom", "Intel EtherExpressPro1000 82540EM LOM"),
11057 +PCI_ROM(0x8086, 0x1016, "e1000-82540ep-lom", "Intel EtherExpressPro1000 82540EP LOM"),
11058 +PCI_ROM(0x8086, 0x1017, "e1000-82540ep", "Intel EtherExpressPro1000 82540EP"),
11059 +PCI_ROM(0x8086, 0x1018, "e1000-82541ep", "Intel EtherExpressPro1000 82541EP"),
11060 +PCI_ROM(0x8086, 0x1019, "e1000-82547ei", "Intel EtherExpressPro1000 82547EI"),
11061 +PCI_ROM(0x8086, 0x101d, "e1000-82546eb-quad-copper", "Intel EtherExpressPro1000 82546EB Quad Copper"),
11062 +PCI_ROM(0x8086, 0x101e, "e1000-82540ep-lp", "Intel EtherExpressPro1000 82540EP LP"),
11063 +PCI_ROM(0x8086, 0x1026, "e1000-82545gm-copper", "Intel EtherExpressPro1000 82545GM Copper"),
11064 +PCI_ROM(0x8086, 0x1027, "e1000-82545gm-fiber", "Intel EtherExpressPro1000 82545GM Fiber"),
11065 +PCI_ROM(0x8086, 0x1028, "e1000-82545gm-serdes", "Intel EtherExpressPro1000 82545GM SERDES"),
11066 +PCI_ROM(0x8086, 0x1075, "e1000-82547gi", "Intel EtherExpressPro1000 82547GI"),
11067 +PCI_ROM(0x8086, 0x1076, "e1000-82541gi", "Intel EtherExpressPro1000 82541GI"),
11068 +PCI_ROM(0x8086, 0x1077, "e1000-82541gi-mobile", "Intel EtherExpressPro1000 82541GI Mobile"),
11069 +PCI_ROM(0x8086, 0x1078, "e1000-82541er", "Intel EtherExpressPro1000 82541ER"),
11070 +PCI_ROM(0x8086, 0x1079, "e1000-82546gb-copper", "Intel EtherExpressPro1000 82546GB Copper"),
11071 +PCI_ROM(0x8086, 0x107a, "e1000-82546gb-fiber", "Intel EtherExpressPro1000 82546GB Fiber"),
11072 +PCI_ROM(0x8086, 0x107b, "e1000-82546gb-serdes", "Intel EtherExpressPro1000 82546GB SERDES"),
11075 +struct pci_driver e1000_driver = {
11076 + .type = NIC_DRIVER,
11077 + .name = "E1000",
11078 + .probe = e1000_probe,
11079 + .ids = e1000_nics,
11080 + .id_count = sizeof(e1000_nics)/sizeof(e1000_nics[0]),
11081 + .class = 0,
11083 Index: b/netboot/e1000_hw.h
11084 ===================================================================
11085 --- /dev/null
11086 +++ b/netboot/e1000_hw.h
11087 @@ -0,0 +1,2058 @@
11088 +/*******************************************************************************
11091 + Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
11093 + This program is free software; you can redistribute it and/or modify it
11094 + under the terms of the GNU General Public License as published by the Free
11095 + Software Foundation; either version 2 of the License, or (at your option)
11096 + any later version.
11098 + This program is distributed in the hope that it will be useful, but WITHOUT
11099 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11100 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11101 + more details.
11103 + You should have received a copy of the GNU General Public License along with
11104 + this program; if not, write to the Free Software Foundation, Inc., 59
11105 + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
11107 + The full GNU General Public License is included in this distribution in the
11108 + file called LICENSE.
11110 + Contact Information:
11111 + Linux NICS <linux.nics@intel.com>
11112 + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
11114 +*******************************************************************************/
11116 +/* e1000_hw.h
11117 + * Structures, enums, and macros for the MAC
11118 + */
11120 +#ifndef _E1000_HW_H_
11121 +#define _E1000_HW_H_
11123 +/* Forward declarations of structures used by the shared code */
11124 +struct e1000_hw;
11125 +struct e1000_hw_stats;
11127 +/* Enumerated types specific to the e1000 hardware */
11128 +/* Media Access Controlers */
11129 +typedef enum {
11130 + e1000_undefined = 0,
11131 + e1000_82542_rev2_0,
11132 + e1000_82542_rev2_1,
11133 + e1000_82543,
11134 + e1000_82544,
11135 + e1000_82540,
11136 + e1000_82545,
11137 + e1000_82545_rev_3,
11138 + e1000_82546,
11139 + e1000_82546_rev_3,
11140 + e1000_82541,
11141 + e1000_82541_rev_2,
11142 + e1000_82547,
11143 + e1000_82547_rev_2,
11144 + e1000_num_macs
11145 +} e1000_mac_type;
11147 +typedef enum {
11148 + e1000_eeprom_uninitialized = 0,
11149 + e1000_eeprom_spi,
11150 + e1000_eeprom_microwire,
11151 + e1000_num_eeprom_types
11152 +} e1000_eeprom_type;
11154 +/* Media Types */
11155 +typedef enum {
11156 + e1000_media_type_copper = 0,
11157 + e1000_media_type_fiber = 1,
11158 + e1000_media_type_internal_serdes = 2,
11159 + e1000_num_media_types
11160 +} e1000_media_type;
11162 +typedef enum {
11163 + e1000_10_half = 0,
11164 + e1000_10_full = 1,
11165 + e1000_100_half = 2,
11166 + e1000_100_full = 3
11167 +} e1000_speed_duplex_type;
11169 +/* Flow Control Settings */
11170 +typedef enum {
11171 + e1000_fc_none = 0,
11172 + e1000_fc_rx_pause = 1,
11173 + e1000_fc_tx_pause = 2,
11174 + e1000_fc_full = 3,
11175 + e1000_fc_default = 0xFF
11176 +} e1000_fc_type;
11178 +/* PCI bus types */
11179 +typedef enum {
11180 + e1000_bus_type_unknown = 0,
11181 + e1000_bus_type_pci,
11182 + e1000_bus_type_pcix,
11183 + e1000_bus_type_reserved
11184 +} e1000_bus_type;
11186 +/* PCI bus speeds */
11187 +typedef enum {
11188 + e1000_bus_speed_unknown = 0,
11189 + e1000_bus_speed_33,
11190 + e1000_bus_speed_66,
11191 + e1000_bus_speed_100,
11192 + e1000_bus_speed_120,
11193 + e1000_bus_speed_133,
11194 + e1000_bus_speed_reserved
11195 +} e1000_bus_speed;
11197 +/* PCI bus widths */
11198 +typedef enum {
11199 + e1000_bus_width_unknown = 0,
11200 + e1000_bus_width_32,
11201 + e1000_bus_width_64,
11202 + e1000_bus_width_reserved
11203 +} e1000_bus_width;
11205 +/* PHY status info structure and supporting enums */
11206 +typedef enum {
11207 + e1000_cable_length_50 = 0,
11208 + e1000_cable_length_50_80,
11209 + e1000_cable_length_80_110,
11210 + e1000_cable_length_110_140,
11211 + e1000_cable_length_140,
11212 + e1000_cable_length_undefined = 0xFF
11213 +} e1000_cable_length;
11215 +typedef enum {
11216 + e1000_igp_cable_length_10 = 10,
11217 + e1000_igp_cable_length_20 = 20,
11218 + e1000_igp_cable_length_30 = 30,
11219 + e1000_igp_cable_length_40 = 40,
11220 + e1000_igp_cable_length_50 = 50,
11221 + e1000_igp_cable_length_60 = 60,
11222 + e1000_igp_cable_length_70 = 70,
11223 + e1000_igp_cable_length_80 = 80,
11224 + e1000_igp_cable_length_90 = 90,
11225 + e1000_igp_cable_length_100 = 100,
11226 + e1000_igp_cable_length_110 = 110,
11227 + e1000_igp_cable_length_120 = 120,
11228 + e1000_igp_cable_length_130 = 130,
11229 + e1000_igp_cable_length_140 = 140,
11230 + e1000_igp_cable_length_150 = 150,
11231 + e1000_igp_cable_length_160 = 160,
11232 + e1000_igp_cable_length_170 = 170,
11233 + e1000_igp_cable_length_180 = 180
11234 +} e1000_igp_cable_length;
11236 +typedef enum {
11237 + e1000_10bt_ext_dist_enable_normal = 0,
11238 + e1000_10bt_ext_dist_enable_lower,
11239 + e1000_10bt_ext_dist_enable_undefined = 0xFF
11240 +} e1000_10bt_ext_dist_enable;
11242 +typedef enum {
11243 + e1000_rev_polarity_normal = 0,
11244 + e1000_rev_polarity_reversed,
11245 + e1000_rev_polarity_undefined = 0xFF
11246 +} e1000_rev_polarity;
11248 +typedef enum {
11249 + e1000_downshift_normal = 0,
11250 + e1000_downshift_activated,
11251 + e1000_downshift_undefined = 0xFF
11252 +} e1000_downshift;
11254 +typedef enum {
11255 + e1000_polarity_reversal_enabled = 0,
11256 + e1000_polarity_reversal_disabled,
11257 + e1000_polarity_reversal_undefined = 0xFF
11258 +} e1000_polarity_reversal;
11260 +typedef enum {
11261 + e1000_auto_x_mode_manual_mdi = 0,
11262 + e1000_auto_x_mode_manual_mdix,
11263 + e1000_auto_x_mode_auto1,
11264 + e1000_auto_x_mode_auto2,
11265 + e1000_auto_x_mode_undefined = 0xFF
11266 +} e1000_auto_x_mode;
11268 +typedef enum {
11269 + e1000_1000t_rx_status_not_ok = 0,
11270 + e1000_1000t_rx_status_ok,
11271 + e1000_1000t_rx_status_undefined = 0xFF
11272 +} e1000_1000t_rx_status;
11274 +typedef enum {
11275 + e1000_phy_m88 = 0,
11276 + e1000_phy_igp,
11277 + e1000_phy_undefined = 0xFF
11278 +} e1000_phy_type;
11280 +typedef enum {
11281 + e1000_ms_hw_default = 0,
11282 + e1000_ms_force_master,
11283 + e1000_ms_force_slave,
11284 + e1000_ms_auto
11285 +} e1000_ms_type;
11287 +typedef enum {
11288 + e1000_ffe_config_enabled = 0,
11289 + e1000_ffe_config_active,
11290 + e1000_ffe_config_blocked
11291 +} e1000_ffe_config;
11293 +typedef enum {
11294 + e1000_dsp_config_disabled = 0,
11295 + e1000_dsp_config_enabled,
11296 + e1000_dsp_config_activated,
11297 + e1000_dsp_config_undefined = 0xFF
11298 +} e1000_dsp_config;
11300 +struct e1000_phy_info {
11301 + e1000_cable_length cable_length;
11302 + e1000_10bt_ext_dist_enable extended_10bt_distance;
11303 + e1000_rev_polarity cable_polarity;
11304 + e1000_downshift downshift;
11305 + e1000_polarity_reversal polarity_correction;
11306 + e1000_auto_x_mode mdix_mode;
11307 + e1000_1000t_rx_status local_rx;
11308 + e1000_1000t_rx_status remote_rx;
11311 +struct e1000_phy_stats {
11312 + uint32_t idle_errors;
11313 + uint32_t receive_errors;
11316 +struct e1000_eeprom_info {
11317 + e1000_eeprom_type type;
11318 + uint16_t word_size;
11319 + uint16_t opcode_bits;
11320 + uint16_t address_bits;
11321 + uint16_t delay_usec;
11322 + uint16_t page_size;
11327 +/* Error Codes */
11328 +#define E1000_SUCCESS 0
11329 +#define E1000_ERR_EEPROM 1
11330 +#define E1000_ERR_PHY 2
11331 +#define E1000_ERR_CONFIG 3
11332 +#define E1000_ERR_PARAM 4
11333 +#define E1000_ERR_MAC_TYPE 5
11334 +#define E1000_ERR_PHY_TYPE 6
11335 +#define E1000_ERR_NOLINK 7
11336 +#define E1000_ERR_TIMEOUT 8
11338 +#define E1000_READ_REG_IO(a, reg) \
11339 + e1000_read_reg_io((a), E1000_##reg)
11340 +#define E1000_WRITE_REG_IO(a, reg, val) \
11341 + e1000_write_reg_io((a), E1000_##reg, val)
11343 +/* PCI Device IDs */
11344 +#define E1000_DEV_ID_82542 0x1000
11345 +#define E1000_DEV_ID_82543GC_FIBER 0x1001
11346 +#define E1000_DEV_ID_82543GC_COPPER 0x1004
11347 +#define E1000_DEV_ID_82544EI_COPPER 0x1008
11348 +#define E1000_DEV_ID_82544EI_FIBER 0x1009
11349 +#define E1000_DEV_ID_82544GC_COPPER 0x100C
11350 +#define E1000_DEV_ID_82544GC_LOM 0x100D
11351 +#define E1000_DEV_ID_82540EM 0x100E
11352 +#define E1000_DEV_ID_82540EM_LOM 0x1015
11353 +#define E1000_DEV_ID_82540EP_LOM 0x1016
11354 +#define E1000_DEV_ID_82540EP 0x1017
11355 +#define E1000_DEV_ID_82540EP_LP 0x101E
11356 +#define E1000_DEV_ID_82545EM_COPPER 0x100F
11357 +#define E1000_DEV_ID_82545EM_FIBER 0x1011
11358 +#define E1000_DEV_ID_82545GM_COPPER 0x1026
11359 +#define E1000_DEV_ID_82545GM_FIBER 0x1027
11360 +#define E1000_DEV_ID_82545GM_SERDES 0x1028
11361 +#define E1000_DEV_ID_82546EB_COPPER 0x1010
11362 +#define E1000_DEV_ID_82546EB_FIBER 0x1012
11363 +#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
11364 +#define E1000_DEV_ID_82541EI 0x1013
11365 +#define E1000_DEV_ID_82541EI_MOBILE 0x1018
11366 +#define E1000_DEV_ID_82541ER 0x1078
11367 +#define E1000_DEV_ID_82547GI 0x1075
11368 +#define E1000_DEV_ID_82541GI 0x1076
11369 +#define E1000_DEV_ID_82541GI_MOBILE 0x1077
11370 +#define E1000_DEV_ID_82546GB_COPPER 0x1079
11371 +#define E1000_DEV_ID_82546GB_FIBER 0x107A
11372 +#define E1000_DEV_ID_82546GB_SERDES 0x107B
11373 +#define E1000_DEV_ID_82547EI 0x1019
11375 +#define NODE_ADDRESS_SIZE 6
11376 +#define ETH_LENGTH_OF_ADDRESS 6
11378 +/* MAC decode size is 128K - This is the size of BAR0 */
11379 +#define MAC_DECODE_SIZE (128 * 1024)
11381 +#define E1000_82542_2_0_REV_ID 2
11382 +#define E1000_82542_2_1_REV_ID 3
11384 +#define SPEED_10 10
11385 +#define SPEED_100 100
11386 +#define SPEED_1000 1000
11387 +#define HALF_DUPLEX 1
11388 +#define FULL_DUPLEX 2
11390 +/* The sizes (in bytes) of a ethernet packet */
11391 +#define ENET_HEADER_SIZE 14
11392 +#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* With FCS */
11393 +#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
11394 +#define ETHERNET_FCS_SIZE 4
11395 +#define MAXIMUM_ETHERNET_PACKET_SIZE \
11396 + (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
11397 +#define MINIMUM_ETHERNET_PACKET_SIZE \
11398 + (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
11399 +#define CRC_LENGTH ETHERNET_FCS_SIZE
11400 +#define MAX_JUMBO_FRAME_SIZE 0x3F00
11403 +/* 802.1q VLAN Packet Sizes */
11404 +#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */
11406 +/* Ethertype field values */
11407 +#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
11408 +#define ETHERNET_IP_TYPE 0x0800 /* IP packets */
11409 +#define ETHERNET_ARP_TYPE 0x0806 /* Address Resolution Protocol (ARP) */
11411 +/* Packet Header defines */
11412 +#define IP_PROTOCOL_TCP 6
11413 +#define IP_PROTOCOL_UDP 0x11
11415 +/* This defines the bits that are set in the Interrupt Mask
11416 + * Set/Read Register. Each bit is documented below:
11417 + * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
11418 + * o RXSEQ = Receive Sequence Error
11419 + */
11420 +#define POLL_IMS_ENABLE_MASK ( \
11421 + E1000_IMS_RXDMT0 | \
11422 + E1000_IMS_RXSEQ)
11424 +/* This defines the bits that are set in the Interrupt Mask
11425 + * Set/Read Register. Each bit is documented below:
11426 + * o RXT0 = Receiver Timer Interrupt (ring 0)
11427 + * o TXDW = Transmit Descriptor Written Back
11428 + * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
11429 + * o RXSEQ = Receive Sequence Error
11430 + * o LSC = Link Status Change
11431 + */
11432 +#define IMS_ENABLE_MASK ( \
11433 + E1000_IMS_RXT0 | \
11434 + E1000_IMS_TXDW | \
11435 + E1000_IMS_RXDMT0 | \
11436 + E1000_IMS_RXSEQ | \
11437 + E1000_IMS_LSC)
11439 +/* Number of high/low register pairs in the RAR. The RAR (Receive Address
11440 + * Registers) holds the directed and multicast addresses that we monitor. We
11441 + * reserve one of these spots for our directed address, allowing us room for
11442 + * E1000_RAR_ENTRIES - 1 multicast addresses.
11443 + */
11444 +#define E1000_RAR_ENTRIES 15
11446 +#define MIN_NUMBER_OF_DESCRIPTORS 8
11447 +#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
11449 +/* Receive Descriptor */
11450 +struct e1000_rx_desc {
11451 + uint64_t buffer_addr; /* Address of the descriptor's data buffer */
11452 + uint16_t length; /* Length of data DMAed into data buffer */
11453 + uint16_t csum; /* Packet checksum */
11454 + uint8_t status; /* Descriptor status */
11455 + uint8_t errors; /* Descriptor Errors */
11456 + uint16_t special;
11459 +/* Receive Decriptor bit definitions */
11460 +#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
11461 +#define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
11462 +#define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
11463 +#define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
11464 +#define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
11465 +#define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
11466 +#define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
11467 +#define E1000_RXD_ERR_CE 0x01 /* CRC Error */
11468 +#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
11469 +#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
11470 +#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */
11471 +#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */
11472 +#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */
11473 +#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
11474 +#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
11475 +#define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
11476 +#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
11477 +#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
11478 +#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */
11480 +/* mask to determine if packets should be dropped due to frame errors */
11481 +#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
11482 + E1000_RXD_ERR_CE | \
11483 + E1000_RXD_ERR_SE | \
11484 + E1000_RXD_ERR_SEQ | \
11485 + E1000_RXD_ERR_CXE | \
11486 + E1000_RXD_ERR_RXE)
11488 +/* Transmit Descriptor */
11489 +struct e1000_tx_desc {
11490 + uint64_t buffer_addr; /* Address of the descriptor's data buffer */
11491 + union {
11492 + uint32_t data;
11493 + struct {
11494 + uint16_t length; /* Data buffer length */
11495 + uint8_t cso; /* Checksum offset */
11496 + uint8_t cmd; /* Descriptor control */
11497 + } flags;
11498 + } lower;
11499 + union {
11500 + uint32_t data;
11501 + struct {
11502 + uint8_t status; /* Descriptor status */
11503 + uint8_t css; /* Checksum start */
11504 + uint16_t special;
11505 + } fields;
11506 + } upper;
11509 +/* Transmit Descriptor bit definitions */
11510 +#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */
11511 +#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */
11512 +#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */
11513 +#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */
11514 +#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */
11515 +#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
11516 +#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */
11517 +#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */
11518 +#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */
11519 +#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */
11520 +#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */
11521 +#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */
11522 +#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */
11523 +#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */
11524 +#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */
11525 +#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */
11526 +#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */
11527 +#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */
11528 +#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */
11529 +#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */
11531 +/* Offload Context Descriptor */
11532 +struct e1000_context_desc {
11533 + union {
11534 + uint32_t ip_config;
11535 + struct {
11536 + uint8_t ipcss; /* IP checksum start */
11537 + uint8_t ipcso; /* IP checksum offset */
11538 + uint16_t ipcse; /* IP checksum end */
11539 + } ip_fields;
11540 + } lower_setup;
11541 + union {
11542 + uint32_t tcp_config;
11543 + struct {
11544 + uint8_t tucss; /* TCP checksum start */
11545 + uint8_t tucso; /* TCP checksum offset */
11546 + uint16_t tucse; /* TCP checksum end */
11547 + } tcp_fields;
11548 + } upper_setup;
11549 + uint32_t cmd_and_length; /* */
11550 + union {
11551 + uint32_t data;
11552 + struct {
11553 + uint8_t status; /* Descriptor status */
11554 + uint8_t hdr_len; /* Header length */
11555 + uint16_t mss; /* Maximum segment size */
11556 + } fields;
11557 + } tcp_seg_setup;
11560 +/* Offload data descriptor */
11561 +struct e1000_data_desc {
11562 + uint64_t buffer_addr; /* Address of the descriptor's buffer address */
11563 + union {
11564 + uint32_t data;
11565 + struct {
11566 + uint16_t length; /* Data buffer length */
11567 + uint8_t typ_len_ext; /* */
11568 + uint8_t cmd; /* */
11569 + } flags;
11570 + } lower;
11571 + union {
11572 + uint32_t data;
11573 + struct {
11574 + uint8_t status; /* Descriptor status */
11575 + uint8_t popts; /* Packet Options */
11576 + uint16_t special; /* */
11577 + } fields;
11578 + } upper;
11581 +/* Filters */
11582 +#define E1000_NUM_UNICAST 16 /* Unicast filter entries */
11583 +#define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
11584 +#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
11587 +/* Receive Address Register */
11588 +struct e1000_rar {
11589 + volatile uint32_t low; /* receive address low */
11590 + volatile uint32_t high; /* receive address high */
11593 +/* Number of entries in the Multicast Table Array (MTA). */
11594 +#define E1000_NUM_MTA_REGISTERS 128
11596 +/* IPv4 Address Table Entry */
11597 +struct e1000_ipv4_at_entry {
11598 + volatile uint32_t ipv4_addr; /* IP Address (RW) */
11599 + volatile uint32_t reserved;
11602 +/* Four wakeup IP addresses are supported */
11603 +#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
11604 +#define E1000_IP4AT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
11605 +#define E1000_IP6AT_SIZE 1
11607 +/* IPv6 Address Table Entry */
11608 +struct e1000_ipv6_at_entry {
11609 + volatile uint8_t ipv6_addr[16];
11612 +/* Flexible Filter Length Table Entry */
11613 +struct e1000_fflt_entry {
11614 + volatile uint32_t length; /* Flexible Filter Length (RW) */
11615 + volatile uint32_t reserved;
11618 +/* Flexible Filter Mask Table Entry */
11619 +struct e1000_ffmt_entry {
11620 + volatile uint32_t mask; /* Flexible Filter Mask (RW) */
11621 + volatile uint32_t reserved;
11624 +/* Flexible Filter Value Table Entry */
11625 +struct e1000_ffvt_entry {
11626 + volatile uint32_t value; /* Flexible Filter Value (RW) */
11627 + volatile uint32_t reserved;
11630 +/* Four Flexible Filters are supported */
11631 +#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
11633 +/* Each Flexible Filter is at most 128 (0x80) bytes in length */
11634 +#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
11636 +#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
11637 +#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
11638 +#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
11640 +/* Register Set. (82543, 82544)
11642 + * Registers are defined to be 32 bits and should be accessed as 32 bit values.
11643 + * These registers are physically located on the NIC, but are mapped into the
11644 + * host memory address space.
11646 + * RW - register is both readable and writable
11647 + * RO - register is read only
11648 + * WO - register is write only
11649 + * R/clr - register is read only and is cleared when read
11650 + * A - register array
11651 + */
11652 +#define E1000_CTRL 0x00000 /* Device Control - RW */
11653 +#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */
11654 +#define E1000_STATUS 0x00008 /* Device Status - RO */
11655 +#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
11656 +#define E1000_EERD 0x00014 /* EEPROM Read - RW */
11657 +#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
11658 +#define E1000_FLA 0x0001C /* Flash Access - RW */
11659 +#define E1000_MDIC 0x00020 /* MDI Control - RW */
11660 +#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
11661 +#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
11662 +#define E1000_FCT 0x00030 /* Flow Control Type - RW */
11663 +#define E1000_VET 0x00038 /* VLAN Ether Type - RW */
11664 +#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */
11665 +#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */
11666 +#define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
11667 +#define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
11668 +#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
11669 +#define E1000_RCTL 0x00100 /* RX Control - RW */
11670 +#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
11671 +#define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
11672 +#define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
11673 +#define E1000_TCTL 0x00400 /* TX Control - RW */
11674 +#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
11675 +#define E1000_TBT 0x00448 /* TX Burst Timer - RW */
11676 +#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
11677 +#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
11678 +#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
11679 +#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
11680 +#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
11681 +#define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
11682 +#define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
11683 +#define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
11684 +#define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
11685 +#define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
11686 +#define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
11687 +#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
11688 +#define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
11689 +#define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
11690 +#define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
11691 +#define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
11692 +#define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
11693 +#define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
11694 +#define E1000_TDFTS 0x03428 /* TX Data FIFO Tail Saved - RW */
11695 +#define E1000_TDFPC 0x03430 /* TX Data FIFO Packet Count - RW */
11696 +#define E1000_TDBAL 0x03800 /* TX Descriptor Base Address Low - RW */
11697 +#define E1000_TDBAH 0x03804 /* TX Descriptor Base Address High - RW */
11698 +#define E1000_TDLEN 0x03808 /* TX Descriptor Length - RW */
11699 +#define E1000_TDH 0x03810 /* TX Descriptor Head - RW */
11700 +#define E1000_TDT 0x03818 /* TX Descripotr Tail - RW */
11701 +#define E1000_TIDV 0x03820 /* TX Interrupt Delay Value - RW */
11702 +#define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
11703 +#define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
11704 +#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
11705 +#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
11706 +#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
11707 +#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
11708 +#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */
11709 +#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */
11710 +#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */
11711 +#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */
11712 +#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */
11713 +#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */
11714 +#define E1000_COLC 0x04028 /* Collision Count - R/clr */
11715 +#define E1000_DC 0x04030 /* Defer Count - R/clr */
11716 +#define E1000_TNCRS 0x04034 /* TX-No CRS - R/clr */
11717 +#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */
11718 +#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */
11719 +#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */
11720 +#define E1000_XONRXC 0x04048 /* XON RX Count - R/clr */
11721 +#define E1000_XONTXC 0x0404C /* XON TX Count - R/clr */
11722 +#define E1000_XOFFRXC 0x04050 /* XOFF RX Count - R/clr */
11723 +#define E1000_XOFFTXC 0x04054 /* XOFF TX Count - R/clr */
11724 +#define E1000_FCRUC 0x04058 /* Flow Control RX Unsupported Count- R/clr */
11725 +#define E1000_PRC64 0x0405C /* Packets RX (64 bytes) - R/clr */
11726 +#define E1000_PRC127 0x04060 /* Packets RX (65-127 bytes) - R/clr */
11727 +#define E1000_PRC255 0x04064 /* Packets RX (128-255 bytes) - R/clr */
11728 +#define E1000_PRC511 0x04068 /* Packets RX (255-511 bytes) - R/clr */
11729 +#define E1000_PRC1023 0x0406C /* Packets RX (512-1023 bytes) - R/clr */
11730 +#define E1000_PRC1522 0x04070 /* Packets RX (1024-1522 bytes) - R/clr */
11731 +#define E1000_GPRC 0x04074 /* Good Packets RX Count - R/clr */
11732 +#define E1000_BPRC 0x04078 /* Broadcast Packets RX Count - R/clr */
11733 +#define E1000_MPRC 0x0407C /* Multicast Packets RX Count - R/clr */
11734 +#define E1000_GPTC 0x04080 /* Good Packets TX Count - R/clr */
11735 +#define E1000_GORCL 0x04088 /* Good Octets RX Count Low - R/clr */
11736 +#define E1000_GORCH 0x0408C /* Good Octets RX Count High - R/clr */
11737 +#define E1000_GOTCL 0x04090 /* Good Octets TX Count Low - R/clr */
11738 +#define E1000_GOTCH 0x04094 /* Good Octets TX Count High - R/clr */
11739 +#define E1000_RNBC 0x040A0 /* RX No Buffers Count - R/clr */
11740 +#define E1000_RUC 0x040A4 /* RX Undersize Count - R/clr */
11741 +#define E1000_RFC 0x040A8 /* RX Fragment Count - R/clr */
11742 +#define E1000_ROC 0x040AC /* RX Oversize Count - R/clr */
11743 +#define E1000_RJC 0x040B0 /* RX Jabber Count - R/clr */
11744 +#define E1000_MGTPRC 0x040B4 /* Management Packets RX Count - R/clr */
11745 +#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */
11746 +#define E1000_MGTPTC 0x040BC /* Management Packets TX Count - R/clr */
11747 +#define E1000_TORL 0x040C0 /* Total Octets RX Low - R/clr */
11748 +#define E1000_TORH 0x040C4 /* Total Octets RX High - R/clr */
11749 +#define E1000_TOTL 0x040C8 /* Total Octets TX Low - R/clr */
11750 +#define E1000_TOTH 0x040CC /* Total Octets TX High - R/clr */
11751 +#define E1000_TPR 0x040D0 /* Total Packets RX - R/clr */
11752 +#define E1000_TPT 0x040D4 /* Total Packets TX - R/clr */
11753 +#define E1000_PTC64 0x040D8 /* Packets TX (64 bytes) - R/clr */
11754 +#define E1000_PTC127 0x040DC /* Packets TX (65-127 bytes) - R/clr */
11755 +#define E1000_PTC255 0x040E0 /* Packets TX (128-255 bytes) - R/clr */
11756 +#define E1000_PTC511 0x040E4 /* Packets TX (256-511 bytes) - R/clr */
11757 +#define E1000_PTC1023 0x040E8 /* Packets TX (512-1023 bytes) - R/clr */
11758 +#define E1000_PTC1522 0x040EC /* Packets TX (1024-1522 Bytes) - R/clr */
11759 +#define E1000_MPTC 0x040F0 /* Multicast Packets TX Count - R/clr */
11760 +#define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
11761 +#define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
11762 +#define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
11763 +#define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
11764 +#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
11765 +#define E1000_RA 0x05400 /* Receive Address - RW Array */
11766 +#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
11767 +#define E1000_WUC 0x05800 /* Wakeup Control - RW */
11768 +#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */
11769 +#define E1000_WUS 0x05810 /* Wakeup Status - RO */
11770 +#define E1000_MANC 0x05820 /* Management Control - RW */
11771 +#define E1000_IPAV 0x05838 /* IP Address Valid - RW */
11772 +#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */
11773 +#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */
11774 +#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */
11775 +#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */
11776 +#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */
11777 +#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
11778 +#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
11780 +/* Register Set (82542)
11782 + * Some of the 82542 registers are located at different offsets than they are
11783 + * in more current versions of the 8254x. Despite the difference in location,
11784 + * the registers function in the same manner.
11785 + */
11786 +#define E1000_82542_CTRL E1000_CTRL
11787 +#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
11788 +#define E1000_82542_STATUS E1000_STATUS
11789 +#define E1000_82542_EECD E1000_EECD
11790 +#define E1000_82542_EERD E1000_EERD
11791 +#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
11792 +#define E1000_82542_FLA E1000_FLA
11793 +#define E1000_82542_MDIC E1000_MDIC
11794 +#define E1000_82542_FCAL E1000_FCAL
11795 +#define E1000_82542_FCAH E1000_FCAH
11796 +#define E1000_82542_FCT E1000_FCT
11797 +#define E1000_82542_VET E1000_VET
11798 +#define E1000_82542_RA 0x00040
11799 +#define E1000_82542_ICR E1000_ICR
11800 +#define E1000_82542_ITR E1000_ITR
11801 +#define E1000_82542_ICS E1000_ICS
11802 +#define E1000_82542_IMS E1000_IMS
11803 +#define E1000_82542_IMC E1000_IMC
11804 +#define E1000_82542_RCTL E1000_RCTL
11805 +#define E1000_82542_RDTR 0x00108
11806 +#define E1000_82542_RDBAL 0x00110
11807 +#define E1000_82542_RDBAH 0x00114
11808 +#define E1000_82542_RDLEN 0x00118
11809 +#define E1000_82542_RDH 0x00120
11810 +#define E1000_82542_RDT 0x00128
11811 +#define E1000_82542_FCRTH 0x00160
11812 +#define E1000_82542_FCRTL 0x00168
11813 +#define E1000_82542_FCTTV E1000_FCTTV
11814 +#define E1000_82542_TXCW E1000_TXCW
11815 +#define E1000_82542_RXCW E1000_RXCW
11816 +#define E1000_82542_MTA 0x00200
11817 +#define E1000_82542_TCTL E1000_TCTL
11818 +#define E1000_82542_TIPG E1000_TIPG
11819 +#define E1000_82542_TDBAL 0x00420
11820 +#define E1000_82542_TDBAH 0x00424
11821 +#define E1000_82542_TDLEN 0x00428
11822 +#define E1000_82542_TDH 0x00430
11823 +#define E1000_82542_TDT 0x00438
11824 +#define E1000_82542_TIDV 0x00440
11825 +#define E1000_82542_TBT E1000_TBT
11826 +#define E1000_82542_AIT E1000_AIT
11827 +#define E1000_82542_VFTA 0x00600
11828 +#define E1000_82542_LEDCTL E1000_LEDCTL
11829 +#define E1000_82542_PBA E1000_PBA
11830 +#define E1000_82542_RXDCTL E1000_RXDCTL
11831 +#define E1000_82542_RADV E1000_RADV
11832 +#define E1000_82542_RSRPD E1000_RSRPD
11833 +#define E1000_82542_TXDMAC E1000_TXDMAC
11834 +#define E1000_82542_TDFHS E1000_TDFHS
11835 +#define E1000_82542_TDFTS E1000_TDFTS
11836 +#define E1000_82542_TDFPC E1000_TDFPC
11837 +#define E1000_82542_TXDCTL E1000_TXDCTL
11838 +#define E1000_82542_TADV E1000_TADV
11839 +#define E1000_82542_TSPMT E1000_TSPMT
11840 +#define E1000_82542_CRCERRS E1000_CRCERRS
11841 +#define E1000_82542_ALGNERRC E1000_ALGNERRC
11842 +#define E1000_82542_SYMERRS E1000_SYMERRS
11843 +#define E1000_82542_RXERRC E1000_RXERRC
11844 +#define E1000_82542_MPC E1000_MPC
11845 +#define E1000_82542_SCC E1000_SCC
11846 +#define E1000_82542_ECOL E1000_ECOL
11847 +#define E1000_82542_MCC E1000_MCC
11848 +#define E1000_82542_LATECOL E1000_LATECOL
11849 +#define E1000_82542_COLC E1000_COLC
11850 +#define E1000_82542_DC E1000_DC
11851 +#define E1000_82542_TNCRS E1000_TNCRS
11852 +#define E1000_82542_SEC E1000_SEC
11853 +#define E1000_82542_CEXTERR E1000_CEXTERR
11854 +#define E1000_82542_RLEC E1000_RLEC
11855 +#define E1000_82542_XONRXC E1000_XONRXC
11856 +#define E1000_82542_XONTXC E1000_XONTXC
11857 +#define E1000_82542_XOFFRXC E1000_XOFFRXC
11858 +#define E1000_82542_XOFFTXC E1000_XOFFTXC
11859 +#define E1000_82542_FCRUC E1000_FCRUC
11860 +#define E1000_82542_PRC64 E1000_PRC64
11861 +#define E1000_82542_PRC127 E1000_PRC127
11862 +#define E1000_82542_PRC255 E1000_PRC255
11863 +#define E1000_82542_PRC511 E1000_PRC511
11864 +#define E1000_82542_PRC1023 E1000_PRC1023
11865 +#define E1000_82542_PRC1522 E1000_PRC1522
11866 +#define E1000_82542_GPRC E1000_GPRC
11867 +#define E1000_82542_BPRC E1000_BPRC
11868 +#define E1000_82542_MPRC E1000_MPRC
11869 +#define E1000_82542_GPTC E1000_GPTC
11870 +#define E1000_82542_GORCL E1000_GORCL
11871 +#define E1000_82542_GORCH E1000_GORCH
11872 +#define E1000_82542_GOTCL E1000_GOTCL
11873 +#define E1000_82542_GOTCH E1000_GOTCH
11874 +#define E1000_82542_RNBC E1000_RNBC
11875 +#define E1000_82542_RUC E1000_RUC
11876 +#define E1000_82542_RFC E1000_RFC
11877 +#define E1000_82542_ROC E1000_ROC
11878 +#define E1000_82542_RJC E1000_RJC
11879 +#define E1000_82542_MGTPRC E1000_MGTPRC
11880 +#define E1000_82542_MGTPDC E1000_MGTPDC
11881 +#define E1000_82542_MGTPTC E1000_MGTPTC
11882 +#define E1000_82542_TORL E1000_TORL
11883 +#define E1000_82542_TORH E1000_TORH
11884 +#define E1000_82542_TOTL E1000_TOTL
11885 +#define E1000_82542_TOTH E1000_TOTH
11886 +#define E1000_82542_TPR E1000_TPR
11887 +#define E1000_82542_TPT E1000_TPT
11888 +#define E1000_82542_PTC64 E1000_PTC64
11889 +#define E1000_82542_PTC127 E1000_PTC127
11890 +#define E1000_82542_PTC255 E1000_PTC255
11891 +#define E1000_82542_PTC511 E1000_PTC511
11892 +#define E1000_82542_PTC1023 E1000_PTC1023
11893 +#define E1000_82542_PTC1522 E1000_PTC1522
11894 +#define E1000_82542_MPTC E1000_MPTC
11895 +#define E1000_82542_BPTC E1000_BPTC
11896 +#define E1000_82542_TSCTC E1000_TSCTC
11897 +#define E1000_82542_TSCTFC E1000_TSCTFC
11898 +#define E1000_82542_RXCSUM E1000_RXCSUM
11899 +#define E1000_82542_WUC E1000_WUC
11900 +#define E1000_82542_WUFC E1000_WUFC
11901 +#define E1000_82542_WUS E1000_WUS
11902 +#define E1000_82542_MANC E1000_MANC
11903 +#define E1000_82542_IPAV E1000_IPAV
11904 +#define E1000_82542_IP4AT E1000_IP4AT
11905 +#define E1000_82542_IP6AT E1000_IP6AT
11906 +#define E1000_82542_WUPL E1000_WUPL
11907 +#define E1000_82542_WUPM E1000_WUPM
11908 +#define E1000_82542_FFLT E1000_FFLT
11909 +#define E1000_82542_TDFH 0x08010
11910 +#define E1000_82542_TDFT 0x08018
11911 +#define E1000_82542_FFMT E1000_FFMT
11912 +#define E1000_82542_FFVT E1000_FFVT
11914 +/* Statistics counters collected by the MAC */
11915 +struct e1000_hw_stats {
11916 + uint64_t crcerrs;
11917 + uint64_t algnerrc;
11918 + uint64_t symerrs;
11919 + uint64_t rxerrc;
11920 + uint64_t mpc;
11921 + uint64_t scc;
11922 + uint64_t ecol;
11923 + uint64_t mcc;
11924 + uint64_t latecol;
11925 + uint64_t colc;
11926 + uint64_t dc;
11927 + uint64_t tncrs;
11928 + uint64_t sec;
11929 + uint64_t cexterr;
11930 + uint64_t rlec;
11931 + uint64_t xonrxc;
11932 + uint64_t xontxc;
11933 + uint64_t xoffrxc;
11934 + uint64_t xofftxc;
11935 + uint64_t fcruc;
11936 + uint64_t prc64;
11937 + uint64_t prc127;
11938 + uint64_t prc255;
11939 + uint64_t prc511;
11940 + uint64_t prc1023;
11941 + uint64_t prc1522;
11942 + uint64_t gprc;
11943 + uint64_t bprc;
11944 + uint64_t mprc;
11945 + uint64_t gptc;
11946 + uint64_t gorcl;
11947 + uint64_t gorch;
11948 + uint64_t gotcl;
11949 + uint64_t gotch;
11950 + uint64_t rnbc;
11951 + uint64_t ruc;
11952 + uint64_t rfc;
11953 + uint64_t roc;
11954 + uint64_t rjc;
11955 + uint64_t mgprc;
11956 + uint64_t mgpdc;
11957 + uint64_t mgptc;
11958 + uint64_t torl;
11959 + uint64_t torh;
11960 + uint64_t totl;
11961 + uint64_t toth;
11962 + uint64_t tpr;
11963 + uint64_t tpt;
11964 + uint64_t ptc64;
11965 + uint64_t ptc127;
11966 + uint64_t ptc255;
11967 + uint64_t ptc511;
11968 + uint64_t ptc1023;
11969 + uint64_t ptc1522;
11970 + uint64_t mptc;
11971 + uint64_t bptc;
11972 + uint64_t tsctc;
11973 + uint64_t tsctfc;
11976 +/* Structure containing variables used by the shared code (e1000_hw.c) */
11977 +struct e1000_hw {
11978 + struct pci_device *pdev;
11979 + uint8_t *hw_addr;
11980 + e1000_mac_type mac_type;
11981 + e1000_phy_type phy_type;
11982 +#if 0
11983 + uint32_t phy_init_script;
11984 +#endif
11985 + e1000_media_type media_type;
11986 + e1000_fc_type fc;
11987 +#if 0
11988 + e1000_bus_speed bus_speed;
11989 + e1000_bus_width bus_width;
11990 + e1000_bus_type bus_type;
11991 +#endif
11992 + struct e1000_eeprom_info eeprom;
11993 +#if 0
11994 + e1000_ms_type master_slave;
11995 + e1000_ms_type original_master_slave;
11996 + e1000_ffe_config ffe_config_state;
11997 +#endif
11998 + uint32_t io_base;
11999 + uint32_t phy_id;
12000 +#ifdef LINUX_DRIVER
12001 + uint32_t phy_revision;
12002 +#endif
12003 + uint32_t phy_addr;
12004 +#if 0
12005 + uint32_t original_fc;
12006 +#endif
12007 + uint32_t txcw;
12008 + uint32_t autoneg_failed;
12009 +#if 0
12010 + uint32_t max_frame_size;
12011 + uint32_t min_frame_size;
12012 + uint32_t mc_filter_type;
12013 + uint32_t num_mc_addrs;
12014 + uint32_t collision_delta;
12015 + uint32_t tx_packet_delta;
12016 + uint32_t ledctl_default;
12017 + uint32_t ledctl_mode1;
12018 + uint32_t ledctl_mode2;
12019 + uint16_t phy_spd_default;
12020 +#endif
12021 + uint16_t autoneg_advertised;
12022 + uint16_t pci_cmd_word;
12023 +#if 0
12024 + uint16_t fc_high_water;
12025 + uint16_t fc_low_water;
12026 + uint16_t fc_pause_time;
12027 + uint16_t current_ifs_val;
12028 + uint16_t ifs_min_val;
12029 + uint16_t ifs_max_val;
12030 + uint16_t ifs_step_size;
12031 + uint16_t ifs_ratio;
12032 +#endif
12033 + uint16_t device_id;
12034 + uint16_t vendor_id;
12035 +#if 0
12036 + uint16_t subsystem_id;
12037 + uint16_t subsystem_vendor_id;
12038 +#endif
12039 + uint8_t revision_id;
12040 +#if 0
12041 + uint8_t autoneg;
12042 + uint8_t mdix;
12043 + uint8_t forced_speed_duplex;
12044 + uint8_t wait_autoneg_complete;
12045 + uint8_t dma_fairness;
12046 +#endif
12047 + uint8_t mac_addr[NODE_ADDRESS_SIZE];
12048 +#if 0
12049 + uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
12050 + boolean_t disable_polarity_correction;
12051 + boolean_t speed_downgraded;
12052 + e1000_dsp_config dsp_config_state;
12053 + boolean_t get_link_status;
12054 + boolean_t serdes_link_down;
12055 +#endif
12056 + boolean_t tbi_compatibility_en;
12057 + boolean_t tbi_compatibility_on;
12058 +#if 0
12059 + boolean_t phy_reset_disable;
12060 + boolean_t fc_send_xon;
12061 + boolean_t fc_strict_ieee;
12062 + boolean_t report_tx_early;
12063 + boolean_t adaptive_ifs;
12064 + boolean_t ifs_params_forced;
12065 + boolean_t in_ifs_mode;
12066 +#endif
12070 +#define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
12071 +#define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
12073 +/* Register Bit Masks */
12074 +/* Device Control */
12075 +#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
12076 +#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
12077 +#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
12078 +#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
12079 +#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
12080 +#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
12081 +#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
12082 +#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
12083 +#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
12084 +#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */
12085 +#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */
12086 +#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */
12087 +#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */
12088 +#define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
12089 +#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
12090 +#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
12091 +#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
12092 +#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
12093 +#define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
12094 +#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */
12095 +#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
12096 +#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */
12097 +#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
12098 +#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
12099 +#define E1000_CTRL_RST 0x04000000 /* Global reset */
12100 +#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
12101 +#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
12102 +#define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
12103 +#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
12104 +#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
12106 +/* Device Status */
12107 +#define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
12108 +#define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
12109 +#define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
12110 +#define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
12111 +#define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
12112 +#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
12113 +#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */
12114 +#define E1000_STATUS_SPEED_MASK 0x000000C0
12115 +#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
12116 +#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
12117 +#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
12118 +#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
12119 +#define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
12120 +#define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
12121 +#define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
12122 +#define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
12123 +#define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
12125 +/* Constants used to intrepret the masked PCI-X bus speed. */
12126 +#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
12127 +#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
12128 +#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
12130 +/* EEPROM/Flash Control */
12131 +#define E1000_EECD_SK 0x00000001 /* EEPROM Clock */
12132 +#define E1000_EECD_CS 0x00000002 /* EEPROM Chip Select */
12133 +#define E1000_EECD_DI 0x00000004 /* EEPROM Data In */
12134 +#define E1000_EECD_DO 0x00000008 /* EEPROM Data Out */
12135 +#define E1000_EECD_FWE_MASK 0x00000030
12136 +#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */
12137 +#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */
12138 +#define E1000_EECD_FWE_SHIFT 4
12139 +#define E1000_EECD_REQ 0x00000040 /* EEPROM Access Request */
12140 +#define E1000_EECD_GNT 0x00000080 /* EEPROM Access Grant */
12141 +#define E1000_EECD_PRES 0x00000100 /* EEPROM Present */
12142 +#define E1000_EECD_SIZE 0x00000200 /* EEPROM Size (0=64 word 1=256 word) */
12143 +#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
12144 + * (0-small, 1-large) */
12145 +#define E1000_EECD_TYPE 0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
12146 +#ifndef E1000_EEPROM_GRANT_ATTEMPTS
12147 +#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
12148 +#endif
12150 +/* EEPROM Read */
12151 +#define E1000_EERD_START 0x00000001 /* Start Read */
12152 +#define E1000_EERD_DONE 0x00000010 /* Read Done */
12153 +#define E1000_EERD_ADDR_SHIFT 8
12154 +#define E1000_EERD_ADDR_MASK 0x0000FF00 /* Read Address */
12155 +#define E1000_EERD_DATA_SHIFT 16
12156 +#define E1000_EERD_DATA_MASK 0xFFFF0000 /* Read Data */
12158 +/* SPI EEPROM Status Register */
12159 +#define EEPROM_STATUS_RDY_SPI 0x01
12160 +#define EEPROM_STATUS_WEN_SPI 0x02
12161 +#define EEPROM_STATUS_BP0_SPI 0x04
12162 +#define EEPROM_STATUS_BP1_SPI 0x08
12163 +#define EEPROM_STATUS_WPEN_SPI 0x80
12165 +/* Extended Device Control */
12166 +#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */
12167 +#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */
12168 +#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
12169 +#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */
12170 +#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */
12171 +#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
12172 +#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
12173 +#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA
12174 +#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
12175 +#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
12176 +#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */
12177 +#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */
12178 +#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */
12179 +#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */
12180 +#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */
12181 +#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
12182 +#define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */
12183 +#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
12184 +#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
12185 +#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
12186 +#define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
12187 +#define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
12188 +#define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
12189 +#define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
12190 +#define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
12191 +#define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
12193 +/* MDI Control */
12194 +#define E1000_MDIC_DATA_MASK 0x0000FFFF
12195 +#define E1000_MDIC_REG_MASK 0x001F0000
12196 +#define E1000_MDIC_REG_SHIFT 16
12197 +#define E1000_MDIC_PHY_MASK 0x03E00000
12198 +#define E1000_MDIC_PHY_SHIFT 21
12199 +#define E1000_MDIC_OP_WRITE 0x04000000
12200 +#define E1000_MDIC_OP_READ 0x08000000
12201 +#define E1000_MDIC_READY 0x10000000
12202 +#define E1000_MDIC_INT_EN 0x20000000
12203 +#define E1000_MDIC_ERROR 0x40000000
12205 +/* LED Control */
12206 +#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
12207 +#define E1000_LEDCTL_LED0_MODE_SHIFT 0
12208 +#define E1000_LEDCTL_LED0_IVRT 0x00000040
12209 +#define E1000_LEDCTL_LED0_BLINK 0x00000080
12210 +#define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
12211 +#define E1000_LEDCTL_LED1_MODE_SHIFT 8
12212 +#define E1000_LEDCTL_LED1_IVRT 0x00004000
12213 +#define E1000_LEDCTL_LED1_BLINK 0x00008000
12214 +#define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
12215 +#define E1000_LEDCTL_LED2_MODE_SHIFT 16
12216 +#define E1000_LEDCTL_LED2_IVRT 0x00400000
12217 +#define E1000_LEDCTL_LED2_BLINK 0x00800000
12218 +#define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
12219 +#define E1000_LEDCTL_LED3_MODE_SHIFT 24
12220 +#define E1000_LEDCTL_LED3_IVRT 0x40000000
12221 +#define E1000_LEDCTL_LED3_BLINK 0x80000000
12223 +#define E1000_LEDCTL_MODE_LINK_10_1000 0x0
12224 +#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
12225 +#define E1000_LEDCTL_MODE_LINK_UP 0x2
12226 +#define E1000_LEDCTL_MODE_ACTIVITY 0x3
12227 +#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
12228 +#define E1000_LEDCTL_MODE_LINK_10 0x5
12229 +#define E1000_LEDCTL_MODE_LINK_100 0x6
12230 +#define E1000_LEDCTL_MODE_LINK_1000 0x7
12231 +#define E1000_LEDCTL_MODE_PCIX_MODE 0x8
12232 +#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9
12233 +#define E1000_LEDCTL_MODE_COLLISION 0xA
12234 +#define E1000_LEDCTL_MODE_BUS_SPEED 0xB
12235 +#define E1000_LEDCTL_MODE_BUS_SIZE 0xC
12236 +#define E1000_LEDCTL_MODE_PAUSED 0xD
12237 +#define E1000_LEDCTL_MODE_LED_ON 0xE
12238 +#define E1000_LEDCTL_MODE_LED_OFF 0xF
12240 +/* Receive Address */
12241 +#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
12243 +/* Interrupt Cause Read */
12244 +#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
12245 +#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
12246 +#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
12247 +#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
12248 +#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
12249 +#define E1000_ICR_RXO 0x00000040 /* rx overrun */
12250 +#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
12251 +#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */
12252 +#define E1000_ICR_RXCFG 0x00000400 /* RX /c/ ordered set */
12253 +#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */
12254 +#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */
12255 +#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */
12256 +#define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
12257 +#define E1000_ICR_TXD_LOW 0x00008000
12258 +#define E1000_ICR_SRPD 0x00010000
12260 +/* Interrupt Cause Set */
12261 +#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
12262 +#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
12263 +#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
12264 +#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
12265 +#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
12266 +#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */
12267 +#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
12268 +#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */
12269 +#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
12270 +#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
12271 +#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
12272 +#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
12273 +#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
12274 +#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
12275 +#define E1000_ICS_SRPD E1000_ICR_SRPD
12277 +/* Interrupt Mask Set */
12278 +#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
12279 +#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
12280 +#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
12281 +#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
12282 +#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
12283 +#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */
12284 +#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
12285 +#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */
12286 +#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
12287 +#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
12288 +#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
12289 +#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
12290 +#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
12291 +#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
12292 +#define E1000_IMS_SRPD E1000_ICR_SRPD
12294 +/* Interrupt Mask Clear */
12295 +#define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
12296 +#define E1000_IMC_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
12297 +#define E1000_IMC_LSC E1000_ICR_LSC /* Link Status Change */
12298 +#define E1000_IMC_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
12299 +#define E1000_IMC_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
12300 +#define E1000_IMC_RXO E1000_ICR_RXO /* rx overrun */
12301 +#define E1000_IMC_RXT0 E1000_ICR_RXT0 /* rx timer intr */
12302 +#define E1000_IMC_MDAC E1000_ICR_MDAC /* MDIO access complete */
12303 +#define E1000_IMC_RXCFG E1000_ICR_RXCFG /* RX /c/ ordered set */
12304 +#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */
12305 +#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */
12306 +#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */
12307 +#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
12308 +#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
12309 +#define E1000_IMC_SRPD E1000_ICR_SRPD
12311 +/* Receive Control */
12312 +#define E1000_RCTL_RST 0x00000001 /* Software reset */
12313 +#define E1000_RCTL_EN 0x00000002 /* enable */
12314 +#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
12315 +#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
12316 +#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
12317 +#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
12318 +#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
12319 +#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
12320 +#define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
12321 +#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
12322 +#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
12323 +#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
12324 +#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
12325 +#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
12326 +#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
12327 +#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
12328 +#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */
12329 +#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */
12330 +#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */
12331 +#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */
12332 +/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
12333 +#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */
12334 +#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */
12335 +#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */
12336 +#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */
12337 +/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
12338 +#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */
12339 +#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */
12340 +#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */
12341 +#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */
12342 +#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */
12343 +#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */
12344 +#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */
12345 +#define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
12346 +#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
12348 +/* Receive Descriptor */
12349 +#define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
12350 +#define E1000_RDT_FPDB 0x80000000 /* Flush descriptor block */
12351 +#define E1000_RDLEN_LEN 0x0007ff80 /* descriptor length */
12352 +#define E1000_RDH_RDH 0x0000ffff /* receive descriptor head */
12353 +#define E1000_RDT_RDT 0x0000ffff /* receive descriptor tail */
12355 +/* Flow Control */
12356 +#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */
12357 +#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */
12358 +#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
12359 +#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
12361 +/* Receive Descriptor Control */
12362 +#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
12363 +#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
12364 +#define E1000_RXDCTL_WTHRESH 0x003F0000 /* RXDCTL Writeback Threshold */
12365 +#define E1000_RXDCTL_GRAN 0x01000000 /* RXDCTL Granularity */
12367 +/* Transmit Descriptor Control */
12368 +#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */
12369 +#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */
12370 +#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */
12371 +#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
12372 +#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
12373 +#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
12375 +/* Transmit Configuration Word */
12376 +#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
12377 +#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */
12378 +#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */
12379 +#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */
12380 +#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */
12381 +#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */
12382 +#define E1000_TXCW_NP 0x00008000 /* TXCW next page */
12383 +#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */
12384 +#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */
12385 +#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */
12387 +/* Receive Configuration Word */
12388 +#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */
12389 +#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */
12390 +#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */
12391 +#define E1000_RXCW_CC 0x10000000 /* Receive config change */
12392 +#define E1000_RXCW_C 0x20000000 /* Receive config */
12393 +#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
12394 +#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */
12396 +/* Transmit Control */
12397 +#define E1000_TCTL_RST 0x00000001 /* software reset */
12398 +#define E1000_TCTL_EN 0x00000002 /* enable tx */
12399 +#define E1000_TCTL_BCE 0x00000004 /* busy check enable */
12400 +#define E1000_TCTL_PSP 0x00000008 /* pad short packets */
12401 +#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */
12402 +#define E1000_TCTL_COLD 0x003ff000 /* collision distance */
12403 +#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */
12404 +#define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
12405 +#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
12406 +#define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
12408 +/* Receive Checksum Control */
12409 +#define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */
12410 +#define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
12411 +#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
12412 +#define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */
12414 +/* Definitions for power management and wakeup registers */
12415 +/* Wake Up Control */
12416 +#define E1000_WUC_APME 0x00000001 /* APM Enable */
12417 +#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */
12418 +#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
12419 +#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */
12420 +#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
12422 +/* Wake Up Filter Control */
12423 +#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
12424 +#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
12425 +#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
12426 +#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */
12427 +#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
12428 +#define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
12429 +#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
12430 +#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
12431 +#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
12432 +#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
12433 +#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
12434 +#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
12435 +#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
12436 +#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
12437 +#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
12439 +/* Wake Up Status */
12440 +#define E1000_WUS_LNKC 0x00000001 /* Link Status Changed */
12441 +#define E1000_WUS_MAG 0x00000002 /* Magic Packet Received */
12442 +#define E1000_WUS_EX 0x00000004 /* Directed Exact Received */
12443 +#define E1000_WUS_MC 0x00000008 /* Directed Multicast Received */
12444 +#define E1000_WUS_BC 0x00000010 /* Broadcast Received */
12445 +#define E1000_WUS_ARP 0x00000020 /* ARP Request Packet Received */
12446 +#define E1000_WUS_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Received */
12447 +#define E1000_WUS_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Received */
12448 +#define E1000_WUS_FLX0 0x00010000 /* Flexible Filter 0 Match */
12449 +#define E1000_WUS_FLX1 0x00020000 /* Flexible Filter 1 Match */
12450 +#define E1000_WUS_FLX2 0x00040000 /* Flexible Filter 2 Match */
12451 +#define E1000_WUS_FLX3 0x00080000 /* Flexible Filter 3 Match */
12452 +#define E1000_WUS_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
12454 +/* Management Control */
12455 +#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
12456 +#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
12457 +#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */
12458 +#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */
12459 +#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */
12460 +#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */
12461 +#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */
12462 +#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */
12463 +#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
12464 +#define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
12465 + * Filtering */
12466 +#define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
12467 +#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
12468 +#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
12469 +#define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
12470 +#define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
12471 +#define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
12472 +#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */
12473 +#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */
12474 +#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */
12476 +#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
12477 +#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
12479 +/* Wake Up Packet Length */
12480 +#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
12482 +#define E1000_MDALIGN 4096
12484 +/* EEPROM Commands - Microwire */
12485 +#define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
12486 +#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
12487 +#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7 /* EEPROM erase opcode */
12488 +#define EEPROM_EWEN_OPCODE_MICROWIRE 0x13 /* EEPROM erase/write enable */
12489 +#define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
12491 +/* EEPROM Commands - SPI */
12492 +#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
12493 +#define EEPROM_READ_OPCODE_SPI 0x3 /* EEPROM read opcode */
12494 +#define EEPROM_WRITE_OPCODE_SPI 0x2 /* EEPROM write opcode */
12495 +#define EEPROM_A8_OPCODE_SPI 0x8 /* opcode bit-3 = address bit-8 */
12496 +#define EEPROM_WREN_OPCODE_SPI 0x6 /* EEPROM set Write Enable latch */
12497 +#define EEPROM_WRDI_OPCODE_SPI 0x4 /* EEPROM reset Write Enable latch */
12498 +#define EEPROM_RDSR_OPCODE_SPI 0x5 /* EEPROM read Status register */
12499 +#define EEPROM_WRSR_OPCODE_SPI 0x1 /* EEPROM write Status register */
12501 +/* EEPROM Size definitions */
12502 +#define EEPROM_SIZE_16KB 0x1800
12503 +#define EEPROM_SIZE_8KB 0x1400
12504 +#define EEPROM_SIZE_4KB 0x1000
12505 +#define EEPROM_SIZE_2KB 0x0C00
12506 +#define EEPROM_SIZE_1KB 0x0800
12507 +#define EEPROM_SIZE_512B 0x0400
12508 +#define EEPROM_SIZE_128B 0x0000
12509 +#define EEPROM_SIZE_MASK 0x1C00
12511 +/* EEPROM Word Offsets */
12512 +#define EEPROM_COMPAT 0x0003
12513 +#define EEPROM_ID_LED_SETTINGS 0x0004
12514 +#define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
12515 +#define EEPROM_INIT_CONTROL1_REG 0x000A
12516 +#define EEPROM_INIT_CONTROL2_REG 0x000F
12517 +#define EEPROM_INIT_CONTROL3_PORT_B 0x0014
12518 +#define EEPROM_INIT_CONTROL3_PORT_A 0x0024
12519 +#define EEPROM_CFG 0x0012
12520 +#define EEPROM_FLASH_VERSION 0x0032
12521 +#define EEPROM_CHECKSUM_REG 0x003F
12523 +/* Word definitions for ID LED Settings */
12524 +#define ID_LED_RESERVED_0000 0x0000
12525 +#define ID_LED_RESERVED_FFFF 0xFFFF
12526 +#define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
12527 + (ID_LED_OFF1_OFF2 << 8) | \
12528 + (ID_LED_DEF1_DEF2 << 4) | \
12529 + (ID_LED_DEF1_DEF2))
12530 +#define ID_LED_DEF1_DEF2 0x1
12531 +#define ID_LED_DEF1_ON2 0x2
12532 +#define ID_LED_DEF1_OFF2 0x3
12533 +#define ID_LED_ON1_DEF2 0x4
12534 +#define ID_LED_ON1_ON2 0x5
12535 +#define ID_LED_ON1_OFF2 0x6
12536 +#define ID_LED_OFF1_DEF2 0x7
12537 +#define ID_LED_OFF1_ON2 0x8
12538 +#define ID_LED_OFF1_OFF2 0x9
12540 +#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF
12541 +#define IGP_ACTIVITY_LED_ENABLE 0x0300
12542 +#define IGP_LED3_MODE 0x07000000
12545 +/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
12546 +#define EEPROM_SERDES_AMPLITUDE_MASK 0x000F
12548 +/* Mask bits for fields in Word 0x0a of the EEPROM */
12549 +#define EEPROM_WORD0A_ILOS 0x0010
12550 +#define EEPROM_WORD0A_SWDPIO 0x01E0
12551 +#define EEPROM_WORD0A_LRST 0x0200
12552 +#define EEPROM_WORD0A_FD 0x0400
12553 +#define EEPROM_WORD0A_66MHZ 0x0800
12555 +/* Mask bits for fields in Word 0x0f of the EEPROM */
12556 +#define EEPROM_WORD0F_PAUSE_MASK 0x3000
12557 +#define EEPROM_WORD0F_PAUSE 0x1000
12558 +#define EEPROM_WORD0F_ASM_DIR 0x2000
12559 +#define EEPROM_WORD0F_ANE 0x0800
12560 +#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
12562 +/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
12563 +#define EEPROM_SUM 0xBABA
12565 +/* EEPROM Map defines (WORD OFFSETS)*/
12566 +#define EEPROM_NODE_ADDRESS_BYTE_0 0
12567 +#define EEPROM_PBA_BYTE_1 8
12569 +#define EEPROM_RESERVED_WORD 0xFFFF
12571 +/* EEPROM Map Sizes (Byte Counts) */
12572 +#define PBA_SIZE 4
12574 +/* Collision related configuration parameters */
12575 +#define E1000_COLLISION_THRESHOLD 16
12576 +#define E1000_CT_SHIFT 4
12577 +#define E1000_COLLISION_DISTANCE 64
12578 +#define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
12579 +#define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
12580 +#define E1000_COLD_SHIFT 12
12582 +/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
12583 +#define REQ_TX_DESCRIPTOR_MULTIPLE 8
12584 +#define REQ_RX_DESCRIPTOR_MULTIPLE 8
12586 +/* Default values for the transmit IPG register */
12587 +#define DEFAULT_82542_TIPG_IPGT 10
12588 +#define DEFAULT_82543_TIPG_IPGT_FIBER 9
12589 +#define DEFAULT_82543_TIPG_IPGT_COPPER 8
12591 +#define E1000_TIPG_IPGT_MASK 0x000003FF
12592 +#define E1000_TIPG_IPGR1_MASK 0x000FFC00
12593 +#define E1000_TIPG_IPGR2_MASK 0x3FF00000
12595 +#define DEFAULT_82542_TIPG_IPGR1 2
12596 +#define DEFAULT_82543_TIPG_IPGR1 8
12597 +#define E1000_TIPG_IPGR1_SHIFT 10
12599 +#define DEFAULT_82542_TIPG_IPGR2 10
12600 +#define DEFAULT_82543_TIPG_IPGR2 6
12601 +#define E1000_TIPG_IPGR2_SHIFT 20
12603 +#define E1000_TXDMAC_DPP 0x00000001
12605 +/* Adaptive IFS defines */
12606 +#define TX_THRESHOLD_START 8
12607 +#define TX_THRESHOLD_INCREMENT 10
12608 +#define TX_THRESHOLD_DECREMENT 1
12609 +#define TX_THRESHOLD_STOP 190
12610 +#define TX_THRESHOLD_DISABLE 0
12611 +#define TX_THRESHOLD_TIMER_MS 10000
12612 +#define MIN_NUM_XMITS 1000
12613 +#define IFS_MAX 80
12614 +#define IFS_STEP 10
12615 +#define IFS_MIN 40
12616 +#define IFS_RATIO 4
12618 +/* PBA constants */
12619 +#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
12620 +#define E1000_PBA_22K 0x0016
12621 +#define E1000_PBA_24K 0x0018
12622 +#define E1000_PBA_30K 0x001E
12623 +#define E1000_PBA_40K 0x0028
12624 +#define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
12626 +/* Flow Control Constants */
12627 +#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
12628 +#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
12629 +#define FLOW_CONTROL_TYPE 0x8808
12631 +/* The historical defaults for the flow control values are given below. */
12632 +#define FC_DEFAULT_HI_THRESH (0x8000) /* 32KB */
12633 +#define FC_DEFAULT_LO_THRESH (0x4000) /* 16KB */
12634 +#define FC_DEFAULT_TX_TIMER (0x100) /* ~130 us */
12636 +/* PCIX Config space */
12637 +#define PCIX_COMMAND_REGISTER 0xE6
12638 +#define PCIX_STATUS_REGISTER_LO 0xE8
12639 +#define PCIX_STATUS_REGISTER_HI 0xEA
12641 +#define PCIX_COMMAND_MMRBC_MASK 0x000C
12642 +#define PCIX_COMMAND_MMRBC_SHIFT 0x2
12643 +#define PCIX_STATUS_HI_MMRBC_MASK 0x0060
12644 +#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5
12645 +#define PCIX_STATUS_HI_MMRBC_4K 0x3
12646 +#define PCIX_STATUS_HI_MMRBC_2K 0x2
12649 +/* Number of bits required to shift right the "pause" bits from the
12650 + * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
12651 + */
12652 +#define PAUSE_SHIFT 5
12654 +/* Number of bits required to shift left the "SWDPIO" bits from the
12655 + * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
12656 + */
12657 +#define SWDPIO_SHIFT 17
12659 +/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
12660 + * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
12661 + */
12662 +#define SWDPIO__EXT_SHIFT 4
12664 +/* Number of bits required to shift left the "ILOS" bit from the EEPROM
12665 + * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
12666 + */
12667 +#define ILOS_SHIFT 3
12670 +#define RECEIVE_BUFFER_ALIGN_SIZE (256)
12672 +/* Number of milliseconds we wait for auto-negotiation to complete */
12673 +#define LINK_UP_TIMEOUT 500
12675 +#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
12677 +/* The carrier extension symbol, as received by the NIC. */
12678 +#define CARRIER_EXTENSION 0x0F
12680 +/* TBI_ACCEPT macro definition:
12682 + * This macro requires:
12683 + * adapter = a pointer to struct e1000_hw
12684 + * status = the 8 bit status field of the RX descriptor with EOP set
12685 + * error = the 8 bit error field of the RX descriptor with EOP set
12686 + * length = the sum of all the length fields of the RX descriptors that
12687 + * make up the current frame
12688 + * last_byte = the last byte of the frame DMAed by the hardware
12689 + * max_frame_length = the maximum frame length we want to accept.
12690 + * min_frame_length = the minimum frame length we want to accept.
12692 + * This macro is a conditional that should be used in the interrupt
12693 + * handler's Rx processing routine when RxErrors have been detected.
12695 + * Typical use:
12696 + * ...
12697 + * if (TBI_ACCEPT) {
12698 + * accept_frame = TRUE;
12699 + * e1000_tbi_adjust_stats(adapter, MacAddress);
12700 + * frame_length--;
12701 + * } else {
12702 + * accept_frame = FALSE;
12703 + * }
12704 + * ...
12705 + */
12707 +#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
12708 + ((adapter)->tbi_compatibility_on && \
12709 + (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
12710 + ((last_byte) == CARRIER_EXTENSION) && \
12711 + (((status) & E1000_RXD_STAT_VP) ? \
12712 + (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
12713 + ((length) <= ((adapter)->max_frame_size + 1))) : \
12714 + (((length) > (adapter)->min_frame_size) && \
12715 + ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
12718 +/* Structures, enums, and macros for the PHY */
12720 +/* Bit definitions for the Management Data IO (MDIO) and Management Data
12721 + * Clock (MDC) pins in the Device Control Register.
12722 + */
12723 +#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0
12724 +#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0
12725 +#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2
12726 +#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2
12727 +#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3
12728 +#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3
12729 +#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
12730 +#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA
12732 +/* PHY 1000 MII Register/Bit Definitions */
12733 +/* PHY Registers defined by IEEE */
12734 +#define PHY_CTRL 0x00 /* Control Register */
12735 +#define PHY_STATUS 0x01 /* Status Regiser */
12736 +#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */
12737 +#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */
12738 +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */
12739 +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */
12740 +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */
12741 +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
12742 +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
12743 +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */
12744 +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
12745 +#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
12747 +/* M88E1000 Specific Registers */
12748 +#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
12749 +#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
12750 +#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */
12751 +#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */
12752 +#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */
12753 +#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */
12755 +#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */
12756 +#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */
12757 +#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */
12758 +#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */
12759 +#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */
12761 +#define IGP01E1000_IEEE_REGS_PAGE 0x0000
12762 +#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
12763 +#define IGP01E1000_IEEE_FORCE_GIGA 0x0140
12765 +/* IGP01E1000 Specific Registers */
12766 +#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
12767 +#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
12768 +#define IGP01E1000_PHY_PORT_CTRL 0x12 /* PHY Specific Control Register */
12769 +#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
12770 +#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */
12771 +#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
12772 +#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */
12774 +/* IGP01E1000 AGC Registers - stores the cable length values*/
12775 +#define IGP01E1000_PHY_AGC_A 0x1172
12776 +#define IGP01E1000_PHY_AGC_B 0x1272
12777 +#define IGP01E1000_PHY_AGC_C 0x1472
12778 +#define IGP01E1000_PHY_AGC_D 0x1872
12780 +/* IGP01E1000 DSP Reset Register */
12781 +#define IGP01E1000_PHY_DSP_RESET 0x1F33
12782 +#define IGP01E1000_PHY_DSP_SET 0x1F71
12783 +#define IGP01E1000_PHY_DSP_FFE 0x1F35
12785 +#define IGP01E1000_PHY_CHANNEL_NUM 4
12786 +#define IGP01E1000_PHY_AGC_PARAM_A 0x1171
12787 +#define IGP01E1000_PHY_AGC_PARAM_B 0x1271
12788 +#define IGP01E1000_PHY_AGC_PARAM_C 0x1471
12789 +#define IGP01E1000_PHY_AGC_PARAM_D 0x1871
12791 +#define IGP01E1000_PHY_EDAC_MU_INDEX 0xC000
12792 +#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
12794 +#define IGP01E1000_PHY_ANALOG_TX_STATE 0x2890
12795 +#define IGP01E1000_PHY_ANALOG_CLASS_A 0x2000
12796 +#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE 0x0004
12797 +#define IGP01E1000_PHY_DSP_FFE_CM_CP 0x0069
12799 +#define IGP01E1000_PHY_DSP_FFE_DEFAULT 0x002A
12800 +/* IGP01E1000 PCS Initialization register - stores the polarity status when
12801 + * speed = 1000 Mbps. */
12802 +#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
12803 +#define IGP01E1000_PHY_PCS_CTRL_REG 0x00B5
12805 +#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0
12807 +#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
12808 +#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/
12809 +/* PHY Control Register */
12810 +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
12811 +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
12812 +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
12813 +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
12814 +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */
12815 +#define MII_CR_POWER_DOWN 0x0800 /* Power down */
12816 +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
12817 +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */
12818 +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
12819 +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
12821 +/* PHY Status Register */
12822 +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */
12823 +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */
12824 +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */
12825 +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */
12826 +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */
12827 +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */
12828 +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
12829 +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */
12830 +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */
12831 +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */
12832 +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */
12833 +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */
12834 +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */
12835 +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */
12836 +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */
12838 +/* Autoneg Advertisement Register */
12839 +#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */
12840 +#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */
12841 +#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */
12842 +#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */
12843 +#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */
12844 +#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */
12845 +#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */
12846 +#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */
12847 +#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */
12848 +#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */
12850 +/* Link Partner Ability Register (Base Page) */
12851 +#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
12852 +#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */
12853 +#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */
12854 +#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */
12855 +#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */
12856 +#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */
12857 +#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */
12858 +#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */
12859 +#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */
12860 +#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */
12861 +#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */
12863 +/* Autoneg Expansion Register */
12864 +#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */
12865 +#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */
12866 +#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */
12867 +#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
12868 +#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */
12870 +/* Next Page TX Register */
12871 +#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
12872 +#define NPTX_TOGGLE 0x0800 /* Toggles between exchanges
12873 + * of different NP
12874 + */
12875 +#define NPTX_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
12876 + * 0 = cannot comply with msg
12877 + */
12878 +#define NPTX_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
12879 +#define NPTX_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
12880 + * 0 = sending last NP
12881 + */
12883 +/* Link Partner Next Page Register */
12884 +#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
12885 +#define LP_RNPR_TOGGLE 0x0800 /* Toggles between exchanges
12886 + * of different NP
12887 + */
12888 +#define LP_RNPR_ACKNOWLDGE2 0x1000 /* 1 = will comply with msg
12889 + * 0 = cannot comply with msg
12890 + */
12891 +#define LP_RNPR_MSG_PAGE 0x2000 /* formatted(1)/unformatted(0) pg */
12892 +#define LP_RNPR_ACKNOWLDGE 0x4000 /* 1 = ACK / 0 = NO ACK */
12893 +#define LP_RNPR_NEXT_PAGE 0x8000 /* 1 = addition NP will follow
12894 + * 0 = sending last NP
12895 + */
12897 +/* 1000BASE-T Control Register */
12898 +#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */
12899 +#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */
12900 +#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */
12901 +#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */
12902 + /* 0=DTE device */
12903 +#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
12904 + /* 0=Configure PHY as Slave */
12905 +#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
12906 + /* 0=Automatic Master/Slave config */
12907 +#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
12908 +#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
12909 +#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */
12910 +#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */
12911 +#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */
12913 +/* 1000BASE-T Status Register */
12914 +#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */
12915 +#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
12916 +#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
12917 +#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
12918 +#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
12919 +#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */
12920 +#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */
12921 +#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */
12922 +#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
12923 +#define SR_1000T_LOCAL_RX_STATUS_SHIFT 13
12924 +#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5
12925 +#define FFE_IDLE_ERR_COUNT_TIMEOUT_20 20
12926 +#define FFE_IDLE_ERR_COUNT_TIMEOUT_100 100
12928 +/* Extended Status Register */
12929 +#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
12930 +#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
12931 +#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
12932 +#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
12934 +#define PHY_TX_POLARITY_MASK 0x0100 /* register 10h bit 8 (polarity bit) */
12935 +#define PHY_TX_NORMAL_POLARITY 0 /* register 10h bit 8 (normal polarity) */
12937 +#define AUTO_POLARITY_DISABLE 0x0010 /* register 11h bit 4 */
12938 + /* (0=enable, 1=disable) */
12940 +/* M88E1000 PHY Specific Control Register */
12941 +#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
12942 +#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
12943 +#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
12944 +#define M88E1000_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low,
12945 + * 0=CLK125 toggling
12946 + */
12947 +#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
12948 + /* Manual MDI configuration */
12949 +#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
12950 +#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover,
12951 + * 100BASE-TX/10BASE-T:
12952 + * MDI Mode
12953 + */
12954 +#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled
12955 + * all speeds.
12956 + */
12957 +#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080
12958 + /* 1=Enable Extended 10BASE-T distance
12959 + * (Lower 10BASE-T RX Threshold)
12960 + * 0=Normal 10BASE-T RX Threshold */
12961 +#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100
12962 + /* 1=5-Bit interface in 100BASE-TX
12963 + * 0=MII interface in 100BASE-TX */
12964 +#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
12965 +#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
12966 +#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
12968 +#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT 1
12969 +#define M88E1000_PSCR_AUTO_X_MODE_SHIFT 5
12970 +#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
12972 +/* M88E1000 PHY Specific Status Register */
12973 +#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
12974 +#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */
12975 +#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */
12976 +#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */
12977 +#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M;
12978 + * 3=110-140M;4=>140M */
12979 +#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */
12980 +#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */
12981 +#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */
12982 +#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */
12983 +#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */
12984 +#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */
12985 +#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */
12986 +#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */
12988 +#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
12989 +#define M88E1000_PSSR_DOWNSHIFT_SHIFT 5
12990 +#define M88E1000_PSSR_MDIX_SHIFT 6
12991 +#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
12993 +/* M88E1000 Extended PHY Specific Control Register */
12994 +#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */
12995 +#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 /* 1=Lost lock detect enabled.
12996 + * Will assert lost lock and bring
12997 + * link down if idle not seen
12998 + * within 1ms in 1000BASE-T
12999 + */
13000 +/* Number of times we will attempt to autonegotiate before downshifting if we
13001 + * are the master */
13002 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
13003 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000
13004 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400
13005 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800
13006 +#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00
13007 +/* Number of times we will attempt to autonegotiate before downshifting if we
13008 + * are the slave */
13009 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300
13010 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000
13011 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100
13012 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200
13013 +#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300
13014 +#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */
13015 +#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
13016 +#define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
13018 +/* IGP01E1000 Specific Port Config Register - R/W */
13019 +#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
13020 +#define IGP01E1000_PSCFR_PRE_EN 0x0020
13021 +#define IGP01E1000_PSCFR_SMART_SPEED 0x0080
13022 +#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK 0x0100
13023 +#define IGP01E1000_PSCFR_DISABLE_JABBER 0x0400
13024 +#define IGP01E1000_PSCFR_DISABLE_TRANSMIT 0x2000
13026 +/* IGP01E1000 Specific Port Status Register - R/O */
13027 +#define IGP01E1000_PSSR_AUTONEG_FAILED 0x0001 /* RO LH SC */
13028 +#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
13029 +#define IGP01E1000_PSSR_CABLE_LENGTH 0x007C
13030 +#define IGP01E1000_PSSR_FULL_DUPLEX 0x0200
13031 +#define IGP01E1000_PSSR_LINK_UP 0x0400
13032 +#define IGP01E1000_PSSR_MDIX 0x0800
13033 +#define IGP01E1000_PSSR_SPEED_MASK 0xC000 /* speed bits mask */
13034 +#define IGP01E1000_PSSR_SPEED_10MBPS 0x4000
13035 +#define IGP01E1000_PSSR_SPEED_100MBPS 0x8000
13036 +#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
13037 +#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT 0x0002 /* shift right 2 */
13038 +#define IGP01E1000_PSSR_MDIX_SHIFT 0x000B /* shift right 11 */
13040 +/* IGP01E1000 Specific Port Control Register - R/W */
13041 +#define IGP01E1000_PSCR_TP_LOOPBACK 0x0001
13042 +#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR 0x0200
13043 +#define IGP01E1000_PSCR_TEN_CRS_SELECT 0x0400
13044 +#define IGP01E1000_PSCR_FLIP_CHIP 0x0800
13045 +#define IGP01E1000_PSCR_AUTO_MDIX 0x1000
13046 +#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0-MDI, 1-MDIX */
13048 +/* IGP01E1000 Specific Port Link Health Register */
13049 +#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
13050 +#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR 0x4000
13051 +#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK 0x0800 /* LH */
13052 +#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW 0x0400 /* LH */
13053 +#define IGP01E1000_PLHR_DATA_ERR_1 0x0200 /* LH */
13054 +#define IGP01E1000_PLHR_DATA_ERR_0 0x0100
13055 +#define IGP01E1000_PLHR_AUTONEG_FAULT 0x0010
13056 +#define IGP01E1000_PLHR_AUTONEG_ACTIVE 0x0008
13057 +#define IGP01E1000_PLHR_VALID_CHANNEL_D 0x0004
13058 +#define IGP01E1000_PLHR_VALID_CHANNEL_C 0x0002
13059 +#define IGP01E1000_PLHR_VALID_CHANNEL_B 0x0001
13060 +#define IGP01E1000_PLHR_VALID_CHANNEL_A 0x0000
13062 +/* IGP01E1000 Channel Quality Register */
13063 +#define IGP01E1000_MSE_CHANNEL_D 0x000F
13064 +#define IGP01E1000_MSE_CHANNEL_C 0x00F0
13065 +#define IGP01E1000_MSE_CHANNEL_B 0x0F00
13066 +#define IGP01E1000_MSE_CHANNEL_A 0xF000
13068 +/* IGP01E1000 DSP reset macros */
13069 +#define DSP_RESET_ENABLE 0x0
13070 +#define DSP_RESET_DISABLE 0x2
13071 +#define E1000_MAX_DSP_RESETS 10
13073 +/* IGP01E1000 AGC Registers */
13075 +#define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
13077 +/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
13078 +#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
13080 +/* The precision of the length is +/- 10 meters */
13081 +#define IGP01E1000_AGC_RANGE 10
13083 +/* IGP01E1000 PCS Initialization register */
13084 +/* bits 3:6 in the PCS registers stores the channels polarity */
13085 +#define IGP01E1000_PHY_POLARITY_MASK 0x0078
13087 +/* IGP01E1000 GMII FIFO Register */
13088 +#define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed
13089 + * on Link-Up */
13090 +#define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */
13092 +/* IGP01E1000 Analog Register */
13093 +#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x20D1
13094 +#define IGP01E1000_ANALOG_FUSE_STATUS 0x20D0
13095 +#define IGP01E1000_ANALOG_FUSE_CONTROL 0x20DC
13096 +#define IGP01E1000_ANALOG_FUSE_BYPASS 0x20DE
13098 +#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000
13099 +#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80
13100 +#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070
13101 +#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100
13102 +#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002
13104 +#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040
13105 +#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010
13106 +#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080
13107 +#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500
13109 +/* Bit definitions for valid PHY IDs. */
13110 +#define M88E1000_E_PHY_ID 0x01410C50
13111 +#define M88E1000_I_PHY_ID 0x01410C30
13112 +#define M88E1011_I_PHY_ID 0x01410C20
13113 +#define IGP01E1000_I_PHY_ID 0x02A80380
13114 +#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
13115 +#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
13116 +#define M88E1011_I_REV_4 0x04
13118 +/* Miscellaneous PHY bit definitions. */
13119 +#define PHY_PREAMBLE 0xFFFFFFFF
13120 +#define PHY_SOF 0x01
13121 +#define PHY_OP_READ 0x02
13122 +#define PHY_OP_WRITE 0x01
13123 +#define PHY_TURNAROUND 0x02
13124 +#define PHY_PREAMBLE_SIZE 32
13125 +#define MII_CR_SPEED_1000 0x0040
13126 +#define MII_CR_SPEED_100 0x2000
13127 +#define MII_CR_SPEED_10 0x0000
13128 +#define E1000_PHY_ADDRESS 0x01
13129 +#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */
13130 +#define PHY_FORCE_TIME 20 /* 2.0 Seconds */
13131 +#define PHY_REVISION_MASK 0xFFFFFFF0
13132 +#define DEVICE_SPEED_MASK 0x00000300 /* Device Ctrl Reg Speed Mask */
13133 +#define REG4_SPEED_MASK 0x01E0
13134 +#define REG9_SPEED_MASK 0x0300
13135 +#define ADVERTISE_10_HALF 0x0001
13136 +#define ADVERTISE_10_FULL 0x0002
13137 +#define ADVERTISE_100_HALF 0x0004
13138 +#define ADVERTISE_100_FULL 0x0008
13139 +#define ADVERTISE_1000_HALF 0x0010
13140 +#define ADVERTISE_1000_FULL 0x0020
13141 +#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F /* Everything but 1000-Half */
13142 +#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/
13143 +#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/
13145 +#endif /* _E1000_HW_H_ */
13146 Index: b/netboot/eepro.c
13147 ===================================================================
13148 --- a/netboot/eepro.c
13149 +++ /dev/null
13150 @@ -1,586 +0,0 @@
13151 -/**************************************************************************
13152 -Etherboot - BOOTP/TFTP Bootstrap Program
13153 -Intel EEPRO/10 NIC driver for Etherboot
13154 -Adapted from Linux eepro.c from kernel 2.2.17
13156 -This board accepts a 32 pin EEPROM (29C256), however a test with a
13157 -27C010 shows that this EPROM also works in the socket, but it's not clear
13158 -how repeatably. The two top address pins appear to be held low, thus
13159 -the bottom 32kB of the 27C010 is visible in the CPU's address space.
13160 -To be sure you could put 4 copies of the code in the 27C010, then
13161 -it doesn't matter whether the extra lines are held low or high, just
13162 -hopefully not floating as CMOS chips don't like floating inputs.
13164 -Be careful with seating the EPROM as the socket on my board actually
13165 -has 34 pins, the top row of 2 are not used.
13166 -***************************************************************************/
13169 - * This program is free software; you can redistribute it and/or
13170 - * modify it under the terms of the GNU General Public License as
13171 - * published by the Free Software Foundation; either version 2, or (at
13172 - * your option) any later version.
13173 - */
13175 -/* to get some global routines like printf */
13176 -#include "etherboot.h"
13177 -/* to get the interface to the body of the program */
13178 -#include "nic.h"
13179 -/* to get our own prototype */
13180 -#include "cards.h"
13181 -/* we use timer2 for microsecond waits */
13182 -#include "timer.h"
13184 -#undef DEBUG /* only after include files */
13186 -/* Different 82595 chips */
13187 -#define LAN595 0
13188 -#define LAN595TX 1
13189 -#define LAN595FX 2
13190 -#define LAN595FX_10ISA 3
13192 -#define SLOW_DOWN inb(0x80);
13194 -/* The station (ethernet) address prefix, used for IDing the board. */
13195 -#define SA_ADDR0 0x00 /* Etherexpress Pro/10 */
13196 -#define SA_ADDR1 0xaa
13197 -#define SA_ADDR2 0x00
13199 -#define GetBit(x,y) ((x & (1<<y))>>y)
13201 -/* EEPROM Word 0: */
13202 -#define ee_PnP 0 /* Plug 'n Play enable bit */
13203 -#define ee_Word1 1 /* Word 1? */
13204 -#define ee_BusWidth 2 /* 8/16 bit */
13205 -#define ee_FlashAddr 3 /* Flash Address */
13206 -#define ee_FlashMask 0x7 /* Mask */
13207 -#define ee_AutoIO 6 /* */
13208 -#define ee_reserved0 7 /* =0! */
13209 -#define ee_Flash 8 /* Flash there? */
13210 -#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
13211 -#define ee_IO0 10 /* IO Address LSB */
13212 -#define ee_IO0Mask 0x /*...*/
13213 -#define ee_IO1 15 /* IO MSB */
13215 -/* EEPROM Word 1: */
13216 -#define ee_IntSel 0 /* Interrupt */
13217 -#define ee_IntMask 0x7
13218 -#define ee_LI 3 /* Link Integrity 0= enabled */
13219 -#define ee_PC 4 /* Polarity Correction 0= enabled */
13220 -#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
13221 -#define ee_Jabber 6 /* Jabber prevention 0= enabled */
13222 -#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
13223 -#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
13224 -#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
13225 -#define ee_reserved1 10 /* .. 12 =0! */
13226 -#define ee_AltReady 13 /* Alternate Ready, 0=normal */
13227 -#define ee_reserved2 14 /* =0! */
13228 -#define ee_Duplex 15
13230 -/* Word2,3,4: */
13231 -#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
13232 -#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
13233 -#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
13234 -#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
13235 -#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
13236 -#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
13238 -/* Word 5: */
13239 -#define ee_BNC_TPE 0 /* 0=TPE */
13240 -#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
13241 -#define ee_BootTypeMask 0x3
13242 -#define ee_NumConn 3 /* Number of Connections 0= One or Two */
13243 -#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
13244 -#define ee_PortTPE 5
13245 -#define ee_PortBNC 6
13246 -#define ee_PortAUI 7
13247 -#define ee_PowerMgt 10 /* 0= disabled */
13248 -#define ee_CP 13 /* Concurrent Processing */
13249 -#define ee_CPMask 0x7
13251 -/* Word 6: */
13252 -#define ee_Stepping 0 /* Stepping info */
13253 -#define ee_StepMask 0x0F
13254 -#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
13255 -#define ee_BoardMask 0x0FFF
13257 -/* Word 7: */
13258 -#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
13259 -#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
13261 -/*..*/
13262 -#define ee_SIZE 0x40 /* total EEprom Size */
13263 -#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
13266 -/* Card identification via EEprom: */
13267 -#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
13268 -#define ee_addr_id 0x11 /* Word offset for Card ID */
13269 -#define ee_addr_SN 0x12 /* Serial Number */
13270 -#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
13273 -#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
13274 -#define ee_vendor_intel1 0xD4
13275 -#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
13276 -#define ee_id_eepro10p1 0x31
13278 -/* now this section could be used by both boards: the oldies and the ee10:
13279 - * ee10 uses tx buffer before of rx buffer and the oldies the inverse.
13280 - * (aris)
13281 - */
13282 -#define RAM_SIZE 0x8000
13284 -#define RCV_HEADER 8
13285 -#define RCV_DEFAULT_RAM 0x6000
13286 -#define RCV_RAM rcv_ram
13288 -static unsigned rcv_ram = RCV_DEFAULT_RAM;
13290 -#define XMT_HEADER 8
13291 -#define XMT_RAM (RAM_SIZE - RCV_RAM)
13293 -#define XMT_START ((rcv_start + RCV_RAM) % RAM_SIZE)
13295 -#define RCV_LOWER_LIMIT (rcv_start >> 8)
13296 -#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8)
13297 -#define XMT_LOWER_LIMIT (XMT_START >> 8)
13298 -#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8)
13300 -#define RCV_START_PRO 0x00
13301 -#define RCV_START_10 XMT_RAM
13302 - /* by default the old driver */
13303 -static unsigned rcv_start = RCV_START_PRO;
13305 -#define RCV_DONE 0x0008
13306 -#define RX_OK 0x2000
13307 -#define RX_ERROR 0x0d81
13309 -#define TX_DONE_BIT 0x0080
13310 -#define CHAIN_BIT 0x8000
13311 -#define XMT_STATUS 0x02
13312 -#define XMT_CHAIN 0x04
13313 -#define XMT_COUNT 0x06
13315 -#define BANK0_SELECT 0x00
13316 -#define BANK1_SELECT 0x40
13317 -#define BANK2_SELECT 0x80
13319 -/* Bank 0 registers */
13320 -#define COMMAND_REG 0x00 /* Register 0 */
13321 -#define MC_SETUP 0x03
13322 -#define XMT_CMD 0x04
13323 -#define DIAGNOSE_CMD 0x07
13324 -#define RCV_ENABLE_CMD 0x08
13325 -#define RCV_DISABLE_CMD 0x0a
13326 -#define STOP_RCV_CMD 0x0b
13327 -#define RESET_CMD 0x0e
13328 -#define POWER_DOWN_CMD 0x18
13329 -#define RESUME_XMT_CMD 0x1c
13330 -#define SEL_RESET_CMD 0x1e
13331 -#define STATUS_REG 0x01 /* Register 1 */
13332 -#define RX_INT 0x02
13333 -#define TX_INT 0x04
13334 -#define EXEC_STATUS 0x30
13335 -#define ID_REG 0x02 /* Register 2 */
13336 -#define R_ROBIN_BITS 0xc0 /* round robin counter */
13337 -#define ID_REG_MASK 0x2c
13338 -#define ID_REG_SIG 0x24
13339 -#define AUTO_ENABLE 0x10
13340 -#define INT_MASK_REG 0x03 /* Register 3 */
13341 -#define RX_STOP_MASK 0x01
13342 -#define RX_MASK 0x02
13343 -#define TX_MASK 0x04
13344 -#define EXEC_MASK 0x08
13345 -#define ALL_MASK 0x0f
13346 -#define IO_32_BIT 0x10
13347 -#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
13348 -#define RCV_STOP 0x06
13350 -#define XMT_BAR_PRO 0x0a
13351 -#define XMT_BAR_10 0x0b
13352 -static unsigned xmt_bar = XMT_BAR_PRO;
13354 -#define HOST_ADDRESS_REG 0x0c
13355 -#define IO_PORT 0x0e
13356 -#define IO_PORT_32_BIT 0x0c
13358 -/* Bank 1 registers */
13359 -#define REG1 0x01
13360 -#define WORD_WIDTH 0x02
13361 -#define INT_ENABLE 0x80
13362 -#define INT_NO_REG 0x02
13363 -#define RCV_LOWER_LIMIT_REG 0x08
13364 -#define RCV_UPPER_LIMIT_REG 0x09
13366 -#define XMT_LOWER_LIMIT_REG_PRO 0x0a
13367 -#define XMT_UPPER_LIMIT_REG_PRO 0x0b
13368 -#define XMT_LOWER_LIMIT_REG_10 0x0b
13369 -#define XMT_UPPER_LIMIT_REG_10 0x0a
13370 -static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
13371 -static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
13373 -/* Bank 2 registers */
13374 -#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
13375 -#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
13376 -#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
13377 -#define REG2 0x02
13378 -#define PRMSC_Mode 0x01
13379 -#define Multi_IA 0x20
13380 -#define REG3 0x03
13381 -#define TPE_BIT 0x04
13382 -#define BNC_BIT 0x20
13383 -#define REG13 0x0d
13384 -#define FDX 0x00
13385 -#define A_N_ENABLE 0x02
13387 -#define I_ADD_REG0 0x04
13388 -#define I_ADD_REG1 0x05
13389 -#define I_ADD_REG2 0x06
13390 -#define I_ADD_REG3 0x07
13391 -#define I_ADD_REG4 0x08
13392 -#define I_ADD_REG5 0x09
13394 -#define EEPROM_REG_PRO 0x0a
13395 -#define EEPROM_REG_10 0x0b
13396 -static unsigned eeprom_reg = EEPROM_REG_PRO;
13398 -#define EESK 0x01
13399 -#define EECS 0x02
13400 -#define EEDI 0x04
13401 -#define EEDO 0x08
13403 -/* The horrible routine to read a word from the serial EEPROM. */
13404 -/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
13406 -/* The delay between EEPROM clock transitions. */
13407 -#define eeprom_delay() { udelay(40); }
13408 -#define EE_READ_CMD (6 << 6)
13410 -/* do a full reset */
13411 -#define eepro_full_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40);
13413 -/* do a nice reset */
13414 -#define eepro_sel_reset(ioaddr) { \
13415 - outb(SEL_RESET_CMD, ioaddr); \
13416 - SLOW_DOWN; \
13417 - SLOW_DOWN; \
13420 -/* clear all interrupts */
13421 -#define eepro_clear_int(ioaddr) outb(ALL_MASK, ioaddr + STATUS_REG)
13423 -/* enable rx */
13424 -#define eepro_en_rx(ioaddr) outb(RCV_ENABLE_CMD, ioaddr)
13426 -/* disable rx */
13427 -#define eepro_dis_rx(ioaddr) outb(RCV_DISABLE_CMD, ioaddr)
13429 -/* switch bank */
13430 -#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
13431 -#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
13432 -#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
13434 -static unsigned int rx_start, tx_start;
13435 -static int tx_last;
13436 -static unsigned tx_end;
13437 -static int eepro = 0;
13438 -static unsigned short ioaddr = 0;
13439 -static unsigned int mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
13441 -#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
13443 -/**************************************************************************
13444 -RESET - Reset adapter
13445 -***************************************************************************/
13446 -static void eepro_reset(struct nic *nic)
13448 - int temp_reg, i;
13450 - /* put the card in its initial state */
13451 - eepro_sw2bank2(ioaddr); /* be careful, bank2 now */
13452 - temp_reg = inb(ioaddr + eeprom_reg);
13453 -#ifdef DEBUG
13454 - printf("Stepping %d\n", temp_reg >> 5);
13455 -#endif
13456 - if (temp_reg & 0x10) /* check the TurnOff Enable bit */
13457 - outb(temp_reg & 0xEF, ioaddr + eeprom_reg);
13458 - for (i = 0; i < ETH_ALEN; i++) /* fill the MAC address */
13459 - outb(nic->node_addr[i], ioaddr + I_ADD_REG0 + i);
13460 - temp_reg = inb(ioaddr + REG1);
13461 - /* setup Transmit Chaining and discard bad RCV frames */
13462 - outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
13463 - | RCV_Discard_BadFrame, ioaddr + REG1);
13464 - temp_reg = inb(ioaddr + REG2); /* match broadcast */
13465 - outb(temp_reg | 0x14, ioaddr + REG2);
13466 - temp_reg = inb(ioaddr + REG3);
13467 - outb(temp_reg & 0x3F, ioaddr + REG3); /* clear test mode */
13468 - /* set the receiving mode */
13469 - eepro_sw2bank1(ioaddr); /* be careful, bank1 now */
13470 - /* initialise the RCV and XMT upper and lower limits */
13471 - outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
13472 - outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
13473 - outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg);
13474 - outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg);
13475 - eepro_sw2bank0(ioaddr); /* Switch back to bank 0 */
13476 - eepro_clear_int(ioaddr);
13477 - /* Initialise RCV */
13478 - outw(rx_start = (RCV_LOWER_LIMIT << 8), ioaddr + RCV_BAR);
13479 - outw(((RCV_UPPER_LIMIT << 8) | 0xFE), ioaddr + RCV_STOP);
13480 - /* Intialise XMT */
13481 - outw((XMT_LOWER_LIMIT << 8), ioaddr + xmt_bar);
13482 - eepro_sel_reset(ioaddr);
13483 - tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
13484 - tx_last = 0;
13485 - eepro_en_rx(ioaddr);
13488 -/**************************************************************************
13489 -POLL - Wait for a frame
13490 -***************************************************************************/
13491 -static int eepro_poll(struct nic *nic)
13493 - int i;
13494 - unsigned int rcv_car = rx_start;
13495 - unsigned int rcv_event, rcv_status, rcv_next_frame, rcv_size;
13497 - /* return true if there's an ethernet packet ready to read */
13498 - /* nic->packet should contain data on return */
13499 - /* nic->packetlen should contain length of data */
13500 -#if 0
13501 - if ((inb(ioaddr + STATUS_REG) & 0x40) == 0)
13502 - return (0);
13503 - outb(0x40, ioaddr + STATUS_REG);
13504 -#endif
13505 - outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
13506 - rcv_event = inw(ioaddr + IO_PORT);
13507 - if (rcv_event != RCV_DONE)
13508 - return (0);
13509 - rcv_status = inw(ioaddr + IO_PORT);
13510 - rcv_next_frame = inw(ioaddr + IO_PORT);
13511 - rcv_size = inw(ioaddr + IO_PORT);
13512 -#if 0
13513 - printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
13514 - inb(ioaddr + STATUS_REG));
13515 -#endif
13516 - if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
13517 - printf("Receive error %hX\n", rcv_status);
13518 - return (0);
13520 - rcv_size &= 0x3FFF;
13521 - insw(ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
13522 -#if 0
13523 - for (i = 0; i < 48; i++) {
13524 - printf("%hhX", nic->packet[i]);
13525 - putchar(i % 16 == 15 ? '\n' : ' ');
13527 -#endif
13528 - nic->packetlen = rcv_size;
13529 - rcv_car = rx_start + RCV_HEADER + rcv_size;
13530 - rx_start = rcv_next_frame;
13531 - if (rcv_car == 0)
13532 - rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
13533 - outw(rcv_car - 1, ioaddr + RCV_STOP);
13534 - return (1);
13537 -/**************************************************************************
13538 -TRANSMIT - Transmit a frame
13539 -***************************************************************************/
13540 -static void eepro_transmit(
13541 - struct nic *nic,
13542 - const char *d, /* Destination */
13543 - unsigned int t, /* Type */
13544 - unsigned int s, /* size */
13545 - const char *p) /* Packet */
13547 - unsigned int status, tx_available, last, end, length;
13548 - unsigned short type;
13549 - int boguscount = 20;
13551 - length = s + ETH_HLEN;
13552 - if (tx_end > tx_start)
13553 - tx_available = XMT_RAM - (tx_end - tx_start);
13554 - else if (tx_end < tx_start)
13555 - tx_available = tx_start - tx_end;
13556 - else
13557 - tx_available = XMT_RAM;
13558 - last = tx_end;
13559 - end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
13560 - if (end >= (XMT_UPPER_LIMIT << 8)) {
13561 - last = (XMT_LOWER_LIMIT << 8);
13562 - end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
13564 - outw(last, ioaddr + HOST_ADDRESS_REG);
13565 - outw(XMT_CMD, ioaddr + IO_PORT);
13566 - outw(0, ioaddr + IO_PORT);
13567 - outw(end, ioaddr + IO_PORT);
13568 - outw(length, ioaddr + IO_PORT);
13569 - outsw(ioaddr + IO_PORT, d, ETH_ALEN / 2);
13570 - outsw(ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
13571 - type = htons(t);
13572 - outsw(ioaddr + IO_PORT, &type, sizeof(type) / 2);
13573 - outsw(ioaddr + IO_PORT, p, (s + 3) >> 1);
13574 - /* A dummy read to flush the DRAM write pipeline */
13575 - status = inw(ioaddr + IO_PORT);
13576 - outw(last, ioaddr + xmt_bar);
13577 - outb(XMT_CMD, ioaddr);
13578 - tx_start = last;
13579 - tx_last = last;
13580 - tx_end = end;
13581 -#if 0
13582 - printf("%d %d\n", tx_start, tx_end);
13583 -#endif
13584 - while (boguscount > 0) {
13585 - if (((status = inw(ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
13586 - udelay(40);
13587 - boguscount--;
13588 - continue;
13590 -#if DEBUG
13591 - if ((status & 0x2000) == 0)
13592 - printf("Transmit status %hX\n", status);
13593 -#endif
13597 -/**************************************************************************
13598 -DISABLE - Turn off ethernet interface
13599 -***************************************************************************/
13600 -static void eepro_disable(struct nic *nic)
13602 - eepro_sw2bank0(ioaddr); /* Switch to bank 0 */
13603 - /* Flush the Tx and disable Rx */
13604 - outb(STOP_RCV_CMD, ioaddr);
13605 - tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
13606 - tx_last = 0;
13607 - /* Reset the 82595 */
13608 - eepro_full_reset(ioaddr);
13611 -static int read_eeprom(int location)
13613 - int i;
13614 - unsigned short retval = 0;
13615 - int ee_addr = ioaddr + eeprom_reg;
13616 - int read_cmd = location | EE_READ_CMD;
13617 - int ctrl_val = EECS;
13619 - if (eepro == LAN595FX_10ISA) {
13620 - eepro_sw2bank1(ioaddr);
13621 - outb(0x00, ioaddr + STATUS_REG);
13623 - eepro_sw2bank2(ioaddr);
13624 - outb(ctrl_val, ee_addr);
13625 - /* shift the read command bits out */
13626 - for (i = 8; i >= 0; i--) {
13627 - short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
13628 - outb(outval, ee_addr);
13629 - outb(outval | EESK, ee_addr); /* EEPROM clock tick */
13630 - eeprom_delay();
13631 - outb(outval, ee_addr); /* finish EEPROM clock tick */
13632 - eeprom_delay();
13634 - outb(ctrl_val, ee_addr);
13635 - for (i = 16; i > 0; i--) {
13636 - outb(ctrl_val | EESK, ee_addr);
13637 - eeprom_delay();
13638 - retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
13639 - outb(ctrl_val, ee_addr);
13640 - eeprom_delay();
13642 - /* terminate the EEPROM access */
13643 - ctrl_val &= ~EECS;
13644 - outb(ctrl_val | EESK, ee_addr);
13645 - eeprom_delay();
13646 - outb(ctrl_val, ee_addr);
13647 - eeprom_delay();
13648 - eepro_sw2bank0(ioaddr);
13649 - return (retval);
13652 -static int eepro_probe1(struct nic *nic)
13654 - int i, id, counter, l_eepro = 0;
13655 - union {
13656 - unsigned char caddr[ETH_ALEN];
13657 - unsigned short saddr[ETH_ALEN/2];
13658 - } station_addr;
13659 - char *name;
13661 - id = inb(ioaddr + ID_REG);
13662 - if ((id & ID_REG_MASK) != ID_REG_SIG)
13663 - return (0);
13664 - counter = id & R_ROBIN_BITS;
13665 - if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
13666 - return (0);
13667 - /* yes the 82595 has been found */
13668 - station_addr.saddr[2] = read_eeprom(2);
13669 - if (station_addr.saddr[2] == 0x0000 || station_addr.saddr[2] == 0xFFFF) {
13670 - l_eepro = 3;
13671 - eepro = LAN595FX_10ISA;
13672 - eeprom_reg= EEPROM_REG_10;
13673 - rcv_start = RCV_START_10;
13674 - xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
13675 - xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
13676 - station_addr.saddr[2] = read_eeprom(2);
13678 - station_addr.saddr[1] = read_eeprom(3);
13679 - station_addr.saddr[0] = read_eeprom(4);
13680 - if (l_eepro)
13681 - name = "Intel EtherExpress 10 ISA";
13682 - else if (read_eeprom(7) == ee_FX_INT2IRQ) {
13683 - name = "Intel EtherExpress Pro/10+ ISA";
13684 - l_eepro = 2;
13685 - } else if (station_addr.saddr[0] == SA_ADDR1) {
13686 - name = "Intel EtherExpress Pro/10 ISA";
13687 - l_eepro = 1;
13688 - } else {
13689 - l_eepro = 0;
13690 - name = "Intel 82595-based LAN card";
13692 - station_addr.saddr[0] = swap16(station_addr.saddr[0]);
13693 - station_addr.saddr[1] = swap16(station_addr.saddr[1]);
13694 - station_addr.saddr[2] = swap16(station_addr.saddr[2]);
13695 - for (i = 0; i < ETH_ALEN; i++) {
13696 - nic->node_addr[i] = station_addr.caddr[i];
13698 - printf("\n%s ioaddr %#hX, addr %!", name, ioaddr, nic->node_addr);
13699 - mem_start = RCV_LOWER_LIMIT << 8;
13700 - if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
13701 - mem_end = RCV_UPPER_LIMIT << 8;
13702 - else {
13703 - mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
13704 - rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
13706 - printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
13707 - GetBit(read_eeprom(5), ee_BNC_TPE) ? "BNC" : "TP");
13708 - return (1);
13711 -/**************************************************************************
13712 -PROBE - Look for an adapter, this routine's visible to the outside
13713 -***************************************************************************/
13714 -struct nic *eepro_probe(struct nic *nic, unsigned short *probe_addrs)
13716 - unsigned short *p;
13717 - /* same probe list as the Linux driver */
13718 - static unsigned short ioaddrs[] = {
13719 - 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
13721 - if (probe_addrs == 0 || probe_addrs[0] == 0)
13722 - probe_addrs = ioaddrs;
13723 - for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
13724 - if (eepro_probe1(nic))
13725 - break;
13727 - if (*p == 0)
13728 - return (0);
13729 - eepro_reset(nic);
13730 - /* point to NIC specific routines */
13731 - nic->reset = eepro_reset;
13732 - nic->poll = eepro_poll;
13733 - nic->transmit = eepro_transmit;
13734 - nic->disable = eepro_disable;
13735 - return (nic);
13737 Index: b/netboot/eepro100.c
13738 ===================================================================
13739 --- a/netboot/eepro100.c
13740 +++ b/netboot/eepro100.c
13741 @@ -80,8 +80,8 @@
13743 * Caveats:
13745 - * The etherboot framework moves the code to the 32k segment from
13746 - * 0x98000 to 0xa0000. There is just a little room between the end of
13747 + * The Etherboot framework moves the code to the 48k segment from
13748 + * 0x94000 to 0xa0000. There is just a little room between the end of
13749 * this driver and the 0xa0000 address. If you compile in too many
13750 * features, this will overflow.
13751 * The number under "hex" in the output of size that scrolls by while
13752 @@ -92,17 +92,13 @@
13753 /* The etherboot authors seem to dislike the argument ordering in
13754 * outb macros that Linux uses. I disklike the confusion that this
13755 * has caused even more.... This file uses the Linux argument ordering. */
13756 -/* Sorry not us. It's inherted code from FreeBSD. [The authors] */
13757 +/* Sorry not us. It's inherited code from FreeBSD. [The authors] */
13759 #include "etherboot.h"
13760 #include "nic.h"
13761 #include "pci.h"
13762 -#include "cards.h"
13763 #include "timer.h"
13765 -#undef virt_to_bus
13766 -#define virt_to_bus(x) ((unsigned long)x)
13768 static int ioaddr;
13770 typedef unsigned char u8;
13771 @@ -121,6 +117,18 @@
13772 SCBEarlyRx = 20, /* Early receive byte count. */
13775 +enum SCBCmdBits {
13776 + SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000,
13777 + SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400,
13778 + SCBTriggerIntr=0x0200, SCBMaskAll=0x0100,
13779 + /* The rest are Rx and Tx commands. */
13780 + CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050,
13781 + CUCmdBase=0x0060, /* CU Base address (set to zero) . */
13782 + CUDumpStats=0x0070, /* Dump then reset stats counters. */
13783 + RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006,
13784 + RxResumeNoResources=0x0007,
13787 static int do_eeprom_cmd(int cmd, int cmd_len);
13788 void hd(void *where, int n);
13790 @@ -139,8 +147,6 @@
13791 #define EE_WRITE_1 0x4806
13792 #define EE_ENB (0x4800 | EE_CS)
13794 -#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
13796 /* The EEPROM commands include the alway-set leading bit. */
13797 #define EE_READ_CMD 6
13799 @@ -184,9 +190,18 @@
13800 Typically this takes 0 ticks. */
13801 static inline void wait_for_cmd_done(int cmd_ioaddr)
13803 - short wait = 100;
13804 - do ;
13805 - while(inb(cmd_ioaddr) && --wait >= 0);
13806 + int wait = 0;
13807 + int delayed_cmd;
13809 + do
13810 + if (inb(cmd_ioaddr) == 0) return;
13811 + while(++wait <= 100);
13812 + delayed_cmd = inb(cmd_ioaddr);
13813 + do
13814 + if (inb(cmd_ioaddr) == 0) break;
13815 + while(++wait <= 10000);
13816 + printf("Command %2.2x was not immediately accepted, %d ticks!\n",
13817 + delayed_cmd, wait);
13820 /* Elements of the dump_statistics block. This block must be lword aligned. */
13821 @@ -212,35 +227,30 @@
13823 /* A speedo3 TX buffer descriptor with two buffers... */
13824 static struct TxFD {
13825 - volatile s16 status;
13826 - s16 command;
13827 - u32 link; /* void * */
13828 - u32 tx_desc_addr; /* (almost) Always points to the tx_buf_addr element. */
13829 - s32 count; /* # of TBD (=2), Tx start thresh., etc. */
13830 - /* This constitutes two "TBD" entries: hdr and data */
13831 - u32 tx_buf_addr0; /* void *, header of frame to be transmitted. */
13832 - s32 tx_buf_size0; /* Length of Tx hdr. */
13833 - u32 tx_buf_addr1; /* void *, data to be transmitted. */
13834 - s32 tx_buf_size1; /* Length of Tx data. */
13835 + volatile s16 status;
13836 + s16 command;
13837 + u32 link; /* void * */
13838 + u32 tx_desc_addr; /* (almost) Always points to the tx_buf_addr element. */
13839 + s32 count; /* # of TBD (=2), Tx start thresh., etc. */
13840 + /* This constitutes two "TBD" entries: hdr and data */
13841 + u32 tx_buf_addr0; /* void *, header of frame to be transmitted. */
13842 + s32 tx_buf_size0; /* Length of Tx hdr. */
13843 + u32 tx_buf_addr1; /* void *, data to be transmitted. */
13844 + s32 tx_buf_size1; /* Length of Tx data. */
13845 } txfd;
13847 struct RxFD { /* Receive frame descriptor. */
13848 - volatile s16 status;
13849 - s16 command;
13850 - u32 link; /* struct RxFD * */
13851 - u32 rx_buf_addr; /* void * */
13852 - u16 count;
13853 - u16 size;
13854 - char packet[1518];
13855 + volatile s16 status;
13856 + s16 command;
13857 + u32 link; /* struct RxFD * */
13858 + u32 rx_buf_addr; /* void * */
13859 + u16 count;
13860 + u16 size;
13861 + char packet[1518];
13864 -#ifdef USE_LOWMEM_BUFFER
13865 -#define rxfd ((struct RxFD *)(0x10000 - sizeof(struct RxFD)))
13866 -#define ACCESS(x) x->
13867 -#else
13868 static struct RxFD rxfd;
13869 #define ACCESS(x) x.
13870 -#endif
13872 static int congenb = 0; /* Enable congestion control in the DP83840. */
13873 static int txfifo = 8; /* Tx FIFO threshold in 4 byte units, 0-15 */
13874 @@ -256,8 +266,7 @@
13875 u32 link;
13876 unsigned char data[22];
13877 } confcmd = {
13878 - 0, CmdConfigure,
13879 - (u32) & txfd,
13880 + 0, 0, 0, /* filled in later */
13881 {22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */
13882 0, 0x2E, 0, 0x60, 0,
13883 0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */
13884 @@ -276,19 +285,20 @@
13886 static int mdio_write(int phy_id, int location, int value)
13888 - int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
13889 + int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
13891 - outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
13892 - ioaddr + SCBCtrlMDI);
13893 - do {
13894 - udelay(16);
13896 - val = inl(ioaddr + SCBCtrlMDI);
13897 - if (--boguscnt < 0) {
13898 - printf(" mdio_write() timed out with val = %X.\n", val);
13900 - } while (! (val & 0x10000000));
13901 - return val & 0xffff;
13902 + outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
13903 + ioaddr + SCBCtrlMDI);
13904 + do {
13905 + udelay(16);
13907 + val = inl(ioaddr + SCBCtrlMDI);
13908 + if (--boguscnt < 0) {
13909 + printf(" mdio_write() timed out with val = %X.\n", val);
13910 + break;
13912 + } while (! (val & 0x10000000));
13913 + return val & 0xffff;
13916 /* Support function: mdio_read
13917 @@ -298,17 +308,19 @@
13919 static int mdio_read(int phy_id, int location)
13921 - int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
13922 - outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
13923 - do {
13924 - udelay(16);
13926 - val = inl(ioaddr + SCBCtrlMDI);
13927 - if (--boguscnt < 0) {
13928 - printf( " mdio_read() timed out with val = %X.\n", val);
13930 - } while (! (val & 0x10000000));
13931 - return val & 0xffff;
13932 + int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
13933 + outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
13934 + do {
13935 + udelay(16);
13937 + val = inl(ioaddr + SCBCtrlMDI);
13939 + if (--boguscnt < 0) {
13940 + printf( " mdio_read() timed out with val = %X.\n", val);
13941 + break;
13943 + } while (! (val & 0x10000000));
13944 + return val & 0xffff;
13947 /* The fixes for the code were kindly provided by Dragan Stancevic
13948 @@ -340,25 +352,26 @@
13949 return retval;
13952 +#if 0
13953 static inline void whereami (const char *str)
13955 -#if 0
13956 printf ("%s\n", str);
13957 sleep (2);
13958 -#endif
13960 +#else
13961 +#define whereami(s)
13962 +#endif
13964 -/* function: eepro100_reset
13965 - * resets the card. This is used to allow Etherboot to probe the card again
13966 - * from a "virginal" state....
13967 - * Arguments: none
13969 - * returns: void.
13970 - */
13972 -static void eepro100_reset(struct nic *nic)
13973 +static void eepro100_irq(struct nic *nic __unused, irq_action_t action __unused)
13975 - outl(0, ioaddr + SCBPort);
13976 + switch ( action ) {
13977 + case DISABLE :
13978 + break;
13979 + case ENABLE :
13980 + break;
13981 + case FORCE :
13982 + break;
13986 /* function: eepro100_transmit
13987 @@ -373,61 +386,87 @@
13989 static void eepro100_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
13991 - struct eth_hdr {
13992 - unsigned char dst_addr[ETH_ALEN];
13993 - unsigned char src_addr[ETH_ALEN];
13994 - unsigned short type;
13995 - } hdr;
13996 - unsigned short status;
13997 - int to;
13998 - int s1, s2;
14000 - status = inw(ioaddr + SCBStatus);
14001 - /* Acknowledge all of the current interrupt sources ASAP. */
14002 - outw(status & 0xfc00, ioaddr + SCBStatus);
14003 + struct eth_hdr {
14004 + unsigned char dst_addr[ETH_ALEN];
14005 + unsigned char src_addr[ETH_ALEN];
14006 + unsigned short type;
14007 + } hdr;
14008 + unsigned short status;
14009 + int s1, s2;
14011 + status = inw(ioaddr + SCBStatus);
14012 + /* Acknowledge all of the current interrupt sources ASAP. */
14013 + outw(status & 0xfc00, ioaddr + SCBStatus);
14015 #ifdef DEBUG
14016 - printf ("transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n",
14017 - t, s, status, inw (ioaddr + SCBCmd));
14018 + printf ("transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n",
14019 + t, s, status, inw (ioaddr + SCBCmd));
14020 #endif
14022 - memcpy (&hdr.dst_addr, d, ETH_ALEN);
14023 - memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
14024 + memcpy (&hdr.dst_addr, d, ETH_ALEN);
14025 + memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
14027 - hdr.type = htons (t);
14028 + hdr.type = htons (t);
14030 - txfd.status = 0;
14031 - txfd.command = CmdSuspend | CmdTx | CmdTxFlex;
14032 - txfd.link = virt_to_bus (&txfd);
14033 - txfd.count = 0x02208000;
14034 - txfd.tx_desc_addr = (u32)&txfd.tx_buf_addr0;
14035 + txfd.status = 0;
14036 + txfd.command = CmdSuspend | CmdTx | CmdTxFlex;
14037 + txfd.link = virt_to_bus (&txfd);
14038 + txfd.count = 0x02208000;
14039 + txfd.tx_desc_addr = virt_to_bus(&txfd.tx_buf_addr0);
14041 - txfd.tx_buf_addr0 = virt_to_bus (&hdr);
14042 - txfd.tx_buf_size0 = sizeof (hdr);
14043 + txfd.tx_buf_addr0 = virt_to_bus (&hdr);
14044 + txfd.tx_buf_size0 = sizeof (hdr);
14046 - txfd.tx_buf_addr1 = virt_to_bus (p);
14047 - txfd.tx_buf_size1 = s;
14048 + txfd.tx_buf_addr1 = virt_to_bus (p);
14049 + txfd.tx_buf_size1 = s;
14051 #ifdef DEBUG
14052 - printf ("txfd: \n");
14053 - hd (&txfd, sizeof (txfd));
14054 + printf ("txfd: \n");
14055 + hd (&txfd, sizeof (txfd));
14056 #endif
14058 - outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
14059 - outw(INT_MASK | CU_START, ioaddr + SCBCmd);
14060 - wait_for_cmd_done(ioaddr + SCBCmd);
14062 - s1 = inw (ioaddr + SCBStatus);
14063 - load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
14064 - while (!txfd.status && timer2_running())
14065 - /* Wait */;
14066 - s2 = inw (ioaddr + SCBStatus);
14067 + outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
14068 + outw(INT_MASK | CU_START, ioaddr + SCBCmd);
14069 + wait_for_cmd_done(ioaddr + SCBCmd);
14071 + s1 = inw (ioaddr + SCBStatus);
14072 + load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
14073 + while (!txfd.status && timer2_running())
14074 + /* Wait */;
14075 + s2 = inw (ioaddr + SCBStatus);
14077 #ifdef DEBUG
14078 - printf ("s1 = %hX, s2 = %hX.\n", s1, s2);
14079 + printf ("s1 = %hX, s2 = %hX.\n", s1, s2);
14080 #endif
14084 + * Sometimes the receiver stops making progress. This routine knows how to
14085 + * get it going again, without losing packets or being otherwise nasty like
14086 + * a chip reset would be. Previously the driver had a whole sequence
14087 + * of if RxSuspended, if it's no buffers do one thing, if it's no resources,
14088 + * do another, etc. But those things don't really matter. Separate logic
14089 + * in the ISR provides for allocating buffers--the other half of operation
14090 + * is just making sure the receiver is active. speedo_rx_soft_reset does that.
14091 + * This problem with the old, more involved algorithm is shown up under
14092 + * ping floods on the order of 60K packets/second on a 100Mbps fdx network.
14093 + */
14094 +static void
14095 +speedo_rx_soft_reset(void)
14097 + wait_for_cmd_done(ioaddr + SCBCmd);
14098 + /*
14099 + * Put the hardware into a known state.
14100 + */
14101 + outb(RX_ABORT, ioaddr + SCBCmd);
14103 + ACCESS(rxfd)rx_buf_addr = 0xffffffff;
14105 + wait_for_cmd_done(ioaddr + SCBCmd);
14107 + outb(RX_START, ioaddr + SCBCmd);
14110 /* function: eepro100_poll / eth_poll
14111 * This recieves a packet from the network.
14113 @@ -440,34 +479,87 @@
14114 * returns the length of the packet in nic->packetlen.
14117 -static int eepro100_poll(struct nic *nic)
14118 +static int eepro100_poll(struct nic *nic, int retrieve)
14120 - if (!ACCESS(rxfd)status)
14121 - return 0;
14122 + unsigned int status;
14123 + status = inw(ioaddr + SCBStatus);
14125 - /* Ok. We got a packet. Now restart the reciever.... */
14126 - ACCESS(rxfd)status = 0;
14127 - ACCESS(rxfd)command = 0xc000;
14128 - outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
14129 - outw(INT_MASK | RX_START, ioaddr + SCBCmd);
14130 - wait_for_cmd_done(ioaddr + SCBCmd);
14131 + if (!ACCESS(rxfd)status)
14132 + return 0;
14134 + /* There is a packet ready */
14135 + if ( ! retrieve ) return 1;
14137 + /*
14138 + * The chip may have suspended reception for various reasons.
14139 + * Check for that, and re-prime it should this be the case.
14140 + */
14141 + switch ((status >> 2) & 0xf) {
14142 + case 0: /* Idle */
14143 + break;
14144 + case 1: /* Suspended */
14145 + case 2: /* No resources (RxFDs) */
14146 + case 9: /* Suspended with no more RBDs */
14147 + case 10: /* No resources due to no RBDs */
14148 + case 12: /* Ready with no RBDs */
14149 + speedo_rx_soft_reset();
14150 + break;
14151 + case 3: case 5: case 6: case 7: case 8:
14152 + case 11: case 13: case 14: case 15:
14153 + /* these are all reserved values */
14154 + break;
14157 + /* Ok. We got a packet. Now restart the reciever.... */
14158 + ACCESS(rxfd)status = 0;
14159 + ACCESS(rxfd)command = 0xc000;
14160 + outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
14161 + outw(INT_MASK | RX_START, ioaddr + SCBCmd);
14162 + wait_for_cmd_done(ioaddr + SCBCmd);
14164 #ifdef DEBUG
14165 - printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
14166 + printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
14167 #endif
14168 - nic->packetlen = ACCESS(rxfd)count & 0x3fff;
14169 - memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
14170 + nic->packetlen = ACCESS(rxfd)count & 0x3fff;
14171 + memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
14172 #ifdef DEBUG
14173 - hd (nic->packet, 0x30);
14174 + hd (nic->packet, 0x30);
14175 #endif
14176 - return 1;
14177 + return 1;
14180 -static void eepro100_disable(struct nic *nic)
14181 +/* function: eepro100_disable
14182 + * resets the card. This is used to allow Etherboot or Linux
14183 + * to probe the card again from a "virginal" state....
14184 + * Arguments: none
14186 + * returns: void.
14187 + */
14188 +static void eepro100_disable(struct dev *dev __unused)
14190 - /* See if this PartialReset solves the problem with interfering with
14191 - kernel operation after Etherboot hands over. - Ken 20001102 */
14192 - outl(2, ioaddr + SCBPort);
14193 +/* from eepro100_reset */
14194 + outl(0, ioaddr + SCBPort);
14195 +/* from eepro100_disable */
14196 + /* See if this PartialReset solves the problem with interfering with
14197 + kernel operation after Etherboot hands over. - Ken 20001102 */
14198 + outl(2, ioaddr + SCBPort);
14200 + /* The following is from the Intel e100 driver.
14201 + * This hopefully solves the problem with hanging hard DOS images. */
14203 + /* wait for the reset to take effect */
14204 + udelay(20);
14206 + /* Mask off our interrupt line -- it is unmasked after reset */
14208 + u16 intr_status;
14209 + /* Disable interrupts on our PCI board by setting the mask bit */
14210 + outw(INT_MASK, ioaddr + SCBCmd);
14211 + intr_status = inw(ioaddr + SCBStatus);
14212 + /* ack and clear intrs */
14213 + outw(intr_status, ioaddr + SCBStatus);
14214 + inw(ioaddr + SCBStatus);
14218 /* exported function: eepro100_probe / eth_probe
14219 @@ -478,25 +570,30 @@
14220 * leaves the 82557 initialized, and ready to recieve packets.
14223 -struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *p)
14224 +static int eepro100_probe(struct dev *dev, struct pci_device *p)
14226 + struct nic *nic = (struct nic *)dev;
14227 unsigned short sum = 0;
14228 int i;
14229 int read_cmd, ee_size;
14230 - unsigned short value;
14231 int options;
14232 - int promisc;
14233 + int rx_mode;
14235 /* we cache only the first few words of the EEPROM data
14236 be careful not to access beyond this array */
14237 unsigned short eeprom[16];
14239 - if (probeaddrs == 0 || probeaddrs[0] == 0)
14240 + if (p->ioaddr == 0)
14241 return 0;
14242 - ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
14243 + ioaddr = p->ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
14244 + nic->ioaddr = ioaddr;
14246 adjust_pci_device(p);
14248 + /* Copy IRQ from PCI information */
14249 + /* nic->irqno = pci->irq; */
14250 + nic->irqno = 0;
14252 if ((do_eeprom_cmd(EE_READ_CMD << 24, 27) & 0xffe0000)
14253 == 0xffe0000) {
14254 ee_size = 0x100;
14255 @@ -513,123 +610,138 @@
14256 sum += value;
14259 - for (i=0;i<ETH_ALEN;i++) {
14260 - nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
14262 - printf ("Ethernet addr: %!\n", nic->node_addr);
14264 - if (sum != 0xBABA)
14265 - printf("eepro100: Invalid EEPROM checksum %#hX, "
14266 - "check settings before activating this device!\n", sum);
14267 - outl(0, ioaddr + SCBPort);
14268 - udelay (10000);
14270 - whereami ("Got eeprom.");
14272 - outl(virt_to_bus(&lstats), ioaddr + SCBPointer);
14273 - outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd);
14274 - wait_for_cmd_done(ioaddr + SCBCmd);
14276 - whereami ("set stats addr.");
14277 - /* INIT RX stuff. */
14279 - /* Base = 0 */
14280 - outl(0, ioaddr + SCBPointer);
14281 - outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd);
14282 - wait_for_cmd_done(ioaddr + SCBCmd);
14284 - whereami ("set rx base addr.");
14286 - ACCESS(rxfd)status = 0x0001;
14287 - ACCESS(rxfd)command = 0x0000;
14288 - ACCESS(rxfd)link = virt_to_bus(&(ACCESS(rxfd)status));
14289 - ACCESS(rxfd)rx_buf_addr = (int) &nic->packet;
14290 - ACCESS(rxfd)count = 0;
14291 - ACCESS(rxfd)size = 1528;
14293 - outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
14294 - outw(INT_MASK | RX_START, ioaddr + SCBCmd);
14295 - wait_for_cmd_done(ioaddr + SCBCmd);
14297 - whereami ("started RX process.");
14299 - /* Start the reciever.... */
14300 - ACCESS(rxfd)status = 0;
14301 - ACCESS(rxfd)command = 0xc000;
14302 - outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
14303 - outw(INT_MASK | RX_START, ioaddr + SCBCmd);
14305 - /* INIT TX stuff. */
14307 - /* Base = 0 */
14308 - outl(0, ioaddr + SCBPointer);
14309 - outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd);
14310 - wait_for_cmd_done(ioaddr + SCBCmd);
14312 - whereami ("set TX base addr.");
14314 - txfd.command = (CmdIASetup);
14315 - txfd.status = 0x0000;
14316 - txfd.link = virt_to_bus (&confcmd);
14319 - char *t = (char *)&txfd.tx_desc_addr;
14320 + for (i=0;i<ETH_ALEN;i++) {
14321 + nic->node_addr[i] = (eeprom[i/2] >> (8*(i&1))) & 0xff;
14323 + printf ("Ethernet addr: %!\n", nic->node_addr);
14325 - for (i=0;i<ETH_ALEN;i++)
14326 - t[i] = nic->node_addr[i];
14328 + if (sum != 0xBABA)
14329 + printf("eepro100: Invalid EEPROM checksum %#hX, "
14330 + "check settings before activating this device!\n", sum);
14331 + outl(0, ioaddr + SCBPort);
14332 + udelay (10000);
14333 + whereami ("Got eeprom.");
14335 + /* Base = 0 */
14336 + outl(0, ioaddr + SCBPointer);
14337 + outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd);
14338 + wait_for_cmd_done(ioaddr + SCBCmd);
14339 + whereami ("set rx base addr.");
14341 + outl(virt_to_bus(&lstats), ioaddr + SCBPointer);
14342 + outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd);
14343 + wait_for_cmd_done(ioaddr + SCBCmd);
14344 + whereami ("set stats addr.");
14346 + /* INIT RX stuff. */
14347 + ACCESS(rxfd)status = 0x0001;
14348 + ACCESS(rxfd)command = 0x0000;
14349 + ACCESS(rxfd)link = virt_to_bus(&(ACCESS(rxfd)status));
14350 + ACCESS(rxfd)rx_buf_addr = virt_to_bus(&nic->packet);
14351 + ACCESS(rxfd)count = 0;
14352 + ACCESS(rxfd)size = 1528;
14354 + outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
14355 + outw(INT_MASK | RX_START, ioaddr + SCBCmd);
14356 + wait_for_cmd_done(ioaddr + SCBCmd);
14358 + whereami ("started RX process.");
14360 + /* Start the reciever.... */
14361 + ACCESS(rxfd)status = 0;
14362 + ACCESS(rxfd)command = 0xc000;
14363 + outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
14364 + outw(INT_MASK | RX_START, ioaddr + SCBCmd);
14366 + /* INIT TX stuff. */
14368 + /* Base = 0 */
14369 + outl(0, ioaddr + SCBPointer);
14370 + outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd);
14371 + wait_for_cmd_done(ioaddr + SCBCmd);
14373 + whereami ("set TX base addr.");
14375 + txfd.command = (CmdIASetup);
14376 + txfd.status = 0x0000;
14377 + txfd.link = virt_to_bus (&confcmd);
14380 + char *t = (char *)&txfd.tx_desc_addr;
14382 + for (i=0;i<ETH_ALEN;i++)
14383 + t[i] = nic->node_addr[i];
14386 #ifdef DEBUG
14387 - printf ("Setup_eaddr:\n");
14388 - hd (&txfd, 0x20);
14389 + printf ("Setup_eaddr:\n");
14390 + hd (&txfd, 0x20);
14391 #endif
14392 - /* options = 0x40; */ /* 10mbps half duplex... */
14393 - options = 0x00; /* Autosense */
14395 - promisc = 0;
14397 - if ( ((eeprom[6]>>8) & 0x3f) == DP83840
14398 - || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
14399 - int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
14400 - if (congenb)
14401 - mdi_reg23 |= 0x0100;
14402 - printf(" DP83840 specific setup, setting register 23 to %hX.\n",
14403 - mdi_reg23);
14404 - mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
14406 - whereami ("Done DP8340 special setup.");
14407 - if (options != 0) {
14408 - mdio_write(eeprom[6] & 0x1f, 0,
14409 - ((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */
14410 - ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
14411 - whereami ("set mdio_register.");
14413 + /* options = 0x40; */ /* 10mbps half duplex... */
14414 + options = 0x00; /* Autosense */
14416 - confcmd.command = CmdSuspend | CmdConfigure;
14417 - confcmd.status = 0x0000;
14418 - confcmd.link = virt_to_bus (&txfd);
14419 - confcmd.data[1] = (txfifo << 4) | rxfifo;
14420 - confcmd.data[4] = rxdmacount;
14421 - confcmd.data[5] = txdmacount + 0x80;
14422 - confcmd.data[15] = promisc ? 0x49: 0x48;
14423 - confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80;
14424 - confcmd.data[21] = promisc ? 0x0D: 0x05;
14425 +#ifdef PROMISC
14426 + rx_mode = 3;
14427 +#elif ALLMULTI
14428 + rx_mode = 1;
14429 +#else
14430 + rx_mode = 0;
14431 +#endif
14433 - outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
14434 - outw(INT_MASK | CU_START, ioaddr + SCBCmd);
14435 - wait_for_cmd_done(ioaddr + SCBCmd);
14436 + if ( ((eeprom[6]>>8) & 0x3f) == DP83840
14437 + || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
14438 + int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
14439 + if (congenb)
14440 + mdi_reg23 |= 0x0100;
14441 + printf(" DP83840 specific setup, setting register 23 to %hX.\n",
14442 + mdi_reg23);
14443 + mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
14445 + whereami ("Done DP8340 special setup.");
14446 + if (options != 0) {
14447 + mdio_write(eeprom[6] & 0x1f, 0,
14448 + ((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */
14449 + ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
14450 + whereami ("set mdio_register.");
14453 - whereami ("started TX thingy (config, iasetup).");
14454 + confcmd.command = CmdSuspend | CmdConfigure;
14455 + confcmd.status = 0x0000;
14456 + confcmd.link = virt_to_bus (&txfd);
14457 + confcmd.data[1] = (txfifo << 4) | rxfifo;
14458 + confcmd.data[4] = rxdmacount;
14459 + confcmd.data[5] = txdmacount + 0x80;
14460 + confcmd.data[15] = (rx_mode & 2) ? 0x49: 0x48;
14461 + confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80;
14462 + confcmd.data[21] = (rx_mode & 1) ? 0x0D: 0x05;
14464 + outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
14465 + outw(INT_MASK | CU_START, ioaddr + SCBCmd);
14466 + wait_for_cmd_done(ioaddr + SCBCmd);
14468 + whereami ("started TX thingy (config, iasetup).");
14470 + load_timer2(10*TICKS_PER_MS);
14471 + while (!txfd.status && timer2_running())
14472 + /* Wait */;
14474 + /* Read the status register once to disgard stale data */
14475 + mdio_read(eeprom[6] & 0x1f, 1);
14476 + /* Check to see if the network cable is plugged in.
14477 + * This allows for faster failure if there is nothing
14478 + * we can do.
14479 + */
14480 + if (!(mdio_read(eeprom[6] & 0x1f, 1) & (1 << 2))) {
14481 + printf("Valid link not established\n");
14482 + eepro100_disable(dev);
14483 + return 0;
14486 - load_timer2(10*TICKS_PER_MS);
14487 - while (!txfd.status && timer2_running())
14488 - /* Wait */;
14490 - nic->reset = eepro100_reset;
14491 - nic->poll = eepro100_poll;
14492 - nic->transmit = eepro100_transmit;
14493 - nic->disable = eepro100_disable;
14494 - return nic;
14495 + dev->disable = eepro100_disable;
14496 + nic->poll = eepro100_poll;
14497 + nic->transmit = eepro100_transmit;
14498 + nic->irq = eepro100_irq;
14499 + return 1;
14502 /*********************************************************************/
14503 @@ -639,16 +751,59 @@
14504 /* Hexdump a number of bytes from memory... */
14505 void hd (void *where, int n)
14507 - int i;
14508 + int i;
14510 - while (n > 0) {
14511 - printf ("%X ", where);
14512 - for (i=0;i < ( (n>16)?16:n);i++)
14513 - printf (" %hhX", ((char *)where)[i]);
14514 - printf ("\n");
14515 - n -= 16;
14516 - where += 16;
14518 + while (n > 0) {
14519 + printf ("%X ", where);
14520 + for (i=0;i < ( (n>16)?16:n);i++)
14521 + printf (" %hhX", ((char *)where)[i]);
14522 + printf ("\n");
14523 + n -= 16;
14524 + where += 16;
14527 #endif
14529 +static struct pci_id eepro100_nics[] = {
14530 +PCI_ROM(0x8086, 0x1029, "id1029", "Intel EtherExpressPro100 ID1029"),
14531 +PCI_ROM(0x8086, 0x1030, "id1030", "Intel EtherExpressPro100 ID1030"),
14532 +PCI_ROM(0x8086, 0x1031, "82801cam", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
14533 +PCI_ROM(0x8086, 0x1032, "eepro100-1032", "Intel PRO/100 VE Network Connection"),
14534 +PCI_ROM(0x8086, 0x1033, "eepro100-1033", "Intel PRO/100 VM Network Connection"),
14535 +PCI_ROM(0x8086, 0x1034, "eepro100-1034", "Intel PRO/100 VM Network Connection"),
14536 +PCI_ROM(0x8086, 0x1035, "eepro100-1035", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
14537 +PCI_ROM(0x8086, 0x1036, "eepro100-1036", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
14538 +PCI_ROM(0x8086, 0x1037, "eepro100-1037", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
14539 +PCI_ROM(0x8086, 0x1038, "id1038", "Intel PRO/100 VM Network Connection"),
14540 +PCI_ROM(0x8086, 0x1039, "82562et", "Intel PRO100 VE 82562ET"),
14541 +PCI_ROM(0x8086, 0x103a, "id103a", "Intel Corporation 82559 InBusiness 10/100"),
14542 +PCI_ROM(0x8086, 0x103b, "82562etb", "Intel PRO100 VE 82562ETB"),
14543 +PCI_ROM(0x8086, 0x103c, "eepro100-103c", "Intel PRO/100 VM Network Connection"),
14544 +PCI_ROM(0x8086, 0x103d, "eepro100-103d", "Intel PRO/100 VE Network Connection"),
14545 +PCI_ROM(0x8086, 0x103e, "eepro100-103e", "Intel PRO/100 VM Network Connection"),
14546 +PCI_ROM(0x8086, 0x1059, "82551qm", "Intel PRO/100 M Mobile Connection"),
14547 +PCI_ROM(0x8086, 0x1209, "82559er", "Intel EtherExpressPro100 82559ER"),
14548 +PCI_ROM(0x8086, 0x1227, "82865", "Intel 82865 EtherExpress PRO/100A"),
14549 +PCI_ROM(0x8086, 0x1228, "82556", "Intel 82556 EtherExpress PRO/100 Smart"),
14550 +PCI_ROM(0x8086, 0x1229, "eepro100", "Intel EtherExpressPro100"),
14551 +PCI_ROM(0x8086, 0x2449, "82562em", "Intel EtherExpressPro100 82562EM"),
14552 +PCI_ROM(0x8086, 0x2459, "82562-1", "Intel 82562 based Fast Ethernet Connection"),
14553 +PCI_ROM(0x8086, 0x245d, "82562-2", "Intel 82562 based Fast Ethernet Connection"),
14554 +PCI_ROM(0x8086, 0x1050, "82562ez", "Intel 82562EZ Network Connection"),
14555 +PCI_ROM(0x8086, 0x5200, "eepro100-5200", "Intel EtherExpress PRO/100 Intelligent Server"),
14556 +PCI_ROM(0x8086, 0x5201, "eepro100-5201", "Intel EtherExpress PRO/100 Intelligent Server"),
14559 +/* Cards with device ids 0x1030 to 0x103F, 0x2449, 0x2459 or 0x245D might need
14560 + * a workaround for hardware bug on 10 mbit half duplex (see linux driver eepro100.c)
14561 + * 2003/03/17 gbaum */
14564 +struct pci_driver eepro100_driver = {
14565 + .type = NIC_DRIVER,
14566 + .name = "EEPRO100",
14567 + .probe = eepro100_probe,
14568 + .ids = eepro100_nics,
14569 + .id_count = sizeof(eepro100_nics)/sizeof(eepro100_nics[0]),
14570 + .class = 0
14572 Index: b/netboot/elf.h
14573 ===================================================================
14574 --- /dev/null
14575 +++ b/netboot/elf.h
14576 @@ -0,0 +1,234 @@
14577 +#ifndef ELF_H
14578 +#define ELF_H
14580 +#define EI_NIDENT 16 /* Size of e_ident array. */
14582 +/* Values for e_type. */
14583 +#define ET_NONE 0 /* No file type */
14584 +#define ET_REL 1 /* Relocatable file */
14585 +#define ET_EXEC 2 /* Executable file */
14586 +#define ET_DYN 3 /* Shared object file */
14587 +#define ET_CORE 4 /* Core file */
14589 +/* Values for e_machine (architecute). */
14590 +#define EM_NONE 0 /* No machine */
14591 +#define EM_M32 1 /* AT&T WE 32100 */
14592 +#define EM_SPARC 2 /* SUN SPARC */
14593 +#define EM_386 3 /* Intel 80386+ */
14594 +#define EM_68K 4 /* Motorola m68k family */
14595 +#define EM_88K 5 /* Motorola m88k family */
14596 +#define EM_486 6 /* Perhaps disused */
14597 +#define EM_860 7 /* Intel 80860 */
14598 +#define EM_MIPS 8 /* MIPS R3000 big-endian */
14599 +#define EM_S370 9 /* IBM System/370 */
14600 +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
14602 +#define EM_PARISC 15 /* HPPA */
14603 +#define EM_VPP500 17 /* Fujitsu VPP500 */
14604 +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
14605 +#define EM_960 19 /* Intel 80960 */
14606 +#define EM_PPC 20 /* PowerPC */
14607 +#define EM_PPC64 21 /* PowerPC 64-bit */
14608 +#define EM_S390 22 /* IBM S390 */
14610 +#define EM_V800 36 /* NEC V800 series */
14611 +#define EM_FR20 37 /* Fujitsu FR20 */
14612 +#define EM_RH32 38 /* TRW RH-32 */
14613 +#define EM_RCE 39 /* Motorola RCE */
14614 +#define EM_ARM 40 /* ARM */
14615 +#define EM_FAKE_ALPHA 41 /* Digital Alpha */
14616 +#define EM_SH 42 /* Hitachi SH */
14617 +#define EM_SPARCV9 43 /* SPARC v9 64-bit */
14618 +#define EM_TRICORE 44 /* Siemens Tricore */
14619 +#define EM_ARC 45 /* Argonaut RISC Core */
14620 +#define EM_H8_300 46 /* Hitachi H8/300 */
14621 +#define EM_H8_300H 47 /* Hitachi H8/300H */
14622 +#define EM_H8S 48 /* Hitachi H8S */
14623 +#define EM_H8_500 49 /* Hitachi H8/500 */
14624 +#define EM_IA_64 50 /* Intel Merced */
14625 +#define EM_MIPS_X 51 /* Stanford MIPS-X */
14626 +#define EM_COLDFIRE 52 /* Motorola Coldfire */
14627 +#define EM_68HC12 53 /* Motorola M68HC12 */
14628 +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
14629 +#define EM_PCP 55 /* Siemens PCP */
14630 +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
14631 +#define EM_NDR1 57 /* Denso NDR1 microprocessor */
14632 +#define EM_STARCORE 58 /* Motorola Start*Core processor */
14633 +#define EM_ME16 59 /* Toyota ME16 processor */
14634 +#define EM_ST100 60 /* STMicroelectronic ST100 processor */
14635 +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
14636 +#define EM_X86_64 62 /* AMD x86-64 architecture */
14637 +#define EM_PDSP 63 /* Sony DSP Processor */
14639 +#define EM_FX66 66 /* Siemens FX66 microcontroller */
14640 +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
14641 +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
14642 +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
14643 +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
14644 +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
14645 +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
14646 +#define EM_SVX 73 /* Silicon Graphics SVx */
14647 +#define EM_AT19 74 /* STMicroelectronics ST19 8 bit mc */
14648 +#define EM_VAX 75 /* Digital VAX */
14649 +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
14650 +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
14651 +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
14652 +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
14653 +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
14654 +#define EM_HUANY 81 /* Harvard University machine-independent object files */
14655 +#define EM_PRISM 82 /* SiTera Prism */
14656 +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
14657 +#define EM_FR30 84 /* Fujitsu FR30 */
14658 +#define EM_D10V 85 /* Mitsubishi D10V */
14659 +#define EM_D30V 86 /* Mitsubishi D30V */
14660 +#define EM_V850 87 /* NEC v850 */
14661 +#define EM_M32R 88 /* Mitsubishi M32R */
14662 +#define EM_MN10300 89 /* Matsushita MN10300 */
14663 +#define EM_MN10200 90 /* Matsushita MN10200 */
14664 +#define EM_PJ 91 /* picoJava */
14665 +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
14666 +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
14667 +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
14668 +#define EM_NUM 95
14670 +/* Values for p_type. */
14671 +#define PT_NULL 0 /* Unused entry. */
14672 +#define PT_LOAD 1 /* Loadable segment. */
14673 +#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
14674 +#define PT_INTERP 3 /* Pathname of interpreter. */
14675 +#define PT_NOTE 4 /* Auxiliary information. */
14676 +#define PT_SHLIB 5 /* Reserved (not used). */
14677 +#define PT_PHDR 6 /* Location of program header itself. */
14679 +/* Values for p_flags. */
14680 +#define PF_X 0x1 /* Executable. */
14681 +#define PF_W 0x2 /* Writable. */
14682 +#define PF_R 0x4 /* Readable. */
14685 +#define ELF_PROGRAM_RETURNS_BIT 0x8000000 /* e_flags bit 31 */
14687 +#define EI_MAG0 0
14688 +#define ELFMAG0 0x7f
14690 +#define EI_MAG1 1
14691 +#define ELFMAG1 'E'
14693 +#define EI_MAG2 2
14694 +#define ELFMAG2 'L'
14696 +#define EI_MAG3 3
14697 +#define ELFMAG3 'F'
14699 +#define ELFMAG "\177ELF"
14701 +#define EI_CLASS 4 /* File class byte index */
14702 +#define ELFCLASSNONE 0 /* Invalid class */
14703 +#define ELFCLASS32 1 /* 32-bit objects */
14704 +#define ELFCLASS64 2 /* 64-bit objects */
14706 +#define EI_DATA 5 /* Data encodeing byte index */
14707 +#define ELFDATANONE 0 /* Invalid data encoding */
14708 +#define ELFDATA2LSB 1 /* 2's complement little endian */
14709 +#define ELFDATA2MSB 2 /* 2's complement big endian */
14711 +#define EI_VERSION 6 /* File version byte index */
14712 + /* Value must be EV_CURRENT */
14714 +#define EV_NONE 0 /* Invalid ELF Version */
14715 +#define EV_CURRENT 1 /* Current version */
14717 +#define ELF32_PHDR_SIZE (8*4) /* Size of an elf program header */
14719 +#ifndef ASSEMBLY
14721 + * ELF definitions common to all 32-bit architectures.
14722 + */
14724 +typedef uint32_t Elf32_Addr;
14725 +typedef uint16_t Elf32_Half;
14726 +typedef uint32_t Elf32_Off;
14727 +typedef int32_t Elf32_Sword;
14728 +typedef uint32_t Elf32_Word;
14729 +typedef uint32_t Elf32_Size;
14731 +typedef uint64_t Elf64_Addr;
14732 +typedef uint16_t Elf64_Half;
14733 +typedef uint64_t Elf64_Off;
14734 +typedef int32_t Elf64_Sword;
14735 +typedef uint32_t Elf64_Word;
14736 +typedef uint64_t Elf64_Size;
14739 + * ELF header.
14740 + */
14741 +typedef struct {
14742 + unsigned char e_ident[EI_NIDENT]; /* File identification. */
14743 + Elf32_Half e_type; /* File type. */
14744 + Elf32_Half e_machine; /* Machine architecture. */
14745 + Elf32_Word e_version; /* ELF format version. */
14746 + Elf32_Addr e_entry; /* Entry point. */
14747 + Elf32_Off e_phoff; /* Program header file offset. */
14748 + Elf32_Off e_shoff; /* Section header file offset. */
14749 + Elf32_Word e_flags; /* Architecture-specific flags. */
14750 + Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
14751 + Elf32_Half e_phentsize; /* Size of program header entry. */
14752 + Elf32_Half e_phnum; /* Number of program header entries. */
14753 + Elf32_Half e_shentsize; /* Size of section header entry. */
14754 + Elf32_Half e_shnum; /* Number of section header entries. */
14755 + Elf32_Half e_shstrndx; /* Section name strings section. */
14756 +} Elf32_Ehdr;
14758 +typedef struct {
14759 + unsigned char e_ident[EI_NIDENT]; /* File identification. */
14760 + Elf64_Half e_type; /* File type. */
14761 + Elf64_Half e_machine; /* Machine architecture. */
14762 + Elf64_Word e_version; /* ELF format version. */
14763 + Elf64_Addr e_entry; /* Entry point. */
14764 + Elf64_Off e_phoff; /* Program header file offset. */
14765 + Elf64_Off e_shoff; /* Section header file offset. */
14766 + Elf64_Word e_flags; /* Architecture-specific flags. */
14767 + Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
14768 + Elf64_Half e_phentsize; /* Size of program header entry. */
14769 + Elf64_Half e_phnum; /* Number of program header entries. */
14770 + Elf64_Half e_shentsize; /* Size of section header entry. */
14771 + Elf64_Half e_shnum; /* Number of section header entries. */
14772 + Elf64_Half e_shstrndx; /* Section name strings section. */
14773 +} Elf64_Ehdr;
14776 + * Program header.
14777 + */
14778 +typedef struct {
14779 + Elf32_Word p_type; /* Entry type. */
14780 + Elf32_Off p_offset; /* File offset of contents. */
14781 + Elf32_Addr p_vaddr; /* Virtual address (not used). */
14782 + Elf32_Addr p_paddr; /* Physical address. */
14783 + Elf32_Size p_filesz; /* Size of contents in file. */
14784 + Elf32_Size p_memsz; /* Size of contents in memory. */
14785 + Elf32_Word p_flags; /* Access permission flags. */
14786 + Elf32_Size p_align; /* Alignment in memory and file. */
14787 +} Elf32_Phdr;
14789 +typedef struct {
14790 + Elf64_Word p_type; /* Entry type. */
14791 + Elf64_Word p_flags; /* Access permission flags. */
14792 + Elf64_Off p_offset; /* File offset of contents. */
14793 + Elf64_Addr p_vaddr; /* Virtual address (not used). */
14794 + Elf64_Addr p_paddr; /* Physical address. */
14795 + Elf64_Size p_filesz; /* Size of contents in file. */
14796 + Elf64_Size p_memsz; /* Size of contents in memory. */
14797 + Elf64_Size p_align; /* Alignment in memory and file. */
14798 +} Elf64_Phdr;
14800 +/* Standardized Elf image notes for booting... The name for all of these is ELFBoot */
14803 +/* ELF Defines for the current architecture */
14804 +#include "i386_elf.h"
14806 +#endif /* ASSEMBLY */
14808 +//#include "elf_boot.h"
14810 +#endif /* ELF_H */
14811 Index: b/netboot/endian.h
14812 ===================================================================
14813 --- /dev/null
14814 +++ b/netboot/endian.h
14815 @@ -0,0 +1,19 @@
14816 +#ifndef ETHERBOOT_ENDIAN_H
14817 +#define ETHERBOOT_ENDIAN_H
14819 +/* Definitions for byte order, according to significance of bytes,
14820 + from low addresses to high addresses. The value is what you get by
14821 + putting '4' in the most significant byte, '3' in the second most
14822 + significant byte, '2' in the second least significant byte, and '1'
14823 + in the least significant byte, and then writing down one digit for
14824 + each byte, starting with the byte at the lowest address at the left,
14825 + and proceeding to the byte with the highest address at the right. */
14827 +#define __LITTLE_ENDIAN 1234
14828 +#define __BIG_ENDIAN 4321
14829 +#define __PDP_ENDIAN 3412
14831 +#include "i386_endian.h"
14834 +#endif /* ETHERBOOT_ENDIAN_H */
14835 Index: b/netboot/epic100.c
14836 ===================================================================
14837 --- a/netboot/epic100.c
14838 +++ b/netboot/epic100.c
14839 @@ -1,15 +1,18 @@
14841 /* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */
14843 +/* 05/06/2003 timlegge Fixed relocation and implemented Multicast */
14844 #define LINUX_OUT_MACROS
14846 #include "etherboot.h"
14847 +#include "pci.h"
14848 #include "nic.h"
14849 -#include "cards.h"
14850 #include "timer.h"
14851 #include "epic100.h"
14853 -#undef virt_to_bus
14854 -#define virt_to_bus(x) ((unsigned long)x)
14855 +/* Condensed operations for readability */
14856 +#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
14857 +#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
14859 #define TX_RING_SIZE 2 /* use at least 2 buffers for TX */
14860 #define RX_RING_SIZE 2
14861 @@ -26,23 +29,18 @@
14863 /* The EPIC100 Rx and Tx buffer descriptors. */
14864 struct epic_rx_desc {
14865 - unsigned short status;
14866 - unsigned short rxlength;
14867 - unsigned long bufaddr;
14868 - unsigned short buflength;
14869 - unsigned short control;
14870 - unsigned long next;
14871 + unsigned long status;
14872 + unsigned long bufaddr;
14873 + unsigned long buflength;
14874 + unsigned long next;
14877 /* description of the tx descriptors control bits commonly used */
14878 #define TD_STDFLAGS TD_LASTDESC
14880 struct epic_tx_desc {
14881 - unsigned short status;
14882 - unsigned short txlength;
14883 - unsigned long bufaddr;
14884 - unsigned short buflength;
14885 - unsigned short control;
14886 + unsigned long status;
14887 + unsigned long bufaddr;
14888 + unsigned long buflength;
14889 unsigned long next;
14892 @@ -51,12 +49,15 @@
14894 static void epic100_open(void);
14895 static void epic100_init_ring(void);
14896 -static void epic100_disable(struct nic *nic);
14897 -static int epic100_poll(struct nic *nic);
14898 +static void epic100_disable(struct dev *dev);
14899 +static int epic100_poll(struct nic *nic, int retrieve);
14900 static void epic100_transmit(struct nic *nic, const char *destaddr,
14901 unsigned int type, unsigned int len, const char *data);
14902 +#ifdef DEBUG_EEPROM
14903 static int read_eeprom(int location);
14904 +#endif
14905 static int mii_read(int phy_id, int location);
14906 +static void epic100_irq(struct nic *nic, irq_action_t action);
14908 static int ioaddr;
14910 @@ -69,6 +70,7 @@
14911 static int mmctl ;
14912 static int mmdata ;
14913 static int lan0 ;
14914 +static int mc0 ;
14915 static int rxcon ;
14916 static int txcon ;
14917 static int prcdar ;
14918 @@ -80,37 +82,27 @@
14919 static unsigned short eeprom[64];
14920 #endif
14921 static signed char phys[4]; /* MII device addresses. */
14922 -static struct epic_rx_desc rx_ring[RX_RING_SIZE];
14923 -static struct epic_tx_desc tx_ring[TX_RING_SIZE];
14924 -#ifdef USE_LOWMEM_BUFFER
14925 -#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
14926 -#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
14927 -#else
14928 -static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
14929 -static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
14930 -#endif
14931 +static struct epic_rx_desc rx_ring[RX_RING_SIZE]
14932 + __attribute__ ((aligned(4)));
14933 +static struct epic_tx_desc tx_ring[TX_RING_SIZE]
14934 + __attribute__ ((aligned(4)));
14935 +static unsigned char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
14936 +static unsigned char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
14938 /***********************************************************************/
14939 /* Externally visible functions */
14940 /***********************************************************************/
14942 - static void
14943 -epic100_reset(struct nic *nic)
14945 - /* Soft reset the chip. */
14946 - outl(GC_SOFT_RESET, genctl);
14949 - struct nic*
14950 -epic100_probe(struct nic *nic, unsigned short *probeaddrs)
14951 + static int
14952 +epic100_probe(struct dev *dev, struct pci_device *pci)
14954 - unsigned short sum = 0;
14955 - unsigned short value;
14956 + struct nic *nic = (struct nic *)dev;
14957 int i;
14958 unsigned short* ap;
14959 unsigned int phy, phy_idx;
14961 - if (probeaddrs == 0 || probeaddrs[0] == 0)
14962 + if (pci->ioaddr == 0)
14963 return 0;
14965 /* Ideally we would detect all network cards in slot order. That would
14966 @@ -118,7 +110,9 @@
14967 well with the current structure. So instead we detect just the
14968 Epic cards in slot order. */
14970 - ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
14971 + ioaddr = pci->ioaddr;
14972 + nic->irqno = 0;
14973 + nic->ioaddr = pci->ioaddr & ~3;
14975 /* compute all used static epic100 registers address */
14976 command = ioaddr + COMMAND; /* Control Register */
14977 @@ -130,6 +124,7 @@
14978 mmctl = ioaddr + MMCTL; /* MII Management Interface Control */
14979 mmdata = ioaddr + MMDATA; /* MII Management Interface Data */
14980 lan0 = ioaddr + LAN0; /* MAC address. (0x40-0x48) */
14981 + mc0 = ioaddr + MC0; /* Multicast Control */
14982 rxcon = ioaddr + RXCON; /* Receive Control */
14983 txcon = ioaddr + TXCON; /* Transmit Control */
14984 prcdar = ioaddr + PRCDAR; /* PCI Receive Current Descr Address */
14985 @@ -160,11 +155,15 @@
14988 #ifdef DEBUG_EEPROM
14990 + unsigned short sum = 0;
14991 + unsigned short value;
14992 for (i = 0; i < 64; i++) {
14993 value = read_eeprom(i);
14994 eeprom[i] = value;
14995 sum += value;
14999 #if (EPIC_DEBUG > 1)
15000 printf("EEPROM contents\n");
15001 @@ -202,15 +201,26 @@
15003 epic100_open();
15005 - nic->reset = epic100_reset;
15006 + dev->disable = epic100_disable;
15007 nic->poll = epic100_poll;
15008 nic->transmit = epic100_transmit;
15009 - nic->disable = epic100_disable;
15010 + nic->irq = epic100_irq;
15012 - return nic;
15013 + return 1;
15016 - static void
15017 +static void set_rx_mode(void)
15019 + unsigned char mc_filter[8];
15020 + int i;
15021 + memset(mc_filter, 0xff, sizeof(mc_filter));
15022 + outl(0x0C, rxcon);
15023 + for(i = 0; i < 4; i++)
15024 + outw(((unsigned short *)mc_filter)[i], mc0 + i*4);
15025 + return;
15028 + static void
15029 epic100_open(void)
15031 int mii_reg5;
15032 @@ -237,11 +247,11 @@
15033 outl(tmp, txcon);
15035 /* Give adress of RX and TX ring to the chip */
15036 - outl(virt_to_bus(&rx_ring), prcdar);
15037 - outl(virt_to_bus(&tx_ring), ptcdar);
15038 + outl(virt_to_le32desc(&rx_ring), prcdar);
15039 + outl(virt_to_le32desc(&tx_ring), ptcdar);
15041 /* Start the chip's Rx process: receive unicast and broadcast */
15042 - outl(0x04, rxcon);
15043 + set_rx_mode();
15044 outl(CR_START_RX | CR_QUEUE_RX, command);
15046 putchar('\n');
15047 @@ -252,34 +262,30 @@
15048 epic100_init_ring(void)
15050 int i;
15051 - char* p;
15053 cur_rx = cur_tx = 0;
15055 - p = &rx_packet[0];
15056 for (i = 0; i < RX_RING_SIZE; i++) {
15057 - rx_ring[i].status = RRING_OWN; /* Owned by Epic chip */
15058 - rx_ring[i].buflength = PKT_BUF_SZ;
15059 - rx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
15060 - rx_ring[i].control = 0;
15061 - rx_ring[i].next = virt_to_bus(&(rx_ring[i + 1]) );
15062 + rx_ring[i].status = cpu_to_le32(RRING_OWN); /* Owned by Epic chip */
15063 + rx_ring[i].buflength = cpu_to_le32(PKT_BUF_SZ);
15064 + rx_ring[i].bufaddr = virt_to_bus(&rx_packet[i * PKT_BUF_SZ]);
15065 + rx_ring[i].next = virt_to_le32desc(&rx_ring[i + 1]) ;
15067 /* Mark the last entry as wrapping the ring. */
15068 - rx_ring[i-1].next = virt_to_bus(&rx_ring[0]);
15069 + rx_ring[i-1].next = virt_to_le32desc(&rx_ring[0]);
15072 *The Tx buffer descriptor is filled in as needed,
15073 * but we do need to clear the ownership bit.
15075 - p = &tx_packet[0];
15077 for (i = 0; i < TX_RING_SIZE; i++) {
15078 - tx_ring[i].status = 0; /* Owned by CPU */
15079 - tx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
15080 - tx_ring[i].control = TD_STDFLAGS;
15081 - tx_ring[i].next = virt_to_bus(&(tx_ring[i + 1]) );
15082 + tx_ring[i].status = 0x0000; /* Owned by CPU */
15083 + tx_ring[i].buflength = 0x0000 | cpu_to_le32(TD_STDFLAGS << 16);
15084 + tx_ring[i].bufaddr = virt_to_bus(&tx_packet[i * PKT_BUF_SZ]);
15085 + tx_ring[i].next = virt_to_le32desc(&tx_ring[i + 1]);
15087 - tx_ring[i-1].next = virt_to_bus(&tx_ring[0]);
15088 + tx_ring[i-1].next = virt_to_le32desc(&tx_ring[0]);
15091 /* function: epic100_transmit
15092 @@ -296,7 +302,7 @@
15093 unsigned int len, const char *data)
15095 unsigned short nstype;
15096 - char* txp;
15097 + unsigned char *txp;
15098 int entry;
15100 /* Calculate the next Tx descriptor entry. */
15101 @@ -310,7 +316,7 @@
15102 return;
15105 - txp = (char*)tx_ring[entry].bufaddr;
15106 + txp = tx_packet + (entry * PKT_BUF_SZ);
15108 memcpy(txp, destaddr, ETH_ALEN);
15109 memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
15110 @@ -319,26 +325,29 @@
15111 memcpy(txp + ETH_HLEN, data, len);
15113 len += ETH_HLEN;
15115 + len &= 0x0FFF;
15116 + while(len < ETH_ZLEN)
15117 + txp[len++] = '\0';
15119 * Caution: the write order is important here,
15120 * set the base address with the "ownership"
15121 * bits last.
15123 - tx_ring[entry].txlength = (len >= 60 ? len : 60);
15124 - tx_ring[entry].buflength = len;
15125 - tx_ring[entry].status = TRING_OWN; /* Pass ownership to the chip. */
15127 + tx_ring[entry].buflength |= cpu_to_le32(len);
15128 + tx_ring[entry].status = cpu_to_le32(len << 16) |
15129 + cpu_to_le32(TRING_OWN); /* Pass ownership to the chip. */
15131 cur_tx++;
15133 /* Trigger an immediate transmit demand. */
15134 - outl(CR_QUEUE_TX, command);
15136 + outl(CR_QUEUE_TX, command);
15138 load_timer2(10*TICKS_PER_MS); /* timeout 10 ms for transmit */
15139 - while ((tx_ring[entry].status & TRING_OWN) && timer2_running())
15140 + while ((le32_to_cpu(tx_ring[entry].status) & (TRING_OWN)) && timer2_running())
15141 /* Wait */;
15143 - if ((tx_ring[entry].status & TRING_OWN) != 0)
15144 + if ((le32_to_cpu(tx_ring[entry].status) & TRING_OWN) != 0)
15145 printf("Oops, transmitter timeout, status=%hX\n",
15146 tx_ring[entry].status);
15148 @@ -356,17 +365,19 @@
15151 static int
15152 -epic100_poll(struct nic *nic)
15153 +epic100_poll(struct nic *nic, int retrieve)
15155 int entry;
15156 - int status;
15157 int retcode;
15159 + int status;
15160 entry = cur_rx % RX_RING_SIZE;
15162 - if ((status = rx_ring[entry].status & RRING_OWN) == RRING_OWN)
15163 + if ((rx_ring[entry].status & cpu_to_le32(RRING_OWN)) == RRING_OWN)
15164 return (0);
15166 + if ( ! retrieve ) return 1;
15168 + status = le32_to_cpu(rx_ring[entry].status);
15169 /* We own the next entry, it's a new packet. Send it up. */
15171 #if (EPIC_DEBUG > 4)
15172 @@ -383,8 +394,8 @@
15173 retcode = 0;
15174 } else {
15175 /* Omit the four octet CRC from the length. */
15176 - nic->packetlen = rx_ring[entry].rxlength - 4;
15177 - memcpy(nic->packet, (char*)rx_ring[entry].bufaddr, nic->packetlen);
15178 + nic->packetlen = le32_to_cpu((rx_ring[entry].buflength))- 4;
15179 + memcpy(nic->packet, &rx_packet[entry * PKT_BUF_SZ], nic->packetlen);
15180 retcode = 1;
15183 @@ -395,17 +406,30 @@
15184 rx_ring[entry].status = RRING_OWN;
15186 /* Restart Receiver */
15187 - outl(CR_START_RX | CR_QUEUE_RX, command);
15188 + outl(CR_START_RX | CR_QUEUE_RX, command);
15190 return retcode;
15194 static void
15195 -epic100_disable(struct nic *nic)
15196 +epic100_disable(struct dev *dev __unused)
15198 + /* Soft reset the chip. */
15199 + outl(GC_SOFT_RESET, genctl);
15202 +static void epic100_irq(struct nic *nic __unused, irq_action_t action __unused)
15204 + switch ( action ) {
15205 + case DISABLE :
15206 + break;
15207 + case ENABLE :
15208 + break;
15209 + case FORCE :
15210 + break;
15214 #ifdef DEBUG_EEPROM
15215 /* Serial EEPROM section. */
15216 @@ -479,3 +503,18 @@
15217 break;
15218 return inw(mmdata);
15222 +static struct pci_id epic100_nics[] = {
15223 +PCI_ROM(0x10b8, 0x0005, "epic100", "SMC EtherPowerII"), /* SMC 83c170 EPIC/100 */
15224 +PCI_ROM(0x10b8, 0x0006, "smc-83c175", "SMC EPIC/C 83c175"),
15227 +struct pci_driver epic100_driver = {
15228 + .type = NIC_DRIVER,
15229 + .name = "EPIC100",
15230 + .probe = epic100_probe,
15231 + .ids = epic100_nics,
15232 + .id_count = sizeof(epic100_nics)/sizeof(epic100_nics[0]),
15233 + .class = 0,
15235 Index: b/netboot/etherboot.h
15236 ===================================================================
15237 --- a/netboot/etherboot.h
15238 +++ b/netboot/etherboot.h
15239 @@ -1,6 +1,6 @@
15241 * GRUB -- GRand Unified Bootloader
15242 - * Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
15243 + * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
15245 * This program is free software; you can redistribute it and/or modify
15246 * it under the terms of the GNU General Public License as published by
15247 @@ -17,528 +17,40 @@
15248 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15251 -/* RULE: You must define the macro ``GRUB'' when including this header
15252 - file in GRUB code. */
15253 +#ifndef ETHERBOOT_H
15254 +#define ETHERBOOT_H
15256 -/* Based on "src/etherboot.h" in etherboot-5.0.5. */
15258 -/**************************************************************************
15259 -ETHERBOOT - BOOTP/TFTP Bootstrap Program
15261 -Author: Martin Renters
15262 - Date: Dec/93
15264 -**************************************************************************/
15266 -/* Include GRUB-specific macros and prototypes here. */
15267 -#include <shared.h>
15269 -/* FIXME: For now, enable the DHCP support. Perhaps I should segregate
15270 - the DHCP support from the BOOTP support, and permit both to
15271 - co-exist. */
15272 -#undef NO_DHCP_SUPPORT
15274 -/* In GRUB, the relocated address in Etherboot doesn't have any sense.
15275 - Just define it as a bogus value. */
15276 -#define RELOC 0
15278 -/* FIXME: Should be an option. */
15279 -#define BACKOFF_LIMIT 7
15281 -#include <osdep.h>
15283 -#define CTRL_C 3
15285 -#ifndef MAX_TFTP_RETRIES
15286 -# define MAX_TFTP_RETRIES 20
15287 +#include "shared.h"
15288 +#include "osdep.h"
15289 +#include "if_ether.h"
15290 +#include "in.h"
15292 +/* Link configuration time in tenths of a second */
15293 +#ifndef VALID_LINK_TIMEOUT
15294 +#define VALID_LINK_TIMEOUT 100 /* 10.0 seconds */
15295 #endif
15297 -#ifndef MAX_BOOTP_RETRIES
15298 -# define MAX_BOOTP_RETRIES 20
15299 -#endif
15301 -#define MAX_BOOTP_EXTLEN (ETH_FRAME_LEN - ETH_HLEN - \
15302 - sizeof (struct bootp_t))
15304 -#ifndef MAX_ARP_RETRIES
15305 -# define MAX_ARP_RETRIES 20
15306 -#endif
15308 -#ifndef MAX_RPC_RETRIES
15309 -# define MAX_RPC_RETRIES 20
15310 -#endif
15312 -#define TICKS_PER_SEC 18
15314 -/* Inter-packet retry in ticks */
15315 -#define TIMEOUT (10 * TICKS_PER_SEC)
15317 -/* These settings have sense only if compiled with -DCONGESTED */
15318 -/* total retransmission timeout in ticks */
15319 -#define TFTP_TIMEOUT (30 * TICKS_PER_SEC)
15320 -/* packet retransmission timeout in ticks */
15321 -#define TFTP_REXMT (3 * TICKS_PER_SEC)
15323 #ifndef NULL
15324 # define NULL ((void *) 0)
15325 #endif
15328 - I'm moving towards the defined names in linux/if_ether.h for clarity.
15329 - The confusion between 60/64 and 1514/1518 arose because the NS8390
15330 - counts the 4 byte frame checksum in the incoming packet, but not
15331 - in the outgoing packet. 60/1514 are the correct numbers for most
15332 - if not all of the other NIC controllers. I will be retiring the
15333 - 64/1518 defines in the lead-up to 5.0.
15336 -#define ETH_ALEN 6 /* Size of Ethernet address */
15337 -#define ETH_HLEN 14 /* Size of ethernet header */
15338 -#define ETH_ZLEN 60 /* Minimum packet */
15339 -/*#define ETH_MIN_PACKET 64*/
15340 -#define ETH_FRAME_LEN 1514 /* Maximum packet */
15341 -/*#define ETH_MAX_PACKET 1518*/
15342 -/* Because some DHCP/BOOTP servers don't treat the maximum length the same
15343 - as Etherboot, subtract the size of an IP header and that of an UDP
15344 - header. */
15345 -#define ETH_MAX_MTU (ETH_FRAME_LEN - ETH_HLEN \
15346 - - sizeof (struct iphdr) \
15347 - - sizeof (struct udphdr))
15349 -#define ARP_CLIENT 0
15350 -#define ARP_SERVER 1
15351 -#define ARP_GATEWAY 2
15352 -#define ARP_ROOTSERVER 3
15353 -#define ARP_SWAPSERVER 4
15354 -#define MAX_ARP ARP_SWAPSERVER+1
15356 -#define RARP_REQUEST 3
15357 -#define RARP_REPLY 4
15359 -#define IP 0x0800
15360 -#define ARP 0x0806
15361 -#define RARP 0x8035
15363 -#define BOOTP_SERVER 67
15364 -#define BOOTP_CLIENT 68
15365 -#define TFTP_PORT 69
15366 -#define SUNRPC_PORT 111
15368 -#define IP_UDP 17
15369 -/* Same after going through htonl */
15370 -#define IP_BROADCAST 0xFFFFFFFF
15372 -#define ARP_REQUEST 1
15373 -#define ARP_REPLY 2
15375 -#define BOOTP_REQUEST 1
15376 -#define BOOTP_REPLY 2
15378 -#define TAG_LEN(p) (*((p) + 1))
15379 -#define RFC1533_COOKIE 99, 130, 83, 99
15380 -#define RFC1533_PAD 0
15381 -#define RFC1533_NETMASK 1
15382 -#define RFC1533_TIMEOFFSET 2
15383 -#define RFC1533_GATEWAY 3
15384 -#define RFC1533_TIMESERVER 4
15385 -#define RFC1533_IEN116NS 5
15386 -#define RFC1533_DNS 6
15387 -#define RFC1533_LOGSERVER 7
15388 -#define RFC1533_COOKIESERVER 8
15389 -#define RFC1533_LPRSERVER 9
15390 -#define RFC1533_IMPRESSSERVER 10
15391 -#define RFC1533_RESOURCESERVER 11
15392 -#define RFC1533_HOSTNAME 12
15393 -#define RFC1533_BOOTFILESIZE 13
15394 -#define RFC1533_MERITDUMPFILE 14
15395 -#define RFC1533_DOMAINNAME 15
15396 -#define RFC1533_SWAPSERVER 16
15397 -#define RFC1533_ROOTPATH 17
15398 -#define RFC1533_EXTENSIONPATH 18
15399 -#define RFC1533_IPFORWARDING 19
15400 -#define RFC1533_IPSOURCEROUTING 20
15401 -#define RFC1533_IPPOLICYFILTER 21
15402 -#define RFC1533_IPMAXREASSEMBLY 22
15403 -#define RFC1533_IPTTL 23
15404 -#define RFC1533_IPMTU 24
15405 -#define RFC1533_IPMTUPLATEAU 25
15406 -#define RFC1533_INTMTU 26
15407 -#define RFC1533_INTLOCALSUBNETS 27
15408 -#define RFC1533_INTBROADCAST 28
15409 -#define RFC1533_INTICMPDISCOVER 29
15410 -#define RFC1533_INTICMPRESPOND 30
15411 -#define RFC1533_INTROUTEDISCOVER 31
15412 -#define RFC1533_INTROUTESOLICIT 32
15413 -#define RFC1533_INTSTATICROUTES 33
15414 -#define RFC1533_LLTRAILERENCAP 34
15415 -#define RFC1533_LLARPCACHETMO 35
15416 -#define RFC1533_LLETHERNETENCAP 36
15417 -#define RFC1533_TCPTTL 37
15418 -#define RFC1533_TCPKEEPALIVETMO 38
15419 -#define RFC1533_TCPKEEPALIVEGB 39
15420 -#define RFC1533_NISDOMAIN 40
15421 -#define RFC1533_NISSERVER 41
15422 -#define RFC1533_NTPSERVER 42
15423 -#define RFC1533_VENDOR 43
15424 -#define RFC1533_NBNS 44
15425 -#define RFC1533_NBDD 45
15426 -#define RFC1533_NBNT 46
15427 -#define RFC1533_NBSCOPE 47
15428 -#define RFC1533_XFS 48
15429 -#define RFC1533_XDM 49
15430 -#ifndef NO_DHCP_SUPPORT
15431 -#define RFC2132_REQ_ADDR 50
15432 -#define RFC2132_MSG_TYPE 53
15433 -#define RFC2132_SRV_ID 54
15434 -#define RFC2132_PARAM_LIST 55
15435 -#define RFC2132_MAX_SIZE 57
15436 -#define RFC2132_VENDOR_CLASS_ID 60
15438 -#define DHCPDISCOVER 1
15439 -#define DHCPOFFER 2
15440 -#define DHCPREQUEST 3
15441 -#define DHCPACK 5
15442 -#endif /* NO_DHCP_SUPPORT */
15444 -#define RFC1533_VENDOR_MAJOR 0
15445 -#define RFC1533_VENDOR_MINOR 0
15447 -#define RFC1533_VENDOR_MAGIC 128
15448 -#define RFC1533_VENDOR_ADDPARM 129
15449 -#define RFC1533_VENDOR_MNUOPTS 160
15450 -#define RFC1533_VENDOR_SELECTION 176
15451 -#define RFC1533_VENDOR_MOTD 184
15452 -#define RFC1533_VENDOR_NUMOFMOTD 8
15453 -#define RFC1533_VENDOR_IMG 192
15454 -#define RFC1533_VENDOR_NUMOFIMG 16
15456 -#define RFC1533_VENDOR_CONFIGFILE 150
15458 -#define RFC1533_END 255
15460 -#define BOOTP_VENDOR_LEN 64
15461 -#ifndef NO_DHCP_SUPPORT
15462 -#define DHCP_OPT_LEN 312
15463 -#endif /* NO_DHCP_SUPPORT */
15465 -#define TFTP_DEFAULTSIZE_PACKET 512
15466 -#define TFTP_MAX_PACKET 1432 /* 512 */
15468 -#define TFTP_RRQ 1
15469 -#define TFTP_WRQ 2
15470 -#define TFTP_DATA 3
15471 -#define TFTP_ACK 4
15472 -#define TFTP_ERROR 5
15473 -#define TFTP_OACK 6
15475 -#define TFTP_CODE_EOF 1
15476 -#define TFTP_CODE_MORE 2
15477 -#define TFTP_CODE_ERROR 3
15478 -#define TFTP_CODE_BOOT 4
15479 -#define TFTP_CODE_CFG 5
15481 -#define AWAIT_ARP 0
15482 -#define AWAIT_BOOTP 1
15483 -#define AWAIT_TFTP 2
15484 -#define AWAIT_RARP 3
15485 -#define AWAIT_RPC 4
15486 -#define AWAIT_QDRAIN 5 /* drain queue, process ARP requests */
15488 -typedef struct
15490 - unsigned long s_addr;
15492 -in_addr;
15494 -struct arptable_t
15496 - in_addr ipaddr;
15497 - unsigned char node[6];
15501 - * A pity sipaddr and tipaddr are not longword aligned or we could use
15502 - * in_addr. No, I don't want to use #pragma packed.
15503 - */
15504 -struct arprequest
15506 - unsigned short hwtype;
15507 - unsigned short protocol;
15508 - char hwlen;
15509 - char protolen;
15510 - unsigned short opcode;
15511 - char shwaddr[6];
15512 - char sipaddr[4];
15513 - char thwaddr[6];
15514 - char tipaddr[4];
15517 -struct iphdr
15519 - char verhdrlen;
15520 - char service;
15521 - unsigned short len;
15522 - unsigned short ident;
15523 - unsigned short frags;
15524 - char ttl;
15525 - char protocol;
15526 - unsigned short chksum;
15527 - in_addr src;
15528 - in_addr dest;
15531 -struct udphdr
15533 - unsigned short src;
15534 - unsigned short dest;
15535 - unsigned short len;
15536 - unsigned short chksum;
15539 -/* Format of a bootp packet. */
15540 -struct bootp_t
15542 - char bp_op;
15543 - char bp_htype;
15544 - char bp_hlen;
15545 - char bp_hops;
15546 - unsigned long bp_xid;
15547 - unsigned short bp_secs;
15548 - unsigned short unused;
15549 - in_addr bp_ciaddr;
15550 - in_addr bp_yiaddr;
15551 - in_addr bp_siaddr;
15552 - in_addr bp_giaddr;
15553 - char bp_hwaddr[16];
15554 - char bp_sname[64];
15555 - char bp_file[128];
15556 -#ifdef NO_DHCP_SUPPORT
15557 - char bp_vend[BOOTP_VENDOR_LEN];
15558 -#else
15559 - char bp_vend[DHCP_OPT_LEN];
15560 -#endif /* NO_DHCP_SUPPORT */
15563 -/* Format of a bootp IP packet. */
15564 -struct bootpip_t
15566 - struct iphdr ip;
15567 - struct udphdr udp;
15568 - struct bootp_t bp;
15571 -/* Format of bootp packet with extensions. */
15572 -struct bootpd_t
15574 - struct bootp_t bootp_reply;
15575 - unsigned char bootp_extension[MAX_BOOTP_EXTLEN];
15578 -struct tftp_t
15580 - struct iphdr ip;
15581 - struct udphdr udp;
15582 - unsigned short opcode;
15583 - union
15585 - char rrq[TFTP_DEFAULTSIZE_PACKET];
15587 - struct
15589 - unsigned short block;
15590 - char download[TFTP_MAX_PACKET];
15592 - data;
15594 - struct
15596 - unsigned short block;
15598 - ack;
15600 - struct
15602 - unsigned short errcode;
15603 - char errmsg[TFTP_DEFAULTSIZE_PACKET];
15605 - err;
15607 - struct
15609 - char data[TFTP_DEFAULTSIZE_PACKET+2];
15611 - oack;
15613 - u;
15616 -/* Define a smaller tftp packet solely for making requests to conserve stack
15617 - 512 bytes should be enough. */
15618 -struct tftpreq_t
15620 - struct iphdr ip;
15621 - struct udphdr udp;
15622 - unsigned short opcode;
15623 - union
15625 - char rrq[512];
15627 - struct
15629 - unsigned short block;
15631 - ack;
15633 - struct
15635 - unsigned short errcode;
15636 - char errmsg[512-2];
15638 - err;
15640 - u;
15643 -#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
15645 -struct rpc_t
15647 - struct iphdr ip;
15648 - struct udphdr udp;
15649 - union
15651 - char data[300]; /* longest RPC call must fit!!!! */
15653 - struct
15655 - long id;
15656 - long type;
15657 - long rpcvers;
15658 - long prog;
15659 - long vers;
15660 - long proc;
15661 - long data[1];
15663 - call;
15665 - struct
15667 - long id;
15668 - long type;
15669 - long rstatus;
15670 - long verifier;
15671 - long v2;
15672 - long astatus;
15673 - long data[1];
15675 - reply;
15677 - u;
15680 -#define PROG_PORTMAP 100000
15681 -#define PROG_NFS 100003
15682 -#define PROG_MOUNT 100005
15684 -#define MSG_CALL 0
15685 -#define MSG_REPLY 1
15687 -#define PORTMAP_GETPORT 3
15689 -#define MOUNT_ADDENTRY 1
15690 -#define MOUNT_UMOUNTALL 4
15692 -#define NFS_LOOKUP 4
15693 -#define NFS_READ 6
15695 -#define NFS_FHSIZE 32
15697 -#define NFSERR_PERM 1
15698 -#define NFSERR_NOENT 2
15699 -#define NFSERR_ACCES 13
15701 -/* Block size used for NFS read accesses. A RPC reply packet (including all
15702 - * headers) must fit within a single Ethernet frame to avoid fragmentation.
15703 - * Chosen to be a power of two, as most NFS servers are optimized for this. */
15704 -#define NFS_READ_SIZE 1024
15706 -#define FLOPPY_BOOT_LOCATION 0x7c00
15707 -/* Must match offsets in loader.S */
15708 -#define ROM_SEGMENT 0x1fa
15709 -#define ROM_LENGTH 0x1fc
15711 -#define ROM_INFO_LOCATION (FLOPPY_BOOT_LOCATION + ROM_SEGMENT)
15712 -/* at end of floppy boot block */
15714 -struct rom_info
15716 - unsigned short rom_segment;
15717 - unsigned short rom_length;
15720 -static inline int
15721 -rom_address_ok (struct rom_info *rom, int assigned_rom_segment)
15723 - return (assigned_rom_segment < 0xC000
15724 - || assigned_rom_segment == rom->rom_segment);
15727 -/* Define a type for passing info to a loaded program. */
15728 -struct ebinfo
15730 - unsigned char major, minor; /* Version */
15731 - unsigned short flags; /* Bit flags */
15734 -/***************************************************************************
15735 -External prototypes
15736 -***************************************************************************/
15737 -/* main.c */
15738 -extern void print_network_configuration (void);
15739 -extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
15740 -extern int udp_transmit (unsigned long destip, unsigned int srcsock,
15741 - unsigned int destsock, int len, const void *buf);
15742 -extern int await_reply (int type, int ival, void *ptr, int timeout);
15743 -extern int decode_rfc1533 (unsigned char *, int, int, int);
15744 -extern long rfc2131_sleep_interval (int base, int exp);
15745 -extern void cleanup (void);
15746 -extern int rarp (void);
15747 -extern int bootp (void);
15748 -extern void cleanup_net (void);
15750 -/* config.c */
15751 -extern void print_config (void);
15752 -extern void eth_reset (void);
15753 -extern int eth_probe (void);
15754 -extern int eth_poll (void);
15755 -extern void eth_transmit (const char *d, unsigned int t,
15756 - unsigned int s, const void *p);
15757 -extern void eth_disable (void);
15759 -/* misc.c */
15760 -extern void twiddle (void);
15761 -extern void sleep (int secs);
15762 -extern int getdec (char **s);
15763 -extern void etherboot_printf (const char *, ...);
15764 -extern int etherboot_sprintf (char *, const char *, ...);
15765 -extern int inet_aton (char *p, in_addr *i);
15767 -/***************************************************************************
15768 -External variables
15769 -***************************************************************************/
15770 -/* main.c */
15771 -extern int ip_abort;
15772 -extern int network_ready;
15773 -extern struct rom_info rom;
15774 -extern struct arptable_t arptable[MAX_ARP];
15776 -/* config.c */
15777 -extern struct nic nic;
15778 +#define gateA20_set() gateA20(1)
15779 +#define gateA20_unset() gateA20(0)
15780 +#define EBDEBUG 0
15781 +/* The 'rom_info' maybe arch depended. It must be moved to some other
15782 + * place */
15783 +struct rom_info {
15784 + unsigned short rom_segment;
15785 + unsigned short rom_length;
15788 +extern void poll_interruptions P((void));
15790 +/* For UNDI drivers */
15791 +extern void fake_irq ( uint8_t irq );
15792 +extern void _trivial_irq_handler_start;
15793 +extern uint32_t get_free_base_memory ( void );
15794 +extern void forget_base_memory ( void*, size_t );
15795 +extern void free_unused_base_memory ( void );
15797 -/* Local hack - define some macros to use etherboot source files "as is". */
15798 -#ifndef GRUB
15799 -# undef printf
15800 -# define printf etherboot_printf
15801 -# undef sprintf
15802 -# define sprintf etherboot_sprintf
15803 -#endif /* GRUB */
15804 +#endif /* ETHERBOOT_H */
15805 Index: b/netboot/fa311.c
15806 ===================================================================
15807 --- a/netboot/fa311.c
15808 +++ /dev/null
15809 @@ -1,421 +0,0 @@
15811 - Driver for the National Semiconductor DP83810 Ethernet controller.
15813 - Portions Copyright (C) 2001 Inprimis Technologies, Inc.
15814 - http://www.inprimis.com/
15816 - This driver is based (heavily) on the Linux driver for this chip
15817 - which is copyright 1999-2001 by Donald Becker.
15819 - This software has no warranties expressed or implied for any
15820 - purpose.
15822 - This software may be used and distributed according to the terms of
15823 - the GNU General Public License (GPL), incorporated herein by reference.
15824 - Drivers based on or derived from this code fall under the GPL and must
15825 - retain the authorship, copyright and license notice. This file is not
15826 - a complete program and may only be used when the entire operating
15827 - system is licensed under the GPL. License for under other terms may be
15828 - available. Contact the original author for details.
15830 - The original author may be reached as becker@scyld.com, or at
15831 - Scyld Computing Corporation
15832 - 410 Severn Ave., Suite 210
15833 - Annapolis MD 21403
15837 -typedef unsigned char u8;
15838 -typedef signed char s8;
15839 -typedef unsigned short u16;
15840 -typedef signed short s16;
15841 -typedef unsigned int u32;
15842 -typedef signed int s32;
15844 -#include "etherboot.h"
15845 -#include "nic.h"
15846 -#include "pci.h"
15848 -#undef virt_to_bus
15849 -#define virt_to_bus(x) ((unsigned long)x)
15850 -#define cpu_to_le32(val) (val)
15851 -#define le32_to_cpu(val) (val)
15852 -#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
15853 -#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
15855 -#define TX_RING_SIZE 1
15856 -#define RX_RING_SIZE 4
15857 -#define TIME_OUT 1000000
15858 -#define PKT_BUF_SZ 1536
15860 -/* Offsets to the device registers. */
15861 -enum register_offsets {
15862 - ChipCmd=0x00, ChipConfig=0x04, EECtrl=0x08, PCIBusCfg=0x0C,
15863 - IntrStatus=0x10, IntrMask=0x14, IntrEnable=0x18,
15864 - TxRingPtr=0x20, TxConfig=0x24,
15865 - RxRingPtr=0x30, RxConfig=0x34,
15866 - WOLCmd=0x40, PauseCmd=0x44, RxFilterAddr=0x48, RxFilterData=0x4C,
15867 - BootRomAddr=0x50, BootRomData=0x54, StatsCtrl=0x5C, StatsData=0x60,
15868 - RxPktErrs=0x60, RxMissed=0x68, RxCRCErrs=0x64,
15871 -/* Bit in ChipCmd. */
15872 -enum ChipCmdBits {
15873 - ChipReset=0x100, RxReset=0x20, TxReset=0x10, RxOff=0x08, RxOn=0x04,
15874 - TxOff=0x02, TxOn=0x01,
15877 -/* Bits in the interrupt status/mask registers. */
15878 -enum intr_status_bits {
15879 - IntrRxDone=0x0001, IntrRxIntr=0x0002, IntrRxErr=0x0004, IntrRxEarly=0x0008,
15880 - IntrRxIdle=0x0010, IntrRxOverrun=0x0020,
15881 - IntrTxDone=0x0040, IntrTxIntr=0x0080, IntrTxErr=0x0100,
15882 - IntrTxIdle=0x0200, IntrTxUnderrun=0x0400,
15883 - StatsMax=0x0800, LinkChange=0x4000, WOLPkt=0x2000,
15884 - RxResetDone=0x1000000, TxResetDone=0x2000000,
15885 - IntrPCIErr=0x00f00000, IntrNormalSummary=0x0251, IntrAbnormalSummary=0xED20,
15888 -/* Bits in the RxMode register. */
15889 -enum rx_mode_bits {
15890 - AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0xC0000000,
15891 - AcceptMulticast=0x00200000, AcceptAllMulticast=0x20000000,
15892 - AcceptAllPhys=0x10000000, AcceptMyPhys=0x08000000,
15895 -/* Bits in network_desc.status */
15896 -enum desc_status_bits {
15897 - DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,
15898 - DescNoCRC=0x10000000,
15899 - DescPktOK=0x08000000, RxTooLong=0x00400000,
15902 -/* The Rx and Tx buffer descriptors. */
15903 -struct netdev_desc {
15904 - u32 next_desc;
15905 - s32 cmd_status;
15906 - u32 addr;
15909 -static struct FA311_DEV {
15910 - unsigned int ioaddr;
15911 - unsigned short vendor;
15912 - unsigned short device;
15913 - unsigned int cur_rx;
15914 - unsigned int cur_tx;
15915 - unsigned int rx_buf_sz;
15916 - volatile struct netdev_desc *rx_head_desc;
15917 - volatile struct netdev_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned (4)));
15918 - volatile struct netdev_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned (4)));
15919 -} fa311_dev;
15921 -static int eeprom_read(long ioaddr, int location);
15922 -static void init_ring(struct FA311_DEV *dev);
15923 -static void fa311_reset(struct nic *nic);
15924 -static int fa311_poll(struct nic *nic);
15925 -static void fa311_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
15926 -static void fa311_disable(struct nic *nic);
15928 -static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned (4)));
15929 -static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned (4)));
15931 -struct nic * fa311_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
15933 -int prev_eedata;
15934 -int i;
15935 -int duplex;
15936 -int tx_config;
15937 -int rx_config;
15938 -unsigned char macaddr[6];
15939 -unsigned char mactest;
15940 -unsigned char pci_bus = 0;
15941 -struct FA311_DEV* dev = &fa311_dev;
15943 - if (io_addrs == 0 || *io_addrs == 0)
15944 - return (0);
15945 - memset(dev, 0, sizeof(*dev));
15946 - dev->vendor = pci->vendor;
15947 - dev->device = pci->dev_id;
15948 - dev->ioaddr = pci->membase;
15950 - /* Work around the dropped serial bit. */
15951 - prev_eedata = eeprom_read(dev->ioaddr, 6);
15952 - for (i = 0; i < 3; i++) {
15953 - int eedata = eeprom_read(dev->ioaddr, i + 7);
15954 - macaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
15955 - macaddr[i*2+1] = eedata >> 7;
15956 - prev_eedata = eedata;
15958 - mactest = 0;
15959 - for (i = 0; i < 6; i++)
15960 - mactest |= macaddr[i];
15961 - if (mactest == 0)
15962 - return (0);
15963 - for (i = 0; i < 6; i++)
15964 - nic->node_addr[i] = macaddr[i];
15965 - printf("%! ", nic->node_addr);
15967 - adjust_pci_device(pci);
15969 - fa311_reset(nic);
15971 - nic->reset = fa311_reset;
15972 - nic->disable = fa311_disable;
15973 - nic->poll = fa311_poll;
15974 - nic->transmit = fa311_transmit;
15976 - init_ring(dev);
15978 - writel(virt_to_bus(dev->rx_ring), dev->ioaddr + RxRingPtr);
15979 - writel(virt_to_bus(dev->tx_ring), dev->ioaddr + TxRingPtr);
15981 - for (i = 0; i < 6; i += 2)
15983 - writel(i, dev->ioaddr + RxFilterAddr);
15984 - writew(macaddr[i] + (macaddr[i+1] << 8),
15985 - dev->ioaddr + RxFilterData);
15988 - /* Initialize other registers. */
15989 - /* Configure for standard, in-spec Ethernet. */
15990 - if (readl(dev->ioaddr + ChipConfig) & 0x20000000)
15991 - { /* Full duplex */
15992 - tx_config = 0xD0801002;
15993 - rx_config = 0x10000020;
15995 - else
15997 - tx_config = 0x10801002;
15998 - rx_config = 0x0020;
16000 - writel(tx_config, dev->ioaddr + TxConfig);
16001 - writel(rx_config, dev->ioaddr + RxConfig);
16003 - duplex = readl(dev->ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
16004 - if (duplex) {
16005 - rx_config |= 0x10000000;
16006 - tx_config |= 0xC0000000;
16007 - } else {
16008 - rx_config &= ~0x10000000;
16009 - tx_config &= ~0xC0000000;
16011 - writew(tx_config, dev->ioaddr + TxConfig);
16012 - writew(rx_config, dev->ioaddr + RxConfig);
16014 - writel(AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys,
16015 - dev->ioaddr + RxFilterAddr);
16017 - writel(RxOn | TxOn, dev->ioaddr + ChipCmd);
16018 - writel(4, dev->ioaddr + StatsCtrl); /* Clear Stats */
16019 - return nic;
16023 -static void fa311_reset(struct nic *nic)
16025 -u32 chip_config;
16026 -struct FA311_DEV* dev = &fa311_dev;
16028 - /* Reset the chip to erase previous misconfiguration. */
16029 - outl(ChipReset, dev->ioaddr + ChipCmd);
16031 - if ((readl(dev->ioaddr + ChipConfig) & 0xe000) != 0xe000)
16033 - chip_config = readl(dev->ioaddr + ChipConfig);
16037 -static int fa311_poll(struct nic *nic)
16039 -s32 desc_status;
16040 -int to;
16041 -int entry;
16042 -int retcode;
16043 -struct FA311_DEV* dev = &fa311_dev;
16045 - retcode = 0;
16046 - entry = dev->cur_rx;
16047 - to = TIME_OUT;
16048 - while (to != 0)
16050 - desc_status = dev->rx_ring[entry].cmd_status;
16051 - if ((desc_status & DescOwn) != 0)
16052 - break;
16053 - else
16054 - --to;
16056 - if (to != 0)
16058 - readl(dev->ioaddr + IntrStatus); /* clear interrrupt bits */
16059 - /* driver owns the next entry it's a new packet. Send it up. */
16060 - if ((desc_status & (DescMore|DescPktOK|RxTooLong)) == DescPktOK)
16062 - nic->packetlen = (desc_status & 0x0fff) - 4; /* Omit CRC size. */
16063 - memcpy(nic->packet, (char*)(dev->rx_ring[entry].addr), nic->packetlen);
16064 - retcode = 1;
16066 - /* Give the descriptor back to the chip */
16067 - dev->rx_ring[entry].cmd_status = cpu_to_le32(dev->rx_buf_sz);
16068 - dev->cur_rx++;
16069 - if (dev->cur_rx >= RX_RING_SIZE)
16070 - dev->cur_rx = 0;
16071 - dev->rx_head_desc = &dev->rx_ring[dev->cur_rx];
16073 - /* Restart Rx engine if stopped. */
16074 - writel(RxOn, dev->ioaddr + ChipCmd);
16075 - return retcode;
16078 -static void fa311_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
16080 -unsigned short nstype;
16081 -s32 desc_status;
16082 -int to;
16083 -int entry;
16084 -char* txp;
16085 -unsigned char* s;
16086 -struct FA311_DEV* dev = &fa311_dev;
16088 - /* Calculate the next Tx descriptor entry. */
16089 - entry = dev->cur_tx;
16090 - txp = (char*)(dev->tx_ring[entry].addr);
16092 - memcpy(txp, destaddr, ETH_ALEN);
16093 - memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
16094 - nstype = htons(type);
16095 - memcpy(txp + 12, (char*)&nstype, 2);
16096 - memcpy(txp + ETH_HLEN, data, len);
16097 - len += ETH_HLEN;
16098 - /* pad frame */
16099 - if (len < ETH_ZLEN)
16101 - s = (unsigned char*)(txp+len);
16102 - while (s < (unsigned char*)(txp+ETH_ZLEN))
16103 - *s++ = 0;
16104 - len = ETH_ZLEN;
16106 - dev->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | len);
16107 - dev->cur_tx++;
16108 - if (dev->cur_tx >= TX_RING_SIZE)
16109 - dev->cur_tx = 0;
16111 - /* Wake the potentially-idle transmit channel. */
16112 - writel(TxOn, dev->ioaddr + ChipCmd);
16114 - /* wait for tranmission to complete */
16115 - to = TIME_OUT;
16116 - while (to != 0)
16118 - desc_status = dev->tx_ring[entry].cmd_status;
16119 - if ((desc_status & DescOwn) == 0)
16120 - break;
16121 - else
16122 - --to;
16125 - readl(dev->ioaddr + IntrStatus); /* clear interrrupt bits */
16126 - return;
16129 -static void fa311_disable(struct nic *nic)
16131 -struct FA311_DEV* dev = &fa311_dev;
16133 - /* Stop the chip's Tx and Rx processes. */
16134 - writel(RxOff | TxOff, dev->ioaddr + ChipCmd);
16138 -/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
16139 - The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
16141 -/* Delay between EEPROM clock transitions.
16142 - No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
16143 - a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
16144 - made udelay() unreliable.
16145 - The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
16146 - depricated.
16148 -#define eeprom_delay(ee_addr) inl(ee_addr)
16150 -enum EEPROM_Ctrl_Bits {
16151 - EE_ShiftClk=0x04, EE_DataIn=0x01, EE_ChipSelect=0x08, EE_DataOut=0x02,
16153 -#define EE_Write0 (EE_ChipSelect)
16154 -#define EE_Write1 (EE_ChipSelect | EE_DataIn)
16156 -/* The EEPROM commands include the alway-set leading bit. */
16157 -enum EEPROM_Cmds {
16158 - EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
16162 -static int eeprom_read(long addr, int location)
16164 - int i;
16165 - int retval = 0;
16166 - int ee_addr = addr + EECtrl;
16167 - int read_cmd = location | EE_ReadCmd;
16168 - writel(EE_Write0, ee_addr);
16170 - /* Shift the read command bits out. */
16171 - for (i = 10; i >= 0; i--) {
16172 - short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
16173 - writel(dataval, ee_addr);
16174 - eeprom_delay(ee_addr);
16175 - writel(dataval | EE_ShiftClk, ee_addr);
16176 - eeprom_delay(ee_addr);
16178 - writel(EE_ChipSelect, ee_addr);
16179 - eeprom_delay(ee_addr);
16181 - for (i = 0; i < 16; i++) {
16182 - writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
16183 - eeprom_delay(ee_addr);
16184 - retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;
16185 - writel(EE_ChipSelect, ee_addr);
16186 - eeprom_delay(ee_addr);
16189 - /* Terminate the EEPROM access. */
16190 - writel(EE_Write0, ee_addr);
16191 - writel(0, ee_addr);
16192 - return retval;
16195 -/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
16196 -static void init_ring(struct FA311_DEV *dev)
16198 - int i;
16200 - dev->cur_rx = 0;
16201 - dev->cur_tx = 0;
16203 - dev->rx_buf_sz = PKT_BUF_SZ;
16204 - dev->rx_head_desc = &dev->rx_ring[0];
16206 - /* Initialize all Rx descriptors. */
16207 - for (i = 0; i < RX_RING_SIZE; i++) {
16208 - dev->rx_ring[i].next_desc = virt_to_le32desc(&dev->rx_ring[i+1]);
16209 - dev->rx_ring[i].cmd_status = DescOwn;
16211 - /* Mark the last entry as wrapping the ring. */
16212 - dev->rx_ring[i-1].next_desc = virt_to_le32desc(&dev->rx_ring[0]);
16214 - /* Fill in the Rx buffers. Handle allocation failure gracefully. */
16215 - for (i = 0; i < RX_RING_SIZE; i++) {
16216 - dev->rx_ring[i].addr = (u32)(&rx_packet[PKT_BUF_SZ * i]);
16217 - dev->rx_ring[i].cmd_status = cpu_to_le32(dev->rx_buf_sz);
16220 - for (i = 0; i < TX_RING_SIZE; i++) {
16221 - dev->tx_ring[i].next_desc = virt_to_le32desc(&dev->tx_ring[i+1]);
16222 - dev->tx_ring[i].cmd_status = 0;
16224 - dev->tx_ring[i-1].next_desc = virt_to_le32desc(&dev->tx_ring[0]);
16226 - for (i = 0; i < TX_RING_SIZE; i++)
16227 - dev->tx_ring[i].addr = (u32)(&tx_packet[PKT_BUF_SZ * i]);
16228 - return;
16231 Index: b/netboot/forcedeth.c
16232 ===================================================================
16233 --- /dev/null
16234 +++ b/netboot/forcedeth.c
16235 @@ -0,0 +1,1039 @@
16236 +/**************************************************************************
16237 +* forcedeth.c -- Etherboot device driver for the NVIDIA nForce
16238 +* media access controllers.
16240 +* Note: This driver is based on the Linux driver that was based on
16241 +* a cleanroom reimplementation which was based on reverse
16242 +* engineered documentation written by Carl-Daniel Hailfinger
16243 +* and Andrew de Quincey. It's neither supported nor endorsed
16244 +* by NVIDIA Corp. Use at your own risk.
16246 +* Written 2004 by Timothy Legge <tlegge@rogers.com>
16248 +* This program is free software; you can redistribute it and/or modify
16249 +* it under the terms of the GNU General Public License as published by
16250 +* the Free Software Foundation; either version 2 of the License, or
16251 +* (at your option) any later version.
16253 +* This program is distributed in the hope that it will be useful,
16254 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
16255 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16256 +* GNU General Public License for more details.
16258 +* You should have received a copy of the GNU General Public License
16259 +* along with this program; if not, write to the Free Software
16260 +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16262 +* Portions of this code based on:
16263 +* forcedeth: Ethernet driver for NVIDIA nForce media access controllers:
16265 +* (C) 2003 Manfred Spraul
16266 +* See Linux Driver for full information
16268 +* Linux Driver Version 0.22, 19 Jan 2004
16271 +* REVISION HISTORY:
16272 +* ================
16273 +* v1.0 01-31-2004 timlegge Initial port of Linux driver
16274 +* v1.1 02-03-2004 timlegge Large Clean up, first release
16276 +* Indent Options: indent -kr -i8
16277 +***************************************************************************/
16279 +/* to get some global routines like printf */
16280 +#include "etherboot.h"
16281 +/* to get the interface to the body of the program */
16282 +#include "nic.h"
16283 +/* to get the PCI support functions, if this is a PCI NIC */
16284 +#include "pci.h"
16285 +/* Include timer support functions */
16286 +#include "timer.h"
16288 +#define drv_version "v1.1"
16289 +#define drv_date "02-03-2004"
16291 +//#define TFTM_DEBUG
16292 +#ifdef TFTM_DEBUG
16293 +#define dprintf(x) printf x
16294 +#else
16295 +#define dprintf(x)
16296 +#endif
16298 +typedef unsigned char u8;
16299 +typedef signed char s8;
16300 +typedef unsigned short u16;
16301 +typedef signed short s16;
16302 +typedef unsigned int u32;
16303 +typedef signed int s32;
16305 +/* Condensed operations for readability. */
16306 +#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
16307 +#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
16309 +unsigned long BASE;
16310 +/* NIC specific static variables go here */
16314 + * Hardware access:
16315 + */
16317 +#define DEV_NEED_LASTPACKET1 0x0001
16318 +#define DEV_IRQMASK_1 0x0002
16319 +#define DEV_IRQMASK_2 0x0004
16320 +#define DEV_NEED_TIMERIRQ 0x0008
16322 +enum {
16323 + NvRegIrqStatus = 0x000,
16324 +#define NVREG_IRQSTAT_MIIEVENT 0040
16325 +#define NVREG_IRQSTAT_MASK 0x1ff
16326 + NvRegIrqMask = 0x004,
16327 +#define NVREG_IRQ_RX 0x0002
16328 +#define NVREG_IRQ_RX_NOBUF 0x0004
16329 +#define NVREG_IRQ_TX_ERR 0x0008
16330 +#define NVREG_IRQ_TX2 0x0010
16331 +#define NVREG_IRQ_TIMER 0x0020
16332 +#define NVREG_IRQ_LINK 0x0040
16333 +#define NVREG_IRQ_TX1 0x0100
16334 +#define NVREG_IRQMASK_WANTED_1 0x005f
16335 +#define NVREG_IRQMASK_WANTED_2 0x0147
16336 +#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1))
16338 + NvRegUnknownSetupReg6 = 0x008,
16339 +#define NVREG_UNKSETUP6_VAL 3
16342 + * NVREG_POLL_DEFAULT is the interval length of the timer source on the nic
16343 + * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
16344 + */
16345 + NvRegPollingInterval = 0x00c,
16346 +#define NVREG_POLL_DEFAULT 970
16347 + NvRegMisc1 = 0x080,
16348 +#define NVREG_MISC1_HD 0x02
16349 +#define NVREG_MISC1_FORCE 0x3b0f3c
16351 + NvRegTransmitterControl = 0x084,
16352 +#define NVREG_XMITCTL_START 0x01
16353 + NvRegTransmitterStatus = 0x088,
16354 +#define NVREG_XMITSTAT_BUSY 0x01
16356 + NvRegPacketFilterFlags = 0x8c,
16357 +#define NVREG_PFF_ALWAYS 0x7F0008
16358 +#define NVREG_PFF_PROMISC 0x80
16359 +#define NVREG_PFF_MYADDR 0x20
16361 + NvRegOffloadConfig = 0x90,
16362 +#define NVREG_OFFLOAD_HOMEPHY 0x601
16363 +#define NVREG_OFFLOAD_NORMAL 0x5ee
16364 + NvRegReceiverControl = 0x094,
16365 +#define NVREG_RCVCTL_START 0x01
16366 + NvRegReceiverStatus = 0x98,
16367 +#define NVREG_RCVSTAT_BUSY 0x01
16369 + NvRegRandomSeed = 0x9c,
16370 +#define NVREG_RNDSEED_MASK 0x00ff
16371 +#define NVREG_RNDSEED_FORCE 0x7f00
16373 + NvRegUnknownSetupReg1 = 0xA0,
16374 +#define NVREG_UNKSETUP1_VAL 0x16070f
16375 + NvRegUnknownSetupReg2 = 0xA4,
16376 +#define NVREG_UNKSETUP2_VAL 0x16
16377 + NvRegMacAddrA = 0xA8,
16378 + NvRegMacAddrB = 0xAC,
16379 + NvRegMulticastAddrA = 0xB0,
16380 +#define NVREG_MCASTADDRA_FORCE 0x01
16381 + NvRegMulticastAddrB = 0xB4,
16382 + NvRegMulticastMaskA = 0xB8,
16383 + NvRegMulticastMaskB = 0xBC,
16385 + NvRegTxRingPhysAddr = 0x100,
16386 + NvRegRxRingPhysAddr = 0x104,
16387 + NvRegRingSizes = 0x108,
16388 +#define NVREG_RINGSZ_TXSHIFT 0
16389 +#define NVREG_RINGSZ_RXSHIFT 16
16390 + NvRegUnknownTransmitterReg = 0x10c,
16391 + NvRegLinkSpeed = 0x110,
16392 +#define NVREG_LINKSPEED_FORCE 0x10000
16393 +#define NVREG_LINKSPEED_10 10
16394 +#define NVREG_LINKSPEED_100 100
16395 +#define NVREG_LINKSPEED_1000 1000
16396 + NvRegUnknownSetupReg5 = 0x130,
16397 +#define NVREG_UNKSETUP5_BIT31 (1<<31)
16398 + NvRegUnknownSetupReg3 = 0x134,
16399 +#define NVREG_UNKSETUP3_VAL1 0x200010
16400 + NvRegTxRxControl = 0x144,
16401 +#define NVREG_TXRXCTL_KICK 0x0001
16402 +#define NVREG_TXRXCTL_BIT1 0x0002
16403 +#define NVREG_TXRXCTL_BIT2 0x0004
16404 +#define NVREG_TXRXCTL_IDLE 0x0008
16405 +#define NVREG_TXRXCTL_RESET 0x0010
16406 + NvRegMIIStatus = 0x180,
16407 +#define NVREG_MIISTAT_ERROR 0x0001
16408 +#define NVREG_MIISTAT_LINKCHANGE 0x0008
16409 +#define NVREG_MIISTAT_MASK 0x000f
16410 +#define NVREG_MIISTAT_MASK2 0x000f
16411 + NvRegUnknownSetupReg4 = 0x184,
16412 +#define NVREG_UNKSETUP4_VAL 8
16414 + NvRegAdapterControl = 0x188,
16415 +#define NVREG_ADAPTCTL_START 0x02
16416 +#define NVREG_ADAPTCTL_LINKUP 0x04
16417 +#define NVREG_ADAPTCTL_PHYVALID 0x4000
16418 +#define NVREG_ADAPTCTL_RUNNING 0x100000
16419 +#define NVREG_ADAPTCTL_PHYSHIFT 24
16420 + NvRegMIISpeed = 0x18c,
16421 +#define NVREG_MIISPEED_BIT8 (1<<8)
16422 +#define NVREG_MIIDELAY 5
16423 + NvRegMIIControl = 0x190,
16424 +#define NVREG_MIICTL_INUSE 0x10000
16425 +#define NVREG_MIICTL_WRITE 0x08000
16426 +#define NVREG_MIICTL_ADDRSHIFT 5
16427 + NvRegMIIData = 0x194,
16428 + NvRegWakeUpFlags = 0x200,
16429 +#define NVREG_WAKEUPFLAGS_VAL 0x7770
16430 +#define NVREG_WAKEUPFLAGS_BUSYSHIFT 24
16431 +#define NVREG_WAKEUPFLAGS_ENABLESHIFT 16
16432 +#define NVREG_WAKEUPFLAGS_D3SHIFT 12
16433 +#define NVREG_WAKEUPFLAGS_D2SHIFT 8
16434 +#define NVREG_WAKEUPFLAGS_D1SHIFT 4
16435 +#define NVREG_WAKEUPFLAGS_D0SHIFT 0
16436 +#define NVREG_WAKEUPFLAGS_ACCEPT_MAGPAT 0x01
16437 +#define NVREG_WAKEUPFLAGS_ACCEPT_WAKEUPPAT 0x02
16438 +#define NVREG_WAKEUPFLAGS_ACCEPT_LINKCHANGE 0x04
16440 + NvRegPatternCRC = 0x204,
16441 + NvRegPatternMask = 0x208,
16442 + NvRegPowerCap = 0x268,
16443 +#define NVREG_POWERCAP_D3SUPP (1<<30)
16444 +#define NVREG_POWERCAP_D2SUPP (1<<26)
16445 +#define NVREG_POWERCAP_D1SUPP (1<<25)
16446 + NvRegPowerState = 0x26c,
16447 +#define NVREG_POWERSTATE_POWEREDUP 0x8000
16448 +#define NVREG_POWERSTATE_VALID 0x0100
16449 +#define NVREG_POWERSTATE_MASK 0x0003
16450 +#define NVREG_POWERSTATE_D0 0x0000
16451 +#define NVREG_POWERSTATE_D1 0x0001
16452 +#define NVREG_POWERSTATE_D2 0x0002
16453 +#define NVREG_POWERSTATE_D3 0x0003
16458 +#define NV_TX_LASTPACKET (1<<0)
16459 +#define NV_TX_RETRYERROR (1<<3)
16460 +#define NV_TX_LASTPACKET1 (1<<8)
16461 +#define NV_TX_DEFERRED (1<<10)
16462 +#define NV_TX_CARRIERLOST (1<<11)
16463 +#define NV_TX_LATECOLLISION (1<<12)
16464 +#define NV_TX_UNDERFLOW (1<<13)
16465 +#define NV_TX_ERROR (1<<14)
16466 +#define NV_TX_VALID (1<<15)
16468 +#define NV_RX_DESCRIPTORVALID (1<<0)
16469 +#define NV_RX_MISSEDFRAME (1<<1)
16470 +#define NV_RX_SUBSTRACT1 (1<<3)
16471 +#define NV_RX_ERROR1 (1<<7)
16472 +#define NV_RX_ERROR2 (1<<8)
16473 +#define NV_RX_ERROR3 (1<<9)
16474 +#define NV_RX_ERROR4 (1<<10)
16475 +#define NV_RX_CRCERR (1<<11)
16476 +#define NV_RX_OVERFLOW (1<<12)
16477 +#define NV_RX_FRAMINGERR (1<<13)
16478 +#define NV_RX_ERROR (1<<14)
16479 +#define NV_RX_AVAIL (1<<15)
16481 +/* Miscelaneous hardware related defines: */
16482 +#define NV_PCI_REGSZ 0x270
16484 +/* various timeout delays: all in usec */
16485 +#define NV_TXRX_RESET_DELAY 4
16486 +#define NV_TXSTOP_DELAY1 10
16487 +#define NV_TXSTOP_DELAY1MAX 500000
16488 +#define NV_TXSTOP_DELAY2 100
16489 +#define NV_RXSTOP_DELAY1 10
16490 +#define NV_RXSTOP_DELAY1MAX 500000
16491 +#define NV_RXSTOP_DELAY2 100
16492 +#define NV_SETUP5_DELAY 5
16493 +#define NV_SETUP5_DELAYMAX 50000
16494 +#define NV_POWERUP_DELAY 5
16495 +#define NV_POWERUP_DELAYMAX 5000
16496 +#define NV_MIIBUSY_DELAY 50
16497 +#define NV_MIIPHY_DELAY 10
16498 +#define NV_MIIPHY_DELAYMAX 10000
16500 +#define NV_WAKEUPPATTERNS 5
16501 +#define NV_WAKEUPMASKENTRIES 4
16503 +/* General driver defaults */
16504 +#define NV_WATCHDOG_TIMEO (2*HZ)
16505 +#define DEFAULT_MTU 1500 /* also maximum supported, at least for now */
16507 +#define RX_RING 4
16508 +#define TX_RING 2
16509 +/* limited to 1 packet until we understand NV_TX_LASTPACKET */
16510 +#define TX_LIMIT_STOP 10
16511 +#define TX_LIMIT_START 5
16513 +/* rx/tx mac addr + type + vlan + align + slack*/
16514 +#define RX_NIC_BUFSIZE (DEFAULT_MTU + 64)
16515 +/* even more slack */
16516 +#define RX_ALLOC_BUFSIZE (DEFAULT_MTU + 128)
16518 +#define OOM_REFILL (1+HZ/20)
16519 +#define POLL_WAIT (1+HZ/100)
16521 +struct ring_desc {
16522 + u32 PacketBuffer;
16523 + u16 Length;
16524 + u16 Flags;
16528 +/* Define the TX Descriptor */
16529 +static struct ring_desc tx_ring[TX_RING];
16531 +/* Create a static buffer of size RX_BUF_SZ for each
16532 +TX Descriptor. All descriptors point to a
16533 +part of this buffer */
16534 +static unsigned char txb[TX_RING * RX_NIC_BUFSIZE];
16536 +/* Define the TX Descriptor */
16537 +static struct ring_desc rx_ring[RX_RING];
16539 +/* Create a static buffer of size RX_BUF_SZ for each
16540 +RX Descriptor All descriptors point to a
16541 +part of this buffer */
16542 +static unsigned char rxb[RX_RING * RX_NIC_BUFSIZE];
16544 +/* Private Storage for the NIC */
16545 +struct forcedeth_private {
16546 + /* General data:
16547 + * Locking: spin_lock(&np->lock); */
16548 + int in_shutdown;
16549 + u32 linkspeed;
16550 + int duplex;
16551 + int phyaddr;
16553 + /* General data: RO fields */
16554 + u8 *ring_addr;
16555 + u32 orig_mac[2];
16556 + u32 irqmask;
16557 + /* rx specific fields.
16558 + * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
16559 + */
16560 + struct ring_desc *rx_ring;
16561 + unsigned int cur_rx, refill_rx;
16562 + struct sk_buff *rx_skbuff[RX_RING];
16563 + u32 rx_dma[RX_RING];
16564 + unsigned int rx_buf_sz;
16566 + /*
16567 + * tx specific fields.
16568 + */
16569 + struct ring_desc *tx_ring;
16570 + unsigned int next_tx, nic_tx;
16571 + struct sk_buff *tx_skbuff[TX_RING];
16572 + u32 tx_dma[TX_RING];
16573 + u16 tx_flags;
16574 +} npx;
16576 +static struct forcedeth_private *np;
16578 +static inline void pci_push(u8 * base)
16580 + /* force out pending posted writes */
16581 + readl(base);
16583 +static int reg_delay(int offset, u32 mask,
16584 + u32 target, int delay, int delaymax, const char *msg)
16586 + u8 *base = (u8 *) BASE;
16588 + pci_push(base);
16589 + do {
16590 + udelay(delay);
16591 + delaymax -= delay;
16592 + if (delaymax < 0) {
16593 + if (msg)
16594 + printf(msg);
16595 + return 1;
16597 + } while ((readl(base + offset) & mask) != target);
16598 + return 0;
16601 +#define MII_READ (-1)
16602 +#define MII_PHYSID1 0x02 /* PHYS ID 1 */
16603 +#define MII_PHYSID2 0x03 /* PHYS ID 2 */
16604 +#define MII_BMCR 0x00 /* Basic mode control register */
16605 +#define MII_BMSR 0x01 /* Basic mode status register */
16606 +#define MII_ADVERTISE 0x04 /* Advertisement control reg */
16607 +#define MII_LPA 0x05 /* Link partner ability reg */
16609 +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
16611 +/* Link partner ability register. */
16612 +#define LPA_SLCT 0x001f /* Same as advertise selector */
16613 +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
16614 +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
16615 +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
16616 +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
16617 +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
16618 +#define LPA_RESV 0x1c00 /* Unused... */
16619 +#define LPA_RFAULT 0x2000 /* Link partner faulted */
16620 +#define LPA_LPACK 0x4000 /* Link partner acked us */
16621 +#define LPA_NPAGE 0x8000 /* Next page bit */
16623 +/* mii_rw: read/write a register on the PHY.
16625 + * Caller must guarantee serialization
16626 + */
16627 +static int mii_rw(struct nic *nic __unused, int addr, int miireg,
16628 + int value)
16630 + u8 *base = (u8 *) BASE;
16631 + int was_running;
16632 + u32 reg;
16633 + int retval;
16635 + writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
16636 + was_running = 0;
16637 + reg = readl(base + NvRegAdapterControl);
16638 + if (reg & NVREG_ADAPTCTL_RUNNING) {
16639 + was_running = 1;
16640 + writel(reg & ~NVREG_ADAPTCTL_RUNNING,
16641 + base + NvRegAdapterControl);
16643 + reg = readl(base + NvRegMIIControl);
16644 + if (reg & NVREG_MIICTL_INUSE) {
16645 + writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl);
16646 + udelay(NV_MIIBUSY_DELAY);
16649 + reg =
16650 + NVREG_MIICTL_INUSE | (addr << NVREG_MIICTL_ADDRSHIFT) | miireg;
16651 + if (value != MII_READ) {
16652 + writel(value, base + NvRegMIIData);
16653 + reg |= NVREG_MIICTL_WRITE;
16655 + writel(reg, base + NvRegMIIControl);
16657 + if (reg_delay(NvRegMIIControl, NVREG_MIICTL_INUSE, 0,
16658 + NV_MIIPHY_DELAY, NV_MIIPHY_DELAYMAX, NULL)) {
16659 + dprintf(("mii_rw of reg %d at PHY %d timed out.\n",
16660 + miireg, addr));
16661 + retval = -1;
16662 + } else if (value != MII_READ) {
16663 + /* it was a write operation - fewer failures are detectable */
16664 + dprintf(("mii_rw wrote 0x%x to reg %d at PHY %d\n",
16665 + value, miireg, addr));
16666 + retval = 0;
16667 + } else if (readl(base + NvRegMIIStatus) & NVREG_MIISTAT_ERROR) {
16668 + dprintf(("mii_rw of reg %d at PHY %d failed.\n",
16669 + miireg, addr));
16670 + retval = -1;
16671 + } else {
16672 + /* FIXME: why is that required? */
16673 + udelay(50);
16674 + retval = readl(base + NvRegMIIData);
16675 + dprintf(("mii_rw read from reg %d at PHY %d: 0x%x.\n",
16676 + miireg, addr, retval));
16678 + if (was_running) {
16679 + reg = readl(base + NvRegAdapterControl);
16680 + writel(reg | NVREG_ADAPTCTL_RUNNING,
16681 + base + NvRegAdapterControl);
16683 + return retval;
16686 +static void start_rx(struct nic *nic __unused)
16688 + u8 *base = (u8 *) BASE;
16690 + dprintf(("start_rx\n"));
16691 + /* Already running? Stop it. */
16692 + if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
16693 + writel(0, base + NvRegReceiverControl);
16694 + pci_push(base);
16696 + writel(np->linkspeed, base + NvRegLinkSpeed);
16697 + pci_push(base);
16698 + writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
16699 + pci_push(base);
16702 +static void stop_rx(void)
16704 + u8 *base = (u8 *) BASE;
16706 + dprintf(("stop_rx\n"));
16707 + writel(0, base + NvRegReceiverControl);
16708 + reg_delay(NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
16709 + NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
16710 + "stop_rx: ReceiverStatus remained busy");
16712 + udelay(NV_RXSTOP_DELAY2);
16713 + writel(0, base + NvRegLinkSpeed);
16716 +static void start_tx(struct nic *nic __unused)
16718 + u8 *base = (u8 *) BASE;
16720 + dprintf(("start_tx\n"));
16721 + writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl);
16722 + pci_push(base);
16725 +static void stop_tx(void)
16727 + u8 *base = (u8 *) BASE;
16729 + dprintf(("stop_tx\n"));
16730 + writel(0, base + NvRegTransmitterControl);
16731 + reg_delay(NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
16732 + NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
16733 + "stop_tx: TransmitterStatus remained busy");
16735 + udelay(NV_TXSTOP_DELAY2);
16736 + writel(0, base + NvRegUnknownTransmitterReg);
16740 +static void txrx_reset(struct nic *nic __unused)
16742 + u8 *base = (u8 *) BASE;
16744 + dprintf(("txrx_reset\n"));
16745 + writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET,
16746 + base + NvRegTxRxControl);
16747 + pci_push(base);
16748 + udelay(NV_TXRX_RESET_DELAY);
16749 + writel(NVREG_TXRXCTL_BIT2, base + NvRegTxRxControl);
16750 + pci_push(base);
16754 + * alloc_rx: fill rx ring entries.
16755 + * Return 1 if the allocations for the skbs failed and the
16756 + * rx engine is without Available descriptors
16757 + */
16758 +static int alloc_rx(struct nic *nic __unused)
16760 + unsigned int refill_rx = np->refill_rx;
16761 + int i;
16762 + //while (np->cur_rx != refill_rx) {
16763 + for (i = 0; i < RX_RING; i++) {
16764 + //int nr = refill_rx % RX_RING;
16765 + rx_ring[i].PacketBuffer =
16766 + virt_to_le32desc(&rxb[i * RX_NIC_BUFSIZE]);
16767 + rx_ring[i].Length = cpu_to_le16(RX_NIC_BUFSIZE);
16768 + wmb();
16769 + rx_ring[i].Flags = cpu_to_le16(NV_RX_AVAIL);
16770 + /* printf("alloc_rx: Packet %d marked as Available\n",
16771 + refill_rx); */
16772 + refill_rx++;
16774 + np->refill_rx = refill_rx;
16775 + if (np->cur_rx - refill_rx == RX_RING)
16776 + return 1;
16777 + return 0;
16780 +static int update_linkspeed(struct nic *nic)
16782 + int adv, lpa, newdup;
16783 + u32 newls;
16784 + adv = mii_rw(nic, np->phyaddr, MII_ADVERTISE, MII_READ);
16785 + lpa = mii_rw(nic, np->phyaddr, MII_LPA, MII_READ);
16786 + dprintf(("update_linkspeed: PHY advertises 0x%hX, lpa 0x%hX.\n",
16787 + adv, lpa));
16789 + /* FIXME: handle parallel detection properly, handle gigabit ethernet */
16790 + lpa = lpa & adv;
16791 + if (lpa & LPA_100FULL) {
16792 + newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100;
16793 + newdup = 1;
16794 + } else if (lpa & LPA_100HALF) {
16795 + newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_100;
16796 + newdup = 0;
16797 + } else if (lpa & LPA_10FULL) {
16798 + newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
16799 + newdup = 1;
16800 + } else if (lpa & LPA_10HALF) {
16801 + newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
16802 + newdup = 0;
16803 + } else {
16804 + printf("bad ability %hX - falling back to 10HD.\n", lpa);
16805 + newls = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
16806 + newdup = 0;
16808 + if (np->duplex != newdup || np->linkspeed != newls) {
16809 + np->duplex = newdup;
16810 + np->linkspeed = newls;
16811 + return 1;
16813 + return 0;
16818 +static int init_ring(struct nic *nic)
16820 + int i;
16822 + np->next_tx = np->nic_tx = 0;
16823 + for (i = 0; i < TX_RING; i++) {
16824 + tx_ring[i].Flags = 0;
16827 + np->cur_rx = 0;
16828 + np->refill_rx = 0;
16829 + for (i = 0; i < RX_RING; i++) {
16830 + rx_ring[i].Flags = 0;
16832 + return alloc_rx(nic);
16835 +static void set_multicast(struct nic *nic)
16838 + u8 *base = (u8 *) BASE;
16839 + u32 addr[2];
16840 + u32 mask[2];
16841 + u32 pff;
16842 + u32 alwaysOff[2];
16843 + u32 alwaysOn[2];
16845 + memset(addr, 0, sizeof(addr));
16846 + memset(mask, 0, sizeof(mask));
16848 + pff = NVREG_PFF_MYADDR;
16850 + alwaysOn[0] = alwaysOn[1] = alwaysOff[0] = alwaysOff[1] = 0;
16852 + addr[0] = alwaysOn[0];
16853 + addr[1] = alwaysOn[1];
16854 + mask[0] = alwaysOn[0] | alwaysOff[0];
16855 + mask[1] = alwaysOn[1] | alwaysOff[1];
16857 + addr[0] |= NVREG_MCASTADDRA_FORCE;
16858 + pff |= NVREG_PFF_ALWAYS;
16859 + stop_rx();
16860 + writel(addr[0], base + NvRegMulticastAddrA);
16861 + writel(addr[1], base + NvRegMulticastAddrB);
16862 + writel(mask[0], base + NvRegMulticastMaskA);
16863 + writel(mask[1], base + NvRegMulticastMaskB);
16864 + writel(pff, base + NvRegPacketFilterFlags);
16865 + start_rx(nic);
16868 +/**************************************************************************
16869 +RESET - Reset the NIC to prepare for use
16870 +***************************************************************************/
16871 +static int forcedeth_reset(struct nic *nic)
16873 + u8 *base = (u8 *) BASE;
16874 + int ret, oom, i;
16875 + ret = 0;
16876 + dprintf(("forcedeth: open\n"));
16878 + /* 1) erase previous misconfiguration */
16879 + /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */
16880 + writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
16881 + writel(0, base + NvRegMulticastAddrB);
16882 + writel(0, base + NvRegMulticastMaskA);
16883 + writel(0, base + NvRegMulticastMaskB);
16884 + writel(0, base + NvRegPacketFilterFlags);
16885 + writel(0, base + NvRegAdapterControl);
16886 + writel(0, base + NvRegLinkSpeed);
16887 + writel(0, base + NvRegUnknownTransmitterReg);
16888 + txrx_reset(nic);
16889 + writel(0, base + NvRegUnknownSetupReg6);
16891 + /* 2) initialize descriptor rings */
16892 + np->in_shutdown = 0;
16893 + oom = init_ring(nic);
16895 + /* 3) set mac address */
16897 + u32 mac[2];
16899 + mac[0] =
16900 + (nic->node_addr[0] << 0) + (nic->node_addr[1] << 8) +
16901 + (nic->node_addr[2] << 16) + (nic->node_addr[3] << 24);
16902 + mac[1] =
16903 + (nic->node_addr[4] << 0) + (nic->node_addr[5] << 8);
16905 + writel(mac[0], base + NvRegMacAddrA);
16906 + writel(mac[1], base + NvRegMacAddrB);
16909 + /* 4) continue setup */
16910 + np->linkspeed = NVREG_LINKSPEED_FORCE | NVREG_LINKSPEED_10;
16911 + np->duplex = 0;
16912 + writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
16913 + writel(0, base + NvRegTxRxControl);
16914 + pci_push(base);
16915 + writel(NVREG_TXRXCTL_BIT1, base + NvRegTxRxControl);
16917 + reg_delay(NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31,
16918 + NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY,
16919 + NV_SETUP5_DELAYMAX,
16920 + "open: SetupReg5, Bit 31 remained off\n");
16921 + writel(0, base + NvRegUnknownSetupReg4);
16923 + /* 5) Find a suitable PHY */
16924 + writel(NVREG_MIISPEED_BIT8 | NVREG_MIIDELAY, base + NvRegMIISpeed);
16925 + for (i = 1; i < 32; i++) {
16926 + int id1, id2;
16928 + id1 = mii_rw(nic, i, MII_PHYSID1, MII_READ);
16929 + if (id1 < 0)
16930 + continue;
16931 + id2 = mii_rw(nic, i, MII_PHYSID2, MII_READ);
16932 + if (id2 < 0)
16933 + continue;
16934 + dprintf(("open: Found PHY %04x:%04x at address %d.\n",
16935 + id1, id2, i));
16936 + np->phyaddr = i;
16938 + update_linkspeed(nic);
16940 + break;
16942 + if (i == 32) {
16943 + printf("open: failing due to lack of suitable PHY.\n");
16944 + ret = -1;
16945 + goto out_drain;
16948 + printf("%d-Mbs Link, %s-Duplex\n",
16949 + np->linkspeed & NVREG_LINKSPEED_10 ? 10 : 100,
16950 + np->duplex ? "Full" : "Half");
16951 + /* 6) continue setup */
16952 + writel(NVREG_MISC1_FORCE | (np->duplex ? 0 : NVREG_MISC1_HD),
16953 + base + NvRegMisc1);
16954 + writel(readl(base + NvRegTransmitterStatus),
16955 + base + NvRegTransmitterStatus);
16956 + writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags);
16957 + writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig);
16959 + writel(readl(base + NvRegReceiverStatus),
16960 + base + NvRegReceiverStatus);
16962 + /* FIXME: I cheated and used the calculator to get a random number */
16963 + i = 75963081;
16964 + writel(NVREG_RNDSEED_FORCE | (i & NVREG_RNDSEED_MASK),
16965 + base + NvRegRandomSeed);
16966 + writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
16967 + writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
16968 + writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval);
16969 + writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6);
16970 + writel((np->
16971 + phyaddr << NVREG_ADAPTCTL_PHYSHIFT) |
16972 + NVREG_ADAPTCTL_PHYVALID, base + NvRegAdapterControl);
16973 + writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4);
16974 + writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags);
16976 + /* 7) start packet processing */
16977 + writel((u32) virt_to_le32desc(&rx_ring[0]),
16978 + base + NvRegRxRingPhysAddr);
16979 + writel((u32) virt_to_le32desc(&tx_ring[0]),
16980 + base + NvRegTxRingPhysAddr);
16983 + writel(((RX_RING - 1) << NVREG_RINGSZ_RXSHIFT) +
16984 + ((TX_RING - 1) << NVREG_RINGSZ_TXSHIFT),
16985 + base + NvRegRingSizes);
16987 + i = readl(base + NvRegPowerState);
16988 + if ((i & NVREG_POWERSTATE_POWEREDUP) == 0) {
16989 + writel(NVREG_POWERSTATE_POWEREDUP | i,
16990 + base + NvRegPowerState);
16992 + pci_push(base);
16993 + udelay(10);
16994 + writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID,
16995 + base + NvRegPowerState);
16996 + writel(NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl);
16998 + writel(0, base + NvRegIrqMask);
16999 + pci_push(base);
17000 + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
17001 + pci_push(base);
17002 + writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
17003 + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
17004 + pci_push(base);
17006 + writel(np->irqmask, base + NvRegIrqMask);
17008 + writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
17009 + writel(0, base + NvRegMulticastAddrB);
17010 + writel(0, base + NvRegMulticastMaskA);
17011 + writel(0, base + NvRegMulticastMaskB);
17012 + writel(NVREG_PFF_ALWAYS | NVREG_PFF_MYADDR,
17013 + base + NvRegPacketFilterFlags);
17015 + set_multicast(nic);
17016 + //start_rx(nic);
17017 + start_tx(nic);
17019 + if (!
17020 + (mii_rw(nic, np->phyaddr, MII_BMSR, MII_READ) &
17021 + BMSR_ANEGCOMPLETE)) {
17022 + printf("no link during initialization.\n");
17025 + udelay(10000);
17026 + out_drain:
17027 + return ret;
17030 +//extern void hex_dump(const char *data, const unsigned int len);
17032 +/**************************************************************************
17033 +POLL - Wait for a frame
17034 +***************************************************************************/
17035 +static int forcedeth_poll(struct nic *nic, int retrieve)
17037 + /* return true if there's an ethernet packet ready to read */
17038 + /* nic->packet should contain data on return */
17039 + /* nic->packetlen should contain length of data */
17041 + struct ring_desc *prd;
17042 + int len;
17043 + int i;
17045 + i = np->cur_rx % RX_RING;
17046 + prd = &rx_ring[i];
17048 + if ( ! (prd->Flags & cpu_to_le16(NV_RX_DESCRIPTORVALID)) ) {
17049 + return 0;
17052 + if ( ! retrieve ) return 1;
17054 + /* got a valid packet - forward it to the network core */
17055 + len = cpu_to_le16(prd->Length);
17056 + nic->packetlen = len;
17057 + //hex_dump(rxb + (i * RX_NIC_BUFSIZE), len);
17058 + memcpy(nic->packet, rxb +
17059 + (i * RX_NIC_BUFSIZE), nic->packetlen);
17061 + wmb();
17062 + np->cur_rx++;
17063 + alloc_rx(nic);
17064 + return 1;
17068 +/**************************************************************************
17069 +TRANSMIT - Transmit a frame
17070 +***************************************************************************/
17071 +static void forcedeth_transmit(struct nic *nic, const char *d, /* Destination */
17072 + unsigned int t, /* Type */
17073 + unsigned int s, /* size */
17074 + const char *p)
17075 +{ /* Packet */
17076 + /* send the packet to destination */
17077 + u8 *ptxb;
17078 + u16 nstype;
17079 + //u16 status;
17080 + u8 *base = (u8 *) BASE;
17081 + int nr = np->next_tx % TX_RING;
17083 + /* point to the current txb incase multiple tx_rings are used */
17084 + ptxb = txb + (nr * RX_NIC_BUFSIZE);
17085 + //np->tx_skbuff[nr] = ptxb;
17087 + /* copy the packet to ring buffer */
17088 + memcpy(ptxb, d, ETH_ALEN); /* dst */
17089 + memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
17090 + nstype = htons((u16) t); /* type */
17091 + memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */
17092 + memcpy(ptxb + ETH_HLEN, p, s);
17094 + s += ETH_HLEN;
17095 + while (s < ETH_ZLEN) /* pad to min length */
17096 + ptxb[s++] = '\0';
17098 + tx_ring[nr].PacketBuffer = (u32) virt_to_le32desc(ptxb);
17099 + tx_ring[nr].Length = cpu_to_le16(s - 1);
17101 + wmb();
17102 + tx_ring[nr].Flags = np->tx_flags;
17104 + writel(NVREG_TXRXCTL_KICK, base + NvRegTxRxControl);
17105 + pci_push(base);
17106 + tx_ring[nr].Flags = np->tx_flags;
17107 + np->next_tx++;
17110 +/**************************************************************************
17111 +DISABLE - Turn off ethernet interface
17112 +***************************************************************************/
17113 +static void forcedeth_disable(struct dev *dev __unused)
17115 + /* put the card in its initial state */
17116 + /* This function serves 3 purposes.
17117 + * This disables DMA and interrupts so we don't receive
17118 + * unexpected packets or interrupts from the card after
17119 + * etherboot has finished.
17120 + * This frees resources so etherboot may use
17121 + * this driver on another interface
17122 + * This allows etherboot to reinitialize the interface
17123 + * if something is something goes wrong.
17124 + */
17125 + u8 *base = (u8 *) BASE;
17126 + np->in_shutdown = 1;
17127 + stop_tx();
17128 + stop_rx();
17130 + /* disable interrupts on the nic or we will lock up */
17131 + writel(0, base + NvRegIrqMask);
17132 + pci_push(base);
17133 + dprintf(("Irqmask is zero again\n"));
17135 + /* specia op:o write back the misordered MAC address - otherwise
17136 + * the next probe_nic would see a wrong address.
17137 + */
17138 + writel(np->orig_mac[0], base + NvRegMacAddrA);
17139 + writel(np->orig_mac[1], base + NvRegMacAddrB);
17142 +/**************************************************************************
17143 +IRQ - Enable, Disable, or Force interrupts
17144 +***************************************************************************/
17145 +static void forcedeth_irq(struct nic *nic __unused, irq_action_t action __unused)
17147 + switch ( action ) {
17148 + case DISABLE :
17149 + break;
17150 + case ENABLE :
17151 + break;
17152 + case FORCE :
17153 + break;
17157 +/**************************************************************************
17158 +PROBE - Look for an adapter, this routine's visible to the outside
17159 +***************************************************************************/
17160 +#define IORESOURCE_MEM 0x00000200
17161 +#define board_found 1
17162 +#define valid_link 0
17163 +static int forcedeth_probe(struct dev *dev, struct pci_device *pci)
17165 + struct nic *nic = (struct nic *) dev;
17166 + unsigned long addr;
17167 + int sz;
17168 + u8 *base;
17170 + if (pci->ioaddr == 0)
17171 + return 0;
17173 + printf("forcedeth.c: Found %s, vendor=0x%hX, device=0x%hX\n",
17174 + pci->name, pci->vendor, pci->dev_id);
17176 + nic->irqno = 0;
17177 + nic->ioaddr = pci->ioaddr & ~3;
17179 + /* point to private storage */
17180 + np = &npx;
17182 + adjust_pci_device(pci);
17184 + addr = pci_bar_start(pci, PCI_BASE_ADDRESS_0);
17185 + sz = pci_bar_size(pci, PCI_BASE_ADDRESS_0);
17187 + /* BASE is used throughout to address the card */
17188 + BASE = (unsigned long) ioremap(addr, sz);
17189 + if (!BASE)
17190 + return 0;
17191 + //rx_ring[0] = rx_ring;
17192 + //tx_ring[0] = tx_ring;
17194 + /* read the mac address */
17195 + base = (u8 *) BASE;
17196 + np->orig_mac[0] = readl(base + NvRegMacAddrA);
17197 + np->orig_mac[1] = readl(base + NvRegMacAddrB);
17199 + nic->node_addr[0] = (np->orig_mac[1] >> 8) & 0xff;
17200 + nic->node_addr[1] = (np->orig_mac[1] >> 0) & 0xff;
17201 + nic->node_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
17202 + nic->node_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
17203 + nic->node_addr[4] = (np->orig_mac[0] >> 8) & 0xff;
17204 + nic->node_addr[5] = (np->orig_mac[0] >> 0) & 0xff;
17205 +#ifdef LINUX
17206 + if (!is_valid_ether_addr(dev->dev_addr)) {
17207 + /*
17208 + * Bad mac address. At least one bios sets the mac address
17209 + * to 01:23:45:67:89:ab
17210 + */
17211 + printk(KERN_ERR
17212 + "%s: Invalid Mac address detected: %02x:%02x:%02x:%02x:%02x:%02x\n",
17213 + pci_name(pci_dev), dev->dev_addr[0],
17214 + dev->dev_addr[1], dev->dev_addr[2],
17215 + dev->dev_addr[3], dev->dev_addr[4],
17216 + dev->dev_addr[5]);
17217 + printk(KERN_ERR
17218 + "Please complain to your hardware vendor. Switching to a random MAC.\n");
17219 + dev->dev_addr[0] = 0x00;
17220 + dev->dev_addr[1] = 0x00;
17221 + dev->dev_addr[2] = 0x6c;
17222 + get_random_bytes(&dev->dev_addr[3], 3);
17224 +#endif
17225 + printf("%s: MAC Address %!, ", pci->name, nic->node_addr);
17227 + np->tx_flags =
17228 + cpu_to_le16(NV_TX_LASTPACKET | NV_TX_LASTPACKET1 |
17229 + NV_TX_VALID);
17230 + switch (pci->dev_id) {
17231 + case 0x01C3: // nforce
17232 + np->irqmask = NVREG_IRQMASK_WANTED_2;
17233 + np->irqmask |= NVREG_IRQ_TIMER;
17234 + break;
17235 + case 0x0066: // nforce2
17236 + np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1);
17237 + np->irqmask = NVREG_IRQMASK_WANTED_2;
17238 + np->irqmask |= NVREG_IRQ_TIMER;
17239 + break;
17240 + case 0x00D6: // nforce3
17241 + np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1);
17242 + np->irqmask = NVREG_IRQMASK_WANTED_2;
17243 + np->irqmask |= NVREG_IRQ_TIMER;
17246 + dprintf(("%s: forcedeth.c: subsystem: %hX:%hX bound to %s\n",
17247 + pci->name, pci->vendor, pci->dev_id, pci->name));
17249 + forcedeth_reset(nic);
17250 +// if (board_found && valid_link)
17251 + /* point to NIC specific routines */
17252 + dev->disable = forcedeth_disable;
17253 + nic->poll = forcedeth_poll;
17254 + nic->transmit = forcedeth_transmit;
17255 + nic->irq = forcedeth_irq;
17256 + return 1;
17257 +// }
17258 + /* else */
17261 +static struct pci_id forcedeth_nics[] = {
17262 + PCI_ROM(0x10de, 0x01C3, "nforce", "nForce Ethernet Controller"),
17263 + PCI_ROM(0x10de, 0x0066, "nforce2", "nForce2 Ethernet Controller"),
17264 + PCI_ROM(0x10de, 0x00D6, "nforce3", "nForce3 Ethernet Controller"),
17267 +struct pci_driver forcedeth_driver = {
17268 + .type = NIC_DRIVER,
17269 + .name = "forcedeth",
17270 + .probe = forcedeth_probe,
17271 + .ids = forcedeth_nics,
17272 + .id_count = sizeof(forcedeth_nics) / sizeof(forcedeth_nics[0]),
17273 + .class = 0,
17275 Index: b/netboot/fsys_tftp.c
17276 ===================================================================
17277 --- a/netboot/fsys_tftp.c
17278 +++ b/netboot/fsys_tftp.c
17279 @@ -29,14 +29,15 @@
17280 /* #define TFTP_DEBUG 1 */
17282 #include <filesys.h>
17283 +#include <shared.h>
17285 -#define GRUB 1
17286 -#include <etherboot.h>
17287 -#include <nic.h>
17288 +#include "grub.h"
17289 +#include "tftp.h"
17290 +#include "nic.h"
17292 static int retry;
17293 static unsigned short iport = 2000;
17294 -static unsigned short oport;
17295 +static unsigned short oport = 0;
17296 static unsigned short block, prevblock;
17297 static int bcounter;
17298 static struct tftp_t tp, saved_tp;
17299 @@ -46,6 +47,172 @@
17300 static unsigned short len, saved_len;
17301 static char *buf;
17303 +/**
17304 + * tftp_read
17306 + * Read file with _name_, data handled by _fnc_. In fact, grub never
17307 + * use it, we just use it to read dhcp config file.
17308 + */
17309 +static int await_tftp(int ival, void *ptr __unused,
17310 + unsigned short ptype __unused, struct iphdr *ip,
17311 + struct udphdr *udp)
17313 + if (!udp) {
17314 + return 0;
17316 + if (arptable[ARP_CLIENT].ipaddr.s_addr != ip->dest.s_addr)
17317 + return 0;
17318 + if (ntohs(udp->dest) != ival)
17319 + return 0;
17320 + return 1;
17323 +int tftp_file_read(const char *name, int (*fnc)(unsigned char *, unsigned int, unsigned int, int))
17325 + struct tftpreq_t tp;
17326 + struct tftp_t *tr;
17327 + int rc;
17329 + retry = 0;
17330 + block = 0;
17331 + prevblock = 0;
17332 + bcounter = 0;
17335 + rx_qdrain();
17337 + tp.opcode = htons(TFTP_RRQ);
17338 + /* Warning: the following assumes the layout of bootp_t.
17339 + But that's fixed by the IP, UDP and BOOTP specs. */
17340 + len = sizeof(tp.ip) + sizeof(tp.udp) + sizeof(tp.opcode) +
17341 + sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
17342 + name, 0, 0, 0, TFTP_MAX_PACKET) + 1;
17343 + if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
17344 + TFTP_PORT, len, &tp))
17345 + return (0);
17346 + for (;;)
17348 + long timeout;
17349 +#ifdef CONGESTED
17350 + timeout = rfc2131_sleep_interval(block?TFTP_REXMT: TIMEOUT, retry);
17351 +#else
17352 + timeout = rfc2131_sleep_interval(TIMEOUT, retry);
17353 +#endif
17354 + if (!await_reply(await_tftp, iport, NULL, timeout))
17356 + if (!block && retry++ < MAX_TFTP_RETRIES)
17357 + { /* maybe initial request was lost */
17358 + if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
17359 + ++iport, TFTP_PORT, len, &tp))
17360 + return (0);
17361 + continue;
17363 +#ifdef CONGESTED
17364 + if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
17365 + { /* we resend our last ack */
17366 +#ifdef MDEBUG
17367 + printf("<REXMT>\n");
17368 +#endif
17369 + udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
17370 + iport, oport,
17371 + TFTP_MIN_PACKET, &tp);
17372 + continue;
17374 +#endif
17375 + break; /* timeout */
17377 + tr = (struct tftp_t *)&nic.packet[ETH_HLEN];
17378 + if (tr->opcode == ntohs(TFTP_ERROR))
17380 + printf("TFTP error %d (%s)\n",
17381 + ntohs(tr->u.err.errcode),
17382 + tr->u.err.errmsg);
17383 + break;
17386 + if (tr->opcode == ntohs(TFTP_OACK)) {
17387 + char *p = tr->u.oack.data, *e;
17389 + if (prevblock) /* shouldn't happen */
17390 + continue; /* ignore it */
17391 + len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 2;
17392 + if (len > TFTP_MAX_PACKET)
17393 + goto noak;
17394 + e = p + len;
17395 + while (*p != '\0' && p < e) {
17396 +/* if (!strcasecmp("blksize", p)) { */
17397 + if (!grub_strcmp("blksize", p)) {
17398 + p += 8;
17399 +/* if ((packetsize = strtoul(p, &p, 10)) < */
17400 + if ((packetsize = getdec(&p)) < TFTP_DEFAULTSIZE_PACKET)
17401 + goto noak;
17402 + while (p < e && *p) p++;
17403 + if (p < e)
17404 + p++;
17406 + else {
17407 + noak:
17408 + tp.opcode = htons(TFTP_ERROR);
17409 + tp.u.err.errcode = 8;
17411 + * Warning: the following assumes the layout of bootp_t.
17412 + * But that's fixed by the IP, UDP and BOOTP specs.
17413 + */
17414 + len = sizeof(tp.ip) + sizeof(tp.udp) + sizeof(tp.opcode) + sizeof(tp.u.err.errcode) +
17416 + * Normally bad form to omit the format string, but in this case
17417 + * the string we are copying from is fixed. sprintf is just being
17418 + * used as a strcpy and strlen.
17419 + */
17420 + sprintf((char *)tp.u.err.errmsg,
17421 + "RFC1782 error") + 1;
17422 + udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
17423 + iport, ntohs(tr->udp.src),
17424 + len, &tp);
17425 + return (0);
17428 + if (p > e)
17429 + goto noak;
17430 + block = tp.u.ack.block = 0; /* this ensures, that */
17431 + /* the packet does not get */
17432 + /* processed as data! */
17434 + else if (tr->opcode == htons(TFTP_DATA)) {
17435 + len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
17436 + if (len > packetsize) /* shouldn't happen */
17437 + continue; /* ignore it */
17438 + block = ntohs(tp.u.ack.block = tr->u.data.block); }
17439 + else {/* neither TFTP_OACK nor TFTP_DATA */
17440 + break;
17443 + if ((block || bcounter) && (block != (unsigned short)(prevblock+1))) {
17444 + /* Block order should be continuous */
17445 + tp.u.ack.block = htons(block = prevblock);
17447 + tp.opcode = htons(TFTP_ACK);
17448 + oport = ntohs(tr->udp.src);
17449 + udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, iport,
17450 + oport, TFTP_MIN_PACKET, &tp); /* ack */
17451 + if ((unsigned short)(block-prevblock) != 1) {
17452 + /* Retransmission or OACK, don't process via callback
17453 + * and don't change the value of prevblock. */
17454 + continue;
17456 + prevblock = block;
17457 + retry = 0; /* It's the right place to zero the timer? */
17458 + if ((rc = fnc(tr->u.data.download,
17459 + ++bcounter, len, len < packetsize)) <= 0)
17460 + return(rc);
17461 + if (len < packetsize) { /* End of data --- fnc should not have returned */
17462 + printf("tftp download complete, but\n");
17463 + return (1);
17466 + return (0);
17469 /* Fill the buffer by receiving the data via the TFTP protocol. */
17470 static int
17471 buf_fill (int abort)
17472 @@ -65,9 +232,9 @@
17473 timeout = rfc2131_sleep_interval (TIMEOUT, retry);
17474 #endif
17476 - if (! await_reply (AWAIT_TFTP, iport, NULL, timeout))
17477 + if (! await_reply (await_tftp, iport, NULL, timeout))
17479 - if (ip_abort)
17480 + if (user_abort)
17481 return 0;
17483 if (! block && retry++ < MAX_TFTP_RETRIES)
17484 @@ -270,13 +437,7 @@
17485 buf_read = 0;
17486 saved_filepos = 0;
17488 - /* Clear out the Rx queue first. It contains nothing of interest,
17489 - * except possibly ARP requests from the DHCP/TFTP server. We use
17490 - * polling throughout Etherboot, so some time may have passed since we
17491 - * last polled the receive queue, which may now be filled with
17492 - * broadcast packets. This will cause the reply to the packets we are
17493 - * about to send to be lost immediately. Not very clever. */
17494 - await_reply (AWAIT_QDRAIN, 0, NULL, 0);
17495 + rx_qdrain();
17497 #ifdef TFTP_DEBUG
17498 grub_printf ("send_rrq ()\n");
17499 Index: b/netboot/grub.h
17500 ===================================================================
17501 --- /dev/null
17502 +++ b/netboot/grub.h
17503 @@ -0,0 +1,171 @@
17504 +#ifndef GRUB_H
17505 +#define GRUB_H
17507 +#include "osdep.h"
17508 +#include "byteswap.h"
17509 +#include "in.h"
17510 +#include "ip.h"
17511 +#include "udp.h"
17512 +#include "if_ether.h"
17513 +#include "latch.h"
17514 +#include "io.h"
17515 +#include "nic.h"
17516 +#include <shared.h>
17518 +#define K_ESC '\033'
17519 +#define K_EOF '\04' /* Ctrl-D */
17520 +#define K_INTR '\03' /* Ctrl-C */
17522 +#ifndef MAX_RPC_RETRIES
17523 +#define MAX_RPC_RETRIES 20
17524 +#endif
17527 +/* Inter-packet retry in ticks */
17528 +#ifndef TIMEOUT
17529 +#define TIMEOUT (10*TICKS_PER_SEC)
17530 +#endif
17532 +#ifndef NULL
17533 +#define NULL ((void *)0)
17534 +#endif
17537 +#define ARP_CLIENT 0
17538 +#define ARP_SERVER 1
17539 +#define ARP_GATEWAY 2
17540 +#define MAX_ARP ARP_GATEWAY+1
17542 +#define IGMP_SERVER 0
17543 +#define MAX_IGMP IGMP_SERVER+1
17545 +#define RARP_REQUEST 3
17546 +#define RARP_REPLY 4
17549 +#define MULTICAST_MASK 0xF0000000
17550 +#define MULTICAST_NETWORK 0xE0000000
17552 +struct arptable_t {
17553 + in_addr ipaddr;
17554 + uint8_t node[6];
17557 +struct igmptable_t {
17558 + in_addr group;
17559 + unsigned long time;
17562 +#define KERNEL_BUF (BOOTP_DATA_ADDR->bootp_reply.bp_file)
17564 +#define FLOPPY_BOOT_LOCATION 0x7c00
17565 +/* Must match offsets in loader.S */
17566 +#define ROM_SEGMENT 0x1fa
17567 +#define ROM_LENGTH 0x1fc
17569 +#define ROM_INFO_LOCATION (FLOPPY_BOOT_LOCATION+ROM_SEGMENT)
17570 +/* at end of floppy boot block */
17574 +/* Define a type for passing info to a loaded program */
17575 +struct ebinfo {
17576 + uint8_t major, minor; /* Version */
17577 + uint16_t flags; /* Bit flags */
17580 +/***************************************************************************
17581 +External prototypes
17582 +***************************************************************************/
17583 +extern void rx_qdrain P((void));
17584 +extern int tftp P((const char *name, int (*)(unsigned char *, unsigned int, unsigned int, int)));
17585 +extern int ip_transmit P((int len, const void *buf));
17586 +extern void build_ip_hdr P((unsigned long destip, int ttl, int protocol,
17587 + int option_len, int len, const void *buf));
17588 +extern void build_udp_hdr P((unsigned long destip,
17589 + unsigned int srcsock, unsigned int destsock, int ttl,
17590 + int len, const void *buf));
17591 +extern int udp_transmit P((unsigned long destip, unsigned int srcsock,
17592 + unsigned int destsock, int len, const void *buf));
17593 +typedef int (*reply_t)(int ival, void *ptr, unsigned short ptype, struct iphdr *ip, struct udphdr *udp);
17594 +extern int await_reply P((reply_t reply, int ival, void *ptr, long timeout));
17595 +extern int decode_rfc1533 P((unsigned char *, unsigned int, unsigned int, int));
17596 +extern void join_group(int slot, unsigned long group);
17597 +extern void leave_group(int slot);
17598 +#define RAND_MAX 2147483647L
17599 +extern uint16_t ipchksum P((const void *ip, unsigned long len));
17600 +extern uint16_t add_ipchksums P((unsigned long offset, uint16_t sum, uint16_t new));
17601 +extern int32_t random P((void));
17602 +extern long rfc2131_sleep_interval P((long base, int exp));
17603 +extern long rfc1112_sleep_interval P((long base, int exp));
17604 +#ifndef DOWNLOAD_PROTO_TFTP
17605 +#define tftp(fname, load_block) 0
17606 +#endif
17607 +extern void cleanup P((void));
17609 +/* misc.c */
17610 +extern void twiddle P((void));
17611 +extern void sleep P((int secs));
17612 +extern void interruptible_sleep P((int secs));
17613 +extern void poll_interruptions P((void));
17614 +extern int strcasecmp P((const char *a, const char *b));
17615 +extern char *substr P((const char *a, const char *b));
17616 +extern unsigned long strtoul P((const char *p, const char **, int base));
17617 +extern void printf P((const char *, ...));
17618 +extern int sprintf P((char *, const char *, ...));
17619 +extern int inet_aton P((char *p, in_addr *i));
17620 +extern void putchar P((int));
17621 +extern int getchar P((void));
17622 +extern int iskey P((void));
17624 +extern void grub_printf(const char *, ...);
17625 +extern char config_file[128];
17626 +extern void etherboot_printf(const char *, ...);
17627 +extern int etherboot_sprintf(char *, const char *, ...);
17628 +extern int getdec(char **s);
17629 +extern void cleanup_net(void);
17630 +extern void print_network_configuration (void);
17631 +extern int ifconfig (char *, char *, char *, char *);
17632 +extern struct arptable_t arptable[MAX_ARP];
17634 +#undef printf
17635 +#undef sprintf
17636 +#define printf etherboot_printf
17637 +#define sprintf etherboot_sprintf
17639 +#ifdef DEBUG
17640 +#define EnterFunction(func) printf("Enter: " func "\n");
17641 +#define LeaveFunction(func) printf("Leave: " func "\n");
17642 +#else
17643 +#define EnterFunction(func)
17644 +#define LeaveFunction(func)
17645 +#endif
17648 + * Some codes from etherboot use a level in DEBUG. Define it to be
17649 + * zero means no debug info output, that will make them silence in
17650 + * compiling. Up it as you want.
17651 + */
17652 +#ifndef DEBUG
17653 +# define DEBUG 0
17654 +#endif
17656 +/*#define RPC_DEBUG*/
17658 +extern char *hostname;
17660 +extern int hostnamelen;
17661 +/* Whether network is ready */
17662 +extern int network_ready;
17664 +/* User aborted in await_reply if not zero */
17665 +extern int user_abort;
17667 +extern int rarp(void);
17668 +extern int grub_eth_probe(void);
17669 +extern int bootp(void);
17671 +extern int dhcp(void);
17673 +extern struct nic nic;
17674 +#endif /* GRUB_H */
17675 Index: b/netboot/i386_byteswap.h
17676 ===================================================================
17677 --- /dev/null
17678 +++ b/netboot/i386_byteswap.h
17679 @@ -0,0 +1,46 @@
17680 +#ifndef ETHERBOOT_BITS_BYTESWAP_H
17681 +#define ETHERBOOT_BITS_BYTESWAP_H
17683 +#include "types.h"
17684 +static inline uint16_t __i386_bswap_16(uint16_t x)
17686 + __asm__("xchgb %b0,%h0\n\t"
17687 + : "=q" (x)
17688 + : "0" (x));
17689 + return x;
17692 +static inline uint32_t __i386_bswap_32(uint32_t x)
17694 + __asm__("xchgb %b0,%h0\n\t"
17695 + "rorl $16,%0\n\t"
17696 + "xchgb %b0,%h0"
17697 + : "=q" (x)
17698 + : "0" (x));
17699 + return x;
17703 +#define __bswap_constant_16(x) \
17704 + ((uint16_t)((((uint16_t)(x) & 0x00ff) << 8) | \
17705 + (((uint16_t)(x) & 0xff00) >> 8)))
17707 +#define __bswap_constant_32(x) \
17708 + ((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
17709 + (((uint32_t)(x) & 0x0000ff00U) << 8) | \
17710 + (((uint32_t)(x) & 0x00ff0000U) >> 8) | \
17711 + (((uint32_t)(x) & 0xff000000U) >> 24)))
17713 +#define __bswap_16(x) \
17714 + (__builtin_constant_p(x) ? \
17715 + __bswap_constant_16(x) : \
17716 + __i386_bswap_16(x))
17719 +#define __bswap_32(x) \
17720 + (__builtin_constant_p(x) ? \
17721 + __bswap_constant_32(x) : \
17722 + __i386_bswap_32(x))
17725 +#endif /* ETHERBOOT_BITS_BYTESWAP_H */
17726 Index: b/netboot/i386_elf.h
17727 ===================================================================
17728 --- /dev/null
17729 +++ b/netboot/i386_elf.h
17730 @@ -0,0 +1,91 @@
17731 +#ifndef I386_BITS_ELF_H
17732 +#define I386_BITS_ELF_H
17734 +#include "cpu.h"
17736 +#ifdef CONFIG_X86_64
17737 +/* ELF Defines for the 64bit version of the current architecture */
17738 +#define EM_CURRENT_64 EM_X86_64
17739 +#define EM_CURRENT_64_PRESENT ( \
17740 + CPU_FEATURE_P(cpu_info.x86_capability, LM) && \
17741 + CPU_FEATURE_P(cpu_info.x86_capability, PAE) && \
17742 + CPU_FEATURE_P(cpu_info.x86_capability, PSE))
17744 +#define ELF_CHECK_X86_64_ARCH(x) \
17745 + (EM_CURRENT_64_PRESENT && ((x).e_machine == EM_X86_64))
17746 +#define __unused_i386
17747 +#else
17748 +#define ELF_CHECK_X86_64_ARCH(x) 0
17749 +#define __unused_i386 __unused
17750 +#endif
17753 +/* ELF Defines for the current architecture */
17754 +#define EM_CURRENT EM_386
17755 +#define ELFDATA_CURRENT ELFDATA2LSB
17757 +#define ELF_CHECK_I386_ARCH(x) \
17758 + (((x).e_machine == EM_386) || ((x).e_machine == EM_486))
17760 +#define ELF_CHECK_ARCH(x) \
17761 + ((ELF_CHECK_I386_ARCH(x) || ELF_CHECK_X86_64_ARCH(x)) && \
17762 + ((x).e_entry <= 0xffffffffUL))
17764 +#ifdef IMAGE_FREEBSD
17766 + * FreeBSD has this rather strange "feature" of its design.
17767 + * At some point in its evolution, FreeBSD started to rely
17768 + * externally on private/static/debug internal symbol information.
17769 + * That is, some of the interfaces that software uses to access
17770 + * and work with the FreeBSD kernel are made available not
17771 + * via the shared library symbol information (the .DYNAMIC section)
17772 + * but rather the debug symbols. This means that any symbol, not
17773 + * just publicly defined symbols can be (and are) used by system
17774 + * tools to make the system work. (such as top, swapinfo, swapon,
17775 + * etc)
17777 + * Even worse, however, is the fact that standard ELF loaders do
17778 + * not know how to load the symbols since they are not within
17779 + * an ELF PT_LOAD section. The kernel needs these symbols to
17780 + * operate so the following changes/additions to the boot
17781 + * loading of EtherBoot have been made to get the kernel to load.
17782 + * All of the changes are within IMAGE_FREEBSD such that the
17783 + * extra/changed code only compiles when FREEBSD support is
17784 + * enabled.
17785 + */
17788 + * Section header for FreeBSD (debug symbol kludge!) support
17789 + */
17790 +typedef struct {
17791 + Elf32_Word sh_name; /* Section name (index into the
17792 + section header string table). */
17793 + Elf32_Word sh_type; /* Section type. */
17794 + Elf32_Word sh_flags; /* Section flags. */
17795 + Elf32_Addr sh_addr; /* Address in memory image. */
17796 + Elf32_Off sh_offset; /* Offset in file. */
17797 + Elf32_Size sh_size; /* Size in bytes. */
17798 + Elf32_Word sh_link; /* Index of a related section. */
17799 + Elf32_Word sh_info; /* Depends on section type. */
17800 + Elf32_Size sh_addralign; /* Alignment in bytes. */
17801 + Elf32_Size sh_entsize; /* Size of each entry in section. */
17802 +} Elf32_Shdr;
17804 +/* sh_type */
17805 +#define SHT_SYMTAB 2 /* symbol table section */
17806 +#define SHT_STRTAB 3 /* string table section */
17809 + * Module information subtypes (for the metadata that we need to build)
17810 + */
17811 +#define MODINFO_END 0x0000 /* End of list */
17812 +#define MODINFO_NAME 0x0001 /* Name of module (string) */
17813 +#define MODINFO_TYPE 0x0002 /* Type of module (string) */
17814 +#define MODINFO_METADATA 0x8000 /* Module-specfic */
17816 +#define MODINFOMD_SSYM 0x0003 /* start of symbols */
17817 +#define MODINFOMD_ESYM 0x0004 /* end of symbols */
17819 +#endif /* IMAGE_FREEBSD */
17821 +#endif /* I386_BITS_ELF_H */
17822 Index: b/netboot/i386_endian.h
17823 ===================================================================
17824 --- /dev/null
17825 +++ b/netboot/i386_endian.h
17826 @@ -0,0 +1,6 @@
17827 +#ifndef ETHERBOOT_BITS_ENDIAN_H
17828 +#define ETHERBOOT_BITS_ENDIAN_H
17830 +#define __BYTE_ORDER __LITTLE_ENDIAN
17832 +#endif /* ETHERBOOT_BITS_ENDIAN_H */
17833 Index: b/netboot/i386_timer.c
17834 ===================================================================
17835 --- /dev/null
17836 +++ b/netboot/i386_timer.c
17837 @@ -0,0 +1,192 @@
17838 +/* A couple of routines to implement a low-overhead timer for drivers */
17840 + /*
17841 + * This program is free software; you can redistribute it and/or
17842 + * modify it under the terms of the GNU General Public License as
17843 + * published by the Free Software Foundation; either version 2, or (at
17844 + * your option) any later version.
17845 + */
17846 +#include "grub.h"
17847 +#include "osdep.h"
17848 +#include "io.h"
17849 +#include "timer.h"
17850 +#include "latch.h"
17852 +void __load_timer2(unsigned int ticks)
17854 + /*
17855 + * Now let's take care of PPC channel 2
17857 + * Set the Gate high, program PPC channel 2 for mode 0,
17858 + * (interrupt on terminal count mode), binary count,
17859 + * load 5 * LATCH count, (LSB and MSB) to begin countdown.
17861 + * Note some implementations have a bug where the high bits byte
17862 + * of channel 2 is ignored.
17863 + */
17864 + /* Set up the timer gate, turn off the speaker */
17865 + /* Set the Gate high, disable speaker */
17866 + outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
17867 + /* binary, mode 0, LSB/MSB, Ch 2 */
17868 + outb(TIMER2_SEL|WORD_ACCESS|MODE0|BINARY_COUNT, TIMER_MODE_PORT);
17869 + /* LSB of ticks */
17870 + outb(ticks & 0xFF, TIMER2_PORT);
17871 + /* MSB of ticks */
17872 + outb(ticks >> 8, TIMER2_PORT);
17875 +static int __timer2_running(void)
17877 + return ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
17880 +#if !defined(CONFIG_TSC_CURRTICKS)
17881 +void setup_timers(void)
17883 + return;
17886 +void load_timer2(unsigned int ticks)
17888 + return __load_timer2(ticks);
17891 +int timer2_running(void)
17893 + return __timer2_running();
17896 +void ndelay(unsigned int nsecs)
17898 + waiton_timer2((nsecs * CLOCK_TICK_RATE)/1000000000);
17900 +void udelay(unsigned int usecs)
17902 + waiton_timer2((usecs * TICKS_PER_MS)/1000);
17904 +#endif /* !defined(CONFIG_TSC_CURRTICKS) */
17906 +#if defined(CONFIG_TSC_CURRTICKS)
17908 +#define rdtsc(low,high) \
17909 + __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
17911 +#define rdtscll(val) \
17912 + __asm__ __volatile__ ("rdtsc" : "=A" (val))
17915 +/* Number of clock ticks to time with the rtc */
17916 +#define LATCH 0xFF
17918 +#define LATCHES_PER_SEC ((CLOCK_TICK_RATE + (LATCH/2))/LATCH)
17919 +#define TICKS_PER_LATCH ((LATCHES_PER_SEC + (TICKS_PER_SEC/2))/TICKS_PER_SEC)
17921 +static void sleep_latch(void)
17923 + __load_timer2(LATCH);
17924 + while(__timer2_running());
17927 +/* ------ Calibrate the TSC -------
17928 + * Time how long it takes to excute a loop that runs in known time.
17929 + * And find the convertion needed to get to CLOCK_TICK_RATE
17930 + */
17933 +static unsigned long long calibrate_tsc(void)
17935 + unsigned long startlow, starthigh;
17936 + unsigned long endlow, endhigh;
17938 + rdtsc(startlow,starthigh);
17939 + sleep_latch();
17940 + rdtsc(endlow,endhigh);
17942 + /* 64-bit subtract - gcc just messes up with long longs */
17943 + __asm__("subl %2,%0\n\t"
17944 + "sbbl %3,%1"
17945 + :"=a" (endlow), "=d" (endhigh)
17946 + :"g" (startlow), "g" (starthigh),
17947 + "0" (endlow), "1" (endhigh));
17949 + /* Error: ECPUTOOFAST */
17950 + if (endhigh)
17951 + goto bad_ctc;
17953 + endlow *= TICKS_PER_LATCH;
17954 + return endlow;
17956 + /*
17957 + * The CTC wasn't reliable: we got a hit on the very first read,
17958 + * or the CPU was so fast/slow that the quotient wouldn't fit in
17959 + * 32 bits..
17960 + */
17961 +bad_ctc:
17962 + printf("bad_ctc\n");
17963 + return 0;
17966 +static unsigned long clocks_per_tick;
17967 +void setup_timers(void)
17969 + if (!clocks_per_tick) {
17970 + clocks_per_tick = calibrate_tsc();
17971 + /* Display the CPU Mhz to easily test if the calibration was bad */
17972 + printf("CPU %ld Mhz\n", (clocks_per_tick/1000 * TICKS_PER_SEC)/1000);
17976 +unsigned long currticks(void)
17978 + unsigned long clocks_high, clocks_low;
17979 + unsigned long currticks;
17980 + /* Read the Time Stamp Counter */
17981 + rdtsc(clocks_low, clocks_high);
17983 + /* currticks = clocks / clocks_per_tick; */
17984 + __asm__("divl %1"
17985 + :"=a" (currticks)
17986 + :"r" (clocks_per_tick), "0" (clocks_low), "d" (clocks_high));
17989 + return currticks;
17992 +static unsigned long long timer_timeout;
17993 +static int __timer_running(void)
17995 + unsigned long long now;
17996 + rdtscll(now);
17997 + return now < timer_timeout;
18000 +void udelay(unsigned int usecs)
18002 + unsigned long long now;
18003 + rdtscll(now);
18004 + timer_timeout = now + usecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000));
18005 + while(__timer_running());
18007 +void ndelay(unsigned int nsecs)
18009 + unsigned long long now;
18010 + rdtscll(now);
18011 + timer_timeout = now + nsecs * ((clocks_per_tick * TICKS_PER_SEC)/(1000*1000*1000));
18012 + while(__timer_running());
18015 +void load_timer2(unsigned int timer2_ticks)
18017 + unsigned long long now;
18018 + unsigned long clocks;
18019 + rdtscll(now);
18020 + clocks = timer2_ticks * ((clocks_per_tick * TICKS_PER_SEC)/CLOCK_TICK_RATE);
18021 + timer_timeout = now + clocks;
18024 +int timer2_running(void)
18026 + return __timer_running();
18029 +#endif /* RTC_CURRTICKS */
18030 Index: b/netboot/i82586.c
18031 ===================================================================
18032 --- a/netboot/i82586.c
18033 +++ /dev/null
18034 @@ -1,825 +0,0 @@
18035 -/**************************************************************************
18036 -Etherboot - BOOTP/TFTP Bootstrap Program
18037 -i82586 NIC driver for Etherboot
18038 -Ken Yap, January 1998
18039 -***************************************************************************/
18042 - * This program is free software; you can redistribute it and/or
18043 - * modify it under the terms of the GNU General Public License as
18044 - * published by the Free Software Foundation; either version 2, or (at
18045 - * your option) any later version.
18046 - */
18048 -#include "etherboot.h"
18049 -#include "nic.h"
18050 -#include "cards.h"
18051 -#include "timer.h"
18053 -#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
18055 -/* Sources of information:
18057 - Donald Becker's excellent 3c507 driver in Linux
18058 - Intel 82596 data sheet (yes, 82596; it has a 586 compatibility mode)
18061 -/* Code below mostly stolen wholesale from 3c507.c driver in Linux */
18064 - Details of the i82586.
18066 - You'll really need the databook to understand the details of this part,
18067 - but the outline is that the i82586 has two separate processing units.
18068 - Both are started from a list of three configuration tables, of which only
18069 - the last, the System Control Block (SCB), is used after reset-time. The SCB
18070 - has the following fields:
18071 - Status word
18072 - Command word
18073 - Tx/Command block addr.
18074 - Rx block addr.
18075 - The command word accepts the following controls for the Tx and Rx units:
18076 - */
18078 -#define CUC_START 0x0100
18079 -#define CUC_RESUME 0x0200
18080 -#define CUC_SUSPEND 0x0300
18081 -#define RX_START 0x0010
18082 -#define RX_RESUME 0x0020
18083 -#define RX_SUSPEND 0x0030
18085 -/* The Rx unit uses a list of frame descriptors and a list of data buffer
18086 - descriptors. We use full-sized (1518 byte) data buffers, so there is
18087 - a one-to-one pairing of frame descriptors to buffer descriptors.
18089 - The Tx ("command") unit executes a list of commands that look like:
18090 - Status word Written by the 82586 when the command is done.
18091 - Command word Command in lower 3 bits, post-command action in upper 3
18092 - Link word The address of the next command.
18093 - Parameters (as needed).
18095 - Some definitions related to the Command Word are:
18096 - */
18097 -#define CMD_EOL 0x8000 /* The last command of the list, stop. */
18098 -#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
18099 -#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
18101 -enum commands {
18102 - CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
18103 - CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
18106 - Details of the EtherLink16 Implementation
18108 - The 3c507 and NI5210 are generic shared-memory i82586 implementations.
18109 - 3c507: The host can map 16K, 32K, 48K, or 64K of the 64K memory into
18110 - 0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
18111 - NI5210: The host can map 8k or 16k at 0x[CDE][048C]000 but we
18112 - assume 8k because to have 16k you cannot put a ROM on the NIC.
18113 - */
18115 -/* Offsets from the base I/O address. */
18117 -#ifdef INCLUDE_3C507
18119 -#define SA_DATA 0 /* Station address data, or 3Com signature. */
18120 -#define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */
18121 -#define RESET_IRQ 10 /* Reset the latched IRQ line. */
18122 -#define I82586_ATTN 11 /* Frob the 82586 Channel Attention line. */
18123 -#define ROM_CONFIG 13
18124 -#define MEM_CONFIG 14
18125 -#define IRQ_CONFIG 15
18126 -#define EL16_IO_EXTENT 16
18128 -/* The ID port is used at boot-time to locate the ethercard. */
18129 -#define ID_PORT 0x100
18131 -#endif
18133 -#ifdef INCLUDE_NI5210
18135 -#define NI52_RESET 0 /* writing to this address, resets the i82586 */
18136 -#define I82586_ATTN 1 /* channel attention, kick the 586 */
18138 -#endif
18140 -#ifdef INCLUDE_EXOS205
18142 -#define EXOS205_RESET 0 /* writing to this address, resets the i82586 */
18143 -#define I82586_ATTN 1 /* channel attention, kick the 586 */
18145 -#endif
18147 -/* Offsets to registers in the mailbox (SCB). */
18148 -#define iSCB_STATUS 0x8
18149 -#define iSCB_CMD 0xA
18150 -#define iSCB_CBL 0xC /* Command BLock offset. */
18151 -#define iSCB_RFA 0xE /* Rx Frame Area offset. */
18153 -/* Since the 3c507 maps the shared memory window so that the last byte is
18154 -at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
18155 -48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
18156 -We can account for this be setting the 'SBC Base' entry in the ISCP table
18157 -below for all the 16 bit offset addresses, and also adding the 'SCB Base'
18158 -value to all 24 bit physical addresses (in the SCP table and the TX and RX
18159 -Buffer Descriptors).
18160 - -Mark
18164 - What follows in 'init_words[]' is the "program" that is downloaded to the
18165 - 82586 memory. It's mostly tables and command blocks, and starts at the
18166 - reset address 0xfffff6. This is designed to be similar to the EtherExpress,
18167 - thus the unusual location of the SCB at 0x0008.
18169 - Even with the additional "don't care" values, doing it this way takes less
18170 - program space than initializing the individual tables, and I feel it's much
18171 - cleaner.
18173 - The databook is particularly useless for the first two structures, I had
18174 - to use the Crynwr driver as an example.
18176 - The memory setup is as follows:
18179 -#define CONFIG_CMD 0x18
18180 -#define SET_SA_CMD 0x24
18181 -#define SA_OFFSET 0x2A
18182 -#define IDLELOOP 0x30
18183 -#define TDR_CMD 0x38
18184 -#define TDR_TIME 0x3C
18185 -#define DUMP_CMD 0x40
18186 -#define DIAG_CMD 0x48
18187 -#define SET_MC_CMD 0x4E
18188 -#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
18190 -#define TX_BUF_START 0x0100
18191 -#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
18193 -#define RX_BUF_START 0x1000
18194 -#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
18195 -#define RX_BUF_END (mem_end - mem_start - 20)
18198 - That's it: only 86 bytes to set up the beast, including every extra
18199 - command available. The 170 byte buffer at DUMP_DATA is shared between the
18200 - Dump command (called only by the diagnostic program) and the SetMulticastList
18201 - command.
18203 - To complete the memory setup you only have to write the station address at
18204 - SA_OFFSET and create the Tx & Rx buffer lists.
18206 - The Tx command chain and buffer list is setup as follows:
18207 - A Tx command table, with the data buffer pointing to...
18208 - A Tx data buffer descriptor. The packet is in a single buffer, rather than
18209 - chaining together several smaller buffers.
18210 - A NoOp command, which initially points to itself,
18211 - And the packet data.
18213 - A transmit is done by filling in the Tx command table and data buffer,
18214 - re-writing the NoOp command, and finally changing the offset of the last
18215 - command to point to the current Tx command. When the Tx command is finished,
18216 - it jumps to the NoOp, when it loops until the next Tx command changes the
18217 - "link offset" in the NoOp. This way the 82586 never has to go through the
18218 - slow restart sequence.
18220 - The Rx buffer list is set up in the obvious ring structure. We have enough
18221 - memory (and low enough interrupt latency) that we can avoid the complicated
18222 - Rx buffer linked lists by alway associating a full-size Rx data buffer with
18223 - each Rx data frame.
18225 - I currently use one transmit buffer starting at TX_BUF_START (0x0100), and
18226 - use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
18228 - */
18230 -static unsigned short init_words[] = {
18231 - /* System Configuration Pointer (SCP). */
18232 -#if defined(INCLUDE_3C507)
18233 - 0x0000, /* Set bus size to 16 bits. */
18234 -#else
18235 - 0x0001, /* Set bus size to 8 bits */
18236 -#endif
18237 - 0,0, /* pad words. */
18238 - 0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */
18240 - /* Intermediate System Configuration Pointer (ISCP). */
18241 - 0x0001, /* Status word that's cleared when init is done. */
18242 - 0x0008,0,0, /* SCB offset, (skip, skip) */
18244 - /* System Control Block (SCB). */
18245 - 0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
18246 - CONFIG_CMD, /* Command list pointer, points to Configure. */
18247 - RX_BUF_START, /* Rx block list. */
18248 - 0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
18250 - /* 0x0018: Configure command. Change to put MAC data with packet. */
18251 - 0, CmdConfigure, /* Status, command. */
18252 - SET_SA_CMD, /* Next command is Set Station Addr. */
18253 - 0x0804, /* "4" bytes of config data, 8 byte FIFO. */
18254 - 0x2e40, /* Magic values, including MAC data location. */
18255 - 0, /* Unused pad word. */
18257 - /* 0x0024: Setup station address command. */
18258 - 0, CmdSASetup,
18259 - SET_MC_CMD, /* Next command. */
18260 - 0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
18262 - /* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
18263 - 0, CmdNOp, IDLELOOP, 0 /* pad */,
18265 - /* 0x0038: A unused Time-Domain Reflectometer command. */
18266 - 0, CmdTDR, IDLELOOP, 0,
18268 - /* 0x0040: An unused Dump State command. */
18269 - 0, CmdDump, IDLELOOP, DUMP_DATA,
18271 - /* 0x0048: An unused Diagnose command. */
18272 - 0, CmdDiagnose, IDLELOOP,
18274 - /* 0x004E: An empty set-multicast-list command. */
18275 - 0, CmdMulticastList, IDLELOOP, 0,
18278 -/* NIC specific static variables go here */
18280 -static unsigned short ioaddr, irq, scb_base;
18281 -static Address mem_start, mem_end;
18282 -static unsigned short rx_head, rx_tail;
18284 -#define read_mem(m,s) fmemcpy((char *)s, m, sizeof(s))
18286 -static void setup_rx_buffers(struct nic *nic)
18288 - Address write_ptr;
18289 - unsigned short cur_rx_buf;
18290 - static unsigned short rx_cmd[16] = {
18291 - 0x0000, /* Rx status */
18292 - 0x0000, /* Rx command, only and last */
18293 - RX_BUF_START, /* Link (will be adjusted) */
18294 - RX_BUF_START + 22, /* Buffer offset (will be adjusted) */
18295 - 0x0000, 0x0000, 0x0000, /* Pad for dest addr */
18296 - 0x0000, 0x0000, 0x0000, /* Pad for source addr */
18297 - 0x0000, /* Pad for protocol */
18298 - 0x0000, /* Buffer: Actual count */
18299 - -1, /* Buffer: Next (none) */
18300 - RX_BUF_START + 0x20, /* Buffer: Address low (+ scb_base) (will be adjusted) */
18301 - 0x0000, /* Buffer: Address high */
18302 - 0x8000 | (RX_BUF_SIZE - 0x20)
18303 - };
18305 - cur_rx_buf = rx_head = RX_BUF_START;
18306 - do { /* While there is room for one more buffer */
18307 - write_ptr = mem_start + cur_rx_buf;
18308 - /* adjust some contents */
18309 - rx_cmd[1] = 0x0000;
18310 - rx_cmd[2] = cur_rx_buf + RX_BUF_SIZE;
18311 - rx_cmd[3] = cur_rx_buf + 22;
18312 - rx_cmd[13] = cur_rx_buf + 0x20 + scb_base;
18313 - memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(rx_cmd));
18314 - rx_tail = cur_rx_buf;
18315 - cur_rx_buf += RX_BUF_SIZE;
18316 - } while (cur_rx_buf <= RX_BUF_END - RX_BUF_SIZE);
18317 - /* Terminate the list by setting the EOL bit and wrap ther pointer
18318 - to make the list a ring. */
18319 - write_ptr = mem_start + rx_tail;
18320 - rx_cmd[1] = 0xC000;
18321 - rx_cmd[2] = rx_head;
18322 - memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(unsigned short) * 3);
18325 -static void ack_status(void)
18327 - unsigned short cmd, status;
18328 - unsigned short *shmem = (short *)mem_start;
18330 - cmd = (status = shmem[iSCB_STATUS>>1]) & 0xf000;
18331 - if (status & 0x100) /* CU suspended? */
18332 - cmd |= CUC_RESUME;
18333 - if ((status & 0x200) == 0) /* CU not active? */
18334 - cmd |= CUC_START;
18335 - if (status & 0x010) /* RU suspended? */
18336 - cmd |= RX_RESUME;
18337 - else if ((status & 0x040) == 0) /* RU not active? */
18338 - cmd |= RX_START;
18339 - if (cmd == 0) /* Nothing to do */
18340 - return;
18341 - shmem[iSCB_CMD>>1] = cmd;
18342 -#if defined(DEBUG)
18343 - printf("Status %hX Command %hX\n", status, cmd);
18344 -#endif
18345 - outb(0, ioaddr + I82586_ATTN);
18348 -/**************************************************************************
18349 -RESET - Reset adapter
18350 -***************************************************************************/
18352 -static void i82586_reset(struct nic *nic)
18354 - unsigned long time;
18355 - unsigned short *shmem = (short *)mem_start;
18357 - /* put the card in its initial state */
18359 -#ifdef INCLUDE_3C507
18360 - /* Enable loopback to protect the wire while starting up,
18361 - and hold the 586 in reset during the memory initialisation. */
18362 - outb(0x20, ioaddr + MISC_CTRL);
18363 -#endif
18365 - /* Fix the ISCP address and base. */
18366 - init_words[3] = scb_base;
18367 - init_words[7] = scb_base;
18369 - /* Write the words at 0xfff6. */
18370 - /* Write the words at 0x0000. */
18371 - /* Fill in the station address. */
18372 - memcpy((char *)(mem_end - 10), (char *)init_words, 10);
18373 - memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
18374 - memcpy((char *)mem_start + SA_OFFSET, nic->node_addr, ETH_ALEN);
18375 - setup_rx_buffers(nic);
18377 -#ifdef INCLUDE_3C507
18378 - /* Start the 586 by releasing the reset line, but leave loopback. */
18379 - outb(0xA0, ioaddr + MISC_CTRL);
18380 -#endif
18382 - /* This was time consuming to track down; you need to give two channel
18383 - attention signals to reliably start up the i82586. */
18384 - outb(0, ioaddr + I82586_ATTN);
18385 - time = currticks() + TICKS_PER_SEC; /* allow 1 second to init */
18386 - while (
18387 - shmem[iSCB_STATUS>>1] == 0)
18389 - if (currticks() > time)
18391 - printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
18392 - shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
18393 - break;
18396 - /* Issue channel-attn -- the 82586 won't start. */
18397 - outb(0, ioaddr + I82586_ATTN);
18399 -#ifdef INCLUDE_3C507
18400 - /* Disable loopback. */
18401 - outb(0x80, ioaddr + MISC_CTRL);
18402 -#endif
18403 -#if defined(DEBUG)
18404 - printf("i82586 status %hX, cmd %hX\n",
18405 - shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
18406 -#endif
18409 -/**************************************************************************
18410 - POLL - Wait for a frame
18411 - ***************************************************************************/
18412 -static int i82586_poll(struct nic *nic)
18414 - int status;
18415 - unsigned short rfd_cmd, next_rx_frame, data_buffer_addr,
18416 - frame_status, pkt_len;
18417 - unsigned short *shmem = (short *)mem_start + rx_head;
18419 - /* return true if there's an ethernet packet ready to read */
18420 - if (
18421 - ((frame_status = shmem[0]) & 0x8000) == 0)
18422 - return (0); /* nope */
18423 - rfd_cmd = shmem[1];
18424 - next_rx_frame = shmem[2];
18425 - data_buffer_addr = shmem[3];
18426 - pkt_len = shmem[11];
18427 - status = 0;
18428 - if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
18429 - || (pkt_len & 0xC000) != 0xC000)
18430 - printf("\nRx frame corrupt, discarded");
18431 - else if ((frame_status & 0x2000) == 0)
18432 - printf("\nRx frame had error");
18433 - else
18435 - /* We have a frame, copy it to our buffer */
18436 - pkt_len &= 0x3FFF;
18437 - memcpy(nic->packet, (char *)mem_start + rx_head + 0x20, pkt_len);
18438 - /* Only packets not from ourself */
18439 - if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) != 0)
18441 - nic->packetlen = pkt_len;
18442 - status = 1;
18445 - /* Clear the status word and set EOL on Rx frame */
18446 - shmem[0] = 0;
18447 - shmem[1] = 0xC000;
18448 - *(short *)(mem_start + rx_tail + 2) = 0;
18449 - rx_tail = rx_head;
18450 - rx_head = next_rx_frame;
18451 - ack_status();
18452 - return (status);
18455 -/**************************************************************************
18456 - TRANSMIT - Transmit a frame
18457 - ***************************************************************************/
18458 -static void i82586_transmit(
18459 - struct nic *nic,
18460 - const char *d, /* Destination */
18461 - unsigned int t, /* Type */
18462 - unsigned int s, /* size */
18463 - const char *p) /* Packet */
18465 - Address bptr;
18466 - unsigned short type, z;
18467 - static unsigned short tx_cmd[11] = {
18468 - 0x0, /* Tx status */
18469 - CmdTx, /* Tx command */
18470 - TX_BUF_START+16, /* Next command is a NoOp */
18471 - TX_BUF_START+8, /* Data Buffer offset */
18472 - 0x8000, /* | with size */
18473 - 0xffff, /* No next data buffer */
18474 - TX_BUF_START+22, /* + scb_base */
18475 - 0x0, /* Buffer address high bits (always zero) */
18476 - 0x0, /* Nop status */
18477 - CmdNOp, /* Nop command */
18478 - TX_BUF_START+16 /* Next is myself */
18479 - };
18480 - unsigned short *shmem = (short *)mem_start + TX_BUF_START;
18482 - /* send the packet to destination */
18483 - /* adjust some contents */
18484 - type = htons(t);
18485 - if (s < ETH_ZLEN)
18486 - s = ETH_ZLEN;
18487 - tx_cmd[4] = (s + ETH_HLEN) | 0x8000;
18488 - tx_cmd[6] = TX_BUF_START + 22 + scb_base;
18489 - bptr = mem_start + TX_BUF_START;
18490 - memcpy((char *)bptr, (char *)tx_cmd, sizeof(tx_cmd));
18491 - bptr += sizeof(tx_cmd);
18492 - memcpy((char *)bptr, d, ETH_ALEN);
18493 - bptr += ETH_ALEN;
18494 - memcpy((char *)bptr, nic->node_addr, ETH_ALEN);
18495 - bptr += ETH_ALEN;
18496 - memcpy((char *)bptr, (char *)&type, sizeof(type));
18497 - bptr += sizeof(type);
18498 - memcpy((char *)bptr, p, s);
18499 - /* Change the offset in the IDLELOOP */
18500 - *(unsigned short *)(mem_start + IDLELOOP + 4) = TX_BUF_START;
18501 - /* Wait for transmit completion */
18502 - while (
18503 - (shmem[0] & 0x2000) == 0)
18505 - /* Change the offset in the IDLELOOP back and
18506 - change the final loop to point here */
18507 - *(unsigned short *)(mem_start + IDLELOOP + 4) = IDLELOOP;
18508 - *(unsigned short *)(mem_start + TX_BUF_START + 20) = IDLELOOP;
18509 - ack_status();
18512 -/**************************************************************************
18513 - DISABLE - Turn off ethernet interface
18514 - ***************************************************************************/
18515 -static void i82586_disable(struct nic *nic)
18517 - unsigned short *shmem = (short *)mem_start;
18519 -#if 0
18520 - /* Flush the Tx and disable Rx. */
18521 - shmem[iSCB_CMD>>1] = RX_SUSPEND | CUC_SUSPEND;
18522 - outb(0, ioaddr + I82586_ATTN);
18523 -#ifdef INCLUDE_NI5210
18524 - outb(0, ioaddr + NI52_RESET);
18525 -#endif
18526 -#endif /* 0 */
18529 -#ifdef INCLUDE_3C507
18531 -static int t507_probe1(struct nic *nic, unsigned short ioaddr)
18533 - int i;
18534 - Address size;
18535 - char mem_config;
18536 - char if_port;
18538 - if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3'
18539 - || inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O')
18540 - return (0);
18541 - irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
18542 - mem_config = inb(ioaddr + MEM_CONFIG);
18543 - if (mem_config & 0x20)
18545 - size = 65536L;
18546 - mem_start = 0xf00000L + (mem_config & 0x08 ? 0x080000L
18547 - : (((Address)mem_config & 0x3) << 17));
18549 - else
18551 - size = ((((Address)mem_config & 0x3) + 1) << 14);
18552 - mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12);
18554 - mem_end = mem_start + size;
18555 - scb_base = 65536L - size;
18556 - if_port = inb(ioaddr + ROM_CONFIG) & 0x80;
18557 - /* Get station address */
18558 - outb(0x01, ioaddr + MISC_CTRL);
18559 - for (i = 0; i < ETH_ALEN; ++i)
18561 - nic->node_addr[i] = inb(ioaddr+i);
18563 - printf("\n3c507 ioaddr %#hX, IRQ %d, mem [%#X-%#X], %sternal xcvr, addr %!\n",
18564 - ioaddr, irq, mem_start, mem_end, if_port ? "in" : "ex", nic->node_addr);
18565 - return (1);
18568 -/**************************************************************************
18569 -PROBE - Look for an adapter, this routine's visible to the outside
18570 -***************************************************************************/
18572 -struct nic *t507_probe(struct nic *nic, unsigned short *probe_addrs)
18574 - static unsigned char init_ID_done = 0;
18575 - unsigned short lrs_state = 0xff;
18576 - static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x280, 0 };
18577 - unsigned short *p;
18578 - int i;
18580 - if (init_ID_done == 0)
18582 - /* Send the ID sequence to the ID_PORT to enable the board */
18583 - outb(0x00, ID_PORT);
18584 - for (i = 0; i < 255; ++i)
18586 - outb(lrs_state, ID_PORT);
18587 - lrs_state <<= 1;
18588 - if (lrs_state & 0x100)
18589 - lrs_state ^= 0xe7;
18591 - outb(0x00, ID_PORT);
18592 - init_ID_done = 1;
18594 - /* if probe_addrs is 0, then routine can use a hardwired default */
18595 - if (probe_addrs == 0)
18596 - probe_addrs = io_addrs;
18597 - for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
18598 - if (t507_probe1(nic, ioaddr))
18599 - break;
18600 - if (ioaddr != 0)
18602 - /* point to NIC specific routines */
18603 - i82586_reset(nic);
18604 - nic->reset = i82586_reset;
18605 - nic->poll = i82586_poll;
18606 - nic->transmit = i82586_transmit;
18607 - nic->disable = i82586_disable;
18608 - return nic;
18610 - /* else */
18612 - return 0;
18616 -#endif
18618 -#ifdef INCLUDE_NI5210
18620 -static int ni5210_probe2(void)
18622 - unsigned short i;
18623 - unsigned short shmem[10];
18625 - /* Fix the ISCP address and base. */
18626 - init_words[3] = scb_base;
18627 - init_words[7] = scb_base;
18629 - /* Write the words at 0xfff6. */
18630 - /* Write the words at 0x0000. */
18631 - memcpy((char *)(mem_end - 10), (char *)init_words, 10);
18632 - memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
18633 - if (*(unsigned short *)mem_start != 1)
18634 - return (0);
18635 - outb(0, ioaddr + NI52_RESET);
18636 - outb(0, ioaddr + I82586_ATTN);
18637 - udelay(32);
18638 - i = 50;
18639 - while (
18640 - shmem[iSCB_STATUS>>1] == 0)
18642 - if (--i == 0)
18644 - printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
18645 - shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
18646 - break;
18649 - /* Issue channel-attn -- the 82586 won't start. */
18650 - outb(0, ioaddr + I82586_ATTN);
18651 - if (*(unsigned short *)mem_start != 0)
18652 - return (0);
18653 - return (1);
18656 -static int ni5210_probe1(struct nic *nic)
18658 - int i;
18659 - static Address mem_addrs[] = {
18660 - 0xc0000, 0xc4000, 0xc8000, 0xcc000,
18661 - 0xd0000, 0xd4000, 0xd8000, 0xdc000,
18662 - 0xe0000, 0xe4000, 0xe8000, 0xec000,
18663 - 0 };
18664 - Address *p;
18666 - if (inb(ioaddr + 6) != 0x0 || inb(ioaddr + 7) != 0x55)
18667 - return (0);
18668 - scb_base = -8192; /* assume 8k memory */
18669 - for (p = mem_addrs; (mem_start = *p) != 0; ++p)
18670 - if (mem_end = mem_start + 8192, ni5210_probe2())
18671 - break;
18672 - if (mem_start == 0)
18673 - return (0);
18674 - /* Get station address */
18675 - for (i = 0; i < ETH_ALEN; ++i)
18677 - nic->node_addr[i] = inb(ioaddr+i);
18679 - printf("\nNI5210 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
18680 - ioaddr, mem_start, mem_end, nic->node_addr);
18681 - return (1);
18684 -struct nic *ni5210_probe(struct nic *nic, unsigned short *probe_addrs)
18686 - /* missing entries are addresses usually already used */
18687 - static unsigned short io_addrs[] = {
18688 - 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 0x238,
18689 - 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, /*Par*/
18690 - 0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8,
18691 - 0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0, /*Ser*/
18692 - 0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330, 0x338,
18693 - 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, /*Par*/
18694 - 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, /*Vid,Par*/
18695 - 0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, /*Ser*/
18696 - 0x0
18697 - };
18698 - unsigned short *p;
18699 - int i;
18701 - /* if probe_addrs is 0, then routine can use a hardwired default */
18702 - if (probe_addrs == 0)
18703 - probe_addrs = io_addrs;
18704 - for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
18705 - if (ni5210_probe1(nic))
18706 - break;
18707 - if (ioaddr != 0)
18709 - /* point to NIC specific routines */
18710 - i82586_reset(nic);
18711 - nic->reset = i82586_reset;
18712 - nic->poll = i82586_poll;
18713 - nic->transmit = i82586_transmit;
18714 - nic->disable = i82586_disable;
18715 - return nic;
18717 - /* else */
18719 - return 0;
18722 -#endif
18724 -#ifdef INCLUDE_EXOS205
18727 - * Code to download to I186 in EXOS205
18728 - */
18730 -static unsigned char exos_i186_init[] =
18732 -0x08,0x00,0x14,0x00,0x00,0x00,0xaa,0xfa,0x33,0xc0,0xba,0xfe,0xff,0xef,0xb8,0xf8,
18733 -0xff,0xe7,0xa0,0xb8,0x7c,0x00,0xe7,0xa4,0xb8,0xbc,0x80,0xe7,0xa8,0x8c,0xc8,0x8e,
18734 -0xd8,0xbb,0x2f,0x0e,0xc6,0x07,0xa5,0x33,0xc9,0xeb,0x00,0xeb,0x00,0xeb,0x00,0xe2,
18735 -0xf8,0xbe,0x2c,0x0e,0xba,0x02,0x05,0x33,0xdb,0xb9,0x03,0x00,0xec,0x24,0x0f,0x8a,
18736 -0xe0,0x02,0xd8,0x42,0x42,0xec,0x02,0xd8,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,
18737 -0x0a,0xc4,0x88,0x04,0x42,0x42,0x46,0xe2,0xe3,0x8a,0xe3,0xd0,0xec,0xd0,0xec,0xd0,
18738 -0xec,0xd0,0xec,0x80,0xe3,0x0f,0x02,0xe3,0x80,0xf4,0x05,0xec,0x3a,0xe0,0x74,0x05,
18739 -0xc6,0x04,0x5a,0xeb,0xfe,0xc6,0x04,0x55,0x33,0xc0,0x8e,0xd8,0xbe,0x38,0x00,0xc7,
18740 -0x04,0xce,0x0e,0x46,0x46,0xc7,0x04,0x00,0xff,0xfb,0xba,0x3c,0x00,0xb8,0x03,0x00,
18741 -0xef,0x33,0xdb,0x33,0xc9,0xbd,0x04,0x0f,0x90,0x90,0x90,0x90,0xe2,0xfa,0x43,0x2e,
18742 -0x89,0x5e,0x00,0xeb,0xf3,0x52,0xba,0x00,0x06,0xef,0x50,0x53,0x55,0xbd,0xf8,0x0e,
18743 -0x2e,0x8b,0x5e,0x00,0x43,0x2e,0x89,0x5e,0x00,0xba,0x22,0x00,0xb8,0x00,0x80,0xef,
18744 -0x5d,0x5b,0x58,0x5a,0xcf,0x49,0x4e,0x54,0x52,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,
18745 -0x00,0x4c,0x4f,0x4f,0x50,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x00,0x00,0x00,
18746 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18747 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18748 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18749 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18750 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18751 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18752 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18753 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18754 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18755 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18756 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18757 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18758 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18759 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18760 -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x30,0x0e,0x00,0xff,0x00,0x00,0x00,0x00,
18761 -0x00,0x00,0x00,0x00,0x00,0x00,00
18764 -/* These offsets are from the end of the i186 download code */
18766 -#define OFFSET_SEMA 0x1D1
18767 -#define OFFSET_ADDR 0x1D7
18769 -static int exos205_probe2(void)
18771 - unsigned short i;
18772 - unsigned short shmem[10];
18774 - /* Fix the ISCP address and base. */
18775 - init_words[3] = scb_base;
18776 - init_words[7] = scb_base;
18778 - /* Write the words at 0xfff6. */
18779 - /* Write the words at 0x0000. */
18780 - memcpy((char *)(mem_end - 10), (char *)init_words, 10);
18781 - memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
18782 - if (*(unsigned short *)mem_start != 1)
18783 - return (0);
18784 - outb(0, ioaddr + EXOS205_RESET);
18785 - outb(0, ioaddr + I82586_ATTN);
18786 - i = 50;
18787 - while (
18788 - shmem[iSCB_STATUS>>1] == 0)
18790 - if (--i == 0)
18792 - printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
18793 - shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
18794 - break;
18797 - /* Issue channel-attn -- the 82586 won't start. */
18798 - outb(0, ioaddr + I82586_ATTN);
18799 - if (*(unsigned short *)mem_start != 0)
18800 - return (0);
18801 - return (1);
18804 -static int exos205_probe1(struct nic *nic)
18806 - int i;
18807 - /* If you know the other addresses please let me know */
18808 - static Address mem_addrs[] = {
18809 - 0xcc000, 0 };
18810 - Address *p;
18812 - scb_base = -16384; /* assume 8k memory */
18813 - for (p = mem_addrs; (mem_start = *p) != 0; ++p)
18814 - if (mem_end = mem_start + 16384, exos205_probe2())
18815 - break;
18816 - if (mem_start == 0)
18817 - return (0);
18818 - /* Get station address */
18819 - for (i = 0; i < ETH_ALEN; ++i)
18821 - nic->node_addr[i] = inb(ioaddr+i);
18823 - printf("\nEXOS205 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
18824 - ioaddr, mem_start, mem_end, nic->node_addr);
18825 - return (1);
18828 -struct nic *exos205_probe(struct nic *nic, unsigned short *probe_addrs)
18830 - /* If you know the other addresses, please let me know */
18831 - static unsigned short io_addrs[] = {
18832 - 0x310, 0x0
18833 - };
18834 - unsigned short *p;
18835 - int i;
18837 - /* if probe_addrs is 0, then routine can use a hardwired default */
18838 - if (probe_addrs == 0)
18839 - probe_addrs = io_addrs;
18840 - for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
18841 - if (exos205_probe1(nic))
18842 - break;
18843 - if (ioaddr != 0)
18845 - /* point to NIC specific routines */
18846 - i82586_reset(nic);
18847 - nic->reset = i82586_reset;
18848 - nic->poll = i82586_poll;
18849 - nic->transmit = i82586_transmit;
18850 - nic->disable = i82586_disable;
18851 - return nic;
18853 - /* else */
18855 - return 0;
18859 -#endif
18860 Index: b/netboot/if_arp.h
18861 ===================================================================
18862 --- /dev/null
18863 +++ b/netboot/if_arp.h
18864 @@ -0,0 +1,29 @@
18865 +#ifndef _IF_ARP_H
18866 +#define _IF_ARP_H
18868 +#include "types.h"
18870 +#define ARP_REQUEST 1
18871 +#define ARP_REPLY 2
18873 +#ifndef MAX_ARP_RETRIES
18874 +#define MAX_ARP_RETRIES 20
18875 +#endif
18878 + * A pity sipaddr and tipaddr are not longword aligned or we could use
18879 + * in_addr. No, I don't want to use #pragma packed.
18880 + */
18881 +struct arprequest {
18882 + uint16_t hwtype;
18883 + uint16_t protocol;
18884 + uint8_t hwlen;
18885 + uint8_t protolen;
18886 + uint16_t opcode;
18887 + uint8_t shwaddr[6];
18888 + uint8_t sipaddr[4];
18889 + uint8_t thwaddr[6];
18890 + uint8_t tipaddr[4];
18893 +#endif /* _IF_ARP_H */
18894 Index: b/netboot/if_ether.h
18895 ===================================================================
18896 --- /dev/null
18897 +++ b/netboot/if_ether.h
18898 @@ -0,0 +1,21 @@
18899 +#ifndef _IF_ETHER_H
18900 +#define _IF_ETHER_H
18903 + I'm moving towards the defined names in linux/if_ether.h for clarity.
18904 + The confusion between 60/64 and 1514/1518 arose because the NS8390
18905 + counts the 4 byte frame checksum in the incoming packet, but not
18906 + in the outgoing packet. 60/1514 are the correct numbers for most
18907 + if not all of the other NIC controllers.
18910 +#define ETH_ALEN 6 /* Size of Ethernet address */
18911 +#define ETH_HLEN 14 /* Size of ethernet header */
18912 +#define ETH_ZLEN 60 /* Minimum packet */
18913 +#define ETH_FRAME_LEN 1514 /* Maximum packet */
18914 +#define ETH_DATA_ALIGN 2 /* Amount needed to align the data after an ethernet header */
18915 +#ifndef ETH_MAX_MTU
18916 +#define ETH_MAX_MTU (ETH_FRAME_LEN-ETH_HLEN)
18917 +#endif
18919 +#endif /* _IF_ETHER_H */
18920 Index: b/netboot/igmp.h
18921 ===================================================================
18922 --- /dev/null
18923 +++ b/netboot/igmp.h
18924 @@ -0,0 +1,27 @@
18925 +#ifndef _IGMP_H
18926 +#define _IGMP_H
18928 +/* Max interval between IGMP packets */
18929 +#define IGMP_INTERVAL (10*TICKS_PER_SEC)
18930 +#define IGMPv1_ROUTER_PRESENT_TIMEOUT (400*TICKS_PER_SEC)
18932 +#define IGMP_QUERY 0x11
18933 +#define IGMPv1_REPORT 0x12
18934 +#define IGMPv2_REPORT 0x16
18935 +#define IGMP_LEAVE 0x17
18936 +#define GROUP_ALL_HOSTS 0xe0000001 /* 224.0.0.1 Host byte order */
18938 +struct igmp {
18939 + uint8_t type;
18940 + uint8_t response_time;
18941 + uint16_t chksum;
18942 + in_addr group;
18945 +struct igmp_ip_t { /* Format of an igmp ip packet */
18946 + struct iphdr ip;
18947 + uint8_t router_alert[4]; /* Router alert option */
18948 + struct igmp igmp;
18951 +#endif /* _IGMP_H */
18952 Index: b/netboot/in.h
18953 ===================================================================
18954 --- /dev/null
18955 +++ b/netboot/in.h
18956 @@ -0,0 +1,21 @@
18957 +#ifndef _IN_H
18958 +#define _IN_H
18960 +#include "types.h"
18962 +#define IP 0x0800
18963 +#define ARP 0x0806
18964 +#define RARP 0x8035
18966 +#define IP_ICMP 1
18967 +#define IP_IGMP 2
18968 +#define IP_UDP 17
18970 +/* Same after going through htonl */
18971 +#define IP_BROADCAST 0xFFFFFFFF
18973 +typedef struct {
18974 + uint32_t s_addr;
18975 +} in_addr;
18977 +#endif /* _IN_H */
18978 Index: b/netboot/io.h
18979 ===================================================================
18980 --- /dev/null
18981 +++ b/netboot/io.h
18982 @@ -0,0 +1,239 @@
18983 +#ifndef IO_H
18984 +#define IO_H
18987 +/* Amount of relocation etherboot is experiencing */
18988 +extern unsigned long virt_offset;
18990 +/* Don't require identity mapped physical memory,
18991 + * osloader.c is the only valid user at the moment.
18992 + */
18993 +unsigned long virt_to_phys(volatile const void *virt_addr);
18994 +void *phys_to_virt(unsigned long phys_addr);
18996 +/* virt_to_bus converts an addresss inside of etherboot [_start, _end]
18997 + * into a memory access cards can use.
18998 + */
18999 +#define virt_to_bus virt_to_phys
19002 +/* bus_to_virt reverses virt_to_bus, the address must be output
19003 + * from virt_to_bus to be valid. This function does not work on
19004 + * all bus addresses.
19005 + */
19006 +#define bus_to_virt phys_to_virt
19008 +/* ioremap converts a random 32bit bus address into something
19009 + * etherboot can access.
19010 + */
19011 +static inline void *ioremap(unsigned long bus_addr, unsigned long length __unused)
19013 + return bus_to_virt(bus_addr);
19016 +/* iounmap cleans up anything ioremap had to setup */
19017 +static inline void iounmap(void *virt_addr __unused)
19019 + return;
19023 + * This file contains the definitions for the x86 IO instructions
19024 + * inb/inw/inl/outb/outw/outl and the "string versions" of the same
19025 + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
19026 + * versions of the single-IO instructions (inb_p/inw_p/..).
19028 + * This file is not meant to be obfuscating: it's just complicated
19029 + * to (a) handle it all in a way that makes gcc able to optimize it
19030 + * as well as possible and (b) trying to avoid writing the same thing
19031 + * over and over again with slight variations and possibly making a
19032 + * mistake somewhere.
19033 + */
19036 + * Thanks to James van Artsdalen for a better timing-fix than
19037 + * the two short jumps: using outb's to a nonexistent port seems
19038 + * to guarantee better timings even on fast machines.
19040 + * On the other hand, I'd like to be sure of a non-existent port:
19041 + * I feel a bit unsafe about using 0x80 (should be safe, though)
19043 + * Linus
19044 + */
19046 +#ifdef SLOW_IO_BY_JUMPING
19047 +#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
19048 +#else
19049 +#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
19050 +#endif
19052 +#ifdef REALLY_SLOW_IO
19053 +#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
19054 +#else
19055 +#define SLOW_DOWN_IO __SLOW_DOWN_IO
19056 +#endif
19059 + * readX/writeX() are used to access memory mapped devices. On some
19060 + * architectures the memory mapped IO stuff needs to be accessed
19061 + * differently. On the x86 architecture, we just read/write the
19062 + * memory location directly.
19063 + */
19064 +#define readb(addr) (*(volatile unsigned char *) (addr))
19065 +#define readw(addr) (*(volatile unsigned short *) (addr))
19066 +#define readl(addr) (*(volatile unsigned int *) (addr))
19068 +#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
19069 +#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
19070 +#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
19072 +#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
19073 +#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
19076 + * Force strict CPU ordering.
19077 + * And yes, this is required on UP too when we're talking
19078 + * to devices.
19080 + * For now, "wmb()" doesn't actually do anything, as all
19081 + * Intel CPU's follow what Intel calls a *Processor Order*,
19082 + * in which all writes are seen in the program order even
19083 + * outside the CPU.
19085 + * I expect future Intel CPU's to have a weaker ordering,
19086 + * but I'd also expect them to finally get their act together
19087 + * and add some real memory barriers if so.
19089 + * Some non intel clones support out of order store. wmb() ceases to be a
19090 + * nop for these.
19091 + */
19093 +#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
19094 +#define rmb() mb()
19095 +#define wmb() mb();
19099 + * Talk about misusing macros..
19100 + */
19102 +#define __OUT1(s,x) \
19103 +extern void __out##s(unsigned x value, unsigned short port); \
19104 +extern inline void __out##s(unsigned x value, unsigned short port) {
19106 +#define __OUT2(s,s1,s2) \
19107 +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
19109 +#define __OUT(s,s1,x) \
19110 +__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
19111 +__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
19112 +__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
19113 +__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
19115 +#define __IN1(s,x) \
19116 +extern unsigned x __in##s(unsigned short port); \
19117 +extern inline unsigned x __in##s(unsigned short port) { unsigned x _v;
19119 +#define __IN2(s,s1,s2) \
19120 +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
19122 +#define __IN(s,s1,x,i...) \
19123 +__IN1(s,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
19124 +__IN1(s##c,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
19125 +__IN1(s##_p,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
19126 +__IN1(s##c_p,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
19128 +#define __INS(s) \
19129 +extern void ins##s(unsigned short port, void * addr, unsigned long count); \
19130 +extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
19131 +{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
19132 +: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
19134 +#define __OUTS(s) \
19135 +extern void outs##s(unsigned short port, const void * addr, unsigned long count); \
19136 +extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
19137 +{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
19138 +: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
19140 +__IN(b,"", char)
19141 +__IN(w,"",short)
19142 +__IN(l,"", long)
19144 +__OUT(b,"b",char)
19145 +__OUT(w,"w",short)
19146 +__OUT(l,,int)
19148 +__INS(b)
19149 +__INS(w)
19150 +__INS(l)
19152 +__OUTS(b)
19153 +__OUTS(w)
19154 +__OUTS(l)
19157 + * Note that due to the way __builtin_constant_p() works, you
19158 + * - can't use it inside a inline function (it will never be true)
19159 + * - you don't have to worry about side effects within the __builtin..
19160 + */
19161 +#define outb(val,port) \
19162 +((__builtin_constant_p((port)) && (port) < 256) ? \
19163 + __outbc((val),(port)) : \
19164 + __outb((val),(port)))
19166 +#define inb(port) \
19167 +((__builtin_constant_p((port)) && (port) < 256) ? \
19168 + __inbc(port) : \
19169 + __inb(port))
19171 +#define outb_p(val,port) \
19172 +((__builtin_constant_p((port)) && (port) < 256) ? \
19173 + __outbc_p((val),(port)) : \
19174 + __outb_p((val),(port)))
19176 +#define inb_p(port) \
19177 +((__builtin_constant_p((port)) && (port) < 256) ? \
19178 + __inbc_p(port) : \
19179 + __inb_p(port))
19181 +#define outw(val,port) \
19182 +((__builtin_constant_p((port)) && (port) < 256) ? \
19183 + __outwc((val),(port)) : \
19184 + __outw((val),(port)))
19186 +#define inw(port) \
19187 +((__builtin_constant_p((port)) && (port) < 256) ? \
19188 + __inwc(port) : \
19189 + __inw(port))
19191 +#define outw_p(val,port) \
19192 +((__builtin_constant_p((port)) && (port) < 256) ? \
19193 + __outwc_p((val),(port)) : \
19194 + __outw_p((val),(port)))
19196 +#define inw_p(port) \
19197 +((__builtin_constant_p((port)) && (port) < 256) ? \
19198 + __inwc_p(port) : \
19199 + __inw_p(port))
19201 +#define outl(val,port) \
19202 +((__builtin_constant_p((port)) && (port) < 256) ? \
19203 + __outlc((val),(port)) : \
19204 + __outl((val),(port)))
19206 +#define inl(port) \
19207 +((__builtin_constant_p((port)) && (port) < 256) ? \
19208 + __inlc(port) : \
19209 + __inl(port))
19211 +#define outl_p(val,port) \
19212 +((__builtin_constant_p((port)) && (port) < 256) ? \
19213 + __outlc_p((val),(port)) : \
19214 + __outl_p((val),(port)))
19216 +#define inl_p(port) \
19217 +((__builtin_constant_p((port)) && (port) < 256) ? \
19218 + __inlc_p(port) : \
19219 + __inl_p(port))
19221 +#endif /* ETHERBOOT_IO_H */
19222 Index: b/netboot/ip.h
19223 ===================================================================
19224 --- /dev/null
19225 +++ b/netboot/ip.h
19226 @@ -0,0 +1,36 @@
19227 +#ifndef _IP_H
19228 +#define _IP_H
19230 +/* We need 'uint16_t' */
19231 +#include "types.h"
19232 +/* We need 'in_addr' */
19233 +#include "in.h"
19235 +struct iphdr {
19236 + uint8_t verhdrlen;
19237 + uint8_t service;
19238 + uint16_t len;
19239 + uint16_t ident;
19240 + uint16_t frags;
19241 + uint8_t ttl;
19242 + uint8_t protocol;
19243 + uint16_t chksum;
19244 + in_addr src;
19245 + in_addr dest;
19248 +extern void build_ip_hdr(unsigned long __destip, int __ttl, int __protocol,
19249 + int __option_len, int __len, const void * __buf);
19251 +extern int ip_transmit(int __len, const void * __buf);
19253 +extern uint16_t ipchksum(const void * __data, unsigned long __length);
19255 +extern uint16_t add_ipchksums(unsigned long __offset, uint16_t __sum,
19256 + uint16_t __new);
19262 +#endif /* _IP_H */
19263 Index: b/netboot/isa.h
19264 ===================================================================
19265 --- /dev/null
19266 +++ b/netboot/isa.h
19267 @@ -0,0 +1,27 @@
19268 +#if !defined(ISA_H) && defined(CONFIG_ISA)
19269 +#define ISA_H
19271 +struct dev;
19273 +#define ISAPNP_VENDOR(a,b,c) (((((a)-'A'+1)&0x3f)<<2)|\
19274 + ((((b)-'A'+1)&0x18)>>3)|((((b)-'A'+1)&7)<<13)|\
19275 + ((((c)-'A'+1)&0x1f)<<8))
19277 +#define GENERIC_ISAPNP_VENDOR ISAPNP_VENDOR('P','N','P')
19279 +struct isa_driver
19281 + int type;
19282 + const char *name;
19283 + int (*probe)(struct dev *, unsigned short *);
19284 + unsigned short *ioaddrs;
19287 +#define __isa_driver __attribute__ ((unused,__section__(".drivers.isa")))
19288 +extern const struct isa_driver isa_drivers[];
19289 +extern const struct isa_driver isa_drivers_end[];
19291 +#define ISA_ROM(IMAGE, DESCRIPTION)
19293 +#endif /* ISA_H */
19295 Index: b/netboot/lance.c
19296 ===================================================================
19297 --- a/netboot/lance.c
19298 +++ /dev/null
19299 @@ -1,564 +0,0 @@
19300 -/**************************************************************************
19301 -Etherboot - BOOTP/TFTP Bootstrap Program
19302 -LANCE NIC driver for Etherboot
19303 -Large portions borrowed from the Linux LANCE driver by Donald Becker
19304 -Ken Yap, July 1997
19305 -***************************************************************************/
19308 - * This program is free software; you can redistribute it and/or
19309 - * modify it under the terms of the GNU General Public License as
19310 - * published by the Free Software Foundation; either version 2, or (at
19311 - * your option) any later version.
19312 - */
19314 -/* to get some global routines like printf */
19315 -#include "etherboot.h"
19316 -/* to get the interface to the body of the program */
19317 -#include "nic.h"
19318 -#ifdef INCLUDE_LANCE
19319 -#include "pci.h"
19320 -#endif
19321 -#include "cards.h"
19323 -/* Offsets from base I/O address */
19324 -#if defined(INCLUDE_NE2100) || defined(INCLUDE_LANCE)
19325 -#define LANCE_ETH_ADDR 0x0
19326 -#define LANCE_DATA 0x10
19327 -#define LANCE_ADDR 0x12
19328 -#define LANCE_RESET 0x14
19329 -#define LANCE_BUS_IF 0x16
19330 -#define LANCE_TOTAL_SIZE 0x18
19331 -#endif
19332 -#ifdef INCLUDE_NI6510
19333 -#define LANCE_ETH_ADDR 0x8
19334 -#define LANCE_DATA 0x0
19335 -#define LANCE_ADDR 0x2
19336 -#define LANCE_RESET 0x4
19337 -#define LANCE_BUS_IF 0x6
19338 -#define LANCE_TOTAL_SIZE 0x10
19339 -#endif
19341 -/* lance_poll() now can use multiple Rx buffers to prevent packet loss. Set
19342 - * Set LANCE_LOG_RX_BUFFERS to 0..7 for 1, 2, 4, 8, 16, 32, 64 or 128 Rx
19343 - * buffers. Usually 4 (=16 Rx buffers) is a good value. (Andreas Neuhaus)
19344 - * Decreased to 2 (=4 Rx buffers) (Ken Yap, 20010305) */
19346 -#define LANCE_LOG_RX_BUFFERS 2 /* Use 2^2=4 Rx buffers */
19348 -#define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
19349 -#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
19350 -#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
19352 -struct lance_init_block
19354 - unsigned short mode;
19355 - unsigned char phys_addr[ETH_ALEN];
19356 - unsigned long filter[2];
19357 - Address rx_ring;
19358 - Address tx_ring;
19361 -struct lance_rx_head
19363 - union {
19364 - Address base;
19365 - unsigned char addr[4];
19366 - } u;
19367 - short buf_length; /* 2s complement */
19368 - short msg_length;
19371 -struct lance_tx_head
19373 - union {
19374 - Address base;
19375 - unsigned char addr[4];
19376 - } u;
19377 - short buf_length; /* 2s complement */
19378 - short misc;
19381 -struct lance_interface
19383 - struct lance_init_block init_block;
19384 - struct lance_rx_head rx_ring[RX_RING_SIZE];
19385 - struct lance_tx_head tx_ring;
19386 - unsigned char rbuf[RX_RING_SIZE][ETH_FRAME_LEN+4];
19387 - unsigned char tbuf[ETH_FRAME_LEN];
19388 - /*
19389 - * Do not alter the order of the struct members above;
19390 - * the hardware depends on the correct alignment.
19391 - */
19392 - int rx_idx;
19395 -#define LANCE_MUST_PAD 0x00000001
19396 -#define LANCE_ENABLE_AUTOSELECT 0x00000002
19397 -#define LANCE_SELECT_PHONELINE 0x00000004
19398 -#define LANCE_MUST_UNRESET 0x00000008
19400 -/* A mapping from the chip ID number to the part number and features.
19401 - These are from the datasheets -- in real life the '970 version
19402 - reportedly has the same ID as the '965. */
19403 -static const struct lance_chip_type
19405 - int id_number;
19406 - const char *name;
19407 - int flags;
19408 -} chip_table[] = {
19409 - {0x0000, "LANCE 7990", /* Ancient lance chip. */
19410 - LANCE_MUST_PAD + LANCE_MUST_UNRESET},
19411 - {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
19412 - LANCE_ENABLE_AUTOSELECT},
19413 - {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
19414 - LANCE_ENABLE_AUTOSELECT},
19415 - {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
19416 - LANCE_ENABLE_AUTOSELECT},
19417 - /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
19418 - it the PCnet32. */
19419 - {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
19420 - LANCE_ENABLE_AUTOSELECT},
19421 - {0x2621, "PCnet/PCI-II 79C970A", /* 79C970A PCInetPCI II. */
19422 - LANCE_ENABLE_AUTOSELECT},
19423 - {0x2625, "PCnet-FAST III 79C973", /* 79C973 PCInet-FAST III. */
19424 - LANCE_ENABLE_AUTOSELECT},
19425 - {0x2626, "PCnet/HomePNA 79C978",
19426 - LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
19427 - {0x0, "PCnet (unknown)",
19428 - LANCE_ENABLE_AUTOSELECT},
19431 -/* Define a macro for converting program addresses to real addresses */
19432 -#undef virt_to_bus
19433 -#define virt_to_bus(x) ((unsigned long)x)
19435 -static int chip_version;
19436 -static int lance_version;
19437 -static unsigned short ioaddr;
19438 -#ifndef INCLUDE_LANCE
19439 -static int dma;
19440 -#endif
19441 -static struct lance_interface *lp;
19443 -/* additional 8 bytes for 8-byte alignment space */
19444 -#ifdef USE_LOWMEM_BUFFER
19445 -#define lance ((char *)0x10000 - (sizeof(struct lance_interface)+8))
19446 -#else
19447 -static char lance[sizeof(struct lance_interface)+8];
19448 -#endif
19450 -#ifndef INCLUDE_LANCE
19451 -/* DMA defines and helper routines */
19453 -/* DMA controller registers */
19454 -#define DMA1_CMD_REG 0x08 /* command register (w) */
19455 -#define DMA1_STAT_REG 0x08 /* status register (r) */
19456 -#define DMA1_REQ_REG 0x09 /* request register (w) */
19457 -#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
19458 -#define DMA1_MODE_REG 0x0B /* mode register (w) */
19459 -#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
19460 -#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
19461 -#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
19462 -#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
19463 -#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
19465 -#define DMA2_CMD_REG 0xD0 /* command register (w) */
19466 -#define DMA2_STAT_REG 0xD0 /* status register (r) */
19467 -#define DMA2_REQ_REG 0xD2 /* request register (w) */
19468 -#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
19469 -#define DMA2_MODE_REG 0xD6 /* mode register (w) */
19470 -#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
19471 -#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
19472 -#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
19473 -#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
19474 -#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
19477 -#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
19478 -#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
19479 -#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
19481 -/* enable/disable a specific DMA channel */
19482 -static void enable_dma(unsigned int dmanr)
19484 - if (dmanr <= 3)
19485 - outb_p(dmanr, DMA1_MASK_REG);
19486 - else
19487 - outb_p(dmanr & 3, DMA2_MASK_REG);
19490 -static void disable_dma(unsigned int dmanr)
19492 - if (dmanr <= 3)
19493 - outb_p(dmanr | 4, DMA1_MASK_REG);
19494 - else
19495 - outb_p((dmanr & 3) | 4, DMA2_MASK_REG);
19498 -/* set mode (above) for a specific DMA channel */
19499 -static void set_dma_mode(unsigned int dmanr, char mode)
19501 - if (dmanr <= 3)
19502 - outb_p(mode | dmanr, DMA1_MODE_REG);
19503 - else
19504 - outb_p(mode | (dmanr&3), DMA2_MODE_REG);
19506 -#endif /* !INCLUDE_LANCE */
19508 -/**************************************************************************
19509 -RESET - Reset adapter
19510 -***************************************************************************/
19511 -static void lance_reset(struct nic *nic)
19513 - int i;
19514 - Address l;
19516 - /* Reset the LANCE */
19517 - (void)inw(ioaddr+LANCE_RESET);
19518 - /* Un-Reset the LANCE, needed only for the NE2100 */
19519 - if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
19520 - outw(0, ioaddr+LANCE_RESET);
19521 - if (chip_table[lance_version].flags & LANCE_ENABLE_AUTOSELECT)
19523 - /* This is 79C960 specific; Turn on auto-select of media
19524 - (AUI, BNC). */
19525 - outw(0x2, ioaddr+LANCE_ADDR);
19526 - /* Don't touch 10base2 power bit. */
19527 - outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF);
19529 - /* HomePNA cards need to explicitly pick the phoneline interface.
19530 - * Some of these cards have ethernet interfaces as well, this
19531 - * code might require some modification for those.
19532 - */
19533 - if (chip_table[lance_version].flags & LANCE_SELECT_PHONELINE) {
19534 - short media, check ;
19535 - /* this is specific to HomePNA cards... */
19536 - outw(49, ioaddr+0x12) ;
19537 - media = inw(ioaddr+0x16) ;
19538 -#ifdef DEBUG
19539 - printf("media was %d\n", media) ;
19540 -#endif
19541 - media &= ~3 ;
19542 - media |= 1 ;
19543 -#ifdef DEBUG
19544 - printf("media changed to %d\n", media) ;
19545 -#endif
19546 - media &= ~3 ;
19547 - media |= 1 ;
19548 - outw(49, ioaddr+0x12) ;
19549 - outw(media, ioaddr+0x16) ;
19550 - outw(49, ioaddr+0x12) ;
19551 - check = inw(ioaddr+0x16) ;
19552 -#ifdef DEBUG
19553 - printf("check %s, media was set properly\n",
19554 - check == media ? "passed" : "FAILED" ) ;
19555 -#endif
19558 - /* Re-initialise the LANCE, and start it when done. */
19559 - /* Set station address */
19560 - for (i = 0; i < ETH_ALEN; ++i)
19561 - lp->init_block.phys_addr[i] = nic->node_addr[i];
19562 - /* Preset the receive ring headers */
19563 - for (i=0; i<RX_RING_SIZE; i++) {
19564 - lp->rx_ring[i].buf_length = -ETH_FRAME_LEN-4;
19565 - /* OWN */
19566 - lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
19567 - /* we set the top byte as the very last thing */
19568 - lp->rx_ring[i].u.addr[3] = 0x80;
19570 - lp->rx_idx = 0;
19571 - lp->init_block.mode = 0x0; /* enable Rx and Tx */
19572 - l = (Address)virt_to_bus(&lp->init_block);
19573 - outw(0x1, ioaddr+LANCE_ADDR);
19574 - (void)inw(ioaddr+LANCE_ADDR);
19575 - outw((short)l, ioaddr+LANCE_DATA);
19576 - outw(0x2, ioaddr+LANCE_ADDR);
19577 - (void)inw(ioaddr+LANCE_ADDR);
19578 - outw((short)(l >> 16), ioaddr+LANCE_DATA);
19579 - outw(0x4, ioaddr+LANCE_ADDR);
19580 - (void)inw(ioaddr+LANCE_ADDR);
19581 - outw(0x915, ioaddr+LANCE_DATA);
19582 - outw(0x0, ioaddr+LANCE_ADDR);
19583 - (void)inw(ioaddr+LANCE_ADDR);
19584 - outw(0x4, ioaddr+LANCE_DATA); /* stop */
19585 - outw(0x1, ioaddr+LANCE_DATA); /* init */
19586 - for (i = 10000; i > 0; --i)
19587 - if (inw(ioaddr+LANCE_DATA) & 0x100)
19588 - break;
19589 -#ifdef DEBUG
19590 - if (i <= 0)
19591 - printf("Init timed out\n");
19592 -#endif
19593 - /* Apparently clearing the InitDone bit here triggers a bug
19594 - in the '974. (Mark Stockton) */
19595 - outw(0x2, ioaddr+LANCE_DATA); /* start */
19598 -/**************************************************************************
19599 -POLL - Wait for a frame
19600 -***************************************************************************/
19601 -static int lance_poll(struct nic *nic)
19603 - int status;
19605 - status = lp->rx_ring[lp->rx_idx].u.base >> 24;
19606 - if (status & 0x80)
19607 - return (0);
19608 -#ifdef DEBUG
19609 - printf("LANCE packet received rx_ring.u.base %X mcnt %hX csr0 %hX\n",
19610 - lp->rx_ring[lp->rx_idx].u.base, lp->rx_ring[lp->rx_idx].msg_length,
19611 - inw(ioaddr+LANCE_DATA));
19612 -#endif
19613 - if (status == 0x3)
19614 - memcpy(nic->packet, lp->rbuf[lp->rx_idx], nic->packetlen = lp->rx_ring[lp->rx_idx].msg_length);
19615 - /* Andrew Boyd of QNX reports that some revs of the 79C765
19616 - clear the buffer length */
19617 - lp->rx_ring[lp->rx_idx].buf_length = -ETH_FRAME_LEN-4;
19618 - lp->rx_ring[lp->rx_idx].u.addr[3] |= 0x80; /* prime for next receive */
19620 - /* I'm not sure if the following is still ok with multiple Rx buffers, but it works */
19621 - outw(0x0, ioaddr+LANCE_ADDR);
19622 - (void)inw(ioaddr+LANCE_ADDR);
19623 - outw(0x500, ioaddr+LANCE_DATA); /* clear receive + InitDone */
19625 - /* Switch to the next Rx ring buffer */
19626 - lp->rx_idx = (lp->rx_idx + 1) & RX_RING_MOD_MASK;
19628 - return (status == 0x3);
19631 -/**************************************************************************
19632 -TRANSMIT - Transmit a frame
19633 -***************************************************************************/
19634 -static void lance_transmit(
19635 - struct nic *nic,
19636 - const char *d, /* Destination */
19637 - unsigned int t, /* Type */
19638 - unsigned int s, /* size */
19639 - const char *p) /* Packet */
19641 - unsigned long time;
19643 - /* copy the packet to ring buffer */
19644 - memcpy(lp->tbuf, d, ETH_ALEN); /* dst */
19645 - memcpy(&lp->tbuf[ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */
19646 - lp->tbuf[ETH_ALEN+ETH_ALEN] = t >> 8; /* type */
19647 - lp->tbuf[ETH_ALEN+ETH_ALEN+1] = t; /* type */
19648 - memcpy(&lp->tbuf[ETH_HLEN], p, s);
19649 - s += ETH_HLEN;
19650 - if (chip_table[chip_version].flags & LANCE_MUST_PAD)
19651 - while (s < ETH_ZLEN) /* pad to min length */
19652 - lp->tbuf[s++] = 0;
19653 - lp->tx_ring.buf_length = -s;
19654 - lp->tx_ring.misc = 0x0;
19655 - /* OWN, STP, ENP */
19656 - lp->tx_ring.u.base = virt_to_bus(lp->tbuf) & 0xffffff;
19657 - /* we set the top byte as the very last thing */
19658 - lp->tx_ring.u.addr[3] = 0x83;
19659 - /* Trigger an immediate send poll */
19660 - outw(0x0, ioaddr+LANCE_ADDR);
19661 - (void)inw(ioaddr+LANCE_ADDR); /* as in the datasheets... */
19662 - /* Klaus Espenlaub: the value below was 0x48, but that enabled the
19663 - * interrupt line, causing a hang if for some reasone the interrupt
19664 - * controller had the LANCE interrupt enabled. I have no idea why
19665 - * nobody ran into this before... */
19666 - outw(0x08, ioaddr+LANCE_DATA);
19667 - /* wait for transmit complete */
19668 - time = currticks() + TICKS_PER_SEC; /* wait one second */
19669 - while (currticks() < time && (lp->tx_ring.u.base & 0x80000000) != 0)
19671 - if ((lp->tx_ring.u.base & 0x80000000) != 0)
19672 - printf("LANCE timed out on transmit\n");
19673 - (void)inw(ioaddr+LANCE_ADDR);
19674 - outw(0x200, ioaddr+LANCE_DATA); /* clear transmit + InitDone */
19675 -#ifdef DEBUG
19676 - printf("tx_ring.u.base %X tx_ring.buf_length %hX tx_ring.misc %hX csr0 %hX\n",
19677 - lp->tx_ring.u.base, lp->tx_ring.buf_length, lp->tx_ring.misc,
19678 - inw(ioaddr+LANCE_DATA));
19679 -#endif
19682 -static void lance_disable(struct nic *nic)
19684 - (void)inw(ioaddr+LANCE_RESET);
19685 - if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
19686 - outw(0, ioaddr+LANCE_RESET);
19688 - outw(0, ioaddr+LANCE_ADDR);
19689 - outw(0x0004, ioaddr+LANCE_DATA); /* stop the LANCE */
19691 -#ifndef INCLUDE_LANCE
19692 - disable_dma(dma);
19693 -#endif
19696 -#ifdef INCLUDE_LANCE
19697 -static int lance_probe1(struct nic *nic, struct pci_device *pci)
19698 -#else
19699 -static int lance_probe1(struct nic *nic)
19700 -#endif
19702 - int reset_val ;
19703 - unsigned int i;
19704 - Address l;
19705 - short dma_channels;
19706 -#ifndef INCLUDE_LANCE
19707 - static const char dmas[] = { 5, 6, 7, 3 };
19708 -#endif
19710 - reset_val = inw(ioaddr+LANCE_RESET);
19711 - outw(reset_val, ioaddr+LANCE_RESET);
19712 -#if 1 /* Klaus Espenlaub -- was #ifdef INCLUDE_NE2100*/
19713 - outw(0x0, ioaddr+LANCE_ADDR); /* Switch to window 0 */
19714 - if (inw(ioaddr+LANCE_DATA) != 0x4)
19715 - return (-1);
19716 -#endif
19717 - outw(88, ioaddr+LANCE_ADDR); /* Get the version of the chip */
19718 - if (inw(ioaddr+LANCE_ADDR) != 88)
19719 - lance_version = 0;
19720 - else
19722 - chip_version = inw(ioaddr+LANCE_DATA);
19723 - outw(89, ioaddr+LANCE_ADDR);
19724 - chip_version |= inw(ioaddr+LANCE_DATA) << 16;
19725 - if ((chip_version & 0xfff) != 0x3)
19726 - return (-1);
19727 - chip_version = (chip_version >> 12) & 0xffff;
19728 - for (lance_version = 1; chip_table[lance_version].id_number != 0; ++lance_version)
19729 - if (chip_table[lance_version].id_number == chip_version)
19730 - break;
19732 - /* make sure data structure is 8-byte aligned */
19733 - l = ((Address)lance + 7) & ~7;
19734 - lp = (struct lance_interface *)l;
19735 - lp->init_block.mode = 0x3; /* disable Rx and Tx */
19736 - lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
19737 - /* using multiple Rx buffer and a single Tx buffer */
19738 - lp->init_block.rx_ring = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
19739 - lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff;
19740 - l = virt_to_bus(&lp->init_block);
19741 - outw(0x1, ioaddr+LANCE_ADDR);
19742 - (void)inw(ioaddr+LANCE_ADDR);
19743 - outw((unsigned short)l, ioaddr+LANCE_DATA);
19744 - outw(0x2, ioaddr+LANCE_ADDR);
19745 - (void)inw(ioaddr+LANCE_ADDR);
19746 - outw((unsigned short)(l >> 16), ioaddr+LANCE_DATA);
19747 - outw(0x4, ioaddr+LANCE_ADDR);
19748 - (void)inw(ioaddr+LANCE_ADDR);
19749 - outw(0x915, ioaddr+LANCE_DATA);
19750 - outw(0x0, ioaddr+LANCE_ADDR);
19751 - (void)inw(ioaddr+LANCE_ADDR);
19752 - /* Get station address */
19753 - for (i = 0; i < ETH_ALEN; ++i) {
19754 - nic->node_addr[i] = inb(ioaddr+LANCE_ETH_ADDR+i);
19756 -#ifndef INCLUDE_LANCE
19757 - /* now probe for DMA channel */
19758 - dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) |
19759 - (inb(DMA2_STAT_REG) & 0xf0);
19760 - /* need to fix when PCI provides DMA info */
19761 - for (i = 0; i < (sizeof(dmas)/sizeof(dmas[0])); ++i)
19763 - int j;
19765 - dma = dmas[i];
19766 - /* Don't enable a permanently busy DMA channel,
19767 - or the machine will hang */
19768 - if (dma_channels & (1 << dma))
19769 - continue;
19770 - outw(0x7f04, ioaddr+LANCE_DATA); /* clear memory error bits */
19771 - set_dma_mode(dma, DMA_MODE_CASCADE);
19772 - enable_dma(dma);
19773 - outw(0x1, ioaddr+LANCE_DATA); /* init */
19774 - for (j = 100; j > 0; --j)
19775 - if (inw(ioaddr+LANCE_DATA) & 0x900)
19776 - break;
19777 - if (inw(ioaddr+LANCE_DATA) & 0x100)
19778 - break;
19779 - else
19780 - disable_dma(dma);
19782 - if (i >= (sizeof(dmas)/sizeof(dmas[0])))
19783 - dma = 0;
19784 - printf("\n%s base %#X, DMA %d, addr %!\n",
19785 - chip_table[lance_version].name, ioaddr, dma, nic->node_addr);
19786 -#else
19787 - printf(" %s base %#hX, addr %!\n", chip_table[lance_version].name, ioaddr, nic->node_addr);
19788 -#endif
19789 - if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
19790 - /* Turn on auto-select of media (10baseT or BNC) so that the
19791 - * user watch the LEDs. */
19792 - outw(0x0002, ioaddr+LANCE_ADDR);
19793 - /* Don't touch 10base2 power bit. */
19794 - outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF);
19796 - return (lance_version);
19799 -/**************************************************************************
19800 -PROBE - Look for an adapter, this routine's visible to the outside
19801 -***************************************************************************/
19803 -#ifdef INCLUDE_LANCE
19804 -struct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *pci)
19805 -#endif
19806 -#ifdef INCLUDE_NE2100
19807 -struct nic *ne2100_probe(struct nic *nic, unsigned short *probe_addrs)
19808 -#endif
19809 -#ifdef INCLUDE_NI6510
19810 -struct nic *ni6510_probe(struct nic *nic, unsigned short *probe_addrs)
19811 -#endif
19813 - unsigned short *p;
19814 -#ifndef INCLUDE_LANCE
19815 - static unsigned short io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 };
19816 -#endif
19818 - /* if probe_addrs is 0, then routine can use a hardwired default */
19819 - if (probe_addrs == 0) {
19820 -#ifdef INCLUDE_LANCE
19821 - return 0;
19822 -#else
19823 - probe_addrs = io_addrs;
19824 -#endif
19826 - for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
19828 - char offset15, offset14 = inb(ioaddr + 14);
19829 - unsigned short pci_cmd;
19831 -#ifdef INCLUDE_NE2100
19832 - if ((offset14 == 0x52 || offset14 == 0x57) &&
19833 - ((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
19834 - if (lance_probe1(nic) >= 0)
19835 - break;
19836 -#endif
19837 -#ifdef INCLUDE_NI6510
19838 - if ((offset14 == 0x00 || offset14 == 0x52) &&
19839 - ((offset15 = inb(ioaddr + 15)) == 0x55 || offset15 == 0x44))
19840 - if (lance_probe1(nic) >= 0)
19841 - break;
19842 -#endif
19843 -#ifdef INCLUDE_LANCE
19844 - adjust_pci_device(pci);
19845 - if (lance_probe1(nic, pci) >= 0)
19846 - break;
19847 -#endif
19849 - /* if board found */
19850 - if (ioaddr != 0)
19852 - /* point to NIC specific routines */
19853 - lance_reset(nic);
19854 - nic->reset = lance_reset;
19855 - nic->poll = lance_poll;
19856 - nic->transmit = lance_transmit;
19857 - nic->disable = lance_disable;
19858 - return nic;
19861 - /* no board found */
19862 - return 0;
19864 Index: b/netboot/latch.h
19865 ===================================================================
19866 --- /dev/null
19867 +++ b/netboot/latch.h
19868 @@ -0,0 +1,10 @@
19869 +#ifndef LATCH_H
19870 +#define LATCH_H
19872 +#define TICKS_PER_SEC 18
19874 +/* For different calibrators of the TSC move the declaration of
19875 + * sleep_latch and the definitions of it's length here...
19876 + */
19878 +#endif /* LATCH_H */
19879 Index: b/netboot/linux-asm-io.h
19880 ===================================================================
19881 --- a/netboot/linux-asm-io.h
19882 +++ /dev/null
19883 @@ -1,187 +0,0 @@
19884 -#ifndef _ASM_IO_H
19885 -#define _ASM_IO_H
19888 - * This file contains the definitions for the x86 IO instructions
19889 - * inb/inw/inl/outb/outw/outl and the "string versions" of the same
19890 - * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
19891 - * versions of the single-IO instructions (inb_p/inw_p/..).
19893 - * This file is not meant to be obfuscating: it's just complicated
19894 - * to (a) handle it all in a way that makes gcc able to optimize it
19895 - * as well as possible and (b) trying to avoid writing the same thing
19896 - * over and over again with slight variations and possibly making a
19897 - * mistake somewhere.
19898 - */
19901 - * Thanks to James van Artsdalen for a better timing-fix than
19902 - * the two short jumps: using outb's to a nonexistent port seems
19903 - * to guarantee better timings even on fast machines.
19905 - * On the other hand, I'd like to be sure of a non-existent port:
19906 - * I feel a bit unsafe about using 0x80 (should be safe, though)
19908 - * Linus
19909 - */
19911 -#ifdef SLOW_IO_BY_JUMPING
19912 -#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
19913 -#else
19914 -#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
19915 -#endif
19917 -#ifdef REALLY_SLOW_IO
19918 -#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
19919 -#else
19920 -#define SLOW_DOWN_IO __SLOW_DOWN_IO
19921 -#endif
19924 - * readX/writeX() are used to access memory mapped devices. On some
19925 - * architectures the memory mapped IO stuff needs to be accessed
19926 - * differently. On the x86 architecture, we just read/write the
19927 - * memory location directly.
19928 - */
19929 -#define readb(addr) (*(volatile unsigned char *) (addr))
19930 -#define readw(addr) (*(volatile unsigned short *) (addr))
19931 -#define readl(addr) (*(volatile unsigned int *) (addr))
19933 -#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
19934 -#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
19935 -#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
19937 -#define memset_io(a,b,c) memset((void *)(a),(b),(c))
19938 -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
19939 -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
19942 - * Again, i386 does not require mem IO specific function.
19943 - */
19945 -#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d))
19948 - * Talk about misusing macros..
19949 - */
19951 -#define __OUT1(s,x) \
19952 -extern void __out##s(unsigned x value, unsigned short port); \
19953 -extern inline void __out##s(unsigned x value, unsigned short port) {
19955 -#define __OUT2(s,s1,s2) \
19956 -__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
19958 -#define __OUT(s,s1,x) \
19959 -__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
19960 -__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
19961 -__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
19962 -__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
19964 -#define __IN1(s,x) \
19965 -extern unsigned x __in##s(unsigned short port); \
19966 -extern inline unsigned x __in##s(unsigned short port) { unsigned x _v;
19968 -#define __IN2(s,s1,s2) \
19969 -__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
19971 -#define __IN(s,s1,x,i...) \
19972 -__IN1(s,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
19973 -__IN1(s##c,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
19974 -__IN1(s##_p,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
19975 -__IN1(s##c_p,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
19977 -#define __INS(s) \
19978 -extern void ins##s(unsigned short port, void * addr, unsigned long count); \
19979 -extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
19980 -{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
19981 -: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
19983 -#define __OUTS(s) \
19984 -extern void outs##s(unsigned short port, const void * addr, unsigned long count); \
19985 -extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
19986 -{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
19987 -: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
19989 -__IN(b,"", char)
19990 -__IN(w,"",short)
19991 -__IN(l,"", long)
19993 -__OUT(b,"b",char)
19994 -__OUT(w,"w",short)
19995 -__OUT(l,,int)
19997 -__INS(b)
19998 -__INS(w)
19999 -__INS(l)
20001 -__OUTS(b)
20002 -__OUTS(w)
20003 -__OUTS(l)
20006 - * Note that due to the way __builtin_constant_p() works, you
20007 - * - can't use it inside a inline function (it will never be true)
20008 - * - you don't have to worry about side effects within the __builtin..
20009 - */
20010 -#define outb(val,port) \
20011 -((__builtin_constant_p((port)) && (port) < 256) ? \
20012 - __outbc((val),(port)) : \
20013 - __outb((val),(port)))
20015 -#define inb(port) \
20016 -((__builtin_constant_p((port)) && (port) < 256) ? \
20017 - __inbc(port) : \
20018 - __inb(port))
20020 -#define outb_p(val,port) \
20021 -((__builtin_constant_p((port)) && (port) < 256) ? \
20022 - __outbc_p((val),(port)) : \
20023 - __outb_p((val),(port)))
20025 -#define inb_p(port) \
20026 -((__builtin_constant_p((port)) && (port) < 256) ? \
20027 - __inbc_p(port) : \
20028 - __inb_p(port))
20030 -#define outw(val,port) \
20031 -((__builtin_constant_p((port)) && (port) < 256) ? \
20032 - __outwc((val),(port)) : \
20033 - __outw((val),(port)))
20035 -#define inw(port) \
20036 -((__builtin_constant_p((port)) && (port) < 256) ? \
20037 - __inwc(port) : \
20038 - __inw(port))
20040 -#define outw_p(val,port) \
20041 -((__builtin_constant_p((port)) && (port) < 256) ? \
20042 - __outwc_p((val),(port)) : \
20043 - __outw_p((val),(port)))
20045 -#define inw_p(port) \
20046 -((__builtin_constant_p((port)) && (port) < 256) ? \
20047 - __inwc_p(port) : \
20048 - __inw_p(port))
20050 -#define outl(val,port) \
20051 -((__builtin_constant_p((port)) && (port) < 256) ? \
20052 - __outlc((val),(port)) : \
20053 - __outl((val),(port)))
20055 -#define inl(port) \
20056 -((__builtin_constant_p((port)) && (port) < 256) ? \
20057 - __inlc(port) : \
20058 - __inl(port))
20060 -#define outl_p(val,port) \
20061 -((__builtin_constant_p((port)) && (port) < 256) ? \
20062 - __outlc_p((val),(port)) : \
20063 - __outl_p((val),(port)))
20065 -#define inl_p(port) \
20066 -((__builtin_constant_p((port)) && (port) < 256) ? \
20067 - __inlc_p(port) : \
20068 - __inl_p(port))
20070 -#endif
20071 Index: b/netboot/linux-asm-string.h
20072 ===================================================================
20073 --- a/netboot/linux-asm-string.h
20074 +++ /dev/null
20075 @@ -1,291 +0,0 @@
20077 - * Taken from Linux /usr/include/asm/string.h
20078 - * All except memcpy, memmove, memset and memcmp removed.
20079 - */
20081 -#ifndef _I386_STRING_H_
20082 -#define _I386_STRING_H_
20085 - * This string-include defines all string functions as inline
20086 - * functions. Use gcc. It also assumes ds=es=data space, this should be
20087 - * normal. Most of the string-functions are rather heavily hand-optimized,
20088 - * see especially strtok,strstr,str[c]spn. They should work, but are not
20089 - * very easy to understand. Everything is done entirely within the register
20090 - * set, making the functions fast and clean. String instructions have been
20091 - * used through-out, making for "slightly" unclear code :-)
20093 - * NO Copyright (C) 1991, 1992 Linus Torvalds,
20094 - * consider these trivial functions to be PD.
20095 - */
20097 -typedef int size_t;
20099 -extern void *__memcpy(void * to, const void * from, size_t n);
20100 -extern void *__constant_memcpy(void * to, const void * from, size_t n);
20101 -extern void *memmove(void * dest,const void * src, size_t n);
20102 -extern void *__memset_generic(void * s, char c,size_t count);
20103 -extern void *__constant_c_memset(void * s, unsigned long c, size_t count);
20104 -extern void *__constant_c_and_count_memset(void * s, unsigned long pattern, size_t count);
20107 -extern inline void * __memcpy(void * to, const void * from, size_t n)
20109 -int d0, d1, d2;
20110 -__asm__ __volatile__(
20111 - "cld\n\t"
20112 - "rep ; movsl\n\t"
20113 - "testb $2,%b4\n\t"
20114 - "je 1f\n\t"
20115 - "movsw\n"
20116 - "1:\ttestb $1,%b4\n\t"
20117 - "je 2f\n\t"
20118 - "movsb\n"
20119 - "2:"
20120 - : "=&c" (d0), "=&D" (d1), "=&S" (d2)
20121 - :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
20122 - : "memory");
20123 -return (to);
20127 - * This looks horribly ugly, but the compiler can optimize it totally,
20128 - * as the count is constant.
20129 - */
20130 -extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
20132 - switch (n) {
20133 - case 0:
20134 - return to;
20135 - case 1:
20136 - *(unsigned char *)to = *(const unsigned char *)from;
20137 - return to;
20138 - case 2:
20139 - *(unsigned short *)to = *(const unsigned short *)from;
20140 - return to;
20141 - case 3:
20142 - *(unsigned short *)to = *(const unsigned short *)from;
20143 - *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
20144 - return to;
20145 - case 4:
20146 - *(unsigned long *)to = *(const unsigned long *)from;
20147 - return to;
20148 - case 6: /* for Ethernet addresses */
20149 - *(unsigned long *)to = *(const unsigned long *)from;
20150 - *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
20151 - return to;
20152 - case 8:
20153 - *(unsigned long *)to = *(const unsigned long *)from;
20154 - *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
20155 - return to;
20156 - case 12:
20157 - *(unsigned long *)to = *(const unsigned long *)from;
20158 - *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
20159 - *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
20160 - return to;
20161 - case 16:
20162 - *(unsigned long *)to = *(const unsigned long *)from;
20163 - *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
20164 - *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
20165 - *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
20166 - return to;
20167 - case 20:
20168 - *(unsigned long *)to = *(const unsigned long *)from;
20169 - *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
20170 - *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
20171 - *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
20172 - *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
20173 - return to;
20175 -#define COMMON(x) \
20176 -__asm__ __volatile__( \
20177 - "cld\n\t" \
20178 - "rep ; movsl" \
20179 - x \
20180 - : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
20181 - : "0" (n/4),"1" ((long) to),"2" ((long) from) \
20182 - : "memory");
20184 - int d0, d1, d2;
20185 - switch (n % 4) {
20186 - case 0: COMMON(""); return to;
20187 - case 1: COMMON("\n\tmovsb"); return to;
20188 - case 2: COMMON("\n\tmovsw"); return to;
20189 - default: COMMON("\n\tmovsw\n\tmovsb"); return to;
20193 -#undef COMMON
20196 -#define __HAVE_ARCH_MEMCPY
20197 -#define memcpy(t, f, n) \
20198 -(__builtin_constant_p(n) ? \
20199 - __constant_memcpy((t),(f),(n)) : \
20200 - __memcpy((t),(f),(n)))
20202 -#define __HAVE_ARCH_MEMMOVE
20203 -extern inline void * memmove(void * dest,const void * src, size_t n)
20205 -int d0, d1, d2;
20206 -if (dest<src)
20207 -__asm__ __volatile__(
20208 - "cld\n\t"
20209 - "rep\n\t"
20210 - "movsb"
20211 - : "=&c" (d0), "=&S" (d1), "=&D" (d2)
20212 - :"0" (n),"1" (src),"2" (dest)
20213 - : "memory");
20214 -else
20215 -__asm__ __volatile__(
20216 - "std\n\t"
20217 - "rep\n\t"
20218 - "movsb\n\t"
20219 - "cld"
20220 - : "=&c" (d0), "=&S" (d1), "=&D" (d2)
20221 - :"0" (n),
20222 - "1" (n-1+(const char *)src),
20223 - "2" (n-1+(char *)dest)
20224 - :"memory");
20225 -return dest;
20228 -#define memcmp __builtin_memcmp
20230 -extern inline void * __memset_generic(void * s, char c,size_t count)
20232 -int d0, d1;
20233 -__asm__ __volatile__(
20234 - "cld\n\t"
20235 - "rep\n\t"
20236 - "stosb"
20237 - : "=&c" (d0), "=&D" (d1)
20238 - :"a" (c),"1" (s),"0" (count)
20239 - :"memory");
20240 -return s;
20243 -/* we might want to write optimized versions of these later */
20244 -#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
20247 - * memset(x,0,y) is a reasonably common thing to do, so we want to fill
20248 - * things 32 bits at a time even when we don't know the size of the
20249 - * area at compile-time..
20250 - */
20251 -extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
20253 -int d0, d1;
20254 -__asm__ __volatile__(
20255 - "cld\n\t"
20256 - "rep ; stosl\n\t"
20257 - "testb $2,%b3\n\t"
20258 - "je 1f\n\t"
20259 - "stosw\n"
20260 - "1:\ttestb $1,%b3\n\t"
20261 - "je 2f\n\t"
20262 - "stosb\n"
20263 - "2:"
20264 - : "=&c" (d0), "=&D" (d1)
20265 - :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
20266 - :"memory");
20267 -return (s);
20271 - * This looks horribly ugly, but the compiler can optimize it totally,
20272 - * as we by now know that both pattern and count is constant..
20273 - */
20274 -extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
20276 - switch (count) {
20277 - case 0:
20278 - return s;
20279 - case 1:
20280 - *(unsigned char *)s = pattern;
20281 - return s;
20282 - case 2:
20283 - *(unsigned short *)s = pattern;
20284 - return s;
20285 - case 3:
20286 - *(unsigned short *)s = pattern;
20287 - *(2+(unsigned char *)s) = pattern;
20288 - return s;
20289 - case 4:
20290 - *(unsigned long *)s = pattern;
20291 - return s;
20293 -#define COMMON(x) \
20294 -__asm__ __volatile__("cld\n\t" \
20295 - "rep ; stosl" \
20296 - x \
20297 - : "=&c" (d0), "=&D" (d1) \
20298 - : "a" (pattern),"0" (count/4),"1" ((long) s) \
20299 - : "memory")
20301 - int d0, d1;
20302 - switch (count % 4) {
20303 - case 0: COMMON(""); return s;
20304 - case 1: COMMON("\n\tstosb"); return s;
20305 - case 2: COMMON("\n\tstosw"); return s;
20306 - default: COMMON("\n\tstosw\n\tstosb"); return s;
20310 -#undef COMMON
20313 -#define __constant_c_x_memset(s, c, count) \
20314 -(__builtin_constant_p(count) ? \
20315 - __constant_c_and_count_memset((s),(c),(count)) : \
20316 - __constant_c_memset((s),(c),(count)))
20318 -#define __memset(s, c, count) \
20319 -(__builtin_constant_p(count) ? \
20320 - __constant_count_memset((s),(c),(count)) : \
20321 - __memset_generic((s),(c),(count)))
20323 -#define __HAVE_ARCH_MEMSET
20324 -#define memset(s, c, count) \
20325 -(__builtin_constant_p(c) ? \
20326 - __constant_c_x_memset((s),(c),(count)) : \
20327 - __memset((s),(c),(count)))
20329 -#define __HAVE_ARCH_STRNCMP
20330 -static inline int strncmp(const char * cs,const char * ct,size_t count)
20332 -register int __res;
20333 -int d0, d1, d2;
20334 -__asm__ __volatile__(
20335 - "1:\tdecl %3\n\t"
20336 - "js 2f\n\t"
20337 - "lodsb\n\t"
20338 - "scasb\n\t"
20339 - "jne 3f\n\t"
20340 - "testb %%al,%%al\n\t"
20341 - "jne 1b\n"
20342 - "2:\txorl %%eax,%%eax\n\t"
20343 - "jmp 4f\n"
20344 - "3:\tsbbl %%eax,%%eax\n\t"
20345 - "orb $1,%%al\n"
20346 - "4:"
20347 - :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
20348 - :"1" (cs),"2" (ct),"3" (count));
20349 -return __res;
20352 -#define __HAVE_ARCH_STRLEN
20353 -static inline size_t strlen(const char * s)
20355 -int d0;
20356 -register int __res;
20357 -__asm__ __volatile__(
20358 - "repne\n\t"
20359 - "scasb\n\t"
20360 - "notl %0\n\t"
20361 - "decl %0"
20362 - :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
20363 -return __res;
20366 -#endif
20367 Index: b/netboot/little_bswap.h
20368 ===================================================================
20369 --- /dev/null
20370 +++ b/netboot/little_bswap.h
20371 @@ -0,0 +1,17 @@
20372 +#ifndef ETHERBOOT_LITTLE_BSWAP_H
20373 +#define ETHERBOOT_LITTLE_BSWAP_H
20375 +#define ntohl(x) __bswap_32(x)
20376 +#define htonl(x) __bswap_32(x)
20377 +#define ntohs(x) __bswap_16(x)
20378 +#define htons(x) __bswap_16(x)
20379 +#define cpu_to_le32(x) (x)
20380 +#define cpu_to_le16(x) (x)
20381 +#define cpu_to_be32(x) __bswap_32(x)
20382 +#define cpu_to_be16(x) __bswap_16(x)
20383 +#define le32_to_cpu(x) (x)
20384 +#define le16_to_cpu(x) (x)
20385 +#define be32_to_cpu(x) __bswap_32(x)
20386 +#define be16_to_cpu(x) __bswap_16(x)
20388 +#endif /* ETHERBOOT_LITTLE_BSWAP_H */
20389 Index: b/netboot/mii.h
20390 ===================================================================
20391 --- /dev/null
20392 +++ b/netboot/mii.h
20393 @@ -0,0 +1,105 @@
20395 + * linux/mii.h: definitions for MII-compatible transceivers
20396 + * Originally drivers/net/sunhme.h.
20398 + * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
20400 + * Copied Form Linux 2.4.25 an unneeded items removed by:
20401 + * Timothy Legge (timlegge at etherboot dot org)
20403 + * 03/26/2004
20404 + */
20406 +/* Generic MII registers. */
20408 +#define MII_BMCR 0x00 /* Basic mode control register */
20409 +#define MII_BMSR 0x01 /* Basic mode status register */
20410 +#define MII_PHYSID1 0x02 /* PHYS ID 1 */
20411 +#define MII_PHYSID2 0x03 /* PHYS ID 2 */
20412 +#define MII_ADVERTISE 0x04 /* Advertisement control reg */
20413 +#define MII_LPA 0x05 /* Link partner ability reg */
20414 +#define MII_EXPANSION 0x06 /* Expansion register */
20415 +#define MII_DCOUNTER 0x12 /* Disconnect counter */
20416 +#define MII_FCSCOUNTER 0x13 /* False carrier counter */
20417 +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
20418 +#define MII_RERRCOUNTER 0x15 /* Receive error counter */
20419 +#define MII_SREVISION 0x16 /* Silicon revision */
20420 +#define MII_RESV1 0x17 /* Reserved... */
20421 +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
20422 +#define MII_PHYADDR 0x19 /* PHY address */
20423 +#define MII_RESV2 0x1a /* Reserved... */
20424 +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
20425 +#define MII_NCONFIG 0x1c /* Network interface config */
20427 +/* Basic mode control register. */
20428 +#define BMCR_RESV 0x007f /* Unused... */
20429 +#define BMCR_CTST 0x0080 /* Collision test */
20430 +#define BMCR_FULLDPLX 0x0100 /* Full duplex */
20431 +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
20432 +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
20433 +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
20434 +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
20435 +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
20436 +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
20437 +#define BMCR_RESET 0x8000 /* Reset the DP83840 */
20439 +/* Basic mode status register. */
20440 +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
20441 +#define BMSR_JCD 0x0002 /* Jabber detected */
20442 +#define BMSR_LSTATUS 0x0004 /* Link status */
20443 +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
20444 +#define BMSR_RFAULT 0x0010 /* Remote fault detected */
20445 +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
20446 +#define BMSR_RESV 0x07c0 /* Unused... */
20447 +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
20448 +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
20449 +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
20450 +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
20451 +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
20453 +/* Advertisement control register. */
20454 +#define ADVERTISE_SLCT 0x001f /* Selector bits */
20455 +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
20456 +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
20457 +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
20458 +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
20459 +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
20460 +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
20461 +#define ADVERTISE_RESV 0x1c00 /* Unused... */
20462 +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
20463 +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
20464 +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
20466 +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
20467 + ADVERTISE_CSMA)
20468 +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
20469 + ADVERTISE_100HALF | ADVERTISE_100FULL)
20471 +/* Link partner ability register. */
20472 +#define LPA_SLCT 0x001f /* Same as advertise selector */
20473 +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
20474 +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
20475 +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
20476 +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
20477 +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
20478 +#define LPA_RESV 0x1c00 /* Unused... */
20479 +#define LPA_RFAULT 0x2000 /* Link partner faulted */
20480 +#define LPA_LPACK 0x4000 /* Link partner acked us */
20481 +#define LPA_NPAGE 0x8000 /* Next page bit */
20483 +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
20484 +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
20486 +/* Expansion register for auto-negotiation. */
20487 +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
20488 +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
20489 +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
20490 +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
20491 +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
20492 +#define EXPANSION_RESV 0xffe0 /* Unused... */
20494 +/* N-way test register. */
20495 +#define NWAYTEST_RESV1 0x00ff /* Unused... */
20496 +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
20497 +#define NWAYTEST_RESV2 0xfe00 /* Unused... */
20499 Index: b/netboot/misc.c
20500 ===================================================================
20501 --- a/netboot/misc.c
20502 +++ b/netboot/misc.c
20503 @@ -19,37 +19,90 @@
20505 /* Based on "src/misc.c" in etherboot-5.0.5. */
20507 -#define GRUB 1
20508 -#include <etherboot.h>
20509 +#include "grub.h"
20510 +#include "timer.h"
20512 -void
20513 -sleep (int secs)
20514 +#include "nic.h"
20516 +/**************************************************************************
20517 +RANDOM - compute a random number between 0 and 2147483647L or 2147483562?
20518 +**************************************************************************/
20519 +int32_t random(void)
20521 - unsigned long tmo = currticks () + secs;
20522 + static int32_t seed = 0;
20523 + int32_t q;
20524 + if (!seed) /* Initialize linear congruential generator */
20525 + seed = currticks() + *(int32_t *)&arptable[ARP_CLIENT].node
20526 + + ((int16_t *)arptable[ARP_CLIENT].node)[2];
20527 + /* simplified version of the LCG given in Bruce Schneier's
20528 + "Applied Cryptography" */
20529 + q = seed/53668;
20530 + if ((seed = 40014*(seed-53668*q) - 12211*q) < 0) seed += 2147483563L;
20531 + return seed;
20534 - while (currticks () < tmo)
20536 +/**************************************************************************
20537 +POLL INTERRUPTIONS
20538 +**************************************************************************/
20539 +void poll_interruptions(void)
20541 + if (checkkey() != -1 && ASCII_CHAR(getkey()) == K_INTR) {
20542 + user_abort++;
20546 -void
20547 -twiddle (void)
20548 +/**************************************************************************
20549 +SLEEP
20550 +**************************************************************************/
20551 +void sleep(int secs)
20553 - static unsigned long lastticks = 0;
20554 - static int count = 0;
20555 - static const char tiddles[]="-\\|/";
20556 - unsigned long ticks;
20557 + unsigned long tmo;
20559 - if (debug)
20561 - if ((ticks = currticks ()) == lastticks)
20562 - return;
20564 - lastticks = ticks;
20565 - grub_putchar (tiddles[(count++) & 3]);
20566 - grub_putchar ('\b');
20568 + for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; ) {
20569 + poll_interruptions();
20573 +/**************************************************************************
20574 +INTERRUPTIBLE SLEEP
20575 +**************************************************************************/
20576 +void interruptible_sleep(int secs)
20578 + printf("<sleep>\n");
20579 + return sleep(secs);
20582 +/**************************************************************************
20583 +TWIDDLE
20584 +**************************************************************************/
20585 +void twiddle(void)
20587 +#ifdef BAR_PROGRESS
20588 + static int count=0;
20589 + static const char tiddles[]="-\\|/";
20590 + static unsigned long lastticks = 0;
20591 + unsigned long ticks;
20592 +#endif
20593 +#ifdef FREEBSD_PXEEMU
20594 + extern char pxeemu_nbp_active;
20595 + if(pxeemu_nbp_active != 0)
20596 + return;
20597 +#endif
20598 +#ifdef BAR_PROGRESS
20599 + /* Limit the maximum rate at which characters are printed */
20600 + ticks = currticks();
20601 + if ((lastticks + (TICKS_PER_SEC/18)) > ticks)
20602 + return;
20603 + lastticks = ticks;
20605 + putchar(tiddles[(count++)&3]);
20606 + putchar('\b');
20607 +#else
20608 + //putchar('.');
20609 +#endif /* BAR_PROGRESS */
20613 /* Because Etherboot uses its own formats for the printf family,
20614 define separate definitions from GRUB. */
20615 /**************************************************************************
20616 @@ -264,3 +317,5 @@
20618 return ret;
20622 Index: b/netboot/natsemi.c
20623 ===================================================================
20624 --- a/netboot/natsemi.c
20625 +++ b/netboot/natsemi.c
20626 @@ -47,15 +47,15 @@
20627 /* Revision History */
20630 + 13 Dec 2003 timlegge 1.1 Enabled Multicast Support
20631 29 May 2001 mdc 1.0
20632 Initial Release. Tested with Netgear FA311 and FA312 boards
20633 -*/\f
20635 /* Includes */
20637 #include "etherboot.h"
20638 #include "nic.h"
20639 #include "pci.h"
20640 -#include "cards.h"
20642 /* defines */
20644 @@ -71,21 +71,18 @@
20646 #define NUM_RX_DESC 4 /* Number of Rx descriptor registers. */
20648 -typedef unsigned char u8;
20649 -typedef signed char s8;
20650 -typedef unsigned short u16;
20651 -typedef signed short s16;
20652 -typedef unsigned int u32;
20653 -typedef signed int s32;
20654 +typedef uint8_t u8;
20655 +typedef int8_t s8;
20656 +typedef uint16_t u16;
20657 +typedef int16_t s16;
20658 +typedef uint32_t u32;
20659 +typedef int32_t s32;
20661 /* helpful macroes if on a big_endian machine for changing byte order.
20662 not strictly needed on Intel */
20663 -#define le16_to_cpu(val) (val)
20664 -#define cpu_to_le32(val) (val)
20665 #define get_unaligned(ptr) (*(ptr))
20666 #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
20667 #define get_u16(ptr) (*(u16 *)(ptr))
20668 -#define virt_to_bus(x) ((unsigned long)x)
20669 #define virt_to_le32desc(addr) virt_to_bus(addr)
20671 enum pcistuff {
20672 @@ -161,7 +158,8 @@
20673 AcceptMulticast = 0x00200000,
20674 AcceptAllMulticast = 0x20000000,
20675 AcceptAllPhys = 0x10000000,
20676 - AcceptMyPhys = 0x08000000
20677 + AcceptMyPhys = 0x08000000,
20678 + RxFilterEnable = 0x80000000
20681 typedef struct _BufferDesc {
20682 @@ -207,17 +205,12 @@
20683 static BufferDesc txd __attribute__ ((aligned(4)));
20684 static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
20686 -#ifdef USE_LOWMEM_BUFFER
20687 -#define txb ((char *)0x10000 - TX_BUF_SIZE)
20688 -#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE)
20689 -#else
20690 static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
20691 static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] __attribute__ ((aligned(4)));
20692 -#endif
20694 /* Function Prototypes */
20696 -struct nic *natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci);
20697 +static int natsemi_probe(struct dev *dev, struct pci_device *pci);
20698 static int eeprom_read(long addr, int location);
20699 static int mdio_read(int phy_id, int location);
20700 static void natsemi_init(struct nic *nic);
20701 @@ -228,8 +221,9 @@
20702 static void natsemi_set_rx_mode(struct nic *nic);
20703 static void natsemi_check_duplex(struct nic *nic);
20704 static void natsemi_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
20705 -static int natsemi_poll(struct nic *nic);
20706 -static void natsemi_disable(struct nic *nic);
20707 +static int natsemi_poll(struct nic *nic, int retrieve);
20708 +static void natsemi_disable(struct dev *dev);
20709 +static void natsemi_irq(struct nic *nic, irq_action_t action);
20712 * Function: natsemi_probe
20713 @@ -245,24 +239,28 @@
20714 * Returns: struct nic *: pointer to NIC data structure
20717 -struct nic *
20718 -natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
20719 +static int
20720 +natsemi_probe(struct dev *dev, struct pci_device *pci)
20722 + struct nic *nic = (struct nic *)dev;
20723 int i;
20724 int prev_eedata;
20725 u32 tmp;
20727 - if (io_addrs == 0 || *io_addrs == 0)
20728 - return NULL;
20729 + if (pci->ioaddr == 0)
20730 + return 0;
20732 + adjust_pci_device(pci);
20734 /* initialize some commonly used globals */
20736 - ioaddr = *io_addrs & ~3;
20737 + nic->irqno = 0;
20738 + nic->ioaddr = pci->ioaddr & ~3;
20740 + ioaddr = pci->ioaddr & ~3;
20741 vendor = pci->vendor;
20742 dev_id = pci->dev_id;
20743 nic_name = pci->name;
20745 - adjust_pci_device(pci);
20747 /* natsemi has a non-standard PM control register
20748 * in PCI config space. Some boards apparently need
20749 @@ -317,12 +315,12 @@
20750 /* initialize device */
20751 natsemi_init(nic);
20753 - nic->reset = natsemi_init;
20754 + dev->disable = natsemi_disable;
20755 nic->poll = natsemi_poll;
20756 nic->transmit = natsemi_transmit;
20757 - nic->disable = natsemi_disable;
20758 + nic->irq = natsemi_irq;
20760 - return nic;
20761 + return 1;
20764 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
20765 @@ -452,7 +450,7 @@
20766 * Returns: void.
20768 static void
20769 -natsemi_reset(struct nic *nic)
20770 +natsemi_reset(struct nic *nic __unused)
20772 outl(ChipReset, ioaddr + ChipCmd);
20774 @@ -504,14 +502,14 @@
20777 static void
20778 -natsemi_init_txd(struct nic *nic)
20779 +natsemi_init_txd(struct nic *nic __unused)
20781 txd.link = (u32) 0;
20782 txd.cmdsts = (u32) 0;
20783 - txd.bufptr = (u32) &txb[0];
20784 + txd.bufptr = virt_to_bus(&txb[0]);
20786 /* load Transmit Descriptor Register */
20787 - outl((u32) &txd, ioaddr + TxRingPtr);
20788 + outl(virt_to_bus(&txd), ioaddr + TxRingPtr);
20789 if (natsemi_debug > 1)
20790 printf("natsemi_init_txd: TX descriptor register loaded with: %X\n",
20791 inl(ioaddr + TxRingPtr));
20792 @@ -527,7 +525,7 @@
20795 static void
20796 -natsemi_init_rxd(struct nic *nic)
20797 +natsemi_init_rxd(struct nic *nic __unused)
20799 int i;
20801 @@ -535,16 +533,16 @@
20803 /* init RX descriptor */
20804 for (i = 0; i < NUM_RX_DESC; i++) {
20805 - rxd[i].link = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0];
20806 + rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
20807 rxd[i].cmdsts = (u32) RX_BUF_SIZE;
20808 - rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE];
20809 + rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
20810 if (natsemi_debug > 1)
20811 printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
20812 i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
20815 /* load Receive Descriptor Register */
20816 - outl((u32) &rxd[0], ioaddr + RxRingPtr);
20817 + outl(virt_to_bus(&rxd[0]), ioaddr + RxRingPtr);
20819 if (natsemi_debug > 1)
20820 printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n",
20821 @@ -562,14 +560,15 @@
20822 * Returns: void.
20825 -static void natsemi_set_rx_mode(struct nic *nic)
20826 +static void natsemi_set_rx_mode(struct nic *nic __unused)
20828 - u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
20829 + u32 rx_mode = RxFilterEnable | AcceptBroadcast |
20830 + AcceptAllMulticast | AcceptMyPhys;
20832 outl(rx_mode, ioaddr + RxFilterAddr);
20835 -static void natsemi_check_duplex(struct nic *nic)
20836 +static void natsemi_check_duplex(struct nic *nic __unused)
20838 int duplex = inl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
20840 @@ -607,14 +606,14 @@
20841 unsigned int s, /* size */
20842 const char *p) /* Packet */
20844 - u32 status, to, nstype;
20845 + u32 to, nstype;
20846 volatile u32 tx_status;
20848 /* Stop the transmitter */
20849 outl(TxOff, ioaddr + ChipCmd);
20851 /* load Transmit Descriptor Register */
20852 - outl((u32) &txd, ioaddr + TxRingPtr);
20853 + outl(virt_to_bus(&txd), ioaddr + TxRingPtr);
20854 if (natsemi_debug > 1)
20855 printf("natsemi_transmit: TX descriptor register loaded with: %X\n",
20856 inl(ioaddr + TxRingPtr));
20857 @@ -636,7 +635,7 @@
20858 txb[s++] = '\0';
20860 /* set the transmit buffer descriptor and enable Transmit State Machine */
20861 - txd.bufptr = (u32) &txb[0];
20862 + txd.bufptr = virt_to_bus(&txb[0]);
20863 txd.cmdsts = (u32) OWN | s;
20865 /* restart the transmitter */
20866 @@ -647,7 +646,7 @@
20868 to = currticks() + TX_TIMEOUT;
20870 - while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
20871 + while (((tx_status=txd.cmdsts & OWN) && (currticks() < to))
20872 /* wait */ ;
20874 if (currticks() >= to) {
20875 @@ -674,7 +673,7 @@
20878 static int
20879 -natsemi_poll(struct nic *nic)
20880 +natsemi_poll(struct nic *nic, int retrieve)
20882 u32 rx_status = rxd[cur_rx].cmdsts;
20883 int retstat = 0;
20884 @@ -685,6 +684,8 @@
20885 if (!(rx_status & OWN))
20886 return retstat;
20888 + if ( ! retrieve ) return 1;
20890 if (natsemi_debug > 1)
20891 printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
20892 cur_rx, rx_status);
20893 @@ -704,7 +705,7 @@
20895 /* return the descriptor and buffer to receive ring */
20896 rxd[cur_rx].cmdsts = RX_BUF_SIZE;
20897 - rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE];
20898 + rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
20900 if (++cur_rx == NUM_RX_DESC)
20901 cur_rx = 0;
20902 @@ -725,8 +726,12 @@
20905 static void
20906 -natsemi_disable(struct nic *nic)
20907 +natsemi_disable(struct dev *dev)
20909 + struct nic *nic = (struct nic *)dev;
20910 + /* merge reset and disable */
20911 + natsemi_init(nic);
20913 /* Disable interrupts using the mask. */
20914 outl(0, ioaddr + IntrMask);
20915 outl(0, ioaddr + IntrEnable);
20916 @@ -737,3 +742,39 @@
20917 /* Restore PME enable bit */
20918 outl(SavedClkRun, ioaddr + ClkRun);
20921 +/* Function: natsemi_irq
20923 + * Description: Enable, Disable, or Force interrupts
20924 + *
20925 + * Arguments: struct nic *nic: NIC data structure
20926 + * irq_action_t action: requested action to perform
20928 + * Returns: void.
20929 + */
20931 +static void
20932 +natsemi_irq(struct nic *nic __unused, irq_action_t action __unused)
20934 + switch ( action ) {
20935 + case DISABLE :
20936 + break;
20937 + case ENABLE :
20938 + break;
20939 + case FORCE :
20940 + break;
20944 +static struct pci_id natsemi_nics[] = {
20945 +PCI_ROM(0x100b, 0x0020, "dp83815", "DP83815"),
20948 +struct pci_driver natsemi_driver = {
20949 + .type = NIC_DRIVER,
20950 + .name = "NATSEMI",
20951 + .probe = natsemi_probe,
20952 + .ids = natsemi_nics,
20953 + .id_count = sizeof(natsemi_nics)/sizeof(natsemi_nics[0]),
20954 + .class = 0,
20956 Index: b/netboot/nfs.h
20957 ===================================================================
20958 --- /dev/null
20959 +++ b/netboot/nfs.h
20960 @@ -0,0 +1,63 @@
20961 +#ifndef _NFS_H
20962 +#define _NFS_H
20964 +#define SUNRPC_PORT 111
20966 +#define PROG_PORTMAP 100000
20967 +#define PROG_NFS 100003
20968 +#define PROG_MOUNT 100005
20970 +#define MSG_CALL 0
20971 +#define MSG_REPLY 1
20973 +#define PORTMAP_GETPORT 3
20975 +#define MOUNT_ADDENTRY 1
20976 +#define MOUNT_UMOUNTALL 4
20978 +#define NFS_LOOKUP 4
20979 +#define NFS_READLINK 5
20980 +#define NFS_READ 6
20982 +#define NFS_FHSIZE 32
20984 +#define NFSERR_PERM 1
20985 +#define NFSERR_NOENT 2
20986 +#define NFSERR_ACCES 13
20987 +#define NFSERR_ISDIR 21
20988 +#define NFSERR_INVAL 22
20990 +/* Block size used for NFS read accesses. A RPC reply packet (including all
20991 + * headers) must fit within a single Ethernet frame to avoid fragmentation.
20992 + * Chosen to be a power of two, as most NFS servers are optimized for this. */
20993 +#define NFS_READ_SIZE 1024
20995 +#define NFS_MAXLINKDEPTH 16
20997 +struct rpc_t {
20998 + struct iphdr ip;
20999 + struct udphdr udp;
21000 + union {
21001 + uint8_t data[300]; /* longest RPC call must fit!!!! */
21002 + struct {
21003 + uint32_t id;
21004 + uint32_t type;
21005 + uint32_t rpcvers;
21006 + uint32_t prog;
21007 + uint32_t vers;
21008 + uint32_t proc;
21009 + uint32_t data[1];
21010 + } call;
21011 + struct {
21012 + uint32_t id;
21013 + uint32_t type;
21014 + uint32_t rstatus;
21015 + uint32_t verifier;
21016 + uint32_t v2;
21017 + uint32_t astatus;
21018 + uint32_t data[1];
21019 + } reply;
21020 + } u;
21023 +#endif /* _NFS_H */
21024 Index: b/netboot/ni5010.c
21025 ===================================================================
21026 --- a/netboot/ni5010.c
21027 +++ /dev/null
21028 @@ -1,371 +0,0 @@
21029 -/**************************************************************************
21030 -Etherboot - BOOTP/TFTP Bootstrap Program
21031 -Driver for NI5010.
21032 -Code freely taken from Jan-Pascal van Best and Andreas Mohr's
21033 -Linux NI5010 driver.
21034 -***************************************************************************/
21037 - * This program is free software; you can redistribute it and/or
21038 - * modify it under the terms of the GNU General Public License as
21039 - * published by the Free Software Foundation; either version 2, or (at
21040 - * your option) any later version.
21041 - */
21043 -/* to get some global routines like printf */
21044 -#include "etherboot.h"
21045 -/* to get the interface to the body of the program */
21046 -#include "nic.h"
21047 -/* to get our own prototype */
21048 -#include "cards.h"
21050 -/* ni5010.h file included verbatim */
21052 - * Racal-Interlan ni5010 Ethernet definitions
21054 - * This is an extension to the Linux operating system, and is covered by the
21055 - * same Gnu Public License that covers that work.
21057 - * copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
21059 - * I have done a look in the following sources:
21060 - * crynwr-packet-driver by Russ Nelson
21061 - */
21063 -#define NI5010_BUFSIZE 2048 /* number of bytes in a buffer */
21065 -#define NI5010_MAGICVAL0 0x00 /* magic-values for ni5010 card */
21066 -#define NI5010_MAGICVAL1 0x55
21067 -#define NI5010_MAGICVAL2 0xAA
21069 -#define SA_ADDR0 0x02
21070 -#define SA_ADDR1 0x07
21071 -#define SA_ADDR2 0x01
21073 -/* The number of low I/O ports used by the ni5010 ethercard. */
21074 -#define NI5010_IO_EXTENT 32
21076 -#define PRINTK(x) if (NI5010_DEBUG) printk x
21077 -#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
21078 -#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
21080 -/* The various IE command registers */
21081 -#define EDLC_XSTAT (ioaddr + 0x00) /* EDLC transmit csr */
21082 -#define EDLC_XCLR (ioaddr + 0x00) /* EDLC transmit "Clear IRQ" */
21083 -#define EDLC_XMASK (ioaddr + 0x01) /* EDLC transmit "IRQ Masks" */
21084 -#define EDLC_RSTAT (ioaddr + 0x02) /* EDLC receive csr */
21085 -#define EDLC_RCLR (ioaddr + 0x02) /* EDLC receive "Clear IRQ" */
21086 -#define EDLC_RMASK (ioaddr + 0x03) /* EDLC receive "IRQ Masks" */
21087 -#define EDLC_XMODE (ioaddr + 0x04) /* EDLC transmit Mode */
21088 -#define EDLC_RMODE (ioaddr + 0x05) /* EDLC receive Mode */
21089 -#define EDLC_RESET (ioaddr + 0x06) /* EDLC RESET register */
21090 -#define EDLC_TDR1 (ioaddr + 0x07) /* "Time Domain Reflectometry" reg1 */
21091 -#define EDLC_ADDR (ioaddr + 0x08) /* EDLC station address, 6 bytes */
21092 - /* 0x0E doesn't exist for r/w */
21093 -#define EDLC_TDR2 (ioaddr + 0x0f) /* "Time Domain Reflectometry" reg2 */
21094 -#define IE_GP (ioaddr + 0x10) /* GP pointer (word register) */
21095 - /* 0x11 is 2nd byte of GP Pointer */
21096 -#define IE_RCNT (ioaddr + 0x10) /* Count of bytes in rcv'd packet */
21097 - /* 0x11 is 2nd byte of "Byte Count" */
21098 -#define IE_MMODE (ioaddr + 0x12) /* Memory Mode register */
21099 -#define IE_DMA_RST (ioaddr + 0x13) /* IE DMA Reset. write only */
21100 -#define IE_ISTAT (ioaddr + 0x13) /* IE Interrupt Status. read only */
21101 -#define IE_RBUF (ioaddr + 0x14) /* IE Receive Buffer port */
21102 -#define IE_XBUF (ioaddr + 0x15) /* IE Transmit Buffer port */
21103 -#define IE_SAPROM (ioaddr + 0x16) /* window on station addr prom */
21104 -#define IE_RESET (ioaddr + 0x17) /* any write causes Board Reset */
21106 -/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
21107 -#define XS_TPOK 0x80 /* transmit packet successful */
21108 -#define XS_CS 0x40 /* carrier sense */
21109 -#define XS_RCVD 0x20 /* transmitted packet received */
21110 -#define XS_SHORT 0x10 /* transmission media is shorted */
21111 -#define XS_UFLW 0x08 /* underflow. iff failed board */
21112 -#define XS_COLL 0x04 /* collision occurred */
21113 -#define XS_16COLL 0x02 /* 16th collision occurred */
21114 -#define XS_PERR 0x01 /* parity error */
21116 -#define XS_CLR_UFLW 0x08 /* clear underflow */
21117 -#define XS_CLR_COLL 0x04 /* clear collision */
21118 -#define XS_CLR_16COLL 0x02 /* clear 16th collision */
21119 -#define XS_CLR_PERR 0x01 /* clear parity error */
21121 -/* bits in EDLC_XMASK, mask/enable transmit interrupts. register is r/w */
21122 -#define XM_TPOK 0x80 /* =1 to enable Xmt Pkt OK interrupts */
21123 -#define XM_RCVD 0x20 /* =1 to enable Xmt Pkt Rcvd ints */
21124 -#define XM_UFLW 0x08 /* =1 to enable Xmt Underflow ints */
21125 -#define XM_COLL 0x04 /* =1 to enable Xmt Collision ints */
21126 -#define XM_COLL16 0x02 /* =1 to enable Xmt 16th Coll ints */
21127 -#define XM_PERR 0x01 /* =1 to enable Xmt Parity Error ints */
21128 - /* note: always clear this bit */
21129 -#define XM_ALL (XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
21131 -/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
21132 -#define RS_PKT_OK 0x80 /* received good packet */
21133 -#define RS_RST_PKT 0x10 /* RESET packet received */
21134 -#define RS_RUNT 0x08 /* Runt Pkt rcvd. Len < 64 Bytes */
21135 -#define RS_ALIGN 0x04 /* Alignment error. not 8 bit aligned */
21136 -#define RS_CRC_ERR 0x02 /* Bad CRC on rcvd pkt */
21137 -#define RS_OFLW 0x01 /* overflow for rcv FIFO */
21138 -#define RS_VALID_BITS ( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
21139 - /* all valid RSTAT bits */
21141 -#define RS_CLR_PKT_OK 0x80 /* clear rcvd packet interrupt */
21142 -#define RS_CLR_RST_PKT 0x10 /* clear RESET packet received */
21143 -#define RS_CLR_RUNT 0x08 /* clear Runt Pckt received */
21144 -#define RS_CLR_ALIGN 0x04 /* clear Alignment error */
21145 -#define RS_CLR_CRC_ERR 0x02 /* clear CRC error */
21146 -#define RS_CLR_OFLW 0x01 /* clear rcv FIFO Overflow */
21148 -/* bits in EDLC_RMASK, mask/enable receive interrupts. register is r/w */
21149 -#define RM_PKT_OK 0x80 /* =1 to enable rcvd good packet ints */
21150 -#define RM_RST_PKT 0x10 /* =1 to enable RESET packet ints */
21151 -#define RM_RUNT 0x08 /* =1 to enable Runt Pkt rcvd ints */
21152 -#define RM_ALIGN 0x04 /* =1 to enable Alignment error ints */
21153 -#define RM_CRC_ERR 0x02 /* =1 to enable Bad CRC error ints */
21154 -#define RM_OFLW 0x01 /* =1 to enable overflow error ints */
21156 -/* bits in EDLC_RMODE, set Receive Packet mode. register is r/w */
21157 -#define RMD_TEST 0x80 /* =1 for Chip testing. normally 0 */
21158 -#define RMD_ADD_SIZ 0x10 /* =1 5-byte addr match. normally 0 */
21159 -#define RMD_EN_RUNT 0x08 /* =1 enable runt rcv. normally 0 */
21160 -#define RMD_EN_RST 0x04 /* =1 to rcv RESET pkt. normally 0 */
21162 -#define RMD_PROMISC 0x03 /* receive *all* packets. unusual */
21163 -#define RMD_MULTICAST 0x02 /* receive multicasts too. unusual */
21164 -#define RMD_BROADCAST 0x01 /* receive broadcasts & normal. usual */
21165 -#define RMD_NO_PACKETS 0x00 /* don't receive any packets. unusual */
21167 -/* bits in EDLC_XMODE, set Transmit Packet mode. register is r/w */
21168 -#define XMD_COLL_CNT 0xf0 /* coll's since success. read-only */
21169 -#define XMD_IG_PAR 0x08 /* =1 to ignore parity. ALWAYS set */
21170 -#define XMD_T_MODE 0x04 /* =1 to power xcvr. ALWAYS set this */
21171 -#define XMD_LBC 0x02 /* =1 for loopback. normally set */
21172 -#define XMD_DIS_C 0x01 /* =1 disables contention. normally 0 */
21174 -/* bits in EDLC_RESET, write only */
21175 -#define RS_RESET 0x80 /* =1 to hold EDLC in reset state */
21177 -/* bits in IE_MMODE, write only */
21178 -#define MM_EN_DMA 0x80 /* =1 begin DMA xfer, Cplt clrs it */
21179 -#define MM_EN_RCV 0x40 /* =1 allows Pkt rcv. clr'd by rcv */
21180 -#define MM_EN_XMT 0x20 /* =1 begin Xmt pkt. Cplt clrs it */
21181 -#define MM_BUS_PAGE 0x18 /* =00 ALWAYS. Used when MUX=1 */
21182 -#define MM_NET_PAGE 0x06 /* =00 ALWAYS. Used when MUX=0 */
21183 -#define MM_MUX 0x01 /* =1 means Rcv Buff on system bus */
21184 - /* =0 means Xmt Buff on system bus */
21186 -/* bits in IE_ISTAT, read only */
21187 -#define IS_TDIAG 0x80 /* =1 if Diagnostic problem */
21188 -#define IS_EN_RCV 0x20 /* =1 until frame is rcv'd cplt */
21189 -#define IS_EN_XMT 0x10 /* =1 until frame is xmt'd cplt */
21190 -#define IS_EN_DMA 0x08 /* =1 until DMA is cplt or aborted */
21191 -#define IS_DMA_INT 0x04 /* =0 iff DMA done interrupt. */
21192 -#define IS_R_INT 0x02 /* =0 iff unmasked Rcv interrupt */
21193 -#define IS_X_INT 0x01 /* =0 iff unmasked Xmt interrupt */
21195 -/* NIC specific static variables go here */
21197 -static unsigned short ioaddr = 0;
21198 -static unsigned int bufsize_rcv = 0;
21200 -#if 0
21201 -static void show_registers(void)
21203 - printf("XSTAT %hhX ", inb(EDLC_XSTAT));
21204 - printf("XMASK %hhX ", inb(EDLC_XMASK));
21205 - printf("RSTAT %hhX ", inb(EDLC_RSTAT));
21206 - printf("RMASK %hhX ", inb(EDLC_RMASK));
21207 - printf("RMODE %hhX ", inb(EDLC_RMODE));
21208 - printf("XMODE %hhX ", inb(EDLC_XMODE));
21209 - printf("ISTAT %hhX\n", inb(IE_ISTAT));
21211 -#endif
21213 -static void reset_receiver(void)
21215 - outw(0, IE_GP); /* Receive packet at start of buffer */
21216 - outb(RS_VALID_BITS, EDLC_RCLR); /* Clear all pending Rcv interrupts */
21217 - outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
21220 -/**************************************************************************
21221 -RESET - Reset adapter
21222 -***************************************************************************/
21223 -static void ni5010_reset(struct nic *nic)
21225 - int i;
21227 - /* Reset the hardware here. Don't forget to set the station address. */
21228 - outb(RS_RESET, EDLC_RESET); /* Hold up EDLC_RESET while configing board */
21229 - outb(0, IE_RESET); /* Hardware reset of ni5010 board */
21230 - outb(0, EDLC_XMASK); /* Disable all Xmt interrupts */
21231 - outb(0, EDLC_RMASK); /* Disable all Rcv interrupt */
21232 - outb(0xFF, EDLC_XCLR); /* Clear all pending Xmt interrupts */
21233 - outb(0xFF, EDLC_RCLR); /* Clear all pending Rcv interrupts */
21234 - outb(XMD_LBC, EDLC_XMODE); /* Only loopback xmits */
21235 - /* Set the station address */
21236 - for(i = 0; i < ETH_ALEN; i++)
21237 - outb(nic->node_addr[i], EDLC_ADDR + i);
21238 - outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE);
21239 - /* Normal packet xmit mode */
21240 - outb(RMD_BROADCAST, EDLC_RMODE);
21241 - /* Receive broadcast and normal packets */
21242 - reset_receiver();
21243 - outb(0x00, EDLC_RESET); /* Un-reset the ni5010 */
21246 -/**************************************************************************
21247 -POLL - Wait for a frame
21248 -***************************************************************************/
21249 -static int ni5010_poll(struct nic *nic)
21251 - int rcv_stat;
21253 - if (((rcv_stat = inb(EDLC_RSTAT)) & RS_VALID_BITS) != RS_PKT_OK) {
21254 - outb(rcv_stat, EDLC_RSTAT); /* Clear the status */
21255 - return (0);
21257 - outb(rcv_stat, EDLC_RCLR); /* Clear the status */
21258 - nic->packetlen = inw(IE_RCNT);
21259 - /* Read packet into buffer */
21260 - outb(MM_MUX, IE_MMODE); /* Rcv buffer to system bus */
21261 - outw(0, IE_GP); /* Seek to beginning of packet */
21262 - insb(IE_RBUF, nic->packet, nic->packetlen);
21263 - return (1);
21266 -/**************************************************************************
21267 -TRANSMIT - Transmit a frame
21268 -***************************************************************************/
21269 -static void ni5010_transmit(struct nic *nic,
21270 - const char *d, /* Destination */
21271 - unsigned int t, /* Type */
21272 - unsigned int s, /* size */
21273 - const char *p) /* Packet */
21275 - unsigned int len;
21276 - int buf_offs, xmt_stat;
21277 - unsigned long time;
21279 - len = s + ETH_HLEN;
21280 - if (len < ETH_ZLEN)
21281 - len = ETH_ZLEN;
21282 - buf_offs = NI5010_BUFSIZE - len;
21283 - outb(0, EDLC_RMASK); /* Mask all receive interrupts */
21284 - outb(0, IE_MMODE); /* Put Xmit buffer on system bus */
21285 - outb(0xFF, EDLC_RCLR); /* Clear out pending rcv interrupts */
21286 - outw(buf_offs, IE_GP); /* Point GP at start of packet */
21287 - outsb(IE_XBUF, d, ETH_ALEN); /* Put dst in buffer */
21288 - outsb(IE_XBUF, nic->node_addr, ETH_ALEN);/* Put src in buffer */
21289 - outb(t >> 8, IE_XBUF);
21290 - outb(t, IE_XBUF);
21291 - outsb(IE_XBUF, p, s); /* Put data in buffer */
21292 - while (s++ < ETH_ZLEN - ETH_HLEN) /* Pad to min size */
21293 - outb(0, IE_XBUF);
21294 - outw(buf_offs, IE_GP); /* Rewrite where packet starts */
21295 - /* should work without that outb() (Crynwr used it) */
21296 - /*outb(MM_MUX, IE_MMODE);*/
21297 - /* Xmt buffer to EDLC bus */
21298 - outb(MM_EN_XMT | MM_MUX, IE_MMODE); /* Begin transmission */
21299 - /* wait for transmit complete */
21300 - while (((xmt_stat = inb(IE_ISTAT)) & IS_EN_XMT) != 0)
21302 - reset_receiver(); /* Immediately switch to receive */
21305 -/**************************************************************************
21306 -DISABLE - Turn off ethernet interface
21307 -***************************************************************************/
21308 -static void ni5010_disable(struct nic *nic)
21310 - outb(0, IE_MMODE);
21311 - outb(RS_RESET, EDLC_RESET);
21314 -static inline int rd_port(void)
21316 - inb(IE_RBUF);
21317 - return inb(IE_SAPROM);
21320 -static int ni5010_probe1(struct nic *nic)
21322 - int i, boguscount = 40, data;
21324 - /* The tests are from the Linux NI5010 driver
21325 - I don't understand it all, but if it works for them... */
21326 - if (inb(ioaddr) == 0xFF)
21327 - return (0);
21328 - while ((rd_port() & rd_port() & rd_port()
21329 - & rd_port() & rd_port() & rd_port()) != 0xFF)
21331 - if (boguscount-- <= 0)
21332 - return (0);
21334 - for (i = 0; i < 32; i++)
21335 - if ((data = rd_port()) != 0xFF)
21336 - break;
21337 - if (data == 0xFF)
21338 - return (0);
21339 - if (data == SA_ADDR0 && rd_port() == SA_ADDR1 && rd_port() == SA_ADDR2) {
21340 - for (i = 0; i < 4; i++)
21341 - rd_port();
21342 - if (rd_port() != NI5010_MAGICVAL1 || rd_port() != NI5010_MAGICVAL2)
21343 - return (0);
21344 - } else
21345 - return (0);
21346 - for (i = 0; i < ETH_ALEN; i++) {
21347 - outw(i, IE_GP);
21348 - nic->node_addr[i] = inb(IE_SAPROM);
21350 - printf("\nNI5010 ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
21351 -/* get the size of the onboard receive buffer
21352 - * higher addresses than bufsize are wrapped into real buffer
21353 - * i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
21354 - */
21355 - if (bufsize_rcv == 0) {
21356 - outb(1, IE_MMODE); /* Put Rcv buffer on system bus */
21357 - outw(0, IE_GP); /* Point GP at start of packet */
21358 - outb(0, IE_RBUF); /* set buffer byte 0 to 0 */
21359 - for (i = 1; i < 0xFF; i++) {
21360 - outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
21361 - outb(i, IE_RBUF);
21362 - outw(0x0, IE_GP); /* Point GP at start of packet */
21363 - data = inb(IE_RBUF);
21364 - if (data == i) break;
21366 - bufsize_rcv = i << 8;
21367 - outw(0, IE_GP); /* Point GP at start of packet */
21368 - outb(0, IE_RBUF); /* set buffer byte 0 to 0 again */
21370 - printf("Bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
21371 - return (1);
21374 -/**************************************************************************
21375 -PROBE - Look for an adapter, this routine's visible to the outside
21376 -***************************************************************************/
21377 -struct nic *ni5010_probe(struct nic *nic, unsigned short *probe_addrs)
21379 - static unsigned short io_addrs[] = {
21380 - 0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
21381 - unsigned short *p;
21383 - /* if probe_addrs is 0, then use list above */
21384 - if (probe_addrs == 0 || *probe_addrs == 0)
21385 - probe_addrs = io_addrs;
21386 - for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
21387 - if (ni5010_probe1(nic))
21388 - break;
21390 - if (ioaddr == 0)
21391 - return (0);
21392 - ni5010_reset(nic);
21393 - /* point to NIC specific routines */
21394 - nic->reset = ni5010_reset;
21395 - nic->poll = ni5010_poll;
21396 - nic->transmit = ni5010_transmit;
21397 - nic->disable = ni5010_disable;
21398 - return (nic);
21400 Index: b/netboot/nic.c
21401 ===================================================================
21402 --- /dev/null
21403 +++ b/netboot/nic.c
21404 @@ -0,0 +1,1198 @@
21405 +/**************************************************************************
21406 +Etherboot - Network Bootstrap Program
21408 +Literature dealing with the network protocols:
21409 + ARP - RFC826
21410 + RARP - RFC903
21411 + IP - RFC791
21412 + UDP - RFC768
21413 + BOOTP - RFC951, RFC2132 (vendor extensions)
21414 + DHCP - RFC2131, RFC2132 (options)
21415 + TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
21416 + RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
21417 + NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
21418 + IGMP - RFC1112, RFC2113, RFC2365, RFC2236, RFC3171
21420 +**************************************************************************/
21421 +#include "etherboot.h"
21422 +#include "grub.h"
21423 +#include "nic.h"
21424 +#include "elf.h" /* FOR EM_CURRENT */
21425 +#include "bootp.h"
21426 +#include "if_arp.h"
21427 +#include "tftp.h"
21428 +#include "timer.h"
21429 +#include "ip.h"
21430 +#include "udp.h"
21432 +/* Currently no other module uses rom, but it is available */
21433 +struct rom_info rom;
21434 +struct arptable_t arptable[MAX_ARP];
21435 +#if MULTICAST_LEVEL2
21436 +unsigned long last_igmpv1 = 0;
21437 +struct igmptable_t igmptable[MAX_IGMP];
21438 +#endif
21439 +static unsigned long netmask;
21440 +/* Used by nfs.c */
21441 +char *hostname = "";
21442 +int hostnamelen = 0;
21443 +static uint32_t xid;
21444 +static unsigned char *end_of_rfc1533 = NULL;
21445 +static const unsigned char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
21446 +static const in_addr zeroIP = { 0L };
21447 +static char rfc1533_venddata[MAX_RFC1533_VENDLEN];
21448 +static unsigned char rfc1533_cookie[4] = { RFC1533_COOKIE };
21449 +static unsigned char rfc1533_cookie_bootp[5] = { RFC1533_COOKIE, RFC1533_END };
21450 +static unsigned char rfc1533_cookie_dhcp[] = { RFC1533_COOKIE };
21451 +static int dhcp_reply;
21452 +static in_addr dhcp_server = { 0L };
21453 +static in_addr dhcp_addr = { 0L };
21455 +static const unsigned char dhcpdiscover[] = {
21456 + RFC2132_MSG_TYPE, 1, DHCPDISCOVER,
21457 + RFC2132_MAX_SIZE, 2, /* request as much as we can */
21458 + ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
21459 + /* Vendor class identifier */
21460 + RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't',
21461 + RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY,
21462 + RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH, RFC1533_END
21464 +static const unsigned char dhcprequest [] = {
21465 + RFC2132_MSG_TYPE,1,DHCPREQUEST,
21466 + RFC2132_SRV_ID,4,0,0,0,0,
21467 + RFC2132_REQ_ADDR,4,0,0,0,0,
21468 + RFC2132_MAX_SIZE,2, /* request as much as we can */
21469 + ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
21470 + /* Vendor class identifier */
21471 + RFC2132_VENDOR_CLASS_ID, 10, 'G', 'R', 'U', 'B', 'C', 'l', 'i', 'e', 'n', 't',
21472 + RFC2132_PARAM_LIST,
21473 + /* 4 standard + 2 vendortags */
21474 + 4 + 2,
21475 + /* Standard parameters */
21476 + RFC1533_NETMASK, RFC1533_GATEWAY,
21477 + RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
21478 + /* Etherboot vendortags */
21479 + RFC1533_VENDOR_MAGIC,
21480 + RFC1533_VENDOR_CONFIGFILE,
21481 + RFC1533_END
21484 +/* See nic.h */
21485 +int user_abort = 0;
21486 +int network_ready = 0;
21488 +#ifdef REQUIRE_VCI_ETHERBOOT
21489 +int vci_etherboot;
21490 +#endif
21492 +static int dummy(void *unused __unused)
21494 + return (0);
21497 +/* Careful. We need an aligned buffer to avoid problems on machines
21498 + * that care about alignment. To trivally align the ethernet data
21499 + * (the ip hdr and arp requests) we offset the packet by 2 bytes.
21500 + * leaving the ethernet data 16 byte aligned. Beyond this
21501 + * we use memmove but this makes the common cast simple and fast.
21502 + */
21503 +static char packet[ETH_FRAME_LEN + ETH_DATA_ALIGN] __aligned;
21505 +struct nic nic =
21508 + 0, /* dev.disable */
21510 + 0,
21511 + 0,
21512 + PCI_BUS_TYPE,
21513 + }, /* dev.devid */
21514 + 0, /* index */
21515 + 0, /* type */
21516 + PROBE_FIRST, /* how_pobe */
21517 + PROBE_NONE, /* to_probe */
21518 + 0, /* failsafe */
21519 + 0, /* type_index */
21520 + {}, /* state */
21521 + },
21522 + (int (*)(struct nic *, int))dummy, /* poll */
21523 + (void (*)(struct nic *, const char *,
21524 + unsigned int, unsigned int,
21525 + const char *))dummy, /* transmit */
21526 + (void (*)(struct nic *, irq_action_t))dummy, /* irq */
21527 + 0, /* flags */
21528 + &rom, /* rom_info */
21529 + arptable[ARP_CLIENT].node, /* node_addr */
21530 + packet + ETH_DATA_ALIGN, /* packet */
21531 + 0, /* packetlen */
21532 + 0, /* ioaddr */
21533 + 0, /* irqno */
21534 + NULL, /* priv_data */
21539 +int grub_eth_probe(void)
21541 + static int probed = 0;
21542 + struct dev *dev;
21544 + EnterFunction("grub_eth_probe");
21546 + if (probed)
21547 + return 1;
21549 + network_ready = 0;
21550 + grub_memset((char *)arptable, 0, MAX_ARP * sizeof(struct arptable_t));
21551 + dev = &nic.dev;
21552 + dev->how_probe = -1;
21553 + dev->type = NIC_DRIVER;
21554 + dev->failsafe = 1;
21555 + rom = *((struct rom_info *)ROM_INFO_LOCATION);
21557 + probed = (eth_probe(dev) == PROBE_WORKED);
21559 + LeaveFunction("grub_eth_probe");
21560 + return probed;
21563 +int eth_probe(struct dev *dev)
21565 + return probe(dev);
21568 +int eth_poll(int retrieve)
21570 + return ((*nic.poll)(&nic, retrieve));
21573 +void eth_transmit(const char *d, unsigned int t, unsigned int s, const void *p)
21575 + (*nic.transmit)(&nic, d, t, s, p);
21576 + if (t == IP) twiddle();
21579 +void eth_disable(void)
21581 +#ifdef MULTICAST_LEVEL2
21582 + int i;
21583 + for(i = 0; i < MAX_IGMP; i++) {
21584 + leave_group(i);
21586 +#endif
21587 + disable(&nic.dev);
21590 +void eth_irq (irq_action_t action)
21592 + (*nic.irq)(&nic,action);
21595 +/**************************************************************************
21596 +IPCHKSUM - Checksum IP Header
21597 +**************************************************************************/
21598 +uint16_t ipchksum(const void *data, unsigned long length)
21600 + unsigned long sum;
21601 + unsigned long i;
21602 + const uint8_t *ptr;
21604 + /* In the most straight forward way possible,
21605 + * compute an ip style checksum.
21606 + */
21607 + sum = 0;
21608 + ptr = data;
21609 + for(i = 0; i < length; i++) {
21610 + unsigned long value;
21611 + value = ptr[i];
21612 + if (i & 1) {
21613 + value <<= 8;
21615 + /* Add the new value */
21616 + sum += value;
21617 + /* Wrap around the carry */
21618 + if (sum > 0xFFFF) {
21619 + sum = (sum + (sum >> 16)) & 0xFFFF;
21622 + return (~cpu_to_le16(sum)) & 0xFFFF;
21625 +uint16_t add_ipchksums(unsigned long offset, uint16_t sum, uint16_t new)
21627 + unsigned long checksum;
21628 + sum = ~sum & 0xFFFF;
21629 + new = ~new & 0xFFFF;
21630 + if (offset & 1) {
21631 + /* byte swap the sum if it came from an odd offset
21632 + * since the computation is endian independant this
21633 + * works.
21634 + */
21635 + new = bswap_16(new);
21637 + checksum = sum + new;
21638 + if (checksum > 0xFFFF) {
21639 + checksum -= 0xFFFF;
21641 + return (~checksum) & 0xFFFF;
21644 +/**************************************************************************
21645 +DEFAULT_NETMASK - Return default netmask for IP address
21646 +**************************************************************************/
21647 +static inline unsigned long default_netmask(void)
21649 + int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
21650 + if (net <= 127)
21651 + return(htonl(0xff000000));
21652 + else if (net < 192)
21653 + return(htonl(0xffff0000));
21654 + else
21655 + return(htonl(0xffffff00));
21658 +/**************************************************************************
21659 +IP_TRANSMIT - Send an IP datagram
21660 +**************************************************************************/
21661 +static int await_arp(int ival, void *ptr,
21662 + unsigned short ptype, struct iphdr *ip __unused, struct udphdr *udp __unused)
21664 + struct arprequest *arpreply;
21665 + if (ptype != ARP)
21666 + return 0;
21667 + if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
21668 + return 0;
21669 + arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
21671 + if (arpreply->opcode != htons(ARP_REPLY))
21672 + return 0;
21673 + if (memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) != 0)
21674 + return 0;
21675 + memcpy(arptable[ival].node, arpreply->shwaddr, ETH_ALEN);
21676 + return 1;
21679 +int ip_transmit(int len, const void *buf)
21681 + unsigned long destip;
21682 + struct iphdr *ip;
21683 + struct arprequest arpreq;
21684 + int arpentry, i;
21685 + int retry;
21687 + ip = (struct iphdr *)buf;
21688 + destip = ip->dest.s_addr;
21689 + if (destip == IP_BROADCAST) {
21690 + eth_transmit(broadcast, IP, len, buf);
21691 +#ifdef MULTICAST_LEVEL1
21692 + } else if ((destip & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
21693 + unsigned char multicast[6];
21694 + unsigned long hdestip;
21695 + hdestip = ntohl(destip);
21696 + multicast[0] = 0x01;
21697 + multicast[1] = 0x00;
21698 + multicast[2] = 0x5e;
21699 + multicast[3] = (hdestip >> 16) & 0x7;
21700 + multicast[4] = (hdestip >> 8) & 0xff;
21701 + multicast[5] = hdestip & 0xff;
21702 + eth_transmit(multicast, IP, len, buf);
21703 +#endif
21704 + } else {
21705 + if (((destip & netmask) !=
21706 + (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&
21707 + arptable[ARP_GATEWAY].ipaddr.s_addr)
21708 + destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
21709 + for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
21710 + if (arptable[arpentry].ipaddr.s_addr == destip) break;
21711 + if (arpentry == MAX_ARP) {
21712 + printf("%@ is not in my arp table!\n", destip);
21713 + return(0);
21715 + for (i = 0; i < ETH_ALEN; i++)
21716 + if (arptable[arpentry].node[i])
21717 + break;
21718 + if (i == ETH_ALEN) { /* Need to do arp request */
21719 + arpreq.hwtype = htons(1);
21720 + arpreq.protocol = htons(IP);
21721 + arpreq.hwlen = ETH_ALEN;
21722 + arpreq.protolen = 4;
21723 + arpreq.opcode = htons(ARP_REQUEST);
21724 + memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
21725 + memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
21726 + memset(arpreq.thwaddr, 0, ETH_ALEN);
21727 + memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));
21728 + for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {
21729 + long timeout;
21730 + eth_transmit(broadcast, ARP, sizeof(arpreq),
21731 + &arpreq);
21732 + timeout = rfc2131_sleep_interval(TIMEOUT, retry);
21733 + if (await_reply(await_arp, arpentry,
21734 + arpreq.tipaddr, timeout)) goto xmit;
21736 + return(0);
21738 +xmit:
21739 + eth_transmit(arptable[arpentry].node, IP, len, buf);
21741 + return 1;
21744 +void build_ip_hdr(unsigned long destip, int ttl, int protocol, int option_len,
21745 + int len, const void *buf)
21747 + struct iphdr *ip;
21748 + ip = (struct iphdr *)buf;
21749 + ip->verhdrlen = 0x45;
21750 + ip->verhdrlen += (option_len/4);
21751 + ip->service = 0;
21752 + ip->len = htons(len);
21753 + ip->ident = 0;
21754 + ip->frags = 0; /* Should we set don't fragment? */
21755 + ip->ttl = ttl;
21756 + ip->protocol = protocol;
21757 + ip->chksum = 0;
21758 + ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
21759 + ip->dest.s_addr = destip;
21760 + ip->chksum = ipchksum(buf, sizeof(struct iphdr) + option_len);
21763 +static uint16_t udpchksum(struct iphdr *ip, struct udphdr *udp)
21765 + struct udp_pseudo_hdr pseudo;
21766 + uint16_t checksum;
21768 + /* Compute the pseudo header */
21769 + pseudo.src.s_addr = ip->src.s_addr;
21770 + pseudo.dest.s_addr = ip->dest.s_addr;
21771 + pseudo.unused = 0;
21772 + pseudo.protocol = IP_UDP;
21773 + pseudo.len = udp->len;
21775 + /* Sum the pseudo header */
21776 + checksum = ipchksum(&pseudo, 12);
21778 + /* Sum the rest of the udp packet */
21779 + checksum = add_ipchksums(12, checksum, ipchksum(udp, ntohs(udp->len)));
21780 + return checksum;
21784 +void build_udp_hdr(unsigned long destip,
21785 + unsigned int srcsock, unsigned int destsock, int ttl,
21786 + int len, const void *buf)
21788 + struct iphdr *ip;
21789 + struct udphdr *udp;
21790 + ip = (struct iphdr *)buf;
21791 + build_ip_hdr(destip, ttl, IP_UDP, 0, len, buf);
21792 + udp = (struct udphdr *)((char *)buf + sizeof(struct iphdr));
21793 + udp->src = htons(srcsock);
21794 + udp->dest = htons(destsock);
21795 + udp->len = htons(len - sizeof(struct iphdr));
21796 + udp->chksum = 0;
21797 + if ((udp->chksum = udpchksum(ip, udp)) == 0)
21798 + udp->chksum = 0xffff;
21802 +/**************************************************************************
21803 +UDP_TRANSMIT - Send an UDP datagram
21804 +**************************************************************************/
21805 +int udp_transmit(unsigned long destip, unsigned int srcsock,
21806 + unsigned int destsock, int len, const void *buf)
21808 + build_udp_hdr(destip, srcsock, destsock, 60, len, buf);
21809 + return ip_transmit(len, buf);
21812 +/**************************************************************************
21813 +QDRAIN - clear the nic's receive queue
21814 +**************************************************************************/
21815 +static int await_qdrain(int ival __unused, void *ptr __unused,
21816 + unsigned short ptype __unused,
21817 + struct iphdr *ip __unused, struct udphdr *udp __unused)
21819 + return 0;
21822 +void rx_qdrain(void)
21824 + /* Clear out the Rx queue first. It contains nothing of interest,
21825 + * except possibly ARP requests from the DHCP/TFTP server. We use
21826 + * polling throughout Etherboot, so some time may have passed since we
21827 + * last polled the receive queue, which may now be filled with
21828 + * broadcast packets. This will cause the reply to the packets we are
21829 + * about to send to be lost immediately. Not very clever. */
21830 + await_reply(await_qdrain, 0, NULL, 0);
21833 +/**
21834 + * rarp
21836 + * Get IP address by rarp. Just copy from etherboot
21837 + **/
21838 +static int await_rarp(int ival, void *ptr, unsigned short ptype,
21839 + struct iphdr *ip, struct udphdr *udp)
21841 + struct arprequest *arpreply;
21842 + if (ptype != RARP)
21843 + return 0;
21844 + if (nic.packetlen < ETH_HLEN + sizeof(struct arprequest))
21845 + return 0;
21846 + arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
21847 + if (arpreply->opcode != htons(RARP_REPLY))
21848 + return 0;
21849 + if (memcmp(arpreply->thwaddr, ptr, ETH_ALEN) == 0){
21850 + memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETH_ALEN);
21851 + memcpy(&arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
21852 + memcpy(&arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
21853 + return 1;
21855 + return 0;
21858 +int rarp(void)
21860 + int retry;
21862 + /* arp and rarp requests share the same packet structure. */
21863 + struct arprequest rarpreq;
21865 + if(!grub_eth_probe())
21866 + return 0;
21867 + network_ready = 0;
21869 + memset(&rarpreq, 0, sizeof(rarpreq));
21871 + rarpreq.hwtype = htons(1);
21872 + rarpreq.protocol = htons(IP);
21873 + rarpreq.hwlen = ETH_ALEN;
21874 + rarpreq.protolen = 4;
21875 + rarpreq.opcode = htons(RARP_REQUEST);
21876 + memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
21877 + /* sipaddr is already zeroed out */
21878 + memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
21879 + /* tipaddr is already zeroed out */
21881 + for (retry = 0; retry < MAX_ARP_RETRIES; ++retry) {
21882 + long timeout;
21883 + eth_transmit(broadcast, RARP, sizeof(rarpreq), &rarpreq);
21885 + timeout = rfc2131_sleep_interval(TIMEOUT, retry);
21886 + if (await_reply(await_rarp, 0, rarpreq.shwaddr, timeout))
21887 + break;
21888 + if (user_abort)
21889 + return 0;
21892 + if (retry < MAX_ARP_RETRIES) {
21893 + network_ready = 1;
21894 + return (1);
21896 + return (0);
21899 +/**
21900 + * bootp
21902 + * Get IP address by bootp, segregate from bootp in etherboot.
21903 + **/
21904 +static int await_bootp(int ival __unused, void *ptr __unused,
21905 + unsigned short ptype __unused, struct iphdr *ip __unused,
21906 + struct udphdr *udp)
21908 + struct bootp_t *bootpreply;
21909 + int len; /* Length of vendor */
21911 + if (!udp) {
21912 + return 0;
21914 + bootpreply = (struct bootp_t *)
21915 + &nic.packet[ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr)];
21916 + len = nic.packetlen - (ETH_HLEN + sizeof(struct iphdr) +
21917 + sizeof(struct udphdr) + sizeof(struct bootp_t) - BOOTP_VENDOR_LEN);
21918 + if (len < 0) {
21919 + return 0;
21921 + if (udp->dest != htons(BOOTP_CLIENT))
21922 + return 0;
21923 + if (bootpreply->bp_op != BOOTP_REPLY)
21924 + return 0;
21925 + if (bootpreply->bp_xid != xid)
21926 + return 0;
21927 + if (memcmp((char *)&bootpreply->bp_siaddr, (char *)&zeroIP, sizeof(in_addr)) == 0)
21928 + return 0;
21929 + if ((memcmp(broadcast, bootpreply->bp_hwaddr, ETH_ALEN) != 0) &&
21930 + (memcmp(arptable[ARP_CLIENT].node, bootpreply->bp_hwaddr, ETH_ALEN) != 0)) {
21931 + return 0;
21933 + arptable[ARP_CLIENT].ipaddr.s_addr = bootpreply->bp_yiaddr.s_addr;
21934 + netmask = default_netmask();
21935 + arptable[ARP_SERVER].ipaddr.s_addr = bootpreply->bp_siaddr.s_addr;
21936 + memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */
21937 + arptable[ARP_GATEWAY].ipaddr.s_addr = bootpreply->bp_giaddr.s_addr;
21938 + memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */
21939 + /* We don't care bootpreply->bp_file, it must be 'pxegrub':-) */
21940 + memcpy((char *)rfc1533_venddata, (char *)(bootpreply->bp_vend), len);
21941 + decode_rfc1533(rfc1533_venddata, 0, len, 1);
21942 + return(1);
21945 +int bootp(void)
21947 + int retry;
21948 + struct bootpip_t ip;
21949 + unsigned long starttime;
21951 + EnterFunction("bootp");
21953 + if(!grub_eth_probe())
21954 + return 0;
21955 + network_ready = 0;
21957 + memset(&ip, 0, sizeof(struct bootpip_t));
21958 + ip.bp.bp_op = BOOTP_REQUEST;
21959 + ip.bp.bp_htype = 1;
21960 + ip.bp.bp_hlen = ETH_ALEN;
21961 + starttime = currticks();
21962 + /* Use lower 32 bits of node address, more likely to be
21963 + distinct than the time since booting */
21964 + memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
21965 + ip.bp.bp_xid = xid += htonl(starttime);
21966 + /* bp_secs defaults to zero */
21967 + memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
21968 + memcpy(ip.bp.bp_vend, rfc1533_cookie_bootp, sizeof(rfc1533_cookie_bootp)); /* request RFC-style options */
21970 + for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
21971 + long timeout;
21973 + rx_qdrain();
21975 + udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
21976 + sizeof(struct bootpip_t), &ip);
21977 + timeout = rfc2131_sleep_interval(TIMEOUT, retry++);
21978 + if (await_reply(await_bootp, 0, NULL, timeout)){
21979 + network_ready = 1;
21980 + return(1);
21982 + if (user_abort)
21983 + return 0;
21984 + ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC);
21986 + return(0);
21989 +/**
21990 + * dhcp
21992 + * Get IP address by dhcp, segregate from bootp in etherboot.
21993 + **/
21994 +static int await_dhcp(int ival __unused, void *ptr __unused,
21995 + unsigned short ptype __unused, struct iphdr *ip __unused,
21996 + struct udphdr *udp)
21998 + struct dhcp_t *dhcpreply;
21999 + int len;
22001 + if (!udp) {
22002 + return 0;
22004 + dhcpreply = (struct dhcp_t *)
22005 + &nic.packet[ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr)];
22006 + len = nic.packetlen - (ETH_HLEN + sizeof(struct iphdr) +
22007 + sizeof(struct udphdr) + sizeof(struct dhcp_t) - DHCP_OPT_LEN);
22008 + if (len < 0){
22009 + return 0;
22011 + if (udp->dest != htons(BOOTP_CLIENT))
22012 + return 0;
22013 + if (dhcpreply->bp_op != BOOTP_REPLY)
22014 + return 0;
22015 + if (dhcpreply->bp_xid != xid)
22016 + return 0;
22017 + if (memcmp((char *)&dhcpreply->bp_siaddr, (char *)&zeroIP, sizeof(in_addr)) == 0)
22018 + return 0;
22019 + if ((memcmp(broadcast, dhcpreply->bp_hwaddr, ETH_ALEN) != 0) &&
22020 + (memcmp(arptable[ARP_CLIENT].node, dhcpreply->bp_hwaddr, ETH_ALEN) != 0)) {
22021 + return 0;
22023 + arptable[ARP_CLIENT].ipaddr.s_addr = dhcpreply->bp_yiaddr.s_addr;
22024 + dhcp_addr.s_addr = dhcpreply->bp_yiaddr.s_addr;
22025 + netmask = default_netmask();
22026 + arptable[ARP_SERVER].ipaddr.s_addr = dhcpreply->bp_siaddr.s_addr;
22027 + memset(arptable[ARP_SERVER].node, 0, ETH_ALEN); /* Kill arp */
22028 + arptable[ARP_GATEWAY].ipaddr.s_addr = dhcpreply->bp_giaddr.s_addr;
22029 + memset(arptable[ARP_GATEWAY].node, 0, ETH_ALEN); /* Kill arp */
22030 + /* We don't care bootpreply->bp_file. It must be 'pxegrub' */
22031 + memcpy((char *)rfc1533_venddata, (char *)(dhcpreply->bp_vend), len);
22032 + decode_rfc1533(rfc1533_venddata, 0, len, 1);
22033 + return(1);
22036 +int dhcp(void)
22038 + int retry;
22039 + int reqretry;
22040 + struct dhcpip_t ip;
22041 + unsigned long starttime;
22043 + if(!grub_eth_probe())
22044 + return 0;
22046 + network_ready = 0;
22048 + memset(&ip, 0, sizeof(struct dhcpip_t));
22049 + ip.bp.bp_op = BOOTP_REQUEST;
22050 + ip.bp.bp_htype = 1;
22051 + ip.bp.bp_hlen = ETH_ALEN;
22052 + starttime = currticks();
22053 + /* Use lower 32 bits of node address, more likely to be
22054 + distinct than the time since booting */
22055 + memcpy(&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
22056 + ip.bp.bp_xid = xid += htonl(starttime);
22057 + memcpy(ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
22058 + memcpy(ip.bp.bp_vend, rfc1533_cookie_dhcp, sizeof rfc1533_cookie_dhcp); /* request RFC-style options */
22059 + memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie_dhcp, dhcpdiscover, sizeof dhcpdiscover);
22061 + for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
22062 + long timeout;
22064 + rx_qdrain();
22066 + udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
22067 + sizeof(struct bootpip_t), &ip);
22068 + timeout = rfc2131_sleep_interval(TIMEOUT, retry++);
22069 + if (await_reply(await_dhcp, 0, NULL, timeout)) {
22070 + /* If not a DHCPOFFER then must be just a
22071 + BOOTP reply, be backward compatible with
22072 + BOOTP then. Jscott report a bug here, but I
22073 + don't know how it happened */
22074 + if (dhcp_reply != DHCPOFFER){
22075 + network_ready = 1;
22076 + return(1);
22078 + dhcp_reply = 0;
22079 + memcpy(ip.bp.bp_vend, rfc1533_cookie_dhcp, sizeof rfc1533_cookie_dhcp);
22080 + memcpy(ip.bp.bp_vend + sizeof rfc1533_cookie_dhcp, dhcprequest, sizeof dhcprequest);
22081 + /* Beware: the magic numbers 9 and 15 depend on
22082 + the layout of dhcprequest */
22083 + memcpy(&ip.bp.bp_vend[9], &dhcp_server, sizeof(in_addr));
22084 + memcpy(&ip.bp.bp_vend[15], &dhcp_addr, sizeof(in_addr));
22085 + for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES; ) {
22086 + udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
22087 + sizeof(struct bootpip_t), &ip);
22088 + dhcp_reply=0;
22089 + timeout = rfc2131_sleep_interval(TIMEOUT, reqretry++);
22090 + if (await_reply(await_dhcp, 0, NULL, timeout))
22091 + if (dhcp_reply == DHCPACK){
22092 + network_ready = 1;
22093 + return(1);
22095 + if (user_abort)
22096 + return 0;
22099 + if (user_abort)
22100 + return 0;
22101 + ip.bp.bp_secs = htons((currticks()-starttime)/TICKS_PER_SEC);
22103 + return(0);
22106 +#ifdef MULTICAST_LEVEL2
22107 +static void send_igmp_reports(unsigned long now)
22109 + int i;
22110 + for(i = 0; i < MAX_IGMP; i++) {
22111 + if (igmptable[i].time && (now >= igmptable[i].time)) {
22112 + struct igmp_ip_t igmp;
22113 + igmp.router_alert[0] = 0x94;
22114 + igmp.router_alert[1] = 0x04;
22115 + igmp.router_alert[2] = 0;
22116 + igmp.router_alert[3] = 0;
22117 + build_ip_hdr(igmptable[i].group.s_addr,
22118 + 1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp);
22119 + igmp.igmp.type = IGMPv2_REPORT;
22120 + if (last_igmpv1 &&
22121 + (now < last_igmpv1 + IGMPv1_ROUTER_PRESENT_TIMEOUT)) {
22122 + igmp.igmp.type = IGMPv1_REPORT;
22124 + igmp.igmp.response_time = 0;
22125 + igmp.igmp.chksum = 0;
22126 + igmp.igmp.group.s_addr = igmptable[i].group.s_addr;
22127 + igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp.igmp));
22128 + ip_transmit(sizeof(igmp), &igmp);
22129 +#ifdef MDEBUG
22130 + printf("Sent IGMP report to: %@\n", igmp.igmp.group.s_addr);
22131 +#endif
22132 + /* Don't send another igmp report until asked */
22133 + igmptable[i].time = 0;
22138 +static void process_igmp(struct iphdr *ip, unsigned long now)
22140 + struct igmp *igmp;
22141 + int i;
22142 + unsigned iplen = 0;
22143 + if (!ip || (ip->protocol == IP_IGMP) ||
22144 + (nic.packetlen < sizeof(struct iphdr) + sizeof(struct igmp))) {
22145 + return;
22147 + iplen = (ip->verhdrlen & 0xf)*4;
22148 + igmp = (struct igmp *)&nic.packet[sizeof(struct iphdr)];
22149 + if (ipchksum(igmp, ntohs(ip->len) - iplen) != 0)
22150 + return;
22151 + if ((igmp->type == IGMP_QUERY) &&
22152 + (ip->dest.s_addr == htonl(GROUP_ALL_HOSTS))) {
22153 + unsigned long interval = IGMP_INTERVAL;
22154 + if (igmp->response_time == 0) {
22155 + last_igmpv1 = now;
22156 + } else {
22157 + interval = (igmp->response_time * TICKS_PER_SEC)/10;
22160 +#ifdef MDEBUG
22161 + printf("Received IGMP query for: %@\n", igmp->group.s_addr);
22162 +#endif
22163 + for(i = 0; i < MAX_IGMP; i++) {
22164 + uint32_t group = igmptable[i].group.s_addr;
22165 + if ((group == 0) || (group == igmp->group.s_addr)) {
22166 + unsigned long time;
22167 + time = currticks() + rfc1112_sleep_interval(interval, 0);
22168 + if (time < igmptable[i].time) {
22169 + igmptable[i].time = time;
22174 + if (((igmp->type == IGMPv1_REPORT) || (igmp->type == IGMPv2_REPORT)) &&
22175 + (ip->dest.s_addr == igmp->group.s_addr)) {
22176 +#ifdef MDEBUG
22177 + printf("Received IGMP report for: %@\n", igmp->group.s_addr);
22178 +#endif
22179 + for(i = 0; i < MAX_IGMP; i++) {
22180 + if ((igmptable[i].group.s_addr == igmp->group.s_addr) &&
22181 + igmptable[i].time != 0) {
22182 + igmptable[i].time = 0;
22188 +void leave_group(int slot)
22190 + /* Be very stupid and always send a leave group message if
22191 + * I have subscribed. Imperfect but it is standards
22192 + * compliant, easy and reliable to implement.
22194 + * The optimal group leave method is to only send leave when,
22195 + * we were the last host to respond to a query on this group,
22196 + * and igmpv1 compatibility is not enabled.
22197 + */
22198 + if (igmptable[slot].group.s_addr) {
22199 + struct igmp_ip_t igmp;
22200 + igmp.router_alert[0] = 0x94;
22201 + igmp.router_alert[1] = 0x04;
22202 + igmp.router_alert[2] = 0;
22203 + igmp.router_alert[3] = 0;
22204 + build_ip_hdr(htonl(GROUP_ALL_HOSTS),
22205 + 1, IP_IGMP, sizeof(igmp.router_alert), sizeof(igmp), &igmp);
22206 + igmp.igmp.type = IGMP_LEAVE;
22207 + igmp.igmp.response_time = 0;
22208 + igmp.igmp.chksum = 0;
22209 + igmp.igmp.group.s_addr = igmptable[slot].group.s_addr;
22210 + igmp.igmp.chksum = ipchksum(&igmp.igmp, sizeof(igmp));
22211 + ip_transmit(sizeof(igmp), &igmp);
22212 +#ifdef MDEBUG
22213 + printf("Sent IGMP leave for: %@\n", igmp.igmp.group.s_addr);
22214 +#endif
22216 + memset(&igmptable[slot], 0, sizeof(igmptable[0]));
22219 +void join_group(int slot, unsigned long group)
22221 + /* I have already joined */
22222 + if (igmptable[slot].group.s_addr == group)
22223 + return;
22224 + if (igmptable[slot].group.s_addr) {
22225 + leave_group(slot);
22227 + /* Only join a group if we are given a multicast ip, this way
22228 + * code can be given a non-multicast (broadcast or unicast ip)
22229 + * and still work...
22230 + */
22231 + if ((group & htonl(MULTICAST_MASK)) == htonl(MULTICAST_NETWORK)) {
22232 + igmptable[slot].group.s_addr = group;
22233 + igmptable[slot].time = currticks();
22236 +#else
22237 +#define send_igmp_reports(now);
22238 +#define process_igmp(ip, now)
22239 +#endif
22241 +/**************************************************************************
22242 +AWAIT_REPLY - Wait until we get a response for our request
22243 +************f**************************************************************/
22244 +int await_reply(reply_t reply, int ival, void *ptr, long timeout)
22246 + unsigned long time, now;
22247 + struct iphdr *ip;
22248 + unsigned iplen = 0;
22249 + struct udphdr *udp;
22250 + unsigned short ptype;
22251 + int result;
22253 + user_abort = 0;
22255 + time = timeout + currticks();
22256 + /* The timeout check is done below. The timeout is only checked if
22257 + * there is no packet in the Rx queue. This assumes that eth_poll()
22258 + * needs a negligible amount of time.
22259 + */
22260 + for (;;) {
22261 + now = currticks();
22262 + send_igmp_reports(now);
22263 + result = eth_poll(1);
22264 + if (result == 0) {
22265 + /* We don't have anything */
22267 + /* Check for abort key only if the Rx queue is empty -
22268 + * as long as we have something to process, don't
22269 + * assume that something failed. It is unlikely that
22270 + * we have no processing time left between packets. */
22271 + poll_interruptions();
22272 + /* Do the timeout after at least a full queue walk. */
22273 + if ((timeout == 0) || (currticks() > time) || user_abort == 1) {
22274 + break;
22276 + continue;
22279 + /* We have something! */
22281 + /* Find the Ethernet packet type */
22282 + if (nic.packetlen >= ETH_HLEN) {
22283 + ptype = ((unsigned short) nic.packet[12]) << 8
22284 + | ((unsigned short) nic.packet[13]);
22285 + } else continue; /* what else could we do with it? */
22286 + /* Verify an IP header */
22287 + ip = 0;
22288 + if ((ptype == IP) && (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr))) {
22289 + unsigned ipoptlen;
22290 + ip = (struct iphdr *)&nic.packet[ETH_HLEN];
22291 + if ((ip->verhdrlen < 0x45) || (ip->verhdrlen > 0x4F))
22292 + continue;
22293 + iplen = (ip->verhdrlen & 0xf) * 4;
22294 + if (ipchksum(ip, iplen) != 0)
22295 + continue;
22296 + if (ip->frags & htons(0x3FFF)) {
22297 + static int warned_fragmentation = 0;
22298 + if (!warned_fragmentation) {
22299 + printf("ALERT: got a fragmented packet - reconfigure your server\n");
22300 + warned_fragmentation = 1;
22302 + continue;
22304 + if (ntohs(ip->len) > ETH_MAX_MTU)
22305 + continue;
22307 + ipoptlen = iplen - sizeof(struct iphdr);
22308 + if (ipoptlen) {
22309 + /* Delete the ip options, to guarantee
22310 + * good alignment, and make etherboot simpler.
22311 + */
22312 + memmove(&nic.packet[ETH_HLEN + sizeof(struct iphdr)],
22313 + &nic.packet[ETH_HLEN + iplen],
22314 + nic.packetlen - ipoptlen);
22315 + nic.packetlen -= ipoptlen;
22318 + udp = 0;
22319 + if (ip && (ip->protocol == IP_UDP) &&
22320 + (nic.packetlen >= ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr))) {
22321 + udp = (struct udphdr *)&nic.packet[ETH_HLEN + sizeof(struct iphdr)];
22323 + /* Make certain we have a reasonable packet length */
22324 + if (ntohs(udp->len) > (ntohs(ip->len) - iplen))
22325 + continue;
22327 + if (udp->chksum && udpchksum(ip, udp)) {
22328 + printf("UDP checksum error\n");
22329 + continue;
22332 + result = reply(ival, ptr, ptype, ip, udp);
22333 + if (result > 0) {
22334 + return result;
22337 + /* If it isn't a packet the upper layer wants see if there is a default
22338 + * action. This allows us reply to arp and igmp queryies.
22339 + */
22340 + if ((ptype == ARP) &&
22341 + (nic.packetlen >= ETH_HLEN + sizeof(struct arprequest))) {
22342 + struct arprequest *arpreply;
22343 + unsigned long tmp;
22345 + arpreply = (struct arprequest *)&nic.packet[ETH_HLEN];
22346 + memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
22347 + if ((arpreply->opcode == htons(ARP_REQUEST)) &&
22348 + (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
22349 + arpreply->opcode = htons(ARP_REPLY);
22350 + memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
22351 + memcpy(arpreply->thwaddr, arpreply->shwaddr, ETH_ALEN);
22352 + memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
22353 + memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
22354 + eth_transmit(arpreply->thwaddr, ARP,
22355 + sizeof(struct arprequest),
22356 + arpreply);
22357 +#ifdef MDEBUG
22358 + memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
22359 + printf("Sent ARP reply to: %@\n",tmp);
22360 +#endif /* MDEBUG */
22363 + process_igmp(ip, now);
22365 + return(0);
22368 +#ifdef REQUIRE_VCI_ETHERBOOT
22369 +/**************************************************************************
22370 +FIND_VCI_ETHERBOOT - Looks for "Etherboot" in Vendor Encapsulated Identifiers
22371 +On entry p points to byte count of VCI options
22372 +**************************************************************************/
22373 +static int find_vci_etherboot(unsigned char *p)
22375 + unsigned char *end = p + 1 + *p;
22377 + for (p++; p < end; ) {
22378 + if (*p == RFC2132_VENDOR_CLASS_ID) {
22379 + if (strncmp("Etherboot", p + 2, sizeof("Etherboot") - 1) == 0)
22380 + return (1);
22381 + } else if (*p == RFC1533_END)
22382 + return (0);
22383 + p += TAG_LEN(p) + 2;
22385 + return (0);
22387 +#endif /* REQUIRE_VCI_ETHERBOOT */
22389 +/**
22390 + * decode_rfc1533
22392 + * Decodes RFC1533 header
22393 + **/
22394 +int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int eof)
22396 + static unsigned char *extdata = NULL, *extend = NULL;
22397 + unsigned char *extpath = NULL;
22398 + unsigned char *endp;
22400 + if (block == 0) {
22401 + end_of_rfc1533 = NULL;
22402 + if (memcmp(p, rfc1533_cookie, sizeof(rfc1533_cookie)))
22403 + return(0); /* no RFC 1533 header found */
22404 + p += 4;
22405 + endp = p + len;
22406 + } else {
22407 + if (block == 1) {
22408 + if (memcmp(p, rfc1533_cookie, sizeof(rfc1533_cookie)))
22409 + return(0); /* no RFC 1533 header found */
22410 + p += 4;
22411 + len -= 4; }
22412 + if (extend + len <= (unsigned char *)
22413 + rfc1533_venddata + sizeof(rfc1533_venddata)) {
22414 + memcpy(extend, p, len);
22415 + extend += len;
22416 + } else {
22417 + printf("Overflow in vendor data buffer! Aborting...\n");
22418 + *extdata = RFC1533_END;
22419 + return(0);
22421 + p = extdata; endp = extend;
22423 + if (!eof)
22424 + return 1;
22425 + while (p < endp) {
22426 + unsigned char c = *p;
22427 + if (c == RFC1533_PAD) {
22428 + p++;
22429 + continue;
22431 + else if (c == RFC1533_END) {
22432 + end_of_rfc1533 = endp = p;
22433 + continue;
22435 + else if (c == RFC1533_NETMASK)
22436 + memcpy(&netmask, p+2, sizeof(in_addr));
22437 + else if (c == RFC1533_GATEWAY) {
22438 + /* This is a little simplistic, but it will
22439 + usually be sufficient.
22440 + Take only the first entry */
22441 + if (TAG_LEN(p) >= sizeof(in_addr))
22442 + memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));
22444 + else if (c == RFC1533_EXTENSIONPATH)
22445 + extpath = p;
22446 + else if (c == RFC2132_MSG_TYPE)
22447 + dhcp_reply=*(p+2);
22448 + else if (c == RFC2132_SRV_ID)
22449 + memcpy(&dhcp_server, p+2, sizeof(in_addr));
22450 + else if (c == RFC1533_HOSTNAME) {
22451 + hostname = p + 2;
22452 + hostnamelen = *(p + 1);
22454 + else if (c == RFC1533_VENDOR_CONFIGFILE){
22455 + int l = TAG_LEN (p);
22457 + /* Eliminate the trailing NULs according to RFC 2132. */
22458 + while (*(p + 2 + l - 1) == '\000' && l > 0)
22459 + l--;
22461 + /* XXX: Should check if LEN is less than the maximum length
22462 + of CONFIG_FILE. This kind of robustness will be a goal
22463 + in GRUB 1.0. */
22464 + memcpy (config_file, p + 2, l);
22465 + config_file[l] = 0;
22467 + else {
22470 + p += TAG_LEN(p) + 2;
22472 + extdata = extend = endp;
22473 + if (block <= 0 && extpath != NULL) {
22474 + char fname[64];
22475 + if (TAG_LEN(extpath) >= sizeof(fname)){
22476 + printf("Overflow in vendor data buffer! Aborting...\n");
22477 + *extdata = RFC1533_END;
22478 + return(0);
22480 + memcpy(fname, extpath+2, TAG_LEN(extpath));
22481 + fname[(int)TAG_LEN(extpath)] = '\0';
22482 + printf("Loading BOOTP-extension file: %s\n",fname);
22483 + tftp_file_read(fname, decode_rfc1533);
22485 + return 1; /* proceed with next block */
22489 +/* FIXME double check TWO_SECOND_DIVISOR */
22490 +#define TWO_SECOND_DIVISOR (RAND_MAX/TICKS_PER_SEC)
22491 +/**************************************************************************
22492 +RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times (base << exp) +- 1 sec)
22493 +**************************************************************************/
22494 +long rfc2131_sleep_interval(long base, int exp)
22496 + unsigned long tmo;
22497 +#ifdef BACKOFF_LIMIT
22498 + if (exp > BACKOFF_LIMIT)
22499 + exp = BACKOFF_LIMIT;
22500 +#endif
22501 + tmo = (base << exp) + (TICKS_PER_SEC - (random()/TWO_SECOND_DIVISOR));
22502 + return tmo;
22505 +#ifdef MULTICAST_LEVEL2
22506 +/**************************************************************************
22507 +RFC1112_SLEEP_INTERVAL - sleep for expotentially longer times, up to (base << exp)
22508 +**************************************************************************/
22509 +long rfc1112_sleep_interval(long base, int exp)
22511 + unsigned long divisor, tmo;
22512 +#ifdef BACKOFF_LIMIT
22513 + if (exp > BACKOFF_LIMIT)
22514 + exp = BACKOFF_LIMIT;
22515 +#endif
22516 + divisor = RAND_MAX/(base << exp);
22517 + tmo = random()/divisor;
22518 + return tmo;
22520 +#endif /* MULTICAST_LEVEL_2 */
22521 +/* ifconfig - configure network interface. */
22522 +int
22523 +ifconfig (char *ip, char *sm, char *gw, char *svr)
22525 + in_addr tmp;
22527 + if (sm)
22529 + if (! inet_aton (sm, &tmp))
22530 + return 0;
22532 + netmask = tmp.s_addr;
22535 + if (ip)
22537 + if (! inet_aton (ip, &arptable[ARP_CLIENT].ipaddr))
22538 + return 0;
22540 + if (! netmask && ! sm)
22541 + netmask = default_netmask ();
22544 + if (gw && ! inet_aton (gw, &arptable[ARP_GATEWAY].ipaddr))
22545 + return 0;
22547 + /* Clear out the ARP entry. */
22548 + grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);
22550 + if (svr && ! inet_aton (svr, &arptable[ARP_SERVER].ipaddr))
22551 + return 0;
22553 + /* Likewise. */
22554 + grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
22556 + if (ip || sm)
22558 + if (IP_BROADCAST == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr)
22559 + || netmask == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr)
22560 + || ! netmask)
22561 + network_ready = 0;
22562 + else
22563 + network_ready = 1;
22566 + return 1;
22570 + * print_network_configuration
22572 + * Output the network configuration. It may broke the graphic console now.:-(
22573 + */
22574 +void print_network_configuration (void)
22576 + EnterFunction("print_network_configuration");
22577 + if (! grub_eth_probe ())
22578 + grub_printf ("No ethernet card found.\n");
22579 + else if (! network_ready)
22580 + grub_printf ("Not initialized yet.\n");
22581 + else {
22582 + etherboot_printf ("Address: %@\n", arptable[ARP_CLIENT].ipaddr.s_addr);
22583 + etherboot_printf ("Netmask: %@\n", netmask);
22584 + etherboot_printf ("Server: %@\n", arptable[ARP_SERVER].ipaddr.s_addr);
22585 + etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr);
22587 + LeaveFunction("print_network_configuration");
22590 +/**
22591 + * cleanup_net
22593 + * Mark network unusable, and disable NICs
22594 + */
22595 +void cleanup_net (void)
22597 + if (network_ready){
22598 + /* Stop receiving packets. */
22599 + eth_disable ();
22600 + network_ready = 0;
22603 Index: b/netboot/nic.h
22604 ===================================================================
22605 --- a/netboot/nic.h
22606 +++ b/netboot/nic.h
22607 @@ -8,24 +8,38 @@
22608 #ifndef NIC_H
22609 #define NIC_H
22611 +#include "dev.h"
22613 +typedef enum {
22614 + DISABLE = 0,
22615 + ENABLE,
22616 + FORCE
22617 +} irq_action_t;
22620 * Structure returned from eth_probe and passed to other driver
22621 * functions.
22624 struct nic
22626 - void (*reset)P((struct nic *));
22627 - int (*poll)P((struct nic *));
22628 + struct dev dev; /* This must come first */
22629 + int (*poll)P((struct nic *, int retrieve));
22630 void (*transmit)P((struct nic *, const char *d,
22631 unsigned int t, unsigned int s, const char *p));
22632 - void (*disable)P((struct nic *));
22633 + void (*irq)P((struct nic *, irq_action_t));
22634 int flags; /* driver specific flags */
22635 struct rom_info *rom_info; /* -> rom_info from main */
22636 unsigned char *node_addr;
22637 - char *packet;
22638 + unsigned char *packet;
22639 unsigned int packetlen;
22640 + unsigned int ioaddr;
22641 + unsigned char irqno;
22642 void *priv_data; /* driver can hang private data here */
22645 +extern int eth_probe(struct dev *dev);
22646 +extern int eth_poll(int retrieve);
22647 +extern void eth_transmit(const char *d, unsigned int t, unsigned int s, const void *p);
22648 +extern void eth_disable(void);
22649 +extern void eth_irq(irq_action_t action);
22650 #endif /* NIC_H */
22651 Index: b/netboot/ns83820.c
22652 ===================================================================
22653 --- /dev/null
22654 +++ b/netboot/ns83820.c
22655 @@ -0,0 +1,1020 @@
22656 +/**************************************************************************
22657 +* ns83820.c: Etherboot device driver for the National Semiconductor 83820
22658 +* Written 2004 by Timothy Legge <tlegge@rogers.com>
22660 +* This program is free software; you can redistribute it and/or modify
22661 +* it under the terms of the GNU General Public License as published by
22662 +* the Free Software Foundation; either version 2 of the License, or
22663 +* (at your option) any later version.
22665 +* This program is distributed in the hope that it will be useful,
22666 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
22667 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22668 +* GNU General Public License for more details.
22670 +* You should have received a copy of the GNU General Public License
22671 +* along with this program; if not, write to the Free Software
22672 +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22674 +* Portions of this code based on:
22675 +* ns83820.c by Benjamin LaHaise with contributions
22676 +* for Linux kernel 2.4.x.
22678 +* Linux Driver Version 0.20, 20020610
22680 +* This development of this Etherboot driver was funded by:
22682 +* NXTV: http://www.nxtv.com/
22684 +* REVISION HISTORY:
22685 +* ================
22687 +* v1.0 02-16-2004 timlegge Initial port of Linux driver
22688 +* v1.1 02-19-2004 timlegge More rohbust transmit and poll
22690 +* Indent Options: indent -kr -i8
22691 +***************************************************************************/
22693 +/* to get some global routines like printf */
22694 +#include "etherboot.h"
22695 +/* to get the interface to the body of the program */
22696 +#include "nic.h"
22697 +/* to get the PCI support functions, if this is a PCI NIC */
22698 +#include "pci.h"
22700 +#if ARCH == ia64 /* Support 64-bit addressing */
22701 +#define USE_64BIT_ADDR
22702 +#endif
22704 +//#define DDEBUG
22705 +#ifdef DDEBUG
22706 +#define dprintf(x) printf x
22707 +#else
22708 +#define dprintf(x)
22709 +#endif
22711 +typedef unsigned char u8;
22712 +typedef signed char s8;
22713 +typedef unsigned short u16;
22714 +typedef signed short s16;
22715 +typedef unsigned int u32;
22716 +typedef signed int s32;
22718 +#define HZ 100
22720 +/* Condensed operations for readability. */
22721 +#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
22722 +#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
22724 +/* NIC specific static variables go here */
22726 +/* Global parameters. See MODULE_PARM near the bottom. */
22727 +// static int ihr = 2;
22728 +static int reset_phy = 0;
22729 +static int lnksts = 0; /* CFG_LNKSTS bit polarity */
22731 +#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
22732 +#define USE_64BIT_ADDR "+"
22733 +#endif
22735 +#if defined(USE_64BIT_ADDR)
22736 +#define TRY_DAC 1
22737 +#else
22738 +#define TRY_DAC 0
22739 +#endif
22741 +/* tunables */
22742 +#define RX_BUF_SIZE 1500 /* 8192 */
22744 +/* Must not exceed ~65000. */
22745 +#define NR_RX_DESC 64
22746 +#define NR_TX_DESC 1
22748 + /* not tunable *//* Extra 6 bytes for 64 bit alignment (divisable by 8) */
22749 +#define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14 + 6) /* rx/tx mac addr + type */
22751 +#define MIN_TX_DESC_FREE 8
22753 +/* register defines */
22754 +#define CFGCS 0x04
22756 +#define CR_TXE 0x00000001
22757 +#define CR_TXD 0x00000002
22758 +/* Ramit : Here's a tip, don't do a RXD immediately followed by an RXE
22759 + * The Receive engine skips one descriptor and moves
22760 + * onto the next one!! */
22761 +#define CR_RXE 0x00000004
22762 +#define CR_RXD 0x00000008
22763 +#define CR_TXR 0x00000010
22764 +#define CR_RXR 0x00000020
22765 +#define CR_SWI 0x00000080
22766 +#define CR_RST 0x00000100
22768 +#define PTSCR_EEBIST_FAIL 0x00000001
22769 +#define PTSCR_EEBIST_EN 0x00000002
22770 +#define PTSCR_EELOAD_EN 0x00000004
22771 +#define PTSCR_RBIST_FAIL 0x000001b8
22772 +#define PTSCR_RBIST_DONE 0x00000200
22773 +#define PTSCR_RBIST_EN 0x00000400
22774 +#define PTSCR_RBIST_RST 0x00002000
22776 +#define MEAR_EEDI 0x00000001
22777 +#define MEAR_EEDO 0x00000002
22778 +#define MEAR_EECLK 0x00000004
22779 +#define MEAR_EESEL 0x00000008
22780 +#define MEAR_MDIO 0x00000010
22781 +#define MEAR_MDDIR 0x00000020
22782 +#define MEAR_MDC 0x00000040
22784 +#define ISR_TXDESC3 0x40000000
22785 +#define ISR_TXDESC2 0x20000000
22786 +#define ISR_TXDESC1 0x10000000
22787 +#define ISR_TXDESC0 0x08000000
22788 +#define ISR_RXDESC3 0x04000000
22789 +#define ISR_RXDESC2 0x02000000
22790 +#define ISR_RXDESC1 0x01000000
22791 +#define ISR_RXDESC0 0x00800000
22792 +#define ISR_TXRCMP 0x00400000
22793 +#define ISR_RXRCMP 0x00200000
22794 +#define ISR_DPERR 0x00100000
22795 +#define ISR_SSERR 0x00080000
22796 +#define ISR_RMABT 0x00040000
22797 +#define ISR_RTABT 0x00020000
22798 +#define ISR_RXSOVR 0x00010000
22799 +#define ISR_HIBINT 0x00008000
22800 +#define ISR_PHY 0x00004000
22801 +#define ISR_PME 0x00002000
22802 +#define ISR_SWI 0x00001000
22803 +#define ISR_MIB 0x00000800
22804 +#define ISR_TXURN 0x00000400
22805 +#define ISR_TXIDLE 0x00000200
22806 +#define ISR_TXERR 0x00000100
22807 +#define ISR_TXDESC 0x00000080
22808 +#define ISR_TXOK 0x00000040
22809 +#define ISR_RXORN 0x00000020
22810 +#define ISR_RXIDLE 0x00000010
22811 +#define ISR_RXEARLY 0x00000008
22812 +#define ISR_RXERR 0x00000004
22813 +#define ISR_RXDESC 0x00000002
22814 +#define ISR_RXOK 0x00000001
22816 +#define TXCFG_CSI 0x80000000
22817 +#define TXCFG_HBI 0x40000000
22818 +#define TXCFG_MLB 0x20000000
22819 +#define TXCFG_ATP 0x10000000
22820 +#define TXCFG_ECRETRY 0x00800000
22821 +#define TXCFG_BRST_DIS 0x00080000
22822 +#define TXCFG_MXDMA1024 0x00000000
22823 +#define TXCFG_MXDMA512 0x00700000
22824 +#define TXCFG_MXDMA256 0x00600000
22825 +#define TXCFG_MXDMA128 0x00500000
22826 +#define TXCFG_MXDMA64 0x00400000
22827 +#define TXCFG_MXDMA32 0x00300000
22828 +#define TXCFG_MXDMA16 0x00200000
22829 +#define TXCFG_MXDMA8 0x00100000
22831 +#define CFG_LNKSTS 0x80000000
22832 +#define CFG_SPDSTS 0x60000000
22833 +#define CFG_SPDSTS1 0x40000000
22834 +#define CFG_SPDSTS0 0x20000000
22835 +#define CFG_DUPSTS 0x10000000
22836 +#define CFG_TBI_EN 0x01000000
22837 +#define CFG_MODE_1000 0x00400000
22838 +/* Ramit : Dont' ever use AUTO_1000, it never works and is buggy.
22839 + * Read the Phy response and then configure the MAC accordingly */
22840 +#define CFG_AUTO_1000 0x00200000
22841 +#define CFG_PINT_CTL 0x001c0000
22842 +#define CFG_PINT_DUPSTS 0x00100000
22843 +#define CFG_PINT_LNKSTS 0x00080000
22844 +#define CFG_PINT_SPDSTS 0x00040000
22845 +#define CFG_TMRTEST 0x00020000
22846 +#define CFG_MRM_DIS 0x00010000
22847 +#define CFG_MWI_DIS 0x00008000
22848 +#define CFG_T64ADDR 0x00004000
22849 +#define CFG_PCI64_DET 0x00002000
22850 +#define CFG_DATA64_EN 0x00001000
22851 +#define CFG_M64ADDR 0x00000800
22852 +#define CFG_PHY_RST 0x00000400
22853 +#define CFG_PHY_DIS 0x00000200
22854 +#define CFG_EXTSTS_EN 0x00000100
22855 +#define CFG_REQALG 0x00000080
22856 +#define CFG_SB 0x00000040
22857 +#define CFG_POW 0x00000020
22858 +#define CFG_EXD 0x00000010
22859 +#define CFG_PESEL 0x00000008
22860 +#define CFG_BROM_DIS 0x00000004
22861 +#define CFG_EXT_125 0x00000002
22862 +#define CFG_BEM 0x00000001
22864 +#define EXTSTS_UDPPKT 0x00200000
22865 +#define EXTSTS_TCPPKT 0x00080000
22866 +#define EXTSTS_IPPKT 0x00020000
22868 +#define SPDSTS_POLARITY (CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0))
22870 +#define MIBC_MIBS 0x00000008
22871 +#define MIBC_ACLR 0x00000004
22872 +#define MIBC_FRZ 0x00000002
22873 +#define MIBC_WRN 0x00000001
22875 +#define PCR_PSEN (1 << 31)
22876 +#define PCR_PS_MCAST (1 << 30)
22877 +#define PCR_PS_DA (1 << 29)
22878 +#define PCR_STHI_8 (3 << 23)
22879 +#define PCR_STLO_4 (1 << 23)
22880 +#define PCR_FFHI_8K (3 << 21)
22881 +#define PCR_FFLO_4K (1 << 21)
22882 +#define PCR_PAUSE_CNT 0xFFFE
22884 +#define RXCFG_AEP 0x80000000
22885 +#define RXCFG_ARP 0x40000000
22886 +#define RXCFG_STRIPCRC 0x20000000
22887 +#define RXCFG_RX_FD 0x10000000
22888 +#define RXCFG_ALP 0x08000000
22889 +#define RXCFG_AIRL 0x04000000
22890 +#define RXCFG_MXDMA512 0x00700000
22891 +#define RXCFG_DRTH 0x0000003e
22892 +#define RXCFG_DRTH0 0x00000002
22894 +#define RFCR_RFEN 0x80000000
22895 +#define RFCR_AAB 0x40000000
22896 +#define RFCR_AAM 0x20000000
22897 +#define RFCR_AAU 0x10000000
22898 +#define RFCR_APM 0x08000000
22899 +#define RFCR_APAT 0x07800000
22900 +#define RFCR_APAT3 0x04000000
22901 +#define RFCR_APAT2 0x02000000
22902 +#define RFCR_APAT1 0x01000000
22903 +#define RFCR_APAT0 0x00800000
22904 +#define RFCR_AARP 0x00400000
22905 +#define RFCR_MHEN 0x00200000
22906 +#define RFCR_UHEN 0x00100000
22907 +#define RFCR_ULM 0x00080000
22909 +#define VRCR_RUDPE 0x00000080
22910 +#define VRCR_RTCPE 0x00000040
22911 +#define VRCR_RIPE 0x00000020
22912 +#define VRCR_IPEN 0x00000010
22913 +#define VRCR_DUTF 0x00000008
22914 +#define VRCR_DVTF 0x00000004
22915 +#define VRCR_VTREN 0x00000002
22916 +#define VRCR_VTDEN 0x00000001
22918 +#define VTCR_PPCHK 0x00000008
22919 +#define VTCR_GCHK 0x00000004
22920 +#define VTCR_VPPTI 0x00000002
22921 +#define VTCR_VGTI 0x00000001
22923 +#define CR 0x00
22924 +#define CFG 0x04
22925 +#define MEAR 0x08
22926 +#define PTSCR 0x0c
22927 +#define ISR 0x10
22928 +#define IMR 0x14
22929 +#define IER 0x18
22930 +#define IHR 0x1c
22931 +#define TXDP 0x20
22932 +#define TXDP_HI 0x24
22933 +#define TXCFG 0x28
22934 +#define GPIOR 0x2c
22935 +#define RXDP 0x30
22936 +#define RXDP_HI 0x34
22937 +#define RXCFG 0x38
22938 +#define PQCR 0x3c
22939 +#define WCSR 0x40
22940 +#define PCR 0x44
22941 +#define RFCR 0x48
22942 +#define RFDR 0x4c
22944 +#define SRR 0x58
22946 +#define VRCR 0xbc
22947 +#define VTCR 0xc0
22948 +#define VDR 0xc4
22949 +#define CCSR 0xcc
22951 +#define TBICR 0xe0
22952 +#define TBISR 0xe4
22953 +#define TANAR 0xe8
22954 +#define TANLPAR 0xec
22955 +#define TANER 0xf0
22956 +#define TESR 0xf4
22958 +#define TBICR_MR_AN_ENABLE 0x00001000
22959 +#define TBICR_MR_RESTART_AN 0x00000200
22961 +#define TBISR_MR_LINK_STATUS 0x00000020
22962 +#define TBISR_MR_AN_COMPLETE 0x00000004
22964 +#define TANAR_PS2 0x00000100
22965 +#define TANAR_PS1 0x00000080
22966 +#define TANAR_HALF_DUP 0x00000040
22967 +#define TANAR_FULL_DUP 0x00000020
22969 +#define GPIOR_GP5_OE 0x00000200
22970 +#define GPIOR_GP4_OE 0x00000100
22971 +#define GPIOR_GP3_OE 0x00000080
22972 +#define GPIOR_GP2_OE 0x00000040
22973 +#define GPIOR_GP1_OE 0x00000020
22974 +#define GPIOR_GP3_OUT 0x00000004
22975 +#define GPIOR_GP1_OUT 0x00000001
22977 +#define LINK_AUTONEGOTIATE 0x01
22978 +#define LINK_DOWN 0x02
22979 +#define LINK_UP 0x04
22982 +#define __kick_rx() writel(CR_RXE, ns->base + CR)
22984 +#define kick_rx() do { \
22985 + dprintf(("kick_rx: maybe kicking\n")); \
22986 + writel(virt_to_le32desc(&rx_ring[ns->cur_rx]), ns->base + RXDP); \
22987 + if (ns->next_rx == ns->next_empty) \
22988 + printf("uh-oh: next_rx == next_empty???\n"); \
22989 + __kick_rx(); \
22990 +} while(0)
22993 +#ifdef USE_64BIT_ADDR
22994 +#define HW_ADDR_LEN 8
22995 +#else
22996 +#define HW_ADDR_LEN 4
22997 +#endif
22999 +#define CMDSTS_OWN 0x80000000
23000 +#define CMDSTS_MORE 0x40000000
23001 +#define CMDSTS_INTR 0x20000000
23002 +#define CMDSTS_ERR 0x10000000
23003 +#define CMDSTS_OK 0x08000000
23004 +#define CMDSTS_LEN_MASK 0x0000ffff
23006 +#define CMDSTS_DEST_MASK 0x01800000
23007 +#define CMDSTS_DEST_SELF 0x00800000
23008 +#define CMDSTS_DEST_MULTI 0x01000000
23010 +#define DESC_SIZE 8 /* Should be cache line sized */
23012 +#ifdef USE_64BIT_ADDR
23013 +struct ring_desc {
23014 + uint64_t link;
23015 + uint64_t bufptr;
23016 + u32 cmdsts;
23017 + u32 extsts; /* Extended status field */
23019 +#else
23020 +struct ring_desc {
23021 + u32 link;
23022 + u32 bufptr;
23023 + u32 cmdsts;
23024 + u32 extsts; /* Extended status field */
23026 +#endif
23028 +/* Define the TX Descriptor */
23029 +static struct ring_desc tx_ring[NR_TX_DESC]
23030 + __attribute__ ((aligned(8)));
23032 +/* Create a static buffer of size REAL_RX_BUF_SIZE for each
23033 +TX Descriptor. All descriptors point to a
23034 +part of this buffer */
23035 +static unsigned char txb[NR_TX_DESC * REAL_RX_BUF_SIZE];
23037 +/* Define the TX Descriptor */
23038 +static struct ring_desc rx_ring[NR_RX_DESC]
23039 + __attribute__ ((aligned(8)));
23041 +/* Create a static buffer of size REAL_RX_BUF_SIZE for each
23042 +RX Descriptor All descriptors point to a
23043 +part of this buffer */
23044 +static unsigned char rxb[NR_RX_DESC * REAL_RX_BUF_SIZE]
23045 + __attribute__ ((aligned(8)));
23047 +/* Private Storage for the NIC */
23048 +struct ns83820_private {
23049 + u8 *base;
23050 + int up;
23051 + long idle;
23052 + u32 *next_rx_desc;
23053 + u16 next_rx, next_empty;
23054 + u32 cur_rx;
23055 + u32 *descs;
23056 + unsigned ihr;
23057 + u32 CFG_cache;
23058 + u32 MEAR_cache;
23059 + u32 IMR_cache;
23060 + int linkstate;
23061 + u16 tx_done_idx;
23062 + u16 tx_idx;
23063 + u16 tx_intr_idx;
23064 + u32 phy_descs;
23065 + u32 *tx_descs;
23067 +} nsx;
23068 +static struct ns83820_private *ns;
23070 +static void phy_intr(struct nic *nic __unused)
23072 + static char *speeds[] =
23073 + { "10", "100", "1000", "1000(?)", "1000F" };
23074 + u32 cfg, new_cfg;
23075 + u32 tbisr, tanar, tanlpar;
23076 + int speed, fullduplex, newlinkstate;
23078 + cfg = readl(ns->base + CFG) ^ SPDSTS_POLARITY;
23079 + if (ns->CFG_cache & CFG_TBI_EN) {
23080 + /* we have an optical transceiver */
23081 + tbisr = readl(ns->base + TBISR);
23082 + tanar = readl(ns->base + TANAR);
23083 + tanlpar = readl(ns->base + TANLPAR);
23084 + dprintf(("phy_intr: tbisr=%hX, tanar=%hX, tanlpar=%hX\n",
23085 + tbisr, tanar, tanlpar));
23087 + if ((fullduplex = (tanlpar & TANAR_FULL_DUP)
23088 + && (tanar & TANAR_FULL_DUP))) {
23090 + /* both of us are full duplex */
23091 + writel(readl(ns->base + TXCFG)
23092 + | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
23093 + ns->base + TXCFG);
23094 + writel(readl(ns->base + RXCFG) | RXCFG_RX_FD,
23095 + ns->base + RXCFG);
23096 + /* Light up full duplex LED */
23097 + writel(readl(ns->base + GPIOR) | GPIOR_GP1_OUT,
23098 + ns->base + GPIOR);
23100 + } else if (((tanlpar & TANAR_HALF_DUP)
23101 + && (tanar & TANAR_HALF_DUP))
23102 + || ((tanlpar & TANAR_FULL_DUP)
23103 + && (tanar & TANAR_HALF_DUP))
23104 + || ((tanlpar & TANAR_HALF_DUP)
23105 + && (tanar & TANAR_FULL_DUP))) {
23107 + /* one or both of us are half duplex */
23108 + writel((readl(ns->base + TXCFG)
23109 + & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
23110 + ns->base + TXCFG);
23111 + writel(readl(ns->base + RXCFG) & ~RXCFG_RX_FD,
23112 + ns->base + RXCFG);
23113 + /* Turn off full duplex LED */
23114 + writel(readl(ns->base + GPIOR) & ~GPIOR_GP1_OUT,
23115 + ns->base + GPIOR);
23118 + speed = 4; /* 1000F */
23120 + } else {
23121 + /* we have a copper transceiver */
23122 + new_cfg =
23123 + ns->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
23125 + if (cfg & CFG_SPDSTS1)
23126 + new_cfg |= CFG_MODE_1000;
23127 + else
23128 + new_cfg &= ~CFG_MODE_1000;
23130 + speed = ((cfg / CFG_SPDSTS0) & 3);
23131 + fullduplex = (cfg & CFG_DUPSTS);
23133 + if (fullduplex)
23134 + new_cfg |= CFG_SB;
23136 + if ((cfg & CFG_LNKSTS) &&
23137 + ((new_cfg ^ ns->CFG_cache) & CFG_MODE_1000)) {
23138 + writel(new_cfg, ns->base + CFG);
23139 + ns->CFG_cache = new_cfg;
23142 + ns->CFG_cache &= ~CFG_SPDSTS;
23143 + ns->CFG_cache |= cfg & CFG_SPDSTS;
23146 + newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
23148 + if (newlinkstate & LINK_UP && ns->linkstate != newlinkstate) {
23149 + printf("link now %s mbps, %s duplex and up.\n",
23150 + speeds[speed], fullduplex ? "full" : "half");
23151 + } else if (newlinkstate & LINK_DOWN
23152 + && ns->linkstate != newlinkstate) {
23153 + printf("link now down.\n");
23155 + ns->linkstate = newlinkstate;
23157 +static void ns83820_set_multicast(struct nic *nic __unused);
23158 +static void ns83820_setup_rx(struct nic *nic)
23160 + unsigned i;
23161 + ns->idle = 1;
23162 + ns->next_rx = 0;
23163 + ns->next_rx_desc = ns->descs;
23164 + ns->next_empty = 0;
23165 + ns->cur_rx = 0;
23168 + for (i = 0; i < NR_RX_DESC; i++) {
23169 + rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]);
23170 + rx_ring[i].bufptr =
23171 + virt_to_le32desc(&rxb[i * REAL_RX_BUF_SIZE]);
23172 + rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE);
23173 + rx_ring[i].extsts = cpu_to_le32(0);
23175 +// No need to wrap the ring
23176 +// rx_ring[i].link = virt_to_le32desc(&rx_ring[0]);
23177 + writel(0, ns->base + RXDP_HI);
23178 + writel(virt_to_le32desc(&rx_ring[0]), ns->base + RXDP);
23180 + dprintf(("starting receiver\n"));
23182 + writel(0x0001, ns->base + CCSR);
23183 + writel(0, ns->base + RFCR);
23184 + writel(0x7fc00000, ns->base + RFCR);
23185 + writel(0xffc00000, ns->base + RFCR);
23187 + ns->up = 1;
23189 + phy_intr(nic);
23191 + /* Okay, let it rip */
23192 + ns->IMR_cache |= ISR_PHY;
23193 + ns->IMR_cache |= ISR_RXRCMP;
23194 + //dev->IMR_cache |= ISR_RXERR;
23195 + //dev->IMR_cache |= ISR_RXOK;
23196 + ns->IMR_cache |= ISR_RXORN;
23197 + ns->IMR_cache |= ISR_RXSOVR;
23198 + ns->IMR_cache |= ISR_RXDESC;
23199 + ns->IMR_cache |= ISR_RXIDLE;
23200 + ns->IMR_cache |= ISR_TXDESC;
23201 + ns->IMR_cache |= ISR_TXIDLE;
23203 + // No reason to enable interupts...
23204 + // writel(ns->IMR_cache, ns->base + IMR);
23205 + // writel(1, ns->base + IER);
23206 + ns83820_set_multicast(nic);
23207 + kick_rx();
23211 +static void ns83820_do_reset(struct nic *nic __unused, u32 which)
23213 + dprintf(("resetting chip...\n"));
23214 + writel(which, ns->base + CR);
23215 + do {
23217 + } while (readl(ns->base + CR) & which);
23218 + dprintf(("okay!\n"));
23221 +static void ns83820_reset(struct nic *nic)
23223 + unsigned i;
23224 + dprintf(("ns83820_reset\n"));
23226 + writel(0, ns->base + PQCR);
23228 + ns83820_setup_rx(nic);
23230 + for (i = 0; i < NR_TX_DESC; i++) {
23231 + tx_ring[i].link = 0;
23232 + tx_ring[i].bufptr = 0;
23233 + tx_ring[i].cmdsts = cpu_to_le32(0);
23234 + tx_ring[i].extsts = cpu_to_le32(0);
23237 + ns->tx_idx = 0;
23238 + ns->tx_done_idx = 0;
23239 + writel(0, ns->base + TXDP_HI);
23240 + return;
23242 +static void ns83820_getmac(struct nic *nic __unused, u8 * mac)
23244 + unsigned i;
23245 + for (i = 0; i < 3; i++) {
23246 + u32 data;
23247 + /* Read from the perfect match memory: this is loaded by
23248 + * the chip from the EEPROM via the EELOAD self test.
23249 + */
23250 + writel(i * 2, ns->base + RFCR);
23251 + data = readl(ns->base + RFDR);
23252 + *mac++ = data;
23253 + *mac++ = data >> 8;
23257 +static void ns83820_set_multicast(struct nic *nic __unused)
23259 + u8 *rfcr = ns->base + RFCR;
23260 + u32 and_mask = 0xffffffff;
23261 + u32 or_mask = 0;
23262 + u32 val;
23264 + /* Support Multicast */
23265 + and_mask &= ~(RFCR_AAU | RFCR_AAM);
23266 + or_mask |= RFCR_AAM;
23267 + val = (readl(rfcr) & and_mask) | or_mask;
23268 + /* Ramit : RFCR Write Fix doc says RFEN must be 0 modify other bits */
23269 + writel(val & ~RFCR_RFEN, rfcr);
23270 + writel(val, rfcr);
23273 +static void ns83820_run_bist(struct nic *nic __unused, const char *name,
23274 + u32 enable, u32 done, u32 fail)
23276 + int timed_out = 0;
23277 + long start;
23278 + u32 status;
23279 + int loops = 0;
23281 + dprintf(("start %s\n", name))
23283 + start = currticks();
23285 + writel(enable, ns->base + PTSCR);
23286 + for (;;) {
23287 + loops++;
23288 + status = readl(ns->base + PTSCR);
23289 + if (!(status & enable))
23290 + break;
23291 + if (status & done)
23292 + break;
23293 + if (status & fail)
23294 + break;
23295 + if ((currticks() - start) >= HZ) {
23296 + timed_out = 1;
23297 + break;
23301 + if (status & fail)
23302 + printf("%s failed! (0x%hX & 0x%hX)\n", name, status, fail);
23303 + else if (timed_out)
23304 + printf("run_bist %s timed out! (%hX)\n", name, status);
23305 + dprintf(("done %s in %d loops\n", name, loops));
23308 +/*************************************
23309 +Check Link
23310 +*************************************/
23311 +static void ns83820_check_intr(struct nic *nic) {
23312 + int i;
23313 + u32 isr = readl(ns->base + ISR);
23314 + if(ISR_PHY & isr)
23315 + phy_intr(nic);
23316 + if(( ISR_RXIDLE | ISR_RXDESC | ISR_RXERR) & isr)
23317 + kick_rx();
23318 + for (i = 0; i < NR_RX_DESC; i++) {
23319 + if (rx_ring[i].cmdsts == CMDSTS_OWN) {
23320 +// rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]);
23321 + rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE);
23325 +/**************************************************************************
23326 +POLL - Wait for a frame
23327 +***************************************************************************/
23328 +static int ns83820_poll(struct nic *nic, int retrieve)
23330 + /* return true if there's an ethernet packet ready to read */
23331 + /* nic->packet should contain data on return */
23332 + /* nic->packetlen should contain length of data */
23333 + u32 cmdsts;
23334 + int entry = ns->cur_rx;
23336 + ns83820_check_intr(nic);
23338 + cmdsts = le32_to_cpu(rx_ring[entry].cmdsts);
23340 + if ( ! ( (CMDSTS_OWN & (cmdsts)) && (cmdsts != (CMDSTS_OWN)) ) )
23341 + return 0;
23343 + if ( ! retrieve ) return 1;
23345 + if (! (CMDSTS_OK & cmdsts) )
23346 + return 0;
23348 + nic->packetlen = cmdsts & 0xffff;
23349 + memcpy(nic->packet,
23350 + rxb + (entry * REAL_RX_BUF_SIZE),
23351 + nic->packetlen);
23352 + // rx_ring[entry].link = 0;
23353 + rx_ring[entry].cmdsts = cpu_to_le32(CMDSTS_OWN);
23355 + ns->cur_rx = ++ns->cur_rx % NR_RX_DESC;
23357 + if (ns->cur_rx == 0) /* We have wrapped the ring */
23358 + kick_rx();
23360 + return 1;
23363 +static inline void kick_tx(struct nic *nic __unused)
23365 + dprintf(("kick_tx\n"));
23366 + writel(CR_TXE, ns->base + CR);
23369 +/**************************************************************************
23370 +TRANSMIT - Transmit a frame
23371 +***************************************************************************/
23372 +static void ns83820_transmit(struct nic *nic, const char *d, /* Destination */
23373 + unsigned int t, /* Type */
23374 + unsigned int s, /* size */
23375 + const char *p)
23376 +{ /* Packet */
23377 + /* send the packet to destination */
23379 + u16 nstype;
23380 + u32 cmdsts, extsts;
23381 + int cur_tx = 0;
23382 + u32 isr = readl(ns->base + ISR);
23383 + if (ISR_TXIDLE & isr)
23384 + kick_tx(nic);
23385 + /* point to the current txb incase multiple tx_rings are used */
23386 + memcpy(txb, d, ETH_ALEN);
23387 + memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
23388 + nstype = htons((u16) t);
23389 + memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
23390 + memcpy(txb + ETH_HLEN, p, s);
23391 + s += ETH_HLEN;
23392 + s &= 0x0FFF;
23393 + while (s < ETH_ZLEN)
23394 + txb[s++] = '\0';
23396 + /* Setup the transmit descriptor */
23397 + extsts = 0;
23398 + extsts |= EXTSTS_UDPPKT;
23400 + tx_ring[cur_tx].bufptr = virt_to_le32desc(&txb);
23401 + tx_ring[cur_tx].extsts = cpu_to_le32(extsts);
23403 + cmdsts = cpu_to_le32(0);
23404 + cmdsts |= cpu_to_le32(CMDSTS_OWN | s);
23405 + tx_ring[cur_tx].cmdsts = cpu_to_le32(cmdsts);
23407 + writel(virt_to_le32desc(&tx_ring[0]), ns->base + TXDP);
23408 + kick_tx(nic);
23411 +/**************************************************************************
23412 +DISABLE - Turn off ethernet interface
23413 +***************************************************************************/
23414 +static void ns83820_disable(struct dev *dev)
23416 + /* put the card in its initial state */
23417 + /* This function serves 3 purposes.
23418 + * This disables DMA and interrupts so we don't receive
23419 + * unexpected packets or interrupts from the card after
23420 + * etherboot has finished.
23421 + * This frees resources so etherboot may use
23422 + * this driver on another interface
23423 + * This allows etherboot to reinitialize the interface
23424 + * if something is something goes wrong.
23425 + */
23426 + /* disable interrupts */
23427 + writel(0, ns->base + IMR);
23428 + writel(0, ns->base + IER);
23429 + readl(ns->base + IER);
23431 + ns->up = 0;
23433 + ns83820_do_reset((struct nic *) dev, CR_RST);
23435 + ns->IMR_cache &=
23436 + ~(ISR_RXOK | ISR_RXDESC | ISR_RXERR | ISR_RXEARLY |
23437 + ISR_RXIDLE);
23438 + writel(ns->IMR_cache, ns->base + IMR);
23440 + /* touch the pci bus... */
23441 + readl(ns->base + IMR);
23443 + /* assumes the transmitter is already disabled and reset */
23444 + writel(0, ns->base + RXDP_HI);
23445 + writel(0, ns->base + RXDP);
23448 +/**************************************************************************
23449 +IRQ - Enable, Disable, or Force interrupts
23450 +***************************************************************************/
23451 +static void ns83820_irq(struct nic *nic __unused, irq_action_t action __unused)
23453 + switch ( action ) {
23454 + case DISABLE :
23455 + break;
23456 + case ENABLE :
23457 + break;
23458 + case FORCE :
23459 + break;
23463 +/**************************************************************************
23464 +PROBE - Look for an adapter, this routine's visible to the outside
23465 +***************************************************************************/
23467 +#define board_found 1
23468 +#define valid_link 0
23469 +static int ns83820_probe(struct dev *dev, struct pci_device *pci)
23471 + struct nic *nic = (struct nic *) dev;
23472 + int sz;
23473 + long addr;
23474 + int using_dac = 0;
23476 + if (pci->ioaddr == 0)
23477 + return 0;
23479 + printf("ns83820.c: Found %s, vendor=0x%hX, device=0x%hX\n",
23480 + pci->name, pci->vendor, pci->dev_id);
23482 + /* point to private storage */
23483 + ns = &nsx;
23485 + adjust_pci_device(pci);
23487 + addr = pci_bar_start(pci, PCI_BASE_ADDRESS_1);
23488 + sz = pci_bar_size(pci, PCI_BASE_ADDRESS_1);
23490 + ns->base = ioremap(addr, (1UL << 12));
23491 +// ns->base = ioremap(addr, sz);
23493 + if (!ns->base)
23494 + return 0;
23496 + nic->irqno = 0;
23497 + nic->ioaddr = pci->ioaddr & ~3;
23499 + /* disable interrupts */
23500 + writel(0, ns->base + IMR);
23501 + writel(0, ns->base + IER);
23502 + readl(ns->base + IER);
23504 + ns->IMR_cache = 0;
23506 + ns83820_do_reset(nic, CR_RST);
23508 + /* Must reset the ram bist before running it */
23509 + writel(PTSCR_RBIST_RST, ns->base + PTSCR);
23510 + ns83820_run_bist(nic, "sram bist", PTSCR_RBIST_EN,
23511 + PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL);
23512 + ns83820_run_bist(nic, "eeprom bist", PTSCR_EEBIST_EN, 0,
23513 + PTSCR_EEBIST_FAIL);
23514 + ns83820_run_bist(nic, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
23516 + /* I love config registers */
23517 + ns->CFG_cache = readl(ns->base + CFG);
23519 + if ((ns->CFG_cache & CFG_PCI64_DET)) {
23520 + printf("%s: detected 64 bit PCI data bus.\n", pci->name);
23521 + /*dev->CFG_cache |= CFG_DATA64_EN; */
23522 + if (!(ns->CFG_cache & CFG_DATA64_EN))
23523 + printf
23524 + ("%s: EEPROM did not enable 64 bit bus. Disabled.\n",
23525 + pci->name);
23526 + } else
23527 + ns->CFG_cache &= ~(CFG_DATA64_EN);
23529 + ns->CFG_cache &= (CFG_TBI_EN | CFG_MRM_DIS | CFG_MWI_DIS |
23530 + CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 |
23531 + CFG_M64ADDR);
23532 + ns->CFG_cache |=
23533 + CFG_PINT_DUPSTS | CFG_PINT_LNKSTS | CFG_PINT_SPDSTS |
23534 + CFG_EXTSTS_EN | CFG_EXD | CFG_PESEL;
23535 + ns->CFG_cache |= CFG_REQALG;
23536 + ns->CFG_cache |= CFG_POW;
23537 + ns->CFG_cache |= CFG_TMRTEST;
23539 + /* When compiled with 64 bit addressing, we must always enable
23540 + * the 64 bit descriptor format.
23541 + */
23542 +#ifdef USE_64BIT_ADDR
23543 + ns->CFG_cache |= CFG_M64ADDR;
23544 +#endif
23546 +//FIXME: Enable section on dac or remove this
23547 + if (using_dac)
23548 + ns->CFG_cache |= CFG_T64ADDR;
23550 + /* Big endian mode does not seem to do what the docs suggest */
23551 + ns->CFG_cache &= ~CFG_BEM;
23553 + /* setup optical transceiver if we have one */
23554 + if (ns->CFG_cache & CFG_TBI_EN) {
23555 + dprintf(("%s: enabling optical transceiver\n", pci->name));
23556 + writel(readl(ns->base + GPIOR) | 0x3e8, ns->base + GPIOR);
23558 + /* setup auto negotiation feature advertisement */
23559 + writel(readl(ns->base + TANAR)
23560 + | TANAR_HALF_DUP | TANAR_FULL_DUP,
23561 + ns->base + TANAR);
23563 + /* start auto negotiation */
23564 + writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN,
23565 + ns->base + TBICR);
23566 + writel(TBICR_MR_AN_ENABLE, ns->base + TBICR);
23567 + ns->linkstate = LINK_AUTONEGOTIATE;
23569 + ns->CFG_cache |= CFG_MODE_1000;
23571 + writel(ns->CFG_cache, ns->base + CFG);
23572 + dprintf(("CFG: %hX\n", ns->CFG_cache));
23574 + /* FIXME: reset_phy is defaulted to 0, should we reset anyway? */
23575 + if (reset_phy) {
23576 + dprintf(("%s: resetting phy\n", pci->name));
23577 + writel(ns->CFG_cache | CFG_PHY_RST, ns->base + CFG);
23578 + writel(ns->CFG_cache, ns->base + CFG);
23580 +#if 0 /* Huh? This sets the PCI latency register. Should be done via
23581 + * the PCI layer. FIXME.
23582 + */
23583 + if (readl(dev->base + SRR))
23584 + writel(readl(dev->base + 0x20c) | 0xfe00,
23585 + dev->base + 0x20c);
23586 +#endif
23588 + /* Note! The DMA burst size interacts with packet
23589 + * transmission, such that the largest packet that
23590 + * can be transmitted is 8192 - FLTH - burst size.
23591 + * If only the transmit fifo was larger...
23592 + */
23593 + /* Ramit : 1024 DMA is not a good idea, it ends up banging
23594 + * some DELL and COMPAQ SMP systems */
23595 + writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA512
23596 + | ((1600 / 32) * 0x100), ns->base + TXCFG);
23598 + /* Set Rx to full duplex, don't accept runt, errored, long or length
23599 + * range errored packets. Use 512 byte DMA.
23600 + */
23601 + /* Ramit : 1024 DMA is not a good idea, it ends up banging
23602 + * some DELL and COMPAQ SMP systems
23603 + * Turn on ALP, only we are accpeting Jumbo Packets */
23604 + writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
23605 + | RXCFG_STRIPCRC
23606 + //| RXCFG_ALP
23607 + | (RXCFG_MXDMA512) | 0, ns->base + RXCFG);
23609 + /* Disable priority queueing */
23610 + writel(0, ns->base + PQCR);
23612 + /* Enable IP checksum validation and detetion of VLAN headers.
23613 + * Note: do not set the reject options as at least the 0x102
23614 + * revision of the chip does not properly accept IP fragments
23615 + * at least for UDP.
23616 + */
23617 + /* Ramit : Be sure to turn on RXCFG_ARP if VLAN's are enabled, since
23618 + * the MAC it calculates the packetsize AFTER stripping the VLAN
23619 + * header, and if a VLAN Tagged packet of 64 bytes is received (like
23620 + * a ping with a VLAN header) then the card, strips the 4 byte VLAN
23621 + * tag and then checks the packet size, so if RXCFG_ARP is not enabled,
23622 + * it discrards it!. These guys......
23623 + */
23624 + writel(VRCR_IPEN | VRCR_VTDEN, ns->base + VRCR);
23626 + /* Enable per-packet TCP/UDP/IP checksumming */
23627 + writel(VTCR_PPCHK, ns->base + VTCR);
23629 + /* Ramit : Enable async and sync pause frames */
23630 +// writel(0, ns->base + PCR);
23631 + writel((PCR_PS_MCAST | PCR_PS_DA | PCR_PSEN | PCR_FFLO_4K |
23632 + PCR_FFHI_8K | PCR_STLO_4 | PCR_STHI_8 | PCR_PAUSE_CNT),
23633 + ns->base + PCR);
23635 + /* Disable Wake On Lan */
23636 + writel(0, ns->base + WCSR);
23638 + ns83820_getmac(nic, nic->node_addr);
23639 + printf("%! at ioaddr 0x%hX, ", nic->node_addr, ns->base);
23641 + if (using_dac) {
23642 + dprintf(("%s: using 64 bit addressing.\n", pci->name));
23645 + dprintf(("%s: DP83820 %d.%d: %! io=0x%hX\n",
23646 + pci->name,
23647 + (unsigned) readl(ns->base + SRR) >> 8,
23648 + (unsigned) readl(ns->base + SRR) & 0xff,
23649 + nic->node_addr, pci->ioaddr));
23651 +#ifdef PHY_CODE_IS_FINISHED
23652 + ns83820_probe_phy(dev);
23653 +#endif
23655 + ns83820_reset(nic);
23656 + /* point to NIC specific routines */
23657 + dev->disable = ns83820_disable;
23658 + nic->poll = ns83820_poll;
23659 + nic->transmit = ns83820_transmit;
23660 + nic->irq = ns83820_irq;
23661 + return 1;
23664 +static struct pci_id ns83820_nics[] = {
23665 + PCI_ROM(0x100b, 0x0022, "ns83820", "National Semiconductor 83820"),
23668 +struct pci_driver ns83820_driver = {
23669 + .type = NIC_DRIVER,
23670 + .name = "NS83820/PCI",
23671 + .probe = ns83820_probe,
23672 + .ids = ns83820_nics,
23673 + .id_count = sizeof(ns83820_nics) / sizeof(ns83820_nics[0]),
23674 + .class = 0,
23676 Index: b/netboot/ns8390.c
23677 ===================================================================
23678 --- a/netboot/ns8390.c
23679 +++ b/netboot/ns8390.c
23680 @@ -13,11 +13,15 @@
23681 the proper functioning of this software, nor do the authors assume any
23682 responsibility for damages incurred with its use.
23684 +Multicast support added by Timothy Legge (timlegge@users.sourceforge.net) 09/28/2003
23685 +Relocation support added by Ken Yap (ken_yap@users.sourceforge.net) 28/12/02
23686 3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94
23687 SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
23688 3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98
23689 RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99
23690 parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
23691 +SMC8416 PIO support added by Andrew Bettison (andrewb@zip.com.au) on 4/3/02
23692 + based on the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
23694 **************************************************************************/
23696 @@ -26,10 +30,16 @@
23697 #include "ns8390.h"
23698 #ifdef INCLUDE_NS8390
23699 #include "pci.h"
23700 +#else
23701 +#include "isa.h"
23702 #endif
23703 -#include "cards.h"
23705 -static unsigned char eth_vendor, eth_flags, eth_laar;
23706 +typedef int Address;
23708 +static unsigned char eth_vendor, eth_flags;
23709 +#ifdef INCLUDE_WD
23710 +static unsigned char eth_laar;
23711 +#endif
23712 static unsigned short eth_nic_base, eth_asic_base;
23713 static unsigned char eth_memsize, eth_rx_start, eth_tx_start;
23714 static Address eth_bmem, eth_rmem;
23715 @@ -66,6 +76,7 @@
23716 #endif
23718 #if defined(INCLUDE_WD)
23719 +#define ASIC_PIO WD_IAR
23720 #define eth_probe wd_probe
23721 #if defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
23722 Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
23723 @@ -101,13 +112,16 @@
23724 #endif
23725 #endif
23727 -#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
23728 +#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
23729 /**************************************************************************
23730 ETH_PIO_READ - Read a frame via Programmed I/O
23731 **************************************************************************/
23732 static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
23734 - if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
23735 +#ifdef INCLUDE_WD
23736 + outb(src & 0xff, eth_asic_base + WD_GP2);
23737 + outb(src >> 8, eth_asic_base + WD_GP2);
23738 +#else
23739 outb(D8390_COMMAND_RD2 |
23740 D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
23741 outb(cnt, eth_nic_base + D8390_P0_RBCR0);
23742 @@ -122,9 +136,10 @@
23743 outb(src >> 8, eth_asic_base + _3COM_DAMSB);
23744 outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
23745 #endif
23746 +#endif
23748 if (eth_flags & FLAG_16BIT)
23749 - cnt >>= 1;
23750 + cnt = (cnt + 1) >> 1;
23752 while(cnt--) {
23753 #ifdef INCLUDE_3C503
23754 @@ -153,7 +168,10 @@
23755 #ifdef COMPEX_RL2000_FIX
23756 unsigned int x;
23757 #endif /* COMPEX_RL2000_FIX */
23758 - if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
23759 +#ifdef INCLUDE_WD
23760 + outb(dst & 0xff, eth_asic_base + WD_GP2);
23761 + outb(dst >> 8, eth_asic_base + WD_GP2);
23762 +#else
23763 outb(D8390_COMMAND_RD2 |
23764 D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
23765 outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
23766 @@ -170,9 +188,10 @@
23768 outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR);
23769 #endif
23770 +#endif
23772 if (eth_flags & FLAG_16BIT)
23773 - cnt >>= 1;
23774 + cnt = (cnt + 1) >> 1;
23776 while(cnt--)
23778 @@ -201,17 +220,40 @@
23779 if (x >= COMPEX_RL2000_TRIES)
23780 printf("Warning: Compex RL2000 aborted wait!\n");
23781 #endif /* COMPEX_RL2000_FIX */
23782 +#ifndef INCLUDE_WD
23783 while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
23784 != D8390_ISR_RDC);
23785 #endif
23786 +#endif
23788 #else
23789 /**************************************************************************
23790 ETH_PIO_READ - Dummy routine when NE2000 not compiled in
23791 **************************************************************************/
23792 -static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {}
23793 +static void eth_pio_read(unsigned int src __unused, unsigned char *dst __unused, unsigned int cnt __unused) {}
23794 #endif
23797 +/**************************************************************************
23798 +enable_multycast - Enable Multicast
23799 +**************************************************************************/
23800 +static void enable_multicast(unsigned short eth_nic_base)
23802 + unsigned char mcfilter[8];
23803 + int i;
23804 + memset(mcfilter, 0xFF, 8);
23805 + outb(4, eth_nic_base+D8390_P0_RCR);
23806 + outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS1, eth_nic_base + D8390_P0_COMMAND);
23807 + for(i=0;i<8;i++)
23809 + outb(mcfilter[i], eth_nic_base + 8 + i);
23810 + if(inb(eth_nic_base + 8 + i)!=mcfilter[i])
23811 + printf("Error SMC 83C690 Multicast filter read/write mishap %d\n",i);
23813 + outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS0, eth_nic_base + D8390_P0_COMMAND);
23814 + outb(4 | 0x08, eth_nic_base+D8390_P0_RCR);
23817 /**************************************************************************
23818 NS8390_RESET - Reset adapter
23819 **************************************************************************/
23820 @@ -238,7 +280,14 @@
23821 outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
23822 outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
23823 #ifdef INCLUDE_WD
23824 - if (eth_flags & FLAG_790) outb(0, eth_nic_base + 0x09);
23825 + if (eth_flags & FLAG_790) {
23826 +#ifdef WD_790_PIO
23827 + outb(0x10, eth_asic_base + 0x06); /* disable interrupts, enable PIO */
23828 + outb(0x01, eth_nic_base + 0x09); /* enable ring read auto-wrap */
23829 +#else
23830 + outb(0, eth_nic_base + 0x09);
23831 +#endif
23833 #endif
23834 outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
23835 outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
23836 @@ -266,8 +315,10 @@
23837 outb(D8390_COMMAND_PS0 |
23838 D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
23839 outb(0xFF, eth_nic_base+D8390_P0_ISR);
23840 - outb(0, eth_nic_base+D8390_P0_TCR);
23841 - outb(4, eth_nic_base+D8390_P0_RCR); /* allow broadcast frames */
23842 + outb(0, eth_nic_base+D8390_P0_TCR); /* transmitter on */
23843 + outb(4, eth_nic_base+D8390_P0_RCR); /* allow rx broadcast frames */
23845 + enable_multicast(eth_nic_base);
23847 #ifdef INCLUDE_3C503
23849 @@ -281,7 +332,7 @@
23850 #endif
23853 -static int ns8390_poll(struct nic *nic);
23854 +static int ns8390_poll(struct nic *nic, int retrieve);
23856 #ifndef INCLUDE_3C503
23857 /**************************************************************************
23858 @@ -324,7 +375,7 @@
23860 /* clear the RX ring, acknowledge overrun interrupt */
23861 eth_drain_receiver = 1;
23862 - while (ns8390_poll(nic))
23863 + while (ns8390_poll(nic, 1))
23864 /* Nothing */;
23865 eth_drain_receiver = 0;
23866 outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
23867 @@ -344,50 +395,54 @@
23868 unsigned int s, /* size */
23869 const char *p) /* Packet */
23871 +#if defined(INCLUDE_3C503) || (defined(INCLUDE_WD) && ! defined(WD_790_PIO))
23872 + Address eth_vmem = bus_to_virt(eth_bmem);
23873 +#endif
23874 #ifdef INCLUDE_3C503
23875 if (!(eth_flags & FLAG_PIO)) {
23876 - memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */
23877 - memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
23878 - *((char *)eth_bmem+12) = t>>8; /* type */
23879 - *((char *)eth_bmem+13) = t;
23880 - memcpy((char *)eth_bmem+ETH_HLEN, p, s);
23881 + memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */
23882 + memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
23883 + *((char *)eth_vmem+12) = t>>8; /* type */
23884 + *((char *)eth_vmem+13) = t;
23885 + memcpy((char *)eth_vmem+ETH_HLEN, p, s);
23886 s += ETH_HLEN;
23887 - while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
23888 + while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
23890 #endif
23892 #ifdef INCLUDE_WD
23893 - /* Memory interface */
23894 if (eth_flags & FLAG_16BIT) {
23895 outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
23896 inb(0x84);
23898 +#ifndef WD_790_PIO
23899 + /* Memory interface */
23900 if (eth_flags & FLAG_790) {
23901 outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
23902 inb(0x84);
23904 inb(0x84);
23905 - memcpy((char *)eth_bmem, d, ETH_ALEN); /* dst */
23906 - memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
23907 - *((char *)eth_bmem+12) = t>>8; /* type */
23908 - *((char *)eth_bmem+13) = t;
23909 - memcpy((char *)eth_bmem+ETH_HLEN, p, s);
23910 + memcpy((char *)eth_vmem, d, ETH_ALEN); /* dst */
23911 + memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
23912 + *((char *)eth_vmem+12) = t>>8; /* type */
23913 + *((char *)eth_vmem+13) = t;
23914 + memcpy((char *)eth_vmem+ETH_HLEN, p, s);
23915 s += ETH_HLEN;
23916 - while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
23917 + while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
23918 if (eth_flags & FLAG_790) {
23919 outb(0, eth_asic_base + WD_MSR);
23920 inb(0x84);
23922 - if (eth_flags & FLAG_16BIT) {
23923 - outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
23924 - inb(0x84);
23926 +#else
23927 + inb(0x84);
23928 +#endif
23929 #endif
23931 #if defined(INCLUDE_3C503)
23932 - if (eth_flags & FLAG_PIO) {
23933 + if (eth_flags & FLAG_PIO)
23934 #endif
23935 -#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
23936 +#if defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
23938 /* Programmed I/O */
23939 unsigned short type;
23940 type = (t >> 8) | (t << 8);
23941 @@ -398,12 +453,16 @@
23942 eth_pio_write(p, (eth_tx_start<<8)+ETH_HLEN, s);
23943 s += ETH_HLEN;
23944 if (s < ETH_ZLEN) s = ETH_ZLEN;
23946 #endif
23947 #if defined(INCLUDE_3C503)
23949 #endif
23951 #ifdef INCLUDE_WD
23952 + if (eth_flags & FLAG_16BIT) {
23953 + outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
23954 + inb(0x84);
23956 if (eth_flags & FLAG_790)
23957 outb(D8390_COMMAND_PS0 |
23958 D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
23959 @@ -428,7 +487,7 @@
23960 /**************************************************************************
23961 NS8390_POLL - Wait for a frame
23962 **************************************************************************/
23963 -static int ns8390_poll(struct nic *nic)
23964 +static int ns8390_poll(struct nic *nic, int retrieve)
23966 int ret = 0;
23967 unsigned char rstat, curr, next;
23968 @@ -453,22 +512,27 @@
23969 outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
23970 if (curr >= eth_memsize) curr=eth_rx_start;
23971 if (curr == next) return(0);
23973 + if ( ! retrieve ) return 1;
23975 #ifdef INCLUDE_WD
23976 if (eth_flags & FLAG_16BIT) {
23977 outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
23978 inb(0x84);
23980 +#ifndef WD_790_PIO
23981 if (eth_flags & FLAG_790) {
23982 outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
23983 inb(0x84);
23985 +#endif
23986 inb(0x84);
23987 #endif
23988 pktoff = next << 8;
23989 if (eth_flags & FLAG_PIO)
23990 eth_pio_read(pktoff, (char *)&pkthdr, 4);
23991 else
23992 - memcpy(&pkthdr, (char *)eth_rmem + pktoff, 4);
23993 + memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4);
23994 pktoff += sizeof(pkthdr);
23995 /* incoming length includes FCS so must sub 4 */
23996 len = pkthdr.len - 4;
23997 @@ -486,7 +550,7 @@
23998 if (eth_flags & FLAG_PIO)
23999 eth_pio_read(pktoff, p, frag);
24000 else
24001 - memcpy(p, (char *)eth_rmem + pktoff, frag);
24002 + memcpy(p, bus_to_virt(eth_rmem + pktoff), frag);
24003 pktoff = eth_rx_start << 8;
24004 p += frag;
24005 len -= frag;
24006 @@ -495,14 +559,16 @@
24007 if (eth_flags & FLAG_PIO)
24008 eth_pio_read(pktoff, p, len);
24009 else
24010 - memcpy(p, (char *)eth_rmem + pktoff, len);
24011 + memcpy(p, bus_to_virt(eth_rmem + pktoff), len);
24012 ret = 1;
24014 #ifdef INCLUDE_WD
24015 +#ifndef WD_790_PIO
24016 if (eth_flags & FLAG_790) {
24017 outb(0, eth_asic_base + WD_MSR);
24018 inb(0x84);
24020 +#endif
24021 if (eth_flags & FLAG_16BIT) {
24022 outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
24023 inb(0x84);
24024 @@ -519,31 +585,56 @@
24025 /**************************************************************************
24026 NS8390_DISABLE - Turn off adapter
24027 **************************************************************************/
24028 -static void ns8390_disable(struct nic *nic)
24029 +static void ns8390_disable(struct dev *dev)
24031 + struct nic *nic = (struct nic *)dev;
24032 + /* reset and disable merge */
24033 + ns8390_reset(nic);
24036 +/**************************************************************************
24037 +NS8390_IRQ - Enable, Disable, or Force interrupts
24038 +**************************************************************************/
24039 +static void ns8390_irq(struct nic *nic __unused, irq_action_t action __unused)
24041 + switch ( action ) {
24042 + case DISABLE :
24043 + break;
24044 + case ENABLE :
24045 + break;
24046 + case FORCE :
24047 + break;
24051 /**************************************************************************
24052 ETH_PROBE - Look for an adapter
24053 **************************************************************************/
24054 #ifdef INCLUDE_NS8390
24055 -struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs,
24056 - struct pci_device *pci)
24057 +static int eth_probe (struct dev *dev, struct pci_device *pci)
24058 #else
24059 -struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
24060 +static int eth_probe (struct dev *dev, unsigned short *probe_addrs __unused)
24061 #endif
24063 + struct nic *nic = (struct nic *)dev;
24064 int i;
24065 - struct wd_board *brd;
24066 - unsigned short chksum;
24067 - unsigned char c;
24068 +#ifdef INCLUDE_NS8390
24069 + unsigned short pci_probe_addrs[] = { pci->ioaddr, 0 };
24070 + unsigned short *probe_addrs = pci_probe_addrs;
24071 +#endif
24072 eth_vendor = VENDOR_NONE;
24073 eth_drain_receiver = 0;
24075 + nic->irqno = 0;
24077 #ifdef INCLUDE_WD
24079 /******************************************************************
24080 Search for WD/SMC cards
24081 ******************************************************************/
24082 + struct wd_board *brd;
24083 + unsigned short chksum;
24084 + unsigned char c;
24085 for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
24086 eth_asic_base += 0x20) {
24087 chksum = 0;
24088 @@ -560,6 +651,9 @@
24089 /* We've found a board */
24090 eth_vendor = VENDOR_WD;
24091 eth_nic_base = eth_asic_base + WD_NIC_ADDR;
24093 + nic->ioaddr = eth_nic_base;
24095 c = inb(eth_asic_base+WD_BID); /* Get board id */
24096 for (brd = wd_boards; brd->name; brd++)
24097 if (brd->id == c) break;
24098 @@ -582,8 +676,9 @@
24099 } else
24100 eth_bmem = WD_DEFAULT_MEM;
24101 if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
24102 - *((unsigned int *)(eth_bmem + 8192)) = (unsigned int)0;
24103 - if (*((unsigned int *)(eth_bmem + 8192))) {
24104 + /* from Linux driver, 8416BT detects as 8216 sometimes */
24105 + unsigned int addr = inb(eth_asic_base + 0xb);
24106 + if (((addr >> 4) & 3) == 0) {
24107 brd += 2;
24108 eth_memsize = brd->memsize;
24110 @@ -592,19 +687,27 @@
24111 for (i=0; i<ETH_ALEN; i++) {
24112 nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR);
24114 - printf("\n%s base %#hx, memory %#hx, addr %!\n",
24115 - brd->name, eth_asic_base, eth_bmem, nic->node_addr);
24116 + printf("\n%s base %#hx", brd->name, eth_asic_base);
24117 if (eth_flags & FLAG_790) {
24118 +#ifdef WD_790_PIO
24119 + printf(", PIO mode, addr %!\n", nic->node_addr);
24120 + eth_bmem = 0;
24121 + eth_flags |= FLAG_PIO; /* force PIO mode */
24122 + outb(0, eth_asic_base+WD_MSR);
24123 +#else
24124 + printf(", memory %#x, addr %!\n", eth_bmem, nic->node_addr);
24125 outb(WD_MSR_MENB, eth_asic_base+WD_MSR);
24126 outb((inb(eth_asic_base+0x04) |
24127 0x80), eth_asic_base+0x04);
24128 - outb((((unsigned)eth_bmem >> 13) & 0x0F) |
24129 - (((unsigned)eth_bmem >> 11) & 0x40) |
24130 + outb(((unsigned)(eth_bmem >> 13) & 0x0F) |
24131 + ((unsigned)(eth_bmem >> 11) & 0x40) |
24132 (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
24133 outb((inb(eth_asic_base+0x04) &
24134 ~0x80), eth_asic_base+0x04);
24135 +#endif
24136 } else {
24137 - outb((((unsigned)eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
24138 + printf(", memory %#x, addr %!\n", eth_bmem, nic->node_addr);
24139 + outb(((unsigned)(eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
24141 if (eth_flags & FLAG_16BIT) {
24142 if (eth_flags & FLAG_790) {
24143 @@ -624,8 +727,14 @@
24145 inb(0x84);
24148 #endif
24149 #ifdef INCLUDE_3C503
24150 +#ifdef T503_AUI
24151 + nic->flags = 1; /* aui */
24152 +#else
24153 + nic->flags = 0; /* no aui */
24154 +#endif
24155 /******************************************************************
24156 Search for 3Com 3c503 if no WD/SMC cards
24157 ******************************************************************/
24158 @@ -708,11 +817,12 @@
24159 /* Get our ethernet address */
24161 outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR);
24162 + nic->ioaddr = eth_nic_base;
24163 printf("\n3Com 3c503 base %#hx, ", eth_nic_base);
24164 if (eth_flags & FLAG_PIO)
24165 printf("PIO mode");
24166 else
24167 - printf("memory %#hx", eth_bmem);
24168 + printf("memory %#x", eth_bmem);
24169 for (i=0; i<ETH_ALEN; i++) {
24170 nic->node_addr[i] = inb(eth_nic_base+i);
24172 @@ -734,9 +844,9 @@
24175 if (!(eth_flags & FLAG_PIO)) {
24176 - memset((char *)eth_bmem, 0, 0x2000);
24177 + memset(bus_to_virt(eth_bmem), 0, 0x2000);
24178 for(i = 0; i < 0x2000; ++i)
24179 - if (*(((char *)eth_bmem)+i)) {
24180 + if (*((char *)(bus_to_virt(eth_bmem+i)))) {
24181 printf ("Failed to clear 3c503 shared mem.\n");
24182 return (0);
24184 @@ -749,9 +859,11 @@
24186 #endif
24187 #if defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
24189 /******************************************************************
24190 Search for NE1000/2000 if no WD/SMC or 3com cards
24191 ******************************************************************/
24192 + unsigned char c;
24193 if (eth_vendor == VENDOR_NONE) {
24194 char romdata[16], testbuf[32];
24195 int idx;
24196 @@ -810,23 +922,94 @@
24197 for (i=0; i<ETH_ALEN; i++) {
24198 nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
24200 + nic->ioaddr = eth_nic_base;
24201 printf("\nNE%c000 base %#hx, addr %!\n",
24202 (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
24203 nic->node_addr);
24206 #endif
24207 if (eth_vendor == VENDOR_NONE)
24208 return(0);
24209 if (eth_vendor != VENDOR_3COM)
24210 eth_rmem = eth_bmem;
24211 ns8390_reset(nic);
24212 - nic->reset = ns8390_reset;
24213 - nic->poll = ns8390_poll;
24215 + dev->disable = ns8390_disable;
24216 + nic->poll = ns8390_poll;
24217 nic->transmit = ns8390_transmit;
24218 - nic->disable = ns8390_disable;
24219 - return(nic);
24220 + nic->irq = ns8390_irq;
24222 + /* Based on PnP ISA map */
24223 +#ifdef INCLUDE_WD
24224 + dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
24225 + dev->devid.device_id = htons(0x812a);
24226 +#endif
24227 +#ifdef INCLUDE_3C503
24228 + dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
24229 + dev->devid.device_id = htons(0x80f3);
24230 +#endif
24231 +#ifdef INCLUDE_NE
24232 + dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
24233 + dev->devid.device_id = htons(0x80d6);
24234 +#endif
24235 + return 1;
24238 +#ifdef INCLUDE_WD
24239 +static struct isa_driver wd_driver __isa_driver = {
24240 + .type = NIC_DRIVER,
24241 + .name = "WD",
24242 + .probe = wd_probe,
24243 + .ioaddrs = 0,
24245 +#endif
24247 +#ifdef INCLUDE_3C503
24248 +static struct isa_driver t503_driver __isa_driver = {
24249 + .type = NIC_DRIVER,
24250 + .name = "3C503",
24251 + .probe = t503_probe,
24252 + .ioaddrs = 0,
24254 +#endif
24256 +#ifdef INCLUDE_NE
24257 +static struct isa_driver ne_driver __isa_driver = {
24258 + .type = NIC_DRIVER,
24259 + .name = "NE*000",
24260 + .probe = ne_probe,
24261 + .ioaddrs = 0,
24263 +#endif
24265 +#ifdef INCLUDE_NS8390
24266 +static struct pci_id nepci_nics[] = {
24267 +/* A few NE2000 PCI clones, list not exhaustive */
24268 +PCI_ROM(0x10ec, 0x8029, "rtl8029", "Realtek 8029"),
24269 +PCI_ROM(0x1186, 0x0300, "dlink-528", "D-Link DE-528"),
24270 +PCI_ROM(0x1050, 0x0940, "winbond940", "Winbond NE2000-PCI"), /* Winbond 86C940 / 89C940 */
24271 +PCI_ROM(0x1050, 0x5a5a, "winbond940f", "Winbond W89c940F"), /* Winbond 89C940F */
24272 +PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000"),
24273 +PCI_ROM(0x8e2e, 0x3000, "ktiet32p2", "KTI ET32P2"),
24274 +PCI_ROM(0x4a14, 0x5000, "nv5000sc", "NetVin NV5000SC"),
24275 +PCI_ROM(0x12c3, 0x0058, "holtek80232", "Holtek HT80232"),
24276 +PCI_ROM(0x12c3, 0x5598, "holtek80229", "Holtek HT80229"),
24277 +PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34"),
24278 +PCI_ROM(0x1106, 0x0926, "via86c926", "Via 86c926"),
24281 +struct pci_driver nepci_driver = {
24282 + .type = NIC_DRIVER,
24283 + .name = "NE2000/PCI",
24284 + .probe = nepci_probe,
24285 + .ids = nepci_nics,
24286 + .id_count = sizeof(nepci_nics)/sizeof(nepci_nics[0]),
24287 + .class = 0,
24290 +#endif /* INCLUDE_NS8390 */
24293 * Local variables:
24294 * c-basic-offset: 8
24295 Index: b/netboot/osdep.h
24296 ===================================================================
24297 --- a/netboot/osdep.h
24298 +++ b/netboot/osdep.h
24299 @@ -1,94 +1,18 @@
24300 -#ifndef __OSDEP_H__
24301 -#define __OSDEP_H__
24302 +#ifndef _OSDEP_H
24303 +#define _OSDEP_H
24306 - * This program is free software; you can redistribute it and/or
24307 - * modify it under the terms of the GNU General Public License as
24308 - * published by the Free Software Foundation; either version 2, or (at
24309 - * your option) any later version.
24310 - */
24311 +#define __unused __attribute__((unused))
24312 +#define __aligned __attribute__((aligned(16)))
24314 -#define __LITTLE_ENDIAN /* x86 */
24316 -/* Taken from /usr/include/linux/hfs_sysdep.h */
24317 -#if defined(__BIG_ENDIAN)
24318 -# if !defined(__constant_htonl)
24319 -# define __constant_htonl(x) (x)
24320 -# endif
24321 -# if !defined(__constant_htons)
24322 -# define __constant_htons(x) (x)
24323 -# endif
24324 -#elif defined(__LITTLE_ENDIAN)
24325 -# if !defined(__constant_htonl)
24326 -# define __constant_htonl(x) \
24327 - ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
24328 - (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
24329 - (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
24330 - (((unsigned long int)(x) & 0xff000000U) >> 24)))
24331 -# endif
24332 -# if !defined(__constant_htons)
24333 -# define __constant_htons(x) \
24334 - ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
24335 - (((unsigned short int)(x) & 0xff00) >> 8)))
24336 -# endif
24337 -#else
24338 -# error "Don't know if bytes are big- or little-endian!"
24339 -#endif
24341 -#define ntohl(x) \
24342 -(__builtin_constant_p(x) ? \
24343 - __constant_htonl((x)) : \
24344 - __swap32(x))
24345 -#define htonl(x) \
24346 -(__builtin_constant_p(x) ? \
24347 - __constant_htonl((x)) : \
24348 - __swap32(x))
24349 -#define ntohs(x) \
24350 -(__builtin_constant_p(x) ? \
24351 - __constant_htons((x)) : \
24352 - __swap16(x))
24353 -#define htons(x) \
24354 -(__builtin_constant_p(x) ? \
24355 - __constant_htons((x)) : \
24356 - __swap16(x))
24358 -static inline unsigned long int __swap32(unsigned long int x)
24360 - __asm__("xchgb %b0,%h0\n\t"
24361 - "rorl $16,%0\n\t"
24362 - "xchgb %b0,%h0"
24363 - : "=q" (x)
24364 - : "0" (x));
24365 - return x;
24368 -static inline unsigned short int __swap16(unsigned short int x)
24370 - __asm__("xchgb %b0,%h0"
24371 - : "=q" (x)
24372 - : "0" (x));
24373 - return x;
24376 -/* Make routines available to all */
24377 -#define swap32(x) __swap32(x)
24378 -#define swap16(x) __swap16(x)
24380 -#include "linux-asm-io.h"
24382 -typedef unsigned long Address;
24383 +#include "io.h"
24384 +#include "byteswap.h"
24385 +#include "latch.h"
24387 /* ANSI prototyping macro */
24388 #ifdef __STDC__
24389 -#define P(x) x
24390 +# define P(x) x
24391 #else
24392 -#define P(x) ()
24393 +# define P(x) ()
24394 #endif
24396 #endif
24399 - * Local variables:
24400 - * c-basic-offset: 8
24401 - * End:
24402 - */
24403 Index: b/netboot/otulip.c
24404 ===================================================================
24405 --- a/netboot/otulip.c
24406 +++ /dev/null
24407 @@ -1,374 +0,0 @@
24409 - Etherboot DEC Tulip driver
24410 - adapted by Ken Yap from
24412 - FreeBSD netboot DEC 21143 driver
24414 - Author: David Sharp
24415 - date: Nov/98
24417 - Known to work on DEC DE500 using 21143-PC chipset.
24418 - Even on cards with the same chipset there can be
24419 - incompatablity problems with the way media selection
24420 - and status LED settings are done. See comments below.
24422 - Some code fragments were taken from verious places,
24423 - Ken Yap's etherboot, FreeBSD's if_de.c, and various
24424 - Linux related files. DEC's manuals for the 21143 and
24425 - SROM format were very helpful. The Linux de driver
24426 - development page has a number of links to useful
24427 - related information. Have a look at:
24428 - ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
24432 -#include "etherboot.h"
24433 -#include "nic.h"
24434 -#include "pci.h"
24435 -#include "cards.h"
24436 -#include "otulip.h"
24438 -static unsigned short vendor, dev_id;
24439 -static unsigned short ioaddr;
24440 -static unsigned int *membase;
24441 -static unsigned char srom[1024];
24443 -#define BUFLEN 1536 /* must be longword divisable */
24444 - /* buffers must be longword aligned */
24446 -/* transmit descriptor and buffer */
24447 -static struct txdesc txd;
24449 -/* receive descriptor(s) and buffer(s) */
24450 -#define NRXD 4
24451 -static struct rxdesc rxd[NRXD];
24452 -static int rxd_tail = 0;
24453 -#ifdef USE_LOWMEM_BUFFER
24454 -#define rxb ((char *)0x10000 - NRXD * BUFLEN)
24455 -#define txb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
24456 -#else
24457 -static unsigned char rxb[NRXD * BUFLEN];
24458 -static unsigned char txb[BUFLEN];
24459 -#endif
24461 -static unsigned char ehdr[ETH_HLEN]; /* buffer for ethernet header */
24463 -enum tulip_offsets {
24464 - CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
24465 - CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
24466 - CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
24469 -/***************************************************************************/
24470 -/* 21143 specific stuff */
24471 -/***************************************************************************/
24473 -/* XXX assume 33MHz PCI bus, this is not very accurate and should be
24474 - used only with gross over estimations of required delay times unless
24475 - you tune UADJUST to your specific processor and I/O subsystem */
24477 -#define UADJUST 870
24478 -static void udelay(unsigned long usec) {
24479 - unsigned long i;
24480 - for (i=((usec*UADJUST)/33)+1; i>0; i--) (void) TULIP_CSR_READ(csr_0);
24483 -/* The following srom related code was taken from FreeBSD's if_de.c */
24484 -/* with minor alterations to make it work here. the Linux code is */
24485 -/* better but this was easier to use */
24487 -static void delay_300ns(void)
24489 - int idx;
24490 - for (idx = (300 / 33) + 1; idx > 0; idx--)
24491 - (void) TULIP_CSR_READ(csr_busmode);
24494 -#define EMIT do { TULIP_CSR_WRITE(csr_srom_mii, csr); delay_300ns(); } while (0)
24496 -static void srom_idle(void)
24498 - unsigned bit, csr;
24500 - csr = SROMSEL ; EMIT;
24501 - csr = SROMSEL | SROMRD; EMIT;
24502 - csr ^= SROMCS; EMIT;
24503 - csr ^= SROMCLKON; EMIT;
24504 - /*
24505 - * Write 25 cycles of 0 which will force the SROM to be idle.
24506 - */
24507 - for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
24508 - csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
24509 - csr ^= SROMCLKON; EMIT; /* clock high; data valid */
24511 - csr ^= SROMCLKOFF; EMIT;
24512 - csr ^= SROMCS; EMIT;
24513 - csr = 0; EMIT;
24516 -static void srom_read(void)
24518 - unsigned idx;
24519 - const unsigned bitwidth = SROM_BITWIDTH;
24520 - const unsigned cmdmask = (SROMCMD_RD << bitwidth);
24521 - const unsigned msb = 1 << (bitwidth + 3 - 1);
24522 - unsigned lastidx = (1 << bitwidth) - 1;
24524 - srom_idle();
24526 - for (idx = 0; idx <= lastidx; idx++) {
24527 - unsigned lastbit, data, bits, bit, csr;
24528 - csr = SROMSEL ; EMIT;
24529 - csr = SROMSEL | SROMRD; EMIT;
24530 - csr ^= SROMCSON; EMIT;
24531 - csr ^= SROMCLKON; EMIT;
24533 - lastbit = 0;
24534 - for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1)
24536 - const unsigned thisbit = bits & msb;
24537 - csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
24538 - if (thisbit != lastbit) {
24539 - csr ^= SROMDOUT; EMIT; /* clock low; invert data */
24540 - } else {
24541 - EMIT;
24543 - csr ^= SROMCLKON; EMIT; /* clock high; data valid */
24544 - lastbit = thisbit;
24546 - csr ^= SROMCLKOFF; EMIT;
24548 - for (data = 0, bits = 0; bits < 16; bits++) {
24549 - data <<= 1;
24550 - csr ^= SROMCLKON; EMIT; /* clock high; data valid */
24551 - data |= TULIP_CSR_READ(csr_srom_mii) & SROMDIN ? 1 : 0;
24552 - csr ^= SROMCLKOFF; EMIT; /* clock low; data not valid */
24554 - srom[idx*2] = data & 0xFF;
24555 - srom[idx*2+1] = data >> 8;
24556 - csr = SROMSEL | SROMRD; EMIT;
24557 - csr = 0; EMIT;
24559 - srom_idle();
24562 -/**************************************************************************
24563 -ETH_RESET - Reset adapter
24564 -***************************************************************************/
24565 -static void tulip_reset(struct nic *nic)
24567 - int x,cnt=2;
24569 - outl(0x00000001, ioaddr + CSR0);
24570 - udelay(1000);
24571 - /* turn off reset and set cache align=16lword, burst=unlimit */
24572 - outl(0x01A08000, ioaddr + CSR0);
24574 - /* for some reason the media selection does not take
24575 - the first time se it is repeated. */
24577 - while(cnt--) {
24578 - /* stop TX,RX processes */
24579 - if (cnt == 1)
24580 - outl(0x32404000, ioaddr + CSR6);
24581 - else
24582 - outl(0x32000040, ioaddr + CSR6);
24584 - /* XXX - media selection is vendor specific and hard coded right
24585 - here. This should be fixed to use the hints in the SROM and
24586 - allow media selection by the user at runtime. MII support
24587 - should also be added. Support for chips other than the
24588 - 21143 should be added here as well */
24590 - /* start set to 10Mbps half-duplex */
24592 - /* setup SIA */
24593 - outl(0x0, ioaddr + CSR13); /* reset SIA */
24594 - outl(0x7f3f, ioaddr + CSR14);
24595 - outl(0x8000008, ioaddr + CSR15);
24596 - outl(0x0, ioaddr + CSR13);
24597 - outl(0x1, ioaddr + CSR13);
24598 - outl(0x2404000, ioaddr + CSR6);
24600 - /* initalize GP */
24601 - outl(0x8af0008, ioaddr + CSR15);
24602 - outl(0x50008, ioaddr + CSR15);
24604 - /* end set to 10Mbps half-duplex */
24606 - if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
24607 - /* do stuff for MX98715 */
24608 - outl(0x01a80000, ioaddr + CSR6);
24609 - outl(0xFFFFFFFF, ioaddr + CSR14);
24610 - outl(0x00001000, ioaddr + CSR12);
24613 - outl(0x0, ioaddr + CSR7); /* disable interrupts */
24615 - /* construct setup packet which is used by the 21143 to
24616 - program its CAM to recognize interesting MAC addresses */
24618 - memset(&txd, 0, sizeof(struct txdesc));
24619 - txd.buf1addr = &txb[0];
24620 - txd.buf2addr = &txb[0]; /* just in case */
24621 - txd.buf1sz = 192; /* setup packet must be 192 bytes */
24622 - txd.buf2sz = 0;
24623 - txd.control = 0x020; /* setup packet */
24624 - txd.status = 0x80000000; /* give ownership to 21143 */
24626 - /* construct perfect filter frame */
24627 - /* with mac address as first match */
24628 - /* and broadcast address for all others */
24630 - for(x=0;x<192;x++) txb[x] = 0xff;
24631 - txb[0] = nic->node_addr[0];
24632 - txb[1] = nic->node_addr[1];
24633 - txb[4] = nic->node_addr[2];
24634 - txb[5] = nic->node_addr[3];
24635 - txb[8] = nic->node_addr[4];
24636 - txb[9] = nic->node_addr[5];
24637 - outl((unsigned long)&txd, ioaddr + CSR4); /* set xmit buf */
24638 - outl(0x2406000, ioaddr + CSR6); /* start transmiter */
24640 - udelay(50000); /* wait for the setup packet to be processed */
24644 - /* setup receive descriptor */
24646 - int x;
24647 - for(x=0;x<NRXD;x++) {
24648 - memset(&rxd[x], 0, sizeof(struct rxdesc));
24649 - rxd[x].buf1addr = &rxb[x * BUFLEN];
24650 - rxd[x].buf2addr = 0; /* not used */
24651 - rxd[x].buf1sz = BUFLEN;
24652 - rxd[x].buf2sz = 0; /* not used */
24653 - rxd[x].control = 0x0;
24654 - rxd[x].status = 0x80000000; /* give ownership it to 21143 */
24656 - rxd[NRXD - 1].control = 0x008; /* Set Receive end of ring on la
24657 -st descriptor */
24658 - rxd_tail = 0;
24661 - /* tell DC211XX where to find rx descriptor list */
24662 - outl((unsigned long)&rxd[0], ioaddr + CSR3);
24663 - /* start the receiver */
24664 - outl(0x2406002, ioaddr + CSR6);
24668 -/**************************************************************************
24669 -ETH_TRANSMIT - Transmit a frame
24670 -***************************************************************************/
24671 -static const char padmap[] = {
24672 - 0, 3, 2, 1};
24674 -static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
24676 - unsigned long time;
24678 - /* setup ethernet header */
24680 - memcpy(ehdr, d, ETH_ALEN);
24681 - memcpy(&ehdr[ETH_ALEN], nic->node_addr, ETH_ALEN);
24682 - ehdr[ETH_ALEN*2] = (t >> 8) & 0xff;
24683 - ehdr[ETH_ALEN*2+1] = t & 0xff;
24685 - /* setup the transmit descriptor */
24687 - memset(&txd, 0, sizeof(struct txdesc));
24689 - txd.buf1addr = &ehdr[0]; /* ethernet header */
24690 - txd.buf1sz = ETH_HLEN;
24692 - txd.buf2addr = p; /* packet to transmit */
24693 - txd.buf2sz = s;
24695 - txd.control = 0x188; /* LS+FS+TER */
24697 - txd.status = 0x80000000; /* give it to 21143 */
24699 - outl(inl(ioaddr + CSR6) & ~0x00004000, ioaddr + CSR6);
24700 - outl((unsigned long)&txd, ioaddr + CSR4);
24701 - outl(inl(ioaddr + CSR6) | 0x00004000, ioaddr + CSR6);
24703 -/* Wait for transmit to complete before returning. not well tested.
24705 - time = currticks();
24706 - while(txd.status & 0x80000000) {
24707 - if (currticks() - time > 20) {
24708 - printf("transmit timeout.\n");
24709 - break;
24716 -/**************************************************************************
24717 -ETH_POLL - Wait for a frame
24718 -***************************************************************************/
24719 -static int tulip_poll(struct nic *nic)
24721 - if (rxd[rxd_tail].status & 0x80000000) return 0;
24723 - nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
24725 - /* copy packet to working buffer */
24726 - /* XXX - this copy could be avoided with a little more work
24727 - but for now we are content with it because the optimised
24728 - memcpy(, , ) is quite fast */
24730 - memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
24732 - /* return the descriptor and buffer to recieve ring */
24733 - rxd[rxd_tail].status = 0x80000000;
24734 - rxd_tail++;
24735 - if (rxd_tail == NRXD) rxd_tail = 0;
24737 - return 1;
24740 -static void tulip_disable(struct nic *nic)
24742 - /* nothing for the moment */
24745 -/**************************************************************************
24746 -ETH_PROBE - Look for an adapter
24747 -***************************************************************************/
24748 -struct nic *otulip_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
24750 - int i;
24752 - if (io_addrs == 0 || *io_addrs == 0)
24753 - return (0);
24754 - vendor = pci->vendor;
24755 - dev_id = pci->dev_id;
24756 - ioaddr = *io_addrs;
24757 - membase = (unsigned int *)pci->membase;
24759 - /* wakeup chip */
24760 - pcibios_write_config_dword(pci->bus,pci->devfn,0x40,0x00000000);
24762 - /* Stop the chip's Tx and Rx processes. */
24763 - /* outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6); */
24764 - /* Clear the missed-packet counter. */
24765 - /* (volatile int)inl(ioaddr + CSR8); */
24767 - srom_read();
24769 - for (i=0; i < ETH_ALEN; i++)
24770 - nic->node_addr[i] = srom[20+i];
24772 - printf("Tulip %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
24774 - tulip_reset(nic);
24776 - nic->reset = tulip_reset;
24777 - nic->poll = tulip_poll;
24778 - nic->transmit = tulip_transmit;
24779 - nic->disable = tulip_disable;
24780 - return nic;
24782 Index: b/netboot/otulip.h
24783 ===================================================================
24784 --- a/netboot/otulip.h
24785 +++ /dev/null
24786 @@ -1,76 +0,0 @@
24787 -/* mostly stolen from FreeBSD if_de.c, if_devar.h */
24789 -#define TULIP_CSR_READ(csr) (membase[csr*2])
24790 -#define CSR_READ(csr) (membase[csr*2])
24791 -#define TULIP_CSR_WRITE(csr, val) (membase[csr*2] = val)
24792 -#define CSR_WRITE(csr, val) (membase[csr*2] = val)
24794 -#define csr_0 0
24795 -#define csr_1 1
24796 -#define csr_2 2
24797 -#define csr_3 3
24798 -#define csr_4 4
24799 -#define csr_5 5
24800 -#define csr_6 6
24801 -#define csr_7 7
24802 -#define csr_8 8
24803 -#define csr_9 9
24804 -#define csr_10 10
24805 -#define csr_11 11
24806 -#define csr_12 12
24807 -#define csr_13 13
24808 -#define csr_14 14
24809 -#define csr_15 15
24811 -#define csr_busmode csr_0
24812 -#define csr_txpoll csr_1
24813 -#define csr_rxpoll csr_2
24814 -#define csr_rxlist csr_3
24815 -#define csr_txlist csr_4
24816 -#define csr_status csr_5
24817 -#define csr_command csr_6
24818 -#define csr_intr csr_7
24819 -#define csr_missed_frames csr_8
24820 -#define csr_enetrom csr_9 /* 21040 */
24821 -#define csr_reserved csr_10 /* 21040 */
24822 -#define csr_full_duplex csr_11 /* 21040 */
24823 -#define csr_bootrom csr_10 /* 21041/21140A/?? */
24824 -#define csr_gp csr_12 /* 21140* */
24825 -#define csr_watchdog csr_15 /* 21140* */
24826 -#define csr_gp_timer csr_11 /* 21041/21140* */
24827 -#define csr_srom_mii csr_9 /* 21041/21140* */
24828 -#define csr_sia_status csr_12 /* 2104x */
24829 -#define csr_sia_connectivity csr_13 /* 2104x */
24830 -#define csr_sia_tx_rx csr_14 /* 2104x */
24831 -#define csr_sia_general csr_15 /* 2104x */
24833 -#define SROMSEL 0x0800
24834 -#define SROMCS 0x0001
24835 -#define SROMCLKON 0x0002
24836 -#define SROMCLKOFF 0x0002
24837 -#define SROMRD 0x4000
24838 -#define SROMWR 0x2000
24839 -#define SROM_BITWIDTH 6
24840 -#define SROMCMD_RD 6
24841 -#define SROMCSON 0x0001
24842 -#define SROMDOUT 0x0004
24843 -#define SROMDIN 0x0008
24846 -struct txdesc {
24847 - unsigned long status; /* owner, status */
24848 - unsigned long buf1sz:11, /* size of buffer 1 */
24849 - buf2sz:11, /* size of buffer 2 */
24850 - control:10; /* control bits */
24851 - const unsigned char *buf1addr; /* buffer 1 address */
24852 - const unsigned char *buf2addr; /* buffer 2 address */
24855 -struct rxdesc {
24856 - unsigned long status; /* owner, status */
24857 - unsigned long buf1sz:11, /* size of buffer 1 */
24858 - buf2sz:11, /* size of buffer 2 */
24859 - control:10; /* control bits */
24860 - unsigned char *buf1addr; /* buffer 1 address */
24861 - unsigned char *buf2addr; /* buffer 2 address */
24863 Index: b/netboot/pci.c
24864 ===================================================================
24865 --- a/netboot/pci.c
24866 +++ b/netboot/pci.c
24867 @@ -1,15 +1,3 @@
24869 -** Support for NE2000 PCI clones added David Monro June 1997
24870 -** Generalised to other NICs by Ken Yap July 1997
24872 -** Most of this is taken from:
24874 -** /usr/src/linux/drivers/pci/pci.c
24875 -** /usr/src/linux/include/linux/pci.h
24876 -** /usr/src/linux/arch/i386/bios32.c
24877 -** /usr/src/linux/include/linux/bios32.h
24878 -** /usr/src/linux/drivers/net/ne.c
24882 * This program is free software; you can redistribute it and/or
24883 @@ -18,402 +6,294 @@
24884 * your option) any later version.
24887 -#include "etherboot.h"
24888 +#include "grub.h"
24889 #include "pci.h"
24891 -/*#define DEBUG 1*/
24892 -#define DEBUG 0
24894 -#ifdef CONFIG_PCI_DIRECT
24895 -#define PCIBIOS_SUCCESSFUL 0x00
24898 - * Functions for accessing PCI configuration space with type 1 accesses
24899 - */
24901 -#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
24903 -int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
24904 - unsigned int where, unsigned char *value)
24905 +unsigned long virt_offset = 0;
24906 +unsigned long virt_to_phys(volatile const void *virt_addr)
24908 - outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
24909 - *value = inb(0xCFC + (where&3));
24910 - return PCIBIOS_SUCCESSFUL;
24911 + return ((unsigned long)virt_addr) + virt_offset;
24914 -int pcibios_read_config_word (unsigned int bus,
24915 - unsigned int device_fn, unsigned int where, unsigned short *value)
24916 +void *phys_to_virt(unsigned long phys_addr)
24918 - outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
24919 - *value = inw(0xCFC + (where&2));
24920 - return PCIBIOS_SUCCESSFUL;
24921 + return (void *)(phys_addr - virt_offset);
24924 -int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
24925 - unsigned int where, unsigned int *value)
24927 - outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
24928 - *value = inl(0xCFC);
24929 - return PCIBIOS_SUCCESSFUL;
24931 +#ifdef INCLUDE_3C595
24932 +extern struct pci_driver t595_driver;
24933 +#endif /* INCLUDE_3C595 */
24935 -int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
24936 - unsigned int where, unsigned char value)
24938 - outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
24939 - outb(value, 0xCFC + (where&3));
24940 - return PCIBIOS_SUCCESSFUL;
24942 +#ifdef INCLUDE_3C90X
24943 +extern struct pci_driver a3c90x_driver;
24944 +#endif /* INCLUDE_3C90X */
24946 -int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
24947 - unsigned int where, unsigned short value)
24949 - outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
24950 - outw(value, 0xCFC + (where&2));
24951 - return PCIBIOS_SUCCESSFUL;
24953 +#ifdef INCLUDE_DAVICOM
24954 +extern struct pci_driver davicom_driver;
24955 +#endif /* INCLUDE_DAVICOM */
24957 -int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value)
24959 - outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
24960 - outl(value, 0xCFC);
24961 - return PCIBIOS_SUCCESSFUL;
24963 +#ifdef INCLUDE_E1000
24964 +extern struct pci_driver e1000_driver;
24965 +#endif /* INCLUDE_E1000 */
24967 -#undef CONFIG_CMD
24968 +#ifdef INCLUDE_EEPRO100
24969 +extern struct pci_driver eepro100_driver;
24970 +#endif /* INCLUDE_EEPRO100 */
24972 -#else /* CONFIG_PCI_DIRECT not defined */
24973 +#ifdef INCLUDE_EPIC100
24974 +extern struct pci_driver epic100_driver;
24975 +#endif /* INCLUDE_EPIC100 */
24977 -static struct {
24978 - unsigned long address;
24979 - unsigned short segment;
24980 -} bios32_indirect = { 0, KERN_CODE_SEG };
24982 -static long pcibios_entry;
24983 -static struct {
24984 - unsigned long address;
24985 - unsigned short segment;
24986 -} pci_indirect = { 0, KERN_CODE_SEG };
24987 +#ifdef INCLUDE_FORCEDETH
24988 +extern struct pci_driver forcedeth_driver;
24989 +#endif /* INCLUDE_FORCEDETH */
24991 -static unsigned long bios32_service(unsigned long service)
24993 - unsigned char return_code; /* %al */
24994 - unsigned long address; /* %ebx */
24995 - unsigned long length; /* %ecx */
24996 - unsigned long entry; /* %edx */
24997 - unsigned long flags;
24999 - save_flags(flags);
25000 - __asm__(
25001 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25002 - "lcall (%%edi)"
25003 -#else
25004 - "lcall *(%%edi)"
25005 -#endif
25006 - : "=a" (return_code),
25007 - "=b" (address),
25008 - "=c" (length),
25009 - "=d" (entry)
25010 - : "0" (service),
25011 - "1" (0),
25012 - "D" (&bios32_indirect));
25013 - restore_flags(flags);
25015 - switch (return_code) {
25016 - case 0:
25017 - return address + entry;
25018 - case 0x80: /* Not present */
25019 - printf("bios32_service(%d) : not present\n", service);
25020 - return 0;
25021 - default: /* Shouldn't happen */
25022 - printf("bios32_service(%d) : returned %#X, mail drew@colorado.edu\n",
25023 - service, return_code);
25024 - return 0;
25027 +#ifdef INCLUDE_NATSEMI
25028 +extern struct pci_driver natsemi_driver;
25029 +#endif /* INCLUDE_NATSEMI */
25031 -int pcibios_read_config_byte(unsigned int bus,
25032 - unsigned int device_fn, unsigned int where, unsigned char *value)
25034 - unsigned long ret;
25035 - unsigned long bx = (bus << 8) | device_fn;
25036 - unsigned long flags;
25038 - save_flags(flags);
25039 - __asm__(
25040 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25041 - "lcall (%%esi)\n\t"
25042 -#else
25043 - "lcall *(%%esi)\n\t"
25044 -#endif
25045 - "jc 1f\n\t"
25046 - "xor %%ah, %%ah\n"
25047 - "1:"
25048 - : "=c" (*value),
25049 - "=a" (ret)
25050 - : "1" (PCIBIOS_READ_CONFIG_BYTE),
25051 - "b" (bx),
25052 - "D" ((long) where),
25053 - "S" (&pci_indirect));
25054 - restore_flags(flags);
25055 - return (int) (ret & 0xff00) >> 8;
25057 +#ifdef INCLUDE_NS83820
25058 +extern struct pci_driver ns83820_driver;
25059 +#endif /* INCLUDE_NS83820 */
25061 -int pcibios_read_config_word(unsigned int bus,
25062 - unsigned int device_fn, unsigned int where, unsigned short *value)
25064 - unsigned long ret;
25065 - unsigned long bx = (bus << 8) | device_fn;
25066 - unsigned long flags;
25068 - save_flags(flags);
25069 - __asm__(
25070 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25071 - "lcall (%%esi)\n\t"
25072 -#else
25073 - "lcall *(%%esi)\n\t"
25074 -#endif
25075 - "jc 1f\n\t"
25076 - "xor %%ah, %%ah\n"
25077 - "1:"
25078 - : "=c" (*value),
25079 - "=a" (ret)
25080 - : "1" (PCIBIOS_READ_CONFIG_WORD),
25081 - "b" (bx),
25082 - "D" ((long) where),
25083 - "S" (&pci_indirect));
25084 - restore_flags(flags);
25085 - return (int) (ret & 0xff00) >> 8;
25087 +#ifdef INCLUDE_NS8390
25088 +extern struct pci_driver nepci_driver;
25089 +#endif /* INCLUDE_NS8390 */
25091 -int pcibios_read_config_dword(unsigned int bus,
25092 - unsigned int device_fn, unsigned int where, unsigned int *value)
25094 - unsigned long ret;
25095 - unsigned long bx = (bus << 8) | device_fn;
25096 - unsigned long flags;
25098 - save_flags(flags);
25099 - __asm__(
25100 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25101 - "lcall (%%esi)\n\t"
25102 -#else
25103 - "lcall *(%%esi)\n\t"
25104 -#endif
25105 - "jc 1f\n\t"
25106 - "xor %%ah, %%ah\n"
25107 - "1:"
25108 - : "=c" (*value),
25109 - "=a" (ret)
25110 - : "1" (PCIBIOS_READ_CONFIG_DWORD),
25111 - "b" (bx),
25112 - "D" ((long) where),
25113 - "S" (&pci_indirect));
25114 - restore_flags(flags);
25115 - return (int) (ret & 0xff00) >> 8;
25117 +#ifdef INCLUDE_PCNET32
25118 +extern struct pci_driver pcnet32_driver;
25119 +#endif /* INCLUDE_PCNET32 */
25121 -int pcibios_write_config_byte (unsigned int bus,
25122 - unsigned int device_fn, unsigned int where, unsigned char value)
25124 - unsigned long ret;
25125 - unsigned long bx = (bus << 8) | device_fn;
25126 - unsigned long flags;
25128 - save_flags(flags); cli();
25129 - __asm__(
25130 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25131 - "lcall (%%esi)\n\t"
25132 -#else
25133 - "lcall *(%%esi)\n\t"
25134 -#endif
25135 - "jc 1f\n\t"
25136 - "xor %%ah, %%ah\n"
25137 - "1:"
25138 - : "=a" (ret)
25139 - : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
25140 - "c" (value),
25141 - "b" (bx),
25142 - "D" ((long) where),
25143 - "S" (&pci_indirect));
25144 - restore_flags(flags);
25145 - return (int) (ret & 0xff00) >> 8;
25147 +#ifdef INCLUDE_PNIC
25148 +extern struct pci_driver pnic_driver;
25149 +#endif /* INCLUDE_PNIC */
25151 -int pcibios_write_config_word (unsigned int bus,
25152 - unsigned int device_fn, unsigned int where, unsigned short value)
25154 - unsigned long ret;
25155 - unsigned long bx = (bus << 8) | device_fn;
25156 - unsigned long flags;
25158 - save_flags(flags); cli();
25159 - __asm__(
25160 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25161 - "lcall (%%esi)\n\t"
25162 -#else
25163 - "lcall *(%%esi)\n\t"
25164 -#endif
25165 - "jc 1f\n\t"
25166 - "xor %%ah, %%ah\n"
25167 - "1:"
25168 - : "=a" (ret)
25169 - : "0" (PCIBIOS_WRITE_CONFIG_WORD),
25170 - "c" (value),
25171 - "b" (bx),
25172 - "D" ((long) where),
25173 - "S" (&pci_indirect));
25174 - restore_flags(flags);
25175 - return (int) (ret & 0xff00) >> 8;
25177 +#ifdef INCLUDE_RTL8139
25178 +extern struct pci_driver rtl8139_driver;
25179 +#endif /* INCLUDE_RTL8139 */
25181 -int pcibios_write_config_dword (unsigned int bus,
25182 - unsigned int device_fn, unsigned int where, unsigned int value)
25184 - unsigned long ret;
25185 - unsigned long bx = (bus << 8) | device_fn;
25186 - unsigned long flags;
25188 - save_flags(flags); cli();
25189 - __asm__(
25190 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25191 - "lcall (%%esi)\n\t"
25192 -#else
25193 - "lcall *(%%esi)\n\t"
25194 -#endif
25195 - "jc 1f\n\t"
25196 - "xor %%ah, %%ah\n"
25197 - "1:"
25198 - : "=a" (ret)
25199 - : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
25200 - "c" (value),
25201 - "b" (bx),
25202 - "D" ((long) where),
25203 - "S" (&pci_indirect));
25204 - restore_flags(flags);
25205 - return (int) (ret & 0xff00) >> 8;
25207 +#ifdef INCLUDE_SIS900
25208 +extern struct pci_driver sis900_driver;
25209 +extern struct pci_driver sis_bridge_driver;
25210 +#endif /* INCLUDE_SIS900 */
25212 -static void check_pcibios(void)
25214 - unsigned long signature;
25215 - unsigned char present_status;
25216 - unsigned char major_revision;
25217 - unsigned char minor_revision;
25218 - unsigned long flags;
25219 - int pack;
25221 - if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
25222 - pci_indirect.address = pcibios_entry;
25224 - save_flags(flags);
25225 - __asm__(
25226 -#ifdef ABSOLUTE_WITHOUT_ASTERISK
25227 - "lcall (%%edi)\n\t"
25228 -#else
25229 - "lcall *(%%edi)\n\t"
25230 -#endif
25231 - "jc 1f\n\t"
25232 - "xor %%ah, %%ah\n"
25233 - "1:\tshl $8, %%eax\n\t"
25234 - "movw %%bx, %%ax"
25235 - : "=d" (signature),
25236 - "=a" (pack)
25237 - : "1" (PCIBIOS_PCI_BIOS_PRESENT),
25238 - "D" (&pci_indirect)
25239 - : "bx", "cx");
25240 - restore_flags(flags);
25242 - present_status = (pack >> 16) & 0xff;
25243 - major_revision = (pack >> 8) & 0xff;
25244 - minor_revision = pack & 0xff;
25245 - if (present_status || (signature != PCI_SIGNATURE)) {
25246 - printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
25247 - "BIOS????\n");
25248 - pcibios_entry = 0;
25250 -#if DEBUG
25251 - if (pcibios_entry) {
25252 - printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
25253 - " entry at %#X\n", major_revision,
25254 - minor_revision, pcibios_entry);
25256 -#endif
25259 +#ifdef INCLUDE_SUNDANCE
25260 +extern struct pci_driver sundance_driver;
25261 +#endif /* INCLUDE_SUNDANCE */
25263 -static void pcibios_init(void)
25265 - union bios32 *check;
25266 - unsigned char sum;
25267 - int i, length;
25268 - unsigned long bios32_entry = 0;
25270 - /*
25271 - * Follow the standard procedure for locating the BIOS32 Service
25272 - * directory by scanning the permissible address range from
25273 - * 0xe0000 through 0xfffff for a valid BIOS32 structure.
25275 - */
25276 +#ifdef INCLUDE_TG3
25277 +extern struct pci_driver tg3_driver;
25278 +#endif /* INCLUDE_TG3 */
25280 +#ifdef INCLUDE_TLAN
25281 +extern struct pci_driver tlan_driver;
25282 +#endif /* INCLUDE_TLAN */
25284 +#ifdef INCLUDE_TULIP
25285 +extern struct pci_driver tulip_driver;
25286 +#endif /* INCLUDE_TULIP */
25288 +#ifdef INCLUDE_UNDI
25289 +extern struct pci_driver undi_driver;
25290 +#endif /* INCLUDE_UNDI */
25292 +#ifdef INCLUDE_VIA_RHINE
25293 +extern struct pci_driver rhine_driver;
25294 +#endif/* INCLUDE_VIA_RHINE */
25296 +#ifdef INCLUDE_W89C840
25297 +extern struct pci_driver w89c840_driver;
25298 +#endif /* INCLUDE_W89C840 */
25300 +#ifdef INCLUDE_R8169
25301 +extern struct pci_driver r8169_driver;
25302 +#endif /* INCLUDE_R8169 */
25304 +static const struct pci_driver *pci_drivers[] = {
25306 +#ifdef INCLUDE_3C595
25307 + &t595_driver,
25308 +#endif /* INCLUDE_3C595 */
25310 +#ifdef INCLUDE_3C90X
25311 + &a3c90x_driver,
25312 +#endif /* INCLUDE_3C90X */
25314 +#ifdef INCLUDE_DAVICOM
25315 + &davicom_driver,
25316 +#endif /* INCLUDE_DAVICOM */
25318 +#ifdef INCLUDE_E1000
25319 + &e1000_driver,
25320 +#endif /* INCLUDE_E1000 */
25322 +#ifdef INCLUDE_EEPRO100
25323 + &eepro100_driver,
25324 +#endif /* INCLUDE_EEPRO100 */
25326 +#ifdef INCLUDE_EPIC100
25327 + &epic100_driver,
25328 +#endif /* INCLUDE_EPIC100 */
25330 +#ifdef INCLUDE_FORCEDETH
25331 + &forcedeth_driver,
25332 +#endif /* INCLUDE_FORCEDETH */
25334 +#ifdef INCLUDE_NATSEMI
25335 + &natsemi_driver,
25336 +#endif /* INCLUDE_NATSEMI */
25338 +#ifdef INCLUDE_NS83820
25339 + &ns83820_driver,
25340 +#endif /* INCLUDE_NS83820 */
25342 +#ifdef INCLUDE_NS8390
25343 + &nepci_driver,
25344 +#endif /* INCLUDE_NS8390 */
25346 +#ifdef INCLUDE_PCNET32
25347 + &pcnet32_driver,
25348 +#endif /* INCLUDE_PCNET32 */
25350 +#ifdef INCLUDE_PNIC
25351 + &pnic_driver,
25352 +#endif /* INCLUDE_PNIC */
25354 - for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
25355 - if (check->fields.signature != BIOS32_SIGNATURE)
25356 +#ifdef INCLUDE_RTL8139
25357 + &rtl8139_driver,
25358 +#endif /* INCLUDE_RTL8139 */
25360 +#ifdef INCLUDE_SIS900
25361 + &sis900_driver,
25362 + &sis_bridge_driver,
25363 +#endif /* INCLUDE_SIS900 */
25365 +#ifdef INCLUDE_SUNDANCE
25366 + &sundance_driver,
25367 +#endif /* INCLUDE_SUNDANCE */
25369 +#ifdef INCLUDE_TG3
25370 + & tg3_driver,
25371 +#endif /* INCLUDE_TG3 */
25373 +#ifdef INCLUDE_TLAN
25374 + &tlan_driver,
25375 +#endif /* INCLUDE_TLAN */
25377 +#ifdef INCLUDE_TULIP
25378 + & tulip_driver,
25379 +#endif /* INCLUDE_TULIP */
25381 +#ifdef INCLUDE_VIA_RHINE
25382 + &rhine_driver,
25383 +#endif/* INCLUDE_VIA_RHINE */
25385 +#ifdef INCLUDE_W89C840
25386 + &w89c840_driver,
25387 +#endif /* INCLUDE_W89C840 */
25389 +#ifdef INCLUDE_R8169
25390 + &r8169_driver,
25391 +#endif /* INCLUDE_R8169 */
25393 +/* We must be the last one */
25394 +#ifdef INCLUDE_UNDI
25395 + &undi_driver,
25396 +#endif /* INCLUDE_UNDI */
25401 +static void scan_drivers(
25402 + int type,
25403 + uint32_t class, uint16_t vendor, uint16_t device,
25404 + const struct pci_driver *last_driver, struct pci_device *dev)
25406 + const struct pci_driver *skip_driver = last_driver;
25407 + /* Assume there is only one match of the correct type */
25408 + const struct pci_driver *driver;
25409 + int i, j;
25411 + for(j = 0; pci_drivers[j] != 0; j++){
25412 + driver = pci_drivers[j];
25413 + if (driver->type != type)
25414 continue;
25415 - length = check->fields.length * 16;
25416 - if (!length)
25417 + if (skip_driver) {
25418 + if (skip_driver == driver)
25419 + skip_driver = 0;
25420 continue;
25421 - sum = 0;
25422 - for (i = 0; i < length ; ++i)
25423 - sum += check->chars[i];
25424 - if (sum != 0)
25426 + for(i = 0; i < driver->id_count; i++) {
25427 + if ((vendor == driver->ids[i].vendor) &&
25428 + (device == driver->ids[i].dev_id)) {
25430 + dev->driver = driver;
25431 + dev->name = driver->ids[i].name;
25433 + goto out;
25437 + if (!class) {
25438 + goto out;
25440 + for(j = 0; pci_drivers[j] != 0; j++){
25441 + driver = pci_drivers[j];
25442 + if (driver->type != type)
25443 continue;
25444 - if (check->fields.revision != 0) {
25445 - printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
25446 - check->fields.revision, check);
25447 + if (skip_driver) {
25448 + if (skip_driver == driver)
25449 + skip_driver = 0;
25450 continue;
25452 -#if DEBUG
25453 - printf("pcibios_init : BIOS32 Service Directory "
25454 - "structure at %#X\n", check);
25455 -#endif
25456 - if (!bios32_entry) {
25457 - if (check->fields.entry >= 0x100000) {
25458 - printf("pcibios_init: entry in high "
25459 - "memory, giving up\n");
25460 - return;
25461 - } else {
25462 - bios32_entry = check->fields.entry;
25463 -#if DEBUG
25464 - printf("pcibios_init : BIOS32 Service Directory"
25465 - " entry at %#X\n", bios32_entry);
25466 -#endif
25467 - bios32_indirect.address = bios32_entry;
25469 + if (last_driver == driver)
25470 + continue;
25471 + if ((class >> 8) == driver->class) {
25472 + dev->driver = driver;
25473 + dev->name = driver->name;
25474 + goto out;
25477 - if (bios32_entry)
25478 - check_pcibios();
25479 + out:
25480 + return;
25482 -#endif /* CONFIG_PCI_DIRECT not defined*/
25484 -static void scan_bus(struct pci_device *pcidev)
25485 +void scan_pci_bus(int type, struct pci_device *dev)
25487 - unsigned int devfn, l, bus, buses;
25488 + unsigned int first_bus, first_devfn;
25489 + const struct pci_driver *first_driver;
25490 + unsigned int devfn, bus, buses;
25491 unsigned char hdr_type = 0;
25492 - unsigned short vendor, device;
25493 - unsigned int membase, ioaddr, romaddr;
25494 - int i, reg;
25495 - unsigned int pci_ioaddr = 0;
25497 + uint32_t class;
25498 + uint16_t vendor, device;
25499 + uint32_t l, membase, ioaddr, romaddr;
25500 + int reg;
25502 + EnterFunction("scan_pci_bus");
25503 + first_bus = 0;
25504 + first_devfn = 0;
25505 + first_driver = 0;
25506 + if (dev->driver) {
25507 + first_driver = dev->driver;
25508 + first_bus = dev->bus;
25509 + first_devfn = dev->devfn;
25510 + /* Re read the header type on a restart */
25511 + pcibios_read_config_byte(first_bus, first_devfn & ~0x7,
25512 + PCI_HEADER_TYPE, &hdr_type);
25513 + dev->driver = 0;
25514 + dev->bus = 0;
25515 + dev->devfn = 0;
25518 /* Scan all PCI buses, until we find our card.
25519 - * We could be smart only scan the required busses but that
25520 + * We could be smart only scan the required buses but that
25521 * is error prone, and tricky.
25522 - * By scanning all possible pci busses in order we should find
25523 + * By scanning all possible pci buses in order we should find
25524 * our card eventually.
25526 buses=256;
25527 - for (bus = 0; bus < buses; ++bus) {
25528 - for (devfn = 0; devfn < 0xff; ++devfn) {
25529 + for (bus = first_bus; bus < buses; ++bus) {
25530 + for (devfn = first_devfn; devfn < 0xff; ++devfn, first_driver = 0) {
25531 if (PCI_FUNC (devfn) == 0)
25532 pcibios_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
25533 else if (!(hdr_type & 0x80)) /* not a multi-function device */
25534 @@ -421,61 +301,90 @@
25535 pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l);
25536 /* some broken boards return 0 if a slot is empty: */
25537 if (l == 0xffffffff || l == 0x00000000) {
25538 - hdr_type = 0;
25539 continue;
25541 vendor = l & 0xffff;
25542 device = (l >> 16) & 0xffff;
25544 + pcibios_read_config_dword(bus, devfn, PCI_REVISION, &l);
25545 + class = (l >> 8) & 0xffffff;
25546 #if DEBUG
25547 - printf("bus %hhX, function %hhX, vendor %hX, device %hX\n",
25548 - bus, devfn, vendor, device);
25550 + int i;
25551 + printf("%hhx:%hhx.%hhx [%hX/%hX] ---- ",
25552 + bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
25553 + vendor, device);
25554 +#if DEBUG > 1
25555 + for(i = 0; i < 256; i++) {
25556 + unsigned char byte;
25557 + if ((i & 0xf) == 0) {
25558 + printf("%hhx: ", i);
25560 + pcibios_read_config_byte(bus, devfn, i, &byte);
25561 + printf("%hhx ", byte);
25562 + if ((i & 0xf) == 0xf) {
25563 + printf("\n");
25566 +#endif
25569 +#endif
25570 + scan_drivers(type, class, vendor, device, first_driver, dev);
25571 + if (!dev->driver){
25572 +#if DEBUG
25573 + printf("No driver fit.\n");
25574 #endif
25575 - for (i = 0; pcidev[i].vendor != 0; i++) {
25576 - if (vendor != pcidev[i].vendor
25577 - || device != pcidev[i].dev_id)
25578 + continue;
25580 +#if DEBUG
25581 + printf("Get Driver:\n");
25582 +#endif
25583 + dev->devfn = devfn;
25584 + dev->bus = bus;
25585 + dev->class = class;
25586 + dev->vendor = vendor;
25587 + dev->dev_id = device;
25590 + /* Get the ROM base address */
25591 + pcibios_read_config_dword(bus, devfn,
25592 + PCI_ROM_ADDRESS, &romaddr);
25593 + romaddr >>= 10;
25594 + dev->romaddr = romaddr;
25596 + /* Get the ``membase'' */
25597 + pcibios_read_config_dword(bus, devfn,
25598 + PCI_BASE_ADDRESS_1, &membase);
25599 + dev->membase = membase;
25601 + /* Get the ``ioaddr'' */
25602 + for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
25603 + pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
25604 + if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
25605 continue;
25606 - pcidev[i].devfn = devfn;
25607 - pcidev[i].bus = bus;
25608 - for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
25609 - pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
25611 - if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
25612 - continue;
25613 - /* Strip the I/O address out of the returned value */
25614 - ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
25615 - /* Get the memory base address */
25616 - pcibios_read_config_dword(bus, devfn,
25617 - PCI_BASE_ADDRESS_1, &membase);
25618 - /* Get the ROM base address */
25619 - pcibios_read_config_dword(bus, devfn, PCI_ROM_ADDRESS, &romaddr);
25620 - romaddr >>= 10;
25621 - printf("Found %s at %#hx, ROM address %#hx\n",
25622 - pcidev[i].name, ioaddr, romaddr);
25623 - /* Take the first one or the one that matches in boot ROM address */
25624 - if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) {
25625 - pcidev[i].membase = membase;
25626 - pcidev[i].ioaddr = ioaddr;
25627 - return;
25632 + /* Strip the I/O address out of the returned value */
25633 + ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
25635 + /* Take the first one or the one that matches in boot ROM address */
25636 + dev->ioaddr = ioaddr;
25638 +#if DEBUG > 2
25639 + printf("Found %s ROM address %#hx\n",
25640 + dev->name, romaddr);
25641 +#endif
25642 + LeaveFunction("scan_pci_bus");
25643 + return;
25645 + first_devfn = 0;
25647 + first_bus = 0;
25648 + LeaveFunction("scan_pci_bus");
25651 -void eth_pci_init(struct pci_device *pcidev)
25653 -#ifndef CONFIG_PCI_DIRECT
25654 - pcibios_init();
25655 - if (!pcibios_entry) {
25656 - printf("pci_init: no BIOS32 detected\n");
25657 - return;
25659 -#endif
25660 - scan_bus(pcidev);
25661 - /* return values are in pcidev structures */
25666 * Set device to be a busmaster in case BIOS neglected to do so.
25667 @@ -489,13 +398,134 @@
25668 pcibios_read_config_word(p->bus, p->devfn, PCI_COMMAND, &pci_command);
25669 new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
25670 if (pci_command != new_command) {
25671 - printf("The PCI BIOS has not enabled this device!\nUpdating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
25672 +#if DEBUG > 0
25673 + printf(
25674 + "The PCI BIOS has not enabled this device!\n"
25675 + "Updating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
25676 pci_command, new_command, p->bus, p->devfn);
25677 +#endif
25678 pcibios_write_config_word(p->bus, p->devfn, PCI_COMMAND, new_command);
25680 pcibios_read_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, &pci_latency);
25681 if (pci_latency < 32) {
25682 - printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n", pci_latency);
25683 +#if DEBUG > 0
25684 + printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n",
25685 + pci_latency);
25686 +#endif
25687 pcibios_write_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, 32);
25692 + * Find the start of a pci resource.
25693 + */
25694 +unsigned long pci_bar_start(struct pci_device *dev, unsigned int index)
25696 + uint32_t lo, hi;
25697 + unsigned long bar;
25698 + pci_read_config_dword(dev, index, &lo);
25699 + if (lo & PCI_BASE_ADDRESS_SPACE_IO) {
25700 + bar = lo & PCI_BASE_ADDRESS_IO_MASK;
25701 + } else {
25702 + bar = 0;
25703 + if ((lo & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
25704 + pci_read_config_dword(dev, index + 4, &hi);
25705 + if (hi) {
25706 + if (sizeof(unsigned long) > sizeof(uint32_t)) {
25707 + bar = hi;
25708 + /* It's REALLY interesting:-) */
25709 + bar <<=32;
25711 + else {
25712 + printf("Unhandled 64bit BAR\n");
25713 + return -1UL;
25717 + bar |= lo & PCI_BASE_ADDRESS_MEM_MASK;
25719 + return bar + pcibios_bus_base(dev->bus);
25723 + * Find the size of a pci resource.
25724 + */
25725 +unsigned long pci_bar_size(struct pci_device *dev, unsigned int bar)
25727 + uint32_t start, size;
25728 + /* Save the original bar */
25729 + pci_read_config_dword(dev, bar, &start);
25730 + /* Compute which bits can be set */
25731 + pci_write_config_dword(dev, bar, ~0);
25732 + pci_read_config_dword(dev, bar, &size);
25733 + /* Restore the original size */
25734 + pci_write_config_dword(dev, bar, start);
25735 + /* Find the significant bits */
25736 + if (start & PCI_BASE_ADDRESS_SPACE_IO) {
25737 + size &= PCI_BASE_ADDRESS_IO_MASK;
25738 + } else {
25739 + size &= PCI_BASE_ADDRESS_MEM_MASK;
25741 + /* Find the lowest bit set */
25742 + size = size & ~(size - 1);
25743 + return size;
25746 +/**
25747 + * pci_find_capability - query for devices' capabilities
25748 + * @dev: PCI device to query
25749 + * @cap: capability code
25751 + * Tell if a device supports a given PCI capability.
25752 + * Returns the address of the requested capability structure within the
25753 + * device's PCI configuration space or 0 in case the device does not
25754 + * support it. Possible values for @cap:
25756 + * %PCI_CAP_ID_PM Power Management
25758 + * %PCI_CAP_ID_AGP Accelerated Graphics Port
25760 + * %PCI_CAP_ID_VPD Vital Product Data
25762 + * %PCI_CAP_ID_SLOTID Slot Identification
25764 + * %PCI_CAP_ID_MSI Message Signalled Interrupts
25766 + * %PCI_CAP_ID_CHSWP CompactPCI HotSwap
25767 + */
25768 +int pci_find_capability(struct pci_device *dev, int cap)
25770 + uint16_t status;
25771 + uint8_t pos, id;
25772 + uint8_t hdr_type;
25773 + int ttl = 48;
25775 + pci_read_config_word(dev, PCI_STATUS, &status);
25776 + if (!(status & PCI_STATUS_CAP_LIST))
25777 + return 0;
25778 + pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
25779 + switch (hdr_type & 0x7F) {
25780 + case PCI_HEADER_TYPE_NORMAL:
25781 + case PCI_HEADER_TYPE_BRIDGE:
25782 + default:
25783 + pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos);
25784 + break;
25785 + case PCI_HEADER_TYPE_CARDBUS:
25786 + pci_read_config_byte(dev, PCI_CB_CAPABILITY_LIST, &pos);
25787 + break;
25789 + while (ttl-- && pos >= 0x40) {
25790 + pos &= ~3;
25791 + pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
25792 +#if DEBUG > 0
25793 + printf("Capability: %d\n", id);
25794 +#endif
25795 + if (id == 0xff)
25796 + break;
25797 + if (id == cap)
25798 + return pos;
25799 + pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
25801 + return 0;
25804 Index: b/netboot/pci.h
25805 ===================================================================
25806 --- a/netboot/pci.h
25807 +++ b/netboot/pci.h
25808 @@ -1,4 +1,4 @@
25809 -#ifndef PCI_H
25810 +#if !defined(PCI_H) && defined(CONFIG_PCI)
25811 #define PCI_H
25814 @@ -21,10 +21,19 @@
25815 * your option) any later version.
25818 +#include "pci_ids.h"
25820 #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
25821 #define PCI_COMMAND_MEM 0x2 /* Enable response in mem space */
25822 #define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
25823 #define PCI_LATENCY_TIMER 0x0d /* 8 bits */
25824 +#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
25825 +#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
25826 +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
25827 +#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
25828 +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
25829 +#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
25830 +#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
25832 #define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
25833 #define PCIBIOS_PCI_BIOS_PRESENT 0xb101
25834 @@ -42,10 +51,37 @@
25835 #define PCI_DEVICE_ID 0x02 /* 16 bits */
25836 #define PCI_COMMAND 0x04 /* 16 bits */
25838 +#define PCI_STATUS 0x06 /* 16 bits */
25839 +#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
25840 +#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
25841 +#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
25842 +#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
25843 +#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
25844 +#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
25845 +#define PCI_STATUS_DEVSEL_FAST 0x000
25846 +#define PCI_STATUS_DEVSEL_MEDIUM 0x200
25847 +#define PCI_STATUS_DEVSEL_SLOW 0x400
25848 +#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
25849 +#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
25850 +#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
25851 +#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
25852 +#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
25854 #define PCI_REVISION 0x08 /* 8 bits */
25855 +#define PCI_REVISION_ID 0x08 /* 8 bits */
25856 +#define PCI_CLASS_REVISION 0x08 /* 32 bits */
25857 #define PCI_CLASS_CODE 0x0b /* 8 bits */
25858 #define PCI_SUBCLASS_CODE 0x0a /* 8 bits */
25859 #define PCI_HEADER_TYPE 0x0e /* 8 bits */
25860 +#define PCI_HEADER_TYPE_NORMAL 0
25861 +#define PCI_HEADER_TYPE_BRIDGE 1
25862 +#define PCI_HEADER_TYPE_CARDBUS 2
25865 +/* Header type 0 (normal devices) */
25866 +#define PCI_CARDBUS_CIS 0x28
25867 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
25868 +#define PCI_SUBSYSTEM_ID 0x2e
25870 #define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
25871 #define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
25872 @@ -54,15 +90,155 @@
25873 #define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
25874 #define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
25876 +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
25877 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
25878 +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
25879 +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
25881 #ifndef PCI_BASE_ADDRESS_IO_MASK
25882 #define PCI_BASE_ADDRESS_IO_MASK (~0x03)
25883 #endif
25884 +#ifndef PCI_BASE_ADDRESS_MEM_MASK
25885 +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0f)
25886 +#endif
25887 #define PCI_BASE_ADDRESS_SPACE_IO 0x01
25888 #define PCI_ROM_ADDRESS 0x30 /* 32 bits */
25889 #define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
25890 bits 31..11 are address,
25891 10..2 are reserved */
25893 +#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
25895 +#define PCI_INTERRUPT_LINE 0x3c /* IRQ number (0-15) */
25896 +#define PCI_INTERRUPT_PIN 0x3d /* IRQ pin on PCI bus (A-D) */
25898 +/* Header type 1 (PCI-to-PCI bridges) */
25899 +#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
25900 +#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
25901 +#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
25902 +#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
25903 +#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
25904 +#define PCI_IO_LIMIT 0x1d
25905 +#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
25906 +#define PCI_IO_RANGE_TYPE_16 0x00
25907 +#define PCI_IO_RANGE_TYPE_32 0x01
25908 +#define PCI_IO_RANGE_MASK ~0x0f
25909 +#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
25910 +#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
25911 +#define PCI_MEMORY_LIMIT 0x22
25912 +#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
25913 +#define PCI_MEMORY_RANGE_MASK ~0x0f
25914 +#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
25915 +#define PCI_PREF_MEMORY_LIMIT 0x26
25916 +#define PCI_PREF_RANGE_TYPE_MASK 0x0f
25917 +#define PCI_PREF_RANGE_TYPE_32 0x00
25918 +#define PCI_PREF_RANGE_TYPE_64 0x01
25919 +#define PCI_PREF_RANGE_MASK ~0x0f
25920 +#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
25921 +#define PCI_PREF_LIMIT_UPPER32 0x2c
25922 +#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
25923 +#define PCI_IO_LIMIT_UPPER16 0x32
25924 +/* 0x34 same as for htype 0 */
25925 +/* 0x35-0x3b is reserved */
25926 +#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
25927 +/* 0x3c-0x3d are same as for htype 0 */
25928 +#define PCI_BRIDGE_CONTROL 0x3e
25929 +#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
25930 +#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
25931 +#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
25932 +#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
25933 +#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
25934 +#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
25935 +#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
25937 +#define PCI_CB_CAPABILITY_LIST 0x14
25939 +/* Capability lists */
25941 +#define PCI_CAP_LIST_ID 0 /* Capability ID */
25942 +#define PCI_CAP_ID_PM 0x01 /* Power Management */
25943 +#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
25944 +#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
25945 +#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
25946 +#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
25947 +#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
25948 +#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
25949 +#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
25950 +#define PCI_CAP_SIZEOF 4
25952 +/* Power Management Registers */
25954 +#define PCI_PM_PMC 2 /* PM Capabilities Register */
25955 +#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
25956 +#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
25957 +#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
25958 +#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
25959 +#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
25960 +#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
25961 +#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
25962 +#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
25963 +#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
25964 +#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
25965 +#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
25966 +#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
25967 +#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
25968 +#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
25969 +#define PCI_PM_CTRL 4 /* PM control and status register */
25970 +#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
25971 +#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
25972 +#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
25973 +#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
25974 +#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
25975 +#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
25976 +#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
25977 +#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
25978 +#define PCI_PM_DATA_REGISTER 7 /* (??) */
25979 +#define PCI_PM_SIZEOF 8
25981 +/* AGP registers */
25983 +#define PCI_AGP_VERSION 2 /* BCD version number */
25984 +#define PCI_AGP_RFU 3 /* Rest of capability flags */
25985 +#define PCI_AGP_STATUS 4 /* Status register */
25986 +#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
25987 +#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
25988 +#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
25989 +#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
25990 +#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
25991 +#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
25992 +#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
25993 +#define PCI_AGP_COMMAND 8 /* Control register */
25994 +#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
25995 +#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
25996 +#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
25997 +#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
25998 +#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
25999 +#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
26000 +#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
26001 +#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
26002 +#define PCI_AGP_SIZEOF 12
26004 +/* Slot Identification */
26006 +#define PCI_SID_ESR 2 /* Expansion Slot Register */
26007 +#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
26008 +#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
26009 +#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
26011 +/* Message Signalled Interrupts registers */
26013 +#define PCI_MSI_FLAGS 2 /* Various flags */
26014 +#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
26015 +#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
26016 +#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
26017 +#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
26018 +#define PCI_MSI_RFU 3 /* Rest of capability flags */
26019 +#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
26020 +#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
26021 +#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
26022 +#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
26024 +#define PCI_SLOT(devfn) ((devfn) >> 3)
26025 #define PCI_FUNC(devfn) ((devfn) & 0x07)
26027 #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
26028 @@ -85,108 +261,97 @@
26029 char chars[16];
26032 -#define KERN_CODE_SEG 0x8 /* This _MUST_ match start.S */
26034 -/* Stuff for asm */
26035 -#define save_flags(x) \
26036 -__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
26038 -#define cli() __asm__ __volatile__ ("cli": : :"memory")
26040 -#define restore_flags(x) \
26041 -__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
26043 -#define PCI_VENDOR_ID_ADMTEK 0x1317
26044 -#define PCI_DEVICE_ID_ADMTEK_0985 0x0985
26045 -#define PCI_VENDOR_ID_REALTEK 0x10ec
26046 -#define PCI_DEVICE_ID_REALTEK_8029 0x8029
26047 -#define PCI_DEVICE_ID_REALTEK_8139 0x8139
26048 -#define PCI_VENDOR_ID_WINBOND2 0x1050
26049 -#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
26050 -#define PCI_DEVICE_ID_WINBOND2_89C840 0x0840
26051 -#define PCI_VENDOR_ID_COMPEX 0x11f6
26052 -#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
26053 -#define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011
26054 -#define PCI_VENDOR_ID_KTI 0x8e2e
26055 -#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
26056 -#define PCI_VENDOR_ID_NETVIN 0x4a14
26057 -#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
26058 -#define PCI_VENDOR_ID_HOLTEK 0x12c3
26059 -#define PCI_DEVICE_ID_HOLTEK_HT80232 0x0058
26060 -#define PCI_VENDOR_ID_3COM 0x10b7
26061 -#define PCI_DEVICE_ID_3COM_3C590 0x5900
26062 -#define PCI_DEVICE_ID_3COM_3C595 0x5950
26063 -#define PCI_DEVICE_ID_3COM_3C595_1 0x5951
26064 -#define PCI_DEVICE_ID_3COM_3C595_2 0x5952
26065 -#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
26066 -#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
26067 -#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
26068 -#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
26069 -#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
26070 -#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200
26071 -#define PCI_VENDOR_ID_INTEL 0x8086
26072 -#define PCI_DEVICE_ID_INTEL_82557 0x1229
26073 -#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
26074 -#define PCI_DEVICE_ID_INTEL_ID1029 0x1029
26075 -#define PCI_DEVICE_ID_INTEL_ID1030 0x1030
26076 -#define PCI_DEVICE_ID_INTEL_82562 0x2449
26077 -#define PCI_VENDOR_ID_AMD 0x1022
26078 -#define PCI_DEVICE_ID_AMD_LANCE 0x2000
26079 -#define PCI_VENDOR_ID_AMD_HOMEPNA 0x1022
26080 -#define PCI_DEVICE_ID_AMD_HOMEPNA 0x2001
26081 -#define PCI_VENDOR_ID_SMC_1211 0x1113
26082 -#define PCI_DEVICE_ID_SMC_1211 0x1211
26083 -#define PCI_VENDOR_ID_DEC 0x1011
26084 -#define PCI_DEVICE_ID_DEC_TULIP 0x0002
26085 -#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
26086 -#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
26087 -#define PCI_DEVICE_ID_DEC_21142 0x0019
26088 -#define PCI_VENDOR_ID_SMC 0x10B8
26089 -#ifndef PCI_DEVICE_ID_SMC_EPIC100
26090 -# define PCI_DEVICE_ID_SMC_EPIC100 0x0005
26091 -#endif
26092 -#define PCI_VENDOR_ID_MACRONIX 0x10d9
26093 -#define PCI_DEVICE_ID_MX987x5 0x0531
26094 -#define PCI_VENDOR_ID_LINKSYS 0x11AD
26095 -#define PCI_DEVICE_ID_LC82C115 0xC115
26096 -#define PCI_VENDOR_ID_VIATEC 0x1106
26097 -#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043
26098 -#define PCI_DEVICE_ID_VIA_VT6102 0x3065
26099 -#define PCI_DEVICE_ID_VIA_86C100A 0x6100
26100 -#define PCI_VENDOR_ID_DAVICOM 0x1282
26101 -#define PCI_DEVICE_ID_DM9009 0x9009
26102 -#define PCI_DEVICE_ID_DM9102 0x9102
26103 -#define PCI_VENDOR_ID_SIS 0x1039
26104 -#define PCI_DEVICE_ID_SIS900 0x0900
26105 -#define PCI_DEVICE_ID_SIS7016 0x7016
26106 -#define PCI_VENDOR_ID_DLINK 0x1186
26107 -#define PCI_DEVICE_ID_DFE530TXP 0x1300
26108 -#define PCI_VENDOR_ID_NS 0x100B
26109 -#define PCI_DEVICE_ID_DP83815 0x0020
26110 -#define PCI_VENDOR_ID_OLICOM 0x108d
26111 -#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
26112 -#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
26113 -#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
26114 -#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
26115 -#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
26116 -#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
26117 +struct pci_device;
26118 +struct dev;
26119 +typedef int (*pci_probe_t)(struct dev *, struct pci_device *);
26121 struct pci_device {
26122 - unsigned short vendor, dev_id;
26123 - const char *name;
26124 - unsigned int membase;
26125 - unsigned short ioaddr;
26126 - unsigned char devfn;
26127 - unsigned char bus;
26128 + uint32_t class;
26129 + uint16_t vendor, dev_id;
26130 + const char *name;
26131 + /* membase and ioaddr are silly and depricated */
26132 + unsigned int membase;
26133 + unsigned int ioaddr;
26134 + unsigned int romaddr;
26135 + unsigned char irq;
26136 + unsigned char devfn;
26137 + unsigned char bus;
26138 + unsigned char use_specified;
26139 + const struct pci_driver *driver;
26142 +extern void scan_pci_bus(int type, struct pci_device *dev);
26143 +extern void find_pci(int type, struct pci_device *dev);
26145 +extern int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn, unsigned int where, uint8_t *value);
26146 +extern int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn, unsigned int where, uint8_t value);
26147 +extern int pcibios_read_config_word(unsigned int bus, unsigned int device_fn, unsigned int where, uint16_t *value);
26148 +extern int pcibios_write_config_word (unsigned int bus, unsigned int device_fn, unsigned int where, uint16_t value);
26149 +extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, uint32_t *value);
26150 +extern int pcibios_write_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, uint32_t value);
26151 +extern unsigned long pcibios_bus_base(unsigned int bus);
26152 +extern void adjust_pci_device(struct pci_device *p);
26155 +static inline int
26156 +pci_read_config_byte(struct pci_device *dev, unsigned int where, uint8_t *value)
26158 + return pcibios_read_config_byte(dev->bus, dev->devfn, where, value);
26160 +static inline int
26161 +pci_write_config_byte(struct pci_device *dev, unsigned int where, uint8_t value)
26163 + return pcibios_write_config_byte(dev->bus, dev->devfn, where, value);
26165 +static inline int
26166 +pci_read_config_word(struct pci_device *dev, unsigned int where, uint16_t *value)
26168 + return pcibios_read_config_word(dev->bus, dev->devfn, where, value);
26170 +static inline int
26171 +pci_write_config_word(struct pci_device *dev, unsigned int where, uint16_t value)
26173 + return pcibios_write_config_word(dev->bus, dev->devfn, where, value);
26175 +static inline int
26176 +pci_read_config_dword(struct pci_device *dev, unsigned int where, uint32_t *value)
26178 + return pcibios_read_config_dword(dev->bus, dev->devfn, where, value);
26180 +static inline int
26181 +pci_write_config_dword(struct pci_device *dev, unsigned int where, uint32_t value)
26183 + return pcibios_write_config_dword(dev->bus, dev->devfn, where, value);
26186 +/* Helper functions to find the size of a pci bar */
26187 +extern unsigned long pci_bar_start(struct pci_device *dev, unsigned int bar);
26188 +extern unsigned long pci_bar_size(struct pci_device *dev, unsigned int bar);
26189 +/* Helper function to find pci capabilities */
26190 +extern int pci_find_capability(struct pci_device *dev, int cap);
26191 +struct pci_id {
26192 + unsigned short vendor, dev_id;
26193 + const char *name;
26196 +struct dev;
26197 +/* Most pci drivers will use this */
26198 +struct pci_driver {
26199 + int type;
26200 + const char *name;
26201 + pci_probe_t probe;
26202 + struct pci_id *ids;
26203 + int id_count;
26205 +/* On a few occasions the hardware is standardized enough that
26206 + * we only need to know the class of the device and not the exact
26207 + * type to drive the device correctly. If this is the case
26208 + * set a class value other than 0.
26209 + */
26210 + unsigned short class;
26213 -extern void eth_pci_init(struct pci_device *);
26214 +#define PCI_ROM(VENDOR_ID, DEVICE_ID, IMAGE, DESCRIPTION) \
26215 + { VENDOR_ID, DEVICE_ID, IMAGE, }
26217 -extern int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char *value);
26218 -extern int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char value);
26219 -extern int pcibios_read_config_word(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short *value);
26220 -extern int pcibios_write_config_word (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short value);
26221 -extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int *value);
26222 -extern int pcibios_write_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value);
26223 -void adjust_pci_device(struct pci_device *p);
26224 #endif /* PCI_H */
26225 Index: b/netboot/pci_ids.h
26226 ===================================================================
26227 --- /dev/null
26228 +++ b/netboot/pci_ids.h
26229 @@ -0,0 +1,1809 @@
26231 + * PCI Class, Vendor and Device IDs
26233 + * Please keep sorted.
26234 + */
26236 +/* Device classes and subclasses */
26238 +#define PCI_CLASS_NOT_DEFINED 0x0000
26239 +#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
26241 +#define PCI_BASE_CLASS_STORAGE 0x01
26242 +#define PCI_CLASS_STORAGE_SCSI 0x0100
26243 +#define PCI_CLASS_STORAGE_IDE 0x0101
26244 +#define PCI_CLASS_STORAGE_FLOPPY 0x0102
26245 +#define PCI_CLASS_STORAGE_IPI 0x0103
26246 +#define PCI_CLASS_STORAGE_RAID 0x0104
26247 +#define PCI_CLASS_STORAGE_OTHER 0x0180
26249 +#define PCI_BASE_CLASS_NETWORK 0x02
26250 +#define PCI_CLASS_NETWORK_ETHERNET 0x0200
26251 +#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
26252 +#define PCI_CLASS_NETWORK_FDDI 0x0202
26253 +#define PCI_CLASS_NETWORK_ATM 0x0203
26254 +#define PCI_CLASS_NETWORK_OTHER 0x0280
26256 +#define PCI_BASE_CLASS_DISPLAY 0x03
26257 +#define PCI_CLASS_DISPLAY_VGA 0x0300
26258 +#define PCI_CLASS_DISPLAY_XGA 0x0301
26259 +#define PCI_CLASS_DISPLAY_3D 0x0302
26260 +#define PCI_CLASS_DISPLAY_OTHER 0x0380
26262 +#define PCI_BASE_CLASS_MULTIMEDIA 0x04
26263 +#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
26264 +#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
26265 +#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402
26266 +#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
26268 +#define PCI_BASE_CLASS_MEMORY 0x05
26269 +#define PCI_CLASS_MEMORY_RAM 0x0500
26270 +#define PCI_CLASS_MEMORY_FLASH 0x0501
26271 +#define PCI_CLASS_MEMORY_OTHER 0x0580
26273 +#define PCI_BASE_CLASS_BRIDGE 0x06
26274 +#define PCI_CLASS_BRIDGE_HOST 0x0600
26275 +#define PCI_CLASS_BRIDGE_ISA 0x0601
26276 +#define PCI_CLASS_BRIDGE_EISA 0x0602
26277 +#define PCI_CLASS_BRIDGE_MC 0x0603
26278 +#define PCI_CLASS_BRIDGE_PCI 0x0604
26279 +#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
26280 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606
26281 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
26282 +#define PCI_CLASS_BRIDGE_RACEWAY 0x0608
26283 +#define PCI_CLASS_BRIDGE_OTHER 0x0680
26285 +#define PCI_BASE_CLASS_COMMUNICATION 0x07
26286 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
26287 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
26288 +#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
26289 +#define PCI_CLASS_COMMUNICATION_MODEM 0x0703
26290 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
26292 +#define PCI_BASE_CLASS_SYSTEM 0x08
26293 +#define PCI_CLASS_SYSTEM_PIC 0x0800
26294 +#define PCI_CLASS_SYSTEM_DMA 0x0801
26295 +#define PCI_CLASS_SYSTEM_TIMER 0x0802
26296 +#define PCI_CLASS_SYSTEM_RTC 0x0803
26297 +#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
26298 +#define PCI_CLASS_SYSTEM_OTHER 0x0880
26300 +#define PCI_BASE_CLASS_INPUT 0x09
26301 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900
26302 +#define PCI_CLASS_INPUT_PEN 0x0901
26303 +#define PCI_CLASS_INPUT_MOUSE 0x0902
26304 +#define PCI_CLASS_INPUT_SCANNER 0x0903
26305 +#define PCI_CLASS_INPUT_GAMEPORT 0x0904
26306 +#define PCI_CLASS_INPUT_OTHER 0x0980
26308 +#define PCI_BASE_CLASS_DOCKING 0x0a
26309 +#define PCI_CLASS_DOCKING_GENERIC 0x0a00
26310 +#define PCI_CLASS_DOCKING_OTHER 0x0a80
26312 +#define PCI_BASE_CLASS_PROCESSOR 0x0b
26313 +#define PCI_CLASS_PROCESSOR_386 0x0b00
26314 +#define PCI_CLASS_PROCESSOR_486 0x0b01
26315 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
26316 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
26317 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
26318 +#define PCI_CLASS_PROCESSOR_MIPS 0x0b30
26319 +#define PCI_CLASS_PROCESSOR_CO 0x0b40
26321 +#define PCI_BASE_CLASS_SERIAL 0x0c
26322 +#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
26323 +#define PCI_CLASS_SERIAL_ACCESS 0x0c01
26324 +#define PCI_CLASS_SERIAL_SSA 0x0c02
26325 +#define PCI_CLASS_SERIAL_USB 0x0c03
26326 +#define PCI_CLASS_SERIAL_FIBER 0x0c04
26327 +#define PCI_CLASS_SERIAL_SMBUS 0x0c05
26329 +#define PCI_BASE_CLASS_INTELLIGENT 0x0e
26330 +#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
26332 +#define PCI_BASE_CLASS_SATELLITE 0x0f
26333 +#define PCI_CLASS_SATELLITE_TV 0x0f00
26334 +#define PCI_CLASS_SATELLITE_AUDIO 0x0f01
26335 +#define PCI_CLASS_SATELLITE_VOICE 0x0f03
26336 +#define PCI_CLASS_SATELLITE_DATA 0x0f04
26338 +#define PCI_BASE_CLASS_CRYPT 0x10
26339 +#define PCI_CLASS_CRYPT_NETWORK 0x1000
26340 +#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001
26341 +#define PCI_CLASS_CRYPT_OTHER 0x1080
26343 +#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
26344 +#define PCI_CLASS_SP_DPIO 0x1100
26345 +#define PCI_CLASS_SP_OTHER 0x1180
26347 +#define PCI_CLASS_OTHERS 0xff
26349 +/* Vendors and devices. Sort key: vendor first, device next. */
26351 +#define PCI_VENDOR_ID_DYNALINK 0x0675
26352 +#define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702
26354 +#define PCI_VENDOR_ID_BERKOM 0x0871
26355 +#define PCI_DEVICE_ID_BERKOM_A1T 0xffa1
26356 +#define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2
26357 +#define PCI_DEVICE_ID_BERKOM_A4T 0xffa4
26358 +#define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO 0xffa8
26360 +#define PCI_VENDOR_ID_COMPAQ 0x0e11
26361 +#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508
26362 +#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
26363 +#define PCI_DEVICE_ID_COMPAQ_TRIFLEX 0x4000
26364 +#define PCI_DEVICE_ID_COMPAQ_6010 0x6010
26365 +#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
26366 +#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
26367 +#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
26368 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35
26369 +#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
26370 +#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43
26371 +#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
26372 +#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060
26373 +#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178
26374 +#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
26375 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150
26377 +#define PCI_VENDOR_ID_NCR 0x1000
26378 +#define PCI_VENDOR_ID_LSI_LOGIC 0x1000
26379 +#define PCI_DEVICE_ID_NCR_53C810 0x0001
26380 +#define PCI_DEVICE_ID_NCR_53C820 0x0002
26381 +#define PCI_DEVICE_ID_NCR_53C825 0x0003
26382 +#define PCI_DEVICE_ID_NCR_53C815 0x0004
26383 +#define PCI_DEVICE_ID_LSI_53C810AP 0x0005
26384 +#define PCI_DEVICE_ID_NCR_53C860 0x0006
26385 +#define PCI_DEVICE_ID_LSI_53C1510 0x000a
26386 +#define PCI_DEVICE_ID_NCR_53C896 0x000b
26387 +#define PCI_DEVICE_ID_NCR_53C895 0x000c
26388 +#define PCI_DEVICE_ID_NCR_53C885 0x000d
26389 +#define PCI_DEVICE_ID_NCR_53C875 0x000f
26390 +#define PCI_DEVICE_ID_NCR_53C1510 0x0010
26391 +#define PCI_DEVICE_ID_LSI_53C895A 0x0012
26392 +#define PCI_DEVICE_ID_LSI_53C875A 0x0013
26393 +#define PCI_DEVICE_ID_LSI_53C1010_33 0x0020
26394 +#define PCI_DEVICE_ID_LSI_53C1010_66 0x0021
26395 +#define PCI_DEVICE_ID_LSI_53C1030 0x0030
26396 +#define PCI_DEVICE_ID_LSI_53C1035 0x0040
26397 +#define PCI_DEVICE_ID_NCR_53C875J 0x008f
26398 +#define PCI_DEVICE_ID_LSI_FC909 0x0621
26399 +#define PCI_DEVICE_ID_LSI_FC929 0x0622
26400 +#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623
26401 +#define PCI_DEVICE_ID_LSI_FC919 0x0624
26402 +#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625
26403 +#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
26404 +#define PCI_DEVICE_ID_LSI_61C102 0x0901
26405 +#define PCI_DEVICE_ID_LSI_63C815 0x1000
26407 +#define PCI_VENDOR_ID_ATI 0x1002
26408 +/* Mach64 */
26409 +#define PCI_DEVICE_ID_ATI_68800 0x4158
26410 +#define PCI_DEVICE_ID_ATI_215CT222 0x4354
26411 +#define PCI_DEVICE_ID_ATI_210888CX 0x4358
26412 +#define PCI_DEVICE_ID_ATI_215ET222 0x4554
26413 +/* Mach64 / Rage */
26414 +#define PCI_DEVICE_ID_ATI_215GB 0x4742
26415 +#define PCI_DEVICE_ID_ATI_215GD 0x4744
26416 +#define PCI_DEVICE_ID_ATI_215GI 0x4749
26417 +#define PCI_DEVICE_ID_ATI_215GP 0x4750
26418 +#define PCI_DEVICE_ID_ATI_215GQ 0x4751
26419 +#define PCI_DEVICE_ID_ATI_215XL 0x4752
26420 +#define PCI_DEVICE_ID_ATI_215GT 0x4754
26421 +#define PCI_DEVICE_ID_ATI_215GTB 0x4755
26422 +#define PCI_DEVICE_ID_ATI_215_IV 0x4756
26423 +#define PCI_DEVICE_ID_ATI_215_IW 0x4757
26424 +#define PCI_DEVICE_ID_ATI_215_IZ 0x475A
26425 +#define PCI_DEVICE_ID_ATI_210888GX 0x4758
26426 +#define PCI_DEVICE_ID_ATI_215_LB 0x4c42
26427 +#define PCI_DEVICE_ID_ATI_215_LD 0x4c44
26428 +#define PCI_DEVICE_ID_ATI_215_LG 0x4c47
26429 +#define PCI_DEVICE_ID_ATI_215_LI 0x4c49
26430 +#define PCI_DEVICE_ID_ATI_215_LM 0x4c4D
26431 +#define PCI_DEVICE_ID_ATI_215_LN 0x4c4E
26432 +#define PCI_DEVICE_ID_ATI_215_LR 0x4c52
26433 +#define PCI_DEVICE_ID_ATI_215_LS 0x4c53
26434 +#define PCI_DEVICE_ID_ATI_264_LT 0x4c54
26435 +/* Mach64 VT */
26436 +#define PCI_DEVICE_ID_ATI_264VT 0x5654
26437 +#define PCI_DEVICE_ID_ATI_264VU 0x5655
26438 +#define PCI_DEVICE_ID_ATI_264VV 0x5656
26439 +/* Rage128 Pro GL */
26440 +#define PCI_DEVICE_ID_ATI_Rage128_PA 0x5041
26441 +#define PCI_DEVICE_ID_ATI_Rage128_PB 0x5042
26442 +#define PCI_DEVICE_ID_ATI_Rage128_PC 0x5043
26443 +#define PCI_DEVICE_ID_ATI_Rage128_PD 0x5044
26444 +#define PCI_DEVICE_ID_ATI_Rage128_PE 0x5045
26445 +#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046
26446 +/* Rage128 Pro VR */
26447 +#define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047
26448 +#define PCI_DEVICE_ID_ATI_RAGE128_PH 0x5048
26449 +#define PCI_DEVICE_ID_ATI_RAGE128_PI 0x5049
26450 +#define PCI_DEVICE_ID_ATI_RAGE128_PJ 0x504A
26451 +#define PCI_DEVICE_ID_ATI_RAGE128_PK 0x504B
26452 +#define PCI_DEVICE_ID_ATI_RAGE128_PL 0x504C
26453 +#define PCI_DEVICE_ID_ATI_RAGE128_PM 0x504D
26454 +#define PCI_DEVICE_ID_ATI_RAGE128_PN 0x504E
26455 +#define PCI_DEVICE_ID_ATI_RAGE128_PO 0x504F
26456 +#define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050
26457 +#define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051
26458 +#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052
26459 +#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452
26460 +#define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053
26461 +#define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054
26462 +#define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055
26463 +#define PCI_DEVICE_ID_ATI_RAGE128_PV 0x5056
26464 +#define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057
26465 +#define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058
26466 +/* Rage128 GL */
26467 +#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245
26468 +#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246
26469 +#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x534b
26470 +#define PCI_DEVICE_ID_ATI_RAGE128_RH 0x534c
26471 +#define PCI_DEVICE_ID_ATI_RAGE128_RI 0x534d
26472 +/* Rage128 VR */
26473 +#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b
26474 +#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c
26475 +#define PCI_DEVICE_ID_ATI_RAGE128_RM 0x5345
26476 +#define PCI_DEVICE_ID_ATI_RAGE128_RN 0x5346
26477 +#define PCI_DEVICE_ID_ATI_RAGE128_RO 0x5347
26478 +/* Rage128 M3 */
26479 +#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45
26480 +#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46
26481 +/* Rage128 Pro Ultra */
26482 +#define PCI_DEVICE_ID_ATI_RAGE128_U1 0x5446
26483 +#define PCI_DEVICE_ID_ATI_RAGE128_U2 0x544C
26484 +#define PCI_DEVICE_ID_ATI_RAGE128_U3 0x5452
26485 +/* Radeon M4 */
26486 +#define PCI_DEVICE_ID_ATI_RADEON_LE 0x4d45
26487 +#define PCI_DEVICE_ID_ATI_RADEON_LF 0x4d46
26488 +/* Radeon NV-100 */
26489 +#define PCI_DEVICE_ID_ATI_RADEON_N1 0x5159
26490 +#define PCI_DEVICE_ID_ATI_RADEON_N2 0x515a
26491 +/* Radeon */
26492 +#define PCI_DEVICE_ID_ATI_RADEON_RA 0x5144
26493 +#define PCI_DEVICE_ID_ATI_RADEON_RB 0x5145
26494 +#define PCI_DEVICE_ID_ATI_RADEON_RC 0x5146
26495 +#define PCI_DEVICE_ID_ATI_RADEON_RD 0x5147
26497 +#define PCI_VENDOR_ID_VLSI 0x1004
26498 +#define PCI_DEVICE_ID_VLSI_82C592 0x0005
26499 +#define PCI_DEVICE_ID_VLSI_82C593 0x0006
26500 +#define PCI_DEVICE_ID_VLSI_82C594 0x0007
26501 +#define PCI_DEVICE_ID_VLSI_82C597 0x0009
26502 +#define PCI_DEVICE_ID_VLSI_82C541 0x000c
26503 +#define PCI_DEVICE_ID_VLSI_82C543 0x000d
26504 +#define PCI_DEVICE_ID_VLSI_82C532 0x0101
26505 +#define PCI_DEVICE_ID_VLSI_82C534 0x0102
26506 +#define PCI_DEVICE_ID_VLSI_82C535 0x0104
26507 +#define PCI_DEVICE_ID_VLSI_82C147 0x0105
26508 +#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702
26510 +#define PCI_VENDOR_ID_ADL 0x1005
26511 +#define PCI_DEVICE_ID_ADL_2301 0x2301
26513 +#define PCI_VENDOR_ID_NS 0x100b
26514 +#define PCI_DEVICE_ID_NS_87415 0x0002
26515 +#define PCI_DEVICE_ID_NS_87560_LIO 0x000e
26516 +#define PCI_DEVICE_ID_NS_87560_USB 0x0012
26517 +#define PCI_DEVICE_ID_NS_83815 0x0020
26518 +#define PCI_DEVICE_ID_DP83815 0x0020
26519 +#define PCI_DEVICE_ID_NS_83820 0x0022
26520 +#define PCI_DEVICE_ID_NS_87410 0xd001
26522 +#define PCI_VENDOR_ID_TSENG 0x100c
26523 +#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
26524 +#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205
26525 +#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206
26526 +#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207
26527 +#define PCI_DEVICE_ID_TSENG_ET6000 0x3208
26529 +#define PCI_VENDOR_ID_WEITEK 0x100e
26530 +#define PCI_DEVICE_ID_WEITEK_P9000 0x9001
26531 +#define PCI_DEVICE_ID_WEITEK_P9100 0x9100
26533 +#define PCI_VENDOR_ID_DEC 0x1011
26534 +#define PCI_DEVICE_ID_DEC_BRD 0x0001
26535 +#define PCI_DEVICE_ID_DEC_TULIP 0x0002
26536 +#define PCI_DEVICE_ID_DEC_TGA 0x0004
26537 +#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
26538 +#define PCI_DEVICE_ID_DEC_TGA2 0x000D
26539 +#define PCI_DEVICE_ID_DEC_FDDI 0x000F
26540 +#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
26541 +#define PCI_DEVICE_ID_DEC_21142 0x0019
26542 +#define PCI_DEVICE_ID_DEC_21052 0x0021
26543 +#define PCI_DEVICE_ID_DEC_21150 0x0022
26544 +#define PCI_DEVICE_ID_DEC_21152 0x0024
26545 +#define PCI_DEVICE_ID_DEC_21153 0x0025
26546 +#define PCI_DEVICE_ID_DEC_21154 0x0026
26547 +#define PCI_DEVICE_ID_DEC_21285 0x1065
26548 +#define PCI_DEVICE_ID_COMPAQ_42XX 0x0046
26550 +#define PCI_VENDOR_ID_CIRRUS 0x1013
26551 +#define PCI_DEVICE_ID_CIRRUS_7548 0x0038
26552 +#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0
26553 +#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4
26554 +#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8
26555 +#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac
26556 +#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8
26557 +#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc
26558 +#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0
26559 +#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4
26560 +#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6
26561 +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
26562 +#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
26563 +#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
26564 +#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
26565 +#define PCI_DEVICE_ID_CIRRUS_7541 0x1204
26567 +#define PCI_VENDOR_ID_IBM 0x1014
26568 +#define PCI_DEVICE_ID_IBM_FIRE_CORAL 0x000a
26569 +#define PCI_DEVICE_ID_IBM_TR 0x0018
26570 +#define PCI_DEVICE_ID_IBM_82G2675 0x001d
26571 +#define PCI_DEVICE_ID_IBM_MCA 0x0020
26572 +#define PCI_DEVICE_ID_IBM_82351 0x0022
26573 +#define PCI_DEVICE_ID_IBM_PYTHON 0x002d
26574 +#define PCI_DEVICE_ID_IBM_SERVERAID 0x002e
26575 +#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
26576 +#define PCI_DEVICE_ID_IBM_MPIC 0x0046
26577 +#define PCI_DEVICE_ID_IBM_3780IDSP 0x007d
26578 +#define PCI_DEVICE_ID_IBM_CHUKAR 0x0096
26579 +#define PCI_DEVICE_ID_IBM_405GP 0x0156
26580 +#define PCI_DEVICE_ID_IBM_SERVERAIDI960 0x01bd
26581 +#define PCI_DEVICE_ID_IBM_MPIC_2 0xffff
26583 +#define PCI_VENDOR_ID_COMPEX2 0x101a // pci.ids says "AT&T GIS (NCR)"
26584 +#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
26586 +#define PCI_VENDOR_ID_WD 0x101c
26587 +#define PCI_DEVICE_ID_WD_7197 0x3296
26589 +#define PCI_VENDOR_ID_AMI 0x101e
26590 +#define PCI_DEVICE_ID_AMI_MEGARAID3 0x1960
26591 +#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010
26592 +#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060
26594 +#define PCI_VENDOR_ID_AMD 0x1022
26596 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000
26597 +#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
26598 +#define PCI_DEVICE_ID_AMD_HOMEPNA 0x2001
26599 +#define PCI_DEVICE_ID_AMD_SCSI 0x2020
26600 +#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006
26601 +#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007
26602 +#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C
26603 +#define PCI_DEVIDE_ID_AMD_FE_GATE_700D 0x700D
26604 +#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E
26605 +#define PCI_DEVICE_ID_AMD_FE_GATE_700F 0x700F
26606 +#define PCI_DEVICE_ID_AMD_COBRA_7400 0x7400
26607 +#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401
26608 +#define PCI_DEVICE_ID_AMD_COBRA_7403 0x7403
26609 +#define PCI_DEVICE_ID_AMD_COBRA_7404 0x7404
26610 +#define PCI_DEVICE_ID_AMD_VIPER_7408 0x7408
26611 +#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409
26612 +#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B
26613 +#define PCI_DEVICE_ID_AMD_VIPER_740C 0x740C
26614 +#define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410
26615 +#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411
26616 +#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413
26617 +#define PCI_DEVICE_ID_AMD_VIPER_7414 0x7414
26618 +#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440
26619 +#define PCI_DEVICE_ID_AMD_VIPER_7441 0x7441
26620 +#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443
26621 +#define PCI_DEVICE_ID_AMD_VIPER_7448 0x7448
26622 +#define PCI_DEVICE_ID_AMD_VIPER_7449 0x7449
26624 +#define PCI_VENDOR_ID_TRIDENT 0x1023
26625 +#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
26626 +#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
26627 +#define PCI_DEVICE_ID_TRIDENT_9320 0x9320
26628 +#define PCI_DEVICE_ID_TRIDENT_9388 0x9388
26629 +#define PCI_DEVICE_ID_TRIDENT_9397 0x9397
26630 +#define PCI_DEVICE_ID_TRIDENT_939A 0x939A
26631 +#define PCI_DEVICE_ID_TRIDENT_9520 0x9520
26632 +#define PCI_DEVICE_ID_TRIDENT_9525 0x9525
26633 +#define PCI_DEVICE_ID_TRIDENT_9420 0x9420
26634 +#define PCI_DEVICE_ID_TRIDENT_9440 0x9440
26635 +#define PCI_DEVICE_ID_TRIDENT_9660 0x9660
26636 +#define PCI_DEVICE_ID_TRIDENT_9750 0x9750
26637 +#define PCI_DEVICE_ID_TRIDENT_9850 0x9850
26638 +#define PCI_DEVICE_ID_TRIDENT_9880 0x9880
26639 +#define PCI_DEVICE_ID_TRIDENT_8400 0x8400
26640 +#define PCI_DEVICE_ID_TRIDENT_8420 0x8420
26641 +#define PCI_DEVICE_ID_TRIDENT_8500 0x8500
26643 +#define PCI_VENDOR_ID_AI 0x1025
26644 +#define PCI_DEVICE_ID_AI_M1435 0x1435
26646 +#define PCI_VENDOR_ID_DELL 0x1028
26648 +#define PCI_VENDOR_ID_MATROX 0x102B
26649 +#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
26650 +#define PCI_DEVICE_ID_MATROX_MIL 0x0519
26651 +#define PCI_DEVICE_ID_MATROX_MYS 0x051A
26652 +#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b
26653 +#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
26654 +#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10
26655 +#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000
26656 +#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001
26657 +#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520
26658 +#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521
26659 +#define PCI_DEVICE_ID_MATROX_G400 0x0525
26660 +#define PCI_DEVICE_ID_MATROX_G550 0x2527
26661 +#define PCI_DEVICE_ID_MATROX_VIA 0x4536
26663 +#define PCI_VENDOR_ID_CT 0x102c
26664 +#define PCI_DEVICE_ID_CT_65545 0x00d8
26665 +#define PCI_DEVICE_ID_CT_65548 0x00dc
26666 +#define PCI_DEVICE_ID_CT_65550 0x00e0
26667 +#define PCI_DEVICE_ID_CT_65554 0x00e4
26668 +#define PCI_DEVICE_ID_CT_65555 0x00e5
26670 +#define PCI_VENDOR_ID_MIRO 0x1031
26671 +#define PCI_DEVICE_ID_MIRO_36050 0x5601
26673 +#define PCI_VENDOR_ID_NEC 0x1033
26674 +#define PCI_DEVICE_ID_NEC_PCX2 0x0046
26675 +#define PCI_DEVICE_ID_NEC_NILE4 0x005a
26676 +#define PCI_DEVICE_ID_NEC_VRC5476 0x009b
26678 +#define PCI_VENDOR_ID_FD 0x1036
26679 +#define PCI_DEVICE_ID_FD_36C70 0x0000
26681 +#define PCI_VENDOR_ID_SIS 0x1039
26682 +#define PCI_VENDOR_ID_SI 0x1039
26683 +#define PCI_DEVICE_ID_SI_5591_AGP 0x0001
26684 +#define PCI_DEVICE_ID_SI_6202 0x0002
26685 +#define PCI_DEVICE_ID_SI_503 0x0008
26686 +#define PCI_DEVICE_ID_SI_ACPI 0x0009
26687 +#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
26688 +#define PCI_DEVICE_ID_SI_6205 0x0205
26689 +#define PCI_DEVICE_ID_SI_501 0x0406
26690 +#define PCI_DEVICE_ID_SI_496 0x0496
26691 +#define PCI_DEVICE_ID_SI_300 0x0300
26692 +#define PCI_DEVICE_ID_SI_315H 0x0310
26693 +#define PCI_DEVICE_ID_SI_315 0x0315
26694 +#define PCI_DEVICE_ID_SI_315PRO 0x0325
26695 +#define PCI_DEVICE_ID_SI_530 0x0530
26696 +#define PCI_DEVICE_ID_SI_540 0x0540
26697 +#define PCI_DEVICE_ID_SI_550 0x0550
26698 +#define PCI_DEVICE_ID_SI_601 0x0601
26699 +#define PCI_DEVICE_ID_SI_620 0x0620
26700 +#define PCI_DEVICE_ID_SI_630 0x0630
26701 +#define PCI_DEVICE_ID_SI_635 0x0635
26702 +#define PCI_DEVICE_ID_SI_640 0x0640
26703 +#define PCI_DEVICE_ID_SI_645 0x0645
26704 +#define PCI_DEVICE_ID_SI_650 0x0650
26705 +#define PCI_DEVICE_ID_SI_730 0x0730
26706 +#define PCI_DEVICE_ID_SI_735 0x0735
26707 +#define PCI_DEVICE_ID_SI_740 0x0740
26708 +#define PCI_DEVICE_ID_SI_745 0x0745
26709 +#define PCI_DEVICE_ID_SI_750 0x0750
26710 +#define PCI_DEVICE_ID_SI_900 0x0900
26711 +#define PCI_DEVICE_ID_SIS900 0x0900
26712 +#define PCI_DEVICE_ID_SI_5107 0x5107
26713 +#define PCI_DEVICE_ID_SI_5300 0x5300
26714 +#define PCI_DEVICE_ID_SI_540_VGA 0x5300
26715 +#define PCI_DEVICE_ID_SI_550_VGA 0x5315
26716 +#define PCI_DEVICE_ID_SI_5511 0x5511
26717 +#define PCI_DEVICE_ID_SI_5513 0x5513
26718 +#define PCI_DEVICE_ID_SI_5571 0x5571
26719 +#define PCI_DEVICE_ID_SI_5591 0x5591
26720 +#define PCI_DEVICE_ID_SI_5597 0x5597
26721 +#define PCI_DEVICE_ID_SI_5598 0x5598
26722 +#define PCI_DEVICE_ID_SI_5600 0x5600
26723 +#define PCI_DEVICE_ID_SI_6300 0x6300
26724 +#define PCI_DEVICE_ID_SI_630_VGA 0x6300
26725 +#define PCI_DEVICE_ID_SI_6306 0x6306
26726 +#define PCI_DEVICE_ID_SI_6326 0x6326
26727 +#define PCI_DEVICE_ID_SI_7001 0x7001
26728 +#define PCI_DEVICE_ID_SI_7016 0x7016
26729 +#define PCI_DEVICE_ID_SIS7016 0x7016
26730 +#define PCI_DEVICE_ID_SI_730_VGA 0x7300
26732 +#define PCI_VENDOR_ID_HP 0x103c
26733 +#define PCI_DEVICE_ID_HP_DONNER_GFX 0x1008
26734 +#define PCI_DEVICE_ID_HP_TACHYON 0x1028
26735 +#define PCI_DEVICE_ID_HP_TACHLITE 0x1029
26736 +#define PCI_DEVICE_ID_HP_J2585A 0x1030
26737 +#define PCI_DEVICE_ID_HP_J2585B 0x1031
26738 +#define PCI_DEVICE_ID_HP_SAS 0x1048
26739 +#define PCI_DEVICE_ID_HP_DIVA1 0x1049
26740 +#define PCI_DEVICE_ID_HP_DIVA2 0x104A
26741 +#define PCI_DEVICE_ID_HP_SP2_0 0x104B
26743 +#define PCI_VENDOR_ID_PCTECH 0x1042
26744 +#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
26745 +#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001
26746 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_0 0x3000
26747 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_1 0x3010
26748 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
26750 +#define PCI_VENDOR_ID_ASUSTEK 0x1043
26751 +#define PCI_DEVICE_ID_ASUSTEK_0675 0x0675
26753 +#define PCI_VENDOR_ID_DPT 0x1044
26754 +#define PCI_DEVICE_ID_DPT 0xa400
26756 +#define PCI_VENDOR_ID_OPTI 0x1045
26757 +#define PCI_DEVICE_ID_OPTI_92C178 0xc178
26758 +#define PCI_DEVICE_ID_OPTI_82C557 0xc557
26759 +#define PCI_DEVICE_ID_OPTI_82C558 0xc558
26760 +#define PCI_DEVICE_ID_OPTI_82C621 0xc621
26761 +#define PCI_DEVICE_ID_OPTI_82C700 0xc700
26762 +#define PCI_DEVICE_ID_OPTI_82C701 0xc701
26763 +#define PCI_DEVICE_ID_OPTI_82C814 0xc814
26764 +#define PCI_DEVICE_ID_OPTI_82C822 0xc822
26765 +#define PCI_DEVICE_ID_OPTI_82C861 0xc861
26766 +#define PCI_DEVICE_ID_OPTI_82C825 0xd568
26768 +#define PCI_VENDOR_ID_ELSA 0x1048
26769 +#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000
26770 +#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
26772 +#define PCI_VENDOR_ID_ELSA 0x1048
26773 +#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000
26774 +#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
26776 +#define PCI_VENDOR_ID_SGS 0x104a
26777 +#define PCI_DEVICE_ID_SGS_2000 0x0008
26778 +#define PCI_DEVICE_ID_SGS_1764 0x0009
26780 +#define PCI_VENDOR_ID_BUSLOGIC 0x104B
26781 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
26782 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
26783 +#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130
26785 +#define PCI_VENDOR_ID_TI 0x104c
26786 +#define PCI_DEVICE_ID_TI_TVP4010 0x3d04
26787 +#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
26788 +#define PCI_DEVICE_ID_TI_1130 0xac12
26789 +#define PCI_DEVICE_ID_TI_1031 0xac13
26790 +#define PCI_DEVICE_ID_TI_1131 0xac15
26791 +#define PCI_DEVICE_ID_TI_1250 0xac16
26792 +#define PCI_DEVICE_ID_TI_1220 0xac17
26793 +#define PCI_DEVICE_ID_TI_1221 0xac19
26794 +#define PCI_DEVICE_ID_TI_1210 0xac1a
26795 +#define PCI_DEVICE_ID_TI_1410 0xac50
26796 +#define PCI_DEVICE_ID_TI_1450 0xac1b
26797 +#define PCI_DEVICE_ID_TI_1225 0xac1c
26798 +#define PCI_DEVICE_ID_TI_1251A 0xac1d
26799 +#define PCI_DEVICE_ID_TI_1211 0xac1e
26800 +#define PCI_DEVICE_ID_TI_1251B 0xac1f
26801 +#define PCI_DEVICE_ID_TI_4410 0xac41
26802 +#define PCI_DEVICE_ID_TI_4451 0xac42
26803 +#define PCI_DEVICE_ID_TI_1420 0xac51
26805 +#define PCI_VENDOR_ID_SONY 0x104d
26806 +#define PCI_DEVICE_ID_SONY_CXD3222 0x8039
26808 +#define PCI_VENDOR_ID_OAK 0x104e
26809 +#define PCI_DEVICE_ID_OAK_OTI107 0x0107
26811 +/* Winbond have two vendor IDs! See 0x10ad as well */
26812 +#define PCI_VENDOR_ID_WINBOND2 0x1050
26813 +#define PCI_DEVICE_ID_WINBOND2_89C840 0x0840
26814 +#define PCI_DEVICE_ID_WINBOND2_89C940 0x0940
26815 +#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a
26816 +#define PCI_DEVICE_ID_WINBOND2_6692 0x6692
26818 +#define PCI_VENDOR_ID_ANIGMA 0x1051
26819 +#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100
26821 +#define PCI_VENDOR_ID_EFAR 0x1055
26822 +#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130
26823 +#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
26824 +#define PCI_DEVICE_ID_EFAR_SLC90E66_2 0x9462
26825 +#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463
26827 +#define PCI_VENDOR_ID_MOTOROLA 0x1057
26828 +#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507
26829 +#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
26830 +#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
26831 +#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
26832 +#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802
26833 +#define PCI_DEVICE_ID_MOTOROLA_CPX8216 0x4806
26835 +#define PCI_VENDOR_ID_PROMISE 0x105a
26836 +#define PCI_DEVICE_ID_PROMISE_20265 0x0d30
26837 +#define PCI_DEVICE_ID_PROMISE_20267 0x4d30
26838 +#define PCI_DEVICE_ID_PROMISE_20246 0x4d33
26839 +#define PCI_DEVICE_ID_PROMISE_20262 0x4d38
26840 +#define PCI_DEVICE_ID_PROMISE_20268 0x4d68
26841 +#define PCI_DEVICE_ID_PROMISE_20268R 0x6268
26842 +#define PCI_DEVICE_ID_PROMISE_20269 0x4d69
26843 +#define PCI_DEVICE_ID_PROMISE_20275 0x1275
26844 +#define PCI_DEVICE_ID_PROMISE_5300 0x5300
26846 +#define PCI_VENDOR_ID_N9 0x105d
26847 +#define PCI_DEVICE_ID_N9_I128 0x2309
26848 +#define PCI_DEVICE_ID_N9_I128_2 0x2339
26849 +#define PCI_DEVICE_ID_N9_I128_T2R 0x493d
26851 +#define PCI_VENDOR_ID_UMC 0x1060
26852 +#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
26853 +#define PCI_DEVICE_ID_UMC_UM8891A 0x0891
26854 +#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
26855 +#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
26856 +#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
26857 +#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
26858 +#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
26859 +#define PCI_DEVICE_ID_UMC_UM8886N 0xe886
26860 +#define PCI_DEVICE_ID_UMC_UM8891N 0xe891
26862 +#define PCI_VENDOR_ID_X 0x1061
26863 +#define PCI_DEVICE_ID_X_AGX016 0x0001
26865 +#define PCI_VENDOR_ID_MYLEX 0x1069
26866 +#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001
26867 +#define PCI_DEVICE_ID_MYLEX_DAC960_PD 0x0002
26868 +#define PCI_DEVICE_ID_MYLEX_DAC960_PG 0x0010
26869 +#define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020
26870 +#define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050
26871 +#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56
26873 +#define PCI_VENDOR_ID_PICOP 0x1066
26874 +#define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001
26875 +#define PCI_DEVICE_ID_PICOP_PT80C524 0x8002
26877 +#define PCI_VENDOR_ID_APPLE 0x106b
26878 +#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
26879 +#define PCI_DEVICE_ID_APPLE_GC 0x0002
26880 +#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
26881 +#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018
26882 +#define PCI_DEVICE_ID_APPLE_KL_USB 0x0019
26883 +#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
26884 +#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
26885 +#define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030
26887 +#define PCI_VENDOR_ID_YAMAHA 0x1073
26888 +#define PCI_DEVICE_ID_YAMAHA_724 0x0004
26889 +#define PCI_DEVICE_ID_YAMAHA_724F 0x000d
26890 +#define PCI_DEVICE_ID_YAMAHA_740 0x000a
26891 +#define PCI_DEVICE_ID_YAMAHA_740C 0x000c
26892 +#define PCI_DEVICE_ID_YAMAHA_744 0x0010
26893 +#define PCI_DEVICE_ID_YAMAHA_754 0x0012
26895 +#define PCI_VENDOR_ID_NEXGEN 0x1074
26896 +#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
26898 +#define PCI_VENDOR_ID_QLOGIC 0x1077
26899 +#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
26900 +#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022
26901 +#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100
26902 +#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200
26904 +#define PCI_VENDOR_ID_CYRIX 0x1078
26905 +#define PCI_DEVICE_ID_CYRIX_5510 0x0000
26906 +#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001
26907 +#define PCI_DEVICE_ID_CYRIX_5520 0x0002
26908 +#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100
26909 +#define PCI_DEVICE_ID_CYRIX_5530_SMI 0x0101
26910 +#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102
26911 +#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
26912 +#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
26914 +#define PCI_VENDOR_ID_LEADTEK 0x107d
26915 +#define PCI_DEVICE_ID_LEADTEK_805 0x0000
26917 +#define PCI_VENDOR_ID_INTERPHASE 0x107e
26918 +#define PCI_DEVICE_ID_INTERPHASE_5526 0x0004
26919 +#define PCI_DEVICE_ID_INTERPHASE_55x6 0x0005
26920 +#define PCI_DEVICE_ID_INTERPHASE_5575 0x0008
26922 +#define PCI_VENDOR_ID_CONTAQ 0x1080
26923 +#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
26924 +#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
26926 +#define PCI_VENDOR_ID_FOREX 0x1083
26928 +#define PCI_VENDOR_ID_OLICOM 0x108d
26929 +#define PCI_DEVICE_ID_OLICOM_OC3136 0x0001
26930 +#define PCI_DEVICE_ID_OLICOM_OC2315 0x0011
26931 +#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
26932 +#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
26933 +#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
26934 +#define PCI_DEVICE_ID_OLICOM_OC6151 0x0021
26936 +#define PCI_VENDOR_ID_SUN 0x108e
26937 +#define PCI_DEVICE_ID_SUN_EBUS 0x1000
26938 +#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001
26939 +#define PCI_DEVICE_ID_SUN_RIO_EBUS 0x1100
26940 +#define PCI_DEVICE_ID_SUN_RIO_GEM 0x1101
26941 +#define PCI_DEVICE_ID_SUN_RIO_1394 0x1102
26942 +#define PCI_DEVICE_ID_SUN_RIO_USB 0x1103
26943 +#define PCI_DEVICE_ID_SUN_GEM 0x2bad
26944 +#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
26945 +#define PCI_DEVICE_ID_SUN_PBM 0x8000
26946 +#define PCI_DEVICE_ID_SUN_SCHIZO 0x8001
26947 +#define PCI_DEVICE_ID_SUN_SABRE 0xa000
26948 +#define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001
26950 +#define PCI_VENDOR_ID_CMD 0x1095
26951 +#define PCI_DEVICE_ID_CMD_640 0x0640
26952 +#define PCI_DEVICE_ID_CMD_643 0x0643
26953 +#define PCI_DEVICE_ID_CMD_646 0x0646
26954 +#define PCI_DEVICE_ID_CMD_647 0x0647
26955 +#define PCI_DEVICE_ID_CMD_648 0x0648
26956 +#define PCI_DEVICE_ID_CMD_649 0x0649
26957 +#define PCI_DEVICE_ID_CMD_670 0x0670
26958 +#define PCI_DEVICE_ID_CMD_680 0x0680
26960 +#define PCI_VENDOR_ID_VISION 0x1098
26961 +#define PCI_DEVICE_ID_VISION_QD8500 0x0001
26962 +#define PCI_DEVICE_ID_VISION_QD8580 0x0002
26964 +#define PCI_VENDOR_ID_BROOKTREE 0x109e
26965 +#define PCI_DEVICE_ID_BROOKTREE_848 0x0350
26966 +#define PCI_DEVICE_ID_BROOKTREE_849A 0x0351
26967 +#define PCI_DEVICE_ID_BROOKTREE_878_1 0x036e
26968 +#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
26969 +#define PCI_DEVICE_ID_BROOKTREE_8474 0x8474
26971 +#define PCI_VENDOR_ID_SIERRA 0x10a8
26972 +#define PCI_DEVICE_ID_SIERRA_STB 0x0000
26974 +#define PCI_VENDOR_ID_SGI 0x10a9
26975 +#define PCI_DEVICE_ID_SGI_IOC3 0x0003
26977 +#define PCI_VENDOR_ID_ACC 0x10aa
26978 +#define PCI_DEVICE_ID_ACC_2056 0x0000
26980 +#define PCI_VENDOR_ID_WINBOND 0x10ad
26981 +#define PCI_DEVICE_ID_WINBOND_83769 0x0001
26982 +#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
26983 +#define PCI_DEVICE_ID_WINBOND_83C553 0x0565
26985 +#define PCI_VENDOR_ID_DATABOOK 0x10b3
26986 +#define PCI_DEVICE_ID_DATABOOK_87144 0xb106
26988 +#define PCI_VENDOR_ID_PLX 0x10b5
26989 +#define PCI_DEVICE_ID_PLX_R685 0x1030
26990 +#define PCI_DEVICE_ID_PLX_ROMULUS 0x106a
26991 +#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076
26992 +#define PCI_DEVICE_ID_PLX_1077 0x1077
26993 +#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103
26994 +#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151
26995 +#define PCI_DEVICE_ID_PLX_R753 0x1152
26996 +#define PCI_DEVICE_ID_PLX_9050 0x9050
26997 +#define PCI_DEVICE_ID_PLX_9060 0x9060
26998 +#define PCI_DEVICE_ID_PLX_9060ES 0x906E
26999 +#define PCI_DEVICE_ID_PLX_9060SD 0x906D
27000 +#define PCI_DEVICE_ID_PLX_9080 0x9080
27001 +#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001
27003 +#define PCI_VENDOR_ID_MADGE 0x10b6
27004 +#define PCI_DEVICE_ID_MADGE_MK2 0x0002
27005 +#define PCI_DEVICE_ID_MADGE_C155S 0x1001
27007 +#define PCI_VENDOR_ID_3COM 0x10b7
27008 +#define PCI_DEVICE_ID_3COM_3C985 0x0001
27009 +#define PCI_DEVICE_ID_3COM_3C339 0x3390
27010 +#define PCI_DEVICE_ID_3COM_3C590 0x5900
27011 +#define PCI_DEVICE_ID_3COM_3C595 0x5950
27012 +#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
27013 +#define PCI_DEVICE_ID_3COM_3C595_1 0x5951
27014 +#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
27015 +#define PCI_DEVICE_ID_3COM_3C595_2 0x5952
27016 +#define PCI_DEVICE_ID_3COM_3C595MII 0x5952
27017 +#define PCI_DEVICE_ID_3COM_3C900TPO 0x9000
27018 +#define PCI_DEVICE_ID_3COM_3C900COMBO 0x9001
27019 +#define PCI_DEVICE_ID_3COM_3C905TX 0x9050
27020 +#define PCI_DEVICE_ID_3COM_3C905T4 0x9051
27021 +#define PCI_DEVICE_ID_3COM_3C905B_TX 0x9055
27022 +#define PCI_DEVICE_ID_3COM_3C905C_TXM 0x9200
27024 +#define PCI_VENDOR_ID_SMC 0x10b8
27025 +#define PCI_DEVICE_ID_SMC_EPIC100 0x0005
27027 +#define PCI_VENDOR_ID_SUNDANCE 0x13F0
27028 +#define PCI_DEVICE_ID_SUNDANCE_ALTA 0x0201
27030 +#define PCI_VENDOR_ID_AL 0x10b9
27031 +#define PCI_DEVICE_ID_AL_M1445 0x1445
27032 +#define PCI_DEVICE_ID_AL_M1449 0x1449
27033 +#define PCI_DEVICE_ID_AL_M1451 0x1451
27034 +#define PCI_DEVICE_ID_AL_M1461 0x1461
27035 +#define PCI_DEVICE_ID_AL_M1489 0x1489
27036 +#define PCI_DEVICE_ID_AL_M1511 0x1511
27037 +#define PCI_DEVICE_ID_AL_M1513 0x1513
27038 +#define PCI_DEVICE_ID_AL_M1521 0x1521
27039 +#define PCI_DEVICE_ID_AL_M1523 0x1523
27040 +#define PCI_DEVICE_ID_AL_M1531 0x1531
27041 +#define PCI_DEVICE_ID_AL_M1533 0x1533
27042 +#define PCI_DEVICE_ID_AL_M1541 0x1541
27043 +#define PCI_DEVICE_ID_AL_M1621 0x1621
27044 +#define PCI_DEVICE_ID_AL_M1631 0x1631
27045 +#define PCI_DEVICE_ID_AL_M1641 0x1641
27046 +#define PCI_DEVICE_ID_AL_M1647 0x1647
27047 +#define PCI_DEVICE_ID_AL_M1651 0x1651
27048 +#define PCI_DEVICE_ID_AL_M1543 0x1543
27049 +#define PCI_DEVICE_ID_AL_M3307 0x3307
27050 +#define PCI_DEVICE_ID_AL_M4803 0x5215
27051 +#define PCI_DEVICE_ID_AL_M5219 0x5219
27052 +#define PCI_DEVICE_ID_AL_M5229 0x5229
27053 +#define PCI_DEVICE_ID_AL_M5237 0x5237
27054 +#define PCI_DEVICE_ID_AL_M5243 0x5243
27055 +#define PCI_DEVICE_ID_AL_M5451 0x5451
27056 +#define PCI_DEVICE_ID_AL_M7101 0x7101
27058 +#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
27060 +#define PCI_VENDOR_ID_SURECOM 0x10bd
27061 +#define PCI_DEVICE_ID_SURECOM_NE34 0x0e34
27063 +#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
27064 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2070 0x0001
27065 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128V 0x0002
27066 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZV 0x0003
27067 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_NM2160 0x0004
27068 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICMEDIA_256AV 0x0005
27069 +#define PCI_DEVICE_ID_NEOMAGIC_MAGICGRAPH_128ZVPLUS 0x0083
27071 +#define PCI_VENDOR_ID_ASP 0x10cd
27072 +#define PCI_DEVICE_ID_ASP_ABP940 0x1200
27073 +#define PCI_DEVICE_ID_ASP_ABP940U 0x1300
27074 +#define PCI_DEVICE_ID_ASP_ABP940UW 0x2300
27076 +#define PCI_VENDOR_ID_MACRONIX 0x10d9
27077 +#define PCI_DEVICE_ID_MACRONIX_MX98713 0x0512
27078 +#define PCI_DEVICE_ID_MX987x3 0x0512
27079 +#define PCI_DEVICE_ID_MACRONIX_MX987x5 0x0531
27080 +#define PCI_DEVICE_ID_MX987x5 0x0531
27082 +#define PCI_VENDOR_ID_TCONRAD 0x10da
27083 +#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508
27085 +#define PCI_VENDOR_ID_CERN 0x10dc
27086 +#define PCI_DEVICE_ID_CERN_SPSB_PMC 0x0001
27087 +#define PCI_DEVICE_ID_CERN_SPSB_PCI 0x0002
27088 +#define PCI_DEVICE_ID_CERN_HIPPI_DST 0x0021
27089 +#define PCI_DEVICE_ID_CERN_HIPPI_SRC 0x0022
27091 +#define PCI_VENDOR_ID_NVIDIA 0x10de
27092 +#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
27093 +#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028
27094 +#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029
27095 +#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C
27096 +#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D
27097 +#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
27098 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
27099 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
27100 +#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103
27101 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110
27102 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111
27103 +#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113
27104 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150
27105 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151
27106 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152
27107 +#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153
27109 +#define PCI_VENDOR_ID_IMS 0x10e0
27110 +#define PCI_DEVICE_ID_IMS_8849 0x8849
27111 +#define PCI_DEVICE_ID_IMS_TT128 0x9128
27112 +#define PCI_DEVICE_ID_IMS_TT3D 0x9135
27114 +#define PCI_VENDOR_ID_TEKRAM2 0x10e1
27115 +#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
27117 +#define PCI_VENDOR_ID_TUNDRA 0x10e3
27118 +#define PCI_DEVICE_ID_TUNDRA_CA91C042 0x0000
27120 +#define PCI_VENDOR_ID_AMCC 0x10e8
27121 +#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
27122 +#define PCI_DEVICE_ID_AMCC_PARASTATION 0x8062
27123 +#define PCI_DEVICE_ID_AMCC_S5933 0x807d
27124 +#define PCI_DEVICE_ID_AMCC_S5933_HEPC3 0x809c
27126 +#define PCI_VENDOR_ID_INTERG 0x10ea
27127 +#define PCI_DEVICE_ID_INTERG_1680 0x1680
27128 +#define PCI_DEVICE_ID_INTERG_1682 0x1682
27129 +#define PCI_DEVICE_ID_INTERG_2000 0x2000
27130 +#define PCI_DEVICE_ID_INTERG_2010 0x2010
27131 +#define PCI_DEVICE_ID_INTERG_5000 0x5000
27132 +#define PCI_DEVICE_ID_INTERG_5050 0x5050
27134 +#define PCI_VENDOR_ID_REALTEK 0x10ec
27135 +#define PCI_DEVICE_ID_REALTEK_8029 0x8029
27136 +#define PCI_DEVICE_ID_REALTEK_8129 0x8129
27137 +#define PCI_DEVICE_ID_REALTEK_8139 0x8139
27139 +#define PCI_VENDOR_ID_XILINX 0x10ee
27140 +#define PCI_DEVICE_ID_TURBOPAM 0x4020
27142 +#define PCI_VENDOR_ID_TRUEVISION 0x10fa
27143 +#define PCI_DEVICE_ID_TRUEVISION_T1000 0x000c
27145 +#define PCI_VENDOR_ID_INIT 0x1101
27146 +#define PCI_DEVICE_ID_INIT_320P 0x9100
27147 +#define PCI_DEVICE_ID_INIT_360P 0x9500
27149 +#define PCI_VENDOR_ID_CREATIVE 0x1102 // duplicate: ECTIVA
27150 +#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
27152 +#define PCI_VENDOR_ID_ECTIVA 0x1102 // duplicate: CREATIVE
27153 +#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
27155 +#define PCI_VENDOR_ID_TTI 0x1103
27156 +#define PCI_DEVICE_ID_TTI_HPT343 0x0003
27157 +#define PCI_DEVICE_ID_TTI_HPT366 0x0004
27159 +#define PCI_VENDOR_ID_VIA 0x1106
27160 +#define PCI_VENDOR_ID_VIATEC 0x1106
27161 +#define PCI_DEVICE_ID_VIA_8363_0 0x0305
27162 +#define PCI_DEVICE_ID_VIA_8371_0 0x0391
27163 +#define PCI_DEVICE_ID_VIA_8501_0 0x0501
27164 +#define PCI_DEVICE_ID_VIA_82C505 0x0505
27165 +#define PCI_DEVICE_ID_VIA_82C561 0x0561
27166 +#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
27167 +#define PCI_DEVICE_ID_VIA_82C576 0x0576
27168 +#define PCI_DEVICE_ID_VIA_82C585 0x0585
27169 +#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
27170 +#define PCI_DEVICE_ID_VIA_82C595 0x0595
27171 +#define PCI_DEVICE_ID_VIA_82C596 0x0596
27172 +#define PCI_DEVICE_ID_VIA_82C597_0 0x0597
27173 +#define PCI_DEVICE_ID_VIA_82C598_0 0x0598
27174 +#define PCI_DEVICE_ID_VIA_8601_0 0x0601
27175 +#define PCI_DEVICE_ID_VIA_8605_0 0x0605
27176 +#define PCI_DEVICE_ID_VIA_82C680 0x0680
27177 +#define PCI_DEVICE_ID_VIA_82C686 0x0686
27178 +#define PCI_DEVICE_ID_VIA_82C691 0x0691
27179 +#define PCI_DEVICE_ID_VIA_82C693 0x0693
27180 +#define PCI_DEVICE_ID_VIA_82C693_1 0x0698
27181 +#define PCI_DEVICE_ID_VIA_82C926 0x0926
27182 +#define PCI_DEVICE_ID_VIA_82C576_1 0x1571
27183 +#define PCI_DEVICE_ID_VIA_82C595_97 0x1595
27184 +#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
27185 +#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
27186 +#define PCI_DEVICE_ID_VIA_RHINE_I 0x3043
27187 +#define PCI_DEVICE_ID_VIA_6305 0x3044
27188 +#define PCI_DEVICE_ID_VIA_82C596_3 0x3050
27189 +#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051
27190 +#define PCI_DEVICE_ID_VIA_82C686_4 0x3057
27191 +#define PCI_DEVICE_ID_VIA_82C686_5 0x3058
27192 +#define PCI_DEVICE_ID_VIA_8233_5 0x3059
27193 +#define PCI_DEVICE_ID_VIA_8233_7 0x3065
27194 +#define PCI_DEVICE_ID_VIA_VT6102 0x3065
27195 +#define PCI_DEVICE_ID_VIA_82C686_6 0x3068
27196 +#define PCI_DEVICE_ID_VIA_8233_0 0x3074
27197 +#define PCI_DEVICE_ID_VIA_VT6105 0x3106
27198 +#define PCI_DEVICE_ID_VIA_8233C_0 0x3109
27199 +#define PCI_DEVICE_ID_VIA_8633_0 0x3091
27200 +#define PCI_DEVICE_ID_VIA_8367_0 0x3099
27201 +#define PCI_DEVICE_ID_VIA_86C100A 0x6100
27202 +#define PCI_DEVICE_ID_VIA_8231 0x8231
27203 +#define PCI_DEVICE_ID_VIA_8231_4 0x8235
27204 +#define PCI_DEVICE_ID_VIA_8365_1 0x8305
27205 +#define PCI_DEVICE_ID_VIA_8371_1 0x8391
27206 +#define PCI_DEVICE_ID_VIA_8501_1 0x8501
27207 +#define PCI_DEVICE_ID_VIA_82C597_1 0x8597
27208 +#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
27209 +#define PCI_DEVICE_ID_VIA_8601_1 0x8601
27210 +#define PCI_DEVICE_ID_VIA_8505_1 0X8605
27211 +#define PCI_DEVICE_ID_VIA_8633_1 0xB091
27212 +#define PCI_DEVICE_ID_VIA_8367_1 0xB099
27214 +#define PCI_VENDOR_ID_SIEMENS 0x110A
27215 +#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102
27217 +#define PCI_VENDOR_ID_SMC2 0x1113
27218 +#define PCI_DEVICE_ID_SMC2_1211TX 0x1211
27219 +#define PCI_DEVICE_ID_SMC2_1211 0x1211
27220 +#define PCI_DEVICE_ID_SMC2_1216 0x1216
27222 +#define PCI_VENDOR_ID_VORTEX 0x1119
27223 +#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
27224 +#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001
27225 +#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002
27226 +#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003
27227 +#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004
27228 +#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005
27229 +#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006
27230 +#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007
27231 +#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008
27232 +#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009
27233 +#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a
27234 +#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b
27235 +#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c
27236 +#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d
27237 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100
27238 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101
27239 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102
27240 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103
27241 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104
27242 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105
27243 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP1 0x0110
27244 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP1 0x0111
27245 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP1 0x0112
27246 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP1 0x0113
27247 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP1 0x0114
27248 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP1 0x0115
27249 +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP2 0x0120
27250 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP2 0x0121
27251 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP2 0x0122
27252 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP2 0x0123
27253 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP2 0x0124
27254 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP2 0x0125
27256 +#define PCI_VENDOR_ID_EF 0x111a
27257 +#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
27258 +#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002
27260 +#define PCI_VENDOR_ID_IDT 0x111d
27261 +#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
27263 +#define PCI_VENDOR_ID_FORE 0x1127
27264 +#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
27265 +#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
27267 +#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
27268 +#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
27270 +#define PCI_VENDOR_ID_PHILIPS 0x1131
27271 +#define PCI_DEVICE_ID_PHILIPS_SAA7145 0x7145
27272 +#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
27273 +#define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730
27275 +#define PCI_VENDOR_ID_EICON 0x1133
27276 +#define PCI_DEVICE_ID_EICON_DIVA20PRO 0xe001
27277 +#define PCI_DEVICE_ID_EICON_DIVA20 0xe002
27278 +#define PCI_DEVICE_ID_EICON_DIVA20PRO_U 0xe003
27279 +#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004
27280 +#define PCI_DEVICE_ID_EICON_DIVA201 0xe005
27281 +#define PCI_DEVICE_ID_EICON_MAESTRA 0xe010
27282 +#define PCI_DEVICE_ID_EICON_MAESTRAQ 0xe012
27283 +#define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013
27284 +#define PCI_DEVICE_ID_EICON_MAESTRAP 0xe014
27286 +#define PCI_VENDOR_ID_CYCLONE 0x113c
27287 +#define PCI_DEVICE_ID_CYCLONE_SDK 0x0001
27289 +#define PCI_VENDOR_ID_ALLIANCE 0x1142
27290 +#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210
27291 +#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
27292 +#define PCI_DEVICE_ID_ALLIANCE_AT24 0x6424
27293 +#define PCI_DEVICE_ID_ALLIANCE_AT3D 0x643d
27295 +#define PCI_VENDOR_ID_SYSKONNECT 0x1148
27296 +#define PCI_DEVICE_ID_SYSKONNECT_FP 0x4000
27297 +#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200
27298 +#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300
27300 +#define PCI_VENDOR_ID_VMIC 0x114a
27301 +#define PCI_DEVICE_ID_VMIC_VME 0x7587
27303 +#define PCI_VENDOR_ID_DIGI 0x114f
27304 +#define PCI_DEVICE_ID_DIGI_EPC 0x0002
27305 +#define PCI_DEVICE_ID_DIGI_RIGHTSWITCH 0x0003
27306 +#define PCI_DEVICE_ID_DIGI_XEM 0x0004
27307 +#define PCI_DEVICE_ID_DIGI_XR 0x0005
27308 +#define PCI_DEVICE_ID_DIGI_CX 0x0006
27309 +#define PCI_DEVICE_ID_DIGI_XRJ 0x0009
27310 +#define PCI_DEVICE_ID_DIGI_EPCJ 0x000a
27311 +#define PCI_DEVICE_ID_DIGI_XR_920 0x0027
27312 +#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070
27313 +#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071
27314 +#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072
27315 +#define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073
27317 +#define PCI_VENDOR_ID_MUTECH 0x1159
27318 +#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
27320 +#define PCI_VENDOR_ID_XIRCOM 0x115d
27321 +#define PCI_DEVICE_ID_XIRCOM_X3201_ETH 0x0003
27322 +#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103
27324 +#define PCI_VENDOR_ID_RENDITION 0x1163
27325 +#define PCI_DEVICE_ID_RENDITION_VERITE 0x0001
27326 +#define PCI_DEVICE_ID_RENDITION_VERITE2100 0x2000
27328 +#define PCI_VENDOR_ID_SERVERWORKS 0x1166
27329 +#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008
27330 +#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009
27331 +#define PCI_DEVICE_ID_SERVERWORKS_CIOB30 0x0010
27332 +#define PCI_DEVICE_ID_SERVERWORKS_CMIC_HE 0x0011
27333 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
27334 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
27335 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
27336 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
27337 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220
27338 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB
27339 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5ISA 0x0230
27341 +#define PCI_VENDOR_ID_SBE 0x1176
27342 +#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
27343 +#define PCI_DEVICE_ID_SBE_WANXL200 0x0302
27344 +#define PCI_DEVICE_ID_SBE_WANXL400 0x0104
27346 +#define PCI_VENDOR_ID_TOSHIBA 0x1179
27347 +#define PCI_DEVICE_ID_TOSHIBA_601 0x0601
27348 +#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
27349 +#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
27351 +#define PCI_VENDOR_ID_RICOH 0x1180
27352 +#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465
27353 +#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466
27354 +#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475
27355 +#define PCI_DEVICE_ID_RICOH_RL5C476 0x0476
27356 +#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478
27358 +#define PCI_VENDOR_ID_DLINK 0x1186
27359 +#define PCI_DEVICE_ID_DFE530TXP 0x1300
27360 +#define PCI_DEVICE_ID_DFE530TXS 0x1002
27362 +#define PCI_VENDOR_ID_ARTOP 0x1191
27363 +#define PCI_DEVICE_ID_ARTOP_ATP8400 0x0004
27364 +#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005
27365 +#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006
27366 +#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007
27367 +#define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002
27368 +#define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010
27369 +#define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020
27370 +#define PCI_DEVICE_ID_ARTOP_AEC7612S 0x8030
27371 +#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040
27372 +#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050
27373 +#define PCI_DEVICE_ID_ARTOP_8060 0x8060
27375 +#define PCI_VENDOR_ID_ZEITNET 0x1193
27376 +#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
27377 +#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
27379 +#define PCI_VENDOR_ID_OMEGA 0x119b
27380 +#define PCI_DEVICE_ID_OMEGA_82C092G 0x1221
27382 +#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
27383 +#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001
27384 +#define PCI_DEVICE_ID_FUJITSU_FS50 0x0003
27386 +#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9
27387 +#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334
27389 +#define PCI_VENDOR_ID_GALILEO 0x11ab
27390 +#define PCI_DEVICE_ID_GALILEO_GT64011 0x4146
27391 +#define PCI_DEVICE_ID_GALILEO_GT64111 0x4146
27392 +#define PCI_DEVICE_ID_GALILEO_GT96100 0x9652
27393 +#define PCI_DEVICE_ID_GALILEO_GT96100A 0x9653
27395 +#define PCI_VENDOR_ID_LINKSYS 0x11ad
27396 +#define PCI_VENDOR_ID_LITEON 0x11ad
27397 +#define PCI_DEVICE_ID_LITEON_LNE100TX 0x0002
27398 +#define PCI_DEVICE_ID_LC82C115 0xC115
27400 +#define PCI_VENDOR_ID_V3 0x11b0
27401 +#define PCI_DEVICE_ID_V3_V960 0x0001
27402 +#define PCI_DEVICE_ID_V3_V350 0x0001
27403 +#define PCI_DEVICE_ID_V3_V961 0x0002
27404 +#define PCI_DEVICE_ID_V3_V351 0x0002
27406 +#define PCI_VENDOR_ID_NP 0x11bc
27407 +#define PCI_DEVICE_ID_NP_PCI_FDDI 0x0001
27409 +#define PCI_VENDOR_ID_ATT 0x11c1
27410 +#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
27411 +#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
27413 +#define PCI_VENDOR_ID_SPECIALIX 0x11cb
27414 +#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
27415 +#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
27416 +#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
27417 +#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
27419 +#define PCI_VENDOR_ID_AURAVISION 0x11d1
27420 +#define PCI_DEVICE_ID_AURAVISION_VXP524 0x01f7
27422 +#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4
27423 +#define PCI_DEVICE_ID_AD1889JS 0x1889
27425 +#define PCI_VENDOR_ID_IKON 0x11d5
27426 +#define PCI_DEVICE_ID_IKON_10115 0x0115
27427 +#define PCI_DEVICE_ID_IKON_10117 0x0117
27429 +#define PCI_VENDOR_ID_ZORAN 0x11de
27430 +#define PCI_DEVICE_ID_ZORAN_36057 0x6057
27431 +#define PCI_DEVICE_ID_ZORAN_36120 0x6120
27433 +#define PCI_VENDOR_ID_KINETIC 0x11f4
27434 +#define PCI_DEVICE_ID_KINETIC_2915 0x2915
27436 +#define PCI_VENDOR_ID_COMPEX 0x11f6
27437 +#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
27438 +#define PCI_DEVICE_ID_COMPEX_RL2000 0x1401
27439 +#define PCI_DEVICE_ID_COMPEX_RL100ATX 0x2011
27441 +#define PCI_VENDOR_ID_RP 0x11fe
27442 +#define PCI_DEVICE_ID_RP32INTF 0x0001
27443 +#define PCI_DEVICE_ID_RP8INTF 0x0002
27444 +#define PCI_DEVICE_ID_RP16INTF 0x0003
27445 +#define PCI_DEVICE_ID_RP4QUAD 0x0004
27446 +#define PCI_DEVICE_ID_RP8OCTA 0x0005
27447 +#define PCI_DEVICE_ID_RP8J 0x0006
27448 +#define PCI_DEVICE_ID_RPP4 0x000A
27449 +#define PCI_DEVICE_ID_RPP8 0x000B
27450 +#define PCI_DEVICE_ID_RP8M 0x000C
27452 +#define PCI_VENDOR_ID_CYCLADES 0x120e
27453 +#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100
27454 +#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101
27455 +#define PCI_DEVICE_ID_CYCLOM_4Y_Lo 0x0102
27456 +#define PCI_DEVICE_ID_CYCLOM_4Y_Hi 0x0103
27457 +#define PCI_DEVICE_ID_CYCLOM_8Y_Lo 0x0104
27458 +#define PCI_DEVICE_ID_CYCLOM_8Y_Hi 0x0105
27459 +#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200
27460 +#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201
27461 +#define PCI_DEVICE_ID_PC300_RX_2 0x0300
27462 +#define PCI_DEVICE_ID_PC300_RX_1 0x0301
27463 +#define PCI_DEVICE_ID_PC300_TE_2 0x0310
27464 +#define PCI_DEVICE_ID_PC300_TE_1 0x0311
27466 +#define PCI_VENDOR_ID_ESSENTIAL 0x120f
27467 +#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
27469 +#define PCI_VENDOR_ID_O2 0x1217
27470 +#define PCI_DEVICE_ID_O2_6729 0x6729
27471 +#define PCI_DEVICE_ID_O2_6730 0x673a
27472 +#define PCI_DEVICE_ID_O2_6832 0x6832
27473 +#define PCI_DEVICE_ID_O2_6836 0x6836
27475 +#define PCI_VENDOR_ID_3DFX 0x121a
27476 +#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
27477 +#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002
27478 +#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
27479 +#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005
27481 +#define PCI_VENDOR_ID_SIGMADES 0x1236
27482 +#define PCI_DEVICE_ID_SIGMADES_6425 0x6401
27484 +#define PCI_VENDOR_ID_CCUBE 0x123f
27486 +#define PCI_VENDOR_ID_AVM 0x1244
27487 +#define PCI_DEVICE_ID_AVM_B1 0x0700
27488 +#define PCI_DEVICE_ID_AVM_C4 0x0800
27489 +#define PCI_DEVICE_ID_AVM_A1 0x0a00
27490 +#define PCI_DEVICE_ID_AVM_A1_V2 0x0e00
27491 +#define PCI_DEVICE_ID_AVM_C2 0x1100
27492 +#define PCI_DEVICE_ID_AVM_T1 0x1200
27494 +#define PCI_VENDOR_ID_DIPIX 0x1246
27496 +#define PCI_VENDOR_ID_STALLION 0x124d
27497 +#define PCI_DEVICE_ID_STALLION_ECHPCI832 0x0000
27498 +#define PCI_DEVICE_ID_STALLION_ECHPCI864 0x0002
27499 +#define PCI_DEVICE_ID_STALLION_EIOPCI 0x0003
27501 +#define PCI_VENDOR_ID_OPTIBASE 0x1255
27502 +#define PCI_DEVICE_ID_OPTIBASE_FORGE 0x1110
27503 +#define PCI_DEVICE_ID_OPTIBASE_FUSION 0x1210
27504 +#define PCI_DEVICE_ID_OPTIBASE_VPLEX 0x2110
27505 +#define PCI_DEVICE_ID_OPTIBASE_VPLEXCC 0x2120
27506 +#define PCI_DEVICE_ID_OPTIBASE_VQUEST 0x2130
27508 +#define PCI_VENDOR_ID_ESS 0x125d
27509 +#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
27510 +#define PCI_DEVICE_ID_ESS_AUDIOPCI 0x1969
27511 +#define PCI_DEVICE_ID_ESS_ESS1978 0x1978
27513 +#define PCI_VENDOR_ID_HARRIS 0x1260
27514 +#define PCI_DEVICE_ID_HARRIS_PRISM2 0x3873
27516 +#define PCI_VENDOR_ID_SATSAGEM 0x1267
27517 +#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016
27518 +#define PCI_DEVICE_ID_SATSAGEM_PCR2101 0x5352
27519 +#define PCI_DEVICE_ID_SATSAGEM_TELSATTURBO 0x5a4b
27521 +#define PCI_VENDOR_ID_HUGHES 0x1273
27522 +#define PCI_DEVICE_ID_HUGHES_DIRECPC 0x0002
27524 +#define PCI_VENDOR_ID_ENSONIQ 0x1274
27525 +#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
27526 +#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
27527 +#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
27529 +#define PCI_VENDOR_ID_ROCKWELL 0x127A
27531 +#define PCI_VENDOR_ID_DAVICOM 0x1282
27532 +#define PCI_DEVICE_ID_DM9009 0x9009
27533 +#define PCI_DEVICE_ID_DM9102 0x9102
27535 +#define PCI_VENDOR_ID_ITE 0x1283
27536 +#define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
27537 +#define PCI_DEVICE_ID_ITE_IT8172G 0x8172
27538 +#define PCI_DEVICE_ID_ITE_8872 0x8872
27541 +/* formerly Platform Tech */
27542 +#define PCI_VENDOR_ID_ESS_OLD 0x1285
27543 +#define PCI_DEVICE_ID_ESS_ESS0100 0x0100
27545 +#define PCI_VENDOR_ID_ALTEON 0x12ae
27546 +#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001
27548 +#define PCI_VENDOR_ID_USR 0x12B9
27550 +#define PCI_VENDOR_ID_HOLTEK 0x12c3
27551 +#define PCI_DEVICE_ID_HOLTEK_HT80232 0x0058
27553 +#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
27554 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001
27555 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002
27556 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232 0x0003
27557 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485 0x0004
27558 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4 0x0005
27559 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485 0x0006
27560 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2 0x0007
27561 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485 0x0008
27562 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6 0x0009
27563 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A
27564 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B
27566 +#define PCI_VENDOR_ID_PICTUREL 0x12c5
27567 +#define PCI_DEVICE_ID_PICTUREL_PCIVST 0x0081
27569 +#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
27570 +#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
27572 +#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
27573 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031
27574 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021
27575 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011
27576 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041
27577 +#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D
27578 +#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001
27579 +#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010
27581 +#define PCI_VENDOR_ID_AUREAL 0x12eb
27582 +#define PCI_DEVICE_ID_AUREAL_VORTEX_1 0x0001
27583 +#define PCI_DEVICE_ID_AUREAL_VORTEX_2 0x0002
27585 +#define PCI_VENDOR_ID_CBOARDS 0x1307
27586 +#define PCI_DEVICE_ID_CBOARDS_DAS1602_16 0x0001
27588 +#define PCI_VENDOR_ID_SIIG 0x131f
27589 +#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000
27590 +#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001
27591 +#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002
27592 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_550 0x1010
27593 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_650 0x1011
27594 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_850 0x1012
27595 +#define PCI_DEVICE_ID_SIIG_1P_10x 0x1020
27596 +#define PCI_DEVICE_ID_SIIG_2P_10x 0x1021
27597 +#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030
27598 +#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031
27599 +#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032
27600 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_550 0x1034
27601 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_650 0x1035
27602 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_850 0x1036
27603 +#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050
27604 +#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051
27605 +#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052
27606 +#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000
27607 +#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001
27608 +#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002
27609 +#define PCI_DEVICE_ID_SIIG_1P_20x 0x2020
27610 +#define PCI_DEVICE_ID_SIIG_2P_20x 0x2021
27611 +#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030
27612 +#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031
27613 +#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032
27614 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_550 0x2040
27615 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_650 0x2041
27616 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_850 0x2042
27617 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_550 0x2010
27618 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_650 0x2011
27619 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_850 0x2012
27620 +#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050
27621 +#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051
27622 +#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052
27623 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060
27624 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061
27625 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062
27627 +#define PCI_VENDOR_ID_ADMTEK 0x1317
27628 +#define PCI_DEVICE_ID_ADMTEK_0985 0x0985
27630 +#define PCI_VENDOR_ID_DOMEX 0x134a
27631 +#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001
27633 +#define PCI_VENDOR_ID_QUATECH 0x135C
27634 +#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010
27635 +#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020
27636 +#define PCI_DEVICE_ID_QUATECH_DSC200 0x0030
27637 +#define PCI_DEVICE_ID_QUATECH_QSC200 0x0040
27638 +#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050
27639 +#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060
27641 +#define PCI_VENDOR_ID_SEALEVEL 0x135e
27642 +#define PCI_DEVICE_ID_SEALEVEL_U530 0x7101
27643 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM2 0x7201
27644 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM422 0x7402
27645 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202
27646 +#define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401
27647 +#define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801
27649 +#define PCI_VENDOR_ID_HYPERCOPE 0x1365
27650 +#define PCI_DEVICE_ID_HYPERCOPE_PLX 0x9050
27651 +#define PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO 0x0104
27652 +#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106
27653 +#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107
27654 +#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108
27655 +#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS 0x0109
27657 +#define PCI_VENDOR_ID_KAWASAKI 0x136b
27658 +#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
27660 +#define PCI_VENDOR_ID_LMC 0x1376
27661 +#define PCI_DEVICE_ID_LMC_HSSI 0x0003
27662 +#define PCI_DEVICE_ID_LMC_DS3 0x0004
27663 +#define PCI_DEVICE_ID_LMC_SSI 0x0005
27664 +#define PCI_DEVICE_ID_LMC_T1 0x0006
27666 +#define PCI_VENDOR_ID_NETGEAR 0x1385
27667 +#define PCI_DEVICE_ID_NETGEAR_MA301 0x4100
27668 +#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
27669 +#define PCI_DEVICE_ID_NETGEAR_GA622 0x622a
27671 +#define PCI_VENDOR_ID_APPLICOM 0x1389
27672 +#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
27673 +#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002
27674 +#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003
27676 +#define PCI_VENDOR_ID_MOXA 0x1393
27677 +#define PCI_DEVICE_ID_MOXA_C104 0x1040
27678 +#define PCI_DEVICE_ID_MOXA_C168 0x1680
27679 +#define PCI_DEVICE_ID_MOXA_CP204J 0x2040
27680 +#define PCI_DEVICE_ID_MOXA_C218 0x2180
27681 +#define PCI_DEVICE_ID_MOXA_C320 0x3200
27683 +#define PCI_VENDOR_ID_CCD 0x1397
27684 +#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0
27685 +#define PCI_DEVICE_ID_CCD_B000 0xb000
27686 +#define PCI_DEVICE_ID_CCD_B006 0xb006
27687 +#define PCI_DEVICE_ID_CCD_B007 0xb007
27688 +#define PCI_DEVICE_ID_CCD_B008 0xb008
27689 +#define PCI_DEVICE_ID_CCD_B009 0xb009
27690 +#define PCI_DEVICE_ID_CCD_B00A 0xb00a
27691 +#define PCI_DEVICE_ID_CCD_B00B 0xb00b
27692 +#define PCI_DEVICE_ID_CCD_B00C 0xb00c
27693 +#define PCI_DEVICE_ID_CCD_B100 0xb100
27695 +#define PCI_VENDOR_ID_MICROGATE 0x13c0
27696 +#define PCI_DEVICE_ID_MICROGATE_USC 0x0010
27697 +#define PCI_DEVICE_ID_MICROGATE_SCC 0x0020
27698 +#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030
27700 +#define PCI_VENDOR_ID_3WARE 0x13C1
27701 +#define PCI_DEVICE_ID_3WARE_1000 0x1000
27703 +#define PCI_VENDOR_ID_ABOCOM 0x13D1
27704 +#define PCI_DEVICE_ID_ABOCOM_2BD1 0x2BD1
27706 +#define PCI_VENDOR_ID_CMEDIA 0x13f6
27707 +#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
27708 +#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
27709 +#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
27710 +#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
27712 +#define PCI_VENDOR_ID_LAVA 0x1407
27713 +#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */
27714 +#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */
27715 +#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */
27716 +#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */
27717 +#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */
27718 +#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */
27719 +#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */
27720 +#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */
27721 +#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
27722 +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */
27723 +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */
27724 +#define PCI_DEVICE_ID_LAVA_BOCA_IOPPAR 0x8800
27726 +#define PCI_VENDOR_ID_TIMEDIA 0x1409
27727 +#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
27729 +#define PCI_VENDOR_ID_OXSEMI 0x1415
27730 +#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403
27731 +#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
27732 +#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A
27733 +#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
27734 +#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513
27736 +#define PCI_VENDOR_ID_AIRONET 0x14b9
27737 +#define PCI_DEVICE_ID_AIRONET_4800_1 0x0001
27738 +#define PCI_DEVICE_ID_AIRONET_4800 0x4500 // values switched? see
27739 +#define PCI_DEVICE_ID_AIRONET_4500 0x4800 // drivers/net/aironet4500_card.c
27741 +#define PCI_VENDOR_ID_TITAN 0x14D2
27742 +#define PCI_DEVICE_ID_TITAN_010L 0x8001
27743 +#define PCI_DEVICE_ID_TITAN_100L 0x8010
27744 +#define PCI_DEVICE_ID_TITAN_110L 0x8011
27745 +#define PCI_DEVICE_ID_TITAN_200L 0x8020
27746 +#define PCI_DEVICE_ID_TITAN_210L 0x8021
27747 +#define PCI_DEVICE_ID_TITAN_400L 0x8040
27748 +#define PCI_DEVICE_ID_TITAN_800L 0x8080
27749 +#define PCI_DEVICE_ID_TITAN_100 0xA001
27750 +#define PCI_DEVICE_ID_TITAN_200 0xA005
27751 +#define PCI_DEVICE_ID_TITAN_400 0xA003
27752 +#define PCI_DEVICE_ID_TITAN_800B 0xA004
27754 +#define PCI_VENDOR_ID_PANACOM 0x14d4
27755 +#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
27756 +#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
27758 +#define PCI_VENDOR_ID_BROADCOM 0x14e4
27759 +#define PCI_DEVICE_ID_TIGON3_5700 0x1644
27760 +#define PCI_DEVICE_ID_TIGON3_5701 0x1645
27761 +#define PCI_DEVICE_ID_TIGON3_5702 0x1646
27762 +#define PCI_DEVICE_ID_TIGON3_5703 0x1647
27763 +#define PCI_DEVICE_ID_TIGON3_5704 0x1648
27764 +#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d
27765 +#define PCI_DEVICE_ID_TIGON3_5705 0x1653
27766 +#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654
27767 +#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
27768 +#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
27769 +#define PCI_DEVICE_ID_TIGON3_5782 0x1696
27770 +#define PCI_DEVICE_ID_TIGON3_5788 0x169c
27771 +#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
27772 +#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
27773 +#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
27774 +#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6
27775 +#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7
27776 +#define PCI_DEVICE_ID_TIGON3_5901 0x170d
27777 +#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e
27779 +#define PCI_VENDOR_ID_SYBA 0x1592
27780 +#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
27781 +#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783
27783 +#define PCI_VENDOR_ID_MORETON 0x15aa
27784 +#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000
27786 +#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
27787 +#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0
27789 +#define PCI_VENDOR_ID_PDC 0x15e9
27790 +#define PCI_DEVICE_ID_PDC_1841 0x1841
27792 +#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
27793 +#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
27795 +#define PCI_VENDOR_ID_TEKRAM 0x1de1
27796 +#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
27798 +#define PCI_VENDOR_ID_3DLABS 0x3d3d
27799 +#define PCI_DEVICE_ID_3DLABS_300SX 0x0001
27800 +#define PCI_DEVICE_ID_3DLABS_500TX 0x0002
27801 +#define PCI_DEVICE_ID_3DLABS_DELTA 0x0003
27802 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA 0x0004
27803 +#define PCI_DEVICE_ID_3DLABS_MX 0x0006
27804 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
27805 +#define PCI_DEVICE_ID_3DLABS_GAMMA 0x0008
27806 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009
27808 +#define PCI_VENDOR_ID_AVANCE 0x4005
27809 +#define PCI_DEVICE_ID_AVANCE_ALG2064 0x2064
27810 +#define PCI_DEVICE_ID_AVANCE_2302 0x2302
27812 +#define PCI_VENDOR_ID_AKS 0x416c
27813 +#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100
27814 +#define PCI_DEVICE_ID_AKS_CPC 0x0200
27816 +#define PCI_VENDOR_ID_NETVIN 0x4a14
27817 +#define PCI_DEVICE_ID_NETVIN_NV5000SC 0x5000
27819 +#define PCI_VENDOR_ID_S3 0x5333
27820 +#define PCI_DEVICE_ID_S3_PLATO_PXS 0x0551
27821 +#define PCI_DEVICE_ID_S3_ViRGE 0x5631
27822 +#define PCI_DEVICE_ID_S3_TRIO 0x8811
27823 +#define PCI_DEVICE_ID_S3_AURORA64VP 0x8812
27824 +#define PCI_DEVICE_ID_S3_TRIO64UVP 0x8814
27825 +#define PCI_DEVICE_ID_S3_ViRGE_VX 0x883d
27826 +#define PCI_DEVICE_ID_S3_868 0x8880
27827 +#define PCI_DEVICE_ID_S3_928 0x88b0
27828 +#define PCI_DEVICE_ID_S3_864_1 0x88c0
27829 +#define PCI_DEVICE_ID_S3_864_2 0x88c1
27830 +#define PCI_DEVICE_ID_S3_964_1 0x88d0
27831 +#define PCI_DEVICE_ID_S3_964_2 0x88d1
27832 +#define PCI_DEVICE_ID_S3_968 0x88f0
27833 +#define PCI_DEVICE_ID_S3_TRIO64V2 0x8901
27834 +#define PCI_DEVICE_ID_S3_PLATO_PXG 0x8902
27835 +#define PCI_DEVICE_ID_S3_ViRGE_DXGX 0x8a01
27836 +#define PCI_DEVICE_ID_S3_ViRGE_GX2 0x8a10
27837 +#define PCI_DEVICE_ID_S3_ViRGE_MX 0x8c01
27838 +#define PCI_DEVICE_ID_S3_ViRGE_MXP 0x8c02
27839 +#define PCI_DEVICE_ID_S3_ViRGE_MXPMV 0x8c03
27840 +#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
27842 +#define PCI_VENDOR_ID_DCI 0x6666
27843 +#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001
27844 +#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002
27846 +#define PCI_VENDOR_ID_GENROCO 0x5555
27847 +#define PCI_DEVICE_ID_GENROCO_HFP832 0x0003
27849 +#define PCI_VENDOR_ID_INTEL 0x8086
27850 +#define PCI_DEVICE_ID_INTEL_21145 0x0039
27851 +#define PCI_DEVICE_ID_INTEL_82375 0x0482
27852 +#define PCI_DEVICE_ID_INTEL_82424 0x0483
27853 +#define PCI_DEVICE_ID_INTEL_82378 0x0484
27854 +#define PCI_DEVICE_ID_INTEL_82430 0x0486
27855 +#define PCI_DEVICE_ID_INTEL_82434 0x04a3
27856 +#define PCI_DEVICE_ID_INTEL_I960 0x0960
27857 +#define PCI_DEVICE_ID_INTEL_82542 0x1000
27858 +#define PCI_DEVICE_ID_INTEL_82543GC_FIBER 0x1001
27859 +#define PCI_DEVICE_ID_INTEL_82543GC_COPPER 0x1004
27860 +#define PCI_DEVICE_ID_INTEL_82544EI_COPPER 0x1008
27861 +#define PCI_DEVICE_ID_INTEL_82544EI_FIBER 0x1009
27862 +#define PCI_DEVICE_ID_INTEL_82544GC_COPPER 0x100C
27863 +#define PCI_DEVICE_ID_INTEL_82544GC_LOM 0x100D
27864 +#define PCI_DEVICE_ID_INTEL_82540EM 0x100E
27865 +#define PCI_DEVICE_ID_INTEL_82545EM_COPPER 0x100F
27866 +#define PCI_DEVICE_ID_INTEL_82546EB_COPPER 0x1010
27867 +#define PCI_DEVICE_ID_INTEL_82545EM_FIBER 0x1011
27868 +#define PCI_DEVICE_ID_INTEL_82546EB_FIBER 0x1012
27869 +#define PCI_DEVICE_ID_INTEL_82540EM_LOM 0x1015
27870 +#define PCI_DEVICE_ID_INTEL_ID1029 0x1029
27871 +#define PCI_DEVICE_ID_INTEL_ID1030 0x1030
27872 +#define PCI_DEVICE_ID_INTEL_ID1031 0x1031
27873 +#define PCI_DEVICE_ID_INTEL_ID1038 0x1038
27874 +#define PCI_DEVICE_ID_INTEL_ID1039 0x1039
27875 +#define PCI_DEVICE_ID_INTEL_ID103A 0x103A
27876 +#define PCI_DEVICE_ID_INTEL_82562ET 0x1031
27877 +#define PCI_DEVICE_ID_INTEL_82559ER 0x1209
27878 +#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
27879 +#define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222
27880 +#define PCI_DEVICE_ID_INTEL_7116 0x1223
27881 +#define PCI_DEVICE_ID_INTEL_82596 0x1226
27882 +#define PCI_DEVICE_ID_INTEL_82865 0x1227
27883 +#define PCI_DEVICE_ID_INTEL_82557 0x1229
27884 +#define PCI_DEVICE_ID_INTEL_82437 0x122d
27885 +#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
27886 +#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
27887 +#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
27888 +#define PCI_DEVICE_ID_INTEL_82437MX 0x1235
27889 +#define PCI_DEVICE_ID_INTEL_82441 0x1237
27890 +#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
27891 +#define PCI_DEVICE_ID_INTEL_82439 0x1250
27892 +#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960
27893 +#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
27894 +#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
27895 +#define PCI_DEVICE_ID_INTEL_82801AA_2 0x2412
27896 +#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
27897 +#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415
27898 +#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416
27899 +#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418
27900 +#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420
27901 +#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421
27902 +#define PCI_DEVICE_ID_INTEL_82801AB_2 0x2422
27903 +#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423
27904 +#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425
27905 +#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426
27906 +#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428
27907 +#define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440
27908 +#define PCI_DEVICE_ID_INTEL_82801BA_1 0x2442
27909 +#define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443
27910 +#define PCI_DEVICE_ID_INTEL_82801BA_3 0x2444
27911 +#define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445
27912 +#define PCI_DEVICE_ID_INTEL_82801BA_5 0x2446
27913 +#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448
27914 +#define PCI_DEVICE_ID_INTEL_82801BA_7 0x2449
27915 +#define PCI_DEVICE_ID_INTEL_82562 0x2449
27916 +#define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a
27917 +#define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b
27918 +#define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c
27919 +#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
27920 +#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
27921 +#define PCI_DEVICE_ID_INTEL_82801CA_2 0x2482
27922 +#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
27923 +#define PCI_DEVICE_ID_INTEL_82801CA_4 0x2484
27924 +#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485
27925 +#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486
27926 +#define PCI_DEVICE_ID_INTEL_82801CA_7 0x2487
27927 +#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
27928 +#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
27929 +#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
27930 +#define PCI_DEVICE_ID_INTEL_80310 0x530d
27931 +#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
27932 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
27933 +#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
27934 +#define PCI_DEVICE_ID_INTEL_82437VX 0x7030
27935 +#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
27936 +#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
27937 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
27938 +#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
27939 +#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
27940 +#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120
27941 +#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121
27942 +#define PCI_DEVICE_ID_INTEL_82810_MC3 0x7122
27943 +#define PCI_DEVICE_ID_INTEL_82810_IG3 0x7123
27944 +#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180
27945 +#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181
27946 +#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190
27947 +#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
27948 +#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192
27949 +#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198
27950 +#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199
27951 +#define PCI_DEVICE_ID_INTEL_82443MX_2 0x719a
27952 +#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b
27953 +#define PCI_DEVICE_ID_INTEL_82372FB_0 0x7600
27954 +#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
27955 +#define PCI_DEVICE_ID_INTEL_82372FB_2 0x7602
27956 +#define PCI_DEVICE_ID_INTEL_82372FB_3 0x7603
27957 +#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
27958 +#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
27959 +#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
27961 +#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
27962 +#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291
27963 +#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302
27964 +#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e
27965 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001
27966 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002
27967 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003
27969 +#define PCI_VENDOR_ID_KTI 0x8e2e
27970 +#define PCI_DEVICE_ID_KTI_ET32P2 0x3000
27972 +#define PCI_VENDOR_ID_ADAPTEC 0x9004
27973 +#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078
27974 +#define PCI_DEVICE_ID_ADAPTEC_7821 0x2178
27975 +#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860
27976 +#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
27977 +#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578
27978 +#define PCI_DEVICE_ID_ADAPTEC_5800 0x5800
27979 +#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038
27980 +#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
27981 +#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078
27982 +#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178
27983 +#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078
27984 +#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178
27985 +#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278
27986 +#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378
27987 +#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478
27988 +#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895
27989 +#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078
27990 +#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178
27991 +#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278
27992 +#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378
27993 +#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478
27994 +#define PCI_DEVICE_ID_ADAPTEC_7885 0x8578
27995 +#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678
27996 +#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778
27997 +#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878
27998 +#define PCI_DEVICE_ID_ADAPTEC_1030 0x8b78
28000 +#define PCI_VENDOR_ID_ADAPTEC2 0x9005
28001 +#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
28002 +#define PCI_DEVICE_ID_ADAPTEC2_2930U2 0x0011
28003 +#define PCI_DEVICE_ID_ADAPTEC2_7890B 0x0013
28004 +#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f
28005 +#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050
28006 +#define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051
28007 +#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f
28008 +#define PCI_DEVICE_ID_ADAPTEC2_7892A 0x0080
28009 +#define PCI_DEVICE_ID_ADAPTEC2_7892B 0x0081
28010 +#define PCI_DEVICE_ID_ADAPTEC2_7892D 0x0083
28011 +#define PCI_DEVICE_ID_ADAPTEC2_7892P 0x008f
28012 +#define PCI_DEVICE_ID_ADAPTEC2_7899A 0x00c0
28013 +#define PCI_DEVICE_ID_ADAPTEC2_7899B 0x00c1
28014 +#define PCI_DEVICE_ID_ADAPTEC2_7899D 0x00c3
28015 +#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf
28017 +#define PCI_VENDOR_ID_ATRONICS 0x907f
28018 +#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
28020 +#define PCI_VENDOR_ID_HOLTEK2 0x9412
28021 +#define PCI_DEVICE_ID_HOLTEK2_6565 0x6565
28023 +#define PCI_VENDOR_ID_NETMOS 0x9710
28024 +#define PCI_DEVICE_ID_NETMOS_9735 0x9735
28025 +#define PCI_DEVICE_ID_NETMOS_9835 0x9835
28027 +#define PCI_SUBVENDOR_ID_EXSYS 0xd84d
28028 +#define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014
28030 +#define PCI_VENDOR_ID_TIGERJET 0xe159
28031 +#define PCI_DEVICE_ID_TIGERJET_300 0x0001
28032 +#define PCI_DEVICE_ID_TIGERJET_100 0x0002
28034 +#define PCI_VENDOR_ID_ARK 0xedd8
28035 +#define PCI_DEVICE_ID_ARK_STING 0xa091
28036 +#define PCI_DEVICE_ID_ARK_STINGARK 0xa099
28037 +#define PCI_DEVICE_ID_ARK_2000MT 0xa0a1
28039 Index: b/netboot/pci_io.c
28040 ===================================================================
28041 --- /dev/null
28042 +++ b/netboot/pci_io.c
28043 @@ -0,0 +1,431 @@
28045 +** Support for NE2000 PCI clones added David Monro June 1997
28046 +** Generalised to other NICs by Ken Yap July 1997
28048 +** Most of this is taken from:
28050 +** /usr/src/linux/drivers/pci/pci.c
28051 +** /usr/src/linux/include/linux/pci.h
28052 +** /usr/src/linux/arch/i386/bios32.c
28053 +** /usr/src/linux/include/linux/bios32.h
28054 +** /usr/src/linux/drivers/net/ne.c
28056 +#define PCBIOS
28057 +#include "grub.h"
28058 +#include "pci.h"
28060 +#ifdef CONFIG_PCI_DIRECT
28061 +#define PCIBIOS_SUCCESSFUL 0x00
28063 +#define DEBUG 0
28066 + * Functions for accessing PCI configuration space with type 1 accesses
28067 + */
28069 +#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
28071 +int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
28072 + unsigned int where, uint8_t *value)
28074 + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
28075 + *value = inb(0xCFC + (where&3));
28076 + return PCIBIOS_SUCCESSFUL;
28079 +int pcibios_read_config_word (unsigned int bus,
28080 + unsigned int device_fn, unsigned int where, uint16_t *value)
28082 + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
28083 + *value = inw(0xCFC + (where&2));
28084 + return PCIBIOS_SUCCESSFUL;
28087 +int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
28088 + unsigned int where, uint32_t *value)
28090 + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
28091 + *value = inl(0xCFC);
28092 + return PCIBIOS_SUCCESSFUL;
28095 +int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
28096 + unsigned int where, uint8_t value)
28098 + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
28099 + outb(value, 0xCFC + (where&3));
28100 + return PCIBIOS_SUCCESSFUL;
28103 +int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
28104 + unsigned int where, uint16_t value)
28106 + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
28107 + outw(value, 0xCFC + (where&2));
28108 + return PCIBIOS_SUCCESSFUL;
28111 +int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, uint32_t value)
28113 + outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
28114 + outl(value, 0xCFC);
28115 + return PCIBIOS_SUCCESSFUL;
28118 +#undef CONFIG_CMD
28120 +#else /* CONFIG_PCI_DIRECT not defined */
28122 +#if !defined(PCBIOS)
28123 +#error "The pcibios can only be used when the PCBIOS support is compiled in"
28124 +#endif
28127 +#define KERN_CODE_SEG 0X8
28128 +/* Stuff for asm */
28129 +#define save_flags(x) \
28130 +__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
28132 +#define cli() __asm__ __volatile__ ("cli": : :"memory")
28134 +#define restore_flags(x) \
28135 +__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
28139 +static struct {
28140 + unsigned long address;
28141 + unsigned short segment;
28142 +} bios32_indirect = { 0, KERN_CODE_SEG };
28144 +static long pcibios_entry = 0;
28145 +static struct {
28146 + unsigned long address;
28147 + unsigned short segment;
28148 +} pci_indirect = { 0, KERN_CODE_SEG };
28150 +static unsigned long bios32_service(unsigned long service)
28152 + unsigned char return_code; /* %al */
28153 + unsigned long address; /* %ebx */
28154 + unsigned long length; /* %ecx */
28155 + unsigned long entry; /* %edx */
28156 + unsigned long flags;
28158 + save_flags(flags);
28159 + __asm__(
28160 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28161 + "lcall (%%edi)"
28162 +#else
28163 + "lcall *(%%edi)"
28164 +#endif
28165 + : "=a" (return_code),
28166 + "=b" (address),
28167 + "=c" (length),
28168 + "=d" (entry)
28169 + : "0" (service),
28170 + "1" (0),
28171 + "D" (&bios32_indirect));
28172 + restore_flags(flags);
28174 + switch (return_code) {
28175 + case 0:
28176 + return address + entry;
28177 + case 0x80: /* Not present */
28178 + printf("bios32_service(%d) : not present\n", service);
28179 + return 0;
28180 + default: /* Shouldn't happen */
28181 + printf("bios32_service(%d) : returned %#X, mail drew@colorado.edu\n",
28182 + service, return_code);
28183 + return 0;
28187 +int pcibios_read_config_byte(unsigned int bus,
28188 + unsigned int device_fn, unsigned int where, uint8_t *value)
28190 + unsigned long ret;
28191 + unsigned long bx = (bus << 8) | device_fn;
28192 + unsigned long flags;
28194 + save_flags(flags);
28195 + __asm__(
28196 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28197 + "lcall (%%esi)\n\t"
28198 +#else
28199 + "lcall *(%%esi)\n\t"
28200 +#endif
28201 + "jc 1f\n\t"
28202 + "xor %%ah, %%ah\n"
28203 + "1:"
28204 + : "=c" (*value),
28205 + "=a" (ret)
28206 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
28207 + "b" (bx),
28208 + "D" ((long) where),
28209 + "S" (&pci_indirect));
28210 + restore_flags(flags);
28211 + return (int) (ret & 0xff00) >> 8;
28214 +int pcibios_read_config_word(unsigned int bus,
28215 + unsigned int device_fn, unsigned int where, uint16_t *value)
28217 + unsigned long ret;
28218 + unsigned long bx = (bus << 8) | device_fn;
28219 + unsigned long flags;
28221 + save_flags(flags);
28222 + __asm__(
28223 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28224 + "lcall (%%esi)\n\t"
28225 +#else
28226 + "lcall *(%%esi)\n\t"
28227 +#endif
28228 + "jc 1f\n\t"
28229 + "xor %%ah, %%ah\n"
28230 + "1:"
28231 + : "=c" (*value),
28232 + "=a" (ret)
28233 + : "1" (PCIBIOS_READ_CONFIG_WORD),
28234 + "b" (bx),
28235 + "D" ((long) where),
28236 + "S" (&pci_indirect));
28237 + restore_flags(flags);
28238 + return (int) (ret & 0xff00) >> 8;
28241 +int pcibios_read_config_dword(unsigned int bus,
28242 + unsigned int device_fn, unsigned int where, uint32_t *value)
28244 + unsigned long ret;
28245 + unsigned long bx = (bus << 8) | device_fn;
28246 + unsigned long flags;
28248 + save_flags(flags);
28249 + __asm__(
28250 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28251 + "lcall (%%esi)\n\t"
28252 +#else
28253 + "lcall *(%%esi)\n\t"
28254 +#endif
28255 + "jc 1f\n\t"
28256 + "xor %%ah, %%ah\n"
28257 + "1:"
28258 + : "=c" (*value),
28259 + "=a" (ret)
28260 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
28261 + "b" (bx),
28262 + "D" ((long) where),
28263 + "S" (&pci_indirect));
28264 + restore_flags(flags);
28265 + return (int) (ret & 0xff00) >> 8;
28268 +int pcibios_write_config_byte (unsigned int bus,
28269 + unsigned int device_fn, unsigned int where, uint8_t value)
28271 + unsigned long ret;
28272 + unsigned long bx = (bus << 8) | device_fn;
28273 + unsigned long flags;
28275 + save_flags(flags); cli();
28276 + __asm__(
28277 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28278 + "lcall (%%esi)\n\t"
28279 +#else
28280 + "lcall *(%%esi)\n\t"
28281 +#endif
28282 + "jc 1f\n\t"
28283 + "xor %%ah, %%ah\n"
28284 + "1:"
28285 + : "=a" (ret)
28286 + : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
28287 + "c" (value),
28288 + "b" (bx),
28289 + "D" ((long) where),
28290 + "S" (&pci_indirect));
28291 + restore_flags(flags);
28292 + return (int) (ret & 0xff00) >> 8;
28295 +int pcibios_write_config_word (unsigned int bus,
28296 + unsigned int device_fn, unsigned int where, uint16_t value)
28298 + unsigned long ret;
28299 + unsigned long bx = (bus << 8) | device_fn;
28300 + unsigned long flags;
28302 + save_flags(flags); cli();
28303 + __asm__(
28304 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28305 + "lcall (%%esi)\n\t"
28306 +#else
28307 + "lcall *(%%esi)\n\t"
28308 +#endif
28309 + "jc 1f\n\t"
28310 + "xor %%ah, %%ah\n"
28311 + "1:"
28312 + : "=a" (ret)
28313 + : "0" (PCIBIOS_WRITE_CONFIG_WORD),
28314 + "c" (value),
28315 + "b" (bx),
28316 + "D" ((long) where),
28317 + "S" (&pci_indirect));
28318 + restore_flags(flags);
28319 + return (int) (ret & 0xff00) >> 8;
28322 +int pcibios_write_config_dword (unsigned int bus,
28323 + unsigned int device_fn, unsigned int where, uint32_t value)
28325 + unsigned long ret;
28326 + unsigned long bx = (bus << 8) | device_fn;
28327 + unsigned long flags;
28329 + save_flags(flags); cli();
28330 + __asm__(
28331 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28332 + "lcall (%%esi)\n\t"
28333 +#else
28334 + "lcall *(%%esi)\n\t"
28335 +#endif
28336 + "jc 1f\n\t"
28337 + "xor %%ah, %%ah\n"
28338 + "1:"
28339 + : "=a" (ret)
28340 + : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
28341 + "c" (value),
28342 + "b" (bx),
28343 + "D" ((long) where),
28344 + "S" (&pci_indirect));
28345 + restore_flags(flags);
28346 + return (int) (ret & 0xff00) >> 8;
28349 +static void check_pcibios(void)
28351 + unsigned long signature;
28352 + unsigned char present_status;
28353 + unsigned char major_revision;
28354 + unsigned char minor_revision;
28355 + unsigned long flags;
28356 + int pack;
28358 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
28359 + pci_indirect.address = pcibios_entry;
28361 + save_flags(flags);
28362 + __asm__(
28363 +#ifdef ABSOLUTE_WITHOUT_ASTERISK
28364 + "lcall (%%edi)\n\t"
28365 +#else
28366 + "lcall *(%%edi)\n\t"
28367 +#endif
28368 + "jc 1f\n\t"
28369 + "xor %%ah, %%ah\n"
28370 + "1:\tshl $8, %%eax\n\t"
28371 + "movw %%bx, %%ax"
28372 + : "=d" (signature),
28373 + "=a" (pack)
28374 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
28375 + "D" (&pci_indirect)
28376 + : "bx", "cx");
28377 + restore_flags(flags);
28379 + present_status = (pack >> 16) & 0xff;
28380 + major_revision = (pack >> 8) & 0xff;
28381 + minor_revision = pack & 0xff;
28382 + if (present_status || (signature != PCI_SIGNATURE)) {
28383 + printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
28384 + "BIOS????\n");
28385 + pcibios_entry = 0;
28387 +#if DEBUG
28388 + if (pcibios_entry) {
28389 + printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
28390 + " entry at %#X\n", major_revision,
28391 + minor_revision, pcibios_entry);
28393 +#endif
28397 +static void pcibios_init(void)
28399 + union bios32 *check;
28400 + unsigned char sum;
28401 + int i, length;
28402 + unsigned long bios32_entry = 0;
28404 + EnterFunction("pcibios_init");
28405 + /*
28406 + * Follow the standard procedure for locating the BIOS32 Service
28407 + * directory by scanning the permissible address range from
28408 + * 0xe0000 through 0xfffff for a valid BIOS32 structure.
28410 + */
28412 + for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
28413 + if (check->fields.signature != BIOS32_SIGNATURE)
28414 + continue;
28415 + length = check->fields.length * 16;
28416 + if (!length)
28417 + continue;
28418 + sum = 0;
28419 + for (i = 0; i < length ; ++i)
28420 + sum += check->chars[i];
28421 + if (sum != 0)
28422 + continue;
28423 + if (check->fields.revision != 0) {
28424 + printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
28425 + check->fields.revision, check);
28426 + continue;
28428 +#if DEBUG
28429 + printf("pcibios_init : BIOS32 Service Directory "
28430 + "structure at %#X\n", check);
28431 +#endif
28432 + if (!bios32_entry) {
28433 + if (check->fields.entry >= 0x100000) {
28434 + printf("pcibios_init: entry in high "
28435 + "memory, giving up\n");
28436 + return;
28437 + } else {
28438 + bios32_entry = check->fields.entry;
28439 +#if DEBUG
28440 + printf("pcibios_init : BIOS32 Service Directory"
28441 + " entry at %#X\n", bios32_entry);
28442 +#endif
28443 + bios32_indirect.address = bios32_entry;
28447 + if (bios32_entry)
28448 + check_pcibios();
28449 + LeaveFunction("pcibios_init");
28452 +#endif /* CONFIG_PCI_DIRECT not defined*/
28454 +unsigned long pcibios_bus_base(unsigned int bus __unused)
28456 + /* architecturally this must be 0 */
28457 + return 0;
28460 +void find_pci(int type, struct pci_device *dev)
28462 + EnterFunction("find_pci");
28463 +#ifndef CONFIG_PCI_DIRECT
28464 + if (!pcibios_entry) {
28465 + pcibios_init();
28467 + if (!pcibios_entry) {
28468 + printf("pci_init: no BIOS32 detected\n");
28469 + return;
28471 +#endif
28472 + LeaveFunction("find_pci");
28473 + return scan_pci_bus(type, dev);
28475 Index: b/netboot/pcnet32.c
28476 ===================================================================
28477 --- /dev/null
28478 +++ b/netboot/pcnet32.c
28479 @@ -0,0 +1,1004 @@
28480 +/**************************************************************************
28482 +* pcnet32.c -- Etherboot device driver for the AMD PCnet32
28483 +* Written 2003-2003 by Timothy Legge <tlegge@rogers.com>
28485 +* This program is free software; you can redistribute it and/or modify
28486 +* it under the terms of the GNU General Public License as published by
28487 +* the Free Software Foundation; either version 2 of the License, or
28488 +* (at your option) any later version.
28490 +* This program is distributed in the hope that it will be useful,
28491 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
28492 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28493 +* GNU General Public License for more details.
28495 +* You should have received a copy of the GNU General Public License
28496 +* along with this program; if not, write to the Free Software
28497 +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28499 +* Portions of this code based on:
28500 +* pcnet32.c: An AMD PCnet32 ethernet driver for linux:
28502 +* (C) 1996-1999 Thomas Bogendoerfer
28503 +* See Linux Driver for full information
28505 +* The transmit and poll functions were written with reference to:
28506 +* lance.c - LANCE NIC driver for Etherboot written by Ken Yap
28508 +* Linux Driver Version 1.27a, 10.02.2002
28511 +* REVISION HISTORY:
28512 +* ================
28513 +* v1.0 08-06-2003 timlegge Initial port of Linux driver
28514 +* v1.1 08-23-2003 timlegge Add multicast support
28515 +* v1.2 01-17-2004 timlegge Initial driver output cleanup
28516 +* v1.3 03-29-2004 timlegge More driver cleanup
28518 +* Indent Options: indent -kr -i8
28519 +***************************************************************************/
28521 +/* to get some global routines like printf */
28522 +#include "etherboot.h"
28523 +/* to get the interface to the body of the program */
28524 +#include "nic.h"
28525 +/* to get the PCI support functions, if this is a PCI NIC */
28526 +#include "pci.h"
28527 +/* Include the time functions */
28528 +#include "timer.h"
28529 +#include "mii.h"
28530 +/* void hex_dump(const char *data, const unsigned int len); */
28532 +/* Etherboot Specific definations */
28533 +#define drv_version "v1.3"
28534 +#define drv_date "03-29-2004"
28536 +typedef unsigned char u8;
28537 +typedef signed char s8;
28538 +typedef unsigned short u16;
28539 +typedef signed short s16;
28540 +typedef unsigned int u32;
28541 +typedef signed int s32;
28543 +static u32 ioaddr; /* Globally used for the card's io address */
28545 +#ifdef EDEBUG
28546 +#define dprintf(x) printf x
28547 +#else
28548 +#define dprintf(x)
28549 +#endif
28551 +/* Condensed operations for readability. */
28552 +#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
28553 +#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
28555 +/* End Etherboot Specific */
28557 +int cards_found /* __initdata */ ;
28559 +#ifdef REMOVE
28560 +/* FIXME: Remove these they are probably pointless */
28562 +/*
28563 + * VLB I/O addresses
28564 + */
28565 +static unsigned int pcnet32_portlist[] /*__initdata */ =
28566 +{ 0x300, 0x320, 0x340, 0x360, 0 };
28568 +static int pcnet32_debug = 1;
28569 +static int tx_start = 1; /* Mapping -- 0:20, 1:64, 2:128, 3:~220 (depends on chip vers) */
28570 +static int pcnet32vlb; /* check for VLB cards ? */
28572 +static struct net_device *pcnet32_dev;
28574 +static int max_interrupt_work = 80;
28575 +static int rx_copybreak = 200;
28576 +#endif
28577 +#define PCNET32_PORT_AUI 0x00
28578 +#define PCNET32_PORT_10BT 0x01
28579 +#define PCNET32_PORT_GPSI 0x02
28580 +#define PCNET32_PORT_MII 0x03
28582 +#define PCNET32_PORT_PORTSEL 0x03
28583 +#define PCNET32_PORT_ASEL 0x04
28584 +#define PCNET32_PORT_100 0x40
28585 +#define PCNET32_PORT_FD 0x80
28587 +#define PCNET32_DMA_MASK 0xffffffff
28590 + * table to translate option values from tulip
28591 + * to internal options
28592 + */
28593 +static unsigned char options_mapping[] = {
28594 + PCNET32_PORT_ASEL, /* 0 Auto-select */
28595 + PCNET32_PORT_AUI, /* 1 BNC/AUI */
28596 + PCNET32_PORT_AUI, /* 2 AUI/BNC */
28597 + PCNET32_PORT_ASEL, /* 3 not supported */
28598 + PCNET32_PORT_10BT | PCNET32_PORT_FD, /* 4 10baseT-FD */
28599 + PCNET32_PORT_ASEL, /* 5 not supported */
28600 + PCNET32_PORT_ASEL, /* 6 not supported */
28601 + PCNET32_PORT_ASEL, /* 7 not supported */
28602 + PCNET32_PORT_ASEL, /* 8 not supported */
28603 + PCNET32_PORT_MII, /* 9 MII 10baseT */
28604 + PCNET32_PORT_MII | PCNET32_PORT_FD, /* 10 MII 10baseT-FD */
28605 + PCNET32_PORT_MII, /* 11 MII (autosel) */
28606 + PCNET32_PORT_10BT, /* 12 10BaseT */
28607 + PCNET32_PORT_MII | PCNET32_PORT_100, /* 13 MII 100BaseTx */
28608 + PCNET32_PORT_MII | PCNET32_PORT_100 | PCNET32_PORT_FD, /* 14 MII 100BaseTx-FD */
28609 + PCNET32_PORT_ASEL /* 15 not supported */
28612 +#define MAX_UNITS 8 /* More are supported, limit only on options */
28613 +static int options[MAX_UNITS];
28614 +static int full_duplex[MAX_UNITS];
28617 + * Theory of Operation
28618 + *
28619 + * This driver uses the same software structure as the normal lance
28620 + * driver. So look for a verbose description in lance.c. The differences
28621 + * to the normal lance driver is the use of the 32bit mode of PCnet32
28622 + * and PCnetPCI chips. Because these chips are 32bit chips, there is no
28623 + * 16MB limitation and we don't need bounce buffers.
28624 + */
28629 + * Set the number of Tx and Rx buffers, using Log_2(# buffers).
28630 + * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
28631 + * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
28632 + */
28633 +#ifndef PCNET32_LOG_TX_BUFFERS
28634 +#define PCNET32_LOG_TX_BUFFERS 1
28635 +#define PCNET32_LOG_RX_BUFFERS 2
28636 +#endif
28638 +#define TX_RING_SIZE (1 << (PCNET32_LOG_TX_BUFFERS))
28639 +#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
28640 +/* FIXME: Fix this to allow multiple tx_ring descriptors */
28641 +#define TX_RING_LEN_BITS 0x0000 /*PCNET32_LOG_TX_BUFFERS) << 12) */
28643 +#define RX_RING_SIZE (1 << (PCNET32_LOG_RX_BUFFERS))
28644 +#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
28645 +#define RX_RING_LEN_BITS ((PCNET32_LOG_RX_BUFFERS) << 4)
28647 +#define PKT_BUF_SZ 1544
28649 +/* Offsets from base I/O address. */
28650 +#define PCNET32_WIO_RDP 0x10
28651 +#define PCNET32_WIO_RAP 0x12
28652 +#define PCNET32_WIO_RESET 0x14
28653 +#define PCNET32_WIO_BDP 0x16
28655 +#define PCNET32_DWIO_RDP 0x10
28656 +#define PCNET32_DWIO_RAP 0x14
28657 +#define PCNET32_DWIO_RESET 0x18
28658 +#define PCNET32_DWIO_BDP 0x1C
28660 +#define PCNET32_TOTAL_SIZE 0x20
28662 +/* Buffers for the tx and Rx */
28664 +/* Create a static buffer of size PKT_BUF_SZ for each
28665 +TX Descriptor. All descriptors point to a
28666 +part of this buffer */
28667 +static unsigned char txb[PKT_BUF_SZ * TX_RING_SIZE];
28668 +// __attribute__ ((aligned(16)));
28670 +/* Create a static buffer of size PKT_BUF_SZ for each
28671 +RX Descriptor All descriptors point to a
28672 +part of this buffer */
28673 +static unsigned char rxb[RX_RING_SIZE * PKT_BUF_SZ];
28674 +// __attribute__ ((aligned(16)));
28676 +/* The PCNET32 Rx and Tx ring descriptors. */
28677 +struct pcnet32_rx_head {
28678 + u32 base;
28679 + s16 buf_length;
28680 + s16 status;
28681 + u32 msg_length;
28682 + u32 reserved;
28685 +struct pcnet32_tx_head {
28686 + u32 base;
28687 + s16 length;
28688 + s16 status;
28689 + u32 misc;
28690 + u32 reserved;
28693 +/* The PCNET32 32-Bit initialization block, described in databook. */
28694 +struct pcnet32_init_block {
28695 + u16 mode;
28696 + u16 tlen_rlen;
28697 + u8 phys_addr[6];
28698 + u16 reserved;
28699 + u32 filter[2];
28700 + /* Receive and transmit ring base, along with extra bits. */
28701 + u32 rx_ring;
28702 + u32 tx_ring;
28704 +/* PCnet32 access functions */
28705 +struct pcnet32_access {
28706 + u16(*read_csr) (unsigned long, int);
28707 + void (*write_csr) (unsigned long, int, u16);
28708 + u16(*read_bcr) (unsigned long, int);
28709 + void (*write_bcr) (unsigned long, int, u16);
28710 + u16(*read_rap) (unsigned long);
28711 + void (*write_rap) (unsigned long, u16);
28712 + void (*reset) (unsigned long);
28715 +/* Define the TX Descriptor */
28716 +static struct pcnet32_tx_head tx_ring[TX_RING_SIZE]
28717 + __attribute__ ((aligned(16)));
28720 +/* Define the RX Descriptor */
28721 +static struct pcnet32_rx_head rx_ring[RX_RING_SIZE]
28722 + __attribute__ ((aligned(16)));
28724 +/* May need to be moved to mii.h */
28725 +struct mii_if_info {
28726 + int phy_id;
28727 + int advertising;
28728 + unsigned int full_duplex:1; /* is full duplex? */
28732 + * The first three fields of pcnet32_private are read by the ethernet device
28733 + * so we allocate the structure should be allocated by pci_alloc_consistent().
28734 + */
28735 +#define MII_CNT 4
28736 +struct pcnet32_private {
28737 + struct pcnet32_init_block init_block;
28738 + struct pci_dev *pci_dev; /* Pointer to the associated pci device structure */
28739 + const char *name;
28740 + /* The saved address of a sent-in-place packet/buffer, for skfree(). */
28741 + struct sk_buff *tx_skbuff[TX_RING_SIZE];
28742 + struct sk_buff *rx_skbuff[RX_RING_SIZE];
28743 + struct pcnet32_access a;
28744 + unsigned int cur_rx, cur_tx; /* The next free ring entry */
28745 + char tx_full;
28746 + int options;
28747 + int shared_irq:1, /* shared irq possible */
28748 + ltint:1, /* enable TxDone-intr inhibitor */
28749 + dxsuflo:1, /* disable transmit stop on uflo */
28750 + mii:1; /* mii port available */
28751 + struct mii_if_info mii_if;
28752 + unsigned char phys[MII_CNT];
28753 + struct net_device *next;
28754 + int full_duplex:1;
28755 +} lpx;
28757 +static struct pcnet32_private *lp;
28759 +static int mdio_read(struct nic *nic __unused, int phy_id, int reg_num);
28760 +#if 0
28761 +static void mdio_write(struct nic *nic __unused, int phy_id, int reg_num,
28762 + int val);
28763 +#endif
28764 +enum pci_flags_bit {
28765 + PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4,
28766 + PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 =
28767 + 0x10 << 2, PCI_ADDR3 = 0x10 << 3,
28771 +static u16 pcnet32_wio_read_csr(unsigned long addr, int index)
28773 + outw(index, addr + PCNET32_WIO_RAP);
28774 + return inw(addr + PCNET32_WIO_RDP);
28777 +static void pcnet32_wio_write_csr(unsigned long addr, int index, u16 val)
28779 + outw(index, addr + PCNET32_WIO_RAP);
28780 + outw(val, addr + PCNET32_WIO_RDP);
28783 +static u16 pcnet32_wio_read_bcr(unsigned long addr, int index)
28785 + outw(index, addr + PCNET32_WIO_RAP);
28786 + return inw(addr + PCNET32_WIO_BDP);
28789 +static void pcnet32_wio_write_bcr(unsigned long addr, int index, u16 val)
28791 + outw(index, addr + PCNET32_WIO_RAP);
28792 + outw(val, addr + PCNET32_WIO_BDP);
28795 +static u16 pcnet32_wio_read_rap(unsigned long addr)
28797 + return inw(addr + PCNET32_WIO_RAP);
28800 +static void pcnet32_wio_write_rap(unsigned long addr, u16 val)
28802 + outw(val, addr + PCNET32_WIO_RAP);
28805 +static void pcnet32_wio_reset(unsigned long addr)
28807 + inw(addr + PCNET32_WIO_RESET);
28810 +static int pcnet32_wio_check(unsigned long addr)
28812 + outw(88, addr + PCNET32_WIO_RAP);
28813 + return (inw(addr + PCNET32_WIO_RAP) == 88);
28816 +static struct pcnet32_access pcnet32_wio = {
28817 + read_csr:pcnet32_wio_read_csr,
28818 + write_csr:pcnet32_wio_write_csr,
28819 + read_bcr:pcnet32_wio_read_bcr,
28820 + write_bcr:pcnet32_wio_write_bcr,
28821 + read_rap:pcnet32_wio_read_rap,
28822 + write_rap:pcnet32_wio_write_rap,
28823 + reset:pcnet32_wio_reset
28826 +static u16 pcnet32_dwio_read_csr(unsigned long addr, int index)
28828 + outl(index, addr + PCNET32_DWIO_RAP);
28829 + return (inl(addr + PCNET32_DWIO_RDP) & 0xffff);
28832 +static void pcnet32_dwio_write_csr(unsigned long addr, int index, u16 val)
28834 + outl(index, addr + PCNET32_DWIO_RAP);
28835 + outl(val, addr + PCNET32_DWIO_RDP);
28838 +static u16 pcnet32_dwio_read_bcr(unsigned long addr, int index)
28840 + outl(index, addr + PCNET32_DWIO_RAP);
28841 + return (inl(addr + PCNET32_DWIO_BDP) & 0xffff);
28844 +static void pcnet32_dwio_write_bcr(unsigned long addr, int index, u16 val)
28846 + outl(index, addr + PCNET32_DWIO_RAP);
28847 + outl(val, addr + PCNET32_DWIO_BDP);
28850 +static u16 pcnet32_dwio_read_rap(unsigned long addr)
28852 + return (inl(addr + PCNET32_DWIO_RAP) & 0xffff);
28855 +static void pcnet32_dwio_write_rap(unsigned long addr, u16 val)
28857 + outl(val, addr + PCNET32_DWIO_RAP);
28860 +static void pcnet32_dwio_reset(unsigned long addr)
28862 + inl(addr + PCNET32_DWIO_RESET);
28865 +static int pcnet32_dwio_check(unsigned long addr)
28867 + outl(88, addr + PCNET32_DWIO_RAP);
28868 + return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88);
28871 +static struct pcnet32_access pcnet32_dwio = {
28872 + read_csr:pcnet32_dwio_read_csr,
28873 + write_csr:pcnet32_dwio_write_csr,
28874 + read_bcr:pcnet32_dwio_read_bcr,
28875 + write_bcr:pcnet32_dwio_write_bcr,
28876 + read_rap:pcnet32_dwio_read_rap,
28877 + write_rap:pcnet32_dwio_write_rap,
28878 + reset:pcnet32_dwio_reset
28882 +/* Initialize the PCNET32 Rx and Tx rings. */
28883 +static int pcnet32_init_ring(struct nic *nic)
28885 + int i;
28887 + lp->tx_full = 0;
28888 + lp->cur_rx = lp->cur_tx = 0;
28890 + for (i = 0; i < RX_RING_SIZE; i++) {
28891 + rx_ring[i].base = (u32) virt_to_le32desc(&rxb[i]);
28892 + rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ);
28893 + rx_ring[i].status = le16_to_cpu(0x8000);
28896 + /* The Tx buffer address is filled in as needed, but we do need to clear
28897 + the upper ownership bit. */
28898 + for (i = 0; i < TX_RING_SIZE; i++) {
28899 + tx_ring[i].base = 0;
28900 + tx_ring[i].status = 0;
28904 + lp->init_block.tlen_rlen =
28905 + le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
28906 + for (i = 0; i < 6; i++)
28907 + lp->init_block.phys_addr[i] = nic->node_addr[i];
28908 + lp->init_block.rx_ring = (u32) virt_to_le32desc(&rx_ring[0]);
28909 + lp->init_block.tx_ring = (u32) virt_to_le32desc(&tx_ring[0]);
28910 + return 0;
28913 +/**************************************************************************
28914 +RESET - Reset adapter
28915 +***************************************************************************/
28916 +static void pcnet32_reset(struct nic *nic)
28918 + /* put the card in its initial state */
28919 + u16 val;
28920 + int i;
28922 + /* Reset the PCNET32 */
28923 + lp->a.reset(ioaddr);
28925 + /* switch pcnet32 to 32bit mode */
28926 + lp->a.write_bcr(ioaddr, 20, 2);
28928 + /* set/reset autoselect bit */
28929 + val = lp->a.read_bcr(ioaddr, 2) & ~2;
28930 + if (lp->options & PCNET32_PORT_ASEL)
28931 + val |= 2;
28932 + lp->a.write_bcr(ioaddr, 2, val);
28933 + /* handle full duplex setting */
28934 + if (lp->full_duplex) {
28935 + val = lp->a.read_bcr(ioaddr, 9) & ~3;
28936 + if (lp->options & PCNET32_PORT_FD) {
28937 + val |= 1;
28938 + if (lp->options ==
28939 + (PCNET32_PORT_FD | PCNET32_PORT_AUI))
28940 + val |= 2;
28941 + } else if (lp->options & PCNET32_PORT_ASEL) {
28942 + /* workaround of xSeries250, turn on for 79C975 only */
28943 + i = ((lp->a.
28944 + read_csr(ioaddr,
28945 + 88) | (lp->a.read_csr(ioaddr,
28946 + 89) << 16)) >>
28947 + 12) & 0xffff;
28948 + if (i == 0x2627)
28949 + val |= 3;
28951 + lp->a.write_bcr(ioaddr, 9, val);
28954 + /* set/reset GPSI bit in test register */
28955 + val = lp->a.read_csr(ioaddr, 124) & ~0x10;
28956 + if ((lp->options & PCNET32_PORT_PORTSEL) == PCNET32_PORT_GPSI)
28957 + val |= 0x10;
28958 + lp->a.write_csr(ioaddr, 124, val);
28960 + if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
28961 + val = lp->a.read_bcr(ioaddr, 32) & ~0x38; /* disable Auto Negotiation, set 10Mpbs, HD */
28962 + if (lp->options & PCNET32_PORT_FD)
28963 + val |= 0x10;
28964 + if (lp->options & PCNET32_PORT_100)
28965 + val |= 0x08;
28966 + lp->a.write_bcr(ioaddr, 32, val);
28967 + } else {
28968 + if (lp->options & PCNET32_PORT_ASEL) { /* enable auto negotiate, setup, disable fd */
28969 + val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
28970 + val |= 0x20;
28971 + lp->a.write_bcr(ioaddr, 32, val);
28975 +#ifdef DO_DXSUFLO
28976 + if (lp->dxsuflo) { /* Disable transmit stop on underflow */
28977 + val = lp->a.read_csr(ioaddr, 3);
28978 + val |= 0x40;
28979 + lp->a.write_csr(ioaddr, 3, val);
28981 +#endif
28983 + if (lp->ltint) { /* Enable TxDone-intr inhibitor */
28984 + val = lp->a.read_csr(ioaddr, 5);
28985 + val |= (1 << 14);
28986 + lp->a.write_csr(ioaddr, 5, val);
28988 + lp->init_block.mode =
28989 + le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
28990 + lp->init_block.filter[0] = 0xffffffff;
28991 + lp->init_block.filter[1] = 0xffffffff;
28993 + pcnet32_init_ring(nic);
28996 + /* Re-initialize the PCNET32, and start it when done. */
28997 + lp->a.write_csr(ioaddr, 1,
28998 + (virt_to_bus(&lp->init_block)) & 0xffff);
28999 + lp->a.write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16);
29000 + lp->a.write_csr(ioaddr, 4, 0x0915);
29001 + lp->a.write_csr(ioaddr, 0, 0x0001);
29004 + i = 0;
29005 + while (i++ < 100)
29006 + if (lp->a.read_csr(ioaddr, 0) & 0x0100)
29007 + break;
29008 + /*
29009 + * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
29010 + * reports that doing so triggers a bug in the '974.
29011 + */
29012 + lp->a.write_csr(ioaddr, 0, 0x0042);
29014 + dprintf(("pcnet32 open, csr0 %hX.\n", lp->a.read_csr(ioaddr, 0)));
29018 +/**************************************************************************
29019 +POLL - Wait for a frame
29020 +***************************************************************************/
29021 +static int pcnet32_poll(struct nic *nic __unused, int retrieve)
29023 + /* return true if there's an ethernet packet ready to read */
29024 + /* nic->packet should contain data on return */
29025 + /* nic->packetlen should contain length of data */
29027 + int status;
29028 + int entry;
29030 + entry = lp->cur_rx & RX_RING_MOD_MASK;
29031 + status = ((short) le16_to_cpu(rx_ring[entry].status) >> 8);
29033 + if (status < 0)
29034 + return 0;
29036 + if ( ! retrieve ) return 1;
29038 + if (status == 0x03) {
29039 + nic->packetlen =
29040 + (le32_to_cpu(rx_ring[entry].msg_length) & 0xfff) - 4;
29041 + memcpy(nic->packet, &rxb[entry], nic->packetlen);
29043 + /* Andrew Boyd of QNX reports that some revs of the 79C765
29044 + * clear the buffer length */
29045 + rx_ring[entry].buf_length = le16_to_cpu(-PKT_BUF_SZ);
29046 + rx_ring[entry].status |= le16_to_cpu(0x8000); /* prime for next receive */
29047 + /* Switch to the next Rx ring buffer */
29048 + lp->cur_rx++;
29050 + } else {
29051 + return 0;
29054 + return 1;
29057 +/**************************************************************************
29058 +TRANSMIT - Transmit a frame
29059 +***************************************************************************/
29060 +static void pcnet32_transmit(struct nic *nic __unused, const char *d, /* Destination */
29061 + unsigned int t, /* Type */
29062 + unsigned int s, /* size */
29063 + const char *p)
29064 +{ /* Packet */
29065 + /* send the packet to destination */
29066 + unsigned long time;
29067 + u8 *ptxb;
29068 + u16 nstype;
29069 + u16 status;
29070 + int entry = 0; /*lp->cur_tx & TX_RING_MOD_MASK; */
29072 + status = 0x8300;
29073 + /* point to the current txb incase multiple tx_rings are used */
29074 + ptxb = txb + (lp->cur_tx * PKT_BUF_SZ);
29076 + /* copy the packet to ring buffer */
29077 + memcpy(ptxb, d, ETH_ALEN); /* dst */
29078 + memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
29079 + nstype = htons((u16) t); /* type */
29080 + memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2); /* type */
29081 + memcpy(ptxb + ETH_HLEN, p, s);
29083 + s += ETH_HLEN;
29084 + while (s < ETH_ZLEN) /* pad to min length */
29085 + ptxb[s++] = '\0';
29087 + tx_ring[entry].length = le16_to_cpu(-s);
29088 + tx_ring[entry].misc = 0x00000000;
29089 + tx_ring[entry].base = (u32) virt_to_le32desc(ptxb);
29091 + /* we set the top byte as the very last thing */
29092 + tx_ring[entry].status = le16_to_cpu(status);
29095 + /* Trigger an immediate send poll */
29096 + lp->a.write_csr(ioaddr, 0, 0x0048);
29098 + /* wait for transmit complete */
29099 + lp->cur_tx = 0; /* (lp->cur_tx + 1); */
29100 + time = currticks() + TICKS_PER_SEC; /* wait one second */
29101 + while (currticks() < time &&
29102 + ((short) le16_to_cpu(tx_ring[entry].status) < 0));
29104 + if ((short) le16_to_cpu(tx_ring[entry].status) < 0)
29105 + printf("PCNET32 timed out on transmit\n");
29107 + /* Stop pointing at the current txb
29108 + * otherwise the card continues to send the packet */
29109 + tx_ring[entry].base = 0;
29113 +/**************************************************************************
29114 +DISABLE - Turn off ethernet interface
29115 +***************************************************************************/
29116 +static void pcnet32_disable(struct dev *dev __unused)
29118 + /* Stop the PCNET32 here -- it ocassionally polls memory if we don't */
29119 + lp->a.write_csr(ioaddr, 0, 0x0004);
29121 + /*
29122 + * Switch back to 16-bit mode to avoid problesm with dumb
29123 + * DOS packet driver after a warm reboot
29124 + */
29125 + lp->a.write_bcr(ioaddr, 20, 4);
29128 +/**************************************************************************
29129 +IRQ - Enable, Disable, or Force interrupts
29130 +***************************************************************************/
29131 +static void pcnet32_irq(struct nic *nic __unused, irq_action_t action __unused)
29133 + switch ( action ) {
29134 + case DISABLE :
29135 + break;
29136 + case ENABLE :
29137 + break;
29138 + case FORCE :
29139 + break;
29143 +/**************************************************************************
29144 +PROBE - Look for an adapter, this routine's visible to the outside
29145 +You should omit the last argument struct pci_device * for a non-PCI NIC
29146 +***************************************************************************/
29147 +static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
29149 + struct nic *nic = (struct nic *) dev;
29150 + int i, media;
29151 + int fdx, mii, fset, dxsuflo, ltint;
29152 + int chip_version;
29153 + char *chipname;
29154 + struct pcnet32_access *a = NULL;
29155 + u8 promaddr[6];
29157 + int shared = 1;
29158 + if (pci->ioaddr == 0)
29159 + return 0;
29161 + /* BASE is used throughout to address the card */
29162 + ioaddr = pci->ioaddr;
29163 + printf("pcnet32.c: Found %s, Vendor=0x%hX Device=0x%hX\n",
29164 + pci->name, pci->vendor, pci->dev_id);
29166 + nic->irqno = 0;
29167 + nic->ioaddr = pci->ioaddr & ~3;
29169 + /* reset the chip */
29170 + pcnet32_wio_reset(ioaddr);
29172 + /* NOTE: 16-bit check is first, otherwise some older PCnet chips fail */
29173 + if (pcnet32_wio_read_csr(ioaddr, 0) == 4
29174 + && pcnet32_wio_check(ioaddr)) {
29175 + a = &pcnet32_wio;
29176 + } else {
29177 + pcnet32_dwio_reset(ioaddr);
29178 + if (pcnet32_dwio_read_csr(ioaddr, 0) == 4
29179 + && pcnet32_dwio_check(ioaddr)) {
29180 + a = &pcnet32_dwio;
29181 + } else
29182 + return 0;
29185 + chip_version =
29186 + a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16);
29188 + dprintf(("PCnet chip version is %0xhX\n", chip_version));
29189 + if ((chip_version & 0xfff) != 0x003)
29190 + return 0;
29192 + /* initialize variables */
29193 + fdx = mii = fset = dxsuflo = ltint = 0;
29194 + chip_version = (chip_version >> 12) & 0xffff;
29196 + switch (chip_version) {
29197 + case 0x2420:
29198 + chipname = "PCnet/PCI 79C970"; /* PCI */
29199 + break;
29200 + case 0x2430:
29201 + if (shared)
29202 + chipname = "PCnet/PCI 79C970"; /* 970 gives the wrong chip id back */
29203 + else
29204 + chipname = "PCnet/32 79C965"; /* 486/VL bus */
29205 + break;
29206 + case 0x2621:
29207 + chipname = "PCnet/PCI II 79C970A"; /* PCI */
29208 + fdx = 1;
29209 + break;
29210 + case 0x2623:
29211 + chipname = "PCnet/FAST 79C971"; /* PCI */
29212 + fdx = 1;
29213 + mii = 1;
29214 + fset = 1;
29215 + ltint = 1;
29216 + break;
29217 + case 0x2624:
29218 + chipname = "PCnet/FAST+ 79C972"; /* PCI */
29219 + fdx = 1;
29220 + mii = 1;
29221 + fset = 1;
29222 + break;
29223 + case 0x2625:
29224 + chipname = "PCnet/FAST III 79C973"; /* PCI */
29225 + fdx = 1;
29226 + mii = 1;
29227 + break;
29228 + case 0x2626:
29229 + chipname = "PCnet/Home 79C978"; /* PCI */
29230 + fdx = 1;
29231 + /*
29232 + * This is based on specs published at www.amd.com. This section
29233 + * assumes that a card with a 79C978 wants to go into 1Mb HomePNA
29234 + * mode. The 79C978 can also go into standard ethernet, and there
29235 + * probably should be some sort of module option to select the
29236 + * mode by which the card should operate
29237 + */
29238 + /* switch to home wiring mode */
29239 + media = a->read_bcr(ioaddr, 49);
29241 + printf("media reset to %#x.\n", media);
29242 + a->write_bcr(ioaddr, 49, media);
29243 + break;
29244 + case 0x2627:
29245 + chipname = "PCnet/FAST III 79C975"; /* PCI */
29246 + fdx = 1;
29247 + mii = 1;
29248 + break;
29249 + default:
29250 + printf("PCnet version %#x, no PCnet32 chip.\n",
29251 + chip_version);
29252 + return 0;
29255 + /*
29256 + * On selected chips turn on the BCR18:NOUFLO bit. This stops transmit
29257 + * starting until the packet is loaded. Strike one for reliability, lose
29258 + * one for latency - although on PCI this isnt a big loss. Older chips
29259 + * have FIFO's smaller than a packet, so you can't do this.
29260 + */
29262 + if (fset) {
29263 + a->write_bcr(ioaddr, 18,
29264 + (a->read_bcr(ioaddr, 18) | 0x0800));
29265 + a->write_csr(ioaddr, 80,
29266 + (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00);
29267 + dxsuflo = 1;
29268 + ltint = 1;
29271 + dprintf(("%s at %hX,", chipname, ioaddr));
29273 + /* read PROM address */
29274 + for (i = 0; i < 6; i++)
29275 + promaddr[i] = inb(ioaddr + i);
29277 + /* Update the nic structure with the MAC Address */
29278 + for (i = 0; i < ETH_ALEN; i++) {
29279 + nic->node_addr[i] = promaddr[i];
29281 + /* Print out some hardware info */
29282 + printf("%s: %! at ioaddr %hX, ", pci->name, nic->node_addr,
29283 + ioaddr);
29285 + /* Set to pci bus master */
29286 + adjust_pci_device(pci);
29288 + /* point to private storage */
29289 + lp = &lpx;
29291 +#if EBDEBUG
29292 + if (((chip_version + 1) & 0xfffe) == 0x2624) { /* Version 0x2623 or 0x2624 */
29293 + i = a->read_csr(ioaddr, 80) & 0x0C00; /* Check tx_start_pt */
29294 + dprintf((" tx_start_pt(0x%hX):", i));
29295 + switch (i >> 10) {
29296 + case 0:
29297 + dprintf((" 20 bytes,"));
29298 + break;
29299 + case 1:
29300 + dprintf((" 64 bytes,"));
29301 + break;
29302 + case 2:
29303 + dprintf((" 128 bytes,"));
29304 + break;
29305 + case 3:
29306 + dprintf(("~220 bytes,"));
29307 + break;
29309 + i = a->read_bcr(ioaddr, 18); /* Check Burst/Bus control */
29310 + dprintf((" BCR18(%hX):", i & 0xffff));
29311 + if (i & (1 << 5))
29312 + dprintf(("BurstWrEn "));
29313 + if (i & (1 << 6))
29314 + dprintf(("BurstRdEn "));
29315 + if (i & (1 << 7))
29316 + dprintf(("DWordIO "));
29317 + if (i & (1 << 11))
29318 + dprintf(("NoUFlow "));
29319 + i = a->read_bcr(ioaddr, 25);
29320 + dprintf((" SRAMSIZE=0x%hX,", i << 8));
29321 + i = a->read_bcr(ioaddr, 26);
29322 + dprintf((" SRAM_BND=0x%hX,", i << 8));
29323 + i = a->read_bcr(ioaddr, 27);
29324 + if (i & (1 << 14))
29325 + dprintf(("LowLatRx"));
29327 +#endif
29328 + lp->name = chipname;
29329 + lp->shared_irq = shared;
29330 + lp->full_duplex = fdx;
29331 + lp->dxsuflo = dxsuflo;
29332 + lp->ltint = ltint;
29333 + lp->mii = mii;
29334 + /* FIXME: Fix Options for only one card */
29335 + if ((cards_found >= MAX_UNITS)
29336 + || ((unsigned int) options[cards_found] > sizeof(options_mapping)))
29337 + lp->options = PCNET32_PORT_ASEL;
29338 + else
29339 + lp->options = options_mapping[options[cards_found]];
29341 + if (fdx && !(lp->options & PCNET32_PORT_ASEL) &&
29342 + ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
29343 + lp->options |= PCNET32_PORT_FD;
29345 + if (!a) {
29346 + printf("No access methods\n");
29347 + return 0;
29349 + lp->a = *a;
29351 + /* detect special T1/E1 WAN card by checking for MAC address */
29352 + if (nic->node_addr[0] == 0x00 && nic->node_addr[1] == 0xe0
29353 + && nic->node_addr[2] == 0x75)
29354 + lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
29356 + lp->init_block.mode = le16_to_cpu(0x0003); /* Disable Rx and Tx. */
29357 + lp->init_block.tlen_rlen =
29358 + le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
29359 + for (i = 0; i < 6; i++)
29360 + lp->init_block.phys_addr[i] = nic->node_addr[i];
29361 + lp->init_block.filter[0] = 0xffffffff;
29362 + lp->init_block.filter[1] = 0xffffffff;
29363 + lp->init_block.rx_ring = virt_to_bus(&rx_ring);
29364 + lp->init_block.tx_ring = virt_to_bus(&tx_ring);
29366 + /* switch pcnet32 to 32bit mode */
29367 + a->write_bcr(ioaddr, 20, 2);
29370 + a->write_csr(ioaddr, 1, (virt_to_bus(&lp->init_block)) & 0xffff);
29371 + a->write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16);
29373 + /*
29374 + * To auto-IRQ we enable the initialization-done and DMA error
29375 + * interrupts. For ISA boards we get a DMA error, but VLB and PCI
29376 + * boards will work.
29377 + */
29378 + /* Trigger an initialization just for the interrupt. */
29380 + a->write_csr(ioaddr, 0, 0x41);
29381 + mdelay(1);
29383 + cards_found++;
29385 + /* point to NIC specific routines */
29386 + pcnet32_reset(nic);
29387 + if (1) {
29388 + int tmp;
29389 + int phy, phy_idx = 0;
29390 + u16 mii_lpa;
29391 + lp->phys[0] = 1; /* Default Setting */
29392 + for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
29393 + int mii_status = mdio_read(nic, phy, MII_BMSR);
29394 + if (mii_status != 0xffff && mii_status != 0x0000) {
29395 + lp->phys[phy_idx++] = phy;
29396 + lp->mii_if.advertising =
29397 + mdio_read(nic, phy, MII_ADVERTISE);
29398 + if ((mii_status & 0x0040) == 0) {
29399 + tmp = phy;
29400 + dprintf (("MII PHY found at address %d, status "
29401 + "%hX advertising %hX\n", phy, mii_status,
29402 + lp->mii_if.advertising));
29406 + if (phy_idx == 0)
29407 + printf("No MII transceiver found!\n");
29408 + lp->mii_if.phy_id = lp->phys[0];
29410 + lp->mii_if.advertising =
29411 + mdio_read(nic, lp->phys[0], MII_ADVERTISE);
29413 + mii_lpa = mdio_read(nic, lp->phys[0], MII_LPA);
29414 + lp->mii_if.advertising &= mii_lpa;
29415 + if (lp->mii_if.advertising & ADVERTISE_100FULL)
29416 + printf("100Mbps Full-Duplex\n");
29417 + else if (lp->mii_if.advertising & ADVERTISE_100HALF)
29418 + printf("100Mbps Half-Duplex\n");
29419 + else if (lp->mii_if.advertising & ADVERTISE_10FULL)
29420 + printf("10Mbps Full-Duplex\n");
29421 + else if (lp->mii_if.advertising & ADVERTISE_10HALF)
29422 + printf("10Mbps Half-Duplex\n");
29423 + else
29424 + printf("\n");
29427 + nic->poll = pcnet32_poll;
29428 + nic->transmit = pcnet32_transmit;
29429 + dev->disable = pcnet32_disable;
29430 + nic->irq = pcnet32_irq;
29432 + return 1;
29434 +static int mdio_read(struct nic *nic __unused, int phy_id, int reg_num)
29436 + u16 val_out;
29437 + int phyaddr;
29439 + if (!lp->mii)
29440 + return 0;
29442 + phyaddr = lp->a.read_bcr(ioaddr, 33);
29444 + lp->a.write_bcr(ioaddr, 33,
29445 + ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
29446 + val_out = lp->a.read_bcr(ioaddr, 34);
29447 + lp->a.write_bcr(ioaddr, 33, phyaddr);
29449 + return val_out;
29452 +#if 0
29453 +static void mdio_write(struct nic *nic __unused, int phy_id, int reg_num,
29454 + int val)
29456 + int phyaddr;
29458 + if (!lp->mii)
29459 + return;
29461 + phyaddr = lp->a.read_bcr(ioaddr, 33);
29463 + lp->a.write_bcr(ioaddr, 33,
29464 + ((phy_id & 0x1f) << 5) | (reg_num & 0x1f));
29465 + lp->a.write_bcr(ioaddr, 34, val);
29466 + lp->a.write_bcr(ioaddr, 33, phyaddr);
29468 +#endif
29470 +static struct pci_id pcnet32_nics[] = {
29471 + PCI_ROM(0x1022, 0x2000, "lancepci", "AMD Lance/PCI"),
29472 + PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD Lance/PCI PCNet/32"),
29473 + PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD Lance/HomePNA"),
29476 +struct pci_driver pcnet32_driver = {
29477 + .type = NIC_DRIVER,
29478 + .name = "PCNET32/PCI",
29479 + .probe = pcnet32_probe,
29480 + .ids = pcnet32_nics,
29481 + .id_count = sizeof(pcnet32_nics) / sizeof(pcnet32_nics[0]),
29482 + .class = 0,
29484 Index: b/netboot/pic8259.c
29485 ===================================================================
29486 --- /dev/null
29487 +++ b/netboot/pic8259.c
29488 @@ -0,0 +1,267 @@
29490 + * Basic support for controlling the 8259 Programmable Interrupt Controllers.
29492 + * Initially written by Michael Brown (mcb30).
29493 + */
29495 +#include <etherboot.h>
29496 +#include <pic8259.h>
29498 +#ifdef DEBUG_IRQ
29499 +#define DBG(...) printf ( __VA_ARGS__ )
29500 +#else
29501 +#define DBG(...)
29502 +#endif
29504 +/* Current locations of trivial IRQ handler. These will change at
29505 + * runtime when relocation is used; the handler needs to be copied to
29506 + * base memory before being installed.
29507 + */
29508 +void (*trivial_irq_handler)P((void)) = _trivial_irq_handler;
29509 +uint16_t volatile *trivial_irq_trigger_count = &_trivial_irq_trigger_count;
29510 +segoff_t *trivial_irq_chain_to = &_trivial_irq_chain_to;
29511 +uint8_t *trivial_irq_chain = &_trivial_irq_chain;
29512 +irq_t trivial_irq_installed_on = IRQ_NONE;
29514 +/* Previous trigger count for trivial IRQ handler */
29515 +static uint16_t trivial_irq_previous_trigger_count = 0;
29517 +/* Install a handler for the specified IRQ. Address of previous
29518 + * handler will be stored in previous_handler. Enabled/disabled state
29519 + * of IRQ will be preserved across call, therefore if the handler does
29520 + * chaining, ensure that either (a) IRQ is disabled before call, or
29521 + * (b) previous_handler points directly to the place that the handler
29522 + * picks up its chain-to address.
29523 + */
29525 +int install_irq_handler ( irq_t irq, segoff_t *handler,
29526 + uint8_t *previously_enabled,
29527 + segoff_t *previous_handler ) {
29528 + segoff_t *irq_vector = IRQ_VECTOR ( irq );
29529 + *previously_enabled = irq_enabled ( irq );
29531 + if ( irq > IRQ_MAX ) {
29532 + DBG ( "Invalid IRQ number %d\n" );
29533 + return 0;
29536 + previous_handler->segment = irq_vector->segment;
29537 + previous_handler->offset = irq_vector->offset;
29538 + if ( *previously_enabled ) disable_irq ( irq );
29539 + DBG ( "Installing handler at %hx:%hx for IRQ %d, leaving %s\n",
29540 + handler->segment, handler->offset, irq,
29541 + ( *previously_enabled ? "enabled" : "disabled" ) );
29542 + DBG ( "...(previous handler at %hx:%hx)\n",
29543 + previous_handler->segment, previous_handler->offset );
29544 + irq_vector->segment = handler->segment;
29545 + irq_vector->offset = handler->offset;
29546 + if ( *previously_enabled ) enable_irq ( irq );
29547 + return 1;
29550 +/* Remove handler for the specified IRQ. Routine checks that another
29551 + * handler has not been installed that chains to handler before
29552 + * uninstalling handler. Enabled/disabled state of the IRQ will be
29553 + * restored to that specified by previously_enabled.
29554 + */
29556 +int remove_irq_handler ( irq_t irq, segoff_t *handler,
29557 + uint8_t *previously_enabled,
29558 + segoff_t *previous_handler ) {
29559 + segoff_t *irq_vector = IRQ_VECTOR ( irq );
29561 + if ( irq > IRQ_MAX ) {
29562 + DBG ( "Invalid IRQ number %d\n" );
29563 + return 0;
29565 + if ( ( irq_vector->segment != handler->segment ) ||
29566 + ( irq_vector->offset != handler->offset ) ) {
29567 + DBG ( "Cannot remove handler for IRQ %d\n" );
29568 + return 0;
29571 + DBG ( "Removing handler for IRQ %d\n", irq );
29572 + disable_irq ( irq );
29573 + irq_vector->segment = previous_handler->segment;
29574 + irq_vector->offset = previous_handler->offset;
29575 + if ( *previously_enabled ) enable_irq ( irq );
29576 + return 1;
29579 +/* Install the trivial IRQ handler. This routine installs the
29580 + * handler, tests it and enables the IRQ.
29581 + */
29583 +int install_trivial_irq_handler ( irq_t irq ) {
29584 + segoff_t trivial_irq_handler_segoff = SEGOFF(trivial_irq_handler);
29586 + if ( trivial_irq_installed_on != IRQ_NONE ) {
29587 + DBG ( "Can install trivial IRQ handler only once\n" );
29588 + return 0;
29590 + if ( SEGMENT(trivial_irq_handler) > 0xffff ) {
29591 + DBG ( "Trivial IRQ handler not in base memory\n" );
29592 + return 0;
29595 + DBG ( "Installing trivial IRQ handler on IRQ %d\n", irq );
29596 + if ( ! install_irq_handler ( irq, &trivial_irq_handler_segoff,
29597 + trivial_irq_chain,
29598 + trivial_irq_chain_to ) )
29599 + return 0;
29600 + trivial_irq_installed_on = irq;
29602 + DBG ( "Testing trivial IRQ handler\n" );
29603 + disable_irq ( irq );
29604 + *trivial_irq_trigger_count = 0;
29605 + trivial_irq_previous_trigger_count = 0;
29606 + fake_irq ( irq );
29607 + if ( ! trivial_irq_triggered ( irq ) ) {
29608 + DBG ( "Installation of trivial IRQ handler failed\n" );
29609 + remove_trivial_irq_handler ( irq );
29610 + return 0;
29612 + DBG ( "Trivial IRQ handler installed successfully\n" );
29613 + enable_irq ( irq );
29614 + return 1;
29617 +/* Remove the trivial IRQ handler.
29618 + */
29620 +int remove_trivial_irq_handler ( irq_t irq ) {
29621 + segoff_t trivial_irq_handler_segoff = SEGOFF(trivial_irq_handler);
29623 + if ( trivial_irq_installed_on == IRQ_NONE ) return 1;
29624 + if ( irq != trivial_irq_installed_on ) {
29625 + DBG ( "Cannot uninstall trivial IRQ handler from IRQ %d; "
29626 + "is installed on IRQ %d\n", irq,
29627 + trivial_irq_installed_on );
29628 + return 0;
29631 + if ( ! remove_irq_handler ( irq, &trivial_irq_handler_segoff,
29632 + trivial_irq_chain,
29633 + trivial_irq_chain_to ) )
29634 + return 0;
29636 + if ( trivial_irq_triggered ( trivial_irq_installed_on ) ) {
29637 + DBG ( "Sending EOI for unwanted trivial IRQ\n" );
29638 + send_specific_eoi ( trivial_irq_installed_on );
29641 + trivial_irq_installed_on = IRQ_NONE;
29642 + return 1;
29645 +/* Safe method to detect whether or not trivial IRQ has been
29646 + * triggered. Using this call avoids potential race conditions. This
29647 + * call will return success only once per trigger.
29648 + */
29650 +int trivial_irq_triggered ( irq_t irq ) {
29651 + uint16_t trivial_irq_this_trigger_count = *trivial_irq_trigger_count;
29652 + int triggered = ( trivial_irq_this_trigger_count -
29653 + trivial_irq_previous_trigger_count );
29655 + /* irq is not used at present, but we have it in the API for
29656 + * future-proofing; in case we want the facility to have
29657 + * multiple trivial IRQ handlers installed simultaneously.
29659 + * Avoid compiler warning about unused variable.
29660 + */
29661 + if ( irq == IRQ_NONE ) {};
29663 + trivial_irq_previous_trigger_count = trivial_irq_this_trigger_count;
29664 + return triggered ? 1 : 0;
29667 +/* Copy trivial IRQ handler to a new location. Typically used to copy
29668 + * the handler into base memory; when relocation is being used we need
29669 + * to do this before installing the handler.
29671 + * Call with target=NULL in order to restore the handler to its
29672 + * original location.
29673 + */
29675 +int copy_trivial_irq_handler ( void *target, size_t target_size ) {
29676 + irq_t currently_installed_on = trivial_irq_installed_on;
29677 + uint32_t offset = ( target == NULL ? 0 :
29678 + target - &_trivial_irq_handler_start );
29680 + if (( target != NULL ) && ( target_size < TRIVIAL_IRQ_HANDLER_SIZE )) {
29681 + DBG ( "Insufficient space to copy trivial IRQ handler\n" );
29682 + return 0;
29685 + if ( currently_installed_on != IRQ_NONE ) {
29686 + DBG ("WARNING: relocating trivial IRQ handler while in use\n");
29687 + if ( ! remove_trivial_irq_handler ( currently_installed_on ) )
29688 + return 0;
29691 + /* Do the actual copy */
29692 + if ( target != NULL ) {
29693 + DBG ( "Copying trivial IRQ handler to %hx:%hx\n",
29694 + SEGMENT(target), OFFSET(target) );
29695 + memcpy ( target, &_trivial_irq_handler_start,
29696 + TRIVIAL_IRQ_HANDLER_SIZE );
29697 + } else {
29698 + DBG ( "Restoring trivial IRQ handler to original location\n" );
29700 + /* Update all the pointers to structures within the handler */
29701 + trivial_irq_handler = ( void (*)P((void)) )
29702 + ( (void*)_trivial_irq_handler + offset );
29703 + trivial_irq_trigger_count = (uint16_t*)
29704 + ( (void*)&_trivial_irq_trigger_count + offset );
29705 + trivial_irq_chain_to = (segoff_t*)
29706 + ( (void*)&_trivial_irq_chain_to + offset );
29707 + trivial_irq_chain = (uint8_t*)
29708 + ( (void*)&_trivial_irq_chain + offset );
29710 + if ( currently_installed_on != IRQ_NONE ) {
29711 + if ( ! install_trivial_irq_handler ( currently_installed_on ) )
29712 + return 0;
29714 + return 1;
29717 +/* Send non-specific EOI(s). This seems to be inherently unsafe.
29718 + */
29720 +void send_nonspecific_eoi ( irq_t irq ) {
29721 + DBG ( "Sending non-specific EOI for IRQ %d\n", irq );
29722 + if ( irq >= IRQ_PIC_CUTOFF ) {
29723 + outb ( ICR_EOI_NON_SPECIFIC, PIC2_ICR );
29724 + }
29725 + outb ( ICR_EOI_NON_SPECIFIC, PIC1_ICR );
29728 +/* Send specific EOI(s).
29729 + */
29731 +void send_specific_eoi ( irq_t irq ) {
29732 + DBG ( "Sending specific EOI for IRQ %d\n", irq );
29733 + outb ( ICR_EOI_SPECIFIC | ICR_VALUE(irq), ICR_REG(irq) );
29734 + if ( irq >= IRQ_PIC_CUTOFF ) {
29735 + outb ( ICR_EOI_SPECIFIC | ICR_VALUE(CHAINED_IRQ),
29736 + ICR_REG(CHAINED_IRQ) );
29740 +/* Dump current 8259 status: enabled IRQs and handler addresses.
29741 + */
29743 +#ifdef DEBUG_IRQ
29744 +void dump_irq_status ( void ) {
29745 + int irq = 0;
29747 + for ( irq = 0; irq < 16; irq++ ) {
29748 + if ( irq_enabled ( irq ) ) {
29749 + printf ( "IRQ%d enabled, ISR at %hx:%hx\n", irq,
29750 + IRQ_VECTOR(irq)->segment,
29751 + IRQ_VECTOR(irq)->offset );
29755 +#endif
29756 Index: b/netboot/pic8259.h
29757 ===================================================================
29758 --- /dev/null
29759 +++ b/netboot/pic8259.h
29760 @@ -0,0 +1,99 @@
29762 + * Basic support for controlling the 8259 Programmable Interrupt Controllers.
29764 + * Initially written by Michael Brown (mcb30).
29765 + */
29767 +#ifndef PIC8259_H
29768 +#define PIC8259_H
29770 +/* For segoff_t */
29771 +#include <segoff.h>
29773 +#define IRQ_PIC_CUTOFF (8)
29775 +/* 8259 register locations */
29776 +#define PIC1_ICW1 (0x20)
29777 +#define PIC1_OCW2 (0x20)
29778 +#define PIC1_OCW3 (0x20)
29779 +#define PIC1_ICR (0x20)
29780 +#define PIC1_IRR (0x20)
29781 +#define PIC1_ISR (0x20)
29782 +#define PIC1_ICW2 (0x21)
29783 +#define PIC1_ICW3 (0x21)
29784 +#define PIC1_ICW4 (0x21)
29785 +#define PIC1_IMR (0x21)
29786 +#define PIC2_ICW1 (0xa0)
29787 +#define PIC2_OCW2 (0xa0)
29788 +#define PIC2_OCW3 (0xa0)
29789 +#define PIC2_ICR (0xa0)
29790 +#define PIC2_IRR (0xa0)
29791 +#define PIC2_ISR (0xa0)
29792 +#define PIC2_ICW2 (0xa1)
29793 +#define PIC2_ICW3 (0xa1)
29794 +#define PIC2_ICW4 (0xa1)
29795 +#define PIC2_IMR (0xa1)
29797 +/* Register command values */
29798 +#define OCW3_ID (0x08)
29799 +#define OCW3_READ_IRR (0x03)
29800 +#define OCW3_READ_ISR (0x02)
29801 +#define ICR_EOI_NON_SPECIFIC (0x20)
29802 +#define ICR_EOI_NOP (0x40)
29803 +#define ICR_EOI_SPECIFIC (0x60)
29804 +#define ICR_EOI_SET_PRIORITY (0xc0)
29806 +/* Macros to enable/disable IRQs */
29807 +#define IMR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_IMR : PIC2_IMR )
29808 +#define IMR_BIT(x) ( 1 << ( (x) % IRQ_PIC_CUTOFF ) )
29809 +#define irq_enabled(x) ( ( inb ( IMR_REG(x) ) & IMR_BIT(x) ) == 0 )
29810 +#define enable_irq(x) outb ( inb( IMR_REG(x) ) & ~IMR_BIT(x), IMR_REG(x) )
29811 +#define disable_irq(x) outb ( inb( IMR_REG(x) ) | IMR_BIT(x), IMR_REG(x) )
29813 +/* Macros for acknowledging IRQs */
29814 +#define ICR_REG(x) ( (x) < IRQ_PIC_CUTOFF ? PIC1_ICR : PIC2_ICR )
29815 +#define ICR_VALUE(x) ( (x) % IRQ_PIC_CUTOFF )
29816 +#define CHAINED_IRQ 2
29818 +/* Utility macros to convert IRQ numbers to INT numbers and INT vectors */
29819 +#define IRQ_INT(x) ( (x)<IRQ_PIC_CUTOFF ? (x)+0x08 : (x)-IRQ_PIC_CUTOFF+0x70 )
29820 +#define INT_VECTOR(x) ( (segoff_t*) phys_to_virt( 4 * (x) ) )
29821 +#define IRQ_VECTOR(x) ( INT_VECTOR ( IRQ_INT(x) ) )
29823 +/* Other constants */
29824 +typedef uint8_t irq_t;
29825 +#define IRQ_MAX (15)
29826 +#define IRQ_NONE (0xff)
29828 +/* Labels in assembly code (in pcbios.S)
29829 + */
29830 +extern void _trivial_irq_handler_start;
29831 +extern void _trivial_irq_handler ( void );
29832 +extern volatile uint16_t _trivial_irq_trigger_count;
29833 +extern segoff_t _trivial_irq_chain_to;
29834 +extern uint8_t _trivial_irq_chain;
29835 +extern void _trivial_irq_handler_end;
29836 +#define TRIVIAL_IRQ_HANDLER_SIZE \
29837 + ((uint32_t)( &_trivial_irq_handler_end - &_trivial_irq_handler_start ))
29839 +/* Function prototypes
29840 + */
29841 +int install_irq_handler ( irq_t irq, segoff_t *handler,
29842 + uint8_t *previously_enabled,
29843 + segoff_t *previous_handler );
29844 +int remove_irq_handler ( irq_t irq, segoff_t *handler,
29845 + uint8_t *previously_enabled,
29846 + segoff_t *previous_handler );
29847 +int install_trivial_irq_handler ( irq_t irq );
29848 +int remove_trivial_irq_handler ( irq_t irq );
29849 +int trivial_irq_triggered ( irq_t irq );
29850 +int copy_trivial_irq_handler ( void *target, size_t target_size );
29851 +void send_non_specific_eoi ( irq_t irq );
29852 +void send_specific_eoi ( irq_t irq );
29853 +#ifdef DEBUG_IRQ
29854 +void dump_irq_status ( void );
29855 +#else
29856 +#define dump_irq_status()
29857 +#endif
29859 +#endif /* PIC8259_H */
29860 Index: b/netboot/pnic.c
29861 ===================================================================
29862 --- /dev/null
29863 +++ b/netboot/pnic.c
29864 @@ -0,0 +1,267 @@
29865 +/**************************************************************************
29866 +Etherboot - BOOTP/TFTP Bootstrap Program
29867 +Bochs Pseudo NIC driver for Etherboot
29868 +***************************************************************************/
29871 + * This program is free software; you can redistribute it and/or
29872 + * modify it under the terms of the GNU General Public License as
29873 + * published by the Free Software Foundation; either version 2, or (at
29874 + * your option) any later version.
29876 + * See pnic_api.h for an explanation of the Bochs Pseudo NIC.
29877 + */
29879 +/* to get some global routines like printf */
29880 +#include "etherboot.h"
29881 +/* to get the interface to the body of the program */
29882 +#include "nic.h"
29883 +/* to get the PCI support functions, if this is a PCI NIC */
29884 +#include "pci.h"
29886 +/* PNIC API */
29887 +#include "pnic_api.h"
29889 +/* Private data structure */
29890 +typedef struct {
29891 + uint16_t api_version;
29892 +} pnic_priv_data_t;
29894 +/* Function prototypes */
29895 +static int pnic_api_check ( uint16_t api_version );
29897 +/* NIC specific static variables go here */
29898 +static uint8_t tx_buffer[ETH_FRAME_LEN];
29900 +/*
29901 + * Utility functions: issue a PNIC command, retrieve result. Use
29902 + * pnic_command_quiet if you don't want failure codes to be
29903 + * automatically printed. Returns the PNIC status code.
29904 + *
29905 + * Set output_length to NULL only if you expect to receive exactly
29906 + * output_max_length bytes, otherwise it'll complain that you didn't
29907 + * get enough data (on the assumption that if you not interested in
29908 + * discovering the output length then you're expecting a fixed amount
29909 + * of data).
29910 + */
29912 +static uint16_t pnic_command_quiet ( struct nic *nic, uint16_t command,
29913 + void *input, uint16_t input_length,
29914 + void *output, uint16_t output_max_length,
29915 + uint16_t *output_length ) {
29916 + int i;
29917 + uint16_t status;
29918 + uint16_t _output_length;
29920 + if ( input != NULL ) {
29921 + /* Write input length */
29922 + outw ( input_length, nic->ioaddr + PNIC_REG_LEN );
29923 + /* Write input data */
29924 + for ( i = 0; i < input_length; i++ ) {
29925 + outb( ((char*)input)[i], nic->ioaddr + PNIC_REG_DATA );
29928 + /* Write command */
29929 + outw ( command, nic->ioaddr + PNIC_REG_CMD );
29930 + /* Retrieve status */
29931 + status = inw ( nic->ioaddr + PNIC_REG_STAT );
29932 + /* Retrieve output length */
29933 + _output_length = inw ( nic->ioaddr + PNIC_REG_LEN );
29934 + if ( output_length == NULL ) {
29935 + if ( _output_length != output_max_length ) {
29936 + printf ( "pnic_command %#hx: wrong data length "
29937 + "returned (expected %d, got %d)\n", command,
29938 + output_max_length, _output_length );
29940 + } else {
29941 + *output_length = _output_length;
29943 + if ( output != NULL ) {
29944 + if ( _output_length > output_max_length ) {
29945 + printf ( "pnic_command %#hx: output buffer too small "
29946 + "(have %d, need %d)\n", command,
29947 + output_max_length, _output_length );
29948 + _output_length = output_max_length;
29950 + /* Retrieve output data */
29951 + for ( i = 0; i < _output_length; i++ ) {
29952 + ((char*)output)[i] =
29953 + inb ( nic->ioaddr + PNIC_REG_DATA );
29956 + return status;
29959 +static uint16_t pnic_command ( struct nic *nic, uint16_t command,
29960 + void *input, uint16_t input_length,
29961 + void *output, uint16_t output_max_length,
29962 + uint16_t *output_length ) {
29963 + pnic_priv_data_t *priv = (pnic_priv_data_t*)nic->priv_data;
29964 + uint16_t status = pnic_command_quiet ( nic, command,
29965 + input, input_length,
29966 + output, output_max_length,
29967 + output_length );
29968 + if ( status == PNIC_STATUS_OK ) return status;
29969 + printf ( "PNIC command %#hx (len %#hx) failed with status %#hx\n",
29970 + command, input_length, status );
29971 + if ( priv->api_version ) pnic_api_check(priv->api_version);
29972 + return status;
29975 +/* Check API version matches that of NIC */
29976 +static int pnic_api_check ( uint16_t api_version ) {
29977 + if ( api_version != PNIC_API_VERSION ) {
29978 + printf ( "Warning: API version mismatch! "
29979 + "(NIC's is %d.%d, ours is %d.%d)\n",
29980 + api_version >> 8, api_version & 0xff,
29981 + PNIC_API_VERSION >> 8, PNIC_API_VERSION & 0xff );
29983 + if ( api_version < PNIC_API_VERSION ) {
29984 + printf ( "*** You may need to update your copy of Bochs ***\n" );
29986 + return ( api_version == PNIC_API_VERSION );
29989 +/**************************************************************************
29990 +POLL - Wait for a frame
29991 +***************************************************************************/
29992 +static int pnic_poll(struct nic *nic, int retrieve)
29994 + uint16_t length;
29995 + uint16_t qlen;
29997 + /* Check receive queue length to see if there's anything to
29998 + * get. Necessary since once we've called PNIC_CMD_RECV we
29999 + * have to read out the packet, otherwise it's lost forever.
30000 + */
30001 + if ( pnic_command ( nic, PNIC_CMD_RECV_QLEN, NULL, 0,
30002 + &qlen, sizeof(qlen), NULL )
30003 + != PNIC_STATUS_OK ) return ( 0 );
30004 + if ( qlen == 0 ) return ( 0 );
30006 + /* There is a packet ready. Return 1 if we're only checking. */
30007 + if ( ! retrieve ) return ( 1 );
30009 + /* Retrieve the packet */
30010 + if ( pnic_command ( nic, PNIC_CMD_RECV, NULL, 0,
30011 + nic->packet, ETH_FRAME_LEN, &length )
30012 + != PNIC_STATUS_OK ) return ( 0 );
30013 + nic->packetlen = length;
30014 + return ( 1 );
30017 +/**************************************************************************
30018 +TRANSMIT - Transmit a frame
30019 +***************************************************************************/
30020 +static void pnic_transmit(
30021 + struct nic *nic,
30022 + const char *dest, /* Destination */
30023 + unsigned int type, /* Type */
30024 + unsigned int size, /* size */
30025 + const char *data) /* Packet */
30027 + unsigned int nstype = htons ( type );
30029 + if ( ( ETH_HLEN + size ) >= ETH_FRAME_LEN ) {
30030 + printf ( "pnic_transmit: packet too large\n" );
30031 + return;
30034 + /* Assemble packet */
30035 + memcpy ( tx_buffer, dest, ETH_ALEN );
30036 + memcpy ( tx_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN );
30037 + memcpy ( tx_buffer + 2 * ETH_ALEN, &nstype, 2 );
30038 + memcpy ( tx_buffer + ETH_HLEN, data, size );
30040 + pnic_command ( nic, PNIC_CMD_XMIT, tx_buffer, ETH_HLEN + size,
30041 + NULL, 0, NULL );
30044 +/**************************************************************************
30045 +DISABLE - Turn off ethernet interface
30046 +***************************************************************************/
30047 +static void pnic_disable(struct dev *dev)
30049 + struct nic *nic = (struct nic *)dev;
30050 + pnic_command ( nic, PNIC_CMD_RESET, NULL, 0, NULL, 0, NULL );
30053 +/**************************************************************************
30054 +IRQ - Handle card interrupt status
30055 +***************************************************************************/
30056 +static void pnic_irq ( struct nic *nic, irq_action_t action )
30058 + uint8_t enabled;
30060 + switch ( action ) {
30061 + case DISABLE :
30062 + case ENABLE :
30063 + enabled = ( action == ENABLE ? 1 : 0 );
30064 + pnic_command ( nic, PNIC_CMD_MASK_IRQ,
30065 + &enabled, sizeof(enabled), NULL, 0, NULL );
30066 + break;
30067 + case FORCE :
30068 + pnic_command ( nic, PNIC_CMD_FORCE_IRQ,
30069 + NULL, 0, NULL, 0, NULL );
30070 + break;
30074 +/**************************************************************************
30075 +PROBE - Look for an adapter, this routine's visible to the outside
30076 +***************************************************************************/
30078 +static int pnic_probe(struct dev *dev, struct pci_device *pci)
30080 + struct nic *nic = (struct nic *)dev;
30081 + static pnic_priv_data_t priv;
30082 + uint16_t status;
30084 + printf(" - ");
30086 + /* Clear private data structure and chain it in */
30087 + memset ( &priv, 0, sizeof(priv) );
30088 + nic->priv_data = &priv;
30090 + /* Mask the bit that says "this is an io addr" */
30091 + nic->ioaddr = pci->ioaddr & ~3;
30092 + nic->irqno = pci->irq;
30093 + /* Not sure what this does, but the rtl8139 driver does it */
30094 + adjust_pci_device(pci);
30096 + status = pnic_command_quiet( nic, PNIC_CMD_API_VER, NULL, 0,
30097 + &priv.api_version,
30098 + sizeof(priv.api_version), NULL );
30099 + if ( status != PNIC_STATUS_OK ) {
30100 + printf ( "PNIC failed installation check, code %#hx\n",
30101 + status );
30102 + return 0;
30104 + pnic_api_check(priv.api_version);
30105 + status = pnic_command ( nic, PNIC_CMD_READ_MAC, NULL, 0,
30106 + nic->node_addr, ETH_ALEN, NULL );
30107 + printf ( "Detected Bochs Pseudo NIC MAC %! (API v%d.%d) at %#hx\n",
30108 + nic->node_addr, priv.api_version>>8, priv.api_version&0xff,
30109 + nic->ioaddr );
30111 + /* point to NIC specific routines */
30112 + dev->disable = pnic_disable;
30113 + nic->poll = pnic_poll;
30114 + nic->transmit = pnic_transmit;
30115 + nic->irq = pnic_irq;
30116 + return 1;
30119 +static struct pci_id pnic_nics[] = {
30120 +/* genrules.pl doesn't let us use macros for PCI IDs...*/
30121 +PCI_ROM(0xfefe, 0xefef, "pnic", "Bochs Pseudo NIC Adaptor"),
30124 +struct pci_driver pnic_driver = {
30125 + .type = NIC_DRIVER,
30126 + .name = "PNIC",
30127 + .probe = pnic_probe,
30128 + .ids = pnic_nics,
30129 + .id_count = sizeof(pnic_nics)/sizeof(pnic_nics[0]),
30130 + .class = 0,
30132 Index: b/netboot/pnic_api.h
30133 ===================================================================
30134 --- /dev/null
30135 +++ b/netboot/pnic_api.h
30136 @@ -0,0 +1,59 @@
30138 + * Constants etc. for the Bochs/Etherboot pseudo-NIC
30139 + *
30140 + * This header file must be valid C and C++.
30142 + * Operation of the pseudo-NIC (PNIC) is pretty simple. To write a
30143 + * command plus data, first write the length of the data to
30144 + * PNIC_REG_LEN, then write the data a byte at a type to
30145 + * PNIC_REG_DATA, then write the command code to PNIC_REG_CMD. The
30146 + * status will be available from PNIC_REG_STAT. The length of any
30147 + * data returned will be in PNIC_REG_LEN and can be read a byte at a
30148 + * time from PNIC_REG_DATA.
30149 + */
30152 + * PCI parameters
30153 + */
30154 +#define PNIC_PCI_VENDOR 0xfefe /* Hopefully these won't clash with */
30155 +#define PNIC_PCI_DEVICE 0xefef /* any real PCI device IDs. */
30158 + * 'Hardware' register addresses, offset from io_base
30159 + */
30160 +#define PNIC_REG_CMD 0x00 /* Command register, 2 bytes, write only */
30161 +#define PNIC_REG_STAT 0x00 /* Status register, 2 bytes, read only */
30162 +#define PNIC_REG_LEN 0x02 /* Length register, 2 bytes, read-write */
30163 +#define PNIC_REG_DATA 0x04 /* Data port, 1 byte, read-write */
30165 + * PNIC_MAX_REG used in Bochs to claim i/o space
30166 + */
30167 +#define PNIC_MAX_REG 0x04
30170 + * Command code definitions: write these into PNIC_REG_CMD
30171 + */
30172 +#define PNIC_CMD_NOOP 0x0000
30173 +#define PNIC_CMD_API_VER 0x0001
30174 +#define PNIC_CMD_READ_MAC 0x0002
30175 +#define PNIC_CMD_RESET 0x0003
30176 +#define PNIC_CMD_XMIT 0x0004
30177 +#define PNIC_CMD_RECV 0x0005
30178 +#define PNIC_CMD_RECV_QLEN 0x0006
30179 +#define PNIC_CMD_MASK_IRQ 0x0007
30180 +#define PNIC_CMD_FORCE_IRQ 0x0008
30183 + * Status code definitions: read these from PNIC_REG_STAT
30185 + * We avoid using status codes that might be confused with
30186 + * randomly-read data (e.g. 0x0000, 0xffff etc.)
30187 + */
30188 +#define PNIC_STATUS_OK 0x4f4b /* 'OK' */
30189 +#define PNIC_STATUS_UNKNOWN_CMD 0x3f3f /* '??' */
30192 + * Other miscellaneous information
30193 + */
30195 +#define PNIC_API_VERSION 0x0101 /* 1.1 */
30196 Index: b/netboot/pxe.h
30197 ===================================================================
30198 --- /dev/null
30199 +++ b/netboot/pxe.h
30200 @@ -0,0 +1,521 @@
30202 + * Copyright (c) 2000 Alfred Perlstein <alfred@freebsd.org>
30203 + * All rights reserved.
30204 + * Copyright (c) 2000 Paul Saab <ps@freebsd.org>
30205 + * All rights reserved.
30206 + * Copyright (c) 2000 John Baldwin <jhb@freebsd.org>
30207 + * All rights reserved.
30209 + * Redistribution and use in source and binary forms, with or without
30210 + * modification, are permitted provided that the following conditions
30211 + * are met:
30212 + * 1. Redistributions of source code must retain the above copyright
30213 + * notice, this list of conditions and the following disclaimer.
30214 + * 2. Redistributions in binary form must reproduce the above copyright
30215 + * notice, this list of conditions and the following disclaimer in the
30216 + * documentation and/or other materials provided with the distribution.
30218 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
30219 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30220 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30221 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
30222 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30223 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30224 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30225 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30226 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30227 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30228 + * SUCH DAMAGE.
30230 + * $FreeBSD: src/sys/boot/i386/libi386/pxe.h,v 1.4.2.2 2000/09/10 02:52:18 ps Exp $
30231 + */
30234 + * The typedefs and structures declared in this file
30235 + * clearly violate style(9), the reason for this is to conform to the
30236 + * typedefs/structure-names used in the Intel literature to avoid confusion.
30238 + * It's for your own good. :)
30239 + */
30241 +/* SEGOFF16_t defined in separate header for Etherboot
30242 + */
30243 +#include <segoff.h>
30245 +/* It seems that intel didn't think about ABI,
30246 + * either that or 16bit ABI != 32bit ABI (which seems reasonable)
30247 + * I have to thank Intel for the hair loss I incurred trying to figure
30248 + * out why PXE was mis-reading structures I was passing it (at least
30249 + * from my point of view)
30251 + * Solution: use gcc's '__attribute__ ((packed))' to correctly align
30252 + * structures passed into PXE
30253 + * Question: does this really work for PXE's expected ABI?
30254 + */
30255 +#define PACKED __attribute__ ((packed))
30257 +#define S_SIZE(s) s, sizeof(s) - 1
30259 +#define IP_STR "%d.%d.%d.%d"
30260 +#define IP_ARGS(ip) \
30261 + (int)(ip >> 24) & 0xff, (int)(ip >> 16) & 0xff, \
30262 + (int)(ip >> 8) & 0xff, (int)ip & 0xff
30264 +#define MAC_STR "%02x:%02x:%02x:%02x:%02x:%02x"
30265 +#define MAC_ARGS(mac) \
30266 + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]
30268 +#define PXENFSROOTPATH "/pxeroot"
30270 +typedef struct {
30271 + uint16_t Seg_Addr;
30272 + uint32_t Phy_Addr;
30273 + uint16_t Seg_Size;
30274 +} PACKED SEGDESC_t; /* PACKED is required, otherwise gcc pads this out to 12
30275 + bytes - mbrown@fensystems.co.uk (mcb30) 17/5/03 */
30277 +typedef uint16_t SEGSEL_t;
30278 +typedef uint16_t PXENV_STATUS_t;
30279 +typedef uint32_t IP4_t;
30280 +typedef uint32_t ADDR32_t;
30281 +typedef uint16_t UDP_PORT_t;
30283 +#define MAC_ADDR_LEN 16
30284 +typedef uint8_t MAC_ADDR[MAC_ADDR_LEN];
30286 +/* PXENV+ */
30287 +typedef struct {
30288 + uint8_t Signature[6]; /* 'PXENV+' */
30289 + uint16_t Version; /* MSB = major, LSB = minor */
30290 + uint8_t Length; /* structure length */
30291 + uint8_t Checksum; /* checksum pad */
30292 + SEGOFF16_t RMEntry; /* SEG:OFF to PXE entry point */
30293 + /* don't use PMOffset and PMSelector (from the 2.1 PXE manual) */
30294 + uint32_t PMOffset; /* Protected mode entry */
30295 + SEGSEL_t PMSelector; /* Protected mode selector */
30296 + SEGSEL_t StackSeg; /* Stack segment address */
30297 + uint16_t StackSize; /* Stack segment size (bytes) */
30298 + SEGSEL_t BC_CodeSeg; /* BC Code segment address */
30299 + uint16_t BC_CodeSize; /* BC Code segment size (bytes) */
30300 + SEGSEL_t BC_DataSeg; /* BC Data segment address */
30301 + uint16_t BC_DataSize; /* BC Data segment size (bytes) */
30302 + SEGSEL_t UNDIDataSeg; /* UNDI Data segment address */
30303 + uint16_t UNDIDataSize; /* UNDI Data segment size (bytes) */
30304 + SEGSEL_t UNDICodeSeg; /* UNDI Code segment address */
30305 + uint16_t UNDICodeSize; /* UNDI Code segment size (bytes) */
30306 + SEGOFF16_t PXEPtr; /* SEG:OFF to !PXE struct,
30307 + only present when Version > 2.1 */
30308 +} PACKED pxenv_t;
30310 +/* !PXE */
30311 +typedef struct {
30312 + uint8_t Signature[4];
30313 + uint8_t StructLength;
30314 + uint8_t StructCksum;
30315 + uint8_t StructRev;
30316 + uint8_t reserved_1;
30317 + SEGOFF16_t UNDIROMID;
30318 + SEGOFF16_t BaseROMID;
30319 + SEGOFF16_t EntryPointSP;
30320 + SEGOFF16_t EntryPointESP;
30321 + SEGOFF16_t StatusCallout;
30322 + uint8_t reserved_2;
30323 + uint8_t SegDescCn;
30324 + SEGSEL_t FirstSelector;
30325 + SEGDESC_t Stack;
30326 + SEGDESC_t UNDIData;
30327 + SEGDESC_t UNDICode;
30328 + SEGDESC_t UNDICodeWrite;
30329 + SEGDESC_t BC_Data;
30330 + SEGDESC_t BC_Code;
30331 + SEGDESC_t BC_CodeWrite;
30332 +} PACKED pxe_t;
30334 +#define PXENV_START_UNDI 0x0000
30335 +typedef struct {
30336 + PXENV_STATUS_t Status;
30337 + uint16_t ax;
30338 + uint16_t bx;
30339 + uint16_t dx;
30340 + uint16_t di;
30341 + uint16_t es;
30342 +} PACKED t_PXENV_START_UNDI;
30344 +#define PXENV_UNDI_STARTUP 0x0001
30345 +typedef struct {
30346 + PXENV_STATUS_t Status;
30347 +} PACKED t_PXENV_UNDI_STARTUP;
30349 +#define PXENV_UNDI_CLEANUP 0x0002
30350 +typedef struct {
30351 + PXENV_STATUS_t Status;
30352 +} PACKED t_PXENV_UNDI_CLEANUP;
30354 +#define PXENV_UNDI_INITIALIZE 0x0003
30355 +typedef struct {
30356 + PXENV_STATUS_t Status;
30357 + ADDR32_t ProtocolIni; /* Phys addr of a copy of the driver module */
30358 + uint8_t reserved[8];
30359 +} PACKED t_PXENV_UNDI_INITIALIZE;
30362 +#define MAXNUM_MCADDR 8
30363 +typedef struct {
30364 + uint16_t MCastAddrCount;
30365 + MAC_ADDR McastAddr[MAXNUM_MCADDR];
30366 +} PACKED t_PXENV_UNDI_MCAST_ADDRESS;
30368 +#define PXENV_UNDI_RESET_ADAPTER 0x0004
30369 +typedef struct {
30370 + PXENV_STATUS_t Status;
30371 + t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
30372 +} PACKED t_PXENV_UNDI_RESET;
30374 +#define PXENV_UNDI_SHUTDOWN 0x0005
30375 +typedef struct {
30376 + PXENV_STATUS_t Status;
30377 +} PACKED t_PXENV_UNDI_SHUTDOWN;
30379 +#define PXENV_UNDI_OPEN 0x0006
30380 +typedef struct {
30381 + PXENV_STATUS_t Status;
30382 + uint16_t OpenFlag;
30383 + uint16_t PktFilter;
30384 +# define FLTR_DIRECTED 0x0001
30385 +# define FLTR_BRDCST 0x0002
30386 +# define FLTR_PRMSCS 0x0003
30387 +# define FLTR_SRC_RTG 0x0004
30389 + t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
30390 +} PACKED t_PXENV_UNDI_OPEN;
30392 +#define PXENV_UNDI_CLOSE 0x0007
30393 +typedef struct {
30394 + PXENV_STATUS_t Status;
30395 +} PACKED t_PXENV_UNDI_CLOSE;
30397 +#define PXENV_UNDI_TRANSMIT 0x0008
30398 +typedef struct {
30399 + PXENV_STATUS_t Status;
30400 + uint8_t Protocol;
30401 +# define P_UNKNOWN 0
30402 +# define P_IP 1
30403 +# define P_ARP 2
30404 +# define P_RARP 3
30406 + uint8_t XmitFlag;
30407 +# define XMT_DESTADDR 0x0000
30408 +# define XMT_BROADCAST 0x0001
30410 + SEGOFF16_t DestAddr;
30411 + SEGOFF16_t TBD;
30412 + uint32_t Reserved[2];
30413 +} PACKED t_PXENV_UNDI_TRANSMIT;
30415 +#define MAX_DATA_BLKS 8
30416 +typedef struct {
30417 + uint16_t ImmedLength;
30418 + SEGOFF16_t Xmit;
30419 + uint16_t DataBlkCount;
30420 + struct DataBlk {
30421 + uint8_t TDPtrType;
30422 + uint8_t TDRsvdByte;
30423 + uint16_t TDDataLen;
30424 + SEGOFF16_t TDDataPtr;
30425 + } DataBlock[MAX_DATA_BLKS];
30426 +} PACKED t_PXENV_UNDI_TBD;
30428 +#define PXENV_UNDI_SET_MCAST_ADDRESS 0x0009
30429 +typedef struct {
30430 + PXENV_STATUS_t Status;
30431 + t_PXENV_UNDI_MCAST_ADDRESS R_Mcast_Buf;
30432 +} PACKED t_PXENV_UNDI_SET_MCAST_ADDR;
30434 +#define PXENV_UNDI_SET_STATION_ADDRESS 0x000A
30435 +typedef struct {
30436 + PXENV_STATUS_t Status;
30437 + MAC_ADDR StationAddress; /* Temp MAC addres to use */
30438 +} PACKED t_PXENV_UNDI_SET_STATION_ADDRESS;
30440 +#define PXENV_UNDI_SET_PACKET_FILTER 0x000B
30441 +typedef struct {
30442 + PXENV_STATUS_t Status;
30443 + uint8_t filter; /* see UNDI_OPEN (0x0006) */
30444 +} PACKED t_PXENV_UNDI_SET_PACKET_FILTER;
30446 +#define PXENV_UNDI_GET_INFORMATION 0x000C
30447 +typedef struct {
30448 + PXENV_STATUS_t Status;
30449 + uint16_t BaseIo; /* Adapter base I/O address */
30450 + uint16_t IntNumber; /* Adapter IRQ number */
30451 + uint16_t MaxTranUnit; /* Adapter maximum transmit unit */
30452 + uint16_t HwType; /* Type of protocol at the hardware addr */
30453 +# define ETHER_TYPE 1
30454 +# define EXP_ETHER_TYPE 2
30455 +# define IEEE_TYPE 6
30456 +# define ARCNET_TYPE 7
30458 + uint16_t HwAddrLen; /* Length of hardware address */
30459 + MAC_ADDR CurrentNodeAddress; /* Current hardware address */
30460 + MAC_ADDR PermNodeAddress; /* Permanent hardware address */
30461 + SEGSEL_t ROMAddress; /* Real mode ROM segment address */
30462 + uint16_t RxBufCt; /* Receive queue length */
30463 + uint16_t TxBufCt; /* Transmit queue length */
30464 +} PACKED t_PXENV_UNDI_GET_INFORMATION;
30466 +#define PXENV_UNDI_GET_STATISTICS 0x000D
30467 +typedef struct {
30468 + PXENV_STATUS_t Status;
30469 + uint32_t XmitGoodFrames; /* Number of successful transmissions */
30470 + uint32_t RcvGoodFrames; /* Number of good frames received */
30471 + uint32_t RcvCRCErrors; /* Number of frames with CRC errors */
30472 + uint32_t RcvResourceErrors; /* Number of frames dropped */
30473 +} PACKED t_PXENV_UNDI_GET_STATISTICS;
30475 +#define PXENV_UNDI_CLEAR_STATISTICS 0x000E
30476 +typedef struct {
30477 + PXENV_STATUS_t Status;
30478 +} PACKED t_PXENV_UNDI_CLEAR_STATISTICS;
30480 +#define PXENV_UNDI_INITIATE_DIAGS 0x000F
30481 +typedef struct {
30482 + PXENV_STATUS_t Status;
30483 +} PACKED t_PXENV_UNDI_INITIATE_DIAGS;
30485 +#define PXENV_UNDI_FORCE_INTERRUPT 0x0010
30486 +typedef struct {
30487 + PXENV_STATUS_t Status;
30488 +} PACKED t_PXENV_UNDI_FORCE_INTERRUPT;
30490 +#define PXENV_UNDI_GET_MCAST_ADDRESS 0x0011
30491 +typedef struct {
30492 + PXENV_STATUS_t Status;
30493 + IP4_t InetAddr; /* IP mulicast address */
30494 + MAC_ADDR MediaAddr; /* MAC multicast address */
30495 +} PACKED t_PXENV_UNDI_GET_MCAST_ADDR;
30497 +#define PXENV_UNDI_GET_NIC_TYPE 0x0012
30498 +typedef struct {
30499 + PXENV_STATUS_t Status;
30500 + uint8_t NicType; /* Type of NIC */
30501 +# define PCI_NIC 2
30502 +# define PnP_NIC 3
30503 +# define CardBus_NIC 4
30505 + union {
30506 + struct {
30507 + uint16_t Vendor_ID;
30508 + uint16_t Dev_ID;
30509 + uint8_t Base_Class;
30510 + uint8_t Sub_Class;
30511 + uint8_t Prog_Intf;
30512 + uint8_t Rev;
30513 + uint16_t BusDevFunc;
30514 + uint16_t SubVendor_ID;
30515 + uint16_t SubDevice_ID;
30516 + } pci, cardbus;
30517 + struct {
30518 + uint32_t EISA_Dev_ID;
30519 + uint8_t Base_Class;
30520 + uint8_t Sub_Class;
30521 + uint8_t Prog_Intf;
30522 + uint16_t CardSelNum;
30523 + } pnp;
30524 + } info;
30525 +} PACKED t_PXENV_UNDI_GET_NIC_TYPE;
30527 +#define PXENV_UNDI_GET_IFACE_INFO 0x0013
30528 +typedef struct {
30529 + PXENV_STATUS_t Status;
30530 + uint8_t IfaceType[16]; /* Name of MAC type in ASCII. */
30531 + uint32_t LinkSpeed; /* Defined in NDIS 2.0 spec */
30532 + uint32_t ServiceFlags; /* Defined in NDIS 2.0 spec */
30533 + uint32_t Reserved[4]; /* must be 0 */
30534 +} PACKED t_PXENV_UNDI_GET_IFACE_INFO;
30536 +#define PXENV_UNDI_ISR 0x0014
30537 +typedef struct {
30538 + PXENV_STATUS_t Status;
30539 + uint16_t FuncFlag; /* PXENV_UNDI_ISR_OUT_xxx */
30540 + uint16_t BufferLength; /* Length of Frame */
30541 + uint16_t FrameLength; /* Total length of reciever frame */
30542 + uint16_t FrameHeaderLength; /* Length of the media header in Frame */
30543 + SEGOFF16_t Frame; /* receive buffer */
30544 + uint8_t ProtType; /* Protocol type */
30545 + uint8_t PktType; /* Packet Type */
30546 +# define PXENV_UNDI_ISR_IN_START 1
30547 +# define PXENV_UNDI_ISR_IN_PROCESS 2
30548 +# define PXENV_UNDI_ISR_IN_GET_NEXT 3
30550 + /* one of these will be returned for PXENV_UNDI_ISR_IN_START */
30551 +# define PXENV_UNDI_ISR_OUT_OURS 0
30552 +# define PXENV_UNDI_ISR_OUT_NOT_OURS 1
30554 + /*
30555 + * one of these will bre returnd for PXEND_UNDI_ISR_IN_PROCESS
30556 + * and PXENV_UNDI_ISR_IN_GET_NEXT
30557 + */
30558 +# define PXENV_UNDI_ISR_OUT_DONE 0
30559 +# define PXENV_UNDI_ISR_OUT_TRANSMIT 2
30560 +# define PXENV_UNDI_ISR_OUT_RECEIVE 3
30561 +# define PXENV_UNDI_ISR_OUT_BUSY 4
30562 +} PACKED t_PXENV_UNDI_ISR;
30564 +#define PXENV_STOP_UNDI 0x0015
30565 +typedef struct {
30566 + PXENV_STATUS_t Status;
30567 +} PACKED t_PXENV_STOP_UNDI;
30569 +#define PXENV_TFTP_OPEN 0x0020
30570 +typedef struct {
30571 + PXENV_STATUS_t Status;
30572 + IP4_t ServerIPAddress;
30573 + IP4_t GatewayIPAddress;
30574 + uint8_t FileName[128];
30575 + UDP_PORT_t TFTPPort;
30576 + uint16_t PacketSize;
30577 +} PACKED t_PXENV_TFTP_OPEN;
30579 +#define PXENV_TFTP_CLOSE 0x0021
30580 +typedef struct {
30581 + PXENV_STATUS_t Status;
30582 +} PACKED t_PXENV_TFTP_CLOSE;
30584 +#define PXENV_TFTP_READ 0x0022
30585 +typedef struct {
30586 + PXENV_STATUS_t Status;
30587 + uint16_t PacketNumber;
30588 + uint16_t BufferSize;
30589 + SEGOFF16_t Buffer;
30590 +} PACKED t_PXENV_TFTP_READ;
30592 +#define PXENV_TFTP_READ_FILE 0x0023
30593 +typedef struct {
30594 + PXENV_STATUS_t Status;
30595 + uint8_t FileName[128];
30596 + uint32_t BufferSize;
30597 + ADDR32_t Buffer;
30598 + IP4_t ServerIPAddress;
30599 + IP4_t GatewayIPAdress;
30600 + IP4_t McastIPAdress;
30601 + UDP_PORT_t TFTPClntPort;
30602 + UDP_PORT_t TFTPSrvPort;
30603 + uint16_t TFTPOpenTimeOut;
30604 + uint16_t TFTPReopenDelay;
30605 +} PACKED t_PXENV_TFTP_READ_FILE;
30607 +#define PXENV_TFTP_GET_FSIZE 0x0025
30608 +typedef struct {
30609 + PXENV_STATUS_t Status;
30610 + IP4_t ServerIPAddress;
30611 + IP4_t GatewayIPAdress;
30612 + uint8_t FileName[128];
30613 + uint32_t FileSize;
30614 +} PACKED t_PXENV_TFTP_GET_FSIZE;
30616 +#define PXENV_UDP_OPEN 0x0030
30617 +typedef struct {
30618 + PXENV_STATUS_t Status;
30619 + IP4_t src_ip; /* IP address of this station */
30620 +} PACKED t_PXENV_UDP_OPEN;
30622 +#define PXENV_UDP_CLOSE 0x0031
30623 +typedef struct {
30624 + PXENV_STATUS_t status;
30625 +} PACKED t_PXENV_UDP_CLOSE;
30627 +#define PXENV_UDP_READ 0x0032
30628 +typedef struct {
30629 + PXENV_STATUS_t status;
30630 + IP4_t src_ip; /* IP of sender */
30631 + IP4_t dest_ip; /* Only accept packets sent to this IP */
30632 + UDP_PORT_t s_port; /* UDP source port of sender */
30633 + UDP_PORT_t d_port; /* Only accept packets sent to this port */
30634 + uint16_t buffer_size; /* Size of the packet buffer */
30635 + SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
30636 +} PACKED t_PXENV_UDP_READ;
30638 +#define PXENV_UDP_WRITE 0x0033
30639 +typedef struct {
30640 + PXENV_STATUS_t status;
30641 + IP4_t ip; /* dest ip addr */
30642 + IP4_t gw; /* ip gateway */
30643 + UDP_PORT_t src_port; /* source udp port */
30644 + UDP_PORT_t dst_port; /* destination udp port */
30645 + uint16_t buffer_size; /* Size of the packet buffer */
30646 + SEGOFF16_t buffer; /* SEG:OFF to the packet buffer */
30647 +} PACKED t_PXENV_UDP_WRITE;
30649 +#define PXENV_UNLOAD_STACK 0x0070
30650 +typedef struct {
30651 + PXENV_STATUS_t Status;
30652 + uint8_t reserved[10];
30653 +} PACKED t_PXENV_UNLOAD_STACK;
30656 +#define PXENV_GET_CACHED_INFO 0x0071
30657 +typedef struct {
30658 + PXENV_STATUS_t Status;
30659 + uint16_t PacketType; /* type (defined right here) */
30660 +# define PXENV_PACKET_TYPE_DHCP_DISCOVER 1
30661 +# define PXENV_PACKET_TYPE_DHCP_ACK 2
30662 +# define PXENV_PACKET_TYPE_BINL_REPLY 3
30663 + uint16_t BufferSize; /* max to copy, leave at 0 for pointer */
30664 + SEGOFF16_t Buffer; /* copy to, leave at 0 for pointer */
30665 + uint16_t BufferLimit; /* max size of buffer in BC dataseg ? */
30666 +} PACKED t_PXENV_GET_CACHED_INFO;
30669 +/* structure filled in by PXENV_GET_CACHED_INFO
30670 + * (how we determine which IP we downloaded the initial bootstrap from)
30671 + * words can't describe...
30672 + */
30673 +typedef struct {
30674 + uint8_t opcode;
30675 +# define BOOTP_REQ 1
30676 +# define BOOTP_REP 2
30677 + uint8_t Hardware; /* hardware type */
30678 + uint8_t Hardlen; /* hardware addr len */
30679 + uint8_t Gatehops; /* zero it */
30680 + uint32_t ident; /* random number chosen by client */
30681 + uint16_t seconds; /* seconds since did initial bootstrap */
30682 + uint16_t Flags; /* seconds since did initial bootstrap */
30683 +# define BOOTP_BCAST 0x8000 /* ? */
30684 + IP4_t cip; /* Client IP */
30685 + IP4_t yip; /* Your IP */
30686 + IP4_t sip; /* IP to use for next boot stage */
30687 + IP4_t gip; /* Relay IP ? */
30688 + MAC_ADDR CAddr; /* Client hardware address */
30689 + uint8_t Sname[64]; /* Server's hostname (Optional) */
30690 + uint8_t bootfile[128]; /* boot filename */
30691 + union {
30692 +# if 1
30693 +# define BOOTP_DHCPVEND 1024 /* DHCP extended vendor field size */
30694 +# else
30695 +# define BOOTP_DHCPVEND 312 /* DHCP standard vendor field size */
30696 +# endif
30697 + uint8_t d[BOOTP_DHCPVEND]; /* raw array of vendor/dhcp options */
30698 + struct {
30699 + uint8_t magic[4]; /* DHCP magic cookie */
30700 +# ifndef VM_RFC1048
30701 +# define VM_RFC1048 0x63825363L /* ? */
30702 +# endif
30703 + uint32_t flags; /* bootp flags/opcodes */
30704 + uint8_t pad[56]; /* I don't think intel knows what a
30705 + union does... */
30706 + } v;
30707 + } vendor;
30708 +} PACKED BOOTPLAYER;
30710 +#define PXENV_RESTART_TFTP 0x0073
30711 +#define t_PXENV_RESTART_TFTP t_PXENV_TFTP_READ_FILE
30713 +#define PXENV_START_BASE 0x0075
30714 +typedef struct {
30715 + PXENV_STATUS_t Status;
30716 +} PACKED t_PXENV_START_BASE;
30718 +#define PXENV_STOP_BASE 0x0076
30719 +typedef struct {
30720 + PXENV_STATUS_t Status;
30721 +} PACKED t_PXENV_STOP_BASE;
30722 Index: b/netboot/r8169.c
30723 ===================================================================
30724 --- /dev/null
30725 +++ b/netboot/r8169.c
30726 @@ -0,0 +1,854 @@
30727 +/**************************************************************************
30728 +* r8169.c: Etherboot device driver for the RealTek RTL-8169 Gigabit
30729 +* Written 2003 by Timothy Legge <tlegge@rogers.com>
30731 +* This program is free software; you can redistribute it and/or modify
30732 +* it under the terms of the GNU General Public License as published by
30733 +* the Free Software Foundation; either version 2 of the License, or
30734 +* (at your option) any later version.
30736 +* This program is distributed in the hope that it will be useful,
30737 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
30738 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30739 +* GNU General Public License for more details.
30741 +* You should have received a copy of the GNU General Public License
30742 +* along with this program; if not, write to the Free Software
30743 +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30745 +* Portions of this code based on:
30746 +* r8169.c: A RealTek RTL-8169 Gigabit Ethernet driver
30747 +* for Linux kernel 2.4.x.
30749 +* Written 2002 ShuChen <shuchen@realtek.com.tw>
30750 +* See Linux Driver for full information
30752 +* Linux Driver Version 1.27a, 10.02.2002
30754 +* Thanks to:
30755 +* Jean Chen of RealTek Semiconductor Corp. for
30756 +* providing the evaluation NIC used to develop
30757 +* this driver. RealTek's support for Etherboot
30758 +* is appreciated.
30760 +* REVISION HISTORY:
30761 +* ================
30763 +* v1.0 11-26-2003 timlegge Initial port of Linux driver
30764 +* v1.5 01-17-2004 timlegge Initial driver output cleanup
30765 +* v1.6 03-27-2004 timlegge Additional Cleanup
30767 +* Indent Options: indent -kr -i8
30768 +***************************************************************************/
30770 +/* to get some global routines like printf */
30771 +#include "etherboot.h"
30772 +/* to get the interface to the body of the program */
30773 +#include "nic.h"
30774 +/* to get the PCI support functions, if this is a PCI NIC */
30775 +#include "pci.h"
30776 +#include "timer.h"
30778 +#define drv_version "v1.6"
30779 +#define drv_date "03-27-2004"
30781 +typedef unsigned char u8;
30782 +typedef signed char s8;
30783 +typedef unsigned short u16;
30784 +typedef signed short s16;
30785 +typedef unsigned int u32;
30786 +typedef signed int s32;
30788 +#define HZ 1000
30790 +static u32 ioaddr;
30792 +#ifdef EDEBUG
30793 +#define dprintf(x) printf x
30794 +#else
30795 +#define dprintf(x)
30796 +#endif
30798 +/* Condensed operations for readability. */
30799 +#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
30800 +#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
30802 +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
30804 +/* media options
30805 + _10_Half = 0x01,
30806 + _10_Full = 0x02,
30807 + _100_Half = 0x04,
30808 + _100_Full = 0x08,
30809 + _1000_Full = 0x10,
30811 +static int media = -1;
30813 +#if 0
30814 +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
30815 +static int max_interrupt_work = 20;
30816 +#endif
30818 +#if 0
30819 +/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
30820 + The RTL chips use a 64 element hash table based on the Ethernet CRC. */
30821 +static int multicast_filter_limit = 32;
30822 +#endif
30824 +/* MAC address length*/
30825 +#define MAC_ADDR_LEN 6
30827 +/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
30828 +#define MAX_ETH_FRAME_SIZE 1536
30830 +#define TX_FIFO_THRESH 256 /* In bytes */
30832 +#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
30833 +#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
30834 +#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
30835 +#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
30836 +#define RxPacketMaxSize 0x0800 /* Maximum size supported is 16K-1 */
30837 +#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
30839 +#define NUM_TX_DESC 1 /* Number of Tx descriptor registers */
30840 +#define NUM_RX_DESC 4 /* Number of Rx descriptor registers */
30841 +#define RX_BUF_SIZE 1536 /* Rx Buffer size */
30843 +#define RTL_MIN_IO_SIZE 0x80
30844 +#define TX_TIMEOUT (6*HZ)
30846 +/* write/read MMIO register */
30847 +#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
30848 +#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
30849 +#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
30850 +#define RTL_R8(reg) readb (ioaddr + (reg))
30851 +#define RTL_R16(reg) readw (ioaddr + (reg))
30852 +#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
30854 +enum RTL8169_registers {
30855 + MAC0 = 0, /* Ethernet hardware address. */
30856 + MAR0 = 8, /* Multicast filter. */
30857 + TxDescStartAddr = 0x20,
30858 + TxHDescStartAddr = 0x28,
30859 + FLASH = 0x30,
30860 + ERSR = 0x36,
30861 + ChipCmd = 0x37,
30862 + TxPoll = 0x38,
30863 + IntrMask = 0x3C,
30864 + IntrStatus = 0x3E,
30865 + TxConfig = 0x40,
30866 + RxConfig = 0x44,
30867 + RxMissed = 0x4C,
30868 + Cfg9346 = 0x50,
30869 + Config0 = 0x51,
30870 + Config1 = 0x52,
30871 + Config2 = 0x53,
30872 + Config3 = 0x54,
30873 + Config4 = 0x55,
30874 + Config5 = 0x56,
30875 + MultiIntr = 0x5C,
30876 + PHYAR = 0x60,
30877 + TBICSR = 0x64,
30878 + TBI_ANAR = 0x68,
30879 + TBI_LPAR = 0x6A,
30880 + PHYstatus = 0x6C,
30881 + RxMaxSize = 0xDA,
30882 + CPlusCmd = 0xE0,
30883 + RxDescStartAddr = 0xE4,
30884 + EarlyTxThres = 0xEC,
30885 + FuncEvent = 0xF0,
30886 + FuncEventMask = 0xF4,
30887 + FuncPresetState = 0xF8,
30888 + FuncForceEvent = 0xFC,
30891 +enum RTL8169_register_content {
30892 + /*InterruptStatusBits */
30893 + SYSErr = 0x8000,
30894 + PCSTimeout = 0x4000,
30895 + SWInt = 0x0100,
30896 + TxDescUnavail = 0x80,
30897 + RxFIFOOver = 0x40,
30898 + RxUnderrun = 0x20,
30899 + RxOverflow = 0x10,
30900 + TxErr = 0x08,
30901 + TxOK = 0x04,
30902 + RxErr = 0x02,
30903 + RxOK = 0x01,
30905 + /*RxStatusDesc */
30906 + RxRES = 0x00200000,
30907 + RxCRC = 0x00080000,
30908 + RxRUNT = 0x00100000,
30909 + RxRWT = 0x00400000,
30911 + /*ChipCmdBits */
30912 + CmdReset = 0x10,
30913 + CmdRxEnb = 0x08,
30914 + CmdTxEnb = 0x04,
30915 + RxBufEmpty = 0x01,
30917 + /*Cfg9346Bits */
30918 + Cfg9346_Lock = 0x00,
30919 + Cfg9346_Unlock = 0xC0,
30921 + /*rx_mode_bits */
30922 + AcceptErr = 0x20,
30923 + AcceptRunt = 0x10,
30924 + AcceptBroadcast = 0x08,
30925 + AcceptMulticast = 0x04,
30926 + AcceptMyPhys = 0x02,
30927 + AcceptAllPhys = 0x01,
30929 + /*RxConfigBits */
30930 + RxCfgFIFOShift = 13,
30931 + RxCfgDMAShift = 8,
30933 + /*TxConfigBits */
30934 + TxInterFrameGapShift = 24,
30935 + TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
30937 + /*rtl8169_PHYstatus */
30938 + TBI_Enable = 0x80,
30939 + TxFlowCtrl = 0x40,
30940 + RxFlowCtrl = 0x20,
30941 + _1000bpsF = 0x10,
30942 + _100bps = 0x08,
30943 + _10bps = 0x04,
30944 + LinkStatus = 0x02,
30945 + FullDup = 0x01,
30947 + /*GIGABIT_PHY_registers */
30948 + PHY_CTRL_REG = 0,
30949 + PHY_STAT_REG = 1,
30950 + PHY_AUTO_NEGO_REG = 4,
30951 + PHY_1000_CTRL_REG = 9,
30953 + /*GIGABIT_PHY_REG_BIT */
30954 + PHY_Restart_Auto_Nego = 0x0200,
30955 + PHY_Enable_Auto_Nego = 0x1000,
30957 + /* PHY_STAT_REG = 1; */
30958 + PHY_Auto_Neco_Comp = 0x0020,
30960 + /* PHY_AUTO_NEGO_REG = 4; */
30961 + PHY_Cap_10_Half = 0x0020,
30962 + PHY_Cap_10_Full = 0x0040,
30963 + PHY_Cap_100_Half = 0x0080,
30964 + PHY_Cap_100_Full = 0x0100,
30966 + /* PHY_1000_CTRL_REG = 9; */
30967 + PHY_Cap_1000_Full = 0x0200,
30969 + PHY_Cap_Null = 0x0,
30971 + /*_MediaType*/
30972 + _10_Half = 0x01,
30973 + _10_Full = 0x02,
30974 + _100_Half = 0x04,
30975 + _100_Full = 0x08,
30976 + _1000_Full = 0x10,
30978 + /*_TBICSRBit*/
30979 + TBILinkOK = 0x02000000,
30982 +static struct {
30983 + const char *name;
30984 + u8 version; /* depend on RTL8169 docs */
30985 + u32 RxConfigMask; /* should clear the bits supported by this chip */
30986 +} rtl_chip_info[] = {
30988 +"RTL-8169", 0x00, 0xff7e1880,},};
30990 +enum _DescStatusBit {
30991 + OWNbit = 0x80000000,
30992 + EORbit = 0x40000000,
30993 + FSbit = 0x20000000,
30994 + LSbit = 0x10000000,
30997 +struct TxDesc {
30998 + u32 status;
30999 + u32 vlan_tag;
31000 + u32 buf_addr;
31001 + u32 buf_Haddr;
31004 +struct RxDesc {
31005 + u32 status;
31006 + u32 vlan_tag;
31007 + u32 buf_addr;
31008 + u32 buf_Haddr;
31011 +/* The descriptors for this card are required to be aligned on
31012 +256 byte boundaries. As the align attribute does not do more than
31013 +16 bytes of alignment it requires some extra steps. Add 256 to the
31014 +size of the array and the init_ring adjusts the alignment */
31016 +/* Define the TX Descriptor */
31017 +static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256];
31019 +/* Create a static buffer of size RX_BUF_SZ for each
31020 +TX Descriptor. All descriptors point to a
31021 +part of this buffer */
31022 +static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE];
31024 +/* Define the RX Descriptor */
31025 +static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256];
31027 +/* Create a static buffer of size RX_BUF_SZ for each
31028 +RX Descriptor All descriptors point to a
31029 +part of this buffer */
31030 +static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
31032 +struct rtl8169_private {
31033 + void *mmio_addr; /* memory map physical address */
31034 + int chipset;
31035 + unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
31036 + unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
31037 + unsigned char *TxDescArrays; /* Index of Tx Descriptor buffer */
31038 + unsigned char *RxDescArrays; /* Index of Rx Descriptor buffer */
31039 + struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */
31040 + struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */
31041 + unsigned char *RxBufferRing[NUM_RX_DESC]; /* Index of Rx Buffer array */
31042 + unsigned char *Tx_skbuff[NUM_TX_DESC];
31043 +} tpx;
31045 +static struct rtl8169_private *tpc;
31047 +static const u16 rtl8169_intr_mask =
31048 + SYSErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr |
31049 + TxOK | RxErr | RxOK;
31050 +static const unsigned int rtl8169_rx_config =
31051 + (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
31053 +void mdio_write(int RegAddr, int value)
31055 + int i;
31057 + RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value);
31058 + udelay(1000);
31060 + for (i = 2000; i > 0; i--) {
31061 + /* Check if the RTL8169 has completed writing to the specified MII register */
31062 + if (!(RTL_R32(PHYAR) & 0x80000000)) {
31063 + break;
31064 + } else {
31065 + udelay(100);
31070 +int mdio_read(int RegAddr)
31072 + int i, value = -1;
31074 + RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16);
31075 + udelay(1000);
31077 + for (i = 2000; i > 0; i--) {
31078 + /* Check if the RTL8169 has completed retrieving data from the specified MII register */
31079 + if (RTL_R32(PHYAR) & 0x80000000) {
31080 + value = (int) (RTL_R32(PHYAR) & 0xFFFF);
31081 + break;
31082 + } else {
31083 + udelay(100);
31086 + return value;
31089 +static int rtl8169_init_board(struct pci_device *pdev)
31091 + int i;
31092 + unsigned long rtreg_base, rtreg_len;
31093 + u32 tmp;
31095 + rtreg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_1);
31096 + rtreg_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_1);
31098 + /* check for weird/broken PCI region reporting */
31099 + if (rtreg_len < RTL_MIN_IO_SIZE) {
31100 + printf("Invalid PCI region size(s), aborting\n");
31103 + adjust_pci_device(pdev);
31104 +/* pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); */
31106 + /* ioremap MMIO region */
31107 + ioaddr = (unsigned long) ioremap(rtreg_base, rtreg_len);
31108 + if (ioaddr == 0)
31109 + return 0;
31111 + tpc->mmio_addr = &ioaddr;
31112 + /* Soft reset the chip. */
31113 + RTL_W8(ChipCmd, CmdReset);
31115 + /* Check that the chip has finished the reset. */
31116 + for (i = 1000; i > 0; i--)
31117 + if ((RTL_R8(ChipCmd) & CmdReset) == 0)
31118 + break;
31119 + else
31120 + udelay(10);
31122 + /* identify chip attached to board */
31123 + tmp = RTL_R32(TxConfig);
31124 + tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >> 24;
31126 + for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--)
31127 + if (tmp == rtl_chip_info[i].version) {
31128 + tpc->chipset = i;
31129 + goto match;
31131 + /* if unknown chip, assume array element #0, original RTL-8169 in this case */
31132 + dprintf(("PCI device: unknown chip version, assuming RTL-8169\n"));
31133 + dprintf(("PCI device: TxConfig = 0x%hX\n",
31134 + (unsigned long) RTL_R32(TxConfig)));
31135 + tpc->chipset = 0;
31136 + return 1;
31137 + match:
31138 + return 0;
31142 +/**************************************************************************
31143 +IRQ - Wait for a frame
31144 +***************************************************************************/
31145 +void r8169_irq ( struct nic *nic __unused, irq_action_t action ) {
31146 + int intr_status = 0;
31147 + int interested = RxUnderrun | RxOverflow | RxFIFOOver | RxErr | RxOK;
31149 + switch ( action ) {
31150 + case DISABLE:
31151 + case ENABLE:
31152 + intr_status = RTL_R16(IntrStatus);
31153 + /* h/w no longer present (hotplug?) or major error,
31154 + bail */
31155 + if (intr_status == 0xFFFF)
31156 + break;
31158 + intr_status = intr_status & ~interested;
31159 + if ( action == ENABLE )
31160 + intr_status = intr_status | interested;
31161 + RTL_W16(IntrMask, intr_status);
31162 + break;
31163 + case FORCE :
31164 + RTL_W8(TxPoll, (RTL_R8(TxPoll) | 0x01));
31165 + break;
31169 +/**************************************************************************
31170 +POLL - Wait for a frame
31171 +***************************************************************************/
31172 +static int r8169_poll(struct nic *nic, int retreive)
31174 + /* return true if there's an ethernet packet ready to read */
31175 + /* nic->packet should contain data on return */
31176 + /* nic->packetlen should contain length of data */
31177 + int cur_rx;
31178 + unsigned int intr_status = 0;
31179 + cur_rx = tpc->cur_rx;
31180 + if ((tpc->RxDescArray[cur_rx].status & OWNbit) == 0) {
31181 + /* There is a packet ready */
31182 + if(!retreive)
31183 + return 1;
31184 + intr_status = RTL_R16(IntrStatus);
31185 + /* h/w no longer present (hotplug?) or major error,
31186 + bail */
31187 + if (intr_status == 0xFFFF)
31188 + return 0;
31189 + RTL_W16(IntrStatus, intr_status &
31190 + ~(RxFIFOOver | RxOverflow | RxOK));
31192 + if (!(tpc->RxDescArray[cur_rx].status & RxRES)) {
31193 + nic->packetlen = (int) (tpc->RxDescArray[cur_rx].
31194 + status & 0x00001FFF) - 4;
31195 + memcpy(nic->packet, tpc->RxBufferRing[cur_rx],
31196 + nic->packetlen);
31197 + if (cur_rx == NUM_RX_DESC - 1)
31198 + tpc->RxDescArray[cur_rx].status =
31199 + (OWNbit | EORbit) + RX_BUF_SIZE;
31200 + else
31201 + tpc->RxDescArray[cur_rx].status =
31202 + OWNbit + RX_BUF_SIZE;
31203 + tpc->RxDescArray[cur_rx].buf_addr =
31204 + virt_to_bus(tpc->RxBufferRing[cur_rx]);
31205 + } else
31206 + printf("Error Rx");
31207 + /* FIXME: shouldn't I reset the status on an error */
31208 + cur_rx = (cur_rx + 1) % NUM_RX_DESC;
31209 + tpc->cur_rx = cur_rx;
31210 + RTL_W16(IntrStatus, intr_status &
31211 + (RxFIFOOver | RxOverflow | RxOK));
31213 + return 1;
31216 + tpc->cur_rx = cur_rx;
31217 + /* FIXME: There is no reason to do this as cur_rx did not change */
31219 + return (0); /* initially as this is called to flush the input */
31223 +/**************************************************************************
31224 +TRANSMIT - Transmit a frame
31225 +***************************************************************************/
31226 +static void r8169_transmit(struct nic *nic, const char *d, /* Destination */
31227 + unsigned int t, /* Type */
31228 + unsigned int s, /* size */
31229 + const char *p)
31230 +{ /* Packet */
31231 + /* send the packet to destination */
31233 + u16 nstype;
31234 + u32 to;
31235 + u8 *ptxb;
31236 + int entry = tpc->cur_tx % NUM_TX_DESC;
31238 + /* point to the current txb incase multiple tx_rings are used */
31239 + ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
31240 + memcpy(ptxb, d, ETH_ALEN);
31241 + memcpy(ptxb + ETH_ALEN, nic->node_addr, ETH_ALEN);
31242 + nstype = htons((u16) t);
31243 + memcpy(ptxb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
31244 + memcpy(ptxb + ETH_HLEN, p, s);
31245 + s += ETH_HLEN;
31246 + s &= 0x0FFF;
31247 + while (s < ETH_ZLEN)
31248 + ptxb[s++] = '\0';
31250 + tpc->TxDescArray[entry].buf_addr = virt_to_bus(ptxb);
31251 + if (entry != (NUM_TX_DESC - 1))
31252 + tpc->TxDescArray[entry].status =
31253 + (OWNbit | FSbit | LSbit) | ((s > ETH_ZLEN) ? s :
31254 + ETH_ZLEN);
31255 + else
31256 + tpc->TxDescArray[entry].status =
31257 + (OWNbit | EORbit | FSbit | LSbit) | ((s > ETH_ZLEN) ? s
31258 + : ETH_ZLEN);
31259 + RTL_W8(TxPoll, 0x40); /* set polling bit */
31261 + tpc->cur_tx++;
31262 + to = currticks() + TX_TIMEOUT;
31263 + while ((tpc->TxDescArray[entry].status & OWNbit) && (currticks() < to)); /* wait */
31265 + if (currticks() >= to) {
31266 + printf("TX Time Out");
31270 +static void rtl8169_set_rx_mode(struct nic *nic __unused)
31272 + u32 mc_filter[2]; /* Multicast hash filter */
31273 + int rx_mode;
31274 + u32 tmp = 0;
31276 + /* IFF_ALLMULTI */
31277 + /* Too many to filter perfectly -- accept all multicasts. */
31278 + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
31279 + mc_filter[1] = mc_filter[0] = 0xffffffff;
31281 + tmp =
31282 + rtl8169_rx_config | rx_mode | (RTL_R32(RxConfig) &
31283 + rtl_chip_info[tpc->chipset].
31284 + RxConfigMask);
31286 + RTL_W32(RxConfig, tmp);
31287 + RTL_W32(MAR0 + 0, mc_filter[0]);
31288 + RTL_W32(MAR0 + 4, mc_filter[1]);
31290 +static void rtl8169_hw_start(struct nic *nic)
31292 + u32 i;
31294 + /* Soft reset the chip. */
31295 + RTL_W8(ChipCmd, CmdReset);
31297 + /* Check that the chip has finished the reset. */
31298 + for (i = 1000; i > 0; i--) {
31299 + if ((RTL_R8(ChipCmd) & CmdReset) == 0)
31300 + break;
31301 + else
31302 + udelay(10);
31305 + RTL_W8(Cfg9346, Cfg9346_Unlock);
31306 + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
31307 + RTL_W8(EarlyTxThres, EarlyTxThld);
31309 + /* For gigabit rtl8169 */
31310 + RTL_W16(RxMaxSize, RxPacketMaxSize);
31312 + /* Set Rx Config register */
31313 + i = rtl8169_rx_config | (RTL_R32(RxConfig) &
31314 + rtl_chip_info[tpc->chipset].RxConfigMask);
31315 + RTL_W32(RxConfig, i);
31317 + /* Set DMA burst size and Interframe Gap Time */
31318 + RTL_W32(TxConfig,
31319 + (TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
31320 + TxInterFrameGapShift));
31323 + tpc->cur_rx = 0;
31325 + RTL_W32(TxDescStartAddr, virt_to_le32desc(tpc->TxDescArray));
31326 + RTL_W32(RxDescStartAddr, virt_to_le32desc(tpc->RxDescArray));
31327 + RTL_W8(Cfg9346, Cfg9346_Lock);
31328 + udelay(10);
31330 + RTL_W32(RxMissed, 0);
31332 + rtl8169_set_rx_mode(nic);
31334 + /* no early-rx interrupts */
31335 + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
31338 +static void rtl8169_init_ring(struct nic *nic __unused)
31340 + int i;
31342 + tpc->cur_rx = 0;
31343 + tpc->cur_tx = 0;
31344 + memset(tpc->TxDescArray, 0x0, NUM_TX_DESC * sizeof(struct TxDesc));
31345 + memset(tpc->RxDescArray, 0x0, NUM_RX_DESC * sizeof(struct RxDesc));
31347 + for (i = 0; i < NUM_TX_DESC; i++) {
31348 + tpc->Tx_skbuff[i] = &txb[i];
31351 + for (i = 0; i < NUM_RX_DESC; i++) {
31352 + if (i == (NUM_RX_DESC - 1))
31353 + tpc->RxDescArray[i].status =
31354 + (OWNbit | EORbit) + RX_BUF_SIZE;
31355 + else
31356 + tpc->RxDescArray[i].status = OWNbit + RX_BUF_SIZE;
31358 + tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
31359 + tpc->RxDescArray[i].buf_addr =
31360 + virt_to_bus(tpc->RxBufferRing[i]);
31364 +/**************************************************************************
31365 +RESET - Finish setting up the ethernet interface
31366 +***************************************************************************/
31367 +static void r8169_reset(struct nic *nic)
31369 + int i;
31370 + u8 diff;
31371 + u32 TxPhyAddr, RxPhyAddr;
31373 + tpc->TxDescArrays = tx_ring;
31374 + if (tpc->TxDescArrays == 0)
31375 + printf("Allot Error");
31376 + /* Tx Desscriptor needs 256 bytes alignment; */
31377 + TxPhyAddr = virt_to_bus(tpc->TxDescArrays);
31378 + diff = 256 - (TxPhyAddr - ((TxPhyAddr >> 8) << 8));
31379 + TxPhyAddr += diff;
31380 + tpc->TxDescArray = (struct TxDesc *) (tpc->TxDescArrays + diff);
31382 + tpc->RxDescArrays = rx_ring;
31383 + /* Rx Desscriptor needs 256 bytes alignment; */
31384 + RxPhyAddr = virt_to_bus(tpc->RxDescArrays);
31385 + diff = 256 - (RxPhyAddr - ((RxPhyAddr >> 8) << 8));
31386 + RxPhyAddr += diff;
31387 + tpc->RxDescArray = (struct RxDesc *) (tpc->RxDescArrays + diff);
31389 + if (tpc->TxDescArrays == NULL || tpc->RxDescArrays == NULL) {
31390 + printf("Allocate RxDescArray or TxDescArray failed\n");
31391 + return;
31394 + rtl8169_init_ring(nic);
31395 + rtl8169_hw_start(nic);
31396 + /* Construct a perfect filter frame with the mac address as first match
31397 + * and broadcast for all others */
31398 + for (i = 0; i < 192; i++)
31399 + txb[i] = 0xFF;
31401 + txb[0] = nic->node_addr[0];
31402 + txb[1] = nic->node_addr[1];
31403 + txb[2] = nic->node_addr[2];
31404 + txb[3] = nic->node_addr[3];
31405 + txb[4] = nic->node_addr[4];
31406 + txb[5] = nic->node_addr[5];
31409 +/**************************************************************************
31410 +DISABLE - Turn off ethernet interface
31411 +***************************************************************************/
31412 +static void r8169_disable(struct dev *dev __unused)
31414 + int i;
31415 + /* Stop the chip's Tx and Rx DMA processes. */
31416 + RTL_W8(ChipCmd, 0x00);
31418 + /* Disable interrupts by clearing the interrupt mask. */
31419 + RTL_W16(IntrMask, 0x0000);
31421 + RTL_W32(RxMissed, 0);
31423 + tpc->TxDescArrays = NULL;
31424 + tpc->RxDescArrays = NULL;
31425 + tpc->TxDescArray = NULL;
31426 + tpc->RxDescArray = NULL;
31427 + for (i = 0; i < NUM_RX_DESC; i++) {
31428 + tpc->RxBufferRing[i] = NULL;
31432 +/**************************************************************************
31433 +PROBE - Look for an adapter, this routine's visible to the outside
31434 +***************************************************************************/
31436 +#define board_found 1
31437 +#define valid_link 0
31438 +static int r8169_probe(struct dev *dev, struct pci_device *pci)
31440 + struct nic *nic = (struct nic *) dev;
31441 + static int board_idx = -1;
31442 + static int printed_version = 0;
31443 + int i, rc;
31444 + int option = -1, Cap10_100 = 0, Cap1000 = 0;
31446 + printf("r8169.c: Found %s, Vendor=%hX Device=%hX\n",
31447 + pci->name, pci->vendor, pci->dev_id);
31449 + board_idx++;
31451 + printed_version = 1;
31453 + /* point to private storage */
31454 + tpc = &tpx;
31456 + rc = rtl8169_init_board(pci); /* Return code is meaningless */
31458 + /* Get MAC address. FIXME: read EEPROM */
31459 + for (i = 0; i < MAC_ADDR_LEN; i++)
31460 + nic->node_addr[i] = RTL_R8(MAC0 + i);
31462 + dprintf(("%s: Identified chip type is '%s'.\n", pci->name,
31463 + rtl_chip_info[tpc->chipset].name));
31464 + /* Print out some hardware info */
31465 + printf("%s: %! at ioaddr %hX, ", pci->name, nic->node_addr,
31466 + ioaddr);
31468 + /* if TBI is not endbled */
31469 + if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
31470 + int val = mdio_read(PHY_AUTO_NEGO_REG);
31472 + option = media;
31473 + /* Force RTL8169 in 10/100/1000 Full/Half mode. */
31474 + if (option > 0) {
31475 + printf(" Force-mode Enabled.\n");
31476 + Cap10_100 = 0, Cap1000 = 0;
31477 + switch (option) {
31478 + case _10_Half:
31479 + Cap10_100 = PHY_Cap_10_Half;
31480 + Cap1000 = PHY_Cap_Null;
31481 + break;
31482 + case _10_Full:
31483 + Cap10_100 = PHY_Cap_10_Full;
31484 + Cap1000 = PHY_Cap_Null;
31485 + break;
31486 + case _100_Half:
31487 + Cap10_100 = PHY_Cap_100_Half;
31488 + Cap1000 = PHY_Cap_Null;
31489 + break;
31490 + case _100_Full:
31491 + Cap10_100 = PHY_Cap_100_Full;
31492 + Cap1000 = PHY_Cap_Null;
31493 + break;
31494 + case _1000_Full:
31495 + Cap10_100 = PHY_Cap_Null;
31496 + Cap1000 = PHY_Cap_1000_Full;
31497 + break;
31498 + default:
31499 + break;
31501 + /* leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
31502 + mdio_write(PHY_AUTO_NEGO_REG,
31503 + Cap10_100 | (val & 0x1F));
31504 + mdio_write(PHY_1000_CTRL_REG, Cap1000);
31505 + } else {
31506 + dprintf(("Auto-negotiation Enabled.\n",
31507 + pci->name));
31509 + /* enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged */
31510 + mdio_write(PHY_AUTO_NEGO_REG,
31511 + PHY_Cap_10_Half | PHY_Cap_10_Full |
31512 + PHY_Cap_100_Half | PHY_Cap_100_Full |
31513 + (val & 0x1F));
31515 + /* enable 1000 Full Mode */
31516 + mdio_write(PHY_1000_CTRL_REG, PHY_Cap_1000_Full);
31520 + /* Enable auto-negotiation and restart auto-nigotiation */
31521 + mdio_write(PHY_CTRL_REG,
31522 + PHY_Enable_Auto_Nego | PHY_Restart_Auto_Nego);
31523 + udelay(100);
31525 + /* wait for auto-negotiation process */
31526 + for (i = 10000; i > 0; i--) {
31527 + /* Check if auto-negotiation complete */
31528 + if (mdio_read(PHY_STAT_REG) & PHY_Auto_Neco_Comp) {
31529 + udelay(100);
31530 + option = RTL_R8(PHYstatus);
31531 + if (option & _1000bpsF) {
31532 + printf
31533 + ("1000Mbps Full-duplex operation.\n");
31534 + } else {
31535 + printf
31536 + ("%sMbps %s-duplex operation.\n",
31537 + (option & _100bps) ? "100" :
31538 + "10",
31539 + (option & FullDup) ? "Full" :
31540 + "Half");
31542 + break;
31543 + } else {
31544 + udelay(100);
31546 + } /* end for-loop to wait for auto-negotiation process */
31548 + } else {
31549 + udelay(100);
31550 + printf
31551 + ("%s: 1000Mbps Full-duplex operation, TBI Link %s!\n",
31552 + pci->name,
31553 + (RTL_R32(TBICSR) & TBILinkOK) ? "OK" : "Failed");
31557 + r8169_reset(nic);
31558 + /* point to NIC specific routines */
31559 + dev->disable = r8169_disable;
31560 + nic->poll = r8169_poll;
31561 + nic->transmit = r8169_transmit;
31562 + nic->irqno = pci->irq;
31563 + nic->irq = r8169_irq;
31564 + nic->ioaddr = ioaddr;
31565 + return 1;
31569 +static struct pci_id r8169_nics[] = {
31570 + PCI_ROM(0x10ec, 0x8169, "r8169", "RealTek RTL8169 Gigabit Ethernet"),
31573 +struct pci_driver r8169_driver = {
31574 + .type = NIC_DRIVER,
31575 + .name = "r8169/PCI",
31576 + .probe = r8169_probe,
31577 + .ids = r8169_nics,
31578 + .id_count = sizeof(r8169_nics) / sizeof(r8169_nics[0]),
31579 + .class = 0,
31581 Index: b/netboot/rtl8139.c
31582 ===================================================================
31583 --- a/netboot/rtl8139.c
31584 +++ b/netboot/rtl8139.c
31585 @@ -17,6 +17,8 @@
31586 /*********************************************************************/
31589 + 28 Dec 2002 ken_yap@users.sourceforge.net (Ken Yap)
31590 + Put in virt_to_bus calls to allow Etherboot relocation.
31592 06 Apr 2001 ken_yap@users.sourceforge.net (Ken Yap)
31593 Following email from Hyun-Joon Cha, added a disable routine, otherwise
31594 @@ -63,7 +65,6 @@
31595 #include "etherboot.h"
31596 #include "nic.h"
31597 #include "pci.h"
31598 -#include "cards.h"
31599 #include "timer.h"
31601 #define RTL_TIMEOUT (1*TICKS_PER_SEC)
31602 @@ -112,9 +113,19 @@
31603 * definitions we will probably never need to know about. */
31606 +enum RxEarlyStatusBits {
31607 + ERGood=0x08, ERBad=0x04, EROVW=0x02, EROK=0x01
31610 enum ChipCmdBits {
31611 CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
31613 +enum IntrMaskBits {
31614 + SERR=0x8000, TimeOut=0x4000, LenChg=0x2000,
31615 + FOVW=0x40, PUN_LinkChg=0x20, RXOVW=0x10,
31616 + TER=0x08, TOK=0x04, RER=0x02, ROK=0x01
31619 /* Interrupt register bits, using my own meaningful names. */
31620 enum IntrStatusBits {
31621 PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
31622 @@ -155,74 +166,68 @@
31623 AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
31626 -static int ioaddr;
31627 static unsigned int cur_rx,cur_tx;
31629 /* The RTL8139 can only transmit from a contiguous, aligned memory block. */
31630 static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
31632 -/* I know that this is a MEGA HACK, but the tagged boot image specification
31633 - * states that we can do whatever we want below 0x10000 - so we do! */
31634 -/* But we still give the user the choice of using an internal buffer
31635 - just in case - Ken */
31636 -#ifdef USE_LOWMEM_BUFFER
31637 -#define rx_ring ((unsigned char *)(0x10000 - (RX_BUF_LEN + 16)))
31638 -#else
31639 static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
31640 -#endif
31642 -struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
31643 - struct pci_device *pci);
31644 -static int read_eeprom(int location);
31645 +static int rtl8139_probe(struct dev *dev, struct pci_device *pci);
31646 +static int read_eeprom(struct nic *nic, int location, int addr_len);
31647 static void rtl_reset(struct nic *nic);
31648 static void rtl_transmit(struct nic *nic, const char *destaddr,
31649 unsigned int type, unsigned int len, const char *data);
31650 -static int rtl_poll(struct nic *nic);
31651 -static void rtl_disable(struct nic*);
31652 +static int rtl_poll(struct nic *nic, int retrieve);
31653 +static void rtl_disable(struct dev *);
31654 +static void rtl_irq(struct nic *nic, irq_action_t action);
31657 -struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
31658 - struct pci_device *pci)
31659 +static int rtl8139_probe(struct dev *dev, struct pci_device *pci)
31661 + struct nic *nic = (struct nic *)dev;
31662 int i;
31663 int speed10, fullduplex;
31664 + int addr_len;
31665 + unsigned short *ap = (unsigned short*)nic->node_addr;
31667 /* There are enough "RTL8139" strings on the console already, so
31668 * be brief and concentrate on the interesting pieces of info... */
31669 printf(" - ");
31671 /* Mask the bit that says "this is an io addr" */
31672 - ioaddr = probeaddrs[0] & ~3;
31673 + nic->ioaddr = pci->ioaddr & ~3;
31675 + /* Copy IRQ from PCI information */
31676 + nic->irqno = pci->irq;
31678 adjust_pci_device(pci);
31680 /* Bring the chip out of low-power mode. */
31681 - outb(0x00, ioaddr + Config1);
31683 - if (read_eeprom(0) != 0xffff) {
31684 - unsigned short *ap = (unsigned short*)nic->node_addr;
31685 - for (i = 0; i < 3; i++)
31686 - *ap++ = read_eeprom(i + 7);
31687 - } else {
31688 - unsigned char *ap = (unsigned char*)nic->node_addr;
31689 - for (i = 0; i < ETH_ALEN; i++)
31690 - *ap++ = inb(ioaddr + MAC0 + i);
31692 + outb(0x00, nic->ioaddr + Config1);
31694 - speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
31695 - fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
31696 - printf("ioaddr %#hX, addr %! %sMbps %s-duplex\n", ioaddr,
31697 - nic->node_addr, speed10 ? "10" : "100",
31698 - fullduplex ? "full" : "half");
31699 + addr_len = read_eeprom(nic,0,8) == 0x8129 ? 8 : 6;
31700 + for (i = 0; i < 3; i++)
31701 + *ap++ = read_eeprom(nic,i + 7,addr_len);
31703 + speed10 = inb(nic->ioaddr + MediaStatus) & MSRSpeed10;
31704 + fullduplex = inw(nic->ioaddr + MII_BMCR) & BMCRDuplex;
31705 + printf("ioaddr %#hX, irq %d, addr %! %sMbps %s-duplex\n", nic->ioaddr,
31706 + nic->irqno, nic->node_addr, speed10 ? "10" : "100",
31707 + fullduplex ? "full" : "half");
31709 rtl_reset(nic);
31711 - nic->reset = rtl_reset;
31712 - nic->poll = rtl_poll;
31713 + if (inb(nic->ioaddr + MediaStatus) & MSRLinkFail) {
31714 + printf("Cable not connected or other link failure\n");
31715 + return(0);
31718 + dev->disable = rtl_disable;
31719 + nic->poll = rtl_poll;
31720 nic->transmit = rtl_transmit;
31721 - nic->disable = rtl_disable;
31722 + nic->irq = rtl_irq;
31724 - return nic;
31725 + return 1;
31728 /* Serial EEPROM section. */
31729 @@ -244,22 +249,23 @@
31730 #define eeprom_delay() inl(ee_addr)
31732 /* The EEPROM commands include the alway-set leading bit. */
31733 -#define EE_WRITE_CMD (5 << 6)
31734 -#define EE_READ_CMD (6 << 6)
31735 -#define EE_ERASE_CMD (7 << 6)
31736 +#define EE_WRITE_CMD (5)
31737 +#define EE_READ_CMD (6)
31738 +#define EE_ERASE_CMD (7)
31740 -static int read_eeprom(int location)
31741 +static int read_eeprom(struct nic *nic, int location, int addr_len)
31743 int i;
31744 unsigned int retval = 0;
31745 - long ee_addr = ioaddr + Cfg9346;
31746 - int read_cmd = location | EE_READ_CMD;
31747 + long ee_addr = nic->ioaddr + Cfg9346;
31748 + int read_cmd = location | (EE_READ_CMD << addr_len);
31750 outb(EE_ENB & ~EE_CS, ee_addr);
31751 outb(EE_ENB, ee_addr);
31752 + eeprom_delay();
31754 /* Shift the read command bits out. */
31755 - for (i = 10; i >= 0; i--) {
31756 + for (i = 4 + addr_len; i >= 0; i--) {
31757 int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
31758 outb(EE_ENB | dataval, ee_addr);
31759 eeprom_delay();
31760 @@ -279,31 +285,51 @@
31762 /* Terminate the EEPROM access. */
31763 outb(~EE_CS, ee_addr);
31764 + eeprom_delay();
31765 return retval;
31768 +static const unsigned int rtl8139_rx_config =
31769 + (RX_BUF_LEN_IDX << 11) |
31770 + (RX_FIFO_THRESH << 13) |
31771 + (RX_DMA_BURST << 8);
31773 +static void set_rx_mode(struct nic *nic) {
31774 + unsigned int mc_filter[2];
31775 + int rx_mode;
31776 + /* !IFF_PROMISC */
31777 + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
31778 + mc_filter[1] = mc_filter[0] = 0xffffffff;
31780 + outl(rtl8139_rx_config | rx_mode, nic->ioaddr + RxConfig);
31782 + outl(mc_filter[0], nic->ioaddr + MAR0 + 0);
31783 + outl(mc_filter[1], nic->ioaddr + MAR0 + 4);
31786 static void rtl_reset(struct nic* nic)
31788 int i;
31790 - outb(CmdReset, ioaddr + ChipCmd);
31791 + outb(CmdReset, nic->ioaddr + ChipCmd);
31793 cur_rx = 0;
31794 cur_tx = 0;
31796 /* Give the chip 10ms to finish the reset. */
31797 load_timer2(10*TICKS_PER_MS);
31798 - while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
31799 + while ((inb(nic->ioaddr + ChipCmd) & CmdReset) != 0 &&
31800 + timer2_running())
31801 /* wait */;
31803 for (i = 0; i < ETH_ALEN; i++)
31804 - outb(nic->node_addr[i], ioaddr + MAC0 + i);
31805 + outb(nic->node_addr[i], nic->ioaddr + MAC0 + i);
31807 /* Must enable Tx/Rx before setting transfer thresholds! */
31808 - outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
31809 + outb(CmdRxEnb | CmdTxEnb, nic->ioaddr + ChipCmd);
31810 outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
31811 - ioaddr + RxConfig); /* accept no frames yet! */
31812 - outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
31813 + nic->ioaddr + RxConfig); /* accept no frames yet! */
31814 + outl((TX_DMA_BURST<<8)|0x03000000, nic->ioaddr + TxConfig);
31816 /* The Linux driver changes Config1 here to use a different LED pattern
31817 * for half duplex or full/autodetect duplex (for full/autodetect, the
31818 @@ -316,19 +342,26 @@
31819 #ifdef DEBUG_RX
31820 printf("rx ring address is %X\n",(unsigned long)rx_ring);
31821 #endif
31822 - outl((unsigned long)rx_ring, ioaddr + RxBuf);
31823 + outl((unsigned long)virt_to_bus(rx_ring), nic->ioaddr + RxBuf);
31827 - /* Start the chip's Tx and Rx process. */
31828 - outl(0, ioaddr + RxMissed);
31829 - /* set_rx_mode */
31830 - outb(AcceptBroadcast|AcceptMyPhys, ioaddr + RxConfig);
31831 /* If we add multicast support, the MAR0 register would have to be
31832 * initialized to 0xffffffffffffffff (two 32 bit accesses). Etherboot
31833 * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast. */
31834 - outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
31836 + outb(CmdRxEnb | CmdTxEnb, nic->ioaddr + ChipCmd);
31838 + outl(rtl8139_rx_config, nic->ioaddr + RxConfig);
31840 + /* Start the chip's Tx and Rx process. */
31841 + outl(0, nic->ioaddr + RxMissed);
31843 + /* set_rx_mode */
31844 + set_rx_mode(nic);
31846 /* Disable all known interrupts by setting the interrupt mask. */
31847 - outw(0, ioaddr + IntrMask);
31848 + outw(0, nic->ioaddr + IntrMask);
31851 static void rtl_transmit(struct nic *nic, const char *destaddr,
31852 @@ -337,10 +370,11 @@
31853 unsigned int status, to, nstype;
31854 unsigned long txstatus;
31856 + /* nstype assignment moved up here to avoid gcc 3.0.3 compiler bug */
31857 + nstype = htons(type);
31858 memcpy(tx_buffer, destaddr, ETH_ALEN);
31859 memcpy(tx_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
31860 - nstype = htons(type);
31861 - memcpy(tx_buffer + 2 * ETH_ALEN, (char*)&nstype, 2);
31862 + memcpy(tx_buffer + 2 * ETH_ALEN, &nstype, 2);
31863 memcpy(tx_buffer + ETH_HLEN, data, len);
31865 len += ETH_HLEN;
31866 @@ -354,22 +388,22 @@
31867 tx_buffer[len++] = '\0';
31870 - outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4);
31871 + outl((unsigned long)virt_to_bus(tx_buffer), nic->ioaddr + TxAddr0 + cur_tx*4);
31872 outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
31873 - ioaddr + TxStatus0 + cur_tx*4);
31874 + nic->ioaddr + TxStatus0 + cur_tx*4);
31876 to = currticks() + RTL_TIMEOUT;
31878 do {
31879 - status = inw(ioaddr + IntrStatus);
31880 + status = inw(nic->ioaddr + IntrStatus);
31881 /* Only acknlowledge interrupt sources we can properly handle
31882 * here - the RxOverflow/RxFIFOOver MUST be handled in the
31883 * rtl_poll() function. */
31884 - outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
31885 + outw(status & (TxOK | TxErr | PCIErr), nic->ioaddr + IntrStatus);
31886 if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
31887 } while (currticks() < to);
31889 - txstatus = inl(ioaddr+ TxStatus0 + cur_tx*4);
31890 + txstatus = inl(nic->ioaddr+ TxStatus0 + cur_tx*4);
31892 if (status & TxOK) {
31893 cur_tx = (cur_tx + 1) % NUM_TX_DESC;
31894 @@ -386,19 +420,22 @@
31898 -static int rtl_poll(struct nic *nic)
31899 +static int rtl_poll(struct nic *nic, int retrieve)
31901 unsigned int status;
31902 unsigned int ring_offs;
31903 unsigned int rx_size, rx_status;
31905 - if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
31906 + if (inb(nic->ioaddr + ChipCmd) & RxBufEmpty) {
31907 return 0;
31910 - status = inw(ioaddr + IntrStatus);
31911 + /* There is a packet ready */
31912 + if ( ! retrieve ) return 1;
31914 + status = inw(nic->ioaddr + IntrStatus);
31915 /* See below for the rest of the interrupt acknowledges. */
31916 - outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
31917 + outw(status & ~(RxFIFOOver | RxOverflow | RxOK), nic->ioaddr + IntrStatus);
31919 #ifdef DEBUG_RX
31920 printf("rtl_poll: int %hX ", status);
31921 @@ -438,21 +475,77 @@
31922 nic->packet[12], nic->packet[13], rx_status);
31923 #endif
31924 cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
31925 - outw(cur_rx - 16, ioaddr + RxBufPtr);
31926 + outw(cur_rx - 16, nic->ioaddr + RxBufPtr);
31927 /* See RTL8139 Programming Guide V0.1 for the official handling of
31928 * Rx overflow situations. The document itself contains basically no
31929 * usable information, except for a few exception handling rules. */
31930 - outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
31931 + outw(status & (RxFIFOOver | RxOverflow | RxOK), nic->ioaddr + IntrStatus);
31932 return 1;
31935 -static void rtl_disable(struct nic *nic)
31936 +static void rtl_irq(struct nic *nic, irq_action_t action)
31938 + unsigned int mask;
31939 + /* Bit of a guess as to which interrupts we should allow */
31940 + unsigned int interested = ROK | RER | RXOVW | FOVW | SERR;
31942 + switch ( action ) {
31943 + case DISABLE :
31944 + case ENABLE :
31945 + mask = inw(nic->ioaddr + IntrMask);
31946 + mask = mask & ~interested;
31947 + if ( action == ENABLE ) mask = mask | interested;
31948 + outw(mask, nic->ioaddr + IntrMask);
31949 + break;
31950 + case FORCE :
31951 + /* Apparently writing a 1 to this read-only bit of a
31952 + * read-only and otherwise unrelated register will
31953 + * force an interrupt. If you ever want to see how
31954 + * not to write a datasheet, read the one for the
31955 + * RTL8139...
31956 + */
31957 + outb(EROK, nic->ioaddr + RxEarlyStatus);
31958 + break;
31962 +static void rtl_disable(struct dev *dev)
31964 + struct nic *nic = (struct nic *)dev;
31965 + /* merge reset and disable */
31966 + rtl_reset(nic);
31968 /* reset the chip */
31969 - outb(CmdReset, ioaddr + ChipCmd);
31970 + outb(CmdReset, nic->ioaddr + ChipCmd);
31972 /* 10 ms timeout */
31973 load_timer2(10*TICKS_PER_MS);
31974 - while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
31975 + while ((inb(nic->ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
31976 /* wait */;
31979 +static struct pci_id rtl8139_nics[] = {
31980 +PCI_ROM(0x10ec, 0x8129, "rtl8129", "Realtek 8129"),
31981 +PCI_ROM(0x10ec, 0x8139, "rtl8139", "Realtek 8139"),
31982 +PCI_ROM(0x10ec, 0x8138, "rtl8139b", "Realtek 8139B"),
31983 +PCI_ROM(0x1186, 0x1300, "dfe538", "DFE530TX+/DFE538TX"),
31984 +PCI_ROM(0x1113, 0x1211, "smc1211-1", "SMC EZ10/100"),
31985 +PCI_ROM(0x1112, 0x1211, "smc1211", "SMC EZ10/100"),
31986 +PCI_ROM(0x1500, 0x1360, "delta8139", "Delta Electronics 8139"),
31987 +PCI_ROM(0x4033, 0x1360, "addtron8139", "Addtron Technology 8139"),
31988 +PCI_ROM(0x1186, 0x1340, "dfe690txd", "D-Link DFE690TXD"),
31989 +PCI_ROM(0x13d1, 0xab06, "fe2000vx", "AboCom FE2000VX"),
31990 +PCI_ROM(0x1259, 0xa117, "allied8139", "Allied Telesyn 8139"),
31991 +PCI_ROM(0x14ea, 0xab06, "fnw3603tx", "Planex FNW-3603-TX"),
31992 +PCI_ROM(0x14ea, 0xab07, "fnw3800tx", "Planex FNW-3800-TX"),
31993 +PCI_ROM(0xffff, 0x8139, "clone-rtl8139", "Cloned 8139"),
31996 +struct pci_driver rtl8139_driver = {
31997 + .type = NIC_DRIVER,
31998 + .name = "RTL8139",
31999 + .probe = rtl8139_probe,
32000 + .ids = rtl8139_nics,
32001 + .id_count = sizeof(rtl8139_nics)/sizeof(rtl8139_nics[0]),
32002 + .class = 0,
32004 Index: b/netboot/segoff.h
32005 ===================================================================
32006 --- /dev/null
32007 +++ b/netboot/segoff.h
32008 @@ -0,0 +1,43 @@
32010 + * Segment:offset types and macros
32012 + * Initially written by Michael Brown (mcb30).
32013 + */
32015 +#ifndef SEGOFF_H
32016 +#define SEGOFF_H
32018 +#include <stdint.h>
32019 +#include <io.h>
32021 +/* Segment:offset structure. Note that the order within the structure
32022 + * is offset:segment.
32023 + */
32024 +typedef struct {
32025 + uint16_t offset;
32026 + uint16_t segment;
32027 +} segoff_t;
32029 +/* For PXE stuff */
32030 +typedef segoff_t SEGOFF16_t;
32032 +/* Macros for converting from virtual to segment:offset addresses,
32033 + * when we don't actually care which of the many isomorphic results we
32034 + * get.
32035 + */
32036 +#ifdef DEBUG_SEGMENT
32037 +uint16_t SEGMENT ( const void * const ptr ) {
32038 + uint32_t phys = virt_to_phys ( ptr );
32039 + if ( phys > 0xfffff ) {
32040 + printf ( "FATAL ERROR: segment address out of range\n" );
32042 + return phys >> 4;
32044 +#else
32045 +#define SEGMENT(x) ( virt_to_phys ( x ) >> 4 )
32046 +#endif
32047 +#define OFFSET(x) ( virt_to_phys ( x ) & 0xf )
32048 +#define SEGOFF(x) { OFFSET(x), SEGMENT(x) }
32049 +#define VIRTUAL(x,y) ( phys_to_virt ( ( ( x ) << 4 ) + ( y ) ) )
32051 +#endif /* SEGOFF_H */
32052 Index: b/netboot/sis900.c
32053 ===================================================================
32054 --- a/netboot/sis900.c
32055 +++ b/netboot/sis900.c
32056 @@ -27,6 +27,11 @@
32057 /* Revision History */
32060 + 07 Dec 2003 timlegge - Enabled Multicast Support
32061 + 06 Dec 2003 timlegge - Fixed relocation issue in 5.2
32062 + 04 Jan 2002 Chien-Yu Chen, Doug Ambrisko, Marty Connor Patch to Etherboot 5.0.5
32063 + Added support for the SiS 630ET plus various bug fixes from linux kernel
32064 + source 2.4.17.
32065 01 March 2001 mdc 1.0
32066 Initial Release. Tested with PCI based sis900 card and ThinkNIC
32067 computer.
32068 @@ -35,13 +40,12 @@
32069 Testet with SIS730S chipset + ICS1893
32073 /* Includes */
32075 #include "etherboot.h"
32076 #include "nic.h"
32077 #include "pci.h"
32078 -#include "cards.h"
32079 +#include "timer.h"
32081 #include "sis900.h"
32083 @@ -51,6 +55,7 @@
32085 static unsigned short vendor, dev_id;
32086 static unsigned long ioaddr;
32087 +static u8 pci_revision;
32089 static unsigned int cur_phy;
32091 @@ -58,15 +63,10 @@
32093 static BufferDesc txd;
32094 static BufferDesc rxd[NUM_RX_DESC];
32096 -#ifdef USE_LOWMEM_BUFFER
32097 -#define txb ((char *)0x10000 - TX_BUF_SIZE)
32098 -#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE)
32099 -#else
32100 static unsigned char txb[TX_BUF_SIZE];
32101 static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
32102 -#endif
32104 +#if 0
32105 static struct mac_chip_info {
32106 const char *name;
32107 u16 vendor_id, device_id, flags;
32108 @@ -78,11 +78,13 @@
32109 PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
32110 {0,0,0,0,0} /* 0 terminated list. */
32112 +#endif
32114 static void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
32115 static void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
32116 static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
32117 static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
32118 +static void vt6103_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
32120 static struct mii_chip_info {
32121 const char * name;
32122 @@ -96,6 +98,7 @@
32123 {"AMD 79C901 HomePNA PHY", 0x0000, 0x35c8, amd79c901_read_mode},
32124 {"ICS 1893 Integrated PHYceiver" , 0x0015, 0xf441,ics1893_read_mode},
32125 {"RTL 8201 10/100Mbps Phyceiver" , 0x0000, 0x8201,rtl8201_read_mode},
32126 + {"VIA 6103 10/100Mbps Phyceiver", 0x0101, 0x8f20,vt6103_read_mode},
32127 {0,0,0,0}
32130 @@ -106,24 +109,32 @@
32131 u16 status;
32132 } mii;
32135 // PCI to ISA bridge for SIS640E access
32136 -static struct pci_device pci_isa_bridge_list[] = {
32137 +static struct pci_id pci_isa_bridge_list[] = {
32138 { 0x1039, 0x0008,
32139 - "SIS 85C503/5513 PCI to ISA bridge", 0, 0, 0, 0},
32140 - {0, 0, NULL, 0, 0, 0, 0}
32141 + "SIS 85C503/5513 PCI to ISA bridge"},
32144 +struct pci_driver sis_bridge_driver = {
32145 + .type = BRIDGE_DRIVER,
32146 + .name = "",
32147 + .probe = 0,
32148 + .ids = pci_isa_bridge_list,
32149 + .id_count = sizeof(pci_isa_bridge_list)/sizeof(pci_isa_bridge_list[0]),
32150 + .class = 0,
32153 /* Function Prototypes */
32155 -struct nic *sis900_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci);
32156 +static int sis900_probe(struct dev *dev, struct pci_device *pci);
32158 static u16 sis900_read_eeprom(int location);
32159 static void sis900_mdio_reset(long mdio_addr);
32160 static void sis900_mdio_idle(long mdio_addr);
32161 static u16 sis900_mdio_read(int phy_id, int location);
32162 +#if 0
32163 static void sis900_mdio_write(int phy_id, int location, int val);
32165 +#endif
32166 static void sis900_init(struct nic *nic);
32168 static void sis900_reset(struct nic *nic);
32169 @@ -136,9 +147,11 @@
32171 static void sis900_transmit(struct nic *nic, const char *d,
32172 unsigned int t, unsigned int s, const char *p);
32173 -static int sis900_poll(struct nic *nic);
32174 +static int sis900_poll(struct nic *nic, int retrieve);
32176 +static void sis900_disable(struct dev *dev);
32178 -static void sis900_disable(struct nic *nic);
32179 +static void sis900_irq(struct nic *nic, irq_action_t action);
32182 * sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
32183 @@ -149,7 +162,7 @@
32184 * MAC address is read from read_eeprom() into @net_dev->dev_addr.
32187 -static int sis900_get_mac_addr(struct pci_device * pci_dev , struct nic *nic)
32188 +static int sis900_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
32190 u16 signature;
32191 int i;
32192 @@ -168,6 +181,50 @@
32196 + * sis96x_get_mac_addr: - Get MAC address for SiS962 or SiS963 model
32197 + * @pci_dev: the sis900 pci device
32198 + * @net_dev: the net device to get address for
32200 + * SiS962 or SiS963 model, use EEPROM to store MAC address. And EEPROM
32201 + * is shared by
32202 + * LAN and 1394. When access EEPROM, send EEREQ signal to hardware first
32203 + * and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access
32204 + * by LAN, otherwise is not. After MAC address is read from EEPROM, send
32205 + * EEDONE signal to refuse EEPROM access by LAN.
32206 + * The EEPROM map of SiS962 or SiS963 is different to SiS900.
32207 + * The signature field in SiS962 or SiS963 spec is meaningless.
32208 + * MAC address is read into @net_dev->dev_addr.
32209 + */
32211 +static int sis96x_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
32213 +/* long ioaddr = net_dev->base_addr; */
32214 + long ee_addr = ioaddr + mear;
32215 + u32 waittime = 0;
32216 + int i;
32218 + printf("Alternate function\n");
32220 + outl(EEREQ, ee_addr);
32221 + while(waittime < 2000) {
32222 + if(inl(ee_addr) & EEGNT) {
32224 + /* get MAC address from EEPROM */
32225 + for (i = 0; i < 3; i++)
32226 + ((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
32228 + outl(EEDONE, ee_addr);
32229 + return 1;
32230 + } else {
32231 + udelay(1);
32232 + waittime ++;
32235 + outl(EEDONE, ee_addr);
32236 + return 0;
32239 +/**
32240 * sis630e_get_mac_addr: - Get MAC address for SiS630E model
32241 * @pci_dev: the sis900 pci device
32242 * @net_dev: the net device to get address for
32243 @@ -177,17 +234,21 @@
32244 * MAC address is read into @net_dev->dev_addr.
32247 -static int sis630e_get_mac_addr(struct pci_device * pci_dev, struct nic *nic)
32248 +static int sis630e_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
32250 u8 reg;
32251 int i;
32252 - struct pci_device *p;
32254 - // find PCI to ISA bridge
32255 - eth_pci_init(pci_isa_bridge_list);
32256 + struct pci_device p[1];
32258 - /* the firts entry in this list should contain bus/devfn */
32259 - p = pci_isa_bridge_list;
32260 + /* find PCI to ISA bridge */
32261 + memset(p, 0, sizeof(p));
32262 + do {
32263 + find_pci(BRIDGE_DRIVER, p);
32264 + } while(p->driver && p->driver != &sis_bridge_driver);
32266 + /* error on failure */
32267 + if (!p->driver)
32268 + return 0;
32270 pcibios_read_config_byte(p->bus,p->devfn, 0x48, &reg);
32271 pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg | 0x40);
32272 @@ -201,7 +262,43 @@
32274 return 1;
32278 +/**
32279 + * sis630e_get_mac_addr: - Get MAC address for SiS630E model
32280 + * @pci_dev: the sis900 pci device
32281 + * @net_dev: the net device to get address for
32283 + * SiS630E model, use APC CMOS RAM to store MAC address.
32284 + * APC CMOS RAM is accessed through ISA bridge.
32285 + * MAC address is read into @net_dev->dev_addr.
32286 + */
32288 +static int sis635_get_mac_addr(struct pci_device * pci_dev __unused, struct nic *nic)
32290 + u32 rfcrSave;
32291 + u32 i;
32294 + rfcrSave = inl(rfcr + ioaddr);
32296 + outl(rfcrSave | RELOAD, ioaddr + cr);
32297 + outl(0, ioaddr + cr);
32299 + /* disable packet filtering before setting filter */
32300 + outl(rfcrSave & ~RFEN, rfcr + ioaddr);
32302 + /* load MAC addr to filter data register */
32303 + for (i = 0 ; i < 3 ; i++) {
32304 + outl((i << RFADDR_shift), ioaddr + rfcr);
32305 + *( ((u16 *)nic->node_addr) + i) = inw(ioaddr + rfdr);
32308 + /* enable packet filitering */
32309 + outl(rfcrSave | RFEN, rfcr + ioaddr);
32311 + return 1;
32315 * Function: sis900_probe
32317 @@ -216,19 +313,21 @@
32318 * Returns: struct nic *: pointer to NIC data structure
32321 -struct nic *sis900_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
32322 +static int sis900_probe(struct dev *dev, struct pci_device *pci)
32324 + struct nic *nic = (struct nic *)dev;
32325 int i;
32326 int found=0;
32327 int phy_addr;
32328 - u16 signature;
32329 u8 revision;
32330 int ret;
32332 - if (io_addrs == 0 || *io_addrs == 0)
32333 - return NULL;
32334 + if (pci->ioaddr == 0)
32335 + return 0;
32337 - ioaddr = *io_addrs & ~3;
32338 + nic->irqno = 0;
32339 + nic->ioaddr = pci->ioaddr & ~3;
32340 + ioaddr = pci->ioaddr & ~3;
32341 vendor = pci->vendor;
32342 dev_id = pci->dev_id;
32344 @@ -240,19 +339,29 @@
32345 /* get MAC address */
32346 ret = 0;
32347 pcibios_read_config_byte(pci->bus,pci->devfn, PCI_REVISION, &revision);
32348 - if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV)
32349 - ret = sis630e_get_mac_addr(pci, nic);
32350 - else if (revision == SIS630S_900_REV)
32352 + /* save for use later in sis900_reset() */
32353 + pci_revision = revision;
32355 + if (revision == SIS630E_900_REV)
32356 ret = sis630e_get_mac_addr(pci, nic);
32357 + else if ((revision > 0x81) && (revision <= 0x90))
32358 + ret = sis635_get_mac_addr(pci, nic);
32359 + else if (revision == SIS96x_900_REV)
32360 + ret = sis96x_get_mac_addr(pci, nic);
32361 else
32362 ret = sis900_get_mac_addr(pci, nic);
32364 if (ret == 0)
32366 printf ("sis900_probe: Error MAC address not found\n");
32367 - return NULL;
32368 + return 0;
32371 + /* 630ET : set the mii access mode as software-mode */
32372 + if (revision == SIS630ET_900_REV)
32373 + outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
32375 printf("\nsis900_probe: MAC addr %! at ioaddr %#hX\n",
32376 nic->node_addr, ioaddr);
32377 printf("sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
32378 @@ -264,7 +373,7 @@
32379 for (phy_addr = 0; phy_addr < 32; phy_addr++) {
32380 u16 mii_status;
32381 u16 phy_id0, phy_id1;
32384 mii_status = sis900_mdio_read(phy_addr, MII_STATUS);
32385 if (mii_status == 0xffff || mii_status == 0x0000)
32386 /* the mii is not accessable, try next one */
32387 @@ -272,7 +381,7 @@
32389 phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
32390 phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
32393 /* search our mii table for the current mii */
32394 for (i = 0; mii_chip_table[i].phy_id1; i++) {
32396 @@ -294,7 +403,7 @@
32398 if (found == 0) {
32399 printf("sis900_probe: No MII transceivers found!\n");
32400 - return NULL;
32401 + return 0;
32404 /* Arbitrarily select the last PHY found as current PHY */
32405 @@ -304,15 +413,14 @@
32406 /* initialize device */
32407 sis900_init(nic);
32409 - nic->reset = sis900_init;
32410 + dev->disable = sis900_disable;
32411 nic->poll = sis900_poll;
32412 nic->transmit = sis900_transmit;
32413 - nic->disable = sis900_disable;
32414 + nic->irq = sis900_irq;
32416 - return nic;
32417 + return 1;
32422 * EEPROM Routines: These functions read and write to EEPROM for
32423 * retrieving the MAC address and other configuration information about
32424 @@ -322,7 +430,6 @@
32425 /* Delay between EEPROM clock transitions. */
32426 #define eeprom_delay() inl(ee_addr)
32429 /* Function: sis900_read_eeprom
32431 * Description: reads and returns a given location from EEPROM
32432 @@ -378,7 +485,6 @@
32434 #define sis900_mdio_delay() inl(mdio_addr)
32438 Read and write the MII management registers using software-generated
32439 serial MDIO protocol. Note that the command bits and data bits are
32440 @@ -432,9 +538,11 @@
32441 outl(MDC, mdio_addr);
32442 sis900_mdio_delay();
32444 + outl(0x00, mdio_addr);
32445 return retval;
32448 +#if 0
32449 static void sis900_mdio_write(int phy_id, int location, int value)
32451 long mdio_addr = ioaddr + mear;
32452 @@ -471,10 +579,11 @@
32453 outb(MDC, mdio_addr);
32454 sis900_mdio_delay();
32456 + outl(0x00, mdio_addr);
32457 return;
32459 +#endif
32462 /* Function: sis900_init
32464 * Description: resets the ethernet controller chip and various
32465 @@ -500,10 +609,9 @@
32467 sis900_check_mode(nic);
32469 - outl(RxENA, ioaddr + cr);
32470 + outl(RxENA| inl(ioaddr + cr), ioaddr + cr);
32475 * Function: sis900_reset
32477 @@ -515,7 +623,7 @@
32480 static void
32481 -sis900_reset(struct nic *nic)
32482 +sis900_reset(struct nic *nic __unused)
32484 int i = 0;
32485 u32 status = TxRCMP | RxRCMP;
32486 @@ -524,16 +632,19 @@
32487 outl(0, ioaddr + imr);
32488 outl(0, ioaddr + rfcr);
32490 - outl(RxRESET | TxRESET | RESET, ioaddr + cr);
32492 + outl(RxRESET | TxRESET | RESET | inl(ioaddr + cr), ioaddr + cr);
32494 /* Check that the chip has finished the reset. */
32495 while (status && (i++ < 1000)) {
32496 status ^= (inl(isr + ioaddr) & status);
32498 - outl(PESEL, ioaddr + cfg);
32500 + if( (pci_revision == SIS635A_900_REV) || (pci_revision == SIS900B_900_REV) )
32501 + outl(PESEL | RND_CNT, ioaddr + cfg);
32502 + else
32503 + outl(PESEL, ioaddr + cfg);
32507 /* Function: sis_init_rxfilter
32509 * Description: sets receive filter address to our MAC address
32510 @@ -552,7 +663,7 @@
32511 rfcrSave = inl(rfcr + ioaddr);
32513 /* disable packet filtering before setting filter */
32514 - outl(rfcrSave & ~RFEN, rfcr);
32515 + outl(rfcrSave & ~RFEN, rfcr + ioaddr);
32517 /* load MAC addr to filter data register */
32518 for (i = 0 ; i < 3 ; i++) {
32519 @@ -571,7 +682,6 @@
32520 outl(rfcrSave | RFEN, rfcr + ioaddr);
32525 * Function: sis_init_txd
32527 @@ -583,20 +693,19 @@
32530 static void
32531 -sis900_init_txd(struct nic *nic)
32532 +sis900_init_txd(struct nic *nic __unused)
32534 txd.link = (u32) 0;
32535 txd.cmdsts = (u32) 0;
32536 - txd.bufptr = (u32) &txb[0];
32537 + txd.bufptr = virt_to_bus(&txb[0]);
32539 /* load Transmit Descriptor Register */
32540 - outl((u32) &txd, ioaddr + txdp);
32541 + outl(virt_to_bus(&txd), ioaddr + txdp);
32542 if (sis900_debug > 0)
32543 printf("sis900_init_txd: TX descriptor register loaded with: %X\n",
32544 inl(ioaddr + txdp));
32548 /* Function: sis_init_rxd
32550 * Description: initializes the Rx descriptor ring
32551 @@ -607,7 +716,7 @@
32554 static void
32555 -sis900_init_rxd(struct nic *nic)
32556 +sis900_init_rxd(struct nic *nic __unused)
32558 int i;
32560 @@ -615,16 +724,16 @@
32562 /* init RX descriptor */
32563 for (i = 0; i < NUM_RX_DESC; i++) {
32564 - rxd[i].link = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0];
32565 + rxd[i].link = virt_to_bus((i+1 < NUM_RX_DESC) ? &rxd[i+1] : &rxd[0]);
32566 rxd[i].cmdsts = (u32) RX_BUF_SIZE;
32567 - rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE];
32568 + rxd[i].bufptr = virt_to_bus(&rxb[i*RX_BUF_SIZE]);
32569 if (sis900_debug > 0)
32570 printf("sis900_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n",
32571 i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
32574 /* load Receive Descriptor Register */
32575 - outl((u32) &rxd[0], ioaddr + rxdp);
32576 + outl(virt_to_bus(&rxd[0]), ioaddr + rxdp);
32578 if (sis900_debug > 0)
32579 printf("sis900_init_rxd: RX descriptor register loaded with: %X\n",
32580 @@ -632,7 +741,6 @@
32585 /* Function: sis_init_rxd
32587 * Description:
32588 @@ -644,25 +752,36 @@
32589 * Returns: void.
32592 -static void sis900_set_rx_mode(struct nic *nic)
32593 +static void sis900_set_rx_mode(struct nic *nic __unused)
32595 - int i;
32596 + int i, table_entries;
32597 + u32 rx_mode;
32598 + u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */
32600 + if((pci_revision == SIS635A_900_REV) || (pci_revision == SIS900B_900_REV))
32601 + table_entries = 16;
32602 + else
32603 + table_entries = 8;
32605 - /* Configure Multicast Hash Table in Receive Filter
32606 - to reject all MCAST packets */
32607 - for (i = 0; i < 8; i++) {
32608 + /* accept all multicast packet */
32609 + rx_mode = RFAAB | RFAAM;
32610 + for (i = 0; i < table_entries; i++)
32611 + mc_filter[i] = 0xffff;
32613 + /* update Multicast Hash Table in Receive Filter */
32614 + for (i = 0; i < table_entries; i++) {
32615 /* why plus 0x04? That makes the correct value for hash table. */
32616 outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
32617 - outl((u32)(0x0), ioaddr + rfdr);
32618 + outl(mc_filter[i], ioaddr + rfdr);
32620 - /* Accept Broadcast packets, destination addresses that match
32622 + /* Accept Broadcast and multicast packets, destination addresses that match
32623 our MAC address */
32624 - outl(RFEN | RFAAB, ioaddr + rfcr);
32625 + outl(RFEN | rx_mode, ioaddr + rfcr);
32627 return;
32631 /* Function: sis900_check_mode
32633 * Description: checks the state of transmit and receive
32634 @@ -674,15 +793,21 @@
32637 static void
32638 -sis900_check_mode (struct nic *nic)
32639 +sis900_check_mode(struct nic *nic)
32641 int speed, duplex;
32642 u32 tx_flags = 0, rx_flags = 0;
32644 mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex);
32646 - tx_flags = TxATP | (TX_DMA_BURST << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
32647 - rx_flags = RX_DMA_BURST << RxMXDMA_shift;
32648 + if( inl(ioaddr + cfg) & EDB_MASTER_EN ) {
32649 + tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
32650 + rx_flags = DMA_BURST_64 << RxMXDMA_shift;
32652 + else {
32653 + tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
32654 + rx_flags = DMA_BURST_512 << RxMXDMA_shift;
32657 if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) {
32658 rx_flags |= (RxDRNT_10 << RxDRNT_shift);
32659 @@ -702,7 +827,6 @@
32660 outl (rx_flags, ioaddr + rxcfg);
32664 /* Function: sis900_read_mode
32666 * Description: retrieves and displays speed and duplex
32667 @@ -714,24 +838,33 @@
32670 static void
32671 -sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
32672 +sis900_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
32674 int i = 0;
32675 u32 status;
32676 + u16 phy_id0, phy_id1;
32678 /* STSOUT register is Latched on Transition, read operation updates it */
32679 while (i++ < 2)
32680 status = sis900_mdio_read(phy_addr, MII_STSOUT);
32682 - if (status & MII_STSOUT_SPD)
32683 - *speed = HW_SPEED_100_MBPS;
32684 - else
32685 - *speed = HW_SPEED_10_MBPS;
32687 - if (status & MII_STSOUT_DPLX)
32688 - *duplex = FDX_CAPABLE_FULL_SELECTED;
32689 - else
32690 - *duplex = FDX_CAPABLE_HALF_SELECTED;
32691 + *speed = HW_SPEED_10_MBPS;
32692 + *duplex = FDX_CAPABLE_HALF_SELECTED;
32694 + if (status & (MII_NWAY_TX | MII_NWAY_TX_FDX))
32695 + *speed = HW_SPEED_100_MBPS;
32696 + if (status & ( MII_NWAY_TX_FDX | MII_NWAY_T_FDX))
32697 + *duplex = FDX_CAPABLE_FULL_SELECTED;
32699 + /* Workaround for Realtek RTL8201 PHY issue */
32700 + phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
32701 + phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
32702 + if((phy_id0 == 0x0000) && ((phy_id1 & 0xFFF0) == 0x8200)){
32703 + if(sis900_mdio_read(phy_addr, MII_CONTROL) & MII_CNTL_FDX)
32704 + *duplex = FDX_CAPABLE_FULL_SELECTED;
32705 + if(sis900_mdio_read(phy_addr, 0x0019) & 0x01)
32706 + *speed = HW_SPEED_100_MBPS;
32709 if (status & MII_STSOUT_LINK_FAIL)
32710 printf("sis900_read_mode: Media Link Off\n");
32711 @@ -743,7 +876,6 @@
32712 "full" : "half");
32716 /* Function: amd79c901_read_mode
32718 * Description: retrieves and displays speed and duplex
32719 @@ -755,7 +887,7 @@
32722 static void
32723 -amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
32724 +amd79c901_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
32726 int i;
32727 u16 status;
32728 @@ -796,7 +928,6 @@
32734 * ics1893_read_mode: - read media mode for ICS1893 PHY
32735 * @net_dev: the net device to read mode for
32736 @@ -808,7 +939,7 @@
32737 * to determine the speed and duplex mode for sis900
32740 -static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
32741 +static void ics1893_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
32743 int i = 0;
32744 u32 status;
32745 @@ -848,7 +979,7 @@
32746 * to determine the speed and duplex mode for sis900
32749 -static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
32750 +static void rtl8201_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
32752 u32 status;
32754 @@ -878,7 +1009,51 @@
32755 *duplex == FDX_CAPABLE_FULL_SELECTED ?
32756 "full" : "half");
32757 else
32758 - printf("rtl9201_read_config_mode: Media Link Off\n");
32759 + printf("rtl8201_read_config_mode: Media Link Off\n");
32762 +/**
32763 + * vt6103_read_mode: - read media mode for vt6103 phy
32764 + * @nic: the net device to read mode for
32765 + * @phy_addr: mii phy address
32766 + * @speed: the transmit speed to be determined
32767 + * @duplex: the duplex mode to be determined
32769 + * read MII_STATUS register from rtl8201 phy
32770 + * to determine the speed and duplex mode for sis900
32771 + */
32773 +static void vt6103_read_mode(struct nic *nic __unused, int phy_addr, int *speed, int *duplex)
32775 + u32 status;
32777 + status = sis900_mdio_read(phy_addr, MII_STATUS);
32779 + if (status & MII_STAT_CAN_TX_FDX) {
32780 + *speed = HW_SPEED_100_MBPS;
32781 + *duplex = FDX_CAPABLE_FULL_SELECTED;
32783 + else if (status & MII_STAT_CAN_TX) {
32784 + *speed = HW_SPEED_100_MBPS;
32785 + *duplex = FDX_CAPABLE_HALF_SELECTED;
32787 + else if (status & MII_STAT_CAN_T_FDX) {
32788 + *speed = HW_SPEED_10_MBPS;
32789 + *duplex = FDX_CAPABLE_FULL_SELECTED;
32791 + else if (status & MII_STAT_CAN_T) {
32792 + *speed = HW_SPEED_10_MBPS;
32793 + *duplex = FDX_CAPABLE_HALF_SELECTED;
32796 + if (status & MII_STAT_LINK)
32797 + printf("vt6103_read_mode: Media Link On %s %s-duplex \n",
32798 + *speed == HW_SPEED_100_MBPS ?
32799 + "100mbps" : "10mbps",
32800 + *duplex == FDX_CAPABLE_FULL_SELECTED ?
32801 + "full" : "half");
32802 + else
32803 + printf("vt6103_read_config_mode: Media Link Off\n");
32806 /* Function: sis900_transmit
32807 @@ -900,14 +1075,14 @@
32808 unsigned int s, /* size */
32809 const char *p) /* Packet */
32811 - u32 status, to, nstype;
32812 + u32 to, nstype;
32813 volatile u32 tx_status;
32815 /* Stop the transmitter */
32816 - outl(TxDIS, ioaddr + cr);
32817 + outl(TxDIS | inl(ioaddr + cr), ioaddr + cr);
32819 /* load Transmit Descriptor Register */
32820 - outl((u32) &txd, ioaddr + txdp);
32821 + outl(virt_to_bus(&txd), ioaddr + txdp);
32822 if (sis900_debug > 1)
32823 printf("sis900_transmit: TX descriptor register loaded with: %X\n",
32824 inl(ioaddr + txdp));
32825 @@ -929,18 +1104,18 @@
32826 txb[s++] = '\0';
32828 /* set the transmit buffer descriptor and enable Transmit State Machine */
32829 - txd.bufptr = (u32) &txb[0];
32830 + txd.bufptr = virt_to_bus(&txb[0]);
32831 txd.cmdsts = (u32) OWN | s;
32833 /* restart the transmitter */
32834 - outl(TxENA, ioaddr + cr);
32835 + outl(TxENA | inl(ioaddr + cr), ioaddr + cr);
32837 if (sis900_debug > 1)
32838 printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);
32840 to = currticks() + TX_TIMEOUT;
32842 - while (((tx_status=txd.cmdsts) & OWN) && (currticks() < to))
32843 + while (((tx_status=txd.cmdsts & OWN) && (currticks() < to))
32844 /* wait */ ;
32846 if (currticks() >= to) {
32847 @@ -955,7 +1130,6 @@
32848 outl(0, ioaddr + imr);
32852 /* Function: sis900_poll
32854 * Description: checks for a received packet and returns it if found.
32855 @@ -971,7 +1145,7 @@
32858 static int
32859 -sis900_poll(struct nic *nic)
32860 +sis900_poll(struct nic *nic, int retrieve)
32862 u32 rx_status = rxd[cur_rx].cmdsts;
32863 int retstat = 0;
32864 @@ -986,6 +1160,8 @@
32865 printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
32866 cur_rx, rx_status);
32868 + if ( ! retrieve ) return 1;
32870 nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
32872 if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
32873 @@ -1001,18 +1177,18 @@
32875 /* return the descriptor and buffer to receive ring */
32876 rxd[cur_rx].cmdsts = RX_BUF_SIZE;
32877 - rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE];
32878 + rxd[cur_rx].bufptr = virt_to_bus(&rxb[cur_rx*RX_BUF_SIZE]);
32880 if (++cur_rx == NUM_RX_DESC)
32881 cur_rx = 0;
32883 /* re-enable the potentially idle receive state machine */
32884 - outl(RxENA , ioaddr + cr);
32885 + outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
32887 return retstat;
32892 /* Function: sis900_disable
32894 * Description: Turns off interrupts and stops Tx and Rx engines
32895 @@ -1023,12 +1199,53 @@
32898 static void
32899 -sis900_disable(struct nic *nic)
32900 +sis900_disable(struct dev *dev)
32902 + struct nic *nic = (struct nic *)dev;
32903 + /* merge reset and disable */
32904 + sis900_init(nic);
32906 /* Disable interrupts by clearing the interrupt mask. */
32907 outl(0, ioaddr + imr);
32908 outl(0, ioaddr + ier);
32910 /* Stop the chip's Tx and Rx Status Machine */
32911 - outl(RxDIS | TxDIS, ioaddr + cr);
32912 + outl(RxDIS | TxDIS | inl(ioaddr + cr), ioaddr + cr);
32915 +/* Function: sis900_irq
32917 + * Description: Enable, Disable, or Force, interrupts
32918 + *
32919 + * Arguments: struct nic *nic: NIC data structure
32920 + * irq_action_t action: Requested action
32922 + * Returns: void.
32923 + */
32925 +static void
32926 +sis900_irq(struct nic *nic __unused, irq_action_t action __unused)
32928 + switch ( action ) {
32929 + case DISABLE :
32930 + break;
32931 + case ENABLE :
32932 + break;
32933 + case FORCE :
32934 + break;
32938 +static struct pci_id sis900_nics[] = {
32939 +PCI_ROM(0x1039, 0x0900, "sis900", "SIS900"),
32940 +PCI_ROM(0x1039, 0x7016, "sis7016", "SIS7016"),
32943 +struct pci_driver sis900_driver = {
32944 + .type = NIC_DRIVER,
32945 + .name = "SIS900",
32946 + .probe = sis900_probe,
32947 + .ids = sis900_nics,
32948 + .id_count = sizeof(sis900_nics)/sizeof(sis900_nics[0]),
32949 + .class = 0,
32951 Index: b/netboot/sis900.h
32952 ===================================================================
32953 --- a/netboot/sis900.h
32954 +++ b/netboot/sis900.h
32955 @@ -39,14 +39,16 @@
32957 /* Symbolic names for bits in various registers */
32958 enum sis900_command_register_bits {
32959 - RESET = 0x00000100,
32960 - SWI = 0x00000080,
32961 - RxRESET = 0x00000020,
32962 - TxRESET = 0x00000010,
32963 - RxDIS = 0x00000008,
32964 - RxENA = 0x00000004,
32965 - TxDIS = 0x00000002,
32966 - TxENA = 0x00000001
32967 + RELOAD = 0x00000400,
32968 + ACCESSMODE = 0x00000200,
32969 + RESET = 0x00000100,
32970 + SWI = 0x00000080,
32971 + RxRESET = 0x00000020,
32972 + TxRESET = 0x00000010,
32973 + RxDIS = 0x00000008,
32974 + RxENA = 0x00000004,
32975 + TxDIS = 0x00000002,
32976 + TxENA = 0x00000001
32979 enum sis900_configuration_register_bits {
32980 @@ -57,7 +59,10 @@
32981 EXD = 0x00000010,
32982 PESEL = 0x00000008,
32983 LPM = 0x00000004,
32984 - BEM = 0x00000001
32985 + BEM = 0x00000001,
32986 + RND_CNT = 0x00000400,
32987 + FAIR_BACKOFF = 0x00000200,
32988 + EDB_MASTER_EN = 0x00002000
32991 enum sis900_eeprom_access_reigster_bits {
32992 @@ -108,6 +113,10 @@
32993 #define TX_DMA_BURST 0
32994 #define RX_DMA_BURST 0
32996 +enum sis900_tx_rx_dma{
32997 + DMA_BURST_512 = 0, DMA_BURST_64 = 5
33000 /* transmit FIFO threshholds */
33001 #define TX_FILL_THRESH 16 /* 1/4 FIFO size */
33002 #define TxFILLT_shift 8
33003 @@ -172,6 +181,11 @@
33004 EEeraseAll = 0x0120,
33005 EEwriteAll = 0x0110,
33006 EEaddrMask = 0x013F,
33007 + EEcmdShift = 16
33009 +/* For SiS962 or SiS963, request the eeprom software access */
33010 +enum sis96x_eeprom_command {
33011 + EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100
33014 /* Manamgement Data I/O (mdio) frame */
33015 @@ -236,7 +250,8 @@
33016 MII_CONFIG1 = 0x0010,
33017 MII_CONFIG2 = 0x0011,
33018 MII_STSOUT = 0x0012,
33019 - MII_MASK = 0x0013
33020 + MII_MASK = 0x0013,
33021 + MII_RESV = 0x0014
33024 /* mii registers specific to AMD 79C901 */
33025 @@ -320,7 +335,9 @@
33027 enum sis900_revision_id {
33028 SIS630A_900_REV = 0x80, SIS630E_900_REV = 0x81,
33029 - SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83
33030 + SIS630S_900_REV = 0x82, SIS630EA1_900_REV = 0x83,
33031 + SIS630ET_900_REV = 0x84, SIS635A_900_REV = 0x90,
33032 + SIS96x_900_REV = 0X91, SIS900B_900_REV = 0x03
33035 enum sis630_revision_id {
33036 Index: b/netboot/sis900.txt
33037 ===================================================================
33038 --- a/netboot/sis900.txt
33039 +++ /dev/null
33040 @@ -1,91 +0,0 @@
33041 -How I added the SIS900 card to Etherboot
33043 -Author: Marty Connor (mdc@thinguin.org)
33045 -Date: 25 Febrary 2001
33047 -Description:
33049 -This file is intended to help people who want to write an Etherboot
33050 -driver or port another driver to Etherboot. It is a starting point.
33051 -Perhaps someday I may write a more detailed description of writing an
33052 -Etherboot driver. This text should help get people started, and
33053 -studying sis900.[ch] should help show the basic structure and
33054 -techniques involved in writing and Etherboot driver.
33056 -***********************************************************************
33058 -0. Back up all the files I need to modify:
33060 -cd etherboot-4.7.20/src
33061 -cp Makefile Makefile.orig
33062 -cp config.c config.c.orig
33063 -cp pci.h pci.h.orig
33064 -cp NIC NIC.orig
33065 -cp cards.h cards.h.orig
33067 -1. Edit src/Makefile to add SIS900FLAGS to defines
33069 -SIS900FLAGS= -DINCLUDE_SIS900
33071 -2. edit src/pci.h to add PCI signatures for card
33073 -#define PCI_VENDOR_ID_SIS 0x1039
33074 -#define PCI_DEVICE_ID_SIS900 0x0900
33075 -#define PCI_DEVICE_ID_SIS7016 0x7016
33077 -3. Edit src/config.c to add the card to the card probe list
33079 -#if defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) ||
33080 - defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) ||
33081 - defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) ||
33082 - defined(INCLUDE_3C90X) || defined(INCLUDE_3C595) ||
33083 - defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) ||
33084 - defined(INCLUDE_SIS900) || defined(INCLUDE_W89C840)
33086 -... and ...
33088 -#ifdef INCLUDE_SIS900
33089 - { PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
33090 - "SIS900", 0, 0, 0, 0},
33091 - { PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
33092 - "SIS7016", 0, 0, 0, 0},
33093 -#endif
33095 -... and ...
33097 -#ifdef INCLUDE_SIS900
33098 - { "SIS900", sis900_probe, pci_ioaddrs },
33099 -#endif
33101 -4. Edit NIC to add sis900 and sis7016 to NIC list
33103 -# SIS 900 and SIS 7016
33104 -sis900 sis900 0x1039,0x0900
33105 -sis7016 sis900 0x1039,0x7016
33107 -5. Edit cards.h to add sis900 probe routine declaration
33109 -#ifdef INCLUDE_SIS900
33110 -extern struct nic *sis900_probe(struct nic *, unsigned short *
33111 - PCI_ARG(struct pci_device *));
33112 -#endif
33114 -***********************************************************************
33116 -At this point, you can begin creating your driver source file. See
33117 -the "Writing and Etherboot Driver" section of the Etherboot
33118 -documentation for some hints. See the skel.c file for a starting
33119 -point. If there is a Linux driver for the card, you may be able to
33120 -use that. Copy and learn from existing Etherboot drivers (this is GPL
33121 -/ Open Source software!).
33123 -Join the etherboot-developers and etherboot-users mailing lists
33124 -(information is on etherboot.sourceforge.net) for information and
33125 -assistance. We invite more developers to help improve Etherboot.
33127 -Visit the http://etherboot.sourceforge.net, http://thinguin.org,
33128 -http://rom-o-matic.net, and http://ltsp.org sites for information and
33129 -assistance.
33131 -Enjoy.
33132 Index: b/netboot/smc9000.c
33133 ===================================================================
33134 --- a/netboot/smc9000.c
33135 +++ /dev/null
33136 @@ -1,522 +0,0 @@
33137 - /*------------------------------------------------------------------------
33138 - * smc9000.c
33139 - * This is a Etherboot driver for SMC's 9000 series of Ethernet cards.
33141 - * Copyright (C) 1998 Daniel Engström <daniel.engstrom@riksnett.no>
33142 - * Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman
33143 - * Copyright (C) 1996 by Erik Stahlman <eric@vt.edu>
33145 - * This software may be used and distributed according to the terms
33146 - * of the GNU Public License, incorporated herein by reference.
33148 - * "Features" of the SMC chip:
33149 - * 4608 byte packet memory. ( for the 91C92/4. Others have more )
33150 - * EEPROM for configuration
33151 - * AUI/TP selection
33153 - * Authors
33154 - * Erik Stahlman <erik@vt.edu>
33155 - * Daniel Engström <daniel.engstrom@riksnett.no>
33157 - * History
33158 - * 98-09-25 Daniel Engström Etherboot driver crated from Eric's
33159 - * Linux driver.
33161 - *---------------------------------------------------------------------------*/
33162 -#define LINUX_OUT_MACROS 1
33163 -#define SMC9000_VERBOSE 1
33164 -#define SMC9000_DEBUG 0
33166 -#include "etherboot.h"
33167 -#include "nic.h"
33168 -#include "cards.h"
33169 -#include "smc9000.h"
33171 -# define _outb outb
33172 -# define _outw outw
33174 -static const char smc9000_version[] = "Version 0.99 98-09-30";
33175 -static unsigned int smc9000_base=0;
33176 -static const char *interfaces[ 2 ] = { "TP", "AUI" };
33177 -static const char *chip_ids[ 15 ] = {
33178 - NULL, NULL, NULL,
33179 - /* 3 */ "SMC91C90/91C92",
33180 - /* 4 */ "SMC91C94",
33181 - /* 5 */ "SMC91C95",
33182 - NULL,
33183 - /* 7 */ "SMC91C100",
33184 - /* 8 */ "SMC91C100FD",
33185 - NULL, NULL, NULL,
33186 - NULL, NULL, NULL
33188 -static const char smc91c96_id[] = "SMC91C96";
33191 - * Function: smc_reset( int ioaddr )
33192 - * Purpose:
33193 - * This sets the SMC91xx chip to its normal state, hopefully from whatever
33194 - * mess that any other DOS driver has put it in.
33196 - * Maybe I should reset more registers to defaults in here? SOFTRESET should
33197 - * do that for me.
33199 - * Method:
33200 - * 1. send a SOFT RESET
33201 - * 2. wait for it to finish
33202 - * 3. reset the memory management unit
33203 - * 4. clear all interrupts
33206 -static void smc_reset(int ioaddr)
33208 - /* This resets the registers mostly to defaults, but doesn't
33209 - * affect EEPROM. That seems unnecessary */
33210 - SMC_SELECT_BANK(ioaddr, 0);
33211 - _outw( RCR_SOFTRESET, ioaddr + RCR );
33213 - /* this should pause enough for the chip to be happy */
33214 - SMC_DELAY(ioaddr);
33216 - /* Set the transmit and receive configuration registers to
33217 - * default values */
33218 - _outw(RCR_CLEAR, ioaddr + RCR);
33219 - _outw(TCR_CLEAR, ioaddr + TCR);
33221 - /* Reset the MMU */
33222 - SMC_SELECT_BANK(ioaddr, 2);
33223 - _outw( MC_RESET, ioaddr + MMU_CMD );
33225 - /* Note: It doesn't seem that waiting for the MMU busy is needed here,
33226 - * but this is a place where future chipsets _COULD_ break. Be wary
33227 - * of issuing another MMU command right after this */
33228 - _outb(0, ioaddr + INT_MASK);
33232 -/*----------------------------------------------------------------------
33233 - * Function: smc_probe( int ioaddr )
33235 - * Purpose:
33236 - * Tests to see if a given ioaddr points to an SMC9xxx chip.
33237 - * Returns a 0 on success
33239 - * Algorithm:
33240 - * (1) see if the high byte of BANK_SELECT is 0x33
33241 - * (2) compare the ioaddr with the base register's address
33242 - * (3) see if I recognize the chip ID in the appropriate register
33244 - * ---------------------------------------------------------------------
33245 - */
33246 -static int smc_probe( int ioaddr )
33248 - word bank;
33249 - word revision_register;
33250 - word base_address_register;
33252 - /* First, see if the high byte is 0x33 */
33253 - bank = inw(ioaddr + BANK_SELECT);
33254 - if ((bank & 0xFF00) != 0x3300) {
33255 - return -1;
33257 - /* The above MIGHT indicate a device, but I need to write to further
33258 - * test this. */
33259 - _outw(0x0, ioaddr + BANK_SELECT);
33260 - bank = inw(ioaddr + BANK_SELECT);
33261 - if ((bank & 0xFF00) != 0x3300) {
33262 - return -1;
33265 - /* well, we've already written once, so hopefully another time won't
33266 - * hurt. This time, I need to switch the bank register to bank 1,
33267 - * so I can access the base address register */
33268 - SMC_SELECT_BANK(ioaddr, 1);
33269 - base_address_register = inw(ioaddr + BASE);
33271 - if (ioaddr != (base_address_register >> 3 & 0x3E0)) {
33272 -#ifdef SMC9000_VERBOSE
33273 - printf("SMC9000: IOADDR %hX doesn't match configuration (%hX)."
33274 - "Probably not a SMC chip\n",
33275 - ioaddr, base_address_register >> 3 & 0x3E0);
33276 -#endif
33277 - /* well, the base address register didn't match. Must not have
33278 - * been a SMC chip after all. */
33279 - return -1;
33283 - /* check if the revision register is something that I recognize.
33284 - * These might need to be added to later, as future revisions
33285 - * could be added. */
33286 - SMC_SELECT_BANK(ioaddr, 3);
33287 - revision_register = inw(ioaddr + REVISION);
33288 - if (!chip_ids[(revision_register >> 4) & 0xF]) {
33289 - /* I don't recognize this chip, so... */
33290 -#ifdef SMC9000_VERBOSE
33291 - printf("SMC9000: IO %hX: Unrecognized revision register:"
33292 - " %hX, Contact author.\n", ioaddr, revision_register);
33293 -#endif
33294 - return -1;
33297 - /* at this point I'll assume that the chip is an SMC9xxx.
33298 - * It might be prudent to check a listing of MAC addresses
33299 - * against the hardware address, or do some other tests. */
33300 - return 0;
33304 -/**************************************************************************
33305 - * ETH_RESET - Reset adapter
33306 - ***************************************************************************/
33308 -static void smc9000_reset(struct nic *nic)
33310 - smc_reset(smc9000_base);
33313 -/**************************************************************************
33314 - * ETH_TRANSMIT - Transmit a frame
33315 - ***************************************************************************/
33316 -static void smc9000_transmit(
33317 - struct nic *nic,
33318 - const char *d, /* Destination */
33319 - unsigned int t, /* Type */
33320 - unsigned int s, /* size */
33321 - const char *p) /* Packet */
33323 - word length; /* real, length incl. header */
33324 - word numPages;
33325 - unsigned long time_out;
33326 - byte packet_no;
33327 - word status;
33328 - int i;
33330 - /* We dont pad here since we can have the hardware doing it for us */
33331 - length = (s + ETH_HLEN + 1)&~1;
33333 - /* convert to MMU pages */
33334 - numPages = length / 256;
33336 - if (numPages > 7 ) {
33337 -#ifdef SMC9000_VERBOSE
33338 - printf("SMC9000: Far too big packet error. \n");
33339 -#endif
33340 - return;
33343 - /* dont try more than, say 30 times */
33344 - for (i=0;i<30;i++) {
33345 - /* now, try to allocate the memory */
33346 - SMC_SELECT_BANK(smc9000_base, 2);
33347 - _outw(MC_ALLOC | numPages, smc9000_base + MMU_CMD);
33349 - status = 0;
33350 - /* wait for the memory allocation to finnish */
33351 - for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
33352 - status = inb(smc9000_base + INTERRUPT);
33353 - if ( status & IM_ALLOC_INT ) {
33354 - /* acknowledge the interrupt */
33355 - _outb(IM_ALLOC_INT, smc9000_base + INTERRUPT);
33356 - break;
33360 - if ((status & IM_ALLOC_INT) != 0 ) {
33361 - /* We've got the memory */
33362 - break;
33363 - } else {
33364 - printf("SMC9000: Memory allocation timed out, resetting MMU.\n");
33365 - _outw(MC_RESET, smc9000_base + MMU_CMD);
33369 - /* If I get here, I _know_ there is a packet slot waiting for me */
33370 - packet_no = inb(smc9000_base + PNR_ARR + 1);
33371 - if (packet_no & 0x80) {
33372 - /* or isn't there? BAD CHIP! */
33373 - printf("SMC9000: Memory allocation failed. \n");
33374 - return;
33377 - /* we have a packet address, so tell the card to use it */
33378 - _outb(packet_no, smc9000_base + PNR_ARR);
33380 - /* point to the beginning of the packet */
33381 - _outw(PTR_AUTOINC, smc9000_base + POINTER);
33383 -#if SMC9000_DEBUG > 2
33384 - printf("Trying to xmit packet of length %hX\n", length );
33385 -#endif
33387 - /* send the packet length ( +6 for status, length and ctl byte )
33388 - * and the status word ( set to zeros ) */
33389 - _outw(0, smc9000_base + DATA_1 );
33391 - /* send the packet length ( +6 for status words, length, and ctl) */
33392 - _outb((length+6) & 0xFF, smc9000_base + DATA_1);
33393 - _outb((length+6) >> 8 , smc9000_base + DATA_1);
33395 - /* Write the contents of the packet */
33397 - /* The ethernet header first... */
33398 - outsw(smc9000_base + DATA_1, d, ETH_ALEN >> 1);
33399 - outsw(smc9000_base + DATA_1, nic->node_addr, ETH_ALEN >> 1);
33400 - _outw(htons(t), smc9000_base + DATA_1);
33402 - /* ... the data ... */
33403 - outsw(smc9000_base + DATA_1 , p, s >> 1);
33405 - /* ... and the last byte, if there is one. */
33406 - if ((s & 1) == 0) {
33407 - _outw(0, smc9000_base + DATA_1);
33408 - } else {
33409 - _outb(p[s-1], smc9000_base + DATA_1);
33410 - _outb(0x20, smc9000_base + DATA_1);
33413 - /* and let the chipset deal with it */
33414 - _outw(MC_ENQUEUE , smc9000_base + MMU_CMD);
33416 - status = 0; time_out = currticks() + 5*TICKS_PER_SEC;
33417 - do {
33418 - status = inb(smc9000_base + INTERRUPT);
33420 - if ((status & IM_TX_INT ) != 0) {
33421 - word tx_status;
33423 - /* ack interrupt */
33424 - _outb(IM_TX_INT, smc9000_base + INTERRUPT);
33426 - packet_no = inw(smc9000_base + FIFO_PORTS);
33427 - packet_no &= 0x7F;
33429 - /* select this as the packet to read from */
33430 - _outb( packet_no, smc9000_base + PNR_ARR );
33432 - /* read the first word from this packet */
33433 - _outw( PTR_AUTOINC | PTR_READ, smc9000_base + POINTER );
33435 - tx_status = inw( smc9000_base + DATA_1 );
33437 - if (0 == (tx_status & TS_SUCCESS)) {
33438 -#ifdef SMC9000_VERBOSE
33439 - printf("SMC9000: TX FAIL STATUS: %hX \n", tx_status);
33440 -#endif
33441 - /* re-enable transmit */
33442 - SMC_SELECT_BANK(smc9000_base, 0);
33443 - _outw(inw(smc9000_base + TCR ) | TCR_ENABLE, smc9000_base + TCR );
33446 - /* kill the packet */
33447 - SMC_SELECT_BANK(smc9000_base, 2);
33448 - _outw(MC_FREEPKT, smc9000_base + MMU_CMD);
33450 - return;
33452 - }while(currticks() < time_out);
33454 - printf("SMC9000: Waring TX timed out, resetting board\n");
33455 - smc_reset(smc9000_base);
33456 - return;
33459 -/**************************************************************************
33460 - * ETH_POLL - Wait for a frame
33461 - ***************************************************************************/
33462 -static int smc9000_poll(struct nic *nic)
33464 - if(!smc9000_base)
33465 - return 0;
33467 - SMC_SELECT_BANK(smc9000_base, 2);
33468 - if (inw(smc9000_base + FIFO_PORTS) & FP_RXEMPTY)
33469 - return 0;
33471 - /* start reading from the start of the packet */
33472 - _outw(PTR_READ | PTR_RCV | PTR_AUTOINC, smc9000_base + POINTER);
33474 - /* First read the status and check that we're ok */
33475 - if (!(inw(smc9000_base + DATA_1) & RS_ERRORS)) {
33476 - /* Next: read the packet length and mask off the top bits */
33477 - nic->packetlen = (inw(smc9000_base + DATA_1) & 0x07ff);
33479 - /* the packet length includes the 3 extra words */
33480 - nic->packetlen -= 6;
33481 -#if SMC9000_DEBUG > 2
33482 - printf(" Reading %d words (and %d byte(s))\n",
33483 - (nic->packetlen >> 1), nic->packetlen & 1);
33484 -#endif
33485 - /* read the packet (and the last "extra" word) */
33486 - insw(smc9000_base + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
33487 - /* is there an odd last byte ? */
33488 - if (nic->packet[nic->packetlen+1] & 0x20)
33489 - nic->packetlen++;
33491 - /* error or good, tell the card to get rid of this packet */
33492 - _outw(MC_RELEASE, smc9000_base + MMU_CMD);
33493 - return 1;
33496 - printf("SMC9000: RX error\n");
33497 - /* error or good, tell the card to get rid of this packet */
33498 - _outw(MC_RELEASE, smc9000_base + MMU_CMD);
33499 - return 0;
33502 -static void smc9000_disable(struct nic *nic)
33504 - if(!smc9000_base)
33505 - return;
33507 - /* no more interrupts for me */
33508 - SMC_SELECT_BANK(smc9000_base, 2);
33509 - _outb( 0, smc9000_base + INT_MASK);
33511 - /* and tell the card to stay away from that nasty outside world */
33512 - SMC_SELECT_BANK(smc9000_base, 0);
33513 - _outb( RCR_CLEAR, smc9000_base + RCR );
33514 - _outb( TCR_CLEAR, smc9000_base + TCR );
33517 -/**************************************************************************
33518 - * ETH_PROBE - Look for an adapter
33519 - ***************************************************************************/
33521 -struct nic *smc9000_probe(struct nic *nic, unsigned short *probe_addrs)
33523 - unsigned short revision;
33524 - int memory;
33525 - int media;
33526 - const char * version_string;
33527 - const char * if_string;
33528 - int i;
33530 - /*
33531 - * the SMC9000 can be at any of the following port addresses. To change,
33532 - * for a slightly different card, you can add it to the array. Keep in
33533 - * mind that the array must end in zero.
33534 - */
33535 - static unsigned short portlist[] = {
33536 -#ifdef SMC9000_SCAN
33537 - SMC9000_SCAN,
33538 -#else
33539 - 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
33540 - 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0,
33541 -#endif
33542 - 0 };
33544 - printf("\nSMC9000 %s\n", smc9000_version);
33545 -#ifdef SMC9000_VERBOSE
33546 - printf("Copyright (C) 1998 Daniel Engstr\x94m\n");
33547 - printf("Copyright (C) 1996 Eric Stahlman\n");
33548 -#endif
33549 - /* if no addresses supplied, fall back on defaults */
33550 - if (probe_addrs == 0 || probe_addrs[0] == 0)
33551 - probe_addrs = portlist;
33553 - /* check every ethernet address */
33554 - for (i = 0; probe_addrs[i]; i++) {
33555 - /* check this specific address */
33556 - if (smc_probe(probe_addrs[i]) == 0)
33557 - smc9000_base = probe_addrs[i];
33560 - /* couldn't find anything */
33561 - if(0 == smc9000_base)
33562 - goto out;
33564 - /*
33565 - * Get the MAC address ( bank 1, regs 4 - 9 )
33566 - */
33567 - SMC_SELECT_BANK(smc9000_base, 1);
33568 - for ( i = 0; i < 6; i += 2 ) {
33569 - word address;
33571 - address = inw(smc9000_base + ADDR0 + i);
33572 - nic->node_addr[i+1] = address >> 8;
33573 - nic->node_addr[i] = address & 0xFF;
33577 - /* get the memory information */
33578 - SMC_SELECT_BANK(smc9000_base, 0);
33579 - memory = ( inw(smc9000_base + MCR) >> 9 ) & 0x7; /* multiplier */
33580 - memory *= 256 * (inw(smc9000_base + MIR) & 0xFF);
33582 - /*
33583 - * Now, I want to find out more about the chip. This is sort of
33584 - * redundant, but it's cleaner to have it in both, rather than having
33585 - * one VERY long probe procedure.
33586 - */
33587 - SMC_SELECT_BANK(smc9000_base, 3);
33588 - revision = inw(smc9000_base + REVISION);
33589 - version_string = chip_ids[(revision >> 4) & 0xF];
33591 - if (((revision & 0xF0) >> 4 == CHIP_9196) &&
33592 - ((revision & 0x0F) >= REV_9196)) {
33593 - /* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but
33594 - * a revision starting at 6 */
33595 - version_string = smc91c96_id;
33598 - if ( !version_string ) {
33599 - /* I shouldn't get here because this call was done before.... */
33600 - goto out;
33603 - /* is it using AUI or 10BaseT ? */
33604 - SMC_SELECT_BANK(smc9000_base, 1);
33605 - if (inw(smc9000_base + CONFIG) & CFG_AUI_SELECT)
33606 - media = 2;
33607 - else
33608 - media = 1;
33610 - if_string = interfaces[media - 1];
33612 - /* now, reset the chip, and put it into a known state */
33613 - smc_reset(smc9000_base);
33615 - printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n",
33616 - version_string, revision & 0xF,
33617 - smc9000_base, if_string, memory );
33618 - /*
33619 - * Print the Ethernet address
33620 - */
33621 - printf("Ethernet MAC address: %!\n", nic->node_addr);
33623 - SMC_SELECT_BANK(smc9000_base, 0);
33625 - /* see the header file for options in TCR/RCR NORMAL*/
33626 - _outw(TCR_NORMAL, smc9000_base + TCR);
33627 - _outw(RCR_NORMAL, smc9000_base + RCR);
33629 - /* Select which interface to use */
33630 - SMC_SELECT_BANK(smc9000_base, 1);
33631 - if ( media == 1 ) {
33632 - _outw( inw( smc9000_base + CONFIG ) & ~CFG_AUI_SELECT,
33633 - smc9000_base + CONFIG );
33635 - else if ( media == 2 ) {
33636 - _outw( inw( smc9000_base + CONFIG ) | CFG_AUI_SELECT,
33637 - smc9000_base + CONFIG );
33640 - nic->reset = smc9000_reset;
33641 - nic->poll = smc9000_poll;
33642 - nic->transmit = smc9000_transmit;
33643 - nic->disable = smc9000_disable;
33646 - return nic;
33648 -out:
33649 -#ifdef SMC9000_VERBOSE
33650 - printf("No SMC9000 adapters found\n");
33651 -#endif
33652 - smc9000_base = 0;
33654 - return (0);
33659 Index: b/netboot/smc9000.h
33660 ===================================================================
33661 --- a/netboot/smc9000.h
33662 +++ /dev/null
33663 @@ -1,205 +0,0 @@
33664 -/*------------------------------------------------------------------------
33665 - * smc9000.h
33667 - * Copyright (C) 1998 by Daniel Engström
33668 - * Copyright (C) 1996 by Erik Stahlman
33670 - * This software may be used and distributed according to the terms
33671 - * of the GNU Public License, incorporated herein by reference.
33673 - * This file contains register information and access macros for
33674 - * the SMC91xxx chipset.
33676 - * Information contained in this file was obtained from the SMC91C94
33677 - * manual from SMC. To get a copy, if you really want one, you can find
33678 - * information under www.smsc.com in the components division.
33679 - * ( this thanks to advice from Donald Becker ).
33681 - * Authors
33682 - * Daniel Engström <daniel.engstrom@riksnett.no>
33683 - * Erik Stahlman <erik@vt.edu>
33685 - * History
33686 - * 96-01-06 Erik Stahlman moved definitions here from main .c
33687 - * file
33688 - * 96-01-19 Erik Stahlman polished this up some, and added
33689 - * better error handling
33690 - * 98-09-25 Daniel Engström adjusted for Etherboot
33691 - * 98-09-27 Daniel Engström moved some static strings back to the
33692 - * main .c file
33693 - * --------------------------------------------------------------------------*/
33694 -#ifndef _SMC9000_H_
33695 -# define _SMC9000_H_
33697 -/* I want some simple types */
33698 -typedef unsigned char byte;
33699 -typedef unsigned short word;
33700 -typedef unsigned long int dword;
33702 -/*---------------------------------------------------------------
33704 - * A description of the SMC registers is probably in order here,
33705 - * although for details, the SMC datasheet is invaluable.
33707 - * Basically, the chip has 4 banks of registers ( 0 to 3 ), which
33708 - * are accessed by writing a number into the BANK_SELECT register
33709 - * ( I also use a SMC_SELECT_BANK macro for this ).
33711 - * The banks are configured so that for most purposes, bank 2 is all
33712 - * that is needed for simple run time tasks.
33713 - * ----------------------------------------------------------------------*/
33716 - * Bank Select Register:
33718 - * yyyy yyyy 0000 00xx
33719 - * xx = bank number
33720 - * yyyy yyyy = 0x33, for identification purposes.
33721 - */
33722 -#define BANK_SELECT 14
33724 -/* BANK 0 */
33726 -#define TCR 0 /* transmit control register */
33727 -#define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */
33728 -#define TCR_FDUPLX 0x0800 /* receive packets sent out */
33729 -#define TCR_STP_SQET 0x1000 /* stop transmitting if Signal quality error */
33730 -#define TCR_MON_CNS 0x0400 /* monitors the carrier status */
33731 -#define TCR_PAD_ENABLE 0x0080 /* pads short packets to 64 bytes */
33733 -#define TCR_CLEAR 0 /* do NOTHING */
33734 -/* the normal settings for the TCR register : */
33735 -#define TCR_NORMAL (TCR_ENABLE | TCR_PAD_ENABLE)
33738 -#define EPH_STATUS 2
33739 -#define ES_LINK_OK 0x4000 /* is the link integrity ok ? */
33741 -#define RCR 4
33742 -#define RCR_SOFTRESET 0x8000 /* resets the chip */
33743 -#define RCR_STRIP_CRC 0x200 /* strips CRC */
33744 -#define RCR_ENABLE 0x100 /* IFF this is set, we can receive packets */
33745 -#define RCR_ALMUL 0x4 /* receive all multicast packets */
33746 -#define RCR_PROMISC 0x2 /* enable promiscuous mode */
33748 -/* the normal settings for the RCR register : */
33749 -#define RCR_NORMAL (RCR_STRIP_CRC | RCR_ENABLE)
33750 -#define RCR_CLEAR 0x0 /* set it to a base state */
33752 -#define COUNTER 6
33753 -#define MIR 8
33754 -#define MCR 10
33755 -/* 12 is reserved */
33757 -/* BANK 1 */
33758 -#define CONFIG 0
33759 -#define CFG_AUI_SELECT 0x100
33760 -#define BASE 2
33761 -#define ADDR0 4
33762 -#define ADDR1 6
33763 -#define ADDR2 8
33764 -#define GENERAL 10
33765 -#define CONTROL 12
33766 -#define CTL_POWERDOWN 0x2000
33767 -#define CTL_LE_ENABLE 0x80
33768 -#define CTL_CR_ENABLE 0x40
33769 -#define CTL_TE_ENABLE 0x0020
33770 -#define CTL_AUTO_RELEASE 0x0800
33771 -#define CTL_EPROM_ACCESS 0x0003 /* high if Eprom is being read */
33773 -/* BANK 2 */
33774 -#define MMU_CMD 0
33775 -#define MC_BUSY 1 /* only readable bit in the register */
33776 -#define MC_NOP 0
33777 -#define MC_ALLOC 0x20 /* or with number of 256 byte packets */
33778 -#define MC_RESET 0x40
33779 -#define MC_REMOVE 0x60 /* remove the current rx packet */
33780 -#define MC_RELEASE 0x80 /* remove and release the current rx packet */
33781 -#define MC_FREEPKT 0xA0 /* Release packet in PNR register */
33782 -#define MC_ENQUEUE 0xC0 /* Enqueue the packet for transmit */
33784 -#define PNR_ARR 2
33785 -#define FIFO_PORTS 4
33787 -#define FP_RXEMPTY 0x8000
33788 -#define FP_TXEMPTY 0x80
33790 -#define POINTER 6
33791 -#define PTR_READ 0x2000
33792 -#define PTR_RCV 0x8000
33793 -#define PTR_AUTOINC 0x4000
33794 -#define PTR_AUTO_INC 0x0040
33796 -#define DATA_1 8
33797 -#define DATA_2 10
33798 -#define INTERRUPT 12
33800 -#define INT_MASK 13
33801 -#define IM_RCV_INT 0x1
33802 -#define IM_TX_INT 0x2
33803 -#define IM_TX_EMPTY_INT 0x4
33804 -#define IM_ALLOC_INT 0x8
33805 -#define IM_RX_OVRN_INT 0x10
33806 -#define IM_EPH_INT 0x20
33807 -#define IM_ERCV_INT 0x40 /* not on SMC9192 */
33809 -/* BANK 3 */
33810 -#define MULTICAST1 0
33811 -#define MULTICAST2 2
33812 -#define MULTICAST3 4
33813 -#define MULTICAST4 6
33814 -#define MGMT 8
33815 -#define REVISION 10 /* ( hi: chip id low: rev # ) */
33818 -/* this is NOT on SMC9192 */
33819 -#define ERCV 12
33821 -/* Note that 9194 and 9196 have the smame chip id,
33822 - * the 9196 will have revisions starting at 6 */
33823 -#define CHIP_9190 3
33824 -#define CHIP_9194 4
33825 -#define CHIP_9195 5
33826 -#define CHIP_9196 4
33827 -#define CHIP_91100 7
33828 -#define CHIP_91100FD 8
33830 -#define REV_9196 6
33833 - * Transmit status bits
33834 - */
33835 -#define TS_SUCCESS 0x0001
33836 -#define TS_LOSTCAR 0x0400
33837 -#define TS_LATCOL 0x0200
33838 -#define TS_16COL 0x0010
33841 - * Receive status bits
33842 - */
33843 -#define RS_ALGNERR 0x8000
33844 -#define RS_BADCRC 0x2000
33845 -#define RS_ODDFRAME 0x1000
33846 -#define RS_TOOLONG 0x0800
33847 -#define RS_TOOSHORT 0x0400
33848 -#define RS_MULTICAST 0x0001
33849 -#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
33852 -/*-------------------------------------------------------------------------
33853 - * I define some macros to make it easier to do somewhat common
33854 - * or slightly complicated, repeated tasks.
33855 - --------------------------------------------------------------------------*/
33857 -/* select a register bank, 0 to 3 */
33859 -#define SMC_SELECT_BANK(x, y) { _outw( y, x + BANK_SELECT ); }
33861 -/* define a small delay for the reset */
33862 -#define SMC_DELAY(x) { inw( x + RCR );\
33863 - inw( x + RCR );\
33864 - inw( x + RCR ); }
33867 -#endif /* _SMC_9000_H_ */
33869 Index: b/netboot/stdint.h
33870 ===================================================================
33871 --- /dev/null
33872 +++ b/netboot/stdint.h
33873 @@ -0,0 +1,18 @@
33874 +#ifndef STDINT_H
33875 +#define STDINT_H
33876 +/*
33877 + * I'm architecture depended. Check me before port GRUB
33878 + */
33879 +typedef unsigned size_t;
33881 +typedef unsigned char uint8_t;
33882 +typedef unsigned short uint16_t;
33883 +typedef unsigned long uint32_t;
33884 +typedef unsigned long long uint64_t;
33886 +typedef signed char int8_t;
33887 +typedef signed short int16_t;
33888 +typedef signed long int32_t;
33889 +typedef signed long long int64_t;
33891 +#endif /* STDINT_H */
33892 Index: b/netboot/tftp.h
33893 ===================================================================
33894 --- /dev/null
33895 +++ b/netboot/tftp.h
33896 @@ -0,0 +1,82 @@
33897 +#ifndef _TFTP_H
33898 +#define _TFTP_H
33900 +#include "if_ether.h"
33901 +#include "ip.h"
33902 +#include "udp.h"
33904 +#ifndef MAX_TFTP_RETRIES
33905 +#define MAX_TFTP_RETRIES 20
33906 +#endif
33908 +/* These settings have sense only if compiled with -DCONGESTED */
33909 +/* total retransmission timeout in ticks */
33910 +#define TFTP_TIMEOUT (30*TICKS_PER_SEC)
33911 +/* packet retransmission timeout in ticks */
33912 +#define TFTP_REXMT (3*TICKS_PER_SEC)
33914 +#define TFTP_PORT 69
33915 +#define TFTP_DEFAULTSIZE_PACKET 512
33916 +#define TFTP_MAX_PACKET 1432 /* 512 */
33918 +#define TFTP_RRQ 1
33919 +#define TFTP_WRQ 2
33920 +#define TFTP_DATA 3
33921 +#define TFTP_ACK 4
33922 +#define TFTP_ERROR 5
33923 +#define TFTP_OACK 6
33925 +#define TFTP_CODE_EOF 1
33926 +#define TFTP_CODE_MORE 2
33927 +#define TFTP_CODE_ERROR 3
33928 +#define TFTP_CODE_BOOT 4
33929 +#define TFTP_CODE_CFG 5
33931 +struct tftp_t {
33932 + struct iphdr ip;
33933 + struct udphdr udp;
33934 + uint16_t opcode;
33935 + union {
33936 + uint8_t rrq[TFTP_DEFAULTSIZE_PACKET];
33937 + struct {
33938 + uint16_t block;
33939 + uint8_t download[TFTP_MAX_PACKET];
33940 + } data;
33941 + struct {
33942 + uint16_t block;
33943 + } ack;
33944 + struct {
33945 + uint16_t errcode;
33946 + uint8_t errmsg[TFTP_DEFAULTSIZE_PACKET];
33947 + } err;
33948 + struct {
33949 + uint8_t data[TFTP_DEFAULTSIZE_PACKET+2];
33950 + } oack;
33951 + } u;
33954 +/* define a smaller tftp packet solely for making requests to conserve stack
33955 + 512 bytes should be enough */
33956 +struct tftpreq_t {
33957 + struct iphdr ip;
33958 + struct udphdr udp;
33959 + uint16_t opcode;
33960 + union {
33961 + uint8_t rrq[512];
33962 + struct {
33963 + uint16_t block;
33964 + } ack;
33965 + struct {
33966 + uint16_t errcode;
33967 + uint8_t errmsg[512-2];
33968 + } err;
33969 + } u;
33972 +#define TFTP_MIN_PACKET (sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
33974 +typedef int (*read_actor_t)(unsigned char *, unsigned int, unsigned int, int);
33976 +int tftp_file_read(const char *name, read_actor_t);
33978 +#endif /* _TFTP_H */
33979 Index: b/netboot/tg3.c
33980 ===================================================================
33981 --- /dev/null
33982 +++ b/netboot/tg3.c
33983 @@ -0,0 +1,3322 @@
33984 +/* $Id: grub-0.95-diskless-patch-2.patch,v 1.1.1.1 2005/06/14 08:18:50 wesolows Exp $
33985 + * tg3.c: Broadcom Tigon3 ethernet driver.
33987 + * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
33988 + * Copyright (C) 2001, 2002 Jeff Garzik (jgarzik@mandrakesoft.com)
33989 + * Copyright (C) 2003 Eric Biederman (ebiederman@lnxi.com) [etherboot port]
33990 + */
33992 +/* 11-13-2003 timlegge Fix Issue with NetGear GA302T
33993 + * 11-18-2003 ebiederm Generalize NetGear Fix to what the code was supposed to be.
33994 + */
33996 +#include "etherboot.h"
33997 +#include "nic.h"
33998 +#include "pci.h"
33999 +#include "timer.h"
34000 +/*#include "string.h"*/
34001 +#include "tg3.h"
34003 +#define SUPPORT_COPPER_PHY 1
34004 +#define SUPPORT_FIBER_PHY 1
34005 +#define SUPPORT_LINK_REPORT 1
34006 +#define SUPPORT_PARTNO_STR 1
34007 +#define SUPPORT_PHY_STR 1
34009 +struct tg3 tg3;
34011 +/* Dummy defines for error handling */
34012 +#define EBUSY 1
34013 +#define ENODEV 2
34014 +#define EINVAL 3
34015 +#define ENOMEM 4
34018 +/* These numbers seem to be hard coded in the NIC firmware somehow.
34019 + * You can't change the ring sizes, but you can change where you place
34020 + * them in the NIC onboard memory.
34021 + */
34022 +#define TG3_RX_RING_SIZE 512
34023 +#define TG3_DEF_RX_RING_PENDING 20 /* RX_RING_PENDING seems to be o.k. at 20 and 200 */
34024 +#define TG3_RX_RCB_RING_SIZE 1024
34026 +/* (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ? \
34027 + 512 : 1024) */
34028 + #define TG3_TX_RING_SIZE 512
34029 +#define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1)
34031 +#define TG3_RX_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_RING_SIZE)
34032 +#define TG3_RX_RCB_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_RCB_RING_SIZE)
34034 +#define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * TG3_TX_RING_SIZE)
34035 +#define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1))
34036 +#define PREV_TX(N) (((N) - 1) & (TG3_TX_RING_SIZE - 1))
34038 +#define RX_PKT_BUF_SZ (1536 + 2 + 64)
34041 +static struct bss {
34042 + struct tg3_rx_buffer_desc rx_std[TG3_RX_RING_SIZE];
34043 + struct tg3_rx_buffer_desc rx_rcb[TG3_RX_RCB_RING_SIZE];
34044 + struct tg3_tx_buffer_desc tx_ring[TG3_TX_RING_SIZE];
34045 + struct tg3_hw_status hw_status;
34046 + struct tg3_hw_stats hw_stats;
34047 + unsigned char rx_bufs[TG3_DEF_RX_RING_PENDING][RX_PKT_BUF_SZ];
34048 +} tg3_bss;
34050 +/**
34051 + * pci_save_state - save the PCI configuration space of a device before suspending
34052 + * @dev: - PCI device that we're dealing with
34053 + * @buffer: - buffer to hold config space context
34055 + * @buffer must be large enough to hold the entire PCI 2.2 config space
34056 + * (>= 64 bytes).
34057 + */
34058 +static int pci_save_state(struct pci_device *dev, uint32_t *buffer)
34060 + int i;
34061 + for (i = 0; i < 16; i++)
34062 + pci_read_config_dword(dev, i * 4,&buffer[i]);
34063 + return 0;
34066 +/**
34067 + * pci_restore_state - Restore the saved state of a PCI device
34068 + * @dev: - PCI device that we're dealing with
34069 + * @buffer: - saved PCI config space
34071 + */
34072 +static int pci_restore_state(struct pci_device *dev, uint32_t *buffer)
34074 + int i;
34076 + for (i = 0; i < 16; i++)
34077 + pci_write_config_dword(dev,i * 4, buffer[i]);
34078 + return 0;
34081 +static void tg3_write_indirect_reg32(uint32_t off, uint32_t val)
34083 + pci_write_config_dword(tg3.pdev, TG3PCI_REG_BASE_ADDR, off);
34084 + pci_write_config_dword(tg3.pdev, TG3PCI_REG_DATA, val);
34087 +#define tw32(reg,val) tg3_write_indirect_reg32((reg),(val))
34088 +#define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tg3.regs + (reg))
34089 +#define tw16(reg,val) writew(((val) & 0xffff), tg3.regs + (reg))
34090 +#define tw8(reg,val) writeb(((val) & 0xff), tg3.regs + (reg))
34091 +#define tr32(reg) readl(tg3.regs + (reg))
34092 +#define tr16(reg) readw(tg3.regs + (reg))
34093 +#define tr8(reg) readb(tg3.regs + (reg))
34095 +static void tw32_carefully(uint32_t reg, uint32_t val)
34097 + tw32(reg, val);
34098 + tr32(reg);
34099 + udelay(100);
34102 +static void tw32_mailbox2(uint32_t reg, uint32_t val)
34104 + tw32_mailbox(reg, val);
34105 + tr32(reg);
34108 +static void tg3_write_mem(uint32_t off, uint32_t val)
34110 + pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
34111 + pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_DATA, val);
34113 + /* Always leave this as zero. */
34114 + pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
34117 +static void tg3_read_mem(uint32_t off, uint32_t *val)
34119 + pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
34120 + pci_read_config_dword(tg3.pdev, TG3PCI_MEM_WIN_DATA, val);
34122 + /* Always leave this as zero. */
34123 + pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
34126 +static void tg3_disable_ints(struct tg3 *tp)
34128 + tw32(TG3PCI_MISC_HOST_CTRL,
34129 + (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
34130 + tw32_mailbox2(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
34133 +static void tg3_switch_clocks(struct tg3 *tp)
34135 + uint32_t orig_clock_ctrl, clock_ctrl;
34137 + clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
34139 + orig_clock_ctrl = clock_ctrl;
34140 + clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE | 0x1f);
34141 + tp->pci_clock_ctrl = clock_ctrl;
34143 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) &&
34144 + (orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE)!=0) {
34145 + tw32_carefully(TG3PCI_CLOCK_CTRL,
34146 + clock_ctrl | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK));
34147 + tw32_carefully(TG3PCI_CLOCK_CTRL,
34148 + clock_ctrl | (CLOCK_CTRL_ALTCLK));
34150 + tw32_carefully(TG3PCI_CLOCK_CTRL, clock_ctrl);
34153 +#define PHY_BUSY_LOOPS 5000
34155 +static int tg3_readphy(struct tg3 *tp, int reg, uint32_t *val)
34157 + uint32_t frame_val;
34158 + int loops, ret;
34160 + tw32_carefully(MAC_MI_MODE, tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL);
34162 + *val = 0xffffffff;
34164 + frame_val = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
34165 + MI_COM_PHY_ADDR_MASK);
34166 + frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
34167 + MI_COM_REG_ADDR_MASK);
34168 + frame_val |= (MI_COM_CMD_READ | MI_COM_START);
34170 + tw32_carefully(MAC_MI_COM, frame_val);
34172 + loops = PHY_BUSY_LOOPS;
34173 + while (loops-- > 0) {
34174 + udelay(10);
34175 + frame_val = tr32(MAC_MI_COM);
34177 + if ((frame_val & MI_COM_BUSY) == 0) {
34178 + udelay(5);
34179 + frame_val = tr32(MAC_MI_COM);
34180 + break;
34184 + ret = -EBUSY;
34185 + if (loops > 0) {
34186 + *val = frame_val & MI_COM_DATA_MASK;
34187 + ret = 0;
34190 + tw32_carefully(MAC_MI_MODE, tp->mi_mode);
34192 + return ret;
34195 +static int tg3_writephy(struct tg3 *tp, int reg, uint32_t val)
34197 + uint32_t frame_val;
34198 + int loops, ret;
34200 + tw32_carefully(MAC_MI_MODE, tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL);
34202 + frame_val = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
34203 + MI_COM_PHY_ADDR_MASK);
34204 + frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
34205 + MI_COM_REG_ADDR_MASK);
34206 + frame_val |= (val & MI_COM_DATA_MASK);
34207 + frame_val |= (MI_COM_CMD_WRITE | MI_COM_START);
34209 + tw32_carefully(MAC_MI_COM, frame_val);
34211 + loops = PHY_BUSY_LOOPS;
34212 + while (loops-- > 0) {
34213 + udelay(10);
34214 + frame_val = tr32(MAC_MI_COM);
34215 + if ((frame_val & MI_COM_BUSY) == 0) {
34216 + udelay(5);
34217 + frame_val = tr32(MAC_MI_COM);
34218 + break;
34222 + ret = -EBUSY;
34223 + if (loops > 0)
34224 + ret = 0;
34226 + tw32_carefully(MAC_MI_MODE, tp->mi_mode);
34228 + return ret;
34231 +static int tg3_writedsp(struct tg3 *tp, uint16_t addr, uint16_t val)
34233 + int err;
34234 + err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, addr);
34235 + err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
34236 + return err;
34240 +static void tg3_phy_set_wirespeed(struct tg3 *tp)
34242 + uint32_t val;
34244 + if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED)
34245 + return;
34247 + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007);
34248 + tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
34249 + tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4)));
34252 +static int tg3_bmcr_reset(struct tg3 *tp)
34254 + uint32_t phy_control;
34255 + int limit, err;
34257 + /* OK, reset it, and poll the BMCR_RESET bit until it
34258 + * clears or we time out.
34259 + */
34260 + phy_control = BMCR_RESET;
34261 + err = tg3_writephy(tp, MII_BMCR, phy_control);
34262 + if (err != 0)
34263 + return -EBUSY;
34265 + limit = 5000;
34266 + while (limit--) {
34267 + err = tg3_readphy(tp, MII_BMCR, &phy_control);
34268 + if (err != 0)
34269 + return -EBUSY;
34271 + if ((phy_control & BMCR_RESET) == 0) {
34272 + udelay(40);
34273 + break;
34275 + udelay(10);
34277 + if (limit <= 0)
34278 + return -EBUSY;
34280 + return 0;
34283 +static int tg3_wait_macro_done(struct tg3 *tp)
34285 + int limit = 100;
34287 + while (limit--) {
34288 + uint32_t tmp32;
34290 + tg3_readphy(tp, 0x16, &tmp32);
34291 + if ((tmp32 & 0x1000) == 0)
34292 + break;
34294 + if (limit <= 0)
34295 + return -EBUSY;
34297 + return 0;
34300 +static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp)
34302 + static const uint32_t test_pat[4][6] = {
34303 + { 0x00005555, 0x00000005, 0x00002aaa, 0x0000000a, 0x00003456, 0x00000003 },
34304 + { 0x00002aaa, 0x0000000a, 0x00003333, 0x00000003, 0x0000789a, 0x00000005 },
34305 + { 0x00005a5a, 0x00000005, 0x00002a6a, 0x0000000a, 0x00001bcd, 0x00000003 },
34306 + { 0x00002a5a, 0x0000000a, 0x000033c3, 0x00000003, 0x00002ef1, 0x00000005 }
34307 + };
34308 + int chan;
34310 + for (chan = 0; chan < 4; chan++) {
34311 + int i;
34313 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
34314 + (chan * 0x2000) | 0x0200);
34315 + tg3_writephy(tp, 0x16, 0x0002);
34317 + for (i = 0; i < 6; i++)
34318 + tg3_writephy(tp, MII_TG3_DSP_RW_PORT,
34319 + test_pat[chan][i]);
34321 + tg3_writephy(tp, 0x16, 0x0202);
34322 + if (tg3_wait_macro_done(tp)) {
34323 + *resetp = 1;
34324 + return -EBUSY;
34327 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
34328 + (chan * 0x2000) | 0x0200);
34329 + tg3_writephy(tp, 0x16, 0x0082);
34330 + if (tg3_wait_macro_done(tp)) {
34331 + *resetp = 1;
34332 + return -EBUSY;
34335 + tg3_writephy(tp, 0x16, 0x0802);
34336 + if (tg3_wait_macro_done(tp)) {
34337 + *resetp = 1;
34338 + return -EBUSY;
34341 + for (i = 0; i < 6; i += 2) {
34342 + uint32_t low, high;
34344 + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low);
34345 + tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high);
34346 + if (tg3_wait_macro_done(tp)) {
34347 + *resetp = 1;
34348 + return -EBUSY;
34350 + low &= 0x7fff;
34351 + high &= 0x000f;
34352 + if (low != test_pat[chan][i] ||
34353 + high != test_pat[chan][i+1]) {
34354 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000b);
34355 + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4001);
34356 + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4005);
34358 + return -EBUSY;
34363 + return 0;
34366 +static int tg3_phy_reset_chanpat(struct tg3 *tp)
34368 + int chan;
34370 + for (chan = 0; chan < 4; chan++) {
34371 + int i;
34373 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
34374 + (chan * 0x2000) | 0x0200);
34375 + tg3_writephy(tp, 0x16, 0x0002);
34376 + for (i = 0; i < 6; i++)
34377 + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000);
34378 + tg3_writephy(tp, 0x16, 0x0202);
34379 + if (tg3_wait_macro_done(tp))
34380 + return -EBUSY;
34383 + return 0;
34386 +static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
34388 + uint32_t reg32, phy9_orig;
34389 + int retries, do_phy_reset, err;
34391 + retries = 10;
34392 + do_phy_reset = 1;
34393 + do {
34394 + if (do_phy_reset) {
34395 + err = tg3_bmcr_reset(tp);
34396 + if (err)
34397 + return err;
34398 + do_phy_reset = 0;
34401 + /* Disable transmitter and interrupt. */
34402 + tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32);
34403 + reg32 |= 0x3000;
34404 + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
34406 + /* Set full-duplex, 1000 mbps. */
34407 + tg3_writephy(tp, MII_BMCR,
34408 + BMCR_FULLDPLX | TG3_BMCR_SPEED1000);
34410 + /* Set to master mode. */
34411 + tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig);
34412 + tg3_writephy(tp, MII_TG3_CTRL,
34413 + (MII_TG3_CTRL_AS_MASTER |
34414 + MII_TG3_CTRL_ENABLE_AS_MASTER));
34416 + /* Enable SM_DSP_CLOCK and 6dB. */
34417 + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
34419 + /* Block the PHY control access. */
34420 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005);
34421 + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0800);
34423 + err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset);
34424 + if (!err)
34425 + break;
34426 + } while (--retries);
34428 + err = tg3_phy_reset_chanpat(tp);
34429 + if (err)
34430 + return err;
34432 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005);
34433 + tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0000);
34435 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
34436 + tg3_writephy(tp, 0x16, 0x0000);
34438 + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
34440 + tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
34442 + tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32);
34443 + reg32 &= ~0x3000;
34444 + tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
34446 + return err;
34449 +/* This will reset the tigon3 PHY if there is no valid
34450 + * link.
34451 + */
34452 +static int tg3_phy_reset(struct tg3 *tp)
34454 + uint32_t phy_status;
34455 + int err;
34457 + err = tg3_readphy(tp, MII_BMSR, &phy_status);
34458 + err |= tg3_readphy(tp, MII_BMSR, &phy_status);
34459 + if (err != 0)
34460 + return -EBUSY;
34462 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
34463 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
34464 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
34465 + err = tg3_phy_reset_5703_4_5(tp);
34466 + if (err)
34467 + return err;
34468 + goto out;
34470 + err = tg3_bmcr_reset(tp);
34471 + if (err)
34472 + return err;
34473 + out:
34474 + tg3_phy_set_wirespeed(tp);
34475 + return 0;
34478 +static void tg3_set_power_state_0(struct tg3 *tp)
34480 + uint16_t power_control;
34481 + int pm = tp->pm_cap;
34483 + /* Make sure register accesses (indirect or otherwise)
34484 + * will function correctly.
34485 + */
34486 + pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
34488 + pci_read_config_word(tp->pdev, pm + PCI_PM_CTRL, &power_control);
34490 + power_control |= PCI_PM_CTRL_PME_STATUS;
34491 + power_control &= ~(PCI_PM_CTRL_STATE_MASK);
34492 + power_control |= 0;
34493 + pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
34495 + tw32_carefully(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
34497 + return;
34501 +#if SUPPORT_LINK_REPORT
34502 +static void tg3_link_report(struct tg3 *tp)
34504 + if (!tp->carrier_ok) {
34505 + printf("Link is down.\n");
34506 + } else {
34507 + printf("Link is up at %d Mbps, %s duplex. %s %s %s\n",
34508 + (tp->link_config.active_speed == SPEED_1000 ?
34509 + 1000 :
34510 + (tp->link_config.active_speed == SPEED_100 ?
34511 + 100 : 10)),
34512 + (tp->link_config.active_duplex == DUPLEX_FULL ?
34513 + "full" : "half"),
34514 + (tp->tg3_flags & TG3_FLAG_TX_PAUSE) ? "TX" : "",
34515 + (tp->tg3_flags & TG3_FLAG_RX_PAUSE) ? "RX" : "",
34516 + (tp->tg3_flags & (TG3_FLAG_TX_PAUSE |TG3_FLAG_RX_PAUSE)) ? "flow control" : "");
34519 +#else
34520 +#define tg3_link_report(tp)
34521 +#endif
34523 +static void tg3_setup_flow_control(struct tg3 *tp, uint32_t local_adv, uint32_t remote_adv)
34525 + uint32_t new_tg3_flags = 0;
34527 + if (local_adv & ADVERTISE_PAUSE_CAP) {
34528 + if (local_adv & ADVERTISE_PAUSE_ASYM) {
34529 + if (remote_adv & LPA_PAUSE_CAP)
34530 + new_tg3_flags |=
34531 + (TG3_FLAG_RX_PAUSE |
34532 + TG3_FLAG_TX_PAUSE);
34533 + else if (remote_adv & LPA_PAUSE_ASYM)
34534 + new_tg3_flags |=
34535 + (TG3_FLAG_RX_PAUSE);
34536 + } else {
34537 + if (remote_adv & LPA_PAUSE_CAP)
34538 + new_tg3_flags |=
34539 + (TG3_FLAG_RX_PAUSE |
34540 + TG3_FLAG_TX_PAUSE);
34542 + } else if (local_adv & ADVERTISE_PAUSE_ASYM) {
34543 + if ((remote_adv & LPA_PAUSE_CAP) &&
34544 + (remote_adv & LPA_PAUSE_ASYM))
34545 + new_tg3_flags |= TG3_FLAG_TX_PAUSE;
34548 + tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);
34549 + tp->tg3_flags |= new_tg3_flags;
34551 + if (new_tg3_flags & TG3_FLAG_RX_PAUSE)
34552 + tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
34553 + else
34554 + tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
34556 + if (new_tg3_flags & TG3_FLAG_TX_PAUSE)
34557 + tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
34558 + else
34559 + tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
34562 +#if SUPPORT_COPPER_PHY
34563 +static void tg3_aux_stat_to_speed_duplex(
34564 + struct tg3 *tp __unused, uint32_t val, uint8_t *speed, uint8_t *duplex)
34566 + static const uint8_t map[] = {
34567 + [0] = (SPEED_INVALID << 2) | DUPLEX_INVALID,
34568 + [MII_TG3_AUX_STAT_10HALF >> 8] = (SPEED_10 << 2) | DUPLEX_HALF,
34569 + [MII_TG3_AUX_STAT_10FULL >> 8] = (SPEED_10 << 2) | DUPLEX_FULL,
34570 + [MII_TG3_AUX_STAT_100HALF >> 8] = (SPEED_100 << 2) | DUPLEX_HALF,
34571 + [MII_TG3_AUX_STAT_100_4 >> 8] = (SPEED_INVALID << 2) | DUPLEX_INVALID,
34572 + [MII_TG3_AUX_STAT_100FULL >> 8] = (SPEED_100 << 2) | DUPLEX_FULL,
34573 + [MII_TG3_AUX_STAT_1000HALF >> 8] = (SPEED_1000 << 2) | DUPLEX_HALF,
34574 + [MII_TG3_AUX_STAT_1000FULL >> 8] = (SPEED_1000 << 2) | DUPLEX_FULL,
34575 + };
34576 + uint8_t result;
34577 + result = map[(val & MII_TG3_AUX_STAT_SPDMASK) >> 8];
34578 + *speed = result >> 2;
34579 + *duplex = result & 3;
34582 +static int tg3_phy_copper_begin(struct tg3 *tp)
34584 + uint32_t new_adv;
34586 + tp->link_config.advertising =
34587 + (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
34588 + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
34589 + ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
34590 + ADVERTISED_Autoneg | ADVERTISED_MII);
34592 + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) {
34593 + tp->link_config.advertising &=
34594 + ~(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
34597 + new_adv = (ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
34598 + if (tp->link_config.advertising & ADVERTISED_10baseT_Half) {
34599 + new_adv |= ADVERTISE_10HALF;
34601 + if (tp->link_config.advertising & ADVERTISED_10baseT_Full) {
34602 + new_adv |= ADVERTISE_10FULL;
34604 + if (tp->link_config.advertising & ADVERTISED_100baseT_Half) {
34605 + new_adv |= ADVERTISE_100HALF;
34607 + if (tp->link_config.advertising & ADVERTISED_100baseT_Full) {
34608 + new_adv |= ADVERTISE_100FULL;
34610 + tg3_writephy(tp, MII_ADVERTISE, new_adv);
34612 + if (tp->link_config.advertising &
34613 + (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) {
34614 + new_adv = 0;
34615 + if (tp->link_config.advertising & ADVERTISED_1000baseT_Half) {
34616 + new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
34618 + if (tp->link_config.advertising & ADVERTISED_1000baseT_Full) {
34619 + new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
34621 + if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY) &&
34622 + (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
34623 + tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)) {
34624 + new_adv |= (MII_TG3_CTRL_AS_MASTER |
34625 + MII_TG3_CTRL_ENABLE_AS_MASTER);
34627 + tg3_writephy(tp, MII_TG3_CTRL, new_adv);
34628 + } else {
34629 + tg3_writephy(tp, MII_TG3_CTRL, 0);
34632 + tg3_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
34634 + return 0;
34637 +static int tg3_init_5401phy_dsp(struct tg3 *tp)
34639 + int err;
34641 + /* Turn off tap power management. */
34642 + err = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20);
34644 + err |= tg3_writedsp(tp, 0x0012, 0x1804);
34645 + err |= tg3_writedsp(tp, 0x0013, 0x1204);
34646 + err |= tg3_writedsp(tp, 0x8006, 0x0132);
34647 + err |= tg3_writedsp(tp, 0x8006, 0x0232);
34648 + err |= tg3_writedsp(tp, 0x201f, 0x0a20);
34650 + udelay(40);
34652 + return err;
34655 +static int tg3_setup_copper_phy(struct tg3 *tp)
34657 + int current_link_up;
34658 + uint32_t bmsr, dummy;
34659 + int i, err;
34661 + tw32_carefully(MAC_STATUS,
34662 + (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
34664 + tp->mi_mode = MAC_MI_MODE_BASE;
34665 + tw32_carefully(MAC_MI_MODE, tp->mi_mode);
34667 + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
34669 + /* Some third-party PHYs need to be reset on link going
34670 + * down.
34671 + */
34672 + if ( ( (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
34673 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
34674 + (tp->pci_chip_rev_id == CHIPREV_ID_5705_A0)) &&
34675 + (tp->carrier_ok)) {
34676 + tg3_readphy(tp, MII_BMSR, &bmsr);
34677 + tg3_readphy(tp, MII_BMSR, &bmsr);
34678 + if (!(bmsr & BMSR_LSTATUS))
34679 + tg3_phy_reset(tp);
34682 + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
34683 + tg3_readphy(tp, MII_BMSR, &bmsr);
34684 + tg3_readphy(tp, MII_BMSR, &bmsr);
34686 + if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
34687 + bmsr = 0;
34689 + if (!(bmsr & BMSR_LSTATUS)) {
34690 + err = tg3_init_5401phy_dsp(tp);
34691 + if (err)
34692 + return err;
34694 + tg3_readphy(tp, MII_BMSR, &bmsr);
34695 + for (i = 0; i < 1000; i++) {
34696 + udelay(10);
34697 + tg3_readphy(tp, MII_BMSR, &bmsr);
34698 + if (bmsr & BMSR_LSTATUS) {
34699 + udelay(40);
34700 + break;
34704 + if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
34705 + !(bmsr & BMSR_LSTATUS) &&
34706 + tp->link_config.active_speed == SPEED_1000) {
34707 + err = tg3_phy_reset(tp);
34708 + if (!err)
34709 + err = tg3_init_5401phy_dsp(tp);
34710 + if (err)
34711 + return err;
34714 + } else if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
34715 + tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
34716 + /* 5701 {A0,B0} CRC bug workaround */
34717 + tg3_writephy(tp, 0x15, 0x0a75);
34718 + tg3_writephy(tp, 0x1c, 0x8c68);
34719 + tg3_writephy(tp, 0x1c, 0x8d68);
34720 + tg3_writephy(tp, 0x1c, 0x8c68);
34723 + /* Clear pending interrupts... */
34724 + tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
34725 + tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
34727 + tg3_writephy(tp, MII_TG3_IMASK, ~0);
34729 + if (tp->led_mode == led_mode_three_link)
34730 + tg3_writephy(tp, MII_TG3_EXT_CTRL,
34731 + MII_TG3_EXT_CTRL_LNK3_LED_MODE);
34732 + else
34733 + tg3_writephy(tp, MII_TG3_EXT_CTRL, 0);
34735 + current_link_up = 0;
34737 + tg3_readphy(tp, MII_BMSR, &bmsr);
34738 + tg3_readphy(tp, MII_BMSR, &bmsr);
34740 + if (bmsr & BMSR_LSTATUS) {
34741 + uint32_t aux_stat, bmcr;
34743 + tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
34744 + for (i = 0; i < 2000; i++) {
34745 + udelay(10);
34746 + tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
34747 + if (aux_stat)
34748 + break;
34751 + tg3_aux_stat_to_speed_duplex(tp, aux_stat,
34752 + &tp->link_config.active_speed,
34753 + &tp->link_config.active_duplex);
34754 + tg3_readphy(tp, MII_BMCR, &bmcr);
34755 + tg3_readphy(tp, MII_BMCR, &bmcr);
34756 + if (bmcr & BMCR_ANENABLE) {
34757 + uint32_t gig_ctrl;
34759 + current_link_up = 1;
34761 + /* Force autoneg restart if we are exiting
34762 + * low power mode.
34763 + */
34764 + tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl);
34765 + if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |
34766 + MII_TG3_CTRL_ADV_1000_FULL))) {
34767 + current_link_up = 0;
34769 + } else {
34770 + current_link_up = 0;
34774 + if (current_link_up == 1 &&
34775 + (tp->link_config.active_duplex == DUPLEX_FULL)) {
34776 + uint32_t local_adv, remote_adv;
34778 + tg3_readphy(tp, MII_ADVERTISE, &local_adv);
34779 + local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
34781 + tg3_readphy(tp, MII_LPA, &remote_adv);
34782 + remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
34784 + /* If we are not advertising full pause capability,
34785 + * something is wrong. Bring the link down and reconfigure.
34786 + */
34787 + if (local_adv != ADVERTISE_PAUSE_CAP) {
34788 + current_link_up = 0;
34789 + } else {
34790 + tg3_setup_flow_control(tp, local_adv, remote_adv);
34794 + if (current_link_up == 0) {
34795 + uint32_t tmp;
34797 + tg3_phy_copper_begin(tp);
34799 + tg3_readphy(tp, MII_BMSR, &tmp);
34800 + tg3_readphy(tp, MII_BMSR, &tmp);
34801 + if (tmp & BMSR_LSTATUS)
34802 + current_link_up = 1;
34805 + tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;
34806 + if (current_link_up == 1) {
34807 + if (tp->link_config.active_speed == SPEED_100 ||
34808 + tp->link_config.active_speed == SPEED_10)
34809 + tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
34810 + else
34811 + tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
34812 + } else
34813 + tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
34815 + tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
34816 + if (tp->link_config.active_duplex == DUPLEX_HALF)
34817 + tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
34819 + tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
34820 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
34821 + if ((tp->led_mode == led_mode_link10) ||
34822 + (current_link_up == 1 &&
34823 + tp->link_config.active_speed == SPEED_10))
34824 + tp->mac_mode |= MAC_MODE_LINK_POLARITY;
34825 + } else {
34826 + if (current_link_up == 1)
34827 + tp->mac_mode |= MAC_MODE_LINK_POLARITY;
34828 + tw32(MAC_LED_CTRL, LED_CTRL_PHY_MODE_1);
34831 + /* ??? Without this setting Netgear GA302T PHY does not
34832 + * ??? send/receive packets...
34833 + * With this other PHYs cannot bring up the link
34834 + */
34835 + if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411 &&
34836 + tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {
34837 + tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;
34838 + tw32_carefully(MAC_MI_MODE, tp->mi_mode);
34841 + tw32_carefully(MAC_MODE, tp->mac_mode);
34843 + /* Link change polled. */
34844 + tw32_carefully(MAC_EVENT, 0);
34846 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
34847 + current_link_up == 1 &&
34848 + tp->link_config.active_speed == SPEED_1000 &&
34849 + ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ||
34850 + (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) {
34851 + udelay(120);
34852 + tw32_carefully(MAC_STATUS,
34853 + (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
34854 + tg3_write_mem(
34855 + NIC_SRAM_FIRMWARE_MBOX,
34856 + NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
34859 + if (current_link_up != tp->carrier_ok) {
34860 + tp->carrier_ok = current_link_up;
34861 + tg3_link_report(tp);
34864 + return 0;
34866 +#else
34867 +#define tg3_setup_copper_phy(TP) (-EINVAL)
34868 +#endif /* SUPPORT_COPPER_PHY */
34870 +#if SUPPORT_FIBER_PHY
34871 +struct tg3_fiber_aneginfo {
34872 + int state;
34873 +#define ANEG_STATE_UNKNOWN 0
34874 +#define ANEG_STATE_AN_ENABLE 1
34875 +#define ANEG_STATE_RESTART_INIT 2
34876 +#define ANEG_STATE_RESTART 3
34877 +#define ANEG_STATE_DISABLE_LINK_OK 4
34878 +#define ANEG_STATE_ABILITY_DETECT_INIT 5
34879 +#define ANEG_STATE_ABILITY_DETECT 6
34880 +#define ANEG_STATE_ACK_DETECT_INIT 7
34881 +#define ANEG_STATE_ACK_DETECT 8
34882 +#define ANEG_STATE_COMPLETE_ACK_INIT 9
34883 +#define ANEG_STATE_COMPLETE_ACK 10
34884 +#define ANEG_STATE_IDLE_DETECT_INIT 11
34885 +#define ANEG_STATE_IDLE_DETECT 12
34886 +#define ANEG_STATE_LINK_OK 13
34887 +#define ANEG_STATE_NEXT_PAGE_WAIT_INIT 14
34888 +#define ANEG_STATE_NEXT_PAGE_WAIT 15
34890 + uint32_t flags;
34891 +#define MR_AN_ENABLE 0x00000001
34892 +#define MR_RESTART_AN 0x00000002
34893 +#define MR_AN_COMPLETE 0x00000004
34894 +#define MR_PAGE_RX 0x00000008
34895 +#define MR_NP_LOADED 0x00000010
34896 +#define MR_TOGGLE_TX 0x00000020
34897 +#define MR_LP_ADV_FULL_DUPLEX 0x00000040
34898 +#define MR_LP_ADV_HALF_DUPLEX 0x00000080
34899 +#define MR_LP_ADV_SYM_PAUSE 0x00000100
34900 +#define MR_LP_ADV_ASYM_PAUSE 0x00000200
34901 +#define MR_LP_ADV_REMOTE_FAULT1 0x00000400
34902 +#define MR_LP_ADV_REMOTE_FAULT2 0x00000800
34903 +#define MR_LP_ADV_NEXT_PAGE 0x00001000
34904 +#define MR_TOGGLE_RX 0x00002000
34905 +#define MR_NP_RX 0x00004000
34907 +#define MR_LINK_OK 0x80000000
34909 + unsigned long link_time, cur_time;
34911 + uint32_t ability_match_cfg;
34912 + int ability_match_count;
34914 + char ability_match, idle_match, ack_match;
34916 + uint32_t txconfig, rxconfig;
34917 +#define ANEG_CFG_NP 0x00000080
34918 +#define ANEG_CFG_ACK 0x00000040
34919 +#define ANEG_CFG_RF2 0x00000020
34920 +#define ANEG_CFG_RF1 0x00000010
34921 +#define ANEG_CFG_PS2 0x00000001
34922 +#define ANEG_CFG_PS1 0x00008000
34923 +#define ANEG_CFG_HD 0x00004000
34924 +#define ANEG_CFG_FD 0x00002000
34925 +#define ANEG_CFG_INVAL 0x00001f06
34928 +#define ANEG_OK 0
34929 +#define ANEG_DONE 1
34930 +#define ANEG_TIMER_ENAB 2
34931 +#define ANEG_FAILED -1
34933 +#define ANEG_STATE_SETTLE_TIME 10000
34935 +static int tg3_fiber_aneg_smachine(struct tg3 *tp,
34936 + struct tg3_fiber_aneginfo *ap)
34938 + unsigned long delta;
34939 + uint32_t rx_cfg_reg;
34940 + int ret;
34942 + if (ap->state == ANEG_STATE_UNKNOWN) {
34943 + ap->rxconfig = 0;
34944 + ap->link_time = 0;
34945 + ap->cur_time = 0;
34946 + ap->ability_match_cfg = 0;
34947 + ap->ability_match_count = 0;
34948 + ap->ability_match = 0;
34949 + ap->idle_match = 0;
34950 + ap->ack_match = 0;
34952 + ap->cur_time++;
34954 + if (tr32(MAC_STATUS) & MAC_STATUS_RCVD_CFG) {
34955 + rx_cfg_reg = tr32(MAC_RX_AUTO_NEG);
34957 + if (rx_cfg_reg != ap->ability_match_cfg) {
34958 + ap->ability_match_cfg = rx_cfg_reg;
34959 + ap->ability_match = 0;
34960 + ap->ability_match_count = 0;
34961 + } else {
34962 + if (++ap->ability_match_count > 1) {
34963 + ap->ability_match = 1;
34964 + ap->ability_match_cfg = rx_cfg_reg;
34967 + if (rx_cfg_reg & ANEG_CFG_ACK)
34968 + ap->ack_match = 1;
34969 + else
34970 + ap->ack_match = 0;
34972 + ap->idle_match = 0;
34973 + } else {
34974 + ap->idle_match = 1;
34975 + ap->ability_match_cfg = 0;
34976 + ap->ability_match_count = 0;
34977 + ap->ability_match = 0;
34978 + ap->ack_match = 0;
34980 + rx_cfg_reg = 0;
34983 + ap->rxconfig = rx_cfg_reg;
34984 + ret = ANEG_OK;
34986 + switch(ap->state) {
34987 + case ANEG_STATE_UNKNOWN:
34988 + if (ap->flags & (MR_AN_ENABLE | MR_RESTART_AN))
34989 + ap->state = ANEG_STATE_AN_ENABLE;
34991 + /* fallthru */
34992 + case ANEG_STATE_AN_ENABLE:
34993 + ap->flags &= ~(MR_AN_COMPLETE | MR_PAGE_RX);
34994 + if (ap->flags & MR_AN_ENABLE) {
34995 + ap->link_time = 0;
34996 + ap->cur_time = 0;
34997 + ap->ability_match_cfg = 0;
34998 + ap->ability_match_count = 0;
34999 + ap->ability_match = 0;
35000 + ap->idle_match = 0;
35001 + ap->ack_match = 0;
35003 + ap->state = ANEG_STATE_RESTART_INIT;
35004 + } else {
35005 + ap->state = ANEG_STATE_DISABLE_LINK_OK;
35007 + break;
35009 + case ANEG_STATE_RESTART_INIT:
35010 + ap->link_time = ap->cur_time;
35011 + ap->flags &= ~(MR_NP_LOADED);
35012 + ap->txconfig = 0;
35013 + tw32(MAC_TX_AUTO_NEG, 0);
35014 + tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
35015 + tw32_carefully(MAC_MODE, tp->mac_mode);
35017 + ret = ANEG_TIMER_ENAB;
35018 + ap->state = ANEG_STATE_RESTART;
35020 + /* fallthru */
35021 + case ANEG_STATE_RESTART:
35022 + delta = ap->cur_time - ap->link_time;
35023 + if (delta > ANEG_STATE_SETTLE_TIME) {
35024 + ap->state = ANEG_STATE_ABILITY_DETECT_INIT;
35025 + } else {
35026 + ret = ANEG_TIMER_ENAB;
35028 + break;
35030 + case ANEG_STATE_DISABLE_LINK_OK:
35031 + ret = ANEG_DONE;
35032 + break;
35034 + case ANEG_STATE_ABILITY_DETECT_INIT:
35035 + ap->flags &= ~(MR_TOGGLE_TX);
35036 + ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1);
35037 + tw32(MAC_TX_AUTO_NEG, ap->txconfig);
35038 + tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
35039 + tw32_carefully(MAC_MODE, tp->mac_mode);
35041 + ap->state = ANEG_STATE_ABILITY_DETECT;
35042 + break;
35044 + case ANEG_STATE_ABILITY_DETECT:
35045 + if (ap->ability_match != 0 && ap->rxconfig != 0) {
35046 + ap->state = ANEG_STATE_ACK_DETECT_INIT;
35048 + break;
35050 + case ANEG_STATE_ACK_DETECT_INIT:
35051 + ap->txconfig |= ANEG_CFG_ACK;
35052 + tw32(MAC_TX_AUTO_NEG, ap->txconfig);
35053 + tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
35054 + tw32_carefully(MAC_MODE, tp->mac_mode);
35056 + ap->state = ANEG_STATE_ACK_DETECT;
35058 + /* fallthru */
35059 + case ANEG_STATE_ACK_DETECT:
35060 + if (ap->ack_match != 0) {
35061 + if ((ap->rxconfig & ~ANEG_CFG_ACK) ==
35062 + (ap->ability_match_cfg & ~ANEG_CFG_ACK)) {
35063 + ap->state = ANEG_STATE_COMPLETE_ACK_INIT;
35064 + } else {
35065 + ap->state = ANEG_STATE_AN_ENABLE;
35067 + } else if (ap->ability_match != 0 &&
35068 + ap->rxconfig == 0) {
35069 + ap->state = ANEG_STATE_AN_ENABLE;
35071 + break;
35073 + case ANEG_STATE_COMPLETE_ACK_INIT:
35074 + if (ap->rxconfig & ANEG_CFG_INVAL) {
35075 + ret = ANEG_FAILED;
35076 + break;
35078 + ap->flags &= ~(MR_LP_ADV_FULL_DUPLEX |
35079 + MR_LP_ADV_HALF_DUPLEX |
35080 + MR_LP_ADV_SYM_PAUSE |
35081 + MR_LP_ADV_ASYM_PAUSE |
35082 + MR_LP_ADV_REMOTE_FAULT1 |
35083 + MR_LP_ADV_REMOTE_FAULT2 |
35084 + MR_LP_ADV_NEXT_PAGE |
35085 + MR_TOGGLE_RX |
35086 + MR_NP_RX);
35087 + if (ap->rxconfig & ANEG_CFG_FD)
35088 + ap->flags |= MR_LP_ADV_FULL_DUPLEX;
35089 + if (ap->rxconfig & ANEG_CFG_HD)
35090 + ap->flags |= MR_LP_ADV_HALF_DUPLEX;
35091 + if (ap->rxconfig & ANEG_CFG_PS1)
35092 + ap->flags |= MR_LP_ADV_SYM_PAUSE;
35093 + if (ap->rxconfig & ANEG_CFG_PS2)
35094 + ap->flags |= MR_LP_ADV_ASYM_PAUSE;
35095 + if (ap->rxconfig & ANEG_CFG_RF1)
35096 + ap->flags |= MR_LP_ADV_REMOTE_FAULT1;
35097 + if (ap->rxconfig & ANEG_CFG_RF2)
35098 + ap->flags |= MR_LP_ADV_REMOTE_FAULT2;
35099 + if (ap->rxconfig & ANEG_CFG_NP)
35100 + ap->flags |= MR_LP_ADV_NEXT_PAGE;
35102 + ap->link_time = ap->cur_time;
35104 + ap->flags ^= (MR_TOGGLE_TX);
35105 + if (ap->rxconfig & 0x0008)
35106 + ap->flags |= MR_TOGGLE_RX;
35107 + if (ap->rxconfig & ANEG_CFG_NP)
35108 + ap->flags |= MR_NP_RX;
35109 + ap->flags |= MR_PAGE_RX;
35111 + ap->state = ANEG_STATE_COMPLETE_ACK;
35112 + ret = ANEG_TIMER_ENAB;
35113 + break;
35115 + case ANEG_STATE_COMPLETE_ACK:
35116 + if (ap->ability_match != 0 &&
35117 + ap->rxconfig == 0) {
35118 + ap->state = ANEG_STATE_AN_ENABLE;
35119 + break;
35121 + delta = ap->cur_time - ap->link_time;
35122 + if (delta > ANEG_STATE_SETTLE_TIME) {
35123 + if (!(ap->flags & (MR_LP_ADV_NEXT_PAGE))) {
35124 + ap->state = ANEG_STATE_IDLE_DETECT_INIT;
35125 + } else {
35126 + if ((ap->txconfig & ANEG_CFG_NP) == 0 &&
35127 + !(ap->flags & MR_NP_RX)) {
35128 + ap->state = ANEG_STATE_IDLE_DETECT_INIT;
35129 + } else {
35130 + ret = ANEG_FAILED;
35134 + break;
35136 + case ANEG_STATE_IDLE_DETECT_INIT:
35137 + ap->link_time = ap->cur_time;
35138 + tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
35139 + tw32_carefully(MAC_MODE, tp->mac_mode);
35141 + ap->state = ANEG_STATE_IDLE_DETECT;
35142 + ret = ANEG_TIMER_ENAB;
35143 + break;
35145 + case ANEG_STATE_IDLE_DETECT:
35146 + if (ap->ability_match != 0 &&
35147 + ap->rxconfig == 0) {
35148 + ap->state = ANEG_STATE_AN_ENABLE;
35149 + break;
35151 + delta = ap->cur_time - ap->link_time;
35152 + if (delta > ANEG_STATE_SETTLE_TIME) {
35153 + /* XXX another gem from the Broadcom driver :( */
35154 + ap->state = ANEG_STATE_LINK_OK;
35156 + break;
35158 + case ANEG_STATE_LINK_OK:
35159 + ap->flags |= (MR_AN_COMPLETE | MR_LINK_OK);
35160 + ret = ANEG_DONE;
35161 + break;
35163 + case ANEG_STATE_NEXT_PAGE_WAIT_INIT:
35164 + /* ??? unimplemented */
35165 + break;
35167 + case ANEG_STATE_NEXT_PAGE_WAIT:
35168 + /* ??? unimplemented */
35169 + break;
35171 + default:
35172 + ret = ANEG_FAILED;
35173 + break;
35174 + };
35176 + return ret;
35179 +static int tg3_setup_fiber_phy(struct tg3 *tp)
35181 + uint32_t orig_pause_cfg;
35182 + uint16_t orig_active_speed;
35183 + uint8_t orig_active_duplex;
35184 + int current_link_up;
35185 + int i;
35187 + orig_pause_cfg =
35188 + (tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
35189 + TG3_FLAG_TX_PAUSE));
35190 + orig_active_speed = tp->link_config.active_speed;
35191 + orig_active_duplex = tp->link_config.active_duplex;
35193 + tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
35194 + tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
35195 + tw32_carefully(MAC_MODE, tp->mac_mode);
35197 + /* Reset when initting first time or we have a link. */
35198 + if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) ||
35199 + (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
35200 + /* Set PLL lock range. */
35201 + tg3_writephy(tp, 0x16, 0x8007);
35203 + /* SW reset */
35204 + tg3_writephy(tp, MII_BMCR, BMCR_RESET);
35206 + /* Wait for reset to complete. */
35207 + mdelay(5);
35209 + /* Config mode; select PMA/Ch 1 regs. */
35210 + tg3_writephy(tp, 0x10, 0x8411);
35212 + /* Enable auto-lock and comdet, select txclk for tx. */
35213 + tg3_writephy(tp, 0x11, 0x0a10);
35215 + tg3_writephy(tp, 0x18, 0x00a0);
35216 + tg3_writephy(tp, 0x16, 0x41ff);
35218 + /* Assert and deassert POR. */
35219 + tg3_writephy(tp, 0x13, 0x0400);
35220 + udelay(40);
35221 + tg3_writephy(tp, 0x13, 0x0000);
35223 + tg3_writephy(tp, 0x11, 0x0a50);
35224 + udelay(40);
35225 + tg3_writephy(tp, 0x11, 0x0a10);
35227 + /* Wait for signal to stabilize */
35228 + mdelay(150);
35230 + /* Deselect the channel register so we can read the PHYID
35231 + * later.
35232 + */
35233 + tg3_writephy(tp, 0x10, 0x8011);
35236 + /* Disable link change interrupt. */
35237 + tw32_carefully(MAC_EVENT, 0);
35239 + current_link_up = 0;
35240 + if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) {
35241 + if (!(tp->tg3_flags & TG3_FLAG_GOT_SERDES_FLOWCTL)) {
35242 + struct tg3_fiber_aneginfo aninfo;
35243 + int status = ANEG_FAILED;
35244 + unsigned int tick;
35245 + uint32_t tmp;
35247 + memset(&aninfo, 0, sizeof(aninfo));
35248 + aninfo.flags |= (MR_AN_ENABLE);
35250 + tw32(MAC_TX_AUTO_NEG, 0);
35252 + tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
35253 + tw32_carefully(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
35255 + tw32_carefully(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
35257 + aninfo.state = ANEG_STATE_UNKNOWN;
35258 + aninfo.cur_time = 0;
35259 + tick = 0;
35260 + while (++tick < 195000) {
35261 + status = tg3_fiber_aneg_smachine(tp, &aninfo);
35262 + if (status == ANEG_DONE ||
35263 + status == ANEG_FAILED)
35264 + break;
35266 + udelay(1);
35269 + tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
35270 + tw32_carefully(MAC_MODE, tp->mac_mode);
35272 + if (status == ANEG_DONE &&
35273 + (aninfo.flags &
35274 + (MR_AN_COMPLETE | MR_LINK_OK |
35275 + MR_LP_ADV_FULL_DUPLEX))) {
35276 + uint32_t local_adv, remote_adv;
35278 + local_adv = ADVERTISE_PAUSE_CAP;
35279 + remote_adv = 0;
35280 + if (aninfo.flags & MR_LP_ADV_SYM_PAUSE)
35281 + remote_adv |= LPA_PAUSE_CAP;
35282 + if (aninfo.flags & MR_LP_ADV_ASYM_PAUSE)
35283 + remote_adv |= LPA_PAUSE_ASYM;
35285 + tg3_setup_flow_control(tp, local_adv, remote_adv);
35287 + tp->tg3_flags |=
35288 + TG3_FLAG_GOT_SERDES_FLOWCTL;
35289 + current_link_up = 1;
35291 + for (i = 0; i < 60; i++) {
35292 + udelay(20);
35293 + tw32_carefully(MAC_STATUS,
35294 + (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
35295 + if ((tr32(MAC_STATUS) &
35296 + (MAC_STATUS_SYNC_CHANGED |
35297 + MAC_STATUS_CFG_CHANGED)) == 0)
35298 + break;
35300 + if (current_link_up == 0 &&
35301 + (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
35302 + current_link_up = 1;
35304 + } else {
35305 + /* Forcing 1000FD link up. */
35306 + current_link_up = 1;
35310 + tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
35311 + tw32_carefully(MAC_MODE, tp->mac_mode);
35313 + tp->hw_status->status =
35314 + (SD_STATUS_UPDATED |
35315 + (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
35317 + for (i = 0; i < 100; i++) {
35318 + udelay(20);
35319 + tw32_carefully(MAC_STATUS,
35320 + (MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
35321 + if ((tr32(MAC_STATUS) &
35322 + (MAC_STATUS_SYNC_CHANGED |
35323 + MAC_STATUS_CFG_CHANGED)) == 0)
35324 + break;
35327 + if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0)
35328 + current_link_up = 0;
35330 + if (current_link_up == 1) {
35331 + tp->link_config.active_speed = SPEED_1000;
35332 + tp->link_config.active_duplex = DUPLEX_FULL;
35333 + } else {
35334 + tp->link_config.active_speed = SPEED_INVALID;
35335 + tp->link_config.active_duplex = DUPLEX_INVALID;
35338 + if (current_link_up != tp->carrier_ok) {
35339 + tp->carrier_ok = current_link_up;
35340 + tg3_link_report(tp);
35341 + } else {
35342 + uint32_t now_pause_cfg =
35343 + tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
35344 + TG3_FLAG_TX_PAUSE);
35345 + if (orig_pause_cfg != now_pause_cfg ||
35346 + orig_active_speed != tp->link_config.active_speed ||
35347 + orig_active_duplex != tp->link_config.active_duplex)
35348 + tg3_link_report(tp);
35351 + if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) {
35352 + tw32_carefully(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY);
35353 + if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
35354 + tw32_carefully(MAC_MODE, tp->mac_mode);
35358 + return 0;
35360 +#else
35361 +#define tg3_setup_fiber_phy(TP) (-EINVAL)
35362 +#endif /* SUPPORT_FIBER_PHY */
35364 +static int tg3_setup_phy(struct tg3 *tp)
35366 + int err;
35368 + if (tp->phy_id == PHY_ID_SERDES) {
35369 + err = tg3_setup_fiber_phy(tp);
35370 + } else {
35371 + err = tg3_setup_copper_phy(tp);
35374 + if (tp->link_config.active_speed == SPEED_1000 &&
35375 + tp->link_config.active_duplex == DUPLEX_HALF)
35376 + tw32(MAC_TX_LENGTHS,
35377 + ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
35378 + (6 << TX_LENGTHS_IPG_SHIFT) |
35379 + (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
35380 + else
35381 + tw32(MAC_TX_LENGTHS,
35382 + ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
35383 + (6 << TX_LENGTHS_IPG_SHIFT) |
35384 + (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
35386 + return err;
35390 +#define MAX_WAIT_CNT 1000
35392 +/* To stop a block, clear the enable bit and poll till it
35393 + * clears.
35394 + */
35395 +static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, uint32_t enable_bit)
35397 + unsigned int i;
35398 + uint32_t val;
35400 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
35401 + switch(ofs) {
35402 + case RCVLSC_MODE:
35403 + case DMAC_MODE:
35404 + case MBFREE_MODE:
35405 + case BUFMGR_MODE:
35406 + case MEMARB_MODE:
35407 + /* We can't enable/disable these bits of the
35408 + * 5705, just say success.
35409 + */
35410 + return 0;
35411 + default:
35412 + break;
35415 + val = tr32(ofs);
35416 + val &= ~enable_bit;
35417 + tw32(ofs, val);
35418 + tr32(ofs);
35420 + for (i = 0; i < MAX_WAIT_CNT; i++) {
35421 + udelay(100);
35422 + val = tr32(ofs);
35423 + if ((val & enable_bit) == 0)
35424 + break;
35427 + if (i == MAX_WAIT_CNT) {
35428 + printf("tg3_stop_block timed out, ofs=%lx enable_bit=%x\n",
35429 + ofs, enable_bit);
35430 + return -ENODEV;
35433 + return 0;
35436 +static int tg3_abort_hw(struct tg3 *tp)
35438 + int i, err;
35440 + tg3_disable_ints(tp);
35442 + tp->rx_mode &= ~RX_MODE_ENABLE;
35443 + tw32_carefully(MAC_RX_MODE, tp->rx_mode);
35445 + err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE);
35446 + err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE);
35447 + err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE);
35448 + err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE);
35449 + err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE);
35450 + err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE);
35452 + err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE);
35453 + err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE);
35454 + err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
35455 + err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE);
35456 + err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
35457 + err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE);
35458 + if (err)
35459 + goto out;
35461 + tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
35462 + tw32_carefully(MAC_MODE, tp->mac_mode);
35464 + tp->tx_mode &= ~TX_MODE_ENABLE;
35465 + tw32_carefully(MAC_TX_MODE, tp->tx_mode);
35467 + for (i = 0; i < MAX_WAIT_CNT; i++) {
35468 + udelay(100);
35469 + if (!(tr32(MAC_TX_MODE) & TX_MODE_ENABLE))
35470 + break;
35472 + if (i >= MAX_WAIT_CNT) {
35473 + printf("tg3_abort_hw timed out TX_MODE_ENABLE will not clear MAC_TX_MODE=%x\n",
35474 + tr32(MAC_TX_MODE));
35475 + return -ENODEV;
35478 + err = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE);
35479 + err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE);
35480 + err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE);
35482 + tw32(FTQ_RESET, 0xffffffff);
35483 + tw32(FTQ_RESET, 0x00000000);
35485 + err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE);
35486 + err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE);
35487 + if (err)
35488 + goto out;
35490 + memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
35492 +out:
35493 + return err;
35496 +static void tg3_chip_reset(struct tg3 *tp)
35498 + uint32_t val;
35500 + if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
35501 + /* Force NVRAM to settle.
35502 + * This deals with a chip bug which can result in EEPROM
35503 + * corruption.
35504 + */
35505 + if (tp->tg3_flags & TG3_FLAG_NVRAM) {
35506 + int i;
35508 + tw32(NVRAM_SWARB, SWARB_REQ_SET1);
35509 + for (i = 0; i < 100000; i++) {
35510 + if (tr32(NVRAM_SWARB) & SWARB_GNT1)
35511 + break;
35512 + udelay(10);
35516 + /* In Etherboot we don't need to worry about the 5701
35517 + * REG_WRITE_BUG because we do all register writes indirectly.
35518 + */
35520 + /* do the reset */
35521 + val = GRC_MISC_CFG_CORECLK_RESET;
35522 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
35523 + val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
35524 + tw32(GRC_MISC_CFG, val);
35526 + /* Flush PCI posted writes. The normal MMIO registers
35527 + * are inaccessible at this time so this is the only
35528 + * way to make this reliably. I tried to use indirect
35529 + * register read/write but this upset some 5701 variants.
35530 + */
35531 + pci_read_config_dword(tp->pdev, PCI_COMMAND, &val);
35533 + udelay(120);
35535 + /* Re-enable indirect register accesses. */
35536 + pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
35537 + tp->misc_host_ctrl);
35539 + /* Set MAX PCI retry to zero. */
35540 + val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);
35541 + if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
35542 + (tp->tg3_flags & TG3_FLAG_PCIX_MODE))
35543 + val |= PCISTATE_RETRY_SAME_DMA;
35544 + pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
35546 + pci_restore_state(tp->pdev, tp->pci_cfg_state);
35548 + /* Make sure PCI-X relaxed ordering bit is clear. */
35549 + pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
35550 + val &= ~PCIX_CAPS_RELAXED_ORDERING;
35551 + pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
35553 + tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
35555 + if (((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0) &&
35556 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
35557 + tp->pci_clock_ctrl |=
35558 + (CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE);
35559 + tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
35562 + tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
35565 +static void tg3_stop_fw(struct tg3 *tp)
35567 + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
35568 + uint32_t val;
35569 + int i;
35571 + tg3_write_mem(NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
35572 + val = tr32(GRC_RX_CPU_EVENT);
35573 + val |= (1 << 14);
35574 + tw32(GRC_RX_CPU_EVENT, val);
35576 + /* Wait for RX cpu to ACK the event. */
35577 + for (i = 0; i < 100; i++) {
35578 + if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14)))
35579 + break;
35580 + udelay(1);
35585 +static int tg3_restart_fw(struct tg3 *tp, uint32_t state)
35587 + uint32_t val;
35588 + int i;
35590 + tg3_write_mem(NIC_SRAM_FIRMWARE_MBOX,
35591 + NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
35592 + /* Wait for firmware initialization to complete. */
35593 + for (i = 0; i < 100000; i++) {
35594 + tg3_read_mem(NIC_SRAM_FIRMWARE_MBOX, &val);
35595 + if (val == (uint32_t) ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
35596 + break;
35597 + udelay(10);
35599 + if (i >= 100000 &&
35600 + !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
35601 + printf("Firmware will not restart magic=%x\n",
35602 + val);
35603 + return -ENODEV;
35605 + if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
35606 + state = DRV_STATE_SUSPEND;
35608 + tg3_write_mem(NIC_SRAM_FW_DRV_STATE_MBOX, state);
35609 + return 0;
35612 +static int tg3_halt(struct tg3 *tp)
35614 + tg3_stop_fw(tp);
35615 + tg3_abort_hw(tp);
35616 + tg3_chip_reset(tp);
35617 + return tg3_restart_fw(tp, DRV_STATE_UNLOAD);
35620 +static void __tg3_set_mac_addr(struct tg3 *tp)
35622 + uint32_t addr_high, addr_low;
35623 + int i;
35625 + addr_high = ((tp->nic->node_addr[0] << 8) |
35626 + tp->nic->node_addr[1]);
35627 + addr_low = ((tp->nic->node_addr[2] << 24) |
35628 + (tp->nic->node_addr[3] << 16) |
35629 + (tp->nic->node_addr[4] << 8) |
35630 + (tp->nic->node_addr[5] << 0));
35631 + for (i = 0; i < 4; i++) {
35632 + tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
35633 + tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
35636 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
35637 + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
35638 + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705)) {
35639 + for(i = 0; i < 12; i++) {
35640 + tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
35641 + tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
35644 + addr_high = (tp->nic->node_addr[0] +
35645 + tp->nic->node_addr[1] +
35646 + tp->nic->node_addr[2] +
35647 + tp->nic->node_addr[3] +
35648 + tp->nic->node_addr[4] +
35649 + tp->nic->node_addr[5]) &
35650 + TX_BACKOFF_SEED_MASK;
35651 + tw32(MAC_TX_BACKOFF_SEED, addr_high);
35654 +static void tg3_set_bdinfo(struct tg3 *tp, uint32_t bdinfo_addr,
35655 + dma_addr_t mapping, uint32_t maxlen_flags,
35656 + uint32_t nic_addr)
35658 + tg3_write_mem((bdinfo_addr +
35659 + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH),
35660 + ((uint64_t) mapping >> 32));
35661 + tg3_write_mem((bdinfo_addr +
35662 + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW),
35663 + ((uint64_t) mapping & 0xffffffff));
35664 + tg3_write_mem((bdinfo_addr +
35665 + TG3_BDINFO_MAXLEN_FLAGS),
35666 + maxlen_flags);
35667 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
35668 + tg3_write_mem((bdinfo_addr + TG3_BDINFO_NIC_ADDR), nic_addr);
35673 +static void tg3_init_rings(struct tg3 *tp)
35675 + unsigned i;
35677 + /* Zero out the tg3 variables */
35678 + memset(&tg3_bss, 0, sizeof(tg3_bss));
35679 + tp->rx_std = &tg3_bss.rx_std[0];
35680 + tp->rx_rcb = &tg3_bss.rx_rcb[0];
35681 + tp->tx_ring = &tg3_bss.tx_ring[0];
35682 + tp->hw_status = &tg3_bss.hw_status;
35683 + tp->hw_stats = &tg3_bss.hw_stats;
35684 + tp->mac_mode = 0;
35687 + /* Initialize tx/rx rings for packet processing.
35689 + * The chip has been shut down and the driver detached from
35690 + * the networking, so no interrupts or new tx packets will
35691 + * end up in the driver.
35692 + */
35694 + /* Initialize invariants of the rings, we only set this
35695 + * stuff once. This works because the card does not
35696 + * write into the rx buffer posting rings.
35697 + */
35698 + for (i = 0; i < TG3_RX_RING_SIZE; i++) {
35699 + struct tg3_rx_buffer_desc *rxd;
35701 + rxd = &tp->rx_std[i];
35702 + rxd->idx_len = (RX_PKT_BUF_SZ - 2 - 64) << RXD_LEN_SHIFT;
35703 + rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
35704 + rxd->opaque = (RXD_OPAQUE_RING_STD | (i << RXD_OPAQUE_INDEX_SHIFT));
35706 + /* Note where the receive buffer for the ring is placed */
35707 + rxd->addr_hi = 0;
35708 + rxd->addr_lo = virt_to_bus(
35709 + &tg3_bss.rx_bufs[i%TG3_DEF_RX_RING_PENDING][2]);
35713 +#define TG3_WRITE_SETTINGS(TABLE) \
35714 +do { \
35715 + const uint32_t *_table, *_end; \
35716 + _table = TABLE; \
35717 + _end = _table + sizeof(TABLE)/sizeof(TABLE[0]); \
35718 + for(; _table < _end; _table += 2) { \
35719 + tw32(_table[0], _table[1]); \
35720 + } \
35721 +} while(0)
35724 +/* initialize/reset the tg3 */
35725 +static int tg3_setup_hw(struct tg3 *tp)
35727 + uint32_t val, rdmac_mode;
35728 + int i, err, limit;
35730 + /* Simply don't support setups with extremly buggy firmware in etherboot */
35731 + if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
35732 + printf("Error 5701_A0 firmware bug detected\n");
35733 + return -EINVAL;
35736 + tg3_disable_ints(tp);
35738 + /* Originally this was all in tg3_init_hw */
35740 + /* Force the chip into D0. */
35741 + tg3_set_power_state_0(tp);
35743 + tg3_switch_clocks(tp);
35745 + tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
35748 + /* Originally this was all in tg3_reset_hw */
35750 + tg3_stop_fw(tp);
35752 + /* No need to call tg3_abort_hw here, it is called before tg3_setup_hw. */
35754 + tg3_chip_reset(tp);
35756 + tw32(GRC_MODE, tp->grc_mode); /* Redundant? */
35758 + err = tg3_restart_fw(tp, DRV_STATE_START);
35759 + if (err)
35760 + return err;
35762 + if (tp->phy_id == PHY_ID_SERDES) {
35763 + tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
35765 + tw32_carefully(MAC_MODE, tp->mac_mode);
35768 + /* This works around an issue with Athlon chipsets on
35769 + * B3 tigon3 silicon. This bit has no effect on any
35770 + * other revision.
35771 + */
35772 + tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT;
35773 + tw32_carefully(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
35775 + if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
35776 + (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
35777 + val = tr32(TG3PCI_PCISTATE);
35778 + val |= PCISTATE_RETRY_SAME_DMA;
35779 + tw32(TG3PCI_PCISTATE, val);
35782 + /* Descriptor ring init may make accesses to the
35783 + * NIC SRAM area to setup the TX descriptors, so we
35784 + * can only do this after the hardware has been
35785 + * successfully reset.
35786 + */
35787 + tg3_init_rings(tp);
35789 + /* Clear statistics/status block in chip */
35790 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
35791 + for (i = NIC_SRAM_STATS_BLK;
35792 + i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
35793 + i += sizeof(uint32_t)) {
35794 + tg3_write_mem(i, 0);
35795 + udelay(40);
35799 + /* This value is determined during the probe time DMA
35800 + * engine test, tg3_setup_dma.
35801 + */
35802 + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
35804 + tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS |
35805 + GRC_MODE_4X_NIC_SEND_RINGS |
35806 + GRC_MODE_NO_TX_PHDR_CSUM |
35807 + GRC_MODE_NO_RX_PHDR_CSUM);
35808 + tp->grc_mode |= GRC_MODE_HOST_SENDBDS;
35809 + tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;
35810 + tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM;
35812 + tw32(GRC_MODE,
35813 + tp->grc_mode |
35814 + (GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
35816 + /* Setup the timer prescalar register. Clock is always 66Mhz. */
35817 + tw32(GRC_MISC_CFG,
35818 + (65 << GRC_MISC_CFG_PRESCALAR_SHIFT));
35820 + /* Initialize MBUF/DESC pool. */
35821 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
35822 + tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
35823 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
35824 + tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64);
35825 + else
35826 + tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
35827 + tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
35828 + tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
35830 + if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) {
35831 + tw32(BUFMGR_MB_RDMA_LOW_WATER,
35832 + tp->bufmgr_config.mbuf_read_dma_low_water);
35833 + tw32(BUFMGR_MB_MACRX_LOW_WATER,
35834 + tp->bufmgr_config.mbuf_mac_rx_low_water);
35835 + tw32(BUFMGR_MB_HIGH_WATER,
35836 + tp->bufmgr_config.mbuf_high_water);
35837 + } else {
35838 + tw32(BUFMGR_MB_RDMA_LOW_WATER,
35839 + tp->bufmgr_config.mbuf_read_dma_low_water_jumbo);
35840 + tw32(BUFMGR_MB_MACRX_LOW_WATER,
35841 + tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo);
35842 + tw32(BUFMGR_MB_HIGH_WATER,
35843 + tp->bufmgr_config.mbuf_high_water_jumbo);
35845 + tw32(BUFMGR_DMA_LOW_WATER,
35846 + tp->bufmgr_config.dma_low_water);
35847 + tw32(BUFMGR_DMA_HIGH_WATER,
35848 + tp->bufmgr_config.dma_high_water);
35850 + tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
35851 + for (i = 0; i < 2000; i++) {
35852 + if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
35853 + break;
35854 + udelay(10);
35856 + if (i >= 2000) {
35857 + printf("tg3_setup_hw cannot enable BUFMGR\n");
35858 + return -ENODEV;
35861 + tw32(FTQ_RESET, 0xffffffff);
35862 + tw32(FTQ_RESET, 0x00000000);
35863 + for (i = 0; i < 2000; i++) {
35864 + if (tr32(FTQ_RESET) == 0x00000000)
35865 + break;
35866 + udelay(10);
35868 + if (i >= 2000) {
35869 + printf("tg3_setup_hw cannot reset FTQ\n");
35870 + return -ENODEV;
35873 + /* Initialize TG3_BDINFO's at:
35874 + * RCVDBDI_STD_BD: standard eth size rx ring
35875 + * RCVDBDI_JUMBO_BD: jumbo frame rx ring
35876 + * RCVDBDI_MINI_BD: small frame rx ring (??? does not work)
35878 + * like so:
35879 + * TG3_BDINFO_HOST_ADDR: high/low parts of DMA address of ring
35880 + * TG3_BDINFO_MAXLEN_FLAGS: (rx max buffer size << 16) |
35881 + * ring attribute flags
35882 + * TG3_BDINFO_NIC_ADDR: location of descriptors in nic SRAM
35884 + * Standard receive ring @ NIC_SRAM_RX_BUFFER_DESC, 512 entries.
35885 + * Jumbo receive ring @ NIC_SRAM_RX_JUMBO_BUFFER_DESC, 256 entries.
35887 + * ??? No space allocated for mini receive ring? :(
35889 + * The size of each ring is fixed in the firmware, but the location is
35890 + * configurable.
35891 + */
35893 + static const uint32_t table_all[] = {
35894 + /* Setup replenish thresholds. */
35895 + RCVBDI_STD_THRESH, TG3_DEF_RX_RING_PENDING / 8,
35897 + /* Etherboot lives below 4GB */
35898 + RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,
35899 + RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC,
35900 + };
35901 + static const uint32_t table_not_5705[] = {
35902 + /* Buffer maximum length */
35903 + RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT,
35905 + /* Disable the mini frame rx ring */
35906 + RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED,
35908 + /* Disable the jumbo frame rx ring */
35909 + RCVBDI_JUMBO_THRESH, 0,
35910 + RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED,
35913 + };
35914 + TG3_WRITE_SETTINGS(table_all);
35915 + tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
35916 + virt_to_bus(tp->rx_std));
35917 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
35918 + tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
35919 + RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT);
35920 + } else {
35921 + TG3_WRITE_SETTINGS(table_not_5705);
35926 + /* There is only one send ring on 5705, no need to explicitly
35927 + * disable the others.
35928 + */
35929 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
35930 + /* Clear out send RCB ring in SRAM. */
35931 + for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE)
35932 + tg3_write_mem(i + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED);
35935 + tp->tx_prod = 0;
35936 + tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
35937 + tw32_mailbox2(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
35939 + tg3_set_bdinfo(tp,
35940 + NIC_SRAM_SEND_RCB,
35941 + virt_to_bus(tp->tx_ring),
35942 + (TG3_TX_RING_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT),
35943 + NIC_SRAM_TX_BUFFER_DESC);
35945 + /* There is only one receive return ring on 5705, no need to explicitly
35946 + * disable the others.
35947 + */
35948 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
35949 + for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; i += TG3_BDINFO_SIZE) {
35950 + tg3_write_mem(i + TG3_BDINFO_MAXLEN_FLAGS,
35951 + BDINFO_FLAGS_DISABLED);
35955 + tp->rx_rcb_ptr = 0;
35956 + tw32_mailbox2(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0);
35958 + tg3_set_bdinfo(tp,
35959 + NIC_SRAM_RCV_RET_RCB,
35960 + virt_to_bus(tp->rx_rcb),
35961 + (TG3_RX_RCB_RING_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT),
35962 + 0);
35964 + tp->rx_std_ptr = TG3_DEF_RX_RING_PENDING;
35965 + tw32_mailbox2(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
35966 + tp->rx_std_ptr);
35968 + tw32_mailbox2(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, 0);
35970 + /* Initialize MAC address and backoff seed. */
35971 + __tg3_set_mac_addr(tp);
35973 + /* Calculate RDMAC_MODE setting early, we need it to determine
35974 + * the RCVLPC_STATE_ENABLE mask.
35975 + */
35976 + rdmac_mode = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
35977 + RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
35978 + RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
35979 + RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
35980 + RDMAC_MODE_LNGREAD_ENAB);
35981 + if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
35982 + rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
35983 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
35984 + if (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
35985 + if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
35986 + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
35987 + rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
35992 + /* Setup host coalescing engine. */
35993 + tw32(HOSTCC_MODE, 0);
35994 + for (i = 0; i < 2000; i++) {
35995 + if (!(tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE))
35996 + break;
35997 + udelay(10);
36000 + tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
36001 + MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
36002 + tw32_carefully(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
36004 + tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
36005 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
36006 + tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
36007 + GRC_LCLCTRL_GPIO_OUTPUT1);
36008 + tw32_carefully(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
36010 + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
36011 + tr32(MAILBOX_INTERRUPT_0);
36013 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
36014 + tw32_carefully(DMAC_MODE, DMAC_MODE_ENABLE);
36017 + val = ( WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB |
36018 + WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB |
36019 + WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB |
36020 + WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB |
36021 + WDMAC_MODE_LNGREAD_ENAB);
36022 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) &&
36023 + ((tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) != 0) &&
36024 + !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
36025 + val |= WDMAC_MODE_RX_ACCEL;
36027 + tw32_carefully(WDMAC_MODE, val);
36029 + if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
36030 + val = tr32(TG3PCI_X_CAPS);
36031 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
36032 + val &= PCIX_CAPS_BURST_MASK;
36033 + val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
36034 + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
36035 + val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
36036 + val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
36037 + if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
36038 + val |= (tp->split_mode_max_reqs <<
36039 + PCIX_CAPS_SPLIT_SHIFT);
36041 + tw32(TG3PCI_X_CAPS, val);
36044 + tw32_carefully(RDMAC_MODE, rdmac_mode);
36046 + static const uint32_t table_all[] = {
36047 + /* MTU + ethernet header + FCS + optional VLAN tag */
36048 + MAC_RX_MTU_SIZE, ETH_MAX_MTU + ETH_HLEN + 8,
36050 + /* The slot time is changed by tg3_setup_phy if we
36051 + * run at gigabit with half duplex.
36052 + */
36053 + MAC_TX_LENGTHS,
36054 + (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
36055 + (6 << TX_LENGTHS_IPG_SHIFT) |
36056 + (32 << TX_LENGTHS_SLOT_TIME_SHIFT),
36058 + /* Receive rules. */
36059 + MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS,
36060 + RCVLPC_CONFIG, 0x0181,
36062 + /* Receive/send statistics. */
36063 + RCVLPC_STATS_ENABLE, 0xffffff,
36064 + RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE,
36065 + SNDDATAI_STATSENAB, 0xffffff,
36066 + SNDDATAI_STATSCTRL, (SNDDATAI_SCTRL_ENABLE |SNDDATAI_SCTRL_FASTUPD),
36068 + /* Host coalescing engine */
36069 + HOSTCC_RXCOL_TICKS, 0,
36070 + HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS,
36071 + HOSTCC_RXMAX_FRAMES, 1,
36072 + HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES,
36073 + HOSTCC_RXCOAL_MAXF_INT, 1,
36074 + HOSTCC_TXCOAL_MAXF_INT, 0,
36076 + /* Status/statistics block address. */
36077 + /* Etherboot lives below 4GB, so HIGH == 0 */
36078 + HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,
36080 + /* No need to enable 32byte coalesce mode. */
36081 + HOSTCC_MODE, HOSTCC_MODE_ENABLE | 0,
36083 + RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE,
36084 + RCVLPC_MODE, RCVLPC_MODE_ENABLE,
36086 + RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE,
36088 + SNDDATAC_MODE, SNDDATAC_MODE_ENABLE,
36089 + SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE,
36090 + RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB,
36091 + RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ,
36092 + SNDDATAI_MODE, SNDDATAI_MODE_ENABLE,
36093 + SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE,
36094 + SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE,
36096 + /* Accept all multicast frames. */
36097 + MAC_HASH_REG_0, 0xffffffff,
36098 + MAC_HASH_REG_1, 0xffffffff,
36099 + MAC_HASH_REG_2, 0xffffffff,
36100 + MAC_HASH_REG_3, 0xffffffff,
36101 + };
36102 + static const uint32_t table_not_5705[] = {
36103 + /* Host coalescing engine */
36104 + HOSTCC_RXCOAL_TICK_INT, 0,
36105 + HOSTCC_TXCOAL_TICK_INT, 0,
36107 + /* Status/statistics block address. */
36108 + /* Etherboot lives below 4GB, so HIGH == 0 */
36109 + HOSTCC_STAT_COAL_TICKS, DEFAULT_STAT_COAL_TICKS,
36110 + HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,
36111 + HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK,
36112 + HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK,
36114 + RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE,
36116 + MBFREE_MODE, MBFREE_MODE_ENABLE,
36117 + };
36118 + TG3_WRITE_SETTINGS(table_all);
36119 + tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
36120 + virt_to_bus(tp->hw_stats));
36121 + tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
36122 + virt_to_bus(tp->hw_status));
36123 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
36124 + TG3_WRITE_SETTINGS(table_not_5705);
36128 + tp->tx_mode = TX_MODE_ENABLE;
36129 + tw32_carefully(MAC_TX_MODE, tp->tx_mode);
36131 + tp->rx_mode = RX_MODE_ENABLE;
36132 + tw32_carefully(MAC_RX_MODE, tp->rx_mode);
36134 + tp->mi_mode = MAC_MI_MODE_BASE;
36135 + tw32_carefully(MAC_MI_MODE, tp->mi_mode);
36137 + tw32(MAC_LED_CTRL, 0);
36138 + tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
36139 + if (tp->phy_id == PHY_ID_SERDES) {
36140 + tw32_carefully(MAC_RX_MODE, RX_MODE_RESET);
36142 + tp->rx_mode |= RX_MODE_KEEP_VLAN_TAG; /* drop tagged vlan packets */
36143 + tw32_carefully(MAC_RX_MODE, tp->rx_mode);
36145 + if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
36146 + tw32(MAC_SERDES_CFG, 0x616000);
36148 + /* Prevent chip from dropping frames when flow control
36149 + * is enabled.
36150 + */
36151 + tw32(MAC_LOW_WMARK_MAX_RX_FRAME, 2);
36152 + tr32(MAC_LOW_WMARK_MAX_RX_FRAME);
36154 + err = tg3_setup_phy(tp);
36156 + /* Ignore CRC stats */
36158 + /* Initialize receive rules. */
36159 + tw32(MAC_RCV_RULE_0, 0xc2000000 & RCV_RULE_DISABLE_MASK);
36160 + tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK);
36161 + tw32(MAC_RCV_RULE_1, 0x86000004 & RCV_RULE_DISABLE_MASK);
36162 + tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
36164 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
36165 + limit = 8;
36166 + else
36167 + limit = 16;
36168 + if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
36169 + limit -= 4;
36170 + switch (limit) {
36171 + case 16: tw32(MAC_RCV_RULE_15, 0); tw32(MAC_RCV_VALUE_15, 0);
36172 + case 15: tw32(MAC_RCV_RULE_14, 0); tw32(MAC_RCV_VALUE_14, 0);
36173 + case 14: tw32(MAC_RCV_RULE_13, 0); tw32(MAC_RCV_VALUE_13, 0);
36174 + case 13: tw32(MAC_RCV_RULE_12, 0); tw32(MAC_RCV_VALUE_12, 0);
36175 + case 12: tw32(MAC_RCV_RULE_11, 0); tw32(MAC_RCV_VALUE_11, 0);
36176 + case 11: tw32(MAC_RCV_RULE_10, 0); tw32(MAC_RCV_VALUE_10, 0);
36177 + case 10: tw32(MAC_RCV_RULE_9, 0); tw32(MAC_RCV_VALUE_9, 0);
36178 + case 9: tw32(MAC_RCV_RULE_8, 0); tw32(MAC_RCV_VALUE_8, 0);
36179 + case 8: tw32(MAC_RCV_RULE_7, 0); tw32(MAC_RCV_VALUE_7, 0);
36180 + case 7: tw32(MAC_RCV_RULE_6, 0); tw32(MAC_RCV_VALUE_6, 0);
36181 + case 6: tw32(MAC_RCV_RULE_5, 0); tw32(MAC_RCV_VALUE_5, 0);
36182 + case 5: tw32(MAC_RCV_RULE_4, 0); tw32(MAC_RCV_VALUE_4, 0);
36183 + case 4: /* tw32(MAC_RCV_RULE_3, 0); tw32(MAC_RCV_VALUE_3, 0); */
36184 + case 3: /* tw32(MAC_RCV_RULE_2, 0); tw32(MAC_RCV_VALUE_2, 0); */
36185 + case 2:
36186 + case 1:
36187 + default:
36188 + break;
36189 + };
36191 + return err;
36196 +/* Chips other than 5700/5701 use the NVRAM for fetching info. */
36197 +static void tg3_nvram_init(struct tg3 *tp)
36199 + tw32(GRC_EEPROM_ADDR,
36200 + (EEPROM_ADDR_FSM_RESET |
36201 + (EEPROM_DEFAULT_CLOCK_PERIOD <<
36202 + EEPROM_ADDR_CLKPERD_SHIFT)));
36204 + mdelay(1);
36206 + /* Enable seeprom accesses. */
36207 + tw32_carefully(GRC_LOCAL_CTRL,
36208 + tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM);
36210 + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
36211 + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
36212 + uint32_t nvcfg1 = tr32(NVRAM_CFG1);
36214 + tp->tg3_flags |= TG3_FLAG_NVRAM;
36215 + if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
36216 + if (nvcfg1 & NVRAM_CFG1_BUFFERED_MODE)
36217 + tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
36218 + } else {
36219 + nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
36220 + tw32(NVRAM_CFG1, nvcfg1);
36223 + } else {
36224 + tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
36229 +static int tg3_nvram_read_using_eeprom(
36230 + struct tg3 *tp __unused, uint32_t offset, uint32_t *val)
36232 + uint32_t tmp;
36233 + int i;
36235 + if (offset > EEPROM_ADDR_ADDR_MASK ||
36236 + (offset % 4) != 0) {
36237 + return -EINVAL;
36240 + tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
36241 + EEPROM_ADDR_DEVID_MASK |
36242 + EEPROM_ADDR_READ);
36243 + tw32(GRC_EEPROM_ADDR,
36244 + tmp |
36245 + (0 << EEPROM_ADDR_DEVID_SHIFT) |
36246 + ((offset << EEPROM_ADDR_ADDR_SHIFT) &
36247 + EEPROM_ADDR_ADDR_MASK) |
36248 + EEPROM_ADDR_READ | EEPROM_ADDR_START);
36250 + for (i = 0; i < 10000; i++) {
36251 + tmp = tr32(GRC_EEPROM_ADDR);
36253 + if (tmp & EEPROM_ADDR_COMPLETE)
36254 + break;
36255 + udelay(100);
36257 + if (!(tmp & EEPROM_ADDR_COMPLETE)) {
36258 + return -EBUSY;
36261 + *val = tr32(GRC_EEPROM_DATA);
36262 + return 0;
36265 +static int tg3_nvram_read(struct tg3 *tp, uint32_t offset, uint32_t *val)
36267 + int i, saw_done_clear;
36269 + if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
36270 + return tg3_nvram_read_using_eeprom(tp, offset, val);
36272 + if (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED)
36273 + offset = ((offset / NVRAM_BUFFERED_PAGE_SIZE) <<
36274 + NVRAM_BUFFERED_PAGE_POS) +
36275 + (offset % NVRAM_BUFFERED_PAGE_SIZE);
36277 + if (offset > NVRAM_ADDR_MSK)
36278 + return -EINVAL;
36280 + tw32(NVRAM_SWARB, SWARB_REQ_SET1);
36281 + for (i = 0; i < 1000; i++) {
36282 + if (tr32(NVRAM_SWARB) & SWARB_GNT1)
36283 + break;
36284 + udelay(20);
36287 + tw32(NVRAM_ADDR, offset);
36288 + tw32(NVRAM_CMD,
36289 + NVRAM_CMD_RD | NVRAM_CMD_GO |
36290 + NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
36292 + /* Wait for done bit to clear then set again. */
36293 + saw_done_clear = 0;
36294 + for (i = 0; i < 1000; i++) {
36295 + udelay(10);
36296 + if (!saw_done_clear &&
36297 + !(tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
36298 + saw_done_clear = 1;
36299 + else if (saw_done_clear &&
36300 + (tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
36301 + break;
36303 + if (i >= 1000) {
36304 + tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
36305 + return -EBUSY;
36308 + *val = bswap_32(tr32(NVRAM_RDDATA));
36309 + tw32(NVRAM_SWARB, 0x20);
36311 + return 0;
36314 +struct subsys_tbl_ent {
36315 + uint16_t subsys_vendor, subsys_devid;
36316 + uint32_t phy_id;
36319 +static struct subsys_tbl_ent subsys_id_to_phy_id[] = {
36320 + /* Broadcom boards. */
36321 + { 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */
36322 + { 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */
36323 + { 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */
36324 + { 0x14e4, 0x0003, PHY_ID_SERDES }, /* BCM95700A9 */
36325 + { 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */
36326 + { 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */
36327 + { 0x14e4, 0x0007, PHY_ID_SERDES }, /* BCM95701A7 */
36328 + { 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
36329 + { 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
36330 + { 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */
36331 + { 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */
36333 + /* 3com boards. */
36334 + { PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */
36335 + { PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */
36336 + /* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX }, 3C996CT */
36337 + /* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX }, 3C997T */
36338 + { PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES }, /* 3C996SX */
36339 + /* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX }, 3C997SZ */
36340 + { PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */
36341 + { PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */
36343 + /* DELL boards. */
36344 + { PCI_VENDOR_ID_DELL, 0x00d1, PHY_ID_BCM5401 }, /* VIPER */
36345 + { PCI_VENDOR_ID_DELL, 0x0106, PHY_ID_BCM5401 }, /* JAGUAR */
36346 + { PCI_VENDOR_ID_DELL, 0x0109, PHY_ID_BCM5411 }, /* MERLOT */
36347 + { PCI_VENDOR_ID_DELL, 0x010a, PHY_ID_BCM5411 }, /* SLIM_MERLOT */
36349 + /* Compaq boards. */
36350 + { PCI_VENDOR_ID_COMPAQ, 0x007c, PHY_ID_BCM5701 }, /* BANSHEE */
36351 + { PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */
36352 + { PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES }, /* CHANGELING */
36353 + { PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */
36354 + { PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 } /* NC7780_2 */
36357 +static int tg3_phy_probe(struct tg3 *tp)
36359 + uint32_t eeprom_phy_id, hw_phy_id_1, hw_phy_id_2;
36360 + uint32_t hw_phy_id, hw_phy_id_masked;
36361 + enum phy_led_mode eeprom_led_mode;
36362 + uint32_t val;
36363 + unsigned i;
36364 + int eeprom_signature_found, err;
36366 + tp->phy_id = PHY_ID_INVALID;
36368 + for (i = 0; i < sizeof(subsys_id_to_phy_id)/sizeof(subsys_id_to_phy_id[0]); i++) {
36369 + if ((subsys_id_to_phy_id[i].subsys_vendor == tp->subsystem_vendor) &&
36370 + (subsys_id_to_phy_id[i].subsys_devid == tp->subsystem_device)) {
36371 + tp->phy_id = subsys_id_to_phy_id[i].phy_id;
36372 + break;
36376 + eeprom_phy_id = PHY_ID_INVALID;
36377 + eeprom_led_mode = led_mode_auto;
36378 + eeprom_signature_found = 0;
36379 + tg3_read_mem(NIC_SRAM_DATA_SIG, &val);
36380 + if (val == NIC_SRAM_DATA_SIG_MAGIC) {
36381 + uint32_t nic_cfg;
36383 + tg3_read_mem(NIC_SRAM_DATA_CFG, &nic_cfg);
36384 + tp->nic_sram_data_cfg = nic_cfg;
36386 + eeprom_signature_found = 1;
36388 + if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
36389 + NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) {
36390 + eeprom_phy_id = PHY_ID_SERDES;
36391 + } else {
36392 + uint32_t nic_phy_id;
36394 + tg3_read_mem(NIC_SRAM_DATA_PHY_ID, &nic_phy_id);
36395 + if (nic_phy_id != 0) {
36396 + uint32_t id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK;
36397 + uint32_t id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK;
36399 + eeprom_phy_id = (id1 >> 16) << 10;
36400 + eeprom_phy_id |= (id2 & 0xfc00) << 16;
36401 + eeprom_phy_id |= (id2 & 0x03ff) << 0;
36405 + switch (nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK) {
36406 + case NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD:
36407 + eeprom_led_mode = led_mode_three_link;
36408 + break;
36410 + case NIC_SRAM_DATA_CFG_LED_LINK_SPD:
36411 + eeprom_led_mode = led_mode_link10;
36412 + break;
36414 + default:
36415 + eeprom_led_mode = led_mode_auto;
36416 + break;
36417 + };
36418 + if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
36419 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
36420 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) &&
36421 + (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) {
36422 + tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
36425 + if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
36426 + tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
36427 + if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
36428 + tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
36431 + /* Now read the physical PHY_ID from the chip and verify
36432 + * that it is sane. If it doesn't look good, we fall back
36433 + * to either the hard-coded table based PHY_ID and failing
36434 + * that the value found in the eeprom area.
36435 + */
36436 + err = tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1);
36437 + err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2);
36439 + hw_phy_id = (hw_phy_id_1 & 0xffff) << 10;
36440 + hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16;
36441 + hw_phy_id |= (hw_phy_id_2 & 0x03ff) << 0;
36443 + hw_phy_id_masked = hw_phy_id & PHY_ID_MASK;
36445 + if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) {
36446 + tp->phy_id = hw_phy_id;
36447 + } else {
36448 + /* phy_id currently holds the value found in the
36449 + * subsys_id_to_phy_id[] table or PHY_ID_INVALID
36450 + * if a match was not found there.
36451 + */
36452 + if (tp->phy_id == PHY_ID_INVALID) {
36453 + if (!eeprom_signature_found ||
36454 + !KNOWN_PHY_ID(eeprom_phy_id & PHY_ID_MASK))
36455 + return -ENODEV;
36456 + tp->phy_id = eeprom_phy_id;
36460 + err = tg3_phy_reset(tp);
36461 + if (err)
36462 + return err;
36464 + if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
36465 + tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
36466 + uint32_t mii_tg3_ctrl;
36468 + /* These chips, when reset, only advertise 10Mb
36469 + * capabilities. Fix that.
36470 + */
36471 + err = tg3_writephy(tp, MII_ADVERTISE,
36472 + (ADVERTISE_CSMA |
36473 + ADVERTISE_PAUSE_CAP |
36474 + ADVERTISE_10HALF |
36475 + ADVERTISE_10FULL |
36476 + ADVERTISE_100HALF |
36477 + ADVERTISE_100FULL));
36478 + mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
36479 + MII_TG3_CTRL_ADV_1000_FULL |
36480 + MII_TG3_CTRL_AS_MASTER |
36481 + MII_TG3_CTRL_ENABLE_AS_MASTER);
36482 + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
36483 + mii_tg3_ctrl = 0;
36485 + err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl);
36486 + err |= tg3_writephy(tp, MII_BMCR,
36487 + (BMCR_ANRESTART | BMCR_ANENABLE));
36490 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
36491 + tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
36492 + tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
36493 + tg3_writedsp(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
36496 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
36497 + tg3_writephy(tp, 0x1c, 0x8d68);
36498 + tg3_writephy(tp, 0x1c, 0x8d68);
36501 + /* Enable Ethernet@WireSpeed */
36502 + tg3_phy_set_wirespeed(tp);
36504 + if (!err && ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)) {
36505 + err = tg3_init_5401phy_dsp(tp);
36508 + /* Determine the PHY led mode.
36509 + * Be careful if this gets set wrong it can result in an inability to
36510 + * establish a link.
36511 + */
36512 + if (tp->phy_id == PHY_ID_SERDES) {
36513 + tp->led_mode = led_mode_three_link;
36515 + else if (tp->subsystem_vendor == PCI_VENDOR_ID_DELL) {
36516 + tp->led_mode = led_mode_link10;
36517 + } else {
36518 + tp->led_mode = led_mode_three_link;
36519 + if (eeprom_signature_found &&
36520 + eeprom_led_mode != led_mode_auto)
36521 + tp->led_mode = eeprom_led_mode;
36524 + if (tp->phy_id == PHY_ID_SERDES)
36525 + tp->link_config.advertising =
36526 + (ADVERTISED_1000baseT_Half |
36527 + ADVERTISED_1000baseT_Full |
36528 + ADVERTISED_Autoneg |
36529 + ADVERTISED_FIBRE);
36530 + if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
36531 + tp->link_config.advertising &=
36532 + ~(ADVERTISED_1000baseT_Half |
36533 + ADVERTISED_1000baseT_Full);
36535 + return err;
36538 +#if SUPPORT_PARTNO_STR
36539 +static void tg3_read_partno(struct tg3 *tp)
36541 + unsigned char vpd_data[256];
36542 + int i;
36544 + for (i = 0; i < 256; i += 4) {
36545 + uint32_t tmp;
36547 + if (tg3_nvram_read(tp, 0x100 + i, &tmp))
36548 + goto out_not_found;
36550 + vpd_data[i + 0] = ((tmp >> 0) & 0xff);
36551 + vpd_data[i + 1] = ((tmp >> 8) & 0xff);
36552 + vpd_data[i + 2] = ((tmp >> 16) & 0xff);
36553 + vpd_data[i + 3] = ((tmp >> 24) & 0xff);
36556 + /* Now parse and find the part number. */
36557 + for (i = 0; i < 256; ) {
36558 + unsigned char val = vpd_data[i];
36559 + int block_end;
36561 + if (val == 0x82 || val == 0x91) {
36562 + i = (i + 3 +
36563 + (vpd_data[i + 1] +
36564 + (vpd_data[i + 2] << 8)));
36565 + continue;
36568 + if (val != 0x90)
36569 + goto out_not_found;
36571 + block_end = (i + 3 +
36572 + (vpd_data[i + 1] +
36573 + (vpd_data[i + 2] << 8)));
36574 + i += 3;
36575 + while (i < block_end) {
36576 + if (vpd_data[i + 0] == 'P' &&
36577 + vpd_data[i + 1] == 'N') {
36578 + int partno_len = vpd_data[i + 2];
36580 + if (partno_len > 24)
36581 + goto out_not_found;
36583 + memcpy(tp->board_part_number,
36584 + &vpd_data[i + 3],
36585 + partno_len);
36587 + /* Success. */
36588 + return;
36592 + /* Part number not found. */
36593 + goto out_not_found;
36596 +out_not_found:
36597 + memcpy(tp->board_part_number, "none", sizeof("none"));
36599 +#else
36600 +#define tg3_read_partno(TP) ((TP)->board_part_number[0] = '\0')
36601 +#endif
36603 +static int tg3_get_invariants(struct tg3 *tp)
36605 + uint32_t misc_ctrl_reg;
36606 + uint32_t pci_state_reg, grc_misc_cfg;
36607 + uint16_t pci_cmd;
36608 + uint8_t pci_latency;
36609 + int err;
36611 + /* Read the subsystem vendor and device ids */
36612 + pci_read_config_word(tp->pdev, PCI_SUBSYSTEM_VENDOR_ID, &tp->subsystem_vendor);
36613 + pci_read_config_word(tp->pdev, PCI_SUBSYSTEM_ID, &tp->subsystem_device);
36615 + /* The sun_5704 code needs infrastructure etherboot does have
36616 + * ignore it for now.
36617 + */
36619 + /* If we have an AMD 762 or Intel ICH/ICH0 chipset, write
36620 + * reordering to the mailbox registers done by the host
36621 + * controller can cause major troubles. We read back from
36622 + * every mailbox register write to force the writes to be
36623 + * posted to the chip in order.
36625 + * TG3_FLAG_MBOX_WRITE_REORDER has been forced on.
36626 + */
36628 + /* Force memory write invalidate off. If we leave it on,
36629 + * then on 5700_BX chips we have to enable a workaround.
36630 + * The workaround is to set the TG3PCI_DMA_RW_CTRL boundry
36631 + * to match the cacheline size. The Broadcom driver have this
36632 + * workaround but turns MWI off all the times so never uses
36633 + * it. This seems to suggest that the workaround is insufficient.
36634 + */
36635 + pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
36636 + pci_cmd &= ~PCI_COMMAND_INVALIDATE;
36637 + /* Also, force SERR#/PERR# in PCI command. */
36638 + pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
36639 + pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
36641 + /* It is absolutely critical that TG3PCI_MISC_HOST_CTRL
36642 + * has the register indirect write enable bit set before
36643 + * we try to access any of the MMIO registers. It is also
36644 + * critical that the PCI-X hw workaround situation is decided
36645 + * before that as well.
36646 + */
36647 + pci_read_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, &misc_ctrl_reg);
36649 + tp->pci_chip_rev_id = (misc_ctrl_reg >> MISC_HOST_CTRL_CHIPREV_SHIFT);
36651 + /* Initialize misc host control in PCI block. */
36652 + tp->misc_host_ctrl |= (misc_ctrl_reg &
36653 + MISC_HOST_CTRL_CHIPREV);
36654 + pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
36655 + tp->misc_host_ctrl);
36657 + pci_read_config_byte(tp->pdev, PCI_LATENCY_TIMER, &pci_latency);
36658 + if (pci_latency < 64) {
36659 + pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER, 64);
36662 + pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE, &pci_state_reg);
36664 + /* If this is a 5700 BX chipset, and we are in PCI-X
36665 + * mode, enable register write workaround.
36667 + * The workaround is to use indirect register accesses
36668 + * for all chip writes not to mailbox registers.
36670 + * In etherboot to simplify things we just always use this work around.
36671 + */
36672 + if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0) {
36673 + tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
36675 + /* Back to back register writes can cause problems on the 5701,
36676 + * the workaround is to read back all reg writes except those to
36677 + * mailbox regs.
36678 + * In etherboot we always use indirect register accesses so
36679 + * we don't see this.
36680 + */
36682 + if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
36683 + tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
36684 + if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
36685 + tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
36687 + /* Chip-specific fixup from Broadcom driver */
36688 + if ((tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) &&
36689 + (!(pci_state_reg & PCISTATE_RETRY_SAME_DMA))) {
36690 + pci_state_reg |= PCISTATE_RETRY_SAME_DMA;
36691 + pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg);
36694 + /* Force the chip into D0. */
36695 + tg3_set_power_state_0(tp);
36697 + /* Etherboot does not ask the tg3 to do checksums */
36698 + /* Etherboot does not ask the tg3 to do jumbo frames */
36699 + /* Ehterboot does not ask the tg3 to use WakeOnLan. */
36701 + /* A few boards don't want Ethernet@WireSpeed phy feature */
36702 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
36703 + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
36704 + (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
36705 + (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1))) {
36706 + tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
36709 + /* Avoid tagged irq status etherboot does not use irqs */
36711 + /* Only 5701 and later support tagged irq status mode.
36712 + * Also, 5788 chips cannot use tagged irq status.
36714 + * However, since etherboot does not use irqs avoid tagged irqs
36715 + * status because the interrupt condition is more difficult to
36716 + * fully clear in that mode.
36717 + */
36719 + /* Since some 5700_AX && 5700_BX have problems with 32BYTE
36720 + * coalesce_mode, and the rest work fine anything set.
36721 + * Don't enable HOST_CC_MODE_32BYTE in etherboot.
36722 + */
36724 + /* Initialize MAC MI mode, polling disabled. */
36725 + tw32_carefully(MAC_MI_MODE, tp->mi_mode);
36727 + /* Initialize data/descriptor byte/word swapping. */
36728 + tw32(GRC_MODE, tp->grc_mode);
36730 + tg3_switch_clocks(tp);
36732 + /* Clear this out for sanity. */
36733 + tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
36735 + /* Etherboot does not need to check if the PCIX_TARGET_HWBUG
36736 + * is needed. It always uses it.
36737 + */
36739 + udelay(50);
36740 + tg3_nvram_init(tp);
36742 + /* The TX descriptors will reside in main memory.
36743 + */
36745 + /* See which board we are using.
36746 + */
36747 + grc_misc_cfg = tr32(GRC_MISC_CFG);
36748 + grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
36750 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
36751 + grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
36752 + tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
36753 + tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
36756 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
36757 + (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
36758 + grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
36759 + tp->tg3_flags2 |= TG3_FLG2_IS_5788;
36761 + /* these are limited to 10/100 only */
36762 + if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) &&
36763 + ((grc_misc_cfg == 0x8000) || (grc_misc_cfg == 0x4000))) ||
36764 + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
36765 + (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM) &&
36766 + ((tp->pdev->dev_id == PCI_DEVICE_ID_TIGON3_5901) ||
36767 + (tp->pdev->dev_id == PCI_DEVICE_ID_TIGON3_5901_2)))) {
36768 + tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
36771 + err = tg3_phy_probe(tp);
36772 + if (err) {
36773 + printf("phy probe failed, err %d\n", err);
36776 + tg3_read_partno(tp);
36779 + /* 5700 BX chips need to have their TX producer index mailboxes
36780 + * written twice to workaround a bug.
36781 + * In etherboot we do this unconditionally to simplify things.
36782 + */
36784 + /* 5700 chips can get confused if TX buffers straddle the
36785 + * 4GB address boundary in some cases.
36786 + *
36787 + * In etherboot we can ignore the problem as etherboot lives below 4GB.
36788 + */
36790 + /* In etherboot wake-on-lan is unconditionally disabled */
36791 + return err;
36794 +static int tg3_get_device_address(struct tg3 *tp)
36796 + struct nic *nic = tp->nic;
36797 + uint32_t hi, lo, mac_offset;
36799 + if (PCI_FUNC(tp->pdev->devfn) == 0)
36800 + mac_offset = 0x7c;
36801 + else
36802 + mac_offset = 0xcc;
36804 + /* First try to get it from MAC address mailbox. */
36805 + tg3_read_mem(NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
36806 + if ((hi >> 16) == 0x484b) {
36807 + nic->node_addr[0] = (hi >> 8) & 0xff;
36808 + nic->node_addr[1] = (hi >> 0) & 0xff;
36810 + tg3_read_mem(NIC_SRAM_MAC_ADDR_LOW_MBOX, &lo);
36811 + nic->node_addr[2] = (lo >> 24) & 0xff;
36812 + nic->node_addr[3] = (lo >> 16) & 0xff;
36813 + nic->node_addr[4] = (lo >> 8) & 0xff;
36814 + nic->node_addr[5] = (lo >> 0) & 0xff;
36816 + /* Next, try NVRAM. */
36817 + else if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
36818 + !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
36819 + nic->node_addr[0] = ((hi >> 16) & 0xff);
36820 + nic->node_addr[1] = ((hi >> 24) & 0xff);
36821 + nic->node_addr[2] = ((lo >> 0) & 0xff);
36822 + nic->node_addr[3] = ((lo >> 8) & 0xff);
36823 + nic->node_addr[4] = ((lo >> 16) & 0xff);
36824 + nic->node_addr[5] = ((lo >> 24) & 0xff);
36826 + /* Finally just fetch it out of the MAC control regs. */
36827 + else {
36828 + hi = tr32(MAC_ADDR_0_HIGH);
36829 + lo = tr32(MAC_ADDR_0_LOW);
36831 + nic->node_addr[5] = lo & 0xff;
36832 + nic->node_addr[4] = (lo >> 8) & 0xff;
36833 + nic->node_addr[3] = (lo >> 16) & 0xff;
36834 + nic->node_addr[2] = (lo >> 24) & 0xff;
36835 + nic->node_addr[1] = hi & 0xff;
36836 + nic->node_addr[0] = (hi >> 8) & 0xff;
36839 + return 0;
36843 +static int tg3_setup_dma(struct tg3 *tp)
36845 + tw32(TG3PCI_CLOCK_CTRL, 0);
36847 + if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) == 0) {
36848 + tp->dma_rwctrl =
36849 + (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
36850 + (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
36851 + (0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
36852 + (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
36853 + (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
36854 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
36855 + tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA << DMA_RWCTRL_MIN_DMA_SHIFT);
36857 + } else {
36858 + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
36859 + tp->dma_rwctrl =
36860 + (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
36861 + (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
36862 + (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
36863 + (0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
36864 + (0x00 << DMA_RWCTRL_MIN_DMA_SHIFT);
36865 + else
36866 + tp->dma_rwctrl =
36867 + (0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
36868 + (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
36869 + (0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
36870 + (0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
36871 + (0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
36873 + /* Wheee, some more chip bugs... */
36874 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
36875 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)) {
36876 + uint32_t ccval = tr32(TG3PCI_CLOCK_CTRL) & 0x1f;
36878 + if ((ccval == 0x6) || (ccval == 0x7)) {
36879 + tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
36884 + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
36885 + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)) {
36886 + tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA << DMA_RWCTRL_MIN_DMA_SHIFT);
36889 + tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE;
36891 + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
36893 + return 0;
36896 +static void tg3_init_link_config(struct tg3 *tp)
36898 + tp->link_config.advertising =
36899 + (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
36900 + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
36901 + ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
36902 + ADVERTISED_Autoneg | ADVERTISED_MII);
36903 + tp->carrier_ok = 0;
36904 + tp->link_config.active_speed = SPEED_INVALID;
36905 + tp->link_config.active_duplex = DUPLEX_INVALID;
36909 +#if SUPPORT_PHY_STR
36910 +static const char * tg3_phy_string(struct tg3 *tp)
36912 + switch (tp->phy_id & PHY_ID_MASK) {
36913 + case PHY_ID_BCM5400: return "5400";
36914 + case PHY_ID_BCM5401: return "5401";
36915 + case PHY_ID_BCM5411: return "5411";
36916 + case PHY_ID_BCM5701: return "5701";
36917 + case PHY_ID_BCM5703: return "5703";
36918 + case PHY_ID_BCM5704: return "5704";
36919 + case PHY_ID_BCM8002: return "8002";
36920 + case PHY_ID_SERDES: return "serdes";
36921 + default: return "unknown";
36922 + };
36924 +#else
36925 +#define tg3_phy_string(TP) "?"
36926 +#endif
36929 +static void tg3_poll_link(struct tg3 *tp)
36931 + uint32_t mac_stat;
36933 + mac_stat = tr32(MAC_STATUS);
36934 + if (tp->phy_id == PHY_ID_SERDES) {
36935 + if (tp->carrier_ok?
36936 + (mac_stat & MAC_STATUS_LNKSTATE_CHANGED):
36937 + (mac_stat & MAC_STATUS_PCS_SYNCED)) {
36938 + tw32_carefully(MAC_MODE, tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK);
36939 + tw32_carefully(MAC_MODE, tp->mac_mode);
36941 + tg3_setup_phy(tp);
36944 + else {
36945 + if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED) {
36946 + tg3_setup_phy(tp);
36951 +/**************************************************************************
36952 +POLL - Wait for a frame
36953 +***************************************************************************/
36954 +static void tg3_ack_irqs(struct tg3 *tp)
36956 + if (tp->hw_status->status & SD_STATUS_UPDATED) {
36957 + /*
36958 + * writing any value to intr-mbox-0 clears PCI INTA# and
36959 + * chip-internal interrupt pending events.
36960 + * writing non-zero to intr-mbox-0 additional tells the
36961 + * NIC to stop sending us irqs, engaging "in-intr-handler"
36962 + * event coalescing.
36963 + */
36964 + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
36965 + 0x00000001);
36966 + /*
36967 + * Flush PCI write. This also guarantees that our
36968 + * status block has been flushed to host memory.
36969 + */
36970 + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
36971 + tp->hw_status->status &= ~SD_STATUS_UPDATED;
36975 +static int tg3_poll(struct nic *nic, int retrieve)
36977 + /* return true if there's an ethernet packet ready to read */
36978 + /* nic->packet should contain data on return */
36979 + /* nic->packetlen should contain length of data */
36981 + struct tg3 *tp = &tg3;
36982 + int result;
36984 + result = 0;
36986 + if ( (tp->hw_status->idx[0].rx_producer != tp->rx_rcb_ptr) && !retrieve )
36987 + return 1;
36989 + tg3_ack_irqs(tp);
36991 + if (tp->hw_status->idx[0].rx_producer != tp->rx_rcb_ptr) {
36992 + struct tg3_rx_buffer_desc *desc;
36993 + unsigned int len;
36994 + desc = &tp->rx_rcb[tp->rx_rcb_ptr];
36995 + if ((desc->opaque & RXD_OPAQUE_RING_MASK) == RXD_OPAQUE_RING_STD) {
36996 + len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */
36998 + nic->packetlen = len;
36999 + memcpy(nic->packet, bus_to_virt(desc->addr_lo), len);
37000 + result = 1;
37002 + tp->rx_rcb_ptr = (tp->rx_rcb_ptr + 1) % TG3_RX_RCB_RING_SIZE;
37004 + /* ACK the status ring */
37005 + tw32_mailbox2(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, tp->rx_rcb_ptr);
37007 + /* Refill RX ring. */
37008 + if (result) {
37009 + tp->rx_std_ptr = (tp->rx_std_ptr + 1) % TG3_RX_RING_SIZE;
37010 + tw32_mailbox2(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW, tp->rx_std_ptr);
37013 + tg3_poll_link(tp);
37014 + return result;
37017 +/**************************************************************************
37018 +TRANSMIT - Transmit a frame
37019 +***************************************************************************/
37020 +#if 0
37021 +static void tg3_set_txd(struct tg3 *tp, int entry,
37022 + dma_addr_t mapping, int len, uint32_t flags,
37023 + uint32_t mss_and_is_end)
37025 + struct tg3_tx_buffer_desc *txd = &tp->tx_ring[entry];
37026 + int is_end = (mss_and_is_end & 0x1);
37027 + if (is_end) {
37028 + flags |= TXD_FLAG_END;
37031 + txd->addr_hi = 0;
37032 + txd->addr_lo = mapping & 0xffffffff;
37033 + txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
37034 + txd->vlan_tag = 0 << TXD_VLAN_TAG_SHIFT;
37036 +#endif
37038 +static void tg3_transmit(struct nic *nic, const char *dst_addr,
37039 + unsigned int type, unsigned int size, const char *packet)
37041 + static struct eth_frame {
37042 + uint8_t dst_addr[ETH_ALEN];
37043 + uint8_t src_addr[ETH_ALEN];
37044 + uint16_t type;
37045 + uint8_t data [ETH_FRAME_LEN - ETH_HLEN];
37046 + } frame[2];
37047 + static int frame_idx;
37049 + /* send the packet to destination */
37050 + struct tg3_tx_buffer_desc *txd;
37051 + struct tg3 *tp;
37052 + uint32_t entry;
37053 + int i;
37055 + /* Wait until there is a free packet frame */
37056 + tp = &tg3;
37057 + i = 0;
37058 + entry = tp->tx_prod;
37059 + while((tp->hw_status->idx[0].tx_consumer != entry) &&
37060 + (tp->hw_status->idx[0].tx_consumer != PREV_TX(entry))) {
37061 + mdelay(10); /* give the nick a chance */
37062 + poll_interruptions();
37063 + if (++i > 500) { /* timeout 5s for transmit */
37064 + printf("transmit timed out\n");
37065 + tg3_halt(tp);
37066 + tg3_setup_hw(tp);
37067 + return;
37070 + if (i != 0) {
37071 + printf("#");
37074 + /* Copy the packet to the our local buffer */
37075 + memcpy(&frame[frame_idx].dst_addr, dst_addr, ETH_ALEN);
37076 + memcpy(&frame[frame_idx].src_addr, nic->node_addr, ETH_ALEN);
37077 + frame[frame_idx].type = htons(type);
37078 + memset(&frame[frame_idx].data, 0, sizeof(frame[frame_idx].data));
37079 + memcpy(&frame[frame_idx].data, packet, size);
37081 + /* Setup the ring buffer entry to transmit */
37082 + txd = &tp->tx_ring[entry];
37083 + txd->addr_hi = 0; /* Etherboot runs under 4GB */
37084 + txd->addr_lo = virt_to_bus(&frame[frame_idx]);
37085 + txd->len_flags = ((size + ETH_HLEN) << TXD_LEN_SHIFT) | TXD_FLAG_END;
37086 + txd->vlan_tag = 0 << TXD_VLAN_TAG_SHIFT;
37088 + /* Advance to the next entry */
37089 + entry = NEXT_TX(entry);
37090 + frame_idx ^= 1;
37092 + /* Packets are ready, update Tx producer idx local and on card */
37093 + tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
37094 + tw32_mailbox2((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
37095 + tp->tx_prod = entry;
37098 +/**************************************************************************
37099 +DISABLE - Turn off ethernet interface
37100 +***************************************************************************/
37101 +static void tg3_disable(struct dev *dev __unused)
37103 + struct tg3 *tp = &tg3;
37104 + /* put the card in its initial state */
37105 + /* This function serves 3 purposes.
37106 + * This disables DMA and interrupts so we don't receive
37107 + * unexpected packets or interrupts from the card after
37108 + * etherboot has finished.
37109 + * This frees resources so etherboot may use
37110 + * this driver on another interface
37111 + * This allows etherboot to reinitialize the interface
37112 + * if something is something goes wrong.
37113 + */
37114 + tg3_halt(tp);
37115 + tp->tg3_flags &= ~(TG3_FLAG_INIT_COMPLETE|TG3_FLAG_GOT_SERDES_FLOWCTL);
37116 + tp->carrier_ok = 0;
37117 + iounmap((void *)tp->regs);
37120 +/**************************************************************************
37121 +IRQ - Enable, Disable, or Force interrupts
37122 +***************************************************************************/
37123 +static void tg3_irq(struct nic *nic __unused, irq_action_t action __unused)
37125 + switch ( action ) {
37126 + case DISABLE :
37127 + break;
37128 + case ENABLE :
37129 + break;
37130 + case FORCE :
37131 + break;
37135 +/**************************************************************************
37136 +PROBE - Look for an adapter, this routine's visible to the outside
37137 +You should omit the last argument struct pci_device * for a non-PCI NIC
37138 +***************************************************************************/
37139 +static int tg3_probe(struct dev *dev, struct pci_device *pdev)
37141 + struct nic *nic = (struct nic *)dev;
37142 + struct tg3 *tp = &tg3;
37143 + unsigned long tg3reg_base, tg3reg_len;
37144 + int i, err, pm_cap;
37146 + if (pdev == 0)
37147 + return 0;
37149 + memset(tp, 0, sizeof(*tp));
37151 + adjust_pci_device(pdev);
37153 + nic->irqno = 0;
37154 + nic->ioaddr = pdev->ioaddr & ~3;
37156 + /* Find power-management capability. */
37157 + pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
37158 + if (pm_cap == 0) {
37159 + printf("Cannot find PowerManagement capability, aborting.\n");
37160 + return 0;
37162 + tg3reg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
37163 + if (tg3reg_base == -1UL) {
37164 + printf("Unuseable bar\n");
37165 + return 0;
37167 + tg3reg_len = pci_bar_size(pdev, PCI_BASE_ADDRESS_0);
37169 + tp->pdev = pdev;
37170 + tp->nic = nic;
37171 + tp->pm_cap = pm_cap;
37172 + tp->rx_mode = 0;
37173 + tp->tx_mode = 0;
37174 + tp->mi_mode = MAC_MI_MODE_BASE;
37175 + tp->tg3_flags = 0 & ~TG3_FLAG_INIT_COMPLETE;
37177 + /* The word/byte swap controls here control register access byte
37178 + * swapping. DMA data byte swapping is controlled in the GRC_MODE
37179 + * setting below.
37180 + */
37181 + tp->misc_host_ctrl =
37182 + MISC_HOST_CTRL_MASK_PCI_INT |
37183 + MISC_HOST_CTRL_WORD_SWAP |
37184 + MISC_HOST_CTRL_INDIR_ACCESS |
37185 + MISC_HOST_CTRL_PCISTATE_RW;
37187 + /* The NONFRM (non-frame) byte/word swap controls take effect
37188 + * on descriptor entries, anything which isn't packet data.
37190 + * The StrongARM chips on the board (one for tx, one for rx)
37191 + * are running in big-endian mode.
37192 + */
37193 + tp->grc_mode = (GRC_MODE_WSWAP_DATA | GRC_MODE_BSWAP_DATA |
37194 + GRC_MODE_WSWAP_NONFRM_DATA);
37195 +#if __BYTE_ORDER == __BIG_ENDIAN
37196 + tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA;
37197 +#endif
37198 + tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
37199 + if (tp->regs == 0UL) {
37200 + printf("Cannot map device registers, aborting\n");
37201 + return 0;
37204 + tg3_init_link_config(tp);
37206 + err = tg3_get_invariants(tp);
37207 + if (err) {
37208 + printf("Problem fetching invariants of chip, aborting.\n");
37209 + goto err_out_iounmap;
37212 + err = tg3_get_device_address(tp);
37213 + if (err) {
37214 + printf("Could not obtain valid ethernet address, aborting.\n");
37215 + goto err_out_iounmap;
37217 + printf("Ethernet addr: %!\n", nic->node_addr);
37219 + tg3_setup_dma(tp);
37221 + /* Now that we have fully setup the chip, save away a snapshot
37222 + * of the PCI config space. We need to restore this after
37223 + * GRC_MISC_CFG core clock resets and some resume events.
37224 + */
37225 + pci_save_state(tp->pdev, tp->pci_cfg_state);
37227 + printf("Tigon3 [partno(%s) rev %hx PHY(%s)] (PCI%s:%s:%s)\n",
37228 + tp->board_part_number,
37229 + tp->pci_chip_rev_id,
37230 + tg3_phy_string(tp),
37231 + ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "X" : ""),
37232 + ((tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) ?
37233 + ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "133MHz" : "66MHz") :
37234 + ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "100MHz" : "33MHz")),
37235 + ((tp->tg3_flags & TG3_FLAG_PCI_32BIT) ? "32-bit" : "64-bit"));
37238 + err = tg3_setup_hw(tp);
37239 + if (err) {
37240 + goto err_out_disable;
37241 + }
37242 + tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
37244 + /* Wait for a reasonable time for the link to come up */
37245 + tg3_poll_link(tp);
37246 + for(i = 0; !tp->carrier_ok && (i < VALID_LINK_TIMEOUT*100); i++) {
37247 + mdelay(1);
37248 + tg3_poll_link(tp);
37250 + if (!tp->carrier_ok){
37251 + printf("Valid link not established\n");
37252 + goto err_out_disable;
37255 + dev->disable = tg3_disable;
37256 + nic->poll = tg3_poll;
37257 + nic->transmit = tg3_transmit;
37258 + nic->irq = tg3_irq;
37260 + return 1;
37262 + err_out_iounmap:
37263 + iounmap((void *)tp->regs);
37264 + return 0;
37265 + err_out_disable:
37266 + tg3_disable(dev);
37267 + return 0;
37270 +static struct pci_id tg3_nics[] = {
37271 +PCI_ROM(0x14e4, 0x1644, "tg3-5700", "Broadcom Tigon 3 5700"),
37272 +PCI_ROM(0x14e4, 0x1645, "tg3-5701", "Broadcom Tigon 3 5701"),
37273 +PCI_ROM(0x14e4, 0x1646, "tg3-5702", "Broadcom Tigon 3 5702"),
37274 +PCI_ROM(0x14e4, 0x1647, "tg3-5703", "Broadcom Tigon 3 5703"),
37275 +PCI_ROM(0x14e4, 0x1648, "tg3-5704", "Broadcom Tigon 3 5704"),
37276 +PCI_ROM(0x14e4, 0x164d, "tg3-5702FE", "Broadcom Tigon 3 5702FE"),
37277 +PCI_ROM(0x14e4, 0x1653, "tg3-5705", "Broadcom Tigon 3 5705"),
37278 +PCI_ROM(0x14e4, 0x1654, "tg3-5705_2", "Broadcom Tigon 3 5705_2"),
37279 +PCI_ROM(0x14e4, 0x165d, "tg3-5705M", "Broadcom Tigon 3 5705M"),
37280 +PCI_ROM(0x14e4, 0x165e, "tg3-5705M_2", "Broadcom Tigon 3 5705M_2"),
37281 +PCI_ROM(0x14e4, 0x1696, "tg3-5782", "Broadcom Tigon 3 5782"),
37282 +PCI_ROM(0x14e4, 0x169c, "tg3-5788", "Broadcom Tigon 3 5788"),
37283 +PCI_ROM(0x14e4, 0x16a6, "tg3-5702X", "Broadcom Tigon 3 5702X"),
37284 +PCI_ROM(0x14e4, 0x16a7, "tg3-5703X", "Broadcom Tigon 3 5703X"),
37285 +PCI_ROM(0x14e4, 0x16a8, "tg3-5704S", "Broadcom Tigon 3 5704S"),
37286 +PCI_ROM(0x14e4, 0x16c6, "tg3-5702A3", "Broadcom Tigon 3 5702A3"),
37287 +PCI_ROM(0x14e4, 0x16c7, "tg3-5703A3", "Broadcom Tigon 3 5703A3"),
37288 +PCI_ROM(0x14e4, 0x170d, "tg3-5901", "Broadcom Tigon 3 5901"),
37289 +PCI_ROM(0x14e4, 0x170e, "tg3-5901_2", "Broadcom Tigon 3 5901_2"),
37290 +PCI_ROM(0x1148, 0x4400, "tg3-9DXX", "Syskonnect 9DXX"),
37291 +PCI_ROM(0x1148, 0x4500, "tg3-9MXX", "Syskonnect 9MXX"),
37292 +PCI_ROM(0x173b, 0x03e8, "tg3-ac1000", "Altima AC1000"),
37293 +PCI_ROM(0x173b, 0x03e9, "tg3-ac1001", "Altima AC1001"),
37294 +PCI_ROM(0x173b, 0x03ea, "tg3-ac9100", "Altima AC9100"),
37295 +PCI_ROM(0x173b, 0x03eb, "tg3-ac1003", "Altima AC1003"),
37298 +struct pci_driver tg3_driver = {
37299 + .type = NIC_DRIVER,
37300 + .name = "TG3",
37301 + .probe = tg3_probe,
37302 + .ids = tg3_nics,
37303 + .id_count = sizeof(tg3_nics)/sizeof(tg3_nics[0]),
37304 + .class = 0,
37306 Index: b/netboot/tg3.h
37307 ===================================================================
37308 --- /dev/null
37309 +++ b/netboot/tg3.h
37310 @@ -0,0 +1,2203 @@
37311 +/* $Id: grub-0.95-diskless-patch-2.patch,v 1.1.1.1 2005/06/14 08:18:50 wesolows Exp $
37312 + * tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
37314 + * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
37315 + * Copyright (C) 2001 Jeff Garzik (jgarzik@mandrakesoft.com)
37316 + */
37318 +#ifndef _T3_H
37319 +#define _T3_H
37321 +#include "stdint.h"
37323 +typedef unsigned long dma_addr_t;
37325 +/* From mii.h */
37327 +/* Indicates what features are advertised by the interface. */
37328 +#define ADVERTISED_10baseT_Half (1 << 0)
37329 +#define ADVERTISED_10baseT_Full (1 << 1)
37330 +#define ADVERTISED_100baseT_Half (1 << 2)
37331 +#define ADVERTISED_100baseT_Full (1 << 3)
37332 +#define ADVERTISED_1000baseT_Half (1 << 4)
37333 +#define ADVERTISED_1000baseT_Full (1 << 5)
37334 +#define ADVERTISED_Autoneg (1 << 6)
37335 +#define ADVERTISED_TP (1 << 7)
37336 +#define ADVERTISED_AUI (1 << 8)
37337 +#define ADVERTISED_MII (1 << 9)
37338 +#define ADVERTISED_FIBRE (1 << 10)
37339 +#define ADVERTISED_BNC (1 << 11)
37341 +/* The following are all involved in forcing a particular link
37342 + * mode for the device for setting things. When getting the
37343 + * devices settings, these indicate the current mode and whether
37344 + * it was foced up into this mode or autonegotiated.
37345 + */
37347 +/* The forced speed, 10Mb, 100Mb, gigabit. */
37348 +#define SPEED_10 0
37349 +#define SPEED_100 1
37350 +#define SPEED_1000 2
37351 +#define SPEED_INVALID 3
37354 +/* Duplex, half or full. */
37355 +#define DUPLEX_HALF 0x00
37356 +#define DUPLEX_FULL 0x01
37357 +#define DUPLEX_INVALID 0x02
37359 +/* Which connector port. */
37360 +#define PORT_TP 0x00
37361 +#define PORT_AUI 0x01
37362 +#define PORT_MII 0x02
37363 +#define PORT_FIBRE 0x03
37364 +#define PORT_BNC 0x04
37366 +/* Which tranceiver to use. */
37367 +#define XCVR_INTERNAL 0x00
37368 +#define XCVR_EXTERNAL 0x01
37369 +#define XCVR_DUMMY1 0x02
37370 +#define XCVR_DUMMY2 0x03
37371 +#define XCVR_DUMMY3 0x04
37373 +/* Enable or disable autonegotiation. If this is set to enable,
37374 + * the forced link modes above are completely ignored.
37375 + */
37376 +#define AUTONEG_DISABLE 0x00
37377 +#define AUTONEG_ENABLE 0x01
37379 +/* Wake-On-Lan options. */
37380 +#define WAKE_PHY (1 << 0)
37381 +#define WAKE_UCAST (1 << 1)
37382 +#define WAKE_MCAST (1 << 2)
37383 +#define WAKE_BCAST (1 << 3)
37384 +#define WAKE_ARP (1 << 4)
37385 +#define WAKE_MAGIC (1 << 5)
37386 +#define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */
37388 +/* Generic MII registers. */
37390 +#define MII_BMCR 0x00 /* Basic mode control register */
37391 +#define MII_BMSR 0x01 /* Basic mode status register */
37392 +#define MII_PHYSID1 0x02 /* PHYS ID 1 */
37393 +#define MII_PHYSID2 0x03 /* PHYS ID 2 */
37394 +#define MII_ADVERTISE 0x04 /* Advertisement control reg */
37395 +#define MII_LPA 0x05 /* Link partner ability reg */
37396 +#define MII_EXPANSION 0x06 /* Expansion register */
37397 +#define MII_DCOUNTER 0x12 /* Disconnect counter */
37398 +#define MII_FCSCOUNTER 0x13 /* False carrier counter */
37399 +#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
37400 +#define MII_RERRCOUNTER 0x15 /* Receive error counter */
37401 +#define MII_SREVISION 0x16 /* Silicon revision */
37402 +#define MII_RESV1 0x17 /* Reserved... */
37403 +#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
37404 +#define MII_PHYADDR 0x19 /* PHY address */
37405 +#define MII_RESV2 0x1a /* Reserved... */
37406 +#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
37407 +#define MII_NCONFIG 0x1c /* Network interface config */
37409 +/* Basic mode control register. */
37410 +#define BMCR_RESV 0x007f /* Unused... */
37411 +#define BMCR_CTST 0x0080 /* Collision test */
37412 +#define BMCR_FULLDPLX 0x0100 /* Full duplex */
37413 +#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
37414 +#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
37415 +#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
37416 +#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
37417 +#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
37418 +#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
37419 +#define BMCR_RESET 0x8000 /* Reset the DP83840 */
37421 +/* Basic mode status register. */
37422 +#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
37423 +#define BMSR_JCD 0x0002 /* Jabber detected */
37424 +#define BMSR_LSTATUS 0x0004 /* Link status */
37425 +#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
37426 +#define BMSR_RFAULT 0x0010 /* Remote fault detected */
37427 +#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
37428 +#define BMSR_RESV 0x07c0 /* Unused... */
37429 +#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
37430 +#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
37431 +#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
37432 +#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
37433 +#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
37435 +/* Advertisement control register. */
37436 +#define ADVERTISE_SLCT 0x001f /* Selector bits */
37437 +#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
37438 +#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
37439 +#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
37440 +#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
37441 +#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
37442 +#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
37443 +#define ADVERTISE_RESV 0x1c00 /* Unused... */
37444 +#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
37445 +#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
37446 +#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
37448 +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
37449 + ADVERTISE_CSMA)
37450 +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
37451 + ADVERTISE_100HALF | ADVERTISE_100FULL)
37453 +/* Link partner ability register. */
37454 +#define LPA_SLCT 0x001f /* Same as advertise selector */
37455 +#define LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */
37456 +#define LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */
37457 +#define LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */
37458 +#define LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */
37459 +#define LPA_100BASE4 0x0200 /* Can do 100mbps 4k packets */
37460 +#define LPA_RESV 0x1c00 /* Unused... */
37461 +#define LPA_RFAULT 0x2000 /* Link partner faulted */
37462 +#define LPA_LPACK 0x4000 /* Link partner acked us */
37463 +#define LPA_NPAGE 0x8000 /* Next page bit */
37465 +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
37466 +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
37468 +/* Expansion register for auto-negotiation. */
37469 +#define EXPANSION_NWAY 0x0001 /* Can do N-way auto-nego */
37470 +#define EXPANSION_LCWP 0x0002 /* Got new RX page code word */
37471 +#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */
37472 +#define EXPANSION_NPCAPABLE 0x0008 /* Link partner supports npage */
37473 +#define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */
37474 +#define EXPANSION_RESV 0xffe0 /* Unused... */
37476 +/* N-way test register. */
37477 +#define NWAYTEST_RESV1 0x00ff /* Unused... */
37478 +#define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */
37479 +#define NWAYTEST_RESV2 0xfe00 /* Unused... */
37482 +/* From tg3.h */
37484 +#define TG3_64BIT_REG_HIGH 0x00UL
37485 +#define TG3_64BIT_REG_LOW 0x04UL
37487 +/* Descriptor block info. */
37488 +#define TG3_BDINFO_HOST_ADDR 0x0UL /* 64-bit */
37489 +#define TG3_BDINFO_MAXLEN_FLAGS 0x8UL /* 32-bit */
37490 +#define BDINFO_FLAGS_USE_EXT_RECV 0x00000001 /* ext rx_buffer_desc */
37491 +#define BDINFO_FLAGS_DISABLED 0x00000002
37492 +#define BDINFO_FLAGS_MAXLEN_MASK 0xffff0000
37493 +#define BDINFO_FLAGS_MAXLEN_SHIFT 16
37494 +#define TG3_BDINFO_NIC_ADDR 0xcUL /* 32-bit */
37495 +#define TG3_BDINFO_SIZE 0x10UL
37497 +#define RX_COPY_THRESHOLD 256
37499 +#define RX_STD_MAX_SIZE 1536
37500 +#define RX_STD_MAX_SIZE_5705 512
37501 +#define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */
37503 +/* First 256 bytes are a mirror of PCI config space. */
37504 +#define TG3PCI_VENDOR 0x00000000
37505 +#define TG3PCI_VENDOR_BROADCOM 0x14e4
37506 +#define TG3PCI_DEVICE 0x00000002
37507 +#define TG3PCI_DEVICE_TIGON3_1 0x1644 /* BCM5700 */
37508 +#define TG3PCI_DEVICE_TIGON3_2 0x1645 /* BCM5701 */
37509 +#define TG3PCI_DEVICE_TIGON3_3 0x1646 /* BCM5702 */
37510 +#define TG3PCI_DEVICE_TIGON3_4 0x1647 /* BCM5703 */
37511 +#define TG3PCI_COMMAND 0x00000004
37512 +#define TG3PCI_STATUS 0x00000006
37513 +#define TG3PCI_CCREVID 0x00000008
37514 +#define TG3PCI_CACHELINESZ 0x0000000c
37515 +#define TG3PCI_LATTIMER 0x0000000d
37516 +#define TG3PCI_HEADERTYPE 0x0000000e
37517 +#define TG3PCI_BIST 0x0000000f
37518 +#define TG3PCI_BASE0_LOW 0x00000010
37519 +#define TG3PCI_BASE0_HIGH 0x00000014
37520 +/* 0x18 --> 0x2c unused */
37521 +#define TG3PCI_SUBSYSVENID 0x0000002c
37522 +#define TG3PCI_SUBSYSID 0x0000002e
37523 +#define TG3PCI_ROMADDR 0x00000030
37524 +#define TG3PCI_CAPLIST 0x00000034
37525 +/* 0x35 --> 0x3c unused */
37526 +#define TG3PCI_IRQ_LINE 0x0000003c
37527 +#define TG3PCI_IRQ_PIN 0x0000003d
37528 +#define TG3PCI_MIN_GNT 0x0000003e
37529 +#define TG3PCI_MAX_LAT 0x0000003f
37530 +#define TG3PCI_X_CAPS 0x00000040
37531 +#define PCIX_CAPS_RELAXED_ORDERING 0x00020000
37532 +#define PCIX_CAPS_SPLIT_MASK 0x00700000
37533 +#define PCIX_CAPS_SPLIT_SHIFT 20
37534 +#define PCIX_CAPS_BURST_MASK 0x000c0000
37535 +#define PCIX_CAPS_BURST_SHIFT 18
37536 +#define PCIX_CAPS_MAX_BURST_CPIOB 2
37537 +#define TG3PCI_PM_CAP_PTR 0x00000041
37538 +#define TG3PCI_X_COMMAND 0x00000042
37539 +#define TG3PCI_X_STATUS 0x00000044
37540 +#define TG3PCI_PM_CAP_ID 0x00000048
37541 +#define TG3PCI_VPD_CAP_PTR 0x00000049
37542 +#define TG3PCI_PM_CAPS 0x0000004a
37543 +#define TG3PCI_PM_CTRL_STAT 0x0000004c
37544 +#define TG3PCI_BR_SUPP_EXT 0x0000004e
37545 +#define TG3PCI_PM_DATA 0x0000004f
37546 +#define TG3PCI_VPD_CAP_ID 0x00000050
37547 +#define TG3PCI_MSI_CAP_PTR 0x00000051
37548 +#define TG3PCI_VPD_ADDR_FLAG 0x00000052
37549 +#define VPD_ADDR_FLAG_WRITE 0x00008000
37550 +#define TG3PCI_VPD_DATA 0x00000054
37551 +#define TG3PCI_MSI_CAP_ID 0x00000058
37552 +#define TG3PCI_NXT_CAP_PTR 0x00000059
37553 +#define TG3PCI_MSI_CTRL 0x0000005a
37554 +#define TG3PCI_MSI_ADDR_LOW 0x0000005c
37555 +#define TG3PCI_MSI_ADDR_HIGH 0x00000060
37556 +#define TG3PCI_MSI_DATA 0x00000064
37557 +/* 0x66 --> 0x68 unused */
37558 +#define TG3PCI_MISC_HOST_CTRL 0x00000068
37559 +#define MISC_HOST_CTRL_CLEAR_INT 0x00000001
37560 +#define MISC_HOST_CTRL_MASK_PCI_INT 0x00000002
37561 +#define MISC_HOST_CTRL_BYTE_SWAP 0x00000004
37562 +#define MISC_HOST_CTRL_WORD_SWAP 0x00000008
37563 +#define MISC_HOST_CTRL_PCISTATE_RW 0x00000010
37564 +#define MISC_HOST_CTRL_CLKREG_RW 0x00000020
37565 +#define MISC_HOST_CTRL_REGWORD_SWAP 0x00000040
37566 +#define MISC_HOST_CTRL_INDIR_ACCESS 0x00000080
37567 +#define MISC_HOST_CTRL_IRQ_MASK_MODE 0x00000100
37568 +#define MISC_HOST_CTRL_TAGGED_STATUS 0x00000200
37569 +#define MISC_HOST_CTRL_CHIPREV 0xffff0000
37570 +#define MISC_HOST_CTRL_CHIPREV_SHIFT 16
37571 +#define GET_CHIP_REV_ID(MISC_HOST_CTRL) \
37572 + (((MISC_HOST_CTRL) & MISC_HOST_CTRL_CHIPREV) >> \
37573 + MISC_HOST_CTRL_CHIPREV_SHIFT)
37574 +#define CHIPREV_ID_5700_A0 0x7000
37575 +#define CHIPREV_ID_5700_A1 0x7001
37576 +#define CHIPREV_ID_5700_B0 0x7100
37577 +#define CHIPREV_ID_5700_B1 0x7101
37578 +#define CHIPREV_ID_5700_B3 0x7102
37579 +#define CHIPREV_ID_5700_ALTIMA 0x7104
37580 +#define CHIPREV_ID_5700_C0 0x7200
37581 +#define CHIPREV_ID_5701_A0 0x0000
37582 +#define CHIPREV_ID_5701_B0 0x0100
37583 +#define CHIPREV_ID_5701_B2 0x0102
37584 +#define CHIPREV_ID_5701_B5 0x0105
37585 +#define CHIPREV_ID_5703_A0 0x1000
37586 +#define CHIPREV_ID_5703_A1 0x1001
37587 +#define CHIPREV_ID_5703_A2 0x1002
37588 +#define CHIPREV_ID_5703_A3 0x1003
37589 +#define CHIPREV_ID_5704_A0 0x2000
37590 +#define CHIPREV_ID_5704_A1 0x2001
37591 +#define CHIPREV_ID_5704_A2 0x2002
37592 +#define CHIPREV_ID_5705_A0 0x3000
37593 +#define CHIPREV_ID_5705_A1 0x3001
37594 +#define CHIPREV_ID_5705_A2 0x3002
37595 +#define CHIPREV_ID_5705_A3 0x3003
37596 +#define GET_ASIC_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 12)
37597 +#define ASIC_REV_5700 0x07
37598 +#define ASIC_REV_5701 0x00
37599 +#define ASIC_REV_5703 0x01
37600 +#define ASIC_REV_5704 0x02
37601 +#define ASIC_REV_5705 0x03
37602 +#define GET_CHIP_REV(CHIP_REV_ID) ((CHIP_REV_ID) >> 8)
37603 +#define CHIPREV_5700_AX 0x70
37604 +#define CHIPREV_5700_BX 0x71
37605 +#define CHIPREV_5700_CX 0x72
37606 +#define CHIPREV_5701_AX 0x00
37607 +#define GET_METAL_REV(CHIP_REV_ID) ((CHIP_REV_ID) & 0xff)
37608 +#define METAL_REV_A0 0x00
37609 +#define METAL_REV_A1 0x01
37610 +#define METAL_REV_B0 0x00
37611 +#define METAL_REV_B1 0x01
37612 +#define METAL_REV_B2 0x02
37613 +#define TG3PCI_DMA_RW_CTRL 0x0000006c
37614 +#define DMA_RWCTRL_MIN_DMA 0x000000ff
37615 +#define DMA_RWCTRL_MIN_DMA_SHIFT 0
37616 +#define DMA_RWCTRL_READ_BNDRY_MASK 0x00000700
37617 +#define DMA_RWCTRL_READ_BNDRY_DISAB 0x00000000
37618 +#define DMA_RWCTRL_READ_BNDRY_16 0x00000100
37619 +#define DMA_RWCTRL_READ_BNDRY_32 0x00000200
37620 +#define DMA_RWCTRL_READ_BNDRY_64 0x00000300
37621 +#define DMA_RWCTRL_READ_BNDRY_128 0x00000400
37622 +#define DMA_RWCTRL_READ_BNDRY_256 0x00000500
37623 +#define DMA_RWCTRL_READ_BNDRY_512 0x00000600
37624 +#define DMA_RWCTRL_READ_BNDRY_1024 0x00000700
37625 +#define DMA_RWCTRL_WRITE_BNDRY_MASK 0x00003800
37626 +#define DMA_RWCTRL_WRITE_BNDRY_DISAB 0x00000000
37627 +#define DMA_RWCTRL_WRITE_BNDRY_16 0x00000800
37628 +#define DMA_RWCTRL_WRITE_BNDRY_32 0x00001000
37629 +#define DMA_RWCTRL_WRITE_BNDRY_64 0x00001800
37630 +#define DMA_RWCTRL_WRITE_BNDRY_128 0x00002000
37631 +#define DMA_RWCTRL_WRITE_BNDRY_256 0x00002800
37632 +#define DMA_RWCTRL_WRITE_BNDRY_512 0x00003000
37633 +#define DMA_RWCTRL_WRITE_BNDRY_1024 0x00003800
37634 +#define DMA_RWCTRL_ONE_DMA 0x00004000
37635 +#define DMA_RWCTRL_READ_WATER 0x00070000
37636 +#define DMA_RWCTRL_READ_WATER_SHIFT 16
37637 +#define DMA_RWCTRL_WRITE_WATER 0x00380000
37638 +#define DMA_RWCTRL_WRITE_WATER_SHIFT 19
37639 +#define DMA_RWCTRL_USE_MEM_READ_MULT 0x00400000
37640 +#define DMA_RWCTRL_ASSERT_ALL_BE 0x00800000
37641 +#define DMA_RWCTRL_PCI_READ_CMD 0x0f000000
37642 +#define DMA_RWCTRL_PCI_READ_CMD_SHIFT 24
37643 +#define DMA_RWCTRL_PCI_WRITE_CMD 0xf0000000
37644 +#define DMA_RWCTRL_PCI_WRITE_CMD_SHIFT 28
37645 +#define TG3PCI_PCISTATE 0x00000070
37646 +#define PCISTATE_FORCE_RESET 0x00000001
37647 +#define PCISTATE_INT_NOT_ACTIVE 0x00000002
37648 +#define PCISTATE_CONV_PCI_MODE 0x00000004
37649 +#define PCISTATE_BUS_SPEED_HIGH 0x00000008
37650 +#define PCISTATE_BUS_32BIT 0x00000010
37651 +#define PCISTATE_ROM_ENABLE 0x00000020
37652 +#define PCISTATE_ROM_RETRY_ENABLE 0x00000040
37653 +#define PCISTATE_FLAT_VIEW 0x00000100
37654 +#define PCISTATE_RETRY_SAME_DMA 0x00002000
37655 +#define TG3PCI_CLOCK_CTRL 0x00000074
37656 +#define CLOCK_CTRL_CORECLK_DISABLE 0x00000200
37657 +#define CLOCK_CTRL_RXCLK_DISABLE 0x00000400
37658 +#define CLOCK_CTRL_TXCLK_DISABLE 0x00000800
37659 +#define CLOCK_CTRL_ALTCLK 0x00001000
37660 +#define CLOCK_CTRL_PWRDOWN_PLL133 0x00008000
37661 +#define CLOCK_CTRL_44MHZ_CORE 0x00040000
37662 +#define CLOCK_CTRL_625_CORE 0x00100000
37663 +#define CLOCK_CTRL_FORCE_CLKRUN 0x00200000
37664 +#define CLOCK_CTRL_CLKRUN_OENABLE 0x00400000
37665 +#define CLOCK_CTRL_DELAY_PCI_GRANT 0x80000000
37666 +#define TG3PCI_REG_BASE_ADDR 0x00000078
37667 +#define TG3PCI_MEM_WIN_BASE_ADDR 0x0000007c
37668 +#define TG3PCI_REG_DATA 0x00000080
37669 +#define TG3PCI_MEM_WIN_DATA 0x00000084
37670 +#define TG3PCI_MODE_CTRL 0x00000088
37671 +#define TG3PCI_MISC_CFG 0x0000008c
37672 +#define TG3PCI_MISC_LOCAL_CTRL 0x00000090
37673 +/* 0x94 --> 0x98 unused */
37674 +#define TG3PCI_STD_RING_PROD_IDX 0x00000098 /* 64-bit */
37675 +#define TG3PCI_RCV_RET_RING_CON_IDX 0x000000a0 /* 64-bit */
37676 +#define TG3PCI_SND_PROD_IDX 0x000000a8 /* 64-bit */
37677 +/* 0xb0 --> 0x100 unused */
37679 +/* 0x100 --> 0x200 unused */
37681 +/* Mailbox registers */
37682 +#define MAILBOX_INTERRUPT_0 0x00000200 /* 64-bit */
37683 +#define MAILBOX_INTERRUPT_1 0x00000208 /* 64-bit */
37684 +#define MAILBOX_INTERRUPT_2 0x00000210 /* 64-bit */
37685 +#define MAILBOX_INTERRUPT_3 0x00000218 /* 64-bit */
37686 +#define MAILBOX_GENERAL_0 0x00000220 /* 64-bit */
37687 +#define MAILBOX_GENERAL_1 0x00000228 /* 64-bit */
37688 +#define MAILBOX_GENERAL_2 0x00000230 /* 64-bit */
37689 +#define MAILBOX_GENERAL_3 0x00000238 /* 64-bit */
37690 +#define MAILBOX_GENERAL_4 0x00000240 /* 64-bit */
37691 +#define MAILBOX_GENERAL_5 0x00000248 /* 64-bit */
37692 +#define MAILBOX_GENERAL_6 0x00000250 /* 64-bit */
37693 +#define MAILBOX_GENERAL_7 0x00000258 /* 64-bit */
37694 +#define MAILBOX_RELOAD_STAT 0x00000260 /* 64-bit */
37695 +#define MAILBOX_RCV_STD_PROD_IDX 0x00000268 /* 64-bit */
37696 +#define MAILBOX_RCV_JUMBO_PROD_IDX 0x00000270 /* 64-bit */
37697 +#define MAILBOX_RCV_MINI_PROD_IDX 0x00000278 /* 64-bit */
37698 +#define MAILBOX_RCVRET_CON_IDX_0 0x00000280 /* 64-bit */
37699 +#define MAILBOX_RCVRET_CON_IDX_1 0x00000288 /* 64-bit */
37700 +#define MAILBOX_RCVRET_CON_IDX_2 0x00000290 /* 64-bit */
37701 +#define MAILBOX_RCVRET_CON_IDX_3 0x00000298 /* 64-bit */
37702 +#define MAILBOX_RCVRET_CON_IDX_4 0x000002a0 /* 64-bit */
37703 +#define MAILBOX_RCVRET_CON_IDX_5 0x000002a8 /* 64-bit */
37704 +#define MAILBOX_RCVRET_CON_IDX_6 0x000002b0 /* 64-bit */
37705 +#define MAILBOX_RCVRET_CON_IDX_7 0x000002b8 /* 64-bit */
37706 +#define MAILBOX_RCVRET_CON_IDX_8 0x000002c0 /* 64-bit */
37707 +#define MAILBOX_RCVRET_CON_IDX_9 0x000002c8 /* 64-bit */
37708 +#define MAILBOX_RCVRET_CON_IDX_10 0x000002d0 /* 64-bit */
37709 +#define MAILBOX_RCVRET_CON_IDX_11 0x000002d8 /* 64-bit */
37710 +#define MAILBOX_RCVRET_CON_IDX_12 0x000002e0 /* 64-bit */
37711 +#define MAILBOX_RCVRET_CON_IDX_13 0x000002e8 /* 64-bit */
37712 +#define MAILBOX_RCVRET_CON_IDX_14 0x000002f0 /* 64-bit */
37713 +#define MAILBOX_RCVRET_CON_IDX_15 0x000002f8 /* 64-bit */
37714 +#define MAILBOX_SNDHOST_PROD_IDX_0 0x00000300 /* 64-bit */
37715 +#define MAILBOX_SNDHOST_PROD_IDX_1 0x00000308 /* 64-bit */
37716 +#define MAILBOX_SNDHOST_PROD_IDX_2 0x00000310 /* 64-bit */
37717 +#define MAILBOX_SNDHOST_PROD_IDX_3 0x00000318 /* 64-bit */
37718 +#define MAILBOX_SNDHOST_PROD_IDX_4 0x00000320 /* 64-bit */
37719 +#define MAILBOX_SNDHOST_PROD_IDX_5 0x00000328 /* 64-bit */
37720 +#define MAILBOX_SNDHOST_PROD_IDX_6 0x00000330 /* 64-bit */
37721 +#define MAILBOX_SNDHOST_PROD_IDX_7 0x00000338 /* 64-bit */
37722 +#define MAILBOX_SNDHOST_PROD_IDX_8 0x00000340 /* 64-bit */
37723 +#define MAILBOX_SNDHOST_PROD_IDX_9 0x00000348 /* 64-bit */
37724 +#define MAILBOX_SNDHOST_PROD_IDX_10 0x00000350 /* 64-bit */
37725 +#define MAILBOX_SNDHOST_PROD_IDX_11 0x00000358 /* 64-bit */
37726 +#define MAILBOX_SNDHOST_PROD_IDX_12 0x00000360 /* 64-bit */
37727 +#define MAILBOX_SNDHOST_PROD_IDX_13 0x00000368 /* 64-bit */
37728 +#define MAILBOX_SNDHOST_PROD_IDX_14 0x00000370 /* 64-bit */
37729 +#define MAILBOX_SNDHOST_PROD_IDX_15 0x00000378 /* 64-bit */
37730 +#define MAILBOX_SNDNIC_PROD_IDX_0 0x00000380 /* 64-bit */
37731 +#define MAILBOX_SNDNIC_PROD_IDX_1 0x00000388 /* 64-bit */
37732 +#define MAILBOX_SNDNIC_PROD_IDX_2 0x00000390 /* 64-bit */
37733 +#define MAILBOX_SNDNIC_PROD_IDX_3 0x00000398 /* 64-bit */
37734 +#define MAILBOX_SNDNIC_PROD_IDX_4 0x000003a0 /* 64-bit */
37735 +#define MAILBOX_SNDNIC_PROD_IDX_5 0x000003a8 /* 64-bit */
37736 +#define MAILBOX_SNDNIC_PROD_IDX_6 0x000003b0 /* 64-bit */
37737 +#define MAILBOX_SNDNIC_PROD_IDX_7 0x000003b8 /* 64-bit */
37738 +#define MAILBOX_SNDNIC_PROD_IDX_8 0x000003c0 /* 64-bit */
37739 +#define MAILBOX_SNDNIC_PROD_IDX_9 0x000003c8 /* 64-bit */
37740 +#define MAILBOX_SNDNIC_PROD_IDX_10 0x000003d0 /* 64-bit */
37741 +#define MAILBOX_SNDNIC_PROD_IDX_11 0x000003d8 /* 64-bit */
37742 +#define MAILBOX_SNDNIC_PROD_IDX_12 0x000003e0 /* 64-bit */
37743 +#define MAILBOX_SNDNIC_PROD_IDX_13 0x000003e8 /* 64-bit */
37744 +#define MAILBOX_SNDNIC_PROD_IDX_14 0x000003f0 /* 64-bit */
37745 +#define MAILBOX_SNDNIC_PROD_IDX_15 0x000003f8 /* 64-bit */
37747 +/* MAC control registers */
37748 +#define MAC_MODE 0x00000400
37749 +#define MAC_MODE_RESET 0x00000001
37750 +#define MAC_MODE_HALF_DUPLEX 0x00000002
37751 +#define MAC_MODE_PORT_MODE_MASK 0x0000000c
37752 +#define MAC_MODE_PORT_MODE_TBI 0x0000000c
37753 +#define MAC_MODE_PORT_MODE_GMII 0x00000008
37754 +#define MAC_MODE_PORT_MODE_MII 0x00000004
37755 +#define MAC_MODE_PORT_MODE_NONE 0x00000000
37756 +#define MAC_MODE_PORT_INT_LPBACK 0x00000010
37757 +#define MAC_MODE_TAGGED_MAC_CTRL 0x00000080
37758 +#define MAC_MODE_TX_BURSTING 0x00000100
37759 +#define MAC_MODE_MAX_DEFER 0x00000200
37760 +#define MAC_MODE_LINK_POLARITY 0x00000400
37761 +#define MAC_MODE_RXSTAT_ENABLE 0x00000800
37762 +#define MAC_MODE_RXSTAT_CLEAR 0x00001000
37763 +#define MAC_MODE_RXSTAT_FLUSH 0x00002000
37764 +#define MAC_MODE_TXSTAT_ENABLE 0x00004000
37765 +#define MAC_MODE_TXSTAT_CLEAR 0x00008000
37766 +#define MAC_MODE_TXSTAT_FLUSH 0x00010000
37767 +#define MAC_MODE_SEND_CONFIGS 0x00020000
37768 +#define MAC_MODE_MAGIC_PKT_ENABLE 0x00040000
37769 +#define MAC_MODE_ACPI_ENABLE 0x00080000
37770 +#define MAC_MODE_MIP_ENABLE 0x00100000
37771 +#define MAC_MODE_TDE_ENABLE 0x00200000
37772 +#define MAC_MODE_RDE_ENABLE 0x00400000
37773 +#define MAC_MODE_FHDE_ENABLE 0x00800000
37774 +#define MAC_STATUS 0x00000404
37775 +#define MAC_STATUS_PCS_SYNCED 0x00000001
37776 +#define MAC_STATUS_SIGNAL_DET 0x00000002
37777 +#define MAC_STATUS_RCVD_CFG 0x00000004
37778 +#define MAC_STATUS_CFG_CHANGED 0x00000008
37779 +#define MAC_STATUS_SYNC_CHANGED 0x00000010
37780 +#define MAC_STATUS_PORT_DEC_ERR 0x00000400
37781 +#define MAC_STATUS_LNKSTATE_CHANGED 0x00001000
37782 +#define MAC_STATUS_MI_COMPLETION 0x00400000
37783 +#define MAC_STATUS_MI_INTERRUPT 0x00800000
37784 +#define MAC_STATUS_AP_ERROR 0x01000000
37785 +#define MAC_STATUS_ODI_ERROR 0x02000000
37786 +#define MAC_STATUS_RXSTAT_OVERRUN 0x04000000
37787 +#define MAC_STATUS_TXSTAT_OVERRUN 0x08000000
37788 +#define MAC_EVENT 0x00000408
37789 +#define MAC_EVENT_PORT_DECODE_ERR 0x00000400
37790 +#define MAC_EVENT_LNKSTATE_CHANGED 0x00001000
37791 +#define MAC_EVENT_MI_COMPLETION 0x00400000
37792 +#define MAC_EVENT_MI_INTERRUPT 0x00800000
37793 +#define MAC_EVENT_AP_ERROR 0x01000000
37794 +#define MAC_EVENT_ODI_ERROR 0x02000000
37795 +#define MAC_EVENT_RXSTAT_OVERRUN 0x04000000
37796 +#define MAC_EVENT_TXSTAT_OVERRUN 0x08000000
37797 +#define MAC_LED_CTRL 0x0000040c
37798 +#define LED_CTRL_LNKLED_OVERRIDE 0x00000001
37799 +#define LED_CTRL_1000MBPS_ON 0x00000002
37800 +#define LED_CTRL_100MBPS_ON 0x00000004
37801 +#define LED_CTRL_10MBPS_ON 0x00000008
37802 +#define LED_CTRL_TRAFFIC_OVERRIDE 0x00000010
37803 +#define LED_CTRL_TRAFFIC_BLINK 0x00000020
37804 +#define LED_CTRL_TRAFFIC_LED 0x00000040
37805 +#define LED_CTRL_1000MBPS_STATUS 0x00000080
37806 +#define LED_CTRL_100MBPS_STATUS 0x00000100
37807 +#define LED_CTRL_10MBPS_STATUS 0x00000200
37808 +#define LED_CTRL_TRAFFIC_STATUS 0x00000400
37809 +#define LED_CTRL_MAC_MODE 0x00000000
37810 +#define LED_CTRL_PHY_MODE_1 0x00000800
37811 +#define LED_CTRL_PHY_MODE_2 0x00001000
37812 +#define LED_CTRL_BLINK_RATE_MASK 0x7ff80000
37813 +#define LED_CTRL_BLINK_RATE_SHIFT 19
37814 +#define LED_CTRL_BLINK_PER_OVERRIDE 0x00080000
37815 +#define LED_CTRL_BLINK_RATE_OVERRIDE 0x80000000
37816 +#define MAC_ADDR_0_HIGH 0x00000410 /* upper 2 bytes */
37817 +#define MAC_ADDR_0_LOW 0x00000414 /* lower 4 bytes */
37818 +#define MAC_ADDR_1_HIGH 0x00000418 /* upper 2 bytes */
37819 +#define MAC_ADDR_1_LOW 0x0000041c /* lower 4 bytes */
37820 +#define MAC_ADDR_2_HIGH 0x00000420 /* upper 2 bytes */
37821 +#define MAC_ADDR_2_LOW 0x00000424 /* lower 4 bytes */
37822 +#define MAC_ADDR_3_HIGH 0x00000428 /* upper 2 bytes */
37823 +#define MAC_ADDR_3_LOW 0x0000042c /* lower 4 bytes */
37824 +#define MAC_ACPI_MBUF_PTR 0x00000430
37825 +#define MAC_ACPI_LEN_OFFSET 0x00000434
37826 +#define ACPI_LENOFF_LEN_MASK 0x0000ffff
37827 +#define ACPI_LENOFF_LEN_SHIFT 0
37828 +#define ACPI_LENOFF_OFF_MASK 0x0fff0000
37829 +#define ACPI_LENOFF_OFF_SHIFT 16
37830 +#define MAC_TX_BACKOFF_SEED 0x00000438
37831 +#define TX_BACKOFF_SEED_MASK 0x000003ff
37832 +#define MAC_RX_MTU_SIZE 0x0000043c
37833 +#define RX_MTU_SIZE_MASK 0x0000ffff
37834 +#define MAC_PCS_TEST 0x00000440
37835 +#define PCS_TEST_PATTERN_MASK 0x000fffff
37836 +#define PCS_TEST_PATTERN_SHIFT 0
37837 +#define PCS_TEST_ENABLE 0x00100000
37838 +#define MAC_TX_AUTO_NEG 0x00000444
37839 +#define TX_AUTO_NEG_MASK 0x0000ffff
37840 +#define TX_AUTO_NEG_SHIFT 0
37841 +#define MAC_RX_AUTO_NEG 0x00000448
37842 +#define RX_AUTO_NEG_MASK 0x0000ffff
37843 +#define RX_AUTO_NEG_SHIFT 0
37844 +#define MAC_MI_COM 0x0000044c
37845 +#define MI_COM_CMD_MASK 0x0c000000
37846 +#define MI_COM_CMD_WRITE 0x04000000
37847 +#define MI_COM_CMD_READ 0x08000000
37848 +#define MI_COM_READ_FAILED 0x10000000
37849 +#define MI_COM_START 0x20000000
37850 +#define MI_COM_BUSY 0x20000000
37851 +#define MI_COM_PHY_ADDR_MASK 0x03e00000
37852 +#define MI_COM_PHY_ADDR_SHIFT 21
37853 +#define MI_COM_REG_ADDR_MASK 0x001f0000
37854 +#define MI_COM_REG_ADDR_SHIFT 16
37855 +#define MI_COM_DATA_MASK 0x0000ffff
37856 +#define MAC_MI_STAT 0x00000450
37857 +#define MAC_MI_STAT_LNKSTAT_ATTN_ENAB 0x00000001
37858 +#define MAC_MI_MODE 0x00000454
37859 +#define MAC_MI_MODE_CLK_10MHZ 0x00000001
37860 +#define MAC_MI_MODE_SHORT_PREAMBLE 0x00000002
37861 +#define MAC_MI_MODE_AUTO_POLL 0x00000010
37862 +#define MAC_MI_MODE_CORE_CLK_62MHZ 0x00008000
37863 +#define MAC_MI_MODE_BASE 0x000c0000 /* XXX magic values XXX */
37864 +#define MAC_AUTO_POLL_STATUS 0x00000458
37865 +#define MAC_AUTO_POLL_ERROR 0x00000001
37866 +#define MAC_TX_MODE 0x0000045c
37867 +#define TX_MODE_RESET 0x00000001
37868 +#define TX_MODE_ENABLE 0x00000002
37869 +#define TX_MODE_FLOW_CTRL_ENABLE 0x00000010
37870 +#define TX_MODE_BIG_BCKOFF_ENABLE 0x00000020
37871 +#define TX_MODE_LONG_PAUSE_ENABLE 0x00000040
37872 +#define MAC_TX_STATUS 0x00000460
37873 +#define TX_STATUS_XOFFED 0x00000001
37874 +#define TX_STATUS_SENT_XOFF 0x00000002
37875 +#define TX_STATUS_SENT_XON 0x00000004
37876 +#define TX_STATUS_LINK_UP 0x00000008
37877 +#define TX_STATUS_ODI_UNDERRUN 0x00000010
37878 +#define TX_STATUS_ODI_OVERRUN 0x00000020
37879 +#define MAC_TX_LENGTHS 0x00000464
37880 +#define TX_LENGTHS_SLOT_TIME_MASK 0x000000ff
37881 +#define TX_LENGTHS_SLOT_TIME_SHIFT 0
37882 +#define TX_LENGTHS_IPG_MASK 0x00000f00
37883 +#define TX_LENGTHS_IPG_SHIFT 8
37884 +#define TX_LENGTHS_IPG_CRS_MASK 0x00003000
37885 +#define TX_LENGTHS_IPG_CRS_SHIFT 12
37886 +#define MAC_RX_MODE 0x00000468
37887 +#define RX_MODE_RESET 0x00000001
37888 +#define RX_MODE_ENABLE 0x00000002
37889 +#define RX_MODE_FLOW_CTRL_ENABLE 0x00000004
37890 +#define RX_MODE_KEEP_MAC_CTRL 0x00000008
37891 +#define RX_MODE_KEEP_PAUSE 0x00000010
37892 +#define RX_MODE_ACCEPT_OVERSIZED 0x00000020
37893 +#define RX_MODE_ACCEPT_RUNTS 0x00000040
37894 +#define RX_MODE_LEN_CHECK 0x00000080
37895 +#define RX_MODE_PROMISC 0x00000100
37896 +#define RX_MODE_NO_CRC_CHECK 0x00000200
37897 +#define RX_MODE_KEEP_VLAN_TAG 0x00000400
37898 +#define MAC_RX_STATUS 0x0000046c
37899 +#define RX_STATUS_REMOTE_TX_XOFFED 0x00000001
37900 +#define RX_STATUS_XOFF_RCVD 0x00000002
37901 +#define RX_STATUS_XON_RCVD 0x00000004
37902 +#define MAC_HASH_REG_0 0x00000470
37903 +#define MAC_HASH_REG_1 0x00000474
37904 +#define MAC_HASH_REG_2 0x00000478
37905 +#define MAC_HASH_REG_3 0x0000047c
37906 +#define MAC_RCV_RULE_0 0x00000480
37907 +#define MAC_RCV_VALUE_0 0x00000484
37908 +#define MAC_RCV_RULE_1 0x00000488
37909 +#define MAC_RCV_VALUE_1 0x0000048c
37910 +#define MAC_RCV_RULE_2 0x00000490
37911 +#define MAC_RCV_VALUE_2 0x00000494
37912 +#define MAC_RCV_RULE_3 0x00000498
37913 +#define MAC_RCV_VALUE_3 0x0000049c
37914 +#define MAC_RCV_RULE_4 0x000004a0
37915 +#define MAC_RCV_VALUE_4 0x000004a4
37916 +#define MAC_RCV_RULE_5 0x000004a8
37917 +#define MAC_RCV_VALUE_5 0x000004ac
37918 +#define MAC_RCV_RULE_6 0x000004b0
37919 +#define MAC_RCV_VALUE_6 0x000004b4
37920 +#define MAC_RCV_RULE_7 0x000004b8
37921 +#define MAC_RCV_VALUE_7 0x000004bc
37922 +#define MAC_RCV_RULE_8 0x000004c0
37923 +#define MAC_RCV_VALUE_8 0x000004c4
37924 +#define MAC_RCV_RULE_9 0x000004c8
37925 +#define MAC_RCV_VALUE_9 0x000004cc
37926 +#define MAC_RCV_RULE_10 0x000004d0
37927 +#define MAC_RCV_VALUE_10 0x000004d4
37928 +#define MAC_RCV_RULE_11 0x000004d8
37929 +#define MAC_RCV_VALUE_11 0x000004dc
37930 +#define MAC_RCV_RULE_12 0x000004e0
37931 +#define MAC_RCV_VALUE_12 0x000004e4
37932 +#define MAC_RCV_RULE_13 0x000004e8
37933 +#define MAC_RCV_VALUE_13 0x000004ec
37934 +#define MAC_RCV_RULE_14 0x000004f0
37935 +#define MAC_RCV_VALUE_14 0x000004f4
37936 +#define MAC_RCV_RULE_15 0x000004f8
37937 +#define MAC_RCV_VALUE_15 0x000004fc
37938 +#define RCV_RULE_DISABLE_MASK 0x7fffffff
37939 +#define MAC_RCV_RULE_CFG 0x00000500
37940 +#define RCV_RULE_CFG_DEFAULT_CLASS 0x00000008
37941 +#define MAC_LOW_WMARK_MAX_RX_FRAME 0x00000504
37942 +/* 0x508 --> 0x520 unused */
37943 +#define MAC_HASHREGU_0 0x00000520
37944 +#define MAC_HASHREGU_1 0x00000524
37945 +#define MAC_HASHREGU_2 0x00000528
37946 +#define MAC_HASHREGU_3 0x0000052c
37947 +#define MAC_EXTADDR_0_HIGH 0x00000530
37948 +#define MAC_EXTADDR_0_LOW 0x00000534
37949 +#define MAC_EXTADDR_1_HIGH 0x00000538
37950 +#define MAC_EXTADDR_1_LOW 0x0000053c
37951 +#define MAC_EXTADDR_2_HIGH 0x00000540
37952 +#define MAC_EXTADDR_2_LOW 0x00000544
37953 +#define MAC_EXTADDR_3_HIGH 0x00000548
37954 +#define MAC_EXTADDR_3_LOW 0x0000054c
37955 +#define MAC_EXTADDR_4_HIGH 0x00000550
37956 +#define MAC_EXTADDR_4_LOW 0x00000554
37957 +#define MAC_EXTADDR_5_HIGH 0x00000558
37958 +#define MAC_EXTADDR_5_LOW 0x0000055c
37959 +#define MAC_EXTADDR_6_HIGH 0x00000560
37960 +#define MAC_EXTADDR_6_LOW 0x00000564
37961 +#define MAC_EXTADDR_7_HIGH 0x00000568
37962 +#define MAC_EXTADDR_7_LOW 0x0000056c
37963 +#define MAC_EXTADDR_8_HIGH 0x00000570
37964 +#define MAC_EXTADDR_8_LOW 0x00000574
37965 +#define MAC_EXTADDR_9_HIGH 0x00000578
37966 +#define MAC_EXTADDR_9_LOW 0x0000057c
37967 +#define MAC_EXTADDR_10_HIGH 0x00000580
37968 +#define MAC_EXTADDR_10_LOW 0x00000584
37969 +#define MAC_EXTADDR_11_HIGH 0x00000588
37970 +#define MAC_EXTADDR_11_LOW 0x0000058c
37971 +#define MAC_SERDES_CFG 0x00000590
37972 +#define MAC_SERDES_STAT 0x00000594
37973 +/* 0x598 --> 0x600 unused */
37974 +#define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */
37975 +#define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */
37976 +/* 0x624 --> 0x800 unused */
37977 +#define MAC_TX_STATS_OCTETS 0x00000800
37978 +#define MAC_TX_STATS_RESV1 0x00000804
37979 +#define MAC_TX_STATS_COLLISIONS 0x00000808
37980 +#define MAC_TX_STATS_XON_SENT 0x0000080c
37981 +#define MAC_TX_STATS_XOFF_SENT 0x00000810
37982 +#define MAC_TX_STATS_RESV2 0x00000814
37983 +#define MAC_TX_STATS_MAC_ERRORS 0x00000818
37984 +#define MAC_TX_STATS_SINGLE_COLLISIONS 0x0000081c
37985 +#define MAC_TX_STATS_MULT_COLLISIONS 0x00000820
37986 +#define MAC_TX_STATS_DEFERRED 0x00000824
37987 +#define MAC_TX_STATS_RESV3 0x00000828
37988 +#define MAC_TX_STATS_EXCESSIVE_COL 0x0000082c
37989 +#define MAC_TX_STATS_LATE_COL 0x00000830
37990 +#define MAC_TX_STATS_RESV4_1 0x00000834
37991 +#define MAC_TX_STATS_RESV4_2 0x00000838
37992 +#define MAC_TX_STATS_RESV4_3 0x0000083c
37993 +#define MAC_TX_STATS_RESV4_4 0x00000840
37994 +#define MAC_TX_STATS_RESV4_5 0x00000844
37995 +#define MAC_TX_STATS_RESV4_6 0x00000848
37996 +#define MAC_TX_STATS_RESV4_7 0x0000084c
37997 +#define MAC_TX_STATS_RESV4_8 0x00000850
37998 +#define MAC_TX_STATS_RESV4_9 0x00000854
37999 +#define MAC_TX_STATS_RESV4_10 0x00000858
38000 +#define MAC_TX_STATS_RESV4_11 0x0000085c
38001 +#define MAC_TX_STATS_RESV4_12 0x00000860
38002 +#define MAC_TX_STATS_RESV4_13 0x00000864
38003 +#define MAC_TX_STATS_RESV4_14 0x00000868
38004 +#define MAC_TX_STATS_UCAST 0x0000086c
38005 +#define MAC_TX_STATS_MCAST 0x00000870
38006 +#define MAC_TX_STATS_BCAST 0x00000874
38007 +#define MAC_TX_STATS_RESV5_1 0x00000878
38008 +#define MAC_TX_STATS_RESV5_2 0x0000087c
38009 +#define MAC_RX_STATS_OCTETS 0x00000880
38010 +#define MAC_RX_STATS_RESV1 0x00000884
38011 +#define MAC_RX_STATS_FRAGMENTS 0x00000888
38012 +#define MAC_RX_STATS_UCAST 0x0000088c
38013 +#define MAC_RX_STATS_MCAST 0x00000890
38014 +#define MAC_RX_STATS_BCAST 0x00000894
38015 +#define MAC_RX_STATS_FCS_ERRORS 0x00000898
38016 +#define MAC_RX_STATS_ALIGN_ERRORS 0x0000089c
38017 +#define MAC_RX_STATS_XON_PAUSE_RECVD 0x000008a0
38018 +#define MAC_RX_STATS_XOFF_PAUSE_RECVD 0x000008a4
38019 +#define MAC_RX_STATS_MAC_CTRL_RECVD 0x000008a8
38020 +#define MAC_RX_STATS_XOFF_ENTERED 0x000008ac
38021 +#define MAC_RX_STATS_FRAME_TOO_LONG 0x000008b0
38022 +#define MAC_RX_STATS_JABBERS 0x000008b4
38023 +#define MAC_RX_STATS_UNDERSIZE 0x000008b8
38024 +/* 0x8bc --> 0xc00 unused */
38026 +/* Send data initiator control registers */
38027 +#define SNDDATAI_MODE 0x00000c00
38028 +#define SNDDATAI_MODE_RESET 0x00000001
38029 +#define SNDDATAI_MODE_ENABLE 0x00000002
38030 +#define SNDDATAI_MODE_STAT_OFLOW_ENAB 0x00000004
38031 +#define SNDDATAI_STATUS 0x00000c04
38032 +#define SNDDATAI_STATUS_STAT_OFLOW 0x00000004
38033 +#define SNDDATAI_STATSCTRL 0x00000c08
38034 +#define SNDDATAI_SCTRL_ENABLE 0x00000001
38035 +#define SNDDATAI_SCTRL_FASTUPD 0x00000002
38036 +#define SNDDATAI_SCTRL_CLEAR 0x00000004
38037 +#define SNDDATAI_SCTRL_FLUSH 0x00000008
38038 +#define SNDDATAI_SCTRL_FORCE_ZERO 0x00000010
38039 +#define SNDDATAI_STATSENAB 0x00000c0c
38040 +#define SNDDATAI_STATSINCMASK 0x00000c10
38041 +/* 0xc14 --> 0xc80 unused */
38042 +#define SNDDATAI_COS_CNT_0 0x00000c80
38043 +#define SNDDATAI_COS_CNT_1 0x00000c84
38044 +#define SNDDATAI_COS_CNT_2 0x00000c88
38045 +#define SNDDATAI_COS_CNT_3 0x00000c8c
38046 +#define SNDDATAI_COS_CNT_4 0x00000c90
38047 +#define SNDDATAI_COS_CNT_5 0x00000c94
38048 +#define SNDDATAI_COS_CNT_6 0x00000c98
38049 +#define SNDDATAI_COS_CNT_7 0x00000c9c
38050 +#define SNDDATAI_COS_CNT_8 0x00000ca0
38051 +#define SNDDATAI_COS_CNT_9 0x00000ca4
38052 +#define SNDDATAI_COS_CNT_10 0x00000ca8
38053 +#define SNDDATAI_COS_CNT_11 0x00000cac
38054 +#define SNDDATAI_COS_CNT_12 0x00000cb0
38055 +#define SNDDATAI_COS_CNT_13 0x00000cb4
38056 +#define SNDDATAI_COS_CNT_14 0x00000cb8
38057 +#define SNDDATAI_COS_CNT_15 0x00000cbc
38058 +#define SNDDATAI_DMA_RDQ_FULL_CNT 0x00000cc0
38059 +#define SNDDATAI_DMA_PRIO_RDQ_FULL_CNT 0x00000cc4
38060 +#define SNDDATAI_SDCQ_FULL_CNT 0x00000cc8
38061 +#define SNDDATAI_NICRNG_SSND_PIDX_CNT 0x00000ccc
38062 +#define SNDDATAI_STATS_UPDATED_CNT 0x00000cd0
38063 +#define SNDDATAI_INTERRUPTS_CNT 0x00000cd4
38064 +#define SNDDATAI_AVOID_INTERRUPTS_CNT 0x00000cd8
38065 +#define SNDDATAI_SND_THRESH_HIT_CNT 0x00000cdc
38066 +/* 0xce0 --> 0x1000 unused */
38068 +/* Send data completion control registers */
38069 +#define SNDDATAC_MODE 0x00001000
38070 +#define SNDDATAC_MODE_RESET 0x00000001
38071 +#define SNDDATAC_MODE_ENABLE 0x00000002
38072 +/* 0x1004 --> 0x1400 unused */
38074 +/* Send BD ring selector */
38075 +#define SNDBDS_MODE 0x00001400
38076 +#define SNDBDS_MODE_RESET 0x00000001
38077 +#define SNDBDS_MODE_ENABLE 0x00000002
38078 +#define SNDBDS_MODE_ATTN_ENABLE 0x00000004
38079 +#define SNDBDS_STATUS 0x00001404
38080 +#define SNDBDS_STATUS_ERROR_ATTN 0x00000004
38081 +#define SNDBDS_HWDIAG 0x00001408
38082 +/* 0x140c --> 0x1440 */
38083 +#define SNDBDS_SEL_CON_IDX_0 0x00001440
38084 +#define SNDBDS_SEL_CON_IDX_1 0x00001444
38085 +#define SNDBDS_SEL_CON_IDX_2 0x00001448
38086 +#define SNDBDS_SEL_CON_IDX_3 0x0000144c
38087 +#define SNDBDS_SEL_CON_IDX_4 0x00001450
38088 +#define SNDBDS_SEL_CON_IDX_5 0x00001454
38089 +#define SNDBDS_SEL_CON_IDX_6 0x00001458
38090 +#define SNDBDS_SEL_CON_IDX_7 0x0000145c
38091 +#define SNDBDS_SEL_CON_IDX_8 0x00001460
38092 +#define SNDBDS_SEL_CON_IDX_9 0x00001464
38093 +#define SNDBDS_SEL_CON_IDX_10 0x00001468
38094 +#define SNDBDS_SEL_CON_IDX_11 0x0000146c
38095 +#define SNDBDS_SEL_CON_IDX_12 0x00001470
38096 +#define SNDBDS_SEL_CON_IDX_13 0x00001474
38097 +#define SNDBDS_SEL_CON_IDX_14 0x00001478
38098 +#define SNDBDS_SEL_CON_IDX_15 0x0000147c
38099 +/* 0x1480 --> 0x1800 unused */
38101 +/* Send BD initiator control registers */
38102 +#define SNDBDI_MODE 0x00001800
38103 +#define SNDBDI_MODE_RESET 0x00000001
38104 +#define SNDBDI_MODE_ENABLE 0x00000002
38105 +#define SNDBDI_MODE_ATTN_ENABLE 0x00000004
38106 +#define SNDBDI_STATUS 0x00001804
38107 +#define SNDBDI_STATUS_ERROR_ATTN 0x00000004
38108 +#define SNDBDI_IN_PROD_IDX_0 0x00001808
38109 +#define SNDBDI_IN_PROD_IDX_1 0x0000180c
38110 +#define SNDBDI_IN_PROD_IDX_2 0x00001810
38111 +#define SNDBDI_IN_PROD_IDX_3 0x00001814
38112 +#define SNDBDI_IN_PROD_IDX_4 0x00001818
38113 +#define SNDBDI_IN_PROD_IDX_5 0x0000181c
38114 +#define SNDBDI_IN_PROD_IDX_6 0x00001820
38115 +#define SNDBDI_IN_PROD_IDX_7 0x00001824
38116 +#define SNDBDI_IN_PROD_IDX_8 0x00001828
38117 +#define SNDBDI_IN_PROD_IDX_9 0x0000182c
38118 +#define SNDBDI_IN_PROD_IDX_10 0x00001830
38119 +#define SNDBDI_IN_PROD_IDX_11 0x00001834
38120 +#define SNDBDI_IN_PROD_IDX_12 0x00001838
38121 +#define SNDBDI_IN_PROD_IDX_13 0x0000183c
38122 +#define SNDBDI_IN_PROD_IDX_14 0x00001840
38123 +#define SNDBDI_IN_PROD_IDX_15 0x00001844
38124 +/* 0x1848 --> 0x1c00 unused */
38126 +/* Send BD completion control registers */
38127 +#define SNDBDC_MODE 0x00001c00
38128 +#define SNDBDC_MODE_RESET 0x00000001
38129 +#define SNDBDC_MODE_ENABLE 0x00000002
38130 +#define SNDBDC_MODE_ATTN_ENABLE 0x00000004
38131 +/* 0x1c04 --> 0x2000 unused */
38133 +/* Receive list placement control registers */
38134 +#define RCVLPC_MODE 0x00002000
38135 +#define RCVLPC_MODE_RESET 0x00000001
38136 +#define RCVLPC_MODE_ENABLE 0x00000002
38137 +#define RCVLPC_MODE_CLASS0_ATTN_ENAB 0x00000004
38138 +#define RCVLPC_MODE_MAPOOR_AATTN_ENAB 0x00000008
38139 +#define RCVLPC_MODE_STAT_OFLOW_ENAB 0x00000010
38140 +#define RCVLPC_STATUS 0x00002004
38141 +#define RCVLPC_STATUS_CLASS0 0x00000004
38142 +#define RCVLPC_STATUS_MAPOOR 0x00000008
38143 +#define RCVLPC_STATUS_STAT_OFLOW 0x00000010
38144 +#define RCVLPC_LOCK 0x00002008
38145 +#define RCVLPC_LOCK_REQ_MASK 0x0000ffff
38146 +#define RCVLPC_LOCK_REQ_SHIFT 0
38147 +#define RCVLPC_LOCK_GRANT_MASK 0xffff0000
38148 +#define RCVLPC_LOCK_GRANT_SHIFT 16
38149 +#define RCVLPC_NON_EMPTY_BITS 0x0000200c
38150 +#define RCVLPC_NON_EMPTY_BITS_MASK 0x0000ffff
38151 +#define RCVLPC_CONFIG 0x00002010
38152 +#define RCVLPC_STATSCTRL 0x00002014
38153 +#define RCVLPC_STATSCTRL_ENABLE 0x00000001
38154 +#define RCVLPC_STATSCTRL_FASTUPD 0x00000002
38155 +#define RCVLPC_STATS_ENABLE 0x00002018
38156 +#define RCVLPC_STATSENAB_LNGBRST_RFIX 0x00400000
38157 +#define RCVLPC_STATS_INCMASK 0x0000201c
38158 +/* 0x2020 --> 0x2100 unused */
38159 +#define RCVLPC_SELLST_BASE 0x00002100 /* 16 16-byte entries */
38160 +#define SELLST_TAIL 0x00000004
38161 +#define SELLST_CONT 0x00000008
38162 +#define SELLST_UNUSED 0x0000000c
38163 +#define RCVLPC_COS_CNTL_BASE 0x00002200 /* 16 4-byte entries */
38164 +#define RCVLPC_DROP_FILTER_CNT 0x00002240
38165 +#define RCVLPC_DMA_WQ_FULL_CNT 0x00002244
38166 +#define RCVLPC_DMA_HIPRIO_WQ_FULL_CNT 0x00002248
38167 +#define RCVLPC_NO_RCV_BD_CNT 0x0000224c
38168 +#define RCVLPC_IN_DISCARDS_CNT 0x00002250
38169 +#define RCVLPC_IN_ERRORS_CNT 0x00002254
38170 +#define RCVLPC_RCV_THRESH_HIT_CNT 0x00002258
38171 +/* 0x225c --> 0x2400 unused */
38173 +/* Receive Data and Receive BD Initiator Control */
38174 +#define RCVDBDI_MODE 0x00002400
38175 +#define RCVDBDI_MODE_RESET 0x00000001
38176 +#define RCVDBDI_MODE_ENABLE 0x00000002
38177 +#define RCVDBDI_MODE_JUMBOBD_NEEDED 0x00000004
38178 +#define RCVDBDI_MODE_FRM_TOO_BIG 0x00000008
38179 +#define RCVDBDI_MODE_INV_RING_SZ 0x00000010
38180 +#define RCVDBDI_STATUS 0x00002404
38181 +#define RCVDBDI_STATUS_JUMBOBD_NEEDED 0x00000004
38182 +#define RCVDBDI_STATUS_FRM_TOO_BIG 0x00000008
38183 +#define RCVDBDI_STATUS_INV_RING_SZ 0x00000010
38184 +#define RCVDBDI_SPLIT_FRAME_MINSZ 0x00002408
38185 +/* 0x240c --> 0x2440 unused */
38186 +#define RCVDBDI_JUMBO_BD 0x00002440 /* TG3_BDINFO_... */
38187 +#define RCVDBDI_STD_BD 0x00002450 /* TG3_BDINFO_... */
38188 +#define RCVDBDI_MINI_BD 0x00002460 /* TG3_BDINFO_... */
38189 +#define RCVDBDI_JUMBO_CON_IDX 0x00002470
38190 +#define RCVDBDI_STD_CON_IDX 0x00002474
38191 +#define RCVDBDI_MINI_CON_IDX 0x00002478
38192 +/* 0x247c --> 0x2480 unused */
38193 +#define RCVDBDI_BD_PROD_IDX_0 0x00002480
38194 +#define RCVDBDI_BD_PROD_IDX_1 0x00002484
38195 +#define RCVDBDI_BD_PROD_IDX_2 0x00002488
38196 +#define RCVDBDI_BD_PROD_IDX_3 0x0000248c
38197 +#define RCVDBDI_BD_PROD_IDX_4 0x00002490
38198 +#define RCVDBDI_BD_PROD_IDX_5 0x00002494
38199 +#define RCVDBDI_BD_PROD_IDX_6 0x00002498
38200 +#define RCVDBDI_BD_PROD_IDX_7 0x0000249c
38201 +#define RCVDBDI_BD_PROD_IDX_8 0x000024a0
38202 +#define RCVDBDI_BD_PROD_IDX_9 0x000024a4
38203 +#define RCVDBDI_BD_PROD_IDX_10 0x000024a8
38204 +#define RCVDBDI_BD_PROD_IDX_11 0x000024ac
38205 +#define RCVDBDI_BD_PROD_IDX_12 0x000024b0
38206 +#define RCVDBDI_BD_PROD_IDX_13 0x000024b4
38207 +#define RCVDBDI_BD_PROD_IDX_14 0x000024b8
38208 +#define RCVDBDI_BD_PROD_IDX_15 0x000024bc
38209 +#define RCVDBDI_HWDIAG 0x000024c0
38210 +/* 0x24c4 --> 0x2800 unused */
38212 +/* Receive Data Completion Control */
38213 +#define RCVDCC_MODE 0x00002800
38214 +#define RCVDCC_MODE_RESET 0x00000001
38215 +#define RCVDCC_MODE_ENABLE 0x00000002
38216 +#define RCVDCC_MODE_ATTN_ENABLE 0x00000004
38217 +/* 0x2804 --> 0x2c00 unused */
38219 +/* Receive BD Initiator Control Registers */
38220 +#define RCVBDI_MODE 0x00002c00
38221 +#define RCVBDI_MODE_RESET 0x00000001
38222 +#define RCVBDI_MODE_ENABLE 0x00000002
38223 +#define RCVBDI_MODE_RCB_ATTN_ENAB 0x00000004
38224 +#define RCVBDI_STATUS 0x00002c04
38225 +#define RCVBDI_STATUS_RCB_ATTN 0x00000004
38226 +#define RCVBDI_JUMBO_PROD_IDX 0x00002c08
38227 +#define RCVBDI_STD_PROD_IDX 0x00002c0c
38228 +#define RCVBDI_MINI_PROD_IDX 0x00002c10
38229 +#define RCVBDI_MINI_THRESH 0x00002c14
38230 +#define RCVBDI_STD_THRESH 0x00002c18
38231 +#define RCVBDI_JUMBO_THRESH 0x00002c1c
38232 +/* 0x2c20 --> 0x3000 unused */
38234 +/* Receive BD Completion Control Registers */
38235 +#define RCVCC_MODE 0x00003000
38236 +#define RCVCC_MODE_RESET 0x00000001
38237 +#define RCVCC_MODE_ENABLE 0x00000002
38238 +#define RCVCC_MODE_ATTN_ENABLE 0x00000004
38239 +#define RCVCC_STATUS 0x00003004
38240 +#define RCVCC_STATUS_ERROR_ATTN 0x00000004
38241 +#define RCVCC_JUMP_PROD_IDX 0x00003008
38242 +#define RCVCC_STD_PROD_IDX 0x0000300c
38243 +#define RCVCC_MINI_PROD_IDX 0x00003010
38244 +/* 0x3014 --> 0x3400 unused */
38246 +/* Receive list selector control registers */
38247 +#define RCVLSC_MODE 0x00003400
38248 +#define RCVLSC_MODE_RESET 0x00000001
38249 +#define RCVLSC_MODE_ENABLE 0x00000002
38250 +#define RCVLSC_MODE_ATTN_ENABLE 0x00000004
38251 +#define RCVLSC_STATUS 0x00003404
38252 +#define RCVLSC_STATUS_ERROR_ATTN 0x00000004
38253 +/* 0x3408 --> 0x3800 unused */
38255 +/* Mbuf cluster free registers */
38256 +#define MBFREE_MODE 0x00003800
38257 +#define MBFREE_MODE_RESET 0x00000001
38258 +#define MBFREE_MODE_ENABLE 0x00000002
38259 +#define MBFREE_STATUS 0x00003804
38260 +/* 0x3808 --> 0x3c00 unused */
38262 +/* Host coalescing control registers */
38263 +#define HOSTCC_MODE 0x00003c00
38264 +#define HOSTCC_MODE_RESET 0x00000001
38265 +#define HOSTCC_MODE_ENABLE 0x00000002
38266 +#define HOSTCC_MODE_ATTN 0x00000004
38267 +#define HOSTCC_MODE_NOW 0x00000008
38268 +#define HOSTCC_MODE_FULL_STATUS 0x00000000
38269 +#define HOSTCC_MODE_64BYTE 0x00000080
38270 +#define HOSTCC_MODE_32BYTE 0x00000100
38271 +#define HOSTCC_MODE_CLRTICK_RXBD 0x00000200
38272 +#define HOSTCC_MODE_CLRTICK_TXBD 0x00000400
38273 +#define HOSTCC_MODE_NOINT_ON_NOW 0x00000800
38274 +#define HOSTCC_MODE_NOINT_ON_FORCE 0x00001000
38275 +#define HOSTCC_STATUS 0x00003c04
38276 +#define HOSTCC_STATUS_ERROR_ATTN 0x00000004
38277 +#define HOSTCC_RXCOL_TICKS 0x00003c08
38278 +#define LOW_RXCOL_TICKS 0x00000032
38279 +#define DEFAULT_RXCOL_TICKS 0x00000048
38280 +#define HIGH_RXCOL_TICKS 0x00000096
38281 +#define HOSTCC_TXCOL_TICKS 0x00003c0c
38282 +#define LOW_TXCOL_TICKS 0x00000096
38283 +#define DEFAULT_TXCOL_TICKS 0x0000012c
38284 +#define HIGH_TXCOL_TICKS 0x00000145
38285 +#define HOSTCC_RXMAX_FRAMES 0x00003c10
38286 +#define LOW_RXMAX_FRAMES 0x00000005
38287 +#define DEFAULT_RXMAX_FRAMES 0x00000008
38288 +#define HIGH_RXMAX_FRAMES 0x00000012
38289 +#define HOSTCC_TXMAX_FRAMES 0x00003c14
38290 +#define LOW_TXMAX_FRAMES 0x00000035
38291 +#define DEFAULT_TXMAX_FRAMES 0x0000004b
38292 +#define HIGH_TXMAX_FRAMES 0x00000052
38293 +#define HOSTCC_RXCOAL_TICK_INT 0x00003c18
38294 +#define DEFAULT_RXCOAL_TICK_INT 0x00000019
38295 +#define HOSTCC_TXCOAL_TICK_INT 0x00003c1c
38296 +#define DEFAULT_TXCOAL_TICK_INT 0x00000019
38297 +#define HOSTCC_RXCOAL_MAXF_INT 0x00003c20
38298 +#define DEFAULT_RXCOAL_MAXF_INT 0x00000005
38299 +#define HOSTCC_TXCOAL_MAXF_INT 0x00003c24
38300 +#define DEFAULT_TXCOAL_MAXF_INT 0x00000005
38301 +#define HOSTCC_STAT_COAL_TICKS 0x00003c28
38302 +#define DEFAULT_STAT_COAL_TICKS 0x000f4240
38303 +/* 0x3c2c --> 0x3c30 unused */
38304 +#define HOSTCC_STATS_BLK_HOST_ADDR 0x00003c30 /* 64-bit */
38305 +#define HOSTCC_STATUS_BLK_HOST_ADDR 0x00003c38 /* 64-bit */
38306 +#define HOSTCC_STATS_BLK_NIC_ADDR 0x00003c40
38307 +#define HOSTCC_STATUS_BLK_NIC_ADDR 0x00003c44
38308 +#define HOSTCC_FLOW_ATTN 0x00003c48
38309 +/* 0x3c4c --> 0x3c50 unused */
38310 +#define HOSTCC_JUMBO_CON_IDX 0x00003c50
38311 +#define HOSTCC_STD_CON_IDX 0x00003c54
38312 +#define HOSTCC_MINI_CON_IDX 0x00003c58
38313 +/* 0x3c5c --> 0x3c80 unused */
38314 +#define HOSTCC_RET_PROD_IDX_0 0x00003c80
38315 +#define HOSTCC_RET_PROD_IDX_1 0x00003c84
38316 +#define HOSTCC_RET_PROD_IDX_2 0x00003c88
38317 +#define HOSTCC_RET_PROD_IDX_3 0x00003c8c
38318 +#define HOSTCC_RET_PROD_IDX_4 0x00003c90
38319 +#define HOSTCC_RET_PROD_IDX_5 0x00003c94
38320 +#define HOSTCC_RET_PROD_IDX_6 0x00003c98
38321 +#define HOSTCC_RET_PROD_IDX_7 0x00003c9c
38322 +#define HOSTCC_RET_PROD_IDX_8 0x00003ca0
38323 +#define HOSTCC_RET_PROD_IDX_9 0x00003ca4
38324 +#define HOSTCC_RET_PROD_IDX_10 0x00003ca8
38325 +#define HOSTCC_RET_PROD_IDX_11 0x00003cac
38326 +#define HOSTCC_RET_PROD_IDX_12 0x00003cb0
38327 +#define HOSTCC_RET_PROD_IDX_13 0x00003cb4
38328 +#define HOSTCC_RET_PROD_IDX_14 0x00003cb8
38329 +#define HOSTCC_RET_PROD_IDX_15 0x00003cbc
38330 +#define HOSTCC_SND_CON_IDX_0 0x00003cc0
38331 +#define HOSTCC_SND_CON_IDX_1 0x00003cc4
38332 +#define HOSTCC_SND_CON_IDX_2 0x00003cc8
38333 +#define HOSTCC_SND_CON_IDX_3 0x00003ccc
38334 +#define HOSTCC_SND_CON_IDX_4 0x00003cd0
38335 +#define HOSTCC_SND_CON_IDX_5 0x00003cd4
38336 +#define HOSTCC_SND_CON_IDX_6 0x00003cd8
38337 +#define HOSTCC_SND_CON_IDX_7 0x00003cdc
38338 +#define HOSTCC_SND_CON_IDX_8 0x00003ce0
38339 +#define HOSTCC_SND_CON_IDX_9 0x00003ce4
38340 +#define HOSTCC_SND_CON_IDX_10 0x00003ce8
38341 +#define HOSTCC_SND_CON_IDX_11 0x00003cec
38342 +#define HOSTCC_SND_CON_IDX_12 0x00003cf0
38343 +#define HOSTCC_SND_CON_IDX_13 0x00003cf4
38344 +#define HOSTCC_SND_CON_IDX_14 0x00003cf8
38345 +#define HOSTCC_SND_CON_IDX_15 0x00003cfc
38346 +/* 0x3d00 --> 0x4000 unused */
38348 +/* Memory arbiter control registers */
38349 +#define MEMARB_MODE 0x00004000
38350 +#define MEMARB_MODE_RESET 0x00000001
38351 +#define MEMARB_MODE_ENABLE 0x00000002
38352 +#define MEMARB_STATUS 0x00004004
38353 +#define MEMARB_TRAP_ADDR_LOW 0x00004008
38354 +#define MEMARB_TRAP_ADDR_HIGH 0x0000400c
38355 +/* 0x4010 --> 0x4400 unused */
38357 +/* Buffer manager control registers */
38358 +#define BUFMGR_MODE 0x00004400
38359 +#define BUFMGR_MODE_RESET 0x00000001
38360 +#define BUFMGR_MODE_ENABLE 0x00000002
38361 +#define BUFMGR_MODE_ATTN_ENABLE 0x00000004
38362 +#define BUFMGR_MODE_BM_TEST 0x00000008
38363 +#define BUFMGR_MODE_MBLOW_ATTN_ENAB 0x00000010
38364 +#define BUFMGR_STATUS 0x00004404
38365 +#define BUFMGR_STATUS_ERROR 0x00000004
38366 +#define BUFMGR_STATUS_MBLOW 0x00000010
38367 +#define BUFMGR_MB_POOL_ADDR 0x00004408
38368 +#define BUFMGR_MB_POOL_SIZE 0x0000440c
38369 +#define BUFMGR_MB_RDMA_LOW_WATER 0x00004410
38370 +#define DEFAULT_MB_RDMA_LOW_WATER 0x00000050
38371 +#define DEFAULT_MB_RDMA_LOW_WATER_5705 0x00000000
38372 +#define DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130
38373 +#define BUFMGR_MB_MACRX_LOW_WATER 0x00004414
38374 +#define DEFAULT_MB_MACRX_LOW_WATER 0x00000020
38375 +#define DEFAULT_MB_MACRX_LOW_WATER_5705 0x00000010
38376 +#define DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
38377 +#define BUFMGR_MB_HIGH_WATER 0x00004418
38378 +#define DEFAULT_MB_HIGH_WATER 0x00000060
38379 +#define DEFAULT_MB_HIGH_WATER_5705 0x00000060
38380 +#define DEFAULT_MB_HIGH_WATER_JUMBO 0x0000017c
38381 +#define BUFMGR_RX_MB_ALLOC_REQ 0x0000441c
38382 +#define BUFMGR_MB_ALLOC_BIT 0x10000000
38383 +#define BUFMGR_RX_MB_ALLOC_RESP 0x00004420
38384 +#define BUFMGR_TX_MB_ALLOC_REQ 0x00004424
38385 +#define BUFMGR_TX_MB_ALLOC_RESP 0x00004428
38386 +#define BUFMGR_DMA_DESC_POOL_ADDR 0x0000442c
38387 +#define BUFMGR_DMA_DESC_POOL_SIZE 0x00004430
38388 +#define BUFMGR_DMA_LOW_WATER 0x00004434
38389 +#define DEFAULT_DMA_LOW_WATER 0x00000005
38390 +#define BUFMGR_DMA_HIGH_WATER 0x00004438
38391 +#define DEFAULT_DMA_HIGH_WATER 0x0000000a
38392 +#define BUFMGR_RX_DMA_ALLOC_REQ 0x0000443c
38393 +#define BUFMGR_RX_DMA_ALLOC_RESP 0x00004440
38394 +#define BUFMGR_TX_DMA_ALLOC_REQ 0x00004444
38395 +#define BUFMGR_TX_DMA_ALLOC_RESP 0x00004448
38396 +#define BUFMGR_HWDIAG_0 0x0000444c
38397 +#define BUFMGR_HWDIAG_1 0x00004450
38398 +#define BUFMGR_HWDIAG_2 0x00004454
38399 +/* 0x4458 --> 0x4800 unused */
38401 +/* Read DMA control registers */
38402 +#define RDMAC_MODE 0x00004800
38403 +#define RDMAC_MODE_RESET 0x00000001
38404 +#define RDMAC_MODE_ENABLE 0x00000002
38405 +#define RDMAC_MODE_TGTABORT_ENAB 0x00000004
38406 +#define RDMAC_MODE_MSTABORT_ENAB 0x00000008
38407 +#define RDMAC_MODE_PARITYERR_ENAB 0x00000010
38408 +#define RDMAC_MODE_ADDROFLOW_ENAB 0x00000020
38409 +#define RDMAC_MODE_FIFOOFLOW_ENAB 0x00000040
38410 +#define RDMAC_MODE_FIFOURUN_ENAB 0x00000080
38411 +#define RDMAC_MODE_FIFOOREAD_ENAB 0x00000100
38412 +#define RDMAC_MODE_LNGREAD_ENAB 0x00000200
38413 +#define RDMAC_MODE_SPLIT_ENABLE 0x00000800
38414 +#define RDMAC_MODE_SPLIT_RESET 0x00001000
38415 +#define RDMAC_MODE_FIFO_SIZE_128 0x00020000
38416 +#define RDMAC_MODE_FIFO_LONG_BURST 0x00030000
38417 +#define RDMAC_STATUS 0x00004804
38418 +#define RDMAC_STATUS_TGTABORT 0x00000004
38419 +#define RDMAC_STATUS_MSTABORT 0x00000008
38420 +#define RDMAC_STATUS_PARITYERR 0x00000010
38421 +#define RDMAC_STATUS_ADDROFLOW 0x00000020
38422 +#define RDMAC_STATUS_FIFOOFLOW 0x00000040
38423 +#define RDMAC_STATUS_FIFOURUN 0x00000080
38424 +#define RDMAC_STATUS_FIFOOREAD 0x00000100
38425 +#define RDMAC_STATUS_LNGREAD 0x00000200
38426 +/* 0x4808 --> 0x4c00 unused */
38428 +/* Write DMA control registers */
38429 +#define WDMAC_MODE 0x00004c00
38430 +#define WDMAC_MODE_RESET 0x00000001
38431 +#define WDMAC_MODE_ENABLE 0x00000002
38432 +#define WDMAC_MODE_TGTABORT_ENAB 0x00000004
38433 +#define WDMAC_MODE_MSTABORT_ENAB 0x00000008
38434 +#define WDMAC_MODE_PARITYERR_ENAB 0x00000010
38435 +#define WDMAC_MODE_ADDROFLOW_ENAB 0x00000020
38436 +#define WDMAC_MODE_FIFOOFLOW_ENAB 0x00000040
38437 +#define WDMAC_MODE_FIFOURUN_ENAB 0x00000080
38438 +#define WDMAC_MODE_FIFOOREAD_ENAB 0x00000100
38439 +#define WDMAC_MODE_LNGREAD_ENAB 0x00000200
38440 +#define WDMAC_MODE_RX_ACCEL 0x00000400
38441 +#define WDMAC_STATUS 0x00004c04
38442 +#define WDMAC_STATUS_TGTABORT 0x00000004
38443 +#define WDMAC_STATUS_MSTABORT 0x00000008
38444 +#define WDMAC_STATUS_PARITYERR 0x00000010
38445 +#define WDMAC_STATUS_ADDROFLOW 0x00000020
38446 +#define WDMAC_STATUS_FIFOOFLOW 0x00000040
38447 +#define WDMAC_STATUS_FIFOURUN 0x00000080
38448 +#define WDMAC_STATUS_FIFOOREAD 0x00000100
38449 +#define WDMAC_STATUS_LNGREAD 0x00000200
38450 +/* 0x4c08 --> 0x5000 unused */
38452 +/* Per-cpu register offsets (arm9) */
38453 +#define CPU_MODE 0x00000000
38454 +#define CPU_MODE_RESET 0x00000001
38455 +#define CPU_MODE_HALT 0x00000400
38456 +#define CPU_STATE 0x00000004
38457 +#define CPU_EVTMASK 0x00000008
38458 +/* 0xc --> 0x1c reserved */
38459 +#define CPU_PC 0x0000001c
38460 +#define CPU_INSN 0x00000020
38461 +#define CPU_SPAD_UFLOW 0x00000024
38462 +#define CPU_WDOG_CLEAR 0x00000028
38463 +#define CPU_WDOG_VECTOR 0x0000002c
38464 +#define CPU_WDOG_PC 0x00000030
38465 +#define CPU_HW_BP 0x00000034
38466 +/* 0x38 --> 0x44 unused */
38467 +#define CPU_WDOG_SAVED_STATE 0x00000044
38468 +#define CPU_LAST_BRANCH_ADDR 0x00000048
38469 +#define CPU_SPAD_UFLOW_SET 0x0000004c
38470 +/* 0x50 --> 0x200 unused */
38471 +#define CPU_R0 0x00000200
38472 +#define CPU_R1 0x00000204
38473 +#define CPU_R2 0x00000208
38474 +#define CPU_R3 0x0000020c
38475 +#define CPU_R4 0x00000210
38476 +#define CPU_R5 0x00000214
38477 +#define CPU_R6 0x00000218
38478 +#define CPU_R7 0x0000021c
38479 +#define CPU_R8 0x00000220
38480 +#define CPU_R9 0x00000224
38481 +#define CPU_R10 0x00000228
38482 +#define CPU_R11 0x0000022c
38483 +#define CPU_R12 0x00000230
38484 +#define CPU_R13 0x00000234
38485 +#define CPU_R14 0x00000238
38486 +#define CPU_R15 0x0000023c
38487 +#define CPU_R16 0x00000240
38488 +#define CPU_R17 0x00000244
38489 +#define CPU_R18 0x00000248
38490 +#define CPU_R19 0x0000024c
38491 +#define CPU_R20 0x00000250
38492 +#define CPU_R21 0x00000254
38493 +#define CPU_R22 0x00000258
38494 +#define CPU_R23 0x0000025c
38495 +#define CPU_R24 0x00000260
38496 +#define CPU_R25 0x00000264
38497 +#define CPU_R26 0x00000268
38498 +#define CPU_R27 0x0000026c
38499 +#define CPU_R28 0x00000270
38500 +#define CPU_R29 0x00000274
38501 +#define CPU_R30 0x00000278
38502 +#define CPU_R31 0x0000027c
38503 +/* 0x280 --> 0x400 unused */
38505 +#define RX_CPU_BASE 0x00005000
38506 +#define TX_CPU_BASE 0x00005400
38508 +/* Mailboxes */
38509 +#define GRCMBOX_INTERRUPT_0 0x00005800 /* 64-bit */
38510 +#define GRCMBOX_INTERRUPT_1 0x00005808 /* 64-bit */
38511 +#define GRCMBOX_INTERRUPT_2 0x00005810 /* 64-bit */
38512 +#define GRCMBOX_INTERRUPT_3 0x00005818 /* 64-bit */
38513 +#define GRCMBOX_GENERAL_0 0x00005820 /* 64-bit */
38514 +#define GRCMBOX_GENERAL_1 0x00005828 /* 64-bit */
38515 +#define GRCMBOX_GENERAL_2 0x00005830 /* 64-bit */
38516 +#define GRCMBOX_GENERAL_3 0x00005838 /* 64-bit */
38517 +#define GRCMBOX_GENERAL_4 0x00005840 /* 64-bit */
38518 +#define GRCMBOX_GENERAL_5 0x00005848 /* 64-bit */
38519 +#define GRCMBOX_GENERAL_6 0x00005850 /* 64-bit */
38520 +#define GRCMBOX_GENERAL_7 0x00005858 /* 64-bit */
38521 +#define GRCMBOX_RELOAD_STAT 0x00005860 /* 64-bit */
38522 +#define GRCMBOX_RCVSTD_PROD_IDX 0x00005868 /* 64-bit */
38523 +#define GRCMBOX_RCVJUMBO_PROD_IDX 0x00005870 /* 64-bit */
38524 +#define GRCMBOX_RCVMINI_PROD_IDX 0x00005878 /* 64-bit */
38525 +#define GRCMBOX_RCVRET_CON_IDX_0 0x00005880 /* 64-bit */
38526 +#define GRCMBOX_RCVRET_CON_IDX_1 0x00005888 /* 64-bit */
38527 +#define GRCMBOX_RCVRET_CON_IDX_2 0x00005890 /* 64-bit */
38528 +#define GRCMBOX_RCVRET_CON_IDX_3 0x00005898 /* 64-bit */
38529 +#define GRCMBOX_RCVRET_CON_IDX_4 0x000058a0 /* 64-bit */
38530 +#define GRCMBOX_RCVRET_CON_IDX_5 0x000058a8 /* 64-bit */
38531 +#define GRCMBOX_RCVRET_CON_IDX_6 0x000058b0 /* 64-bit */
38532 +#define GRCMBOX_RCVRET_CON_IDX_7 0x000058b8 /* 64-bit */
38533 +#define GRCMBOX_RCVRET_CON_IDX_8 0x000058c0 /* 64-bit */
38534 +#define GRCMBOX_RCVRET_CON_IDX_9 0x000058c8 /* 64-bit */
38535 +#define GRCMBOX_RCVRET_CON_IDX_10 0x000058d0 /* 64-bit */
38536 +#define GRCMBOX_RCVRET_CON_IDX_11 0x000058d8 /* 64-bit */
38537 +#define GRCMBOX_RCVRET_CON_IDX_12 0x000058e0 /* 64-bit */
38538 +#define GRCMBOX_RCVRET_CON_IDX_13 0x000058e8 /* 64-bit */
38539 +#define GRCMBOX_RCVRET_CON_IDX_14 0x000058f0 /* 64-bit */
38540 +#define GRCMBOX_RCVRET_CON_IDX_15 0x000058f8 /* 64-bit */
38541 +#define GRCMBOX_SNDHOST_PROD_IDX_0 0x00005900 /* 64-bit */
38542 +#define GRCMBOX_SNDHOST_PROD_IDX_1 0x00005908 /* 64-bit */
38543 +#define GRCMBOX_SNDHOST_PROD_IDX_2 0x00005910 /* 64-bit */
38544 +#define GRCMBOX_SNDHOST_PROD_IDX_3 0x00005918 /* 64-bit */
38545 +#define GRCMBOX_SNDHOST_PROD_IDX_4 0x00005920 /* 64-bit */
38546 +#define GRCMBOX_SNDHOST_PROD_IDX_5 0x00005928 /* 64-bit */
38547 +#define GRCMBOX_SNDHOST_PROD_IDX_6 0x00005930 /* 64-bit */
38548 +#define GRCMBOX_SNDHOST_PROD_IDX_7 0x00005938 /* 64-bit */
38549 +#define GRCMBOX_SNDHOST_PROD_IDX_8 0x00005940 /* 64-bit */
38550 +#define GRCMBOX_SNDHOST_PROD_IDX_9 0x00005948 /* 64-bit */
38551 +#define GRCMBOX_SNDHOST_PROD_IDX_10 0x00005950 /* 64-bit */
38552 +#define GRCMBOX_SNDHOST_PROD_IDX_11 0x00005958 /* 64-bit */
38553 +#define GRCMBOX_SNDHOST_PROD_IDX_12 0x00005960 /* 64-bit */
38554 +#define GRCMBOX_SNDHOST_PROD_IDX_13 0x00005968 /* 64-bit */
38555 +#define GRCMBOX_SNDHOST_PROD_IDX_14 0x00005970 /* 64-bit */
38556 +#define GRCMBOX_SNDHOST_PROD_IDX_15 0x00005978 /* 64-bit */
38557 +#define GRCMBOX_SNDNIC_PROD_IDX_0 0x00005980 /* 64-bit */
38558 +#define GRCMBOX_SNDNIC_PROD_IDX_1 0x00005988 /* 64-bit */
38559 +#define GRCMBOX_SNDNIC_PROD_IDX_2 0x00005990 /* 64-bit */
38560 +#define GRCMBOX_SNDNIC_PROD_IDX_3 0x00005998 /* 64-bit */
38561 +#define GRCMBOX_SNDNIC_PROD_IDX_4 0x000059a0 /* 64-bit */
38562 +#define GRCMBOX_SNDNIC_PROD_IDX_5 0x000059a8 /* 64-bit */
38563 +#define GRCMBOX_SNDNIC_PROD_IDX_6 0x000059b0 /* 64-bit */
38564 +#define GRCMBOX_SNDNIC_PROD_IDX_7 0x000059b8 /* 64-bit */
38565 +#define GRCMBOX_SNDNIC_PROD_IDX_8 0x000059c0 /* 64-bit */
38566 +#define GRCMBOX_SNDNIC_PROD_IDX_9 0x000059c8 /* 64-bit */
38567 +#define GRCMBOX_SNDNIC_PROD_IDX_10 0x000059d0 /* 64-bit */
38568 +#define GRCMBOX_SNDNIC_PROD_IDX_11 0x000059d8 /* 64-bit */
38569 +#define GRCMBOX_SNDNIC_PROD_IDX_12 0x000059e0 /* 64-bit */
38570 +#define GRCMBOX_SNDNIC_PROD_IDX_13 0x000059e8 /* 64-bit */
38571 +#define GRCMBOX_SNDNIC_PROD_IDX_14 0x000059f0 /* 64-bit */
38572 +#define GRCMBOX_SNDNIC_PROD_IDX_15 0x000059f8 /* 64-bit */
38573 +#define GRCMBOX_HIGH_PRIO_EV_VECTOR 0x00005a00
38574 +#define GRCMBOX_HIGH_PRIO_EV_MASK 0x00005a04
38575 +#define GRCMBOX_LOW_PRIO_EV_VEC 0x00005a08
38576 +#define GRCMBOX_LOW_PRIO_EV_MASK 0x00005a0c
38577 +/* 0x5a10 --> 0x5c00 */
38579 +/* Flow Through queues */
38580 +#define FTQ_RESET 0x00005c00
38581 +/* 0x5c04 --> 0x5c10 unused */
38582 +#define FTQ_DMA_NORM_READ_CTL 0x00005c10
38583 +#define FTQ_DMA_NORM_READ_FULL_CNT 0x00005c14
38584 +#define FTQ_DMA_NORM_READ_FIFO_ENQDEQ 0x00005c18
38585 +#define FTQ_DMA_NORM_READ_WRITE_PEEK 0x00005c1c
38586 +#define FTQ_DMA_HIGH_READ_CTL 0x00005c20
38587 +#define FTQ_DMA_HIGH_READ_FULL_CNT 0x00005c24
38588 +#define FTQ_DMA_HIGH_READ_FIFO_ENQDEQ 0x00005c28
38589 +#define FTQ_DMA_HIGH_READ_WRITE_PEEK 0x00005c2c
38590 +#define FTQ_DMA_COMP_DISC_CTL 0x00005c30
38591 +#define FTQ_DMA_COMP_DISC_FULL_CNT 0x00005c34
38592 +#define FTQ_DMA_COMP_DISC_FIFO_ENQDEQ 0x00005c38
38593 +#define FTQ_DMA_COMP_DISC_WRITE_PEEK 0x00005c3c
38594 +#define FTQ_SEND_BD_COMP_CTL 0x00005c40
38595 +#define FTQ_SEND_BD_COMP_FULL_CNT 0x00005c44
38596 +#define FTQ_SEND_BD_COMP_FIFO_ENQDEQ 0x00005c48
38597 +#define FTQ_SEND_BD_COMP_WRITE_PEEK 0x00005c4c
38598 +#define FTQ_SEND_DATA_INIT_CTL 0x00005c50
38599 +#define FTQ_SEND_DATA_INIT_FULL_CNT 0x00005c54
38600 +#define FTQ_SEND_DATA_INIT_FIFO_ENQDEQ 0x00005c58
38601 +#define FTQ_SEND_DATA_INIT_WRITE_PEEK 0x00005c5c
38602 +#define FTQ_DMA_NORM_WRITE_CTL 0x00005c60
38603 +#define FTQ_DMA_NORM_WRITE_FULL_CNT 0x00005c64
38604 +#define FTQ_DMA_NORM_WRITE_FIFO_ENQDEQ 0x00005c68
38605 +#define FTQ_DMA_NORM_WRITE_WRITE_PEEK 0x00005c6c
38606 +#define FTQ_DMA_HIGH_WRITE_CTL 0x00005c70
38607 +#define FTQ_DMA_HIGH_WRITE_FULL_CNT 0x00005c74
38608 +#define FTQ_DMA_HIGH_WRITE_FIFO_ENQDEQ 0x00005c78
38609 +#define FTQ_DMA_HIGH_WRITE_WRITE_PEEK 0x00005c7c
38610 +#define FTQ_SWTYPE1_CTL 0x00005c80
38611 +#define FTQ_SWTYPE1_FULL_CNT 0x00005c84
38612 +#define FTQ_SWTYPE1_FIFO_ENQDEQ 0x00005c88
38613 +#define FTQ_SWTYPE1_WRITE_PEEK 0x00005c8c
38614 +#define FTQ_SEND_DATA_COMP_CTL 0x00005c90
38615 +#define FTQ_SEND_DATA_COMP_FULL_CNT 0x00005c94
38616 +#define FTQ_SEND_DATA_COMP_FIFO_ENQDEQ 0x00005c98
38617 +#define FTQ_SEND_DATA_COMP_WRITE_PEEK 0x00005c9c
38618 +#define FTQ_HOST_COAL_CTL 0x00005ca0
38619 +#define FTQ_HOST_COAL_FULL_CNT 0x00005ca4
38620 +#define FTQ_HOST_COAL_FIFO_ENQDEQ 0x00005ca8
38621 +#define FTQ_HOST_COAL_WRITE_PEEK 0x00005cac
38622 +#define FTQ_MAC_TX_CTL 0x00005cb0
38623 +#define FTQ_MAC_TX_FULL_CNT 0x00005cb4
38624 +#define FTQ_MAC_TX_FIFO_ENQDEQ 0x00005cb8
38625 +#define FTQ_MAC_TX_WRITE_PEEK 0x00005cbc
38626 +#define FTQ_MB_FREE_CTL 0x00005cc0
38627 +#define FTQ_MB_FREE_FULL_CNT 0x00005cc4
38628 +#define FTQ_MB_FREE_FIFO_ENQDEQ 0x00005cc8
38629 +#define FTQ_MB_FREE_WRITE_PEEK 0x00005ccc
38630 +#define FTQ_RCVBD_COMP_CTL 0x00005cd0
38631 +#define FTQ_RCVBD_COMP_FULL_CNT 0x00005cd4
38632 +#define FTQ_RCVBD_COMP_FIFO_ENQDEQ 0x00005cd8
38633 +#define FTQ_RCVBD_COMP_WRITE_PEEK 0x00005cdc
38634 +#define FTQ_RCVLST_PLMT_CTL 0x00005ce0
38635 +#define FTQ_RCVLST_PLMT_FULL_CNT 0x00005ce4
38636 +#define FTQ_RCVLST_PLMT_FIFO_ENQDEQ 0x00005ce8
38637 +#define FTQ_RCVLST_PLMT_WRITE_PEEK 0x00005cec
38638 +#define FTQ_RCVDATA_INI_CTL 0x00005cf0
38639 +#define FTQ_RCVDATA_INI_FULL_CNT 0x00005cf4
38640 +#define FTQ_RCVDATA_INI_FIFO_ENQDEQ 0x00005cf8
38641 +#define FTQ_RCVDATA_INI_WRITE_PEEK 0x00005cfc
38642 +#define FTQ_RCVDATA_COMP_CTL 0x00005d00
38643 +#define FTQ_RCVDATA_COMP_FULL_CNT 0x00005d04
38644 +#define FTQ_RCVDATA_COMP_FIFO_ENQDEQ 0x00005d08
38645 +#define FTQ_RCVDATA_COMP_WRITE_PEEK 0x00005d0c
38646 +#define FTQ_SWTYPE2_CTL 0x00005d10
38647 +#define FTQ_SWTYPE2_FULL_CNT 0x00005d14
38648 +#define FTQ_SWTYPE2_FIFO_ENQDEQ 0x00005d18
38649 +#define FTQ_SWTYPE2_WRITE_PEEK 0x00005d1c
38650 +/* 0x5d20 --> 0x6000 unused */
38652 +/* Message signaled interrupt registers */
38653 +#define MSGINT_MODE 0x00006000
38654 +#define MSGINT_MODE_RESET 0x00000001
38655 +#define MSGINT_MODE_ENABLE 0x00000002
38656 +#define MSGINT_STATUS 0x00006004
38657 +#define MSGINT_FIFO 0x00006008
38658 +/* 0x600c --> 0x6400 unused */
38660 +/* DMA completion registers */
38661 +#define DMAC_MODE 0x00006400
38662 +#define DMAC_MODE_RESET 0x00000001
38663 +#define DMAC_MODE_ENABLE 0x00000002
38664 +/* 0x6404 --> 0x6800 unused */
38666 +/* GRC registers */
38667 +#define GRC_MODE 0x00006800
38668 +#define GRC_MODE_UPD_ON_COAL 0x00000001
38669 +#define GRC_MODE_BSWAP_NONFRM_DATA 0x00000002
38670 +#define GRC_MODE_WSWAP_NONFRM_DATA 0x00000004
38671 +#define GRC_MODE_BSWAP_DATA 0x00000010
38672 +#define GRC_MODE_WSWAP_DATA 0x00000020
38673 +#define GRC_MODE_SPLITHDR 0x00000100
38674 +#define GRC_MODE_NOFRM_CRACKING 0x00000200
38675 +#define GRC_MODE_INCL_CRC 0x00000400
38676 +#define GRC_MODE_ALLOW_BAD_FRMS 0x00000800
38677 +#define GRC_MODE_NOIRQ_ON_SENDS 0x00002000
38678 +#define GRC_MODE_NOIRQ_ON_RCV 0x00004000
38679 +#define GRC_MODE_FORCE_PCI32BIT 0x00008000
38680 +#define GRC_MODE_HOST_STACKUP 0x00010000
38681 +#define GRC_MODE_HOST_SENDBDS 0x00020000
38682 +#define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000
38683 +#define GRC_MODE_NO_RX_PHDR_CSUM 0x00800000
38684 +#define GRC_MODE_IRQ_ON_TX_CPU_ATTN 0x01000000
38685 +#define GRC_MODE_IRQ_ON_RX_CPU_ATTN 0x02000000
38686 +#define GRC_MODE_IRQ_ON_MAC_ATTN 0x04000000
38687 +#define GRC_MODE_IRQ_ON_DMA_ATTN 0x08000000
38688 +#define GRC_MODE_IRQ_ON_FLOW_ATTN 0x10000000
38689 +#define GRC_MODE_4X_NIC_SEND_RINGS 0x20000000
38690 +#define GRC_MODE_MCAST_FRM_ENABLE 0x40000000
38691 +#define GRC_MISC_CFG 0x00006804
38692 +#define GRC_MISC_CFG_CORECLK_RESET 0x00000001
38693 +#define GRC_MISC_CFG_PRESCALAR_MASK 0x000000fe
38694 +#define GRC_MISC_CFG_PRESCALAR_SHIFT 1
38695 +#define GRC_MISC_CFG_BOARD_ID_MASK 0x0001e000
38696 +#define GRC_MISC_CFG_BOARD_ID_5700 0x0001e000
38697 +#define GRC_MISC_CFG_BOARD_ID_5701 0x00000000
38698 +#define GRC_MISC_CFG_BOARD_ID_5702FE 0x00004000
38699 +#define GRC_MISC_CFG_BOARD_ID_5703 0x00000000
38700 +#define GRC_MISC_CFG_BOARD_ID_5703S 0x00002000
38701 +#define GRC_MISC_CFG_BOARD_ID_5704 0x00000000
38702 +#define GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000
38703 +#define GRC_MISC_CFG_BOARD_ID_5704_A2 0x00008000
38704 +#define GRC_MISC_CFG_BOARD_ID_5788 0x00010000
38705 +#define GRC_MISC_CFG_BOARD_ID_5788M 0x00018000
38706 +#define GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
38707 +#define GRC_MISC_CFG_KEEP_GPHY_POWER 0x04000000
38708 +#define GRC_LOCAL_CTRL 0x00006808
38709 +#define GRC_LCLCTRL_INT_ACTIVE 0x00000001
38710 +#define GRC_LCLCTRL_CLEARINT 0x00000002
38711 +#define GRC_LCLCTRL_SETINT 0x00000004
38712 +#define GRC_LCLCTRL_INT_ON_ATTN 0x00000008
38713 +#define GRC_LCLCTRL_GPIO_INPUT0 0x00000100
38714 +#define GRC_LCLCTRL_GPIO_INPUT1 0x00000200
38715 +#define GRC_LCLCTRL_GPIO_INPUT2 0x00000400
38716 +#define GRC_LCLCTRL_GPIO_OE0 0x00000800
38717 +#define GRC_LCLCTRL_GPIO_OE1 0x00001000
38718 +#define GRC_LCLCTRL_GPIO_OE2 0x00002000
38719 +#define GRC_LCLCTRL_GPIO_OUTPUT0 0x00004000
38720 +#define GRC_LCLCTRL_GPIO_OUTPUT1 0x00008000
38721 +#define GRC_LCLCTRL_GPIO_OUTPUT2 0x00010000
38722 +#define GRC_LCLCTRL_EXTMEM_ENABLE 0x00020000
38723 +#define GRC_LCLCTRL_MEMSZ_MASK 0x001c0000
38724 +#define GRC_LCLCTRL_MEMSZ_256K 0x00000000
38725 +#define GRC_LCLCTRL_MEMSZ_512K 0x00040000
38726 +#define GRC_LCLCTRL_MEMSZ_1M 0x00080000
38727 +#define GRC_LCLCTRL_MEMSZ_2M 0x000c0000
38728 +#define GRC_LCLCTRL_MEMSZ_4M 0x00100000
38729 +#define GRC_LCLCTRL_MEMSZ_8M 0x00140000
38730 +#define GRC_LCLCTRL_MEMSZ_16M 0x00180000
38731 +#define GRC_LCLCTRL_BANK_SELECT 0x00200000
38732 +#define GRC_LCLCTRL_SSRAM_TYPE 0x00400000
38733 +#define GRC_LCLCTRL_AUTO_SEEPROM 0x01000000
38734 +#define GRC_TIMER 0x0000680c
38735 +#define GRC_RX_CPU_EVENT 0x00006810
38736 +#define GRC_RX_TIMER_REF 0x00006814
38737 +#define GRC_RX_CPU_SEM 0x00006818
38738 +#define GRC_REMOTE_RX_CPU_ATTN 0x0000681c
38739 +#define GRC_TX_CPU_EVENT 0x00006820
38740 +#define GRC_TX_TIMER_REF 0x00006824
38741 +#define GRC_TX_CPU_SEM 0x00006828
38742 +#define GRC_REMOTE_TX_CPU_ATTN 0x0000682c
38743 +#define GRC_MEM_POWER_UP 0x00006830 /* 64-bit */
38744 +#define GRC_EEPROM_ADDR 0x00006838
38745 +#define EEPROM_ADDR_WRITE 0x00000000
38746 +#define EEPROM_ADDR_READ 0x80000000
38747 +#define EEPROM_ADDR_COMPLETE 0x40000000
38748 +#define EEPROM_ADDR_FSM_RESET 0x20000000
38749 +#define EEPROM_ADDR_DEVID_MASK 0x1c000000
38750 +#define EEPROM_ADDR_DEVID_SHIFT 26
38751 +#define EEPROM_ADDR_START 0x02000000
38752 +#define EEPROM_ADDR_CLKPERD_SHIFT 16
38753 +#define EEPROM_ADDR_ADDR_MASK 0x0000ffff
38754 +#define EEPROM_ADDR_ADDR_SHIFT 0
38755 +#define EEPROM_DEFAULT_CLOCK_PERIOD 0x60
38756 +#define EEPROM_CHIP_SIZE (64 * 1024)
38757 +#define GRC_EEPROM_DATA 0x0000683c
38758 +#define GRC_EEPROM_CTRL 0x00006840
38759 +#define GRC_MDI_CTRL 0x00006844
38760 +#define GRC_SEEPROM_DELAY 0x00006848
38761 +/* 0x684c --> 0x6c00 unused */
38763 +/* 0x6c00 --> 0x7000 unused */
38765 +/* NVRAM Control registers */
38766 +#define NVRAM_CMD 0x00007000
38767 +#define NVRAM_CMD_RESET 0x00000001
38768 +#define NVRAM_CMD_DONE 0x00000008
38769 +#define NVRAM_CMD_GO 0x00000010
38770 +#define NVRAM_CMD_WR 0x00000020
38771 +#define NVRAM_CMD_RD 0x00000000
38772 +#define NVRAM_CMD_ERASE 0x00000040
38773 +#define NVRAM_CMD_FIRST 0x00000080
38774 +#define NVRAM_CMD_LAST 0x00000100
38775 +#define NVRAM_STAT 0x00007004
38776 +#define NVRAM_WRDATA 0x00007008
38777 +#define NVRAM_ADDR 0x0000700c
38778 +#define NVRAM_ADDR_MSK 0x00ffffff
38779 +#define NVRAM_RDDATA 0x00007010
38780 +#define NVRAM_CFG1 0x00007014
38781 +#define NVRAM_CFG1_FLASHIF_ENAB 0x00000001
38782 +#define NVRAM_CFG1_BUFFERED_MODE 0x00000002
38783 +#define NVRAM_CFG1_PASS_THRU 0x00000004
38784 +#define NVRAM_CFG1_BIT_BANG 0x00000008
38785 +#define NVRAM_CFG1_COMPAT_BYPASS 0x80000000
38786 +#define NVRAM_CFG2 0x00007018
38787 +#define NVRAM_CFG3 0x0000701c
38788 +#define NVRAM_SWARB 0x00007020
38789 +#define SWARB_REQ_SET0 0x00000001
38790 +#define SWARB_REQ_SET1 0x00000002
38791 +#define SWARB_REQ_SET2 0x00000004
38792 +#define SWARB_REQ_SET3 0x00000008
38793 +#define SWARB_REQ_CLR0 0x00000010
38794 +#define SWARB_REQ_CLR1 0x00000020
38795 +#define SWARB_REQ_CLR2 0x00000040
38796 +#define SWARB_REQ_CLR3 0x00000080
38797 +#define SWARB_GNT0 0x00000100
38798 +#define SWARB_GNT1 0x00000200
38799 +#define SWARB_GNT2 0x00000400
38800 +#define SWARB_GNT3 0x00000800
38801 +#define SWARB_REQ0 0x00001000
38802 +#define SWARB_REQ1 0x00002000
38803 +#define SWARB_REQ2 0x00004000
38804 +#define SWARB_REQ3 0x00008000
38805 +#define NVRAM_BUFFERED_PAGE_SIZE 264
38806 +#define NVRAM_BUFFERED_PAGE_POS 9
38807 +/* 0x7024 --> 0x7400 unused */
38809 +/* 0x7400 --> 0x8000 unused */
38811 +/* 32K Window into NIC internal memory */
38812 +#define NIC_SRAM_WIN_BASE 0x00008000
38814 +/* Offsets into first 32k of NIC internal memory. */
38815 +#define NIC_SRAM_PAGE_ZERO 0x00000000
38816 +#define NIC_SRAM_SEND_RCB 0x00000100 /* 16 * TG3_BDINFO_... */
38817 +#define NIC_SRAM_RCV_RET_RCB 0x00000200 /* 16 * TG3_BDINFO_... */
38818 +#define NIC_SRAM_STATS_BLK 0x00000300
38819 +#define NIC_SRAM_STATUS_BLK 0x00000b00
38821 +#define NIC_SRAM_FIRMWARE_MBOX 0x00000b50
38822 +#define NIC_SRAM_FIRMWARE_MBOX_MAGIC1 0x4B657654
38823 +#define NIC_SRAM_FIRMWARE_MBOX_MAGIC2 0x4861764b /* !dma on linkchg */
38825 +#define NIC_SRAM_DATA_SIG 0x00000b54
38826 +#define NIC_SRAM_DATA_SIG_MAGIC 0x4b657654 /* ascii for 'KevT' */
38828 +#define NIC_SRAM_DATA_CFG 0x00000b58
38829 +#define NIC_SRAM_DATA_CFG_LED_MODE_MASK 0x0000000c
38830 +#define NIC_SRAM_DATA_CFG_LED_MODE_UNKNOWN 0x00000000
38831 +#define NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD 0x00000004
38832 +#define NIC_SRAM_DATA_CFG_LED_OPEN_DRAIN 0x00000004
38833 +#define NIC_SRAM_DATA_CFG_LED_LINK_SPD 0x00000008
38834 +#define NIC_SRAM_DATA_CFG_LED_OUTPUT 0x00000008
38835 +#define NIC_SRAM_DATA_CFG_PHY_TYPE_MASK 0x00000030
38836 +#define NIC_SRAM_DATA_CFG_PHY_TYPE_UNKNOWN 0x00000000
38837 +#define NIC_SRAM_DATA_CFG_PHY_TYPE_COPPER 0x00000010
38838 +#define NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER 0x00000020
38839 +#define NIC_SRAM_DATA_CFG_WOL_ENABLE 0x00000040
38840 +#define NIC_SRAM_DATA_CFG_ASF_ENABLE 0x00000080
38841 +#define NIC_SRAM_DATA_CFG_EEPROM_WP 0x00000100
38842 +#define NIC_SRAM_DATA_CFG_MINI_PCI 0x00001000
38843 +#define NIC_SRAM_DATA_CFG_FIBER_WOL 0x00004000
38845 +#define NIC_SRAM_DATA_PHY_ID 0x00000b74
38846 +#define NIC_SRAM_DATA_PHY_ID1_MASK 0xffff0000
38847 +#define NIC_SRAM_DATA_PHY_ID2_MASK 0x0000ffff
38849 +#define NIC_SRAM_FW_CMD_MBOX 0x00000b78
38850 +#define FWCMD_NICDRV_ALIVE 0x00000001
38851 +#define FWCMD_NICDRV_PAUSE_FW 0x00000002
38852 +#define FWCMD_NICDRV_IPV4ADDR_CHG 0x00000003
38853 +#define FWCMD_NICDRV_IPV6ADDR_CHG 0x00000004
38854 +#define FWCMD_NICDRV_FIX_DMAR 0x00000005
38855 +#define FWCMD_NICDRV_FIX_DMAW 0x00000006
38856 +#define NIC_SRAM_FW_CMD_LEN_MBOX 0x00000b7c
38857 +#define NIC_SRAM_FW_CMD_DATA_MBOX 0x00000b80
38858 +#define NIC_SRAM_FW_ASF_STATUS_MBOX 0x00000c00
38859 +#define NIC_SRAM_FW_DRV_STATE_MBOX 0x00000c04
38860 +#define DRV_STATE_START 0x00000001
38861 +#define DRV_STATE_UNLOAD 0x00000002
38862 +#define DRV_STATE_WOL 0x00000003
38863 +#define DRV_STATE_SUSPEND 0x00000004
38865 +#define NIC_SRAM_FW_RESET_TYPE_MBOX 0x00000c08
38867 +#define NIC_SRAM_MAC_ADDR_HIGH_MBOX 0x00000c14
38868 +#define NIC_SRAM_MAC_ADDR_LOW_MBOX 0x00000c18
38870 +#define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000
38872 +#define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000
38873 +#define NIC_SRAM_DMA_DESC_POOL_SIZE 0x00002000
38874 +#define NIC_SRAM_TX_BUFFER_DESC 0x00004000 /* 512 entries */
38875 +#define NIC_SRAM_RX_BUFFER_DESC 0x00006000 /* 256 entries */
38876 +#define NIC_SRAM_RX_JUMBO_BUFFER_DESC 0x00007000 /* 256 entries */
38877 +#define NIC_SRAM_MBUF_POOL_BASE 0x00008000
38878 +#define NIC_SRAM_MBUF_POOL_SIZE96 0x00018000
38879 +#define NIC_SRAM_MBUF_POOL_SIZE64 0x00010000
38880 +#define NIC_SRAM_MBUF_POOL_BASE5705 0x00010000
38881 +#define NIC_SRAM_MBUF_POOL_SIZE5705 0x0000e000
38883 +/* Currently this is fixed. */
38884 +#define PHY_ADDR 0x01
38886 +/* Tigon3 specific PHY MII registers. */
38887 +#define TG3_BMCR_SPEED1000 0x0040
38889 +#define MII_TG3_CTRL 0x09 /* 1000-baseT control register */
38890 +#define MII_TG3_CTRL_ADV_1000_HALF 0x0100
38891 +#define MII_TG3_CTRL_ADV_1000_FULL 0x0200
38892 +#define MII_TG3_CTRL_AS_MASTER 0x0800
38893 +#define MII_TG3_CTRL_ENABLE_AS_MASTER 0x1000
38895 +#define MII_TG3_EXT_CTRL 0x10 /* Extended control register */
38896 +#define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002
38897 +#define MII_TG3_EXT_CTRL_TBI 0x8000
38899 +#define MII_TG3_EXT_STAT 0x11 /* Extended status register */
38900 +#define MII_TG3_EXT_STAT_LPASS 0x0100
38902 +#define MII_TG3_DSP_RW_PORT 0x15 /* DSP coefficient read/write port */
38904 +#define MII_TG3_DSP_ADDRESS 0x17 /* DSP address register */
38906 +#define MII_TG3_AUX_CTRL 0x18 /* auxilliary control register */
38908 +#define MII_TG3_AUX_STAT 0x19 /* auxilliary status register */
38909 +#define MII_TG3_AUX_STAT_LPASS 0x0004
38910 +#define MII_TG3_AUX_STAT_SPDMASK 0x0700
38911 +#define MII_TG3_AUX_STAT_10HALF 0x0100
38912 +#define MII_TG3_AUX_STAT_10FULL 0x0200
38913 +#define MII_TG3_AUX_STAT_100HALF 0x0300
38914 +#define MII_TG3_AUX_STAT_100_4 0x0400
38915 +#define MII_TG3_AUX_STAT_100FULL 0x0500
38916 +#define MII_TG3_AUX_STAT_1000HALF 0x0600
38917 +#define MII_TG3_AUX_STAT_1000FULL 0x0700
38919 +#define MII_TG3_ISTAT 0x1a /* IRQ status register */
38920 +#define MII_TG3_IMASK 0x1b /* IRQ mask register */
38922 +/* ISTAT/IMASK event bits */
38923 +#define MII_TG3_INT_LINKCHG 0x0002
38924 +#define MII_TG3_INT_SPEEDCHG 0x0004
38925 +#define MII_TG3_INT_DUPLEXCHG 0x0008
38926 +#define MII_TG3_INT_ANEG_PAGE_RX 0x0400
38928 +/* XXX Add this to mii.h */
38929 +#ifndef ADVERTISE_PAUSE
38930 +#define ADVERTISE_PAUSE_CAP 0x0400
38931 +#endif
38932 +#ifndef ADVERTISE_PAUSE_ASYM
38933 +#define ADVERTISE_PAUSE_ASYM 0x0800
38934 +#endif
38935 +#ifndef LPA_PAUSE
38936 +#define LPA_PAUSE_CAP 0x0400
38937 +#endif
38938 +#ifndef LPA_PAUSE_ASYM
38939 +#define LPA_PAUSE_ASYM 0x0800
38940 +#endif
38942 +/* There are two ways to manage the TX descriptors on the tigon3.
38943 + * Either the descriptors are in host DMA'able memory, or they
38944 + * exist only in the cards on-chip SRAM. All 16 send bds are under
38945 + * the same mode, they may not be configured individually.
38947 + * The mode we use is controlled by TG3_FLAG_HOST_TXDS in tp->tg3_flags.
38949 + * To use host memory TX descriptors:
38950 + * 1) Set GRC_MODE_HOST_SENDBDS in GRC_MODE register.
38951 + * Make sure GRC_MODE_4X_NIC_SEND_RINGS is clear.
38952 + * 2) Allocate DMA'able memory.
38953 + * 3) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM:
38954 + * a) Set TG3_BDINFO_HOST_ADDR to DMA address of memory
38955 + * obtained in step 2
38956 + * b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC.
38957 + * c) Set len field of TG3_BDINFO_MAXLEN_FLAGS to number
38958 + * of TX descriptors. Leave flags field clear.
38959 + * 4) Access TX descriptors via host memory. The chip
38960 + * will refetch into local SRAM as needed when producer
38961 + * index mailboxes are updated.
38963 + * To use on-chip TX descriptors:
38964 + * 1) Set GRC_MODE_4X_NIC_SEND_RINGS in GRC_MODE register.
38965 + * Make sure GRC_MODE_HOST_SENDBDS is clear.
38966 + * 2) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM:
38967 + * a) Set TG3_BDINFO_HOST_ADDR to zero.
38968 + * b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC
38969 + * c) TG3_BDINFO_MAXLEN_FLAGS is don't care.
38970 + * 3) Access TX descriptors directly in on-chip SRAM
38971 + * using normal {read,write}l(). (and not using
38972 + * pointer dereferencing of ioremap()'d memory like
38973 + * the broken Broadcom driver does)
38975 + * Note that BDINFO_FLAGS_DISABLED should be set in the flags field of
38976 + * TG3_BDINFO_MAXLEN_FLAGS of all unused SEND_RCB indices.
38977 + */
38978 +struct tg3_tx_buffer_desc {
38979 + uint32_t addr_hi;
38980 + uint32_t addr_lo;
38982 + uint32_t len_flags;
38983 +#define TXD_FLAG_TCPUDP_CSUM 0x0001
38984 +#define TXD_FLAG_IP_CSUM 0x0002
38985 +#define TXD_FLAG_END 0x0004
38986 +#define TXD_FLAG_IP_FRAG 0x0008
38987 +#define TXD_FLAG_IP_FRAG_END 0x0010
38988 +#define TXD_FLAG_VLAN 0x0040
38989 +#define TXD_FLAG_COAL_NOW 0x0080
38990 +#define TXD_FLAG_CPU_PRE_DMA 0x0100
38991 +#define TXD_FLAG_CPU_POST_DMA 0x0200
38992 +#define TXD_FLAG_ADD_SRC_ADDR 0x1000
38993 +#define TXD_FLAG_CHOOSE_SRC_ADDR 0x6000
38994 +#define TXD_FLAG_NO_CRC 0x8000
38995 +#define TXD_LEN_SHIFT 16
38997 + uint32_t vlan_tag;
38998 +#define TXD_VLAN_TAG_SHIFT 0
38999 +#define TXD_MSS_SHIFT 16
39002 +#define TXD_ADDR 0x00UL /* 64-bit */
39003 +#define TXD_LEN_FLAGS 0x08UL /* 32-bit (upper 16-bits are len) */
39004 +#define TXD_VLAN_TAG 0x0cUL /* 32-bit (upper 16-bits are tag) */
39005 +#define TXD_SIZE 0x10UL
39007 +struct tg3_rx_buffer_desc {
39008 + uint32_t addr_hi;
39009 + uint32_t addr_lo;
39011 + uint32_t idx_len;
39012 +#define RXD_IDX_MASK 0xffff0000
39013 +#define RXD_IDX_SHIFT 16
39014 +#define RXD_LEN_MASK 0x0000ffff
39015 +#define RXD_LEN_SHIFT 0
39017 + uint32_t type_flags;
39018 +#define RXD_TYPE_SHIFT 16
39019 +#define RXD_FLAGS_SHIFT 0
39021 +#define RXD_FLAG_END 0x0004
39022 +#define RXD_FLAG_MINI 0x0800
39023 +#define RXD_FLAG_JUMBO 0x0020
39024 +#define RXD_FLAG_VLAN 0x0040
39025 +#define RXD_FLAG_ERROR 0x0400
39026 +#define RXD_FLAG_IP_CSUM 0x1000
39027 +#define RXD_FLAG_TCPUDP_CSUM 0x2000
39028 +#define RXD_FLAG_IS_TCP 0x4000
39030 + uint32_t ip_tcp_csum;
39031 +#define RXD_IPCSUM_MASK 0xffff0000
39032 +#define RXD_IPCSUM_SHIFT 16
39033 +#define RXD_TCPCSUM_MASK 0x0000ffff
39034 +#define RXD_TCPCSUM_SHIFT 0
39036 + uint32_t err_vlan;
39038 +#define RXD_VLAN_MASK 0x0000ffff
39040 +#define RXD_ERR_BAD_CRC 0x00010000
39041 +#define RXD_ERR_COLLISION 0x00020000
39042 +#define RXD_ERR_LINK_LOST 0x00040000
39043 +#define RXD_ERR_PHY_DECODE 0x00080000
39044 +#define RXD_ERR_ODD_NIBBLE_RCVD_MII 0x00100000
39045 +#define RXD_ERR_MAC_ABRT 0x00200000
39046 +#define RXD_ERR_TOO_SMALL 0x00400000
39047 +#define RXD_ERR_NO_RESOURCES 0x00800000
39048 +#define RXD_ERR_HUGE_FRAME 0x01000000
39049 +#define RXD_ERR_MASK 0xffff0000
39051 + uint32_t reserved;
39052 + uint32_t opaque;
39053 +#define RXD_OPAQUE_INDEX_MASK 0x0000ffff
39054 +#define RXD_OPAQUE_INDEX_SHIFT 0
39055 +#define RXD_OPAQUE_RING_STD 0x00010000
39056 +#define RXD_OPAQUE_RING_JUMBO 0x00020000
39057 +#define RXD_OPAQUE_RING_MINI 0x00040000
39058 +#define RXD_OPAQUE_RING_MASK 0x00070000
39061 +struct tg3_ext_rx_buffer_desc {
39062 + struct {
39063 + uint32_t addr_hi;
39064 + uint32_t addr_lo;
39065 + } addrlist[3];
39066 + uint32_t len2_len1;
39067 + uint32_t resv_len3;
39068 + struct tg3_rx_buffer_desc std;
39071 +/* We only use this when testing out the DMA engine
39072 + * at probe time. This is the internal format of buffer
39073 + * descriptors used by the chip at NIC_SRAM_DMA_DESCS.
39074 + */
39075 +struct tg3_internal_buffer_desc {
39076 + uint32_t addr_hi;
39077 + uint32_t addr_lo;
39078 + uint32_t nic_mbuf;
39079 + /* XXX FIX THIS */
39080 +#if __BYTE_ORDER == __BIG_ENDIAN
39081 + uint16_t cqid_sqid;
39082 + uint16_t len;
39083 +#else
39084 + uint16_t len;
39085 + uint16_t cqid_sqid;
39086 +#endif
39087 + uint32_t flags;
39088 + uint32_t __cookie1;
39089 + uint32_t __cookie2;
39090 + uint32_t __cookie3;
39093 +#define TG3_HW_STATUS_SIZE 0x50
39094 +struct tg3_hw_status {
39095 + uint32_t status;
39096 +#define SD_STATUS_UPDATED 0x00000001
39097 +#define SD_STATUS_LINK_CHG 0x00000002
39098 +#define SD_STATUS_ERROR 0x00000004
39100 + uint32_t status_tag;
39102 +#if __BYTE_ORDER == __BIG_ENDIAN
39103 + uint16_t rx_consumer;
39104 + uint16_t rx_jumbo_consumer;
39105 +#else
39106 + uint16_t rx_jumbo_consumer;
39107 + uint16_t rx_consumer;
39108 +#endif
39110 +#if __BYTE_ORDER == __BIG_ENDIAN
39111 + uint16_t reserved;
39112 + uint16_t rx_mini_consumer;
39113 +#else
39114 + uint16_t rx_mini_consumer;
39115 + uint16_t reserved;
39116 +#endif
39117 + struct {
39118 +#if __BYTE_ORDER == __BIG_ENDIAN
39119 + uint16_t tx_consumer;
39120 + uint16_t rx_producer;
39121 +#else
39122 + uint16_t rx_producer;
39123 + uint16_t tx_consumer;
39124 +#endif
39125 + } idx[16];
39128 +typedef struct {
39129 + uint32_t high, low;
39130 +} tg3_stat64_t;
39132 +struct tg3_hw_stats {
39133 + uint8_t __reserved0[0x400-0x300];
39135 + /* Statistics maintained by Receive MAC. */
39136 + tg3_stat64_t rx_octets;
39137 + uint64_t __reserved1;
39138 + tg3_stat64_t rx_fragments;
39139 + tg3_stat64_t rx_ucast_packets;
39140 + tg3_stat64_t rx_mcast_packets;
39141 + tg3_stat64_t rx_bcast_packets;
39142 + tg3_stat64_t rx_fcs_errors;
39143 + tg3_stat64_t rx_align_errors;
39144 + tg3_stat64_t rx_xon_pause_rcvd;
39145 + tg3_stat64_t rx_xoff_pause_rcvd;
39146 + tg3_stat64_t rx_mac_ctrl_rcvd;
39147 + tg3_stat64_t rx_xoff_entered;
39148 + tg3_stat64_t rx_frame_too_long_errors;
39149 + tg3_stat64_t rx_jabbers;
39150 + tg3_stat64_t rx_undersize_packets;
39151 + tg3_stat64_t rx_in_length_errors;
39152 + tg3_stat64_t rx_out_length_errors;
39153 + tg3_stat64_t rx_64_or_less_octet_packets;
39154 + tg3_stat64_t rx_65_to_127_octet_packets;
39155 + tg3_stat64_t rx_128_to_255_octet_packets;
39156 + tg3_stat64_t rx_256_to_511_octet_packets;
39157 + tg3_stat64_t rx_512_to_1023_octet_packets;
39158 + tg3_stat64_t rx_1024_to_1522_octet_packets;
39159 + tg3_stat64_t rx_1523_to_2047_octet_packets;
39160 + tg3_stat64_t rx_2048_to_4095_octet_packets;
39161 + tg3_stat64_t rx_4096_to_8191_octet_packets;
39162 + tg3_stat64_t rx_8192_to_9022_octet_packets;
39164 + uint64_t __unused0[37];
39166 + /* Statistics maintained by Transmit MAC. */
39167 + tg3_stat64_t tx_octets;
39168 + uint64_t __reserved2;
39169 + tg3_stat64_t tx_collisions;
39170 + tg3_stat64_t tx_xon_sent;
39171 + tg3_stat64_t tx_xoff_sent;
39172 + tg3_stat64_t tx_flow_control;
39173 + tg3_stat64_t tx_mac_errors;
39174 + tg3_stat64_t tx_single_collisions;
39175 + tg3_stat64_t tx_mult_collisions;
39176 + tg3_stat64_t tx_deferred;
39177 + uint64_t __reserved3;
39178 + tg3_stat64_t tx_excessive_collisions;
39179 + tg3_stat64_t tx_late_collisions;
39180 + tg3_stat64_t tx_collide_2times;
39181 + tg3_stat64_t tx_collide_3times;
39182 + tg3_stat64_t tx_collide_4times;
39183 + tg3_stat64_t tx_collide_5times;
39184 + tg3_stat64_t tx_collide_6times;
39185 + tg3_stat64_t tx_collide_7times;
39186 + tg3_stat64_t tx_collide_8times;
39187 + tg3_stat64_t tx_collide_9times;
39188 + tg3_stat64_t tx_collide_10times;
39189 + tg3_stat64_t tx_collide_11times;
39190 + tg3_stat64_t tx_collide_12times;
39191 + tg3_stat64_t tx_collide_13times;
39192 + tg3_stat64_t tx_collide_14times;
39193 + tg3_stat64_t tx_collide_15times;
39194 + tg3_stat64_t tx_ucast_packets;
39195 + tg3_stat64_t tx_mcast_packets;
39196 + tg3_stat64_t tx_bcast_packets;
39197 + tg3_stat64_t tx_carrier_sense_errors;
39198 + tg3_stat64_t tx_discards;
39199 + tg3_stat64_t tx_errors;
39201 + uint64_t __unused1[31];
39203 + /* Statistics maintained by Receive List Placement. */
39204 + tg3_stat64_t COS_rx_packets[16];
39205 + tg3_stat64_t COS_rx_filter_dropped;
39206 + tg3_stat64_t dma_writeq_full;
39207 + tg3_stat64_t dma_write_prioq_full;
39208 + tg3_stat64_t rxbds_empty;
39209 + tg3_stat64_t rx_discards;
39210 + tg3_stat64_t rx_errors;
39211 + tg3_stat64_t rx_threshold_hit;
39213 + uint64_t __unused2[9];
39215 + /* Statistics maintained by Send Data Initiator. */
39216 + tg3_stat64_t COS_out_packets[16];
39217 + tg3_stat64_t dma_readq_full;
39218 + tg3_stat64_t dma_read_prioq_full;
39219 + tg3_stat64_t tx_comp_queue_full;
39221 + /* Statistics maintained by Host Coalescing. */
39222 + tg3_stat64_t ring_set_send_prod_index;
39223 + tg3_stat64_t ring_status_update;
39224 + tg3_stat64_t nic_irqs;
39225 + tg3_stat64_t nic_avoided_irqs;
39226 + tg3_stat64_t nic_tx_threshold_hit;
39228 + uint8_t __reserved4[0xb00-0x9c0];
39231 +enum phy_led_mode {
39232 + led_mode_auto,
39233 + led_mode_three_link,
39234 + led_mode_link10
39237 +#if 0
39238 +/* 'mapping' is superfluous as the chip does not write into
39239 + * the tx/rx post rings so we could just fetch it from there.
39240 + * But the cache behavior is better how we are doing it now.
39241 + */
39242 +struct ring_info {
39243 + struct sk_buff *skb;
39244 + DECLARE_PCI_UNMAP_ADDR(mapping)
39247 +struct tx_ring_info {
39248 + struct sk_buff *skb;
39249 + DECLARE_PCI_UNMAP_ADDR(mapping)
39250 + uint32_t prev_vlan_tag;
39252 +#endif
39254 +struct tg3_config_info {
39255 + uint32_t flags;
39258 +struct tg3_link_config {
39259 + /* Describes what we're trying to get. */
39260 + uint32_t advertising;
39261 +#if 0
39262 + uint16_t speed;
39263 + uint8_t duplex;
39264 + uint8_t autoneg;
39265 +#define SPEED_INVALID 0xffff
39266 +#define DUPLEX_INVALID 0xff
39267 +#define AUTONEG_INVALID 0xff
39268 +#endif
39270 + /* Describes what we actually have. */
39271 + uint8_t active_speed;
39272 + uint8_t active_duplex;
39274 + /* When we go in and out of low power mode we need
39275 + * to swap with this state.
39276 + */
39277 +#if 0
39278 + int phy_is_low_power;
39279 + uint16_t orig_speed;
39280 + uint8_t orig_duplex;
39281 + uint8_t orig_autoneg;
39282 +#endif
39285 +struct tg3_bufmgr_config {
39286 + uint32_t mbuf_read_dma_low_water;
39287 + uint32_t mbuf_mac_rx_low_water;
39288 + uint32_t mbuf_high_water;
39290 + uint32_t mbuf_read_dma_low_water_jumbo;
39291 + uint32_t mbuf_mac_rx_low_water_jumbo;
39292 + uint32_t mbuf_high_water_jumbo;
39294 + uint32_t dma_low_water;
39295 + uint32_t dma_high_water;
39298 +struct tg3 {
39299 +#if 0
39300 + /* SMP locking strategy:
39302 + * lock: Held during all operations except TX packet
39303 + * processing.
39305 + * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
39307 + * If you want to shut up all asynchronous processing you must
39308 + * acquire both locks, 'lock' taken before 'tx_lock'. IRQs must
39309 + * be disabled to take 'lock' but only softirq disabling is
39310 + * necessary for acquisition of 'tx_lock'.
39311 + */
39312 + spinlock_t lock;
39313 + spinlock_t tx_lock;
39314 +#endif
39316 + uint32_t tx_prod;
39317 +#if 0
39318 + uint32_t tx_cons;
39319 +#endif
39320 + uint32_t rx_rcb_ptr;
39321 + uint32_t rx_std_ptr;
39322 +#if 0
39323 + uint32_t rx_jumbo_ptr;
39324 + spinlock_t indirect_lock;
39326 + struct net_device_stats net_stats;
39327 + struct net_device_stats net_stats_prev;
39328 +#endif
39329 + unsigned long phy_crc_errors;
39331 +#if 0
39332 + uint32_t rx_offset;
39333 +#endif
39334 + uint32_t tg3_flags;
39335 +#if 0
39336 +#define TG3_FLAG_HOST_TXDS 0x00000001
39337 +#endif
39338 +#define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002
39339 +#define TG3_FLAG_RX_CHECKSUMS 0x00000004
39340 +#define TG3_FLAG_USE_LINKCHG_REG 0x00000008
39341 +#define TG3_FLAG_USE_MI_INTERRUPT 0x00000010
39342 +#define TG3_FLAG_ENABLE_ASF 0x00000020
39343 +#define TG3_FLAG_5701_REG_WRITE_BUG 0x00000040
39344 +#define TG3_FLAG_POLL_SERDES 0x00000080
39345 +#define TG3_FLAG_MBOX_WRITE_REORDER 0x00000100
39346 +#define TG3_FLAG_PCIX_TARGET_HWBUG 0x00000200
39347 +#define TG3_FLAG_WOL_SPEED_100MB 0x00000400
39348 +#define TG3_FLAG_WOL_ENABLE 0x00000800
39349 +#define TG3_FLAG_EEPROM_WRITE_PROT 0x00001000
39350 +#define TG3_FLAG_NVRAM 0x00002000
39351 +#define TG3_FLAG_NVRAM_BUFFERED 0x00004000
39352 +#define TG3_FLAG_RX_PAUSE 0x00008000
39353 +#define TG3_FLAG_TX_PAUSE 0x00010000
39354 +#define TG3_FLAG_PCIX_MODE 0x00020000
39355 +#define TG3_FLAG_PCI_HIGH_SPEED 0x00040000
39356 +#define TG3_FLAG_PCI_32BIT 0x00080000
39357 +#define TG3_FLAG_NO_TX_PSEUDO_CSUM 0x00100000
39358 +#define TG3_FLAG_NO_RX_PSEUDO_CSUM 0x00200000
39359 +#define TG3_FLAG_SERDES_WOL_CAP 0x00400000
39360 +#define TG3_FLAG_JUMBO_ENABLE 0x00800000
39361 +#define TG3_FLAG_10_100_ONLY 0x01000000
39362 +#define TG3_FLAG_PAUSE_AUTONEG 0x02000000
39363 +#define TG3_FLAG_PAUSE_RX 0x04000000
39364 +#define TG3_FLAG_PAUSE_TX 0x08000000
39365 +#define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000
39366 +#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
39367 +#define TG3_FLAG_SPLIT_MODE 0x40000000
39368 +#define TG3_FLAG_INIT_COMPLETE 0x80000000
39370 + uint32_t tg3_flags2;
39371 +#define TG3_FLG2_RESTART_TIMER 0x00000001
39372 +#define TG3_FLG2_SUN_5704 0x00000002
39373 +#define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004
39374 +#define TG3_FLG2_IS_5788 0x00000008
39375 +#define TG3_FLG2_MAX_RXPEND_64 0x00000010
39376 +#define TG3_FLG2_TSO_CAPABLE 0x00000020
39380 + uint32_t split_mode_max_reqs;
39381 +#define SPLIT_MODE_5704_MAX_REQ 3
39383 +#if 0
39384 + struct timer_list timer;
39385 + uint16_t timer_counter;
39386 + uint16_t timer_multiplier;
39387 + uint32_t timer_offset;
39388 + uint16_t asf_counter;
39389 + uint16_t asf_multiplier;
39390 +#endif
39392 + struct tg3_link_config link_config;
39393 + struct tg3_bufmgr_config bufmgr_config;
39395 +#if 0
39396 + uint32_t rx_pending;
39397 + uint32_t rx_jumbo_pending;
39398 + uint32_t tx_pending;
39399 +#endif
39401 + /* cache h/w values, often passed straight to h/w */
39402 + uint32_t rx_mode;
39403 + uint32_t tx_mode;
39404 + uint32_t mac_mode;
39405 + uint32_t mi_mode;
39406 + uint32_t misc_host_ctrl;
39407 + uint32_t grc_mode;
39408 + uint32_t grc_local_ctrl;
39409 + uint32_t dma_rwctrl;
39410 +#if 0
39411 + uint32_t coalesce_mode;
39412 +#endif
39414 + /* PCI block */
39415 + uint16_t pci_chip_rev_id;
39416 +#if 0
39417 + uint8_t pci_cacheline_sz;
39418 + uint8_t pci_lat_timer;
39419 + uint8_t pci_hdr_type;
39420 + uint8_t pci_bist;
39421 +#endif
39422 + uint32_t pci_cfg_state[64 / sizeof(uint32_t)];
39424 + int pm_cap;
39426 + /* PHY info */
39427 + uint32_t phy_id;
39428 +#define PHY_ID_MASK 0xfffffff0
39429 +#define PHY_ID_BCM5400 0x60008040
39430 +#define PHY_ID_BCM5401 0x60008050
39431 +#define PHY_ID_BCM5411 0x60008070
39432 +#define PHY_ID_BCM5701 0x60008110
39433 +#define PHY_ID_BCM5703 0x60008160
39434 +#define PHY_ID_BCM5704 0x60008190
39435 +#define PHY_ID_BCM5705 0x600081a0
39436 +#define PHY_ID_BCM8002 0x60010140
39437 +#define PHY_ID_SERDES 0xfeedbee0
39438 +#define PHY_ID_INVALID 0xffffffff
39439 +#define PHY_ID_REV_MASK 0x0000000f
39440 +#define PHY_REV_BCM5401_B0 0x1
39441 +#define PHY_REV_BCM5401_B2 0x3
39442 +#define PHY_REV_BCM5401_C0 0x6
39443 +#define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */
39445 + enum phy_led_mode led_mode;
39447 + char board_part_number[24];
39448 + uint32_t nic_sram_data_cfg;
39449 + uint32_t pci_clock_ctrl;
39450 +#if 0
39451 + struct pci_device *pdev_peer;
39452 +#endif
39454 + /* This macro assumes the passed PHY ID is already masked
39455 + * with PHY_ID_MASK.
39456 + */
39457 +#define KNOWN_PHY_ID(X) \
39458 + ((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
39459 + (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
39460 + (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
39461 + (X) == PHY_ID_BCM5705 || \
39462 + (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES)
39464 + unsigned long regs;
39465 + struct pci_device *pdev;
39466 + struct nic *nic;
39467 +#if 0
39468 + struct net_device *dev;
39469 +#endif
39470 +#if TG3_VLAN_TAG_USED
39471 + struct vlan_group *vlgrp;
39472 +#endif
39474 + struct tg3_rx_buffer_desc *rx_std;
39475 +#if 0
39476 + struct ring_info *rx_std_buffers;
39477 + dma_addr_t rx_std_mapping;
39478 + struct tg3_rx_buffer_desc *rx_jumbo;
39479 + struct ring_info *rx_jumbo_buffers;
39480 + dma_addr_t rx_jumbo_mapping;
39481 +#endif
39483 + struct tg3_rx_buffer_desc *rx_rcb;
39484 +#if 0
39485 + dma_addr_t rx_rcb_mapping;
39486 +#endif
39488 + /* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */
39489 + struct tg3_tx_buffer_desc *tx_ring;
39490 +#if 0
39491 + struct tx_ring_info *tx_buffers;
39492 + dma_addr_t tx_desc_mapping;
39493 +#endif
39495 + struct tg3_hw_status *hw_status;
39496 +#if 0
39497 + dma_addr_t status_mapping;
39498 +#endif
39499 +#if 0
39500 + uint32_t msg_enable;
39501 +#endif
39503 + struct tg3_hw_stats *hw_stats;
39504 +#if 0
39505 + dma_addr_t stats_mapping;
39506 +#endif
39508 + int carrier_ok;
39509 + uint16_t subsystem_vendor;
39510 + uint16_t subsystem_device;
39513 +#endif /* !(_T3_H) */
39514 Index: b/netboot/tiara.c
39515 ===================================================================
39516 --- a/netboot/tiara.c
39517 +++ /dev/null
39518 @@ -1,255 +0,0 @@
39519 -/**************************************************************************
39520 -Etherboot - BOOTP/TFTP Bootstrap Program
39522 -TIARA (Fujitsu Etherstar) NIC driver for Etherboot
39523 -Copyright (c) Ken Yap 1998
39525 -Information gleaned from:
39527 -TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, Ontario
39528 -Fujitsu MB86960 spec sheet (different chip but same family)
39529 -***************************************************************************/
39532 - * This program is free software; you can redistribute it and/or
39533 - * modify it under the terms of the GNU General Public License as
39534 - * published by the Free Software Foundation; either version 2, or (at
39535 - * your option) any later version.
39536 - */
39538 -/* to get some global routines like printf */
39539 -#include "etherboot.h"
39540 -/* to get the interface to the body of the program */
39541 -#include "nic.h"
39542 -#include "cards.h"
39545 - EtherStar I/O Register offsets
39548 -/* Offsets of registers */
39549 -#define DLCR_XMIT_STAT 0x00
39550 -#define DLCR_XMIT_MASK 0x01
39551 -#define DLCR_RECV_STAT 0x02
39552 -#define DLCR_RECV_MASK 0x03
39553 -#define DLCR_XMIT_MODE 0x04
39554 -#define DLCR_RECV_MODE 0x05
39555 -#define DLCR_ENABLE 0x06
39556 -#define DLCR_TDR_LOW 0x07
39557 -#define DLCR_NODE_ID 0x08
39558 -#define DLCR_TDR_HIGH 0x0F
39559 -#define BMPR_MEM_PORT 0x10
39560 -#define BMPR_PKT_LEN 0x12
39561 -#define BMPR_DMA_ENABLE 0x14
39562 -#define PROM_ID 0x18
39564 -#define TMST 0x80
39565 -#define TMT_OK 0x80
39566 -#define TMT_16COLL 0x02
39567 -#define BUF_EMPTY 0x40
39569 -#define CARD_DISABLE 0x80 /* written to DLCR_ENABLE to disable card */
39570 -#define CARD_ENABLE 0 /* written to DLCR_ENABLE to enable card */
39572 -#define CLEAR_STATUS 0x0F /* used to clear status info */
39574 - 00001111B
39575 - !!!!!!!!--------
39576 - !!!!!!!+--------CLEAR BUS WRITE ERROR
39577 - !!!!!!+---------CLEAR 16 COLLISION
39578 - !!!!!+----------CLEAR COLLISION
39579 - !!!!+-----------CLEAR UNDERFLOW
39580 - !!!+------------NC
39581 - !!+-------------NC
39582 - !+--------------NC
39583 - +---------------NC
39586 -#define NO_TX_IRQS 0 /* written to clear transmit IRQs */
39588 -#define CLR_RCV_STATUS 0xCF /* clears receive status */
39590 -#define EN_RCV_IRQS 0x80 /* enable receive interrupts */
39592 - 10000000B
39593 - !!!!!!!!--------
39594 - !!!!!!!+--------ENABLE OVERFLOW
39595 - !!!!!!+---------ENABLE CRC
39596 - !!!!!+----------ENABLE ALIGN
39597 - !!!!+-----------ENABLE SHORT PKT
39598 - !!!+------------DISABLE REMOTE RESET
39599 - !!+-------------RESERVED
39600 - !+--------------RESERVED
39601 - +---------------ENABLE PKT READY
39604 -#define XMIT_MODE 0x02
39606 - 00000010B
39607 - !!!!!!!!---------ENABLE CARRIER DETECT
39608 - !!!!!!!+---------DISABLE LOOPBACK
39611 -#define RECV_MODE 0x02
39613 - 00000010B
39614 - !!!!!!!!---------ACCEPT ALL PACKETS
39615 - !!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
39616 - !!!!!!+----------BROADCAST PACKETS
39617 - !!!!!+-----------DISABLE REMOTE RESET
39618 - !!!!+------------DISABLE SHORT PACKETS
39619 - !!!+-------------USE 6 BYTE ADDRESS
39620 - !!+--------------NC
39621 - !+---------------NC
39622 - +----------------DISABLE CRC TEST MODE
39625 -/* NIC specific static variables go here */
39627 -static unsigned short ioaddr;
39629 -/**************************************************************************
39630 -RESET - Reset adapter
39631 -***************************************************************************/
39632 -static void tiara_reset(struct nic *nic)
39634 - int i;
39636 - outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
39637 - outb(CLEAR_STATUS, ioaddr + DLCR_XMIT_STAT);
39638 - outb(NO_TX_IRQS, ioaddr + DLCR_XMIT_MASK);
39639 - outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
39640 - outb(XMIT_MODE, ioaddr + DLCR_XMIT_MODE);
39641 - outb(RECV_MODE, ioaddr + DLCR_RECV_MODE);
39642 - /* Vacuum recv buffer */
39643 - while ((inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) == 0)
39644 - inb(ioaddr + BMPR_MEM_PORT);
39645 - /* Set node address */
39646 - for (i = 0; i < ETH_ALEN; ++i)
39647 - outb(nic->node_addr[i], ioaddr + DLCR_NODE_ID + i);
39648 - outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
39649 - outb(CARD_ENABLE, ioaddr + DLCR_ENABLE);
39652 -/**************************************************************************
39653 -POLL - Wait for a frame
39654 -***************************************************************************/
39655 -static int tiara_poll(struct nic *nic)
39657 - unsigned int len;
39659 - if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY)
39660 - return (0);
39661 - /* Ack packet */
39662 - outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
39663 - len = inw(ioaddr + BMPR_MEM_PORT); /* throw away status */
39664 - len = inw(ioaddr + BMPR_MEM_PORT);
39665 - /* Drop overlength packets */
39666 - if (len > ETH_FRAME_LEN)
39667 - return (0); /* should we drain the buffer? */
39668 - insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2);
39669 - /* If it's our own, drop it */
39670 - if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0)
39671 - return (0);
39672 - nic->packetlen = len;
39673 - return (1);
39676 -/**************************************************************************
39677 -TRANSMIT - Transmit a frame
39678 -***************************************************************************/
39679 -static void tiara_transmit(
39680 -struct nic *nic,
39681 -const char *d, /* Destination */
39682 -unsigned int t, /* Type */
39683 -unsigned int s, /* size */
39684 -const char *p) /* Packet */
39686 - unsigned int len;
39687 - unsigned long time;
39689 - len = s + ETH_HLEN;
39690 - if (len < ETH_ZLEN)
39691 - len = ETH_ZLEN;
39692 - t = htons(t);
39693 - outsw(ioaddr + BMPR_MEM_PORT, d, ETH_ALEN / 2);
39694 - outsw(ioaddr + BMPR_MEM_PORT, nic->node_addr, ETH_ALEN / 2);
39695 - outw(t, ioaddr + BMPR_MEM_PORT);
39696 - outsw(ioaddr + BMPR_MEM_PORT, p, s / 2);
39697 - if (s & 1) /* last byte */
39698 - outb(p[s-1], ioaddr + BMPR_MEM_PORT);
39699 - while (s++ < ETH_ZLEN - ETH_HLEN) /* pad */
39700 - outb(0, ioaddr + BMPR_MEM_PORT);
39701 - outw(len | (TMST << 8), ioaddr + BMPR_PKT_LEN);
39702 - /* wait for transmit complete */
39703 - time = currticks() + TICKS_PER_SEC; /* wait one second */
39704 - while (currticks() < time && (inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
39706 - if ((inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
39707 - printf("Tiara timed out on transmit\n");
39708 - /* Do we need to ack the transmit? */
39711 -/**************************************************************************
39712 -DISABLE - Turn off ethernet interface
39713 -***************************************************************************/
39714 -static void tiara_disable(struct nic *nic)
39716 - /* Apparently only a power down can do this properly */
39717 - outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
39720 -static int tiara_probe1(struct nic *nic)
39722 - /* Hope all the Tiara cards have this vendor prefix */
39723 - static char vendor_prefix[] = { 0x08, 0x00, 0x1A };
39724 - static char all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
39725 - int i;
39727 - for (i = 0; i < ETH_ALEN; ++i)
39728 - nic->node_addr[i] = inb(ioaddr + PROM_ID + i);
39729 - if (memcmp(nic->node_addr, vendor_prefix, sizeof(vendor_prefix)) != 0)
39730 - return (0);
39731 - if (memcmp(nic->node_addr, all_ones, sizeof(all_ones)) == 0)
39732 - return (0);
39733 - printf("\nTiara ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
39734 - return (1);
39737 -/**************************************************************************
39738 -PROBE - Look for an adapter, this routine's visible to the outside
39739 -***************************************************************************/
39740 -struct nic *tiara_probe(struct nic *nic, unsigned short *probe_addrs)
39742 - /* missing entries are addresses usually already used */
39743 - static unsigned short io_addrs[] = {
39744 - 0x100, 0x120, 0x140, 0x160,
39745 - 0x180, 0x1A0, 0x1C0, 0x1E0,
39746 - 0x200, 0x220, 0x240, /*Par*/
39747 - 0x280, 0x2A0, 0x2C0, /*Ser*/
39748 - 0x300, 0x320, 0x340, /*Par*/
39749 - 0x380, /*Vid,Par*/ 0x3C0, /*Ser*/
39750 - 0x0
39751 - };
39752 - unsigned short *p;
39754 - /* if probe_addrs is 0, then routine can use a hardwired default */
39755 - if (probe_addrs == 0)
39756 - probe_addrs = io_addrs;
39757 - for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
39758 - if (tiara_probe1(nic))
39759 - break;
39760 - /* if board found */
39761 - if (ioaddr != 0)
39763 - tiara_reset(nic);
39764 - /* point to NIC specific routines */
39765 - nic->reset = tiara_reset;
39766 - nic->poll = tiara_poll;
39767 - nic->transmit = tiara_transmit;
39768 - nic->disable = tiara_disable;
39769 - return nic;
39771 - else
39772 - return (0);
39774 Index: b/netboot/timer.c
39775 ===================================================================
39776 --- a/netboot/timer.c
39777 +++ b/netboot/timer.c
39778 @@ -6,122 +6,24 @@
39779 * published by the Free Software Foundation; either version 2, or (at
39780 * your option) any later version.
39783 -#include "etherboot.h"
39784 +#include "grub.h"
39785 #include "timer.h"
39787 -void load_timer2(unsigned int ticks)
39789 - /* Set up the timer gate, turn off the speaker */
39790 - outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
39791 - outb(TIMER2_SEL|WORD_ACCESS|MODE0|BINARY_COUNT, TIMER_MODE_PORT);
39792 - outb(ticks & 0xFF, TIMER2_PORT);
39793 - outb(ticks >> 8, TIMER2_PORT);
39796 -#if defined(CONFIG_TSC_CURRTICKS)
39797 -#define rdtsc(low,high) \
39798 - __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
39800 -#define rdtscll(val) \
39801 - __asm__ __volatile__ ("rdtsc" : "=A" (val))
39804 -#define HZ TICKS_PER_SEC
39805 -#define CLOCK_TICK_RATE 1193180U /* Underlying HZ */
39806 -/* LATCH is used in the interval timer and ftape setup. */
39807 -#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
39808 +/* Machine Independant timer helper functions */
39811 -/* ------ Calibrate the TSC -------
39812 - * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
39813 - * Too much 64-bit arithmetic here to do this cleanly in C, and for
39814 - * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
39815 - * output busy loop as low as possible. We avoid reading the CTC registers
39816 - * directly because of the awkward 8-bit access mechanism of the 82C54
39817 - * device.
39818 - */
39820 -#define CALIBRATE_LATCH (5 * LATCH)
39822 -static unsigned long long calibrate_tsc(void)
39823 +void mdelay(unsigned int msecs)
39825 - /* Set the Gate high, disable speaker */
39826 - outb((inb(0x61) & ~0x02) | 0x01, 0x61);
39828 - /*
39829 - * Now let's take care of CTC channel 2
39831 - * Set the Gate high, program CTC channel 2 for mode 0,
39832 - * (interrupt on terminal count mode), binary count,
39833 - * load 5 * LATCH count, (LSB and MSB) to begin countdown.
39834 - */
39835 - outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
39836 - outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
39837 - outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
39840 - unsigned long startlow, starthigh;
39841 - unsigned long endlow, endhigh;
39842 - unsigned long count;
39844 - rdtsc(startlow,starthigh);
39845 - count = 0;
39846 - do {
39847 - count++;
39848 - } while ((inb(0x61) & 0x20) == 0);
39849 - rdtsc(endlow,endhigh);
39851 - /* Error: ECTCNEVERSET */
39852 - if (count <= 1)
39853 - goto bad_ctc;
39855 - /* 64-bit subtract - gcc just messes up with long longs */
39856 - __asm__("subl %2,%0\n\t"
39857 - "sbbl %3,%1"
39858 - :"=a" (endlow), "=d" (endhigh)
39859 - :"g" (startlow), "g" (starthigh),
39860 - "0" (endlow), "1" (endhigh));
39862 - /* Error: ECPUTOOFAST */
39863 - if (endhigh)
39864 - goto bad_ctc;
39866 - endlow /= 5;
39867 - return endlow;
39868 + unsigned int i;
39869 + for(i = 0; i < msecs; i++) {
39870 + udelay(1000);
39871 + poll_interruptions();
39874 - /*
39875 - * The CTC wasn't reliable: we got a hit on the very first read,
39876 - * or the CPU was so fast/slow that the quotient wouldn't fit in
39877 - * 32 bits..
39878 - */
39879 -bad_ctc:
39880 - printf("bad_ctc\n");
39881 - return 0;
39885 -unsigned long currticks(void)
39886 +void waiton_timer2(unsigned int ticks)
39888 - static unsigned long clocks_per_tick;
39889 - unsigned long clocks_high, clocks_low;
39890 - unsigned long currticks;
39891 - if (!clocks_per_tick) {
39892 - clocks_per_tick = calibrate_tsc();
39893 - printf("clocks_per_tick = %d\n", clocks_per_tick);
39894 + load_timer2(ticks);
39895 + while(timer2_running()) {
39896 + poll_interruptions();
39899 - /* Read the Time Stamp Counter */
39900 - rdtsc(clocks_low, clocks_high);
39902 - /* currticks = clocks / clocks_per_tick; */
39903 - __asm__("divl %1"
39904 - :"=a" (currticks)
39905 - :"r" (clocks_per_tick), "0" (clocks_low), "d" (clocks_high));
39908 - return currticks;
39911 -#endif /* RTC_CURRTICKS */
39912 Index: b/netboot/timer.h
39913 ===================================================================
39914 --- a/netboot/timer.h
39915 +++ b/netboot/timer.h
39916 @@ -36,7 +36,8 @@
39917 #define BCD_COUNT 0x01
39919 /* Timers tick over at this rate */
39920 -#define TICKS_PER_MS 1193
39921 +#define CLOCK_TICK_RATE 1193180U
39922 +#define TICKS_PER_MS (CLOCK_TICK_RATE/1000)
39924 /* Parallel Peripheral Controller Port B */
39925 #define PPC_PORTB 0x61
39926 @@ -49,16 +50,19 @@
39927 /* Ticks must be between 0 and 65535 (0 == 65536)
39928 because it is a 16 bit counter */
39929 extern void load_timer2(unsigned int ticks);
39930 -extern inline int timer2_running(void)
39932 - return ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
39935 -extern inline void waiton_timer2(unsigned int ticks)
39937 - load_timer2(ticks);
39938 - while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0)
39941 +extern inline int timer2_running(void);
39942 +extern void waiton_timer2(unsigned int ticks);
39943 +extern void __load_timer2(unsigned int ticks);
39945 +extern void setup_timers(void);
39946 +extern void ndelay(unsigned int nsecs);
39947 +extern void udelay(unsigned int usecs);
39948 +extern void mdelay(unsigned int msecs);
39949 +//extern unsigned long currticks(void);
39951 +struct timeval {
39952 + long tv_sec;
39953 + long tv_usec;
39956 #endif /* TIMER_H */
39957 Index: b/netboot/tlan.c
39958 ===================================================================
39959 --- a/netboot/tlan.c
39960 +++ b/netboot/tlan.c
39961 @@ -1,3746 +1,1814 @@
39962 +#define EB51
39964 +#ifdef EB50
39965 +#define __unused __attribute__((unused))
39966 +#endif
39968 /**************************************************************************
39969 -Etherboot - BOOTP/TFTP Bootstrap Program
39970 -TLAN driver for Etherboot
39972 +* tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN
39973 +* Written 2003-2003 by Timothy Legge <tlegge@rogers.com>
39975 +* This program is free software; you can redistribute it and/or modify
39976 +* it under the terms of the GNU General Public License as published by
39977 +* the Free Software Foundation; either version 2 of the License, or
39978 +* (at your option) any later version.
39980 +* This program is distributed in the hope that it will be useful,
39981 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
39982 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39983 +* GNU General Public License for more details.
39985 +* You should have received a copy of the GNU General Public License
39986 +* along with this program; if not, write to the Free Software
39987 +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
39989 +* Portions of this code based on:
39990 +* lan.c: Linux ThunderLan Driver:
39992 +* by James Banks
39994 +* (C) 1997-1998 Caldera, Inc.
39995 +* (C) 1998 James Banks
39996 +* (C) 1999-2001 Torben Mathiasen
39997 +* (C) 2002 Samuel Chessman
39999 +* REVISION HISTORY:
40000 +* ================
40001 +* v1.0 07-08-2003 timlegge Initial not quite working version
40002 +* v1.1 07-27-2003 timlegge Sync 5.0 and 5.1 versions
40003 +* v1.2 08-19-2003 timlegge Implement Multicast Support
40004 +* v1.3 08-23-2003 timlegge Fix the transmit Function
40005 +* v1.4 01-17-2004 timlegge Initial driver output cleanup
40007 +* Indent Options: indent -kr -i8
40008 ***************************************************************************/
40011 - * This program is free software; you can redistribute it and/or
40012 - * modify it under the terms of the GNU General Public License as
40013 - * published by the Free Software Foundation; either version 2, or (at
40014 - * your option) any later version.
40015 - */
40017 /* to get some global routines like printf */
40018 #include "etherboot.h"
40019 /* to get the interface to the body of the program */
40020 #include "nic.h"
40021 /* to get the PCI support functions, if this is a PCI NIC */
40022 #include "pci.h"
40023 -/* to get our own prototype */
40024 -#include "cards.h"
40026 - /*****************************************************************
40027 - * TLan Definitions
40029 - ****************************************************************/
40030 +#include "timer.h"
40031 +#include "tlan.h"
40033 -#define TLAN_MIN_FRAME_SIZE 64
40034 -#define TLAN_MAX_FRAME_SIZE 1600
40035 +#define drv_version "v1.4"
40036 +#define drv_date "01-17-2004"
40038 -#define TLAN_NUM_RX_LISTS 32
40039 -#define TLAN_NUM_TX_LISTS 64
40040 +/* NIC specific static variables go here */
40041 +#define HZ 100
40042 +#define TX_TIME_OUT (6*HZ)
40044 -#define TLAN_IGNORE 0
40045 -#define TLAN_RECORD 1
40046 +#ifdef EB50
40047 +#define cpu_to_le32(val) (val)
40048 +#define le32_to_cpu(val) (val)
40049 +#define virt_to_bus(x) ((unsigned long) x)
40050 +#define bus_to_virt(x) ((unsigned long) x)
40051 +#endif
40053 -#define TLAN_DBG(lvl, format, args...) if (debug&lvl) printf("TLAN: " format, ##args );
40054 -#define TLAN_DEBUG_GNRL 0x0001
40055 -#define TLAN_DEBUG_TX 0x0002
40056 -#define TLAN_DEBUG_RX 0x0004
40057 -#define TLAN_DEBUG_LIST 0x0008
40058 -#define TLAN_DEBUG_PROBE 0x0010
40059 +/* Condensed operations for readability. */
40060 +#define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
40061 +#define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
40063 -#define MAX_TLAN_BOARDS 8 /* Max number of boards installed at a time */
40065 - /*****************************************************************
40066 - * Device Identification Definitions
40068 - ****************************************************************/
40070 -#define PCI_DEVICE_ID_NETELLIGENT_10_T2 0xB012
40071 -#define PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100 0xB030
40072 -#ifndef PCI_DEVICE_ID_OLICOM_OC2183
40073 -#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
40074 -#endif
40075 -#ifndef PCI_DEVICE_ID_OLICOM_OC2325
40076 -#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
40077 -#endif
40078 -#ifndef PCI_DEVICE_ID_OLICOM_OC2326
40079 -#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
40080 -#endif
40081 -#define TLAN_ADAPTER_NONE 0x00000000
40082 -#define TLAN_ADAPTER_UNMANAGED_PHY 0x00000001
40083 -#define TLAN_ADAPTER_BIT_RATE_PHY 0x00000002
40084 -#define TLAN_ADAPTER_USE_INTERN_10 0x00000004
40085 -#define TLAN_ADAPTER_ACTIVITY_LED 0x00000008
40086 -#define TLAN_SPEED_DEFAULT 0
40087 -#define TLAN_SPEED_10 10
40088 -#define TLAN_SPEED_100 100
40089 -#define TLAN_DUPLEX_DEFAULT 0
40090 -#define TLAN_DUPLEX_HALF 1
40091 -#define TLAN_DUPLEX_FULL 2
40092 -#define TLAN_BUFFERS_PER_LIST 10
40093 -#define TLAN_LAST_BUFFER 0x80000000
40094 -#define TLAN_CSTAT_UNUSED 0x8000
40095 -#define TLAN_CSTAT_FRM_CMP 0x4000
40096 -#define TLAN_CSTAT_READY 0x3000
40097 -#define TLAN_CSTAT_EOC 0x0800
40098 -#define TLAN_CSTAT_RX_ERROR 0x0400
40099 -#define TLAN_CSTAT_PASS_CRC 0x0200
40100 -#define TLAN_CSTAT_DP_PR 0x0100
40102 - /*****************************************************************
40103 - * PHY definitions
40105 - ****************************************************************/
40107 -#define TLAN_PHY_MAX_ADDR 0x1F
40108 -#define TLAN_PHY_NONE 0x20
40110 - /*****************************************************************
40111 - * TLan Driver Timer Definitions
40113 - ****************************************************************/
40115 -#define TLAN_TIMER_LINK_BEAT 1
40116 -#define TLAN_TIMER_ACTIVITY 2
40117 -#define TLAN_TIMER_PHY_PDOWN 3
40118 -#define TLAN_TIMER_PHY_PUP 4
40119 -#define TLAN_TIMER_PHY_RESET 5
40120 -#define TLAN_TIMER_PHY_START_LINK 6
40121 -#define TLAN_TIMER_PHY_FINISH_AN 7
40122 -#define TLAN_TIMER_FINISH_RESET 8
40123 -#define TLAN_TIMER_ACT_DELAY (HZ/10)
40125 - /*****************************************************************
40126 - * TLan Driver Eeprom Definitions
40128 - ****************************************************************/
40130 -#define TLAN_EEPROM_ACK 0
40131 -#define TLAN_EEPROM_STOP 1
40133 - /*****************************************************************
40134 - * Host Register Offsets and Contents
40136 - ****************************************************************/
40138 -#define TLAN_HOST_CMD 0x00
40139 -#define TLAN_HC_GO 0x80000000
40140 -#define TLAN_HC_STOP 0x40000000
40141 -#define TLAN_HC_ACK 0x20000000
40142 -#define TLAN_HC_CS_MASK 0x1FE00000
40143 -#define TLAN_HC_EOC 0x00100000
40144 -#define TLAN_HC_RT 0x00080000
40145 -#define TLAN_HC_NES 0x00040000
40146 -#define TLAN_HC_AD_RST 0x00008000
40147 -#define TLAN_HC_LD_TMR 0x00004000
40148 -#define TLAN_HC_LD_THR 0x00002000
40149 -#define TLAN_HC_REQ_INT 0x00001000
40150 -#define TLAN_HC_INT_OFF 0x00000800
40151 -#define TLAN_HC_INT_ON 0x00000400
40152 -#define TLAN_HC_AC_MASK 0x000000FF
40153 -#define TLAN_CH_PARM 0x04
40154 -#define TLAN_DIO_ADR 0x08
40155 -#define TLAN_DA_ADR_INC 0x8000
40156 -#define TLAN_DA_RAM_ADR 0x4000
40157 -#define TLAN_HOST_INT 0x0A
40158 -#define TLAN_HI_IV_MASK 0x1FE0
40159 -#define TLAN_HI_IT_MASK 0x001C
40160 -#define TLAN_DIO_DATA 0x0C
40162 -/* ThunderLAN Internal Register DIO Offsets */
40164 -#define TLAN_NET_CMD 0x00
40165 -#define TLAN_NET_CMD_NRESET 0x80
40166 -#define TLAN_NET_CMD_NWRAP 0x40
40167 -#define TLAN_NET_CMD_CSF 0x20
40168 -#define TLAN_NET_CMD_CAF 0x10
40169 -#define TLAN_NET_CMD_NOBRX 0x08
40170 -#define TLAN_NET_CMD_DUPLEX 0x04
40171 -#define TLAN_NET_CMD_TRFRAM 0x02
40172 -#define TLAN_NET_CMD_TXPACE 0x01
40173 -#define TLAN_NET_SIO 0x01
40174 -#define TLAN_NET_SIO_MINTEN 0x80
40175 -#define TLAN_NET_SIO_ECLOK 0x40
40176 -#define TLAN_NET_SIO_ETXEN 0x20
40177 -#define TLAN_NET_SIO_EDATA 0x10
40178 -#define TLAN_NET_SIO_NMRST 0x08
40179 -#define TLAN_NET_SIO_MCLK 0x04
40180 -#define TLAN_NET_SIO_MTXEN 0x02
40181 -#define TLAN_NET_SIO_MDATA 0x01
40182 -#define TLAN_NET_STS 0x02
40183 -#define TLAN_NET_STS_MIRQ 0x80
40184 -#define TLAN_NET_STS_HBEAT 0x40
40185 -#define TLAN_NET_STS_TXSTOP 0x20
40186 -#define TLAN_NET_STS_RXSTOP 0x10
40187 -#define TLAN_NET_STS_RSRVD 0x0F
40188 -#define TLAN_NET_MASK 0x03
40189 -#define TLAN_NET_MASK_MASK7 0x80
40190 -#define TLAN_NET_MASK_MASK6 0x40
40191 -#define TLAN_NET_MASK_MASK5 0x20
40192 -#define TLAN_NET_MASK_MASK4 0x10
40193 -#define TLAN_NET_MASK_RSRVD 0x0F
40194 -#define TLAN_NET_CONFIG 0x04
40195 -#define TLAN_NET_CFG_RCLK 0x8000
40196 -#define TLAN_NET_CFG_TCLK 0x4000
40197 -#define TLAN_NET_CFG_BIT 0x2000
40198 -#define TLAN_NET_CFG_RXCRC 0x1000
40199 -#define TLAN_NET_CFG_PEF 0x0800
40200 -#define TLAN_NET_CFG_1FRAG 0x0400
40201 -#define TLAN_NET_CFG_1CHAN 0x0200
40202 -#define TLAN_NET_CFG_MTEST 0x0100
40203 -#define TLAN_NET_CFG_PHY_EN 0x0080
40204 -#define TLAN_NET_CFG_MSMASK 0x007F
40205 -#define TLAN_MAN_TEST 0x06
40206 -#define TLAN_DEF_VENDOR_ID 0x08
40207 -#define TLAN_DEF_DEVICE_ID 0x0A
40208 -#define TLAN_DEF_REVISION 0x0C
40209 -#define TLAN_DEF_SUBCLASS 0x0D
40210 -#define TLAN_DEF_MIN_LAT 0x0E
40211 -#define TLAN_DEF_MAX_LAT 0x0F
40212 -#define TLAN_AREG_0 0x10
40213 -#define TLAN_AREG_1 0x16
40214 -#define TLAN_AREG_2 0x1C
40215 -#define TLAN_AREG_3 0x22
40216 -#define TLAN_HASH_1 0x28
40217 -#define TLAN_HASH_2 0x2C
40218 -#define TLAN_GOOD_TX_FRMS 0x30
40219 -#define TLAN_TX_UNDERUNS 0x33
40220 -#define TLAN_GOOD_RX_FRMS 0x34
40221 -#define TLAN_RX_OVERRUNS 0x37
40222 -#define TLAN_DEFERRED_TX 0x38
40223 -#define TLAN_CRC_ERRORS 0x3A
40224 -#define TLAN_CODE_ERRORS 0x3B
40225 -#define TLAN_MULTICOL_FRMS 0x3C
40226 -#define TLAN_SINGLECOL_FRMS 0x3E
40227 -#define TLAN_EXCESSCOL_FRMS 0x40
40228 -#define TLAN_LATE_COLS 0x41
40229 -#define TLAN_CARRIER_LOSS 0x42
40230 -#define TLAN_ACOMMIT 0x43
40231 -#define TLAN_LED_REG 0x44
40232 -#define TLAN_LED_ACT 0x10
40233 -#define TLAN_LED_LINK 0x01
40234 -#define TLAN_BSIZE_REG 0x45
40235 -#define TLAN_MAX_RX 0x46
40236 -#define TLAN_INT_DIS 0x48
40237 -#define TLAN_ID_TX_EOC 0x04
40238 -#define TLAN_ID_RX_EOF 0x02
40239 -#define TLAN_ID_RX_EOC 0x01
40241 -/* ThunderLAN Interrupt Codes */
40243 -#define TLAN_INT_NUMBER_OF_INTS 8
40245 -#define TLAN_INT_NONE 0x0000
40246 -#define TLAN_INT_TX_EOF 0x0001
40247 -#define TLAN_INT_STAT_OVERFLOW 0x0002
40248 -#define TLAN_INT_RX_EOF 0x0003
40249 -#define TLAN_INT_DUMMY 0x0004
40250 -#define TLAN_INT_TX_EOC 0x0005
40251 -#define TLAN_INT_STATUS_CHECK 0x0006
40252 -#define TLAN_INT_RX_EOC 0x0007
40253 -#define TLAN_TLPHY_ID 0x10
40254 -#define TLAN_TLPHY_CTL 0x11
40255 -#define TLAN_TC_IGLINK 0x8000
40256 -#define TLAN_TC_SWAPOL 0x4000
40257 -#define TLAN_TC_AUISEL 0x2000
40258 -#define TLAN_TC_SQEEN 0x1000
40259 -#define TLAN_TC_MTEST 0x0800
40260 -#define TLAN_TC_RESERVED 0x07F8
40261 -#define TLAN_TC_NFEW 0x0004
40262 -#define TLAN_TC_INTEN 0x0002
40263 -#define TLAN_TC_TINT 0x0001
40264 -#define TLAN_TLPHY_STS 0x12
40265 -#define TLAN_TS_MINT 0x8000
40266 -#define TLAN_TS_PHOK 0x4000
40267 -#define TLAN_TS_POLOK 0x2000
40268 -#define TLAN_TS_TPENERGY 0x1000
40269 -#define TLAN_TS_RESERVED 0x0FFF
40270 -#define TLAN_TLPHY_PAR 0x19
40271 -#define TLAN_PHY_CIM_STAT 0x0020
40272 -#define TLAN_PHY_SPEED_100 0x0040
40273 -#define TLAN_PHY_DUPLEX_FULL 0x0080
40274 -#define TLAN_PHY_AN_EN_STAT 0x0400
40277 -/* ThunderLAN MII Registers */
40279 -/* Generic MII/PHY Registers */
40281 -#define MII_GEN_CTL 0x00
40282 -#define MII_GC_RESET 0x8000
40283 -#define MII_GC_LOOPBK 0x4000
40284 -#define MII_GC_SPEEDSEL 0x2000
40285 -#define MII_GC_AUTOENB 0x1000
40286 -#define MII_GC_PDOWN 0x0800
40287 -#define MII_GC_ISOLATE 0x0400
40288 -#define MII_GC_AUTORSRT 0x0200
40289 -#define MII_GC_DUPLEX 0x0100
40290 -#define MII_GC_COLTEST 0x0080
40291 -#define MII_GC_RESERVED 0x007F
40292 -#define MII_GEN_STS 0x01
40293 -#define MII_GS_100BT4 0x8000
40294 -#define MII_GS_100BTXFD 0x4000
40295 -#define MII_GS_100BTXHD 0x2000
40296 -#define MII_GS_10BTFD 0x1000
40297 -#define MII_GS_10BTHD 0x0800
40298 -#define MII_GS_RESERVED 0x07C0
40299 -#define MII_GS_AUTOCMPLT 0x0020
40300 -#define MII_GS_RFLT 0x0010
40301 -#define MII_GS_AUTONEG 0x0008
40302 -#define MII_GS_LINK 0x0004
40303 -#define MII_GS_JABBER 0x0002
40304 -#define MII_GS_EXTCAP 0x0001
40305 -#define MII_GEN_ID_HI 0x02
40306 -#define MII_GEN_ID_LO 0x03
40307 -#define MII_GIL_OUI 0xFC00
40308 -#define MII_GIL_MODEL 0x03F0
40309 -#define MII_GIL_REVISION 0x000F
40310 -#define MII_AN_ADV 0x04
40311 -#define MII_AN_LPA 0x05
40312 -#define MII_AN_EXP 0x06
40314 -/* ThunderLAN Specific MII/PHY Registers */
40316 -#define TLAN_TC_IGLINK 0x8000
40317 -#define TLAN_TC_SWAPOL 0x4000
40318 -#define TLAN_TC_AUISEL 0x2000
40319 -#define TLAN_TC_SQEEN 0x1000
40320 -#define TLAN_TC_MTEST 0x0800
40321 -#define TLAN_TC_RESERVED 0x07F8
40322 -#define TLAN_TC_NFEW 0x0004
40323 -#define TLAN_TC_INTEN 0x0002
40324 -#define TLAN_TC_TINT 0x0001
40325 -#define TLAN_TS_MINT 0x8000
40326 -#define TLAN_TS_PHOK 0x4000
40327 -#define TLAN_TS_POLOK 0x2000
40328 -#define TLAN_TS_TPENERGY 0x1000
40329 -#define TLAN_TS_RESERVED 0x0FFF
40330 -#define TLAN_PHY_CIM_STAT 0x0020
40331 -#define TLAN_PHY_SPEED_100 0x0040
40332 -#define TLAN_PHY_DUPLEX_FULL 0x0080
40333 -#define TLAN_PHY_AN_EN_STAT 0x0400
40335 -/* National Sem. & Level1 PHY id's */
40336 -#define NAT_SEM_ID1 0x2000
40337 -#define NAT_SEM_ID2 0x5C01
40338 -#define LEVEL1_ID1 0x7810
40339 -#define LEVEL1_ID2 0x0000
40341 -#define TLan_ClearBit( bit, port ) outb_p(inb_p(port) & ~bit, port)
40342 -#define TLan_GetBit( bit, port ) ((int) (inb_p(port) & bit))
40343 -#define TLan_SetBit( bit, port ) outb_p(inb_p(port) | bit, port)
40345 -typedef unsigned int u32;
40346 -typedef unsigned short u16;
40347 -typedef unsigned char u8;
40348 +static void TLan_ResetLists(struct nic *nic __unused);
40349 +static void TLan_ResetAdapter(struct nic *nic __unused);
40350 +static void TLan_FinishReset(struct nic *nic __unused);
40352 -/* Routines to access internal registers. */
40353 +static void TLan_EeSendStart(u16);
40354 +static int TLan_EeSendByte(u16, u8, int);
40355 +static void TLan_EeReceiveByte(u16, u8 *, int);
40356 +static int TLan_EeReadByte(u16 io_base, u8, u8 *);
40358 -inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
40360 - outw(internal_addr, base_addr + TLAN_DIO_ADR);
40361 - return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)));
40363 -} /* TLan_DioRead8 */
40364 +static void TLan_PhyDetect(struct nic *nic);
40365 +static void TLan_PhyPowerDown(struct nic *nic);
40366 +static void TLan_PhyPowerUp(struct nic *nic);
40368 -inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
40370 - outw(internal_addr, base_addr + TLAN_DIO_ADR);
40371 - return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)));
40373 -} /* TLan_DioRead16 */
40374 +static void TLan_SetMac(struct nic *nic __unused, int areg, char *mac);
40376 -inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr)
40378 - outw(internal_addr, base_addr + TLAN_DIO_ADR);
40379 - return (inl(base_addr + TLAN_DIO_DATA));
40380 +static void TLan_PhyReset(struct nic *nic);
40381 +static void TLan_PhyStartLink(struct nic *nic);
40382 +static void TLan_PhyFinishAutoNeg(struct nic *nic);
40384 -} /* TLan_DioRead32 */
40385 +#ifdef MONITOR
40386 +static void TLan_PhyMonitor(struct nic *nic);
40387 +#endif
40389 -inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data)
40391 - outw(internal_addr, base_addr + TLAN_DIO_ADR);
40392 - outb(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x3));
40395 +static void refill_rx(struct nic *nic __unused);
40397 -inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data)
40399 - outw(internal_addr, base_addr + TLAN_DIO_ADR);
40400 - outw(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
40401 +static int TLan_MiiReadReg(struct nic *nic __unused, u16, u16, u16 *);
40402 +static void TLan_MiiSendData(u16, u32, unsigned);
40403 +static void TLan_MiiSync(u16);
40404 +static void TLan_MiiWriteReg(struct nic *nic __unused, u16, u16, u16);
40408 -inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data)
40410 - outw(internal_addr, base_addr + TLAN_DIO_ADR);
40411 - outl(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
40412 +const char *media[] = {
40413 + "10BaseT-HD ", "10BaseT-FD ", "100baseTx-HD ",
40414 + "100baseTx-FD", "100baseT4", 0
40418 +/* This much match tlan_pci_tbl[]! */
40419 +enum tlan_nics {
40420 + NETEL10 = 0, NETEL100 = 1, NETFLEX3I = 2, THUNDER = 3, NETFLEX3B =
40421 + 4, NETEL100PI = 5,
40422 + NETEL100D = 6, NETEL100I = 7, OC2183 = 8, OC2325 = 9, OC2326 =
40423 + 10, NETELLIGENT_10_100_WS_5100 = 11,
40424 + NETELLIGENT_10_T2 = 12
40427 -/* NIC specific static variables go here */
40428 +struct pci_id_info {
40429 + const char *name;
40430 + int nic_id;
40431 + struct match_info {
40432 + u32 pci, pci_mask, subsystem, subsystem_mask;
40433 + u32 revision, revision_mask; /* Only 8 bits. */
40434 + } id;
40435 + u32 flags;
40436 + u16 addrOfs; /* Address Offset */
40439 -/*****************************************************************************
40440 -******************************************************************************
40441 +static struct pci_id_info tlan_pci_tbl[] = {
40442 + {"Compaq Netelligent 10 T PCI UTP", NETEL10,
40443 + {0xae340e11, 0xffffffff, 0, 0, 0, 0},
40444 + TLAN_ADAPTER_ACTIVITY_LED, 0x83},
40445 + {"Compaq Netelligent 10/100 TX PCI UTP", NETEL100,
40446 + {0xae320e11, 0xffffffff, 0, 0, 0, 0},
40447 + TLAN_ADAPTER_ACTIVITY_LED, 0x83},
40448 + {"Compaq Integrated NetFlex-3/P", NETFLEX3I,
40449 + {0xae350e11, 0xffffffff, 0, 0, 0, 0},
40450 + TLAN_ADAPTER_NONE, 0x83},
40451 + {"Compaq NetFlex-3/P", THUNDER,
40452 + {0xf1300e11, 0xffffffff, 0, 0, 0, 0},
40453 + TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83},
40454 + {"Compaq NetFlex-3/P", NETFLEX3B,
40455 + {0xf1500e11, 0xffffffff, 0, 0, 0, 0},
40456 + TLAN_ADAPTER_NONE, 0x83},
40457 + {"Compaq Netelligent Integrated 10/100 TX UTP", NETEL100PI,
40458 + {0xae430e11, 0xffffffff, 0, 0, 0, 0},
40459 + TLAN_ADAPTER_ACTIVITY_LED, 0x83},
40460 + {"Compaq Netelligent Dual 10/100 TX PCI UTP", NETEL100D,
40461 + {0xae400e11, 0xffffffff, 0, 0, 0, 0},
40462 + TLAN_ADAPTER_NONE, 0x83},
40463 + {"Compaq Netelligent 10/100 TX Embedded UTP", NETEL100I,
40464 + {0xb0110e11, 0xffffffff, 0, 0, 0, 0},
40465 + TLAN_ADAPTER_NONE, 0x83},
40466 + {"Olicom OC-2183/2185", OC2183,
40467 + {0x0013108d, 0xffffffff, 0, 0, 0, 0},
40468 + TLAN_ADAPTER_USE_INTERN_10, 0x83},
40469 + {"Olicom OC-2325", OC2325,
40470 + {0x0012108d, 0xffffffff, 0, 0, 0, 0},
40471 + TLAN_ADAPTER_UNMANAGED_PHY, 0xF8},
40472 + {"Olicom OC-2326", OC2326,
40473 + {0x0014108d, 0xffffffff, 0, 0, 0, 0},
40474 + TLAN_ADAPTER_USE_INTERN_10, 0xF8},
40475 + {"Compaq Netelligent 10/100 TX UTP", NETELLIGENT_10_100_WS_5100,
40476 + {0xb0300e11, 0xffffffff, 0, 0, 0, 0},
40477 + TLAN_ADAPTER_ACTIVITY_LED, 0x83},
40478 + {"Compaq Netelligent 10 T/2 PCI UTP/Coax", NETELLIGENT_10_T2,
40479 + {0xb0120e11, 0xffffffff, 0, 0, 0, 0},
40480 + TLAN_ADAPTER_NONE, 0x83},
40481 + {"Compaq NetFlex-3/E", 0, /* EISA card */
40482 + {0, 0, 0, 0, 0, 0},
40483 + TLAN_ADAPTER_ACTIVITY_LED | TLAN_ADAPTER_UNMANAGED_PHY |
40484 + TLAN_ADAPTER_BIT_RATE_PHY, 0x83},
40485 + {"Compaq NetFlex-3/E", 0, /* EISA card */
40486 + {0, 0, 0, 0, 0, 0},
40487 + TLAN_ADAPTER_ACTIVITY_LED, 0x83},
40488 + {0, 0,
40489 + {0, 0, 0, 0, 0, 0},
40490 + 0, 0},
40493 - ThunderLAN Driver Eeprom routines
40495 - The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
40496 - EEPROM. These functions are based on information in Microchip's
40497 - data sheet. I don't know how well this functions will work with
40498 - other EEPROMs.
40499 +struct TLanList {
40500 + u32 forward;
40501 + u16 cStat;
40502 + u16 frameSize;
40503 + struct {
40504 + u32 count;
40505 + u32 address;
40506 + } buffer[TLAN_BUFFERS_PER_LIST];
40509 -******************************************************************************
40510 -*****************************************************************************/
40512 - /***************************************************************
40513 - * TLan_EeSendStart
40515 - * Returns:
40516 - * Nothing
40517 - * Parms:
40518 - * io_base The IO port base address for the
40519 - * TLAN device with the EEPROM to
40520 - * use.
40522 - * This function sends a start cycle to an EEPROM attached
40523 - * to a TLAN chip.
40525 - **************************************************************/
40527 -static void TLan_EeSendStart( u16 io_base )
40529 - u16 sio;
40530 +struct TLanList tx_ring[TLAN_NUM_TX_LISTS];
40531 +static unsigned char txb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_TX_LISTS];
40533 - outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
40534 - sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
40535 +struct TLanList rx_ring[TLAN_NUM_RX_LISTS];
40536 +static unsigned char rxb[TLAN_MAX_FRAME_SIZE * TLAN_NUM_RX_LISTS];
40538 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40539 - TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
40540 - TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
40541 - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
40542 - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
40543 +typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE];
40545 -} /* TLan_EeSendStart */
40547 - /***************************************************************
40548 - * TLan_EeSendByte
40550 - * Returns:
40551 - * If the correct ack was received, 0, otherwise 1
40552 - * Parms: io_base The IO port base address for the
40553 - * TLAN device with the EEPROM to
40554 - * use.
40555 - * data The 8 bits of information to
40556 - * send to the EEPROM.
40557 - * stop If TLAN_EEPROM_STOP is passed, a
40558 - * stop cycle is sent after the
40559 - * byte is sent after the ack is
40560 - * read.
40562 - * This function sends a byte on the serial EEPROM line,
40563 - * driving the clock to send each bit. The function then
40564 - * reverses transmission direction and reads an acknowledge
40565 - * bit.
40567 - **************************************************************/
40568 +int chip_idx;
40570 -static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
40572 - int err;
40573 - u8 place;
40574 - u16 sio;
40576 - outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
40577 - sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
40578 +/*****************************************************************
40579 +* TLAN Private Information Structure
40581 +****************************************************************/
40582 +struct tlan_private {
40583 + unsigned short vendor_id; /* PCI Vendor code */
40584 + unsigned short dev_id; /* PCI Device code */
40585 + const char *nic_name;
40586 + u8 *padBuffer;
40587 + u8 *rxBuffer;
40588 + struct TLanList *rx_head_desc;
40589 + u32 rxHead;
40590 + u32 rxTail;
40591 + u32 rxEocCount;
40592 + unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indicies */
40593 + unsigned int cur_tx, dirty_tx;
40594 + unsigned rx_buf_sz; /* Based on mtu + Slack */
40595 + struct TLanList *txList;
40596 + struct TLanList *rxList;
40597 + u8 *txBuffer;
40598 + u32 txHead;
40599 + u32 txInProgress;
40600 + u32 txTail;
40601 + int eoc;
40602 + u32 txBusyCount;
40603 + u32 phyOnline;
40604 + u32 timerSetAt;
40605 + u32 timerType;
40606 + u32 adapterRev;
40607 + u32 aui;
40608 + u32 debug;
40609 + u32 duplex;
40610 + u32 phy[2];
40611 + u32 phyNum;
40612 + u32 speed;
40613 + u8 tlanRev;
40614 + u8 tlanFullDuplex;
40615 + char devName[8];
40616 + u8 link;
40617 + u8 is_eisa;
40618 + u8 neg_be_verbose;
40619 +} TLanPrivateInfo;
40621 - /* Assume clock is low, tx is enabled; */
40622 - for ( place = 0x80; place != 0; place >>= 1 ) {
40623 - if ( place & data )
40624 - TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
40625 - else
40626 - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
40627 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40628 - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
40630 - TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
40631 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40632 - err = TLan_GetBit( TLAN_NET_SIO_EDATA, sio );
40633 - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
40634 - TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
40635 +static struct tlan_private *priv;
40637 - if ( ( ! err ) && stop ) {
40638 - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
40639 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40640 - TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
40642 +u32 BASE;
40644 - return ( err );
40646 -} /* TLan_EeSendByte */
40648 - /***************************************************************
40649 - * TLan_EeReceiveByte
40651 - * Returns:
40652 - * Nothing
40653 - * Parms:
40654 - * io_base The IO port base address for the
40655 - * TLAN device with the EEPROM to
40656 - * use.
40657 - * data An address to a char to hold the
40658 - * data sent from the EEPROM.
40659 - * stop If TLAN_EEPROM_STOP is passed, a
40660 - * stop cycle is sent after the
40661 - * byte is received, and no ack is
40662 - * sent.
40664 - * This function receives 8 bits of data from the EEPROM
40665 - * over the serial link. It then sends and ack bit, or no
40666 - * ack and a stop bit. This function is used to retrieve
40667 - * data after the address of a byte in the EEPROM has been
40668 - * sent.
40670 - **************************************************************/
40671 +/***************************************************************
40672 +* TLan_ResetLists
40674 +* Returns:
40675 +* Nothing
40676 +* Parms:
40677 +* dev The device structure with the list
40678 +* stuctures to be reset.
40680 +* This routine sets the variables associated with managing
40681 +* the TLAN lists to their initial values.
40683 +**************************************************************/
40685 -static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
40686 +void TLan_ResetLists(struct nic *nic __unused)
40688 - u8 place;
40689 - u16 sio;
40691 - outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
40692 - sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
40693 - *data = 0;
40694 + int i;
40695 + struct TLanList *list;
40696 + priv->txHead = 0;
40697 + priv->txTail = 0;
40699 - /* Assume clock is low, tx is enabled; */
40700 - TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
40701 - for ( place = 0x80; place; place >>= 1 ) {
40702 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40703 - if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) )
40704 - *data |= place;
40705 - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
40706 + for (i = 0; i < TLAN_NUM_TX_LISTS; i++) {
40707 + list = &tx_ring[i];
40708 + list->cStat = TLAN_CSTAT_UNUSED;
40709 +/* list->buffer[0].address = 0; */
40710 + list->buffer[0].address = virt_to_bus(txb +
40711 + (i * TLAN_MAX_FRAME_SIZE));
40712 + list->buffer[2].count = 0;
40713 + list->buffer[2].address = 0;
40714 + list->buffer[9].address = 0;
40715 +/* list->forward = 0; */
40718 - TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
40719 - if ( ! stop ) {
40720 - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* Ack = 0 */
40721 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40722 - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
40723 - } else {
40724 - TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); /* No ack = 1 (?) */
40725 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40726 - TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
40727 - TLan_ClearBit( TLAN_NET_SIO_EDATA, sio ); /* STOP, raise data while clock is high */
40728 - TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
40729 - TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
40731 + priv->cur_rx = 0;
40732 + priv->rx_buf_sz = (TLAN_MAX_FRAME_SIZE);
40733 + priv->rx_head_desc = &rx_ring[0];
40735 + /* Initialize all the Rx descriptors */
40736 + for (i = 0; i < TLAN_NUM_RX_LISTS; i++) {
40737 + rx_ring[i].forward = virt_to_le32desc(&rx_ring[i + 1]);
40738 + rx_ring[i].cStat = TLAN_CSTAT_READY;
40739 + rx_ring[i].frameSize = TLAN_MAX_FRAME_SIZE;
40740 + rx_ring[i].buffer[0].count =
40741 + TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
40742 + rx_ring[i].buffer[0].address =
40743 + virt_to_le32desc(&rxb[i * TLAN_MAX_FRAME_SIZE]);
40744 + rx_ring[i].buffer[1].count = 0;
40745 + rx_ring[i].buffer[1].address = 0;
40748 + /* Mark the last entry as wrapping the ring */
40749 + rx_ring[i - 1].forward = virt_to_le32desc(&rx_ring[0]);
40750 + priv->dirty_rx = (unsigned int) (i - TLAN_NUM_RX_LISTS);
40752 -} /* TLan_EeReceiveByte */
40753 +} /* TLan_ResetLists */
40755 - /***************************************************************
40756 - * TLan_EeReadByte
40758 - * Returns:
40759 - * No error = 0, else, the stage at which the error
40760 - * occurred.
40761 - * Parms:
40762 - * io_base The IO port base address for the
40763 - * TLAN device with the EEPROM to
40764 - * use.
40765 - * ee_addr The address of the byte in the
40766 - * EEPROM whose contents are to be
40767 - * retrieved.
40768 - * data An address to a char to hold the
40769 - * data obtained from the EEPROM.
40771 - * This function reads a byte of information from an byte
40772 - * cell in the EEPROM.
40774 - **************************************************************/
40775 +/***************************************************************
40776 +* TLan_Reset
40778 +* Returns:
40779 +* 0
40780 +* Parms:
40781 +* dev Pointer to device structure of adapter
40782 +* to be reset.
40784 +* This function resets the adapter and it's physical
40785 +* device. See Chap. 3, pp. 9-10 of the "ThunderLAN
40786 +* Programmer's Guide" for details. The routine tries to
40787 +* implement what is detailed there, though adjustments
40788 +* have been made.
40790 +**************************************************************/
40792 -static int TLan_EeReadByte( u16 io_base, u8 ee_addr, u8 *data )
40793 +void TLan_ResetAdapter(struct nic *nic __unused)
40795 - int err;
40796 - unsigned long flags = 0;
40797 - int ret=0;
40798 + int i;
40799 + u32 addr;
40800 + u32 data;
40801 + u8 data8;
40803 - TLan_EeSendStart( io_base );
40804 - err = TLan_EeSendByte( io_base, 0xA0, TLAN_EEPROM_ACK );
40805 - if (err)
40807 - ret=1;
40808 - goto fail;
40810 - err = TLan_EeSendByte( io_base, ee_addr, TLAN_EEPROM_ACK );
40811 - if (err)
40813 - ret=2;
40814 - goto fail;
40816 - TLan_EeSendStart( io_base );
40817 - err = TLan_EeSendByte( io_base, 0xA1, TLAN_EEPROM_ACK );
40818 - if (err)
40820 - ret=3;
40821 - goto fail;
40823 - TLan_EeReceiveByte( io_base, data, TLAN_EEPROM_STOP );
40824 -fail:
40825 + priv->tlanFullDuplex = FALSE;
40826 + priv->phyOnline = 0;
40827 +/* 1. Assert reset bit. */
40829 - return ret;
40830 + data = inl(BASE + TLAN_HOST_CMD);
40831 + data |= TLAN_HC_AD_RST;
40832 + outl(data, BASE + TLAN_HOST_CMD);
40834 -} /* TLan_EeReadByte */
40835 + udelay(1000);
40837 -#if 0
40838 -/* Not yet converted from Linux driver */
40839 -/*****************************************************************************
40840 -******************************************************************************
40841 +/* 2. Turn off interrupts. ( Probably isn't necessary ) */
40843 - ThunderLAN Driver PHY Layer Routines
40844 + data = inl(BASE + TLAN_HOST_CMD);
40845 + data |= TLAN_HC_INT_OFF;
40846 + outl(data, BASE + TLAN_HOST_CMD);
40847 +/* 3. Clear AREGs and HASHs. */
40849 -******************************************************************************
40850 -*****************************************************************************/
40851 + for (i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4) {
40852 + TLan_DioWrite32(BASE, (u16) i, 0);
40855 - /*********************************************************************
40856 - * TLan_PhyPrint
40858 - * Returns:
40859 - * Nothing
40860 - * Parms:
40861 - * dev A pointer to the device structure of the
40862 - * TLAN device having the PHYs to be detailed.
40863 - *
40864 - * This function prints the registers a PHY (aka tranceiver).
40866 - ********************************************************************/
40867 +/* 4. Setup NetConfig register. */
40869 -void TLan_PhyPrint( struct net_device *dev )
40871 - TLanPrivateInfo *priv = dev->priv;
40872 - u16 i, data0, data1, data2, data3, phy;
40873 + data =
40874 + TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
40875 + TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data);
40877 - phy = priv->phy[priv->phyNum];
40878 +/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
40880 - if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
40881 - printk( "TLAN: Device %s, Unmanaged PHY.\n", dev->name );
40882 - } else if ( phy <= TLAN_PHY_MAX_ADDR ) {
40883 - printk( "TLAN: Device %s, PHY 0x%02x.\n", dev->name, phy );
40884 - printk( "TLAN: Off. +0 +1 +2 +3 \n" );
40885 - for ( i = 0; i < 0x20; i+= 4 ) {
40886 - printk( "TLAN: 0x%02x", i );
40887 - TLan_MiiReadReg( dev, phy, i, &data0 );
40888 - printk( " 0x%04hx", data0 );
40889 - TLan_MiiReadReg( dev, phy, i + 1, &data1 );
40890 - printk( " 0x%04hx", data1 );
40891 - TLan_MiiReadReg( dev, phy, i + 2, &data2 );
40892 - printk( " 0x%04hx", data2 );
40893 - TLan_MiiReadReg( dev, phy, i + 3, &data3 );
40894 - printk( " 0x%04hx\n", data3 );
40896 - } else {
40897 - printk( "TLAN: Device %s, Invalid PHY.\n", dev->name );
40899 + outl(TLAN_HC_LD_TMR | 0x3f, BASE + TLAN_HOST_CMD);
40900 + outl(TLAN_HC_LD_THR | 0x0, BASE + TLAN_HOST_CMD);
40902 -} /* TLan_PhyPrint */
40903 +/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
40905 - /*********************************************************************
40906 - * TLan_PhyDetect
40908 - * Returns:
40909 - * Nothing
40910 - * Parms:
40911 - * dev A pointer to the device structure of the adapter
40912 - * for which the PHY needs determined.
40914 - * So far I've found that adapters which have external PHYs
40915 - * may also use the internal PHY for part of the functionality.
40916 - * (eg, AUI/Thinnet). This function finds out if this TLAN
40917 - * chip has an internal PHY, and then finds the first external
40918 - * PHY (starting from address 0) if it exists).
40920 - ********************************************************************/
40921 + outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
40922 + addr = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
40923 + TLan_SetBit(TLAN_NET_SIO_NMRST, addr);
40925 -void TLan_PhyDetect( struct net_device *dev )
40927 - TLanPrivateInfo *priv = dev->priv;
40928 - u16 control;
40929 - u16 hi;
40930 - u16 lo;
40931 - u32 phy;
40932 +/* 7. Setup the remaining registers. */
40934 - if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
40935 - priv->phyNum = 0xFFFF;
40936 - return;
40937 + if (priv->tlanRev >= 0x30) {
40938 + data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
40939 + TLan_DioWrite8(BASE, TLAN_INT_DIS, data8);
40941 + TLan_PhyDetect(nic);
40942 + data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
40944 - TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi );
40946 - if ( hi != 0xFFFF ) {
40947 - priv->phy[0] = TLAN_PHY_MAX_ADDR;
40948 - } else {
40949 - priv->phy[0] = TLAN_PHY_NONE;
40950 + if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_BIT_RATE_PHY) {
40951 + data |= TLAN_NET_CFG_BIT;
40952 + if (priv->aui == 1) {
40953 + TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x0a);
40954 + } else if (priv->duplex == TLAN_DUPLEX_FULL) {
40955 + TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x00);
40956 + priv->tlanFullDuplex = TRUE;
40957 + } else {
40958 + TLan_DioWrite8(BASE, TLAN_ACOMMIT, 0x08);
40962 - priv->phy[1] = TLAN_PHY_NONE;
40963 - for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) {
40964 - TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
40965 - TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
40966 - TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
40967 - if ( ( control != 0xFFFF ) || ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
40968 - TLAN_DBG( TLAN_DEBUG_GNRL, "PHY found at %02x %04x %04x %04x\n", phy, control, hi, lo );
40969 - if ( ( priv->phy[1] == TLAN_PHY_NONE ) && ( phy != TLAN_PHY_MAX_ADDR ) ) {
40970 - priv->phy[1] = phy;
40973 + if (priv->phyNum == 0) {
40974 + data |= TLAN_NET_CFG_PHY_EN;
40976 + TLan_DioWrite16(BASE, TLAN_NET_CONFIG, (u16) data);
40978 - if ( priv->phy[1] != TLAN_PHY_NONE ) {
40979 - priv->phyNum = 1;
40980 - } else if ( priv->phy[0] != TLAN_PHY_NONE ) {
40981 - priv->phyNum = 0;
40982 + if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) {
40983 + TLan_FinishReset(nic);
40984 } else {
40985 - printk( "TLAN: Cannot initialize device, no PHY was found!\n" );
40986 + TLan_PhyPowerDown(nic);
40989 -} /* TLan_PhyDetect */
40990 +} /* TLan_ResetAdapter */
40992 -void TLan_PhyPowerDown( struct net_device *dev )
40993 +void TLan_FinishReset(struct nic *nic)
40995 - TLanPrivateInfo *priv = dev->priv;
40996 - u16 value;
40998 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
40999 - value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
41000 - TLan_MiiSync( dev->base_addr );
41001 - TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
41002 - if ( ( priv->phyNum == 0 ) && ( priv->phy[1] != TLAN_PHY_NONE ) && ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
41003 - TLan_MiiSync( dev->base_addr );
41004 - TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
41005 + u8 data;
41006 + u32 phy;
41007 + u8 sio;
41008 + u16 status;
41009 + u16 partner;
41010 + u16 tlphy_ctl;
41011 + u16 tlphy_par;
41012 + u16 tlphy_id1, tlphy_id2;
41013 + int i;
41015 + phy = priv->phy[priv->phyNum];
41017 + data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
41018 + if (priv->tlanFullDuplex) {
41019 + data |= TLAN_NET_CMD_DUPLEX;
41021 + TLan_DioWrite8(BASE, TLAN_NET_CMD, data);
41022 + data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
41023 + if (priv->phyNum == 0) {
41024 + data |= TLAN_NET_MASK_MASK7;
41026 + TLan_DioWrite8(BASE, TLAN_NET_MASK, data);
41027 + TLan_DioWrite16(BASE, TLAN_MAX_RX, ((1536) + 7) & ~7);
41028 + TLan_MiiReadReg(nic, phy, MII_GEN_ID_HI, &tlphy_id1);
41029 + TLan_MiiReadReg(nic, phy, MII_GEN_ID_LO, &tlphy_id2);
41031 - /* Wait for 50 ms and powerup
41032 - * This is abitrary. It is intended to make sure the
41033 - * tranceiver settles.
41034 - */
41035 - TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
41036 + if ((tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY)
41037 + || (priv->aui)) {
41038 + status = MII_GS_LINK;
41039 + printf("TLAN: %s: Link forced.\n", priv->nic_name);
41040 + } else {
41041 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &status);
41042 + udelay(1000);
41043 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &status);
41044 + if ((status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */
41045 + (tlphy_id1 == NAT_SEM_ID1)
41046 + && (tlphy_id2 == NAT_SEM_ID2)) {
41047 + TLan_MiiReadReg(nic, phy, MII_AN_LPA, &partner);
41048 + TLan_MiiReadReg(nic, phy, TLAN_TLPHY_PAR,
41049 + &tlphy_par);
41051 -} /* TLan_PhyPowerDown */
41052 + printf("TLAN: %s: Link active with ",
41053 + priv->nic_name);
41054 + if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
41055 + printf("forced 10%sMbps %s-Duplex\n",
41056 + tlphy_par & TLAN_PHY_SPEED_100 ? ""
41057 + : "0",
41058 + tlphy_par & TLAN_PHY_DUPLEX_FULL ?
41059 + "Full" : "Half");
41060 + } else {
41061 + printf
41062 + ("AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
41063 + tlphy_par & TLAN_PHY_SPEED_100 ? "" :
41064 + "0",
41065 + tlphy_par & TLAN_PHY_DUPLEX_FULL ?
41066 + "Full" : "Half");
41067 + printf("TLAN: Partner capability: ");
41068 + for (i = 5; i <= 10; i++)
41069 + if (partner & (1 << i))
41070 + printf("%s", media[i - 5]);
41071 + printf("\n");
41074 -void TLan_PhyPowerUp( struct net_device *dev )
41076 - TLanPrivateInfo *priv = dev->priv;
41077 - u16 value;
41078 + TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK);
41079 +#ifdef MONITOR
41080 + /* We have link beat..for now anyway */
41081 + priv->link = 1;
41082 + /*Enabling link beat monitoring */
41083 + /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_LINK_BEAT ); */
41084 + mdelay(10000);
41085 + TLan_PhyMonitor(nic);
41086 +#endif
41087 + } else if (status & MII_GS_LINK) {
41088 + printf("TLAN: %s: Link active\n", priv->nic_name);
41089 + TLan_DioWrite8(BASE, TLAN_LED_REG, TLAN_LED_LINK);
41093 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
41094 - TLan_MiiSync( dev->base_addr );
41095 - value = MII_GC_LOOPBK;
41096 - TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
41097 - TLan_MiiSync(dev->base_addr);
41098 - /* Wait for 500 ms and reset the
41099 - * tranceiver. The TLAN docs say both 50 ms and
41100 - * 500 ms, so do the longer, just in case.
41101 - */
41102 - TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
41103 + if (priv->phyNum == 0) {
41104 + TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tlphy_ctl);
41105 + tlphy_ctl |= TLAN_TC_INTEN;
41106 + TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tlphy_ctl);
41107 + sio = TLan_DioRead8(BASE, TLAN_NET_SIO);
41108 + sio |= TLAN_NET_SIO_MINTEN;
41109 + TLan_DioWrite8(BASE, TLAN_NET_SIO, sio);
41112 -} /* TLan_PhyPowerUp */
41113 + if (status & MII_GS_LINK) {
41114 + TLan_SetMac(nic, 0, nic->node_addr);
41115 + priv->phyOnline = 1;
41116 + outb((TLAN_HC_INT_ON >> 8), BASE + TLAN_HOST_CMD + 1);
41117 +/* if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
41118 + outb( ( TLAN_HC_REQ_INT >> 8 ), BASE + TLAN_HOST_CMD + 1 );
41121 -void TLan_PhyReset( struct net_device *dev )
41123 - TLanPrivateInfo *priv = dev->priv;
41124 - u16 phy;
41125 - u16 value;
41126 + */
41127 + outl(virt_to_bus(&rx_ring), BASE + TLAN_CH_PARM);
41128 + outl(TLAN_HC_GO | TLAN_HC_RT, BASE + TLAN_HOST_CMD);
41129 + } else {
41130 + printf
41131 + ("TLAN: %s: Link inactive, will retry in 10 secs...\n",
41132 + priv->nic_name);
41133 + /* TLan_SetTimer( nic, (10*HZ), TLAN_TIMER_FINISH_RESET ); */
41134 + mdelay(10000);
41135 + TLan_FinishReset(nic);
41136 + return;
41138 - phy = priv->phy[priv->phyNum];
41141 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name );
41142 - TLan_MiiSync( dev->base_addr );
41143 - value = MII_GC_LOOPBK | MII_GC_RESET;
41144 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value );
41145 - TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
41146 - while ( value & MII_GC_RESET ) {
41147 - TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
41150 - /* Wait for 500 ms and initialize.
41151 - * I don't remember why I wait this long.
41152 - * I've changed this to 50ms, as it seems long enough.
41153 - */
41154 - TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK );
41156 -} /* TLan_PhyReset */
41158 -void TLan_PhyStartLink( struct net_device *dev )
41160 - TLanPrivateInfo *priv = dev->priv;
41161 - u16 ability;
41162 - u16 control;
41163 - u16 data;
41164 - u16 phy;
41165 - u16 status;
41166 - u16 tctl;
41168 - phy = priv->phy[priv->phyNum];
41169 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name );
41170 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
41171 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
41173 - if ( ( status & MII_GS_AUTONEG ) &&
41174 - ( ! priv->aui ) ) {
41175 - ability = status >> 11;
41176 - if ( priv->speed == TLAN_SPEED_10 &&
41177 - priv->duplex == TLAN_DUPLEX_HALF) {
41178 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
41179 - } else if ( priv->speed == TLAN_SPEED_10 &&
41180 - priv->duplex == TLAN_DUPLEX_FULL) {
41181 - priv->tlanFullDuplex = TRUE;
41182 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
41183 - } else if ( priv->speed == TLAN_SPEED_100 &&
41184 - priv->duplex == TLAN_DUPLEX_HALF) {
41185 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
41186 - } else if ( priv->speed == TLAN_SPEED_100 &&
41187 - priv->duplex == TLAN_DUPLEX_FULL) {
41188 - priv->tlanFullDuplex = TRUE;
41189 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
41190 - } else {
41192 - /* Set Auto-Neg advertisement */
41193 - TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1);
41194 - /* Enablee Auto-Neg */
41195 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
41196 - /* Restart Auto-Neg */
41197 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
41198 - /* Wait for 4 sec for autonegotiation
41199 - * to complete. The max spec time is less than this
41200 - * but the card need additional time to start AN.
41201 - * .5 sec should be plenty extra.
41202 - */
41203 - printk( "TLAN: %s: Starting autonegotiation.\n", dev->name );
41204 - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN );
41205 - return;
41208 - }
41210 - if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
41211 - priv->phyNum = 0;
41212 - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
41213 - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
41214 - TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
41215 - return;
41216 - } else if ( priv->phyNum == 0 ) {
41217 - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
41218 - if ( priv->aui ) {
41219 - tctl |= TLAN_TC_AUISEL;
41220 - } else {
41221 - tctl &= ~TLAN_TC_AUISEL;
41222 - control = 0;
41223 - if ( priv->duplex == TLAN_DUPLEX_FULL ) {
41224 - control |= MII_GC_DUPLEX;
41225 - priv->tlanFullDuplex = TRUE;
41227 - if ( priv->speed == TLAN_SPEED_100 ) {
41228 - control |= MII_GC_SPEEDSEL;
41230 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
41232 - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
41235 - /* Wait for 2 sec to give the tranceiver time
41236 - * to establish link.
41237 - */
41238 - TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
41240 -} /* TLan_PhyStartLink */
41242 -void TLan_PhyFinishAutoNeg( struct net_device *dev )
41244 - TLanPrivateInfo *priv = dev->priv;
41245 - u16 an_adv;
41246 - u16 an_lpa;
41247 - u16 data;
41248 - u16 mode;
41249 - u16 phy;
41250 - u16 status;
41252 - phy = priv->phy[priv->phyNum];
41254 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
41255 - udelay( 1000 );
41256 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
41258 - if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
41259 - /* Wait for 8 sec to give the process
41260 - * more time. Perhaps we should fail after a while.
41261 - */
41262 - if (!priv->neg_be_verbose++) {
41263 - printk(KERN_INFO "TLAN: Giving autonegotiation more time.\n");
41264 - printk(KERN_INFO "TLAN: Please check that your adapter has\n");
41265 - printk(KERN_INFO "TLAN: been properly connected to a HUB or Switch.\n");
41266 - printk(KERN_INFO "TLAN: Trying to establish link in the background...\n");
41268 - TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
41269 - return;
41272 - printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );
41273 - TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
41274 - TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
41275 - mode = an_adv & an_lpa & 0x03E0;
41276 - if ( mode & 0x0100 ) {
41277 - priv->tlanFullDuplex = TRUE;
41278 - } else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
41279 - priv->tlanFullDuplex = TRUE;
41282 - if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
41283 - priv->phyNum = 0;
41284 - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
41285 - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
41286 - TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
41287 - return;
41290 - if ( priv->phyNum == 0 ) {
41291 - if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
41292 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
41293 - printk( "TLAN: Starting internal PHY with FULL-DUPLEX\n" );
41294 - } else {
41295 - TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
41296 - printk( "TLAN: Starting internal PHY with HALF-DUPLEX\n" );
41300 - /* Wait for 100 ms. No reason in partiticular.
41301 - */
41302 - TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );
41304 -} /* TLan_PhyFinishAutoNeg */
41306 -#ifdef MONITOR
41308 - /*********************************************************************
41310 - * TLan_phyMonitor
41312 - * Returns:
41313 - * None
41315 - * Params:
41316 - * dev The device structure of this device.
41318 - *
41319 - * This function monitors PHY condition by reading the status
41320 - * register via the MII bus. This can be used to give info
41321 - * about link changes (up/down), and possible switch to alternate
41322 - * media.
41324 - * ******************************************************************/
41326 -void TLan_PhyMonitor( struct net_device *dev )
41328 - TLanPrivateInfo *priv = dev->priv;
41329 - u16 phy;
41330 - u16 phy_status;
41332 - phy = priv->phy[priv->phyNum];
41334 - /* Get PHY status register */
41335 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );
41337 - /* Check if link has been lost */
41338 - if (!(phy_status & MII_GS_LINK)) {
41339 - if (priv->link) {
41340 - priv->link = 0;
41341 - printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
41342 - dev->flags &= ~IFF_RUNNING;
41343 - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
41344 - return;
41348 - /* Link restablished? */
41349 - if ((phy_status & MII_GS_LINK) && !priv->link) {
41350 - priv->link = 1;
41351 - printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
41352 - dev->flags |= IFF_RUNNING;
41355 - /* Setup a new monitor */
41356 - TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
41359 -#endif /* MONITOR */
41361 -/*****************************************************************************
41362 -******************************************************************************
41364 - ThunderLAN Driver MII Routines
41366 - These routines are based on the information in Chap. 2 of the
41367 - "ThunderLAN Programmer's Guide", pp. 15-24.
41369 -******************************************************************************
41370 -*****************************************************************************/
41372 - /***************************************************************
41373 - * TLan_MiiReadReg
41375 - * Returns:
41376 - * 0 if ack received ok
41377 - * 1 otherwise.
41379 - * Parms:
41380 - * dev The device structure containing
41381 - * The io address and interrupt count
41382 - * for this device.
41383 - * phy The address of the PHY to be queried.
41384 - * reg The register whose contents are to be
41385 - * retreived.
41386 - * val A pointer to a variable to store the
41387 - * retrieved value.
41389 - * This function uses the TLAN's MII bus to retreive the contents
41390 - * of a given register on a PHY. It sends the appropriate info
41391 - * and then reads the 16-bit register value from the MII bus via
41392 - * the TLAN SIO register.
41394 - **************************************************************/
41396 -int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
41398 - u8 nack;
41399 - u16 sio, tmp;
41400 - u32 i;
41401 - int err;
41402 - int minten;
41403 - TLanPrivateInfo *priv = dev->priv;
41404 - unsigned long flags = 0;
41406 - err = FALSE;
41407 - outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
41408 - sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
41410 - if (!in_irq())
41411 - spin_lock_irqsave(&priv->lock, flags);
41413 - TLan_MiiSync(dev->base_addr);
41415 - minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
41416 - if ( minten )
41417 - TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
41419 - TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
41420 - TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Read ( 10b ) */
41421 - TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
41422 - TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
41424 - TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */
41426 - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */
41427 - TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
41428 - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */
41430 - nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */
41431 - TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */
41432 - if (nack) { /* No ACK, so fake it */
41433 - for (i = 0; i < 16; i++) {
41434 - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
41435 - TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
41437 - tmp = 0xffff;
41438 - err = TRUE;
41439 - } else { /* ACK, so read data */
41440 - for (tmp = 0, i = 0x8000; i; i >>= 1) {
41441 - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
41442 - if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
41443 - tmp |= i;
41444 - TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
41448 - TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */
41449 - TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
41451 - if ( minten )
41452 - TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
41454 - *val = tmp;
41456 - if (!in_irq())
41457 - spin_unlock_irqrestore(&priv->lock, flags);
41459 - return err;
41461 -} /* TLan_MiiReadReg */
41463 - /***************************************************************
41464 - * TLan_MiiSendData
41466 - * Returns:
41467 - * Nothing
41468 - * Parms:
41469 - * base_port The base IO port of the adapter in
41470 - * question.
41471 - * dev The address of the PHY to be queried.
41472 - * data The value to be placed on the MII bus.
41473 - * num_bits The number of bits in data that are to
41474 - * be placed on the MII bus.
41476 - * This function sends on sequence of bits on the MII
41477 - * configuration bus.
41479 - **************************************************************/
41481 -void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
41483 - u16 sio;
41484 - u32 i;
41486 - if ( num_bits == 0 )
41487 - return;
41489 - outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
41490 - sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
41491 - TLan_SetBit( TLAN_NET_SIO_MTXEN, sio );
41493 - for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {
41494 - TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
41495 - (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
41496 - if ( data & i )
41497 - TLan_SetBit( TLAN_NET_SIO_MDATA, sio );
41498 - else
41499 - TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );
41500 - TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
41501 - (void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
41504 -} /* TLan_MiiSendData */
41506 - /***************************************************************
41507 - * TLan_MiiSync
41509 - * Returns:
41510 - * Nothing
41511 - * Parms:
41512 - * base_port The base IO port of the adapter in
41513 - * question.
41515 - * This functions syncs all PHYs in terms of the MII configuration
41516 - * bus.
41518 - **************************************************************/
41520 -void TLan_MiiSync( u16 base_port )
41522 - int i;
41523 - u16 sio;
41525 - outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
41526 - sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
41528 - TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio );
41529 - for ( i = 0; i < 32; i++ ) {
41530 - TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
41531 - TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
41534 -} /* TLan_MiiSync */
41536 - /***************************************************************
41537 - * TLan_MiiWriteReg
41539 - * Returns:
41540 - * Nothing
41541 - * Parms:
41542 - * dev The device structure for the device
41543 - * to write to.
41544 - * phy The address of the PHY to be written to.
41545 - * reg The register whose contents are to be
41546 - * written.
41547 - * val The value to be written to the register.
41549 - * This function uses the TLAN's MII bus to write the contents of a
41550 - * given register on a PHY. It sends the appropriate info and then
41551 - * writes the 16-bit register value from the MII configuration bus
41552 - * via the TLAN SIO register.
41554 - **************************************************************/
41556 -void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
41558 - u16 sio;
41559 - int minten;
41560 - unsigned long flags = 0;
41561 - TLanPrivateInfo *priv = dev->priv;
41563 - outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
41564 - sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
41566 - if (!in_irq())
41567 - spin_lock_irqsave(&priv->lock, flags);
41569 - TLan_MiiSync( dev->base_addr );
41571 - minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
41572 - if ( minten )
41573 - TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio );
41575 - TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Start ( 01b ) */
41576 - TLan_MiiSendData( dev->base_addr, 0x1, 2 ); /* Write ( 01b ) */
41577 - TLan_MiiSendData( dev->base_addr, phy, 5 ); /* Device # */
41578 - TLan_MiiSendData( dev->base_addr, reg, 5 ); /* Register # */
41580 - TLan_MiiSendData( dev->base_addr, 0x2, 2 ); /* Send ACK */
41581 - TLan_MiiSendData( dev->base_addr, val, 16 ); /* Send Data */
41583 - TLan_ClearBit( TLAN_NET_SIO_MCLK, sio ); /* Idle cycle */
41584 - TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
41586 - if ( minten )
41587 - TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
41589 - if (!in_irq())
41590 - spin_unlock_irqrestore(&priv->lock, flags);
41592 -} /* TLan_MiiWriteReg */
41593 -#endif
41595 -/**************************************************************************
41596 -RESET - Reset adapter
41597 -***************************************************************************/
41598 -static void skel_reset(struct nic *nic)
41600 - /* put the card in its initial state */
41603 -/**************************************************************************
41604 -POLL - Wait for a frame
41605 -***************************************************************************/
41606 -static int skel_poll(struct nic *nic)
41608 - /* return true if there's an ethernet packet ready to read */
41609 - /* nic->packet should contain data on return */
41610 - /* nic->packetlen should contain length of data */
41611 - return (0); /* initially as this is called to flush the input */
41614 -/**************************************************************************
41615 -TRANSMIT - Transmit a frame
41616 -***************************************************************************/
41617 -static void skel_transmit(
41618 - struct nic *nic,
41619 - const char *d, /* Destination */
41620 - unsigned int t, /* Type */
41621 - unsigned int s, /* size */
41622 - const char *p) /* Packet */
41624 - /* send the packet to destination */
41627 -/**************************************************************************
41628 -DISABLE - Turn off ethernet interface
41629 -***************************************************************************/
41630 -static void skel_disable(struct nic *nic)
41634 -/**************************************************************************
41635 -PROBE - Look for an adapter, this routine's visible to the outside
41636 -You should omit the last argument struct pci_device * for a non-PCI NIC
41637 -***************************************************************************/
41638 -struct nic *tlan_probe(struct nic *nic, unsigned short *probe_addrs,
41639 - struct pci_device *p)
41641 - /* if probe_addrs is 0, then routine can use a hardwired default */
41642 - /* if board found */
41644 - /* point to NIC specific routines */
41645 - nic->reset = skel_reset;
41646 - nic->poll = skel_poll;
41647 - nic->transmit = skel_transmit;
41648 - nic->disable = skel_disable;
41649 - return nic;
41651 - /* else */
41652 - return 0;
41655 -#if 0
41656 -#ifndef TLAN_H
41657 -#define TLAN_H
41658 -/********************************************************************
41660 - * Linux ThunderLAN Driver
41662 - * tlan.h
41663 - * by James Banks
41665 - * (C) 1997-1998 Caldera, Inc.
41666 - * (C) 1999-2001 Torben Mathiasen
41667 - *
41668 - * This software may be used and distributed according to the terms
41669 - * of the GNU General Public License, incorporated herein by reference.
41671 - ** This file is best viewed/edited with tabstop=4, colums>=132
41673 - *
41674 - * Dec 10, 1999 Torben Mathiasen <torben.mathiasen@compaq.com>
41675 - * New Maintainer
41677 - ********************************************************************/
41679 -#include <asm/io.h>
41680 -#include <asm/types.h>
41681 -#include <linux/netdevice.h>
41683 -#define FALSE 0
41684 -#define TRUE 1
41686 -#define TX_TIMEOUT (10*HZ) /* We need time for auto-neg */
41688 -typedef struct tlan_adapter_entry {
41689 - u16 vendorId;
41690 - u16 deviceId;
41691 - char *deviceLabel;
41692 - u32 flags;
41693 - u16 addrOfs;
41694 -} TLanAdapterEntry;
41696 - /*****************************************************************
41697 - * EISA Definitions
41699 - ****************************************************************/
41701 -#define EISA_ID 0xc80 /* EISA ID Registers */
41702 -#define EISA_ID0 0xc80 /* EISA ID Register 0 */
41703 -#define EISA_ID1 0xc81 /* EISA ID Register 1 */
41704 -#define EISA_ID2 0xc82 /* EISA ID Register 2 */
41705 -#define EISA_ID3 0xc83 /* EISA ID Register 3 */
41706 -#define EISA_CR 0xc84 /* EISA Control Register */
41707 -#define EISA_REG0 0xc88 /* EISA Configuration Register 0 */
41708 -#define EISA_REG1 0xc89 /* EISA Configuration Register 1 */
41709 -#define EISA_REG2 0xc8a /* EISA Configuration Register 2 */
41710 -#define EISA_REG3 0xc8f /* EISA Configuration Register 3 */
41711 -#define EISA_APROM 0xc90 /* Ethernet Address PROM */
41713 - /*****************************************************************
41714 - * Rx/Tx List Definitions
41716 - ****************************************************************/
41718 -typedef struct tlan_buffer_ref_tag {
41719 - u32 count;
41720 - u32 address;
41721 -} TLanBufferRef;
41723 -typedef struct tlan_list_tag {
41724 - u32 forward;
41725 - u16 cStat;
41726 - u16 frameSize;
41727 - TLanBufferRef buffer[TLAN_BUFFERS_PER_LIST];
41728 -} TLanList;
41730 -typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE];
41732 - /*****************************************************************
41733 - * TLAN Private Information Structure
41735 - ****************************************************************/
41737 -typedef struct tlan_private_tag {
41738 - struct net_device *nextDevice;
41739 - void *dmaStorage;
41740 - u8 *padBuffer;
41741 - TLanList *rxList;
41742 - u8 *rxBuffer;
41743 - u32 rxHead;
41744 - u32 rxTail;
41745 - u32 rxEocCount;
41746 - TLanList *txList;
41747 - u8 *txBuffer;
41748 - u32 txHead;
41749 - u32 txInProgress;
41750 - u32 txTail;
41751 - u32 txBusyCount;
41752 - u32 phyOnline;
41753 - u32 timerSetAt;
41754 - u32 timerType;
41755 - struct timer_list timer;
41756 - struct net_device_stats stats;
41757 - struct board *adapter;
41758 - u32 adapterRev;
41759 - u32 aui;
41760 - u32 debug;
41761 - u32 duplex;
41762 - u32 phy[2];
41763 - u32 phyNum;
41764 - u32 speed;
41765 - u8 tlanRev;
41766 - u8 tlanFullDuplex;
41767 - char devName[8];
41768 - spinlock_t lock;
41769 - u8 link;
41770 - u8 is_eisa;
41771 - struct tq_struct tlan_tqueue;
41772 - u8 neg_be_verbose;
41773 -} TLanPrivateInfo;
41775 -#define TLAN_HC_GO 0x80000000
41776 -#define TLAN_HC_STOP 0x40000000
41777 -#define TLAN_HC_ACK 0x20000000
41778 -#define TLAN_HC_CS_MASK 0x1FE00000
41779 -#define TLAN_HC_EOC 0x00100000
41780 -#define TLAN_HC_RT 0x00080000
41781 -#define TLAN_HC_NES 0x00040000
41782 -#define TLAN_HC_AD_RST 0x00008000
41783 -#define TLAN_HC_LD_TMR 0x00004000
41784 -#define TLAN_HC_LD_THR 0x00002000
41785 -#define TLAN_HC_REQ_INT 0x00001000
41786 -#define TLAN_HC_INT_OFF 0x00000800
41787 -#define TLAN_HC_INT_ON 0x00000400
41788 -#define TLAN_HC_AC_MASK 0x000000FF
41789 -#define TLAN_DA_ADR_INC 0x8000
41790 -#define TLAN_DA_RAM_ADR 0x4000
41791 -#define TLAN_HI_IV_MASK 0x1FE0
41792 -#define TLAN_HI_IT_MASK 0x001C
41794 -#define TLAN_NET_CMD_NRESET 0x80
41795 -#define TLAN_NET_CMD_NWRAP 0x40
41796 -#define TLAN_NET_CMD_CSF 0x20
41797 -#define TLAN_NET_CMD_CAF 0x10
41798 -#define TLAN_NET_CMD_NOBRX 0x08
41799 -#define TLAN_NET_CMD_DUPLEX 0x04
41800 -#define TLAN_NET_CMD_TRFRAM 0x02
41801 -#define TLAN_NET_CMD_TXPACE 0x01
41802 -#define TLAN_NET_SIO_MINTEN 0x80
41803 -#define TLAN_NET_SIO_ECLOK 0x40
41804 -#define TLAN_NET_SIO_ETXEN 0x20
41805 -#define TLAN_NET_SIO_EDATA 0x10
41806 -#define TLAN_NET_SIO_NMRST 0x08
41807 -#define TLAN_NET_SIO_MCLK 0x04
41808 -#define TLAN_NET_SIO_MTXEN 0x02
41809 -#define TLAN_NET_SIO_MDATA 0x01
41810 -#define TLAN_NET_STS_MIRQ 0x80
41811 -#define TLAN_NET_STS_HBEAT 0x40
41812 -#define TLAN_NET_STS_TXSTOP 0x20
41813 -#define TLAN_NET_STS_RXSTOP 0x10
41814 -#define TLAN_NET_STS_RSRVD 0x0F
41815 -#define TLAN_NET_MASK_MASK7 0x80
41816 -#define TLAN_NET_MASK_MASK6 0x40
41817 -#define TLAN_NET_MASK_MASK5 0x20
41818 -#define TLAN_NET_MASK_MASK4 0x10
41819 -#define TLAN_NET_MASK_RSRVD 0x0F
41820 -#define TLAN_NET_CFG_RCLK 0x8000
41821 -#define TLAN_NET_CFG_TCLK 0x4000
41822 -#define TLAN_NET_CFG_BIT 0x2000
41823 -#define TLAN_NET_CFG_RXCRC 0x1000
41824 -#define TLAN_NET_CFG_PEF 0x0800
41825 -#define TLAN_NET_CFG_1FRAG 0x0400
41826 -#define TLAN_NET_CFG_1CHAN 0x0200
41827 -#define TLAN_NET_CFG_MTEST 0x0100
41828 -#define TLAN_NET_CFG_PHY_EN 0x0080
41829 -#define TLAN_NET_CFG_MSMASK 0x007F
41830 -#define TLAN_LED_ACT 0x10
41831 -#define TLAN_LED_LINK 0x01
41832 -#define TLAN_ID_TX_EOC 0x04
41833 -#define TLAN_ID_RX_EOF 0x02
41834 -#define TLAN_ID_RX_EOC 0x01
41836 -#define CIRC_INC( a, b ) if ( ++a >= b ) a = 0
41838 -#ifdef I_LIKE_A_FAST_HASH_FUNCTION
41839 -/* given 6 bytes, view them as 8 6-bit numbers and return the XOR of those */
41840 -/* the code below is about seven times as fast as the original code */
41841 -inline u32 TLan_HashFunc( u8 *a )
41843 - u8 hash;
41845 - hash = (a[0]^a[3]); /* & 077 */
41846 - hash ^= ((a[0]^a[3])>>6); /* & 003 */
41847 - hash ^= ((a[1]^a[4])<<2); /* & 074 */
41848 - hash ^= ((a[1]^a[4])>>4); /* & 017 */
41849 - hash ^= ((a[2]^a[5])<<4); /* & 060 */
41850 - hash ^= ((a[2]^a[5])>>2); /* & 077 */
41852 - return (hash & 077);
41855 -#else /* original code */
41857 -inline u32 xor( u32 a, u32 b )
41859 - return ( ( a && ! b ) || ( ! a && b ) );
41861 -#define XOR8( a, b, c, d, e, f, g, h ) xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) )
41862 -#define DA( a, bit ) ( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) )
41864 -inline u32 TLan_HashFunc( u8 *a )
41866 - u32 hash;
41868 - hash = XOR8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30), DA(a,36), DA(a,42) );
41869 - hash |= XOR8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31), DA(a,37), DA(a,43) ) << 1;
41870 - hash |= XOR8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32), DA(a,38), DA(a,44) ) << 2;
41871 - hash |= XOR8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33), DA(a,39), DA(a,45) ) << 3;
41872 - hash |= XOR8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34), DA(a,40), DA(a,46) ) << 4;
41873 - hash |= XOR8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35), DA(a,41), DA(a,47) ) << 5;
41875 - return hash;
41879 -#endif /* I_LIKE_A_FAST_HASH_FUNCTION */
41880 -#endif
41881 -/*******************************************************************************
41883 - * Linux ThunderLAN Driver
41885 - * tlan.c
41886 - * by James Banks
41888 - * (C) 1997-1998 Caldera, Inc.
41889 - * (C) 1998 James Banks
41890 - * (C) 1999-2001 Torben Mathiasen
41892 - * This software may be used and distributed according to the terms
41893 - * of the GNU General Public License, incorporated herein by reference.
41895 - ** This file is best viewed/edited with columns>=132.
41897 - ** Useful (if not required) reading:
41899 - * Texas Instruments, ThunderLAN Programmer's Guide,
41900 - * TI Literature Number SPWU013A
41901 - * available in PDF format from www.ti.com
41902 - * Level One, LXT901 and LXT970 Data Sheets
41903 - * available in PDF format from www.level1.com
41904 - * National Semiconductor, DP83840A Data Sheet
41905 - * available in PDF format from www.national.com
41906 - * Microchip Technology, 24C01A/02A/04A Data Sheet
41907 - * available in PDF format from www.microchip.com
41909 - * Change History
41911 - * Tigran Aivazian <tigran@sco.com>: TLan_PciProbe() now uses
41912 - * new PCI BIOS interface.
41913 - * Alan Cox <alan@redhat.com>: Fixed the out of memory
41914 - * handling.
41915 - *
41916 - * Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
41918 - * v1.1 Dec 20, 1999 - Removed linux version checking
41919 - * Patch from Tigran Aivazian.
41920 - * - v1.1 includes Alan's SMP updates.
41921 - * - We still have problems on SMP though,
41922 - * but I'm looking into that.
41923 - *
41924 - * v1.2 Jan 02, 2000 - Hopefully fixed the SMP deadlock.
41925 - * - Removed dependency of HZ being 100.
41926 - * - We now allow higher priority timers to
41927 - * overwrite timers like TLAN_TIMER_ACTIVITY
41928 - * Patch from John Cagle <john.cagle@compaq.com>.
41929 - * - Fixed a few compiler warnings.
41931 - * v1.3 Feb 04, 2000 - Fixed the remaining HZ issues.
41932 - * - Removed call to pci_present().
41933 - * - Removed SA_INTERRUPT flag from irq handler.
41934 - * - Added __init and __initdata to reduce resisdent
41935 - * code size.
41936 - * - Driver now uses module_init/module_exit.
41937 - * - Rewrote init_module and tlan_probe to
41938 - * share a lot more code. We now use tlan_probe
41939 - * with builtin and module driver.
41940 - * - Driver ported to new net API.
41941 - * - tlan.txt has been reworked to reflect current
41942 - * driver (almost)
41943 - * - Other minor stuff
41945 - * v1.4 Feb 10, 2000 - Updated with more changes required after Dave's
41946 - * network cleanup in 2.3.43pre7 (Tigran & myself)
41947 - * - Minor stuff.
41949 - * v1.5 March 22, 2000 - Fixed another timer bug that would hang the driver
41950 - * if no cable/link were present.
41951 - * - Cosmetic changes.
41952 - * - TODO: Port completely to new PCI/DMA API
41953 - * Auto-Neg fallback.
41955 - * v1.6 April 04, 2000 - Fixed driver support for kernel-parameters. Haven't
41956 - * tested it though, as the kernel support is currently
41957 - * broken (2.3.99p4p3).
41958 - * - Updated tlan.txt accordingly.
41959 - * - Adjusted minimum/maximum frame length.
41960 - * - There is now a TLAN website up at
41961 - * http://tlan.kernel.dk
41963 - * v1.7 April 07, 2000 - Started to implement custom ioctls. Driver now
41964 - * reports PHY information when used with Donald
41965 - * Beckers userspace MII diagnostics utility.
41967 - * v1.8 April 23, 2000 - Fixed support for forced speed/duplex settings.
41968 - * - Added link information to Auto-Neg and forced
41969 - * modes. When NIC operates with auto-neg the driver
41970 - * will report Link speed & duplex modes as well as
41971 - * link partner abilities. When forced link is used,
41972 - * the driver will report status of the established
41973 - * link.
41974 - * Please read tlan.txt for additional information.
41975 - * - Removed call to check_region(), and used
41976 - * return value of request_region() instead.
41977 - *
41978 - * v1.8a May 28, 2000 - Minor updates.
41980 - * v1.9 July 25, 2000 - Fixed a few remaining Full-Duplex issues.
41981 - * - Updated with timer fixes from Andrew Morton.
41982 - * - Fixed module race in TLan_Open.
41983 - * - Added routine to monitor PHY status.
41984 - * - Added activity led support for Proliant devices.
41986 - * v1.10 Aug 30, 2000 - Added support for EISA based tlan controllers
41987 - * like the Compaq NetFlex3/E.
41988 - * - Rewrote tlan_probe to better handle multiple
41989 - * bus probes. Probing and device setup is now
41990 - * done through TLan_Probe and TLan_init_one. Actual
41991 - * hardware probe is done with kernel API and
41992 - * TLan_EisaProbe.
41993 - * - Adjusted debug information for probing.
41994 - * - Fixed bug that would cause general debug information
41995 - * to be printed after driver removal.
41996 - * - Added transmit timeout handling.
41997 - * - Fixed OOM return values in tlan_probe.
41998 - * - Fixed possible mem leak in tlan_exit
41999 - * (now tlan_remove_one).
42000 - * - Fixed timer bug in TLan_phyMonitor.
42001 - * - This driver version is alpha quality, please
42002 - * send me any bug issues you may encounter.
42004 - * v1.11 Aug 31, 2000 - Do not try to register irq 0 if no irq line was
42005 - * set for EISA cards.
42006 - * - Added support for NetFlex3/E with nibble-rate
42007 - * 10Base-T PHY. This is untestet as I haven't got
42008 - * one of these cards.
42009 - * - Fixed timer being added twice.
42010 - * - Disabled PhyMonitoring by default as this is
42011 - * work in progress. Define MONITOR to enable it.
42012 - * - Now we don't display link info with PHYs that
42013 - * doesn't support it (level1).
42014 - * - Incresed tx_timeout beacuse of auto-neg.
42015 - * - Adjusted timers for forced speeds.
42017 - * v1.12 Oct 12, 2000 - Minor fixes (memleak, init, etc.)
42019 - * v1.13 Nov 28, 2000 - Stop flooding console with auto-neg issues
42020 - * when link can't be established.
42021 - * - Added the bbuf option as a kernel parameter.
42022 - * - Fixed ioaddr probe bug.
42023 - * - Fixed stupid deadlock with MII interrupts.
42024 - * - Added support for speed/duplex selection with
42025 - * multiple nics.
42026 - * - Added partly fix for TX Channel lockup with
42027 - * TLAN v1.0 silicon. This needs to be investigated
42028 - * further.
42030 - * v1.14 Dec 16, 2000 - Added support for servicing multiple frames per.
42031 - * interrupt. Thanks goes to
42032 - * Adam Keys <adam@ti.com>
42033 - * Denis Beaudoin <dbeaudoin@ti.com>
42034 - * for providing the patch.
42035 - * - Fixed auto-neg output when using multiple
42036 - * adapters.
42037 - * - Converted to use new taskq interface.
42039 - * v1.14a Jan 6, 2001 - Minor adjustments (spinlocks, etc.)
42041 - *******************************************************************************/
42044 -#include <linux/module.h>
42046 -#include "tlan.h"
42048 -#include <linux/init.h>
42049 -#include <linux/ioport.h>
42050 -#include <linux/pci.h>
42051 -#include <linux/etherdevice.h>
42052 -#include <linux/delay.h>
42053 -#include <linux/spinlock.h>
42054 -#include <linux/mii.h>
42056 -typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 );
42058 -/* For removing EISA devices */
42059 -static struct net_device *TLan_Eisa_Devices;
42061 -static int TLanDevicesInstalled;
42063 -/* Set speed, duplex and aui settings */
42064 -static int aui[MAX_TLAN_BOARDS];
42065 -static int duplex[MAX_TLAN_BOARDS];
42066 -static int speed[MAX_TLAN_BOARDS];
42067 -static int boards_found;
42069 -MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>");
42070 -MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
42071 -MODULE_LICENSE("GPL");
42073 -MODULE_PARM(aui, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
42074 -MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
42075 -MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
42076 -MODULE_PARM(debug, "i");
42077 -MODULE_PARM(bbuf, "i");
42078 -MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
42079 -MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
42080 -MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
42081 -MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
42082 -MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
42083 -EXPORT_NO_SYMBOLS;
42085 -/* Define this to enable Link beat monitoring */
42086 -#undef MONITOR
42088 -/* Turn on debugging. See linux/Documentation/networking/tlan.txt for details */
42089 -static int debug;
42091 -static int bbuf;
42092 -static u8 *TLanPadBuffer;
42093 -static char TLanSignature[] = "TLAN";
42094 -static const char tlan_banner[] = "ThunderLAN driver v1.14a\n";
42095 -static int tlan_have_pci;
42096 -static int tlan_have_eisa;
42098 -const char *media[] = {
42099 - "10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ",
42100 - "100baseTx-FD", "100baseT4", 0
42103 -int media_map[] = { 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,};
42105 -static struct board {
42106 - const char *deviceLabel;
42107 - u32 flags;
42108 - u16 addrOfs;
42109 -} board_info[] __devinitdata = {
42110 - { "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
42111 - { "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
42112 - { "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
42113 - { "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
42114 - { "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
42115 - { "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
42116 - { "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },
42117 - { "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },
42118 - { "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
42119 - { "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 },
42120 - { "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },
42121 - { "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
42122 - { "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },
42123 - { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | /* EISA card */
42124 - TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
42125 - { "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
42128 -static struct pci_device_id tlan_pci_tbl[] __devinitdata = {
42129 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
42130 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
42131 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
42132 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
42133 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
42134 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
42135 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
42136 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
42137 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
42138 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
42139 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
42140 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
42141 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
42142 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
42143 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
42144 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
42145 - { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
42146 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
42147 - { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
42148 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
42149 - { PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
42150 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
42151 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
42152 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
42153 - { PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
42154 - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
42155 - { 0,}
42157 -MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);
42159 -static void TLan_EisaProbe( void );
42160 -static void TLan_Eisa_Cleanup( void );
42161 -static int TLan_Init( struct net_device * );
42162 -static int TLan_Open( struct net_device *dev );
42163 -static int TLan_StartTx( struct sk_buff *, struct net_device *);
42164 -static void TLan_HandleInterrupt( int, void *, struct pt_regs *);
42165 -static int TLan_Close( struct net_device *);
42166 -static struct net_device_stats *TLan_GetStats( struct net_device *);
42167 -static void TLan_SetMulticastList( struct net_device *);
42168 -static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
42169 -static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
42170 -static void TLan_tx_timeout( struct net_device *dev);
42171 -static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
42173 -static u32 TLan_HandleInvalid( struct net_device *, u16 );
42174 -static u32 TLan_HandleTxEOF( struct net_device *, u16 );
42175 -static u32 TLan_HandleStatOverflow( struct net_device *, u16 );
42176 -static u32 TLan_HandleRxEOF( struct net_device *, u16 );
42177 -static u32 TLan_HandleDummy( struct net_device *, u16 );
42178 -static u32 TLan_HandleTxEOC( struct net_device *, u16 );
42179 -static u32 TLan_HandleStatusCheck( struct net_device *, u16 );
42180 -static u32 TLan_HandleRxEOC( struct net_device *, u16 );
42182 -static void TLan_Timer( unsigned long );
42184 -static void TLan_ResetLists( struct net_device * );
42185 -static void TLan_FreeLists( struct net_device * );
42186 -static void TLan_PrintDio( u16 );
42187 -static void TLan_PrintList( TLanList *, char *, int );
42188 -static void TLan_ReadAndClearStats( struct net_device *, int );
42189 -static void TLan_ResetAdapter( struct net_device * );
42190 -static void TLan_FinishReset( struct net_device * );
42191 -static void TLan_SetMac( struct net_device *, int areg, char *mac );
42193 -static void TLan_PhyPrint( struct net_device * );
42194 -static void TLan_PhyDetect( struct net_device * );
42195 -static void TLan_PhyPowerDown( struct net_device * );
42196 -static void TLan_PhyPowerUp( struct net_device * );
42197 -static void TLan_PhyReset( struct net_device * );
42198 -static void TLan_PhyStartLink( struct net_device * );
42199 -static void TLan_PhyFinishAutoNeg( struct net_device * );
42200 -#ifdef MONITOR
42201 -static void TLan_PhyMonitor( struct net_device * );
42202 -#endif
42205 -static int TLan_PhyNop( struct net_device * );
42206 -static int TLan_PhyInternalCheck( struct net_device * );
42207 -static int TLan_PhyInternalService( struct net_device * );
42208 -static int TLan_PhyDp83840aCheck( struct net_device * );
42211 -static int TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
42212 -static void TLan_MiiSendData( u16, u32, unsigned );
42213 -static void TLan_MiiSync( u16 );
42214 -static void TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
42216 -static void TLan_EeSendStart( u16 );
42217 -static int TLan_EeSendByte( u16, u8, int );
42218 -static void TLan_EeReceiveByte( u16, u8 *, int );
42219 -static int TLan_EeReadByte( struct net_device *, u8, u8 * );
42221 -static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
42222 - TLan_HandleInvalid,
42223 - TLan_HandleTxEOF,
42224 - TLan_HandleStatOverflow,
42225 - TLan_HandleRxEOF,
42226 - TLan_HandleDummy,
42227 - TLan_HandleTxEOC,
42228 - TLan_HandleStatusCheck,
42229 - TLan_HandleRxEOC
42232 -static inline void
42233 -TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
42235 - TLanPrivateInfo *priv = dev->priv;
42236 - unsigned long flags = 0;
42238 - if (!in_irq())
42239 - spin_lock_irqsave(&priv->lock, flags);
42240 - if ( priv->timer.function != NULL &&
42241 - priv->timerType != TLAN_TIMER_ACTIVITY ) {
42242 - if (!in_irq())
42243 - spin_unlock_irqrestore(&priv->lock, flags);
42244 - return;
42246 - priv->timer.function = &TLan_Timer;
42247 - if (!in_irq())
42248 - spin_unlock_irqrestore(&priv->lock, flags);
42250 - priv->timer.data = (unsigned long) dev;
42251 - priv->timerSetAt = jiffies;
42252 - priv->timerType = type;
42253 - mod_timer(&priv->timer, jiffies + ticks);
42255 -} /* TLan_SetTimer */
42257 -/*****************************************************************************
42258 -******************************************************************************
42260 - ThunderLAN Driver Primary Functions
42262 - These functions are more or less common to all Linux network drivers.
42264 -******************************************************************************
42265 -*****************************************************************************/
42267 - /***************************************************************
42268 - * tlan_remove_one
42270 - * Returns:
42271 - * Nothing
42272 - * Parms:
42273 - * None
42275 - * Goes through the TLanDevices list and frees the device
42276 - * structs and memory associated with each device (lists
42277 - * and buffers). It also ureserves the IO port regions
42278 - * associated with this device.
42280 - **************************************************************/
42282 -static void __devexit tlan_remove_one( struct pci_dev *pdev)
42284 - struct net_device *dev = pci_get_drvdata( pdev );
42285 - TLanPrivateInfo *priv = dev->priv;
42287 - unregister_netdev( dev );
42289 - if ( priv->dmaStorage ) {
42290 - kfree( priv->dmaStorage );
42293 - release_region( dev->base_addr, 0x10 );
42295 - kfree( dev );
42297 - pci_set_drvdata( pdev, NULL );
42300 -static struct pci_driver tlan_driver = {
42301 - name: "tlan",
42302 - id_table: tlan_pci_tbl,
42303 - probe: tlan_init_one,
42304 - remove: tlan_remove_one,
42307 -static int __init tlan_probe(void)
42309 - static int pad_allocated;
42311 - printk(KERN_INFO "%s", tlan_banner);
42313 - TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE,
42314 - GFP_KERNEL);
42316 - if (TLanPadBuffer == NULL) {
42317 - printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
42318 - return -ENOMEM;
42321 - memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
42322 - pad_allocated = 1;
42324 - TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
42326 - /* Use new style PCI probing. Now the kernel will
42327 - do most of this for us */
42328 - pci_register_driver(&tlan_driver);
42330 - TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
42331 - TLan_EisaProbe();
42333 - printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d EISA: %d\n",
42334 - TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",
42335 - tlan_have_pci, tlan_have_eisa);
42337 - if (TLanDevicesInstalled == 0) {
42338 - pci_unregister_driver(&tlan_driver);
42339 - kfree(TLanPadBuffer);
42340 - return -ENODEV;
42342 - return 0;
42346 -static int __devinit tlan_init_one( struct pci_dev *pdev,
42347 - const struct pci_device_id *ent)
42349 - return TLan_probe1( pdev, -1, -1, 0, ent);
42353 - ***************************************************************
42354 - * tlan_probe1
42356 - * Returns:
42357 - * 0 on success, error code on error
42358 - * Parms:
42359 - * none
42361 - * The name is lower case to fit in with all the rest of
42362 - * the netcard_probe names. This function looks for
42363 - * another TLan based adapter, setting it up with the
42364 - * allocated device struct if one is found.
42365 - * tlan_probe has been ported to the new net API and
42366 - * now allocates its own device structure. This function
42367 - * is also used by modules.
42369 - **************************************************************/
42371 -static int __devinit TLan_probe1(struct pci_dev *pdev,
42372 - long ioaddr, int irq, int rev, const struct pci_device_id *ent )
42375 - struct net_device *dev;
42376 - TLanPrivateInfo *priv;
42377 - u8 pci_rev;
42378 - u16 device_id;
42379 - int reg;
42381 - if (pdev && pci_enable_device(pdev))
42382 - return -EIO;
42384 - dev = init_etherdev(NULL, sizeof(TLanPrivateInfo));
42385 - if (dev == NULL) {
42386 - printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
42387 - return -ENOMEM;
42389 - SET_MODULE_OWNER(dev);
42391 - priv = dev->priv;
42393 - /* Is this a PCI device? */
42394 - if (pdev) {
42395 - u32 pci_io_base = 0;
42397 - priv->adapter = &board_info[ent->driver_data];
42399 - pci_read_config_byte ( pdev, PCI_REVISION_ID, &pci_rev);
42401 - for ( reg= 0; reg <= 5; reg ++ ) {
42402 - if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
42403 - pci_io_base = pci_resource_start(pdev, reg);
42404 - TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",
42405 - pci_io_base);
42406 - break;
42409 - if (!pci_io_base) {
42410 - printk(KERN_ERR "TLAN: No IO mappings available\n");
42411 - unregister_netdev(dev);
42412 - kfree(dev);
42413 - return -ENODEV;
42416 - dev->base_addr = pci_io_base;
42417 - dev->irq = pdev->irq;
42418 - priv->adapterRev = pci_rev;
42419 - pci_set_master(pdev);
42420 - pci_set_drvdata(pdev, dev);
42422 - } else { /* EISA card */
42423 - /* This is a hack. We need to know which board structure
42424 - * is suited for this adapter */
42425 - device_id = inw(ioaddr + EISA_ID2);
42426 - priv->is_eisa = 1;
42427 - if (device_id == 0x20F1) {
42428 - priv->adapter = &board_info[13]; /* NetFlex-3/E */
42429 - priv->adapterRev = 23; /* TLAN 2.3 */
42430 - } else {
42431 - priv->adapter = &board_info[14];
42432 - priv->adapterRev = 10; /* TLAN 1.0 */
42434 - dev->base_addr = ioaddr;
42435 - dev->irq = irq;
42438 - /* Kernel parameters */
42439 - if (dev->mem_start) {
42440 - priv->aui = dev->mem_start & 0x01;
42441 - priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;
42442 - priv->speed = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;
42444 - if (priv->speed == 0x1) {
42445 - priv->speed = TLAN_SPEED_10;
42446 - } else if (priv->speed == 0x2) {
42447 - priv->speed = TLAN_SPEED_100;
42449 - debug = priv->debug = dev->mem_end;
42450 - } else {
42451 - priv->aui = aui[boards_found];
42452 - priv->speed = speed[boards_found];
42453 - priv->duplex = duplex[boards_found];
42454 - priv->debug = debug;
42457 - /* This will be used when we get an adapter error from
42458 - * within our irq handler */
42459 - INIT_LIST_HEAD(&priv->tlan_tqueue.list);
42460 - priv->tlan_tqueue.sync = 0;
42461 - priv->tlan_tqueue.routine = (void *)(void*)TLan_tx_timeout;
42462 - priv->tlan_tqueue.data = dev;
42464 - spin_lock_init(&priv->lock);
42466 - if (TLan_Init(dev)) {
42467 - printk(KERN_ERR "TLAN: Could not register device.\n");
42468 - unregister_netdev(dev);
42469 - kfree(dev);
42470 - return -EAGAIN;
42471 - } else {
42473 - TLanDevicesInstalled++;
42474 - boards_found++;
42476 - /* pdev is NULL if this is an EISA device */
42477 - if (pdev)
42478 - tlan_have_pci++;
42479 - else {
42480 - priv->nextDevice = TLan_Eisa_Devices;
42481 - TLan_Eisa_Devices = dev;
42482 - tlan_have_eisa++;
42485 - printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
42486 - dev->name,
42487 - (int) dev->irq,
42488 - (int) dev->base_addr,
42489 - priv->adapter->deviceLabel,
42490 - priv->adapterRev);
42491 - return 0;
42495 +} /* TLan_FinishReset */
42497 -static void TLan_Eisa_Cleanup(void)
42499 - struct net_device *dev;
42500 - TLanPrivateInfo *priv;
42502 - while( tlan_have_eisa ) {
42503 - dev = TLan_Eisa_Devices;
42504 - priv = dev->priv;
42505 - if (priv->dmaStorage) {
42506 - kfree(priv->dmaStorage);
42508 - release_region( dev->base_addr, 0x10);
42509 - unregister_netdev( dev );
42510 - TLan_Eisa_Devices = priv->nextDevice;
42511 - kfree( dev );
42512 - tlan_have_eisa--;
42517 -static void __exit tlan_exit(void)
42519 - pci_unregister_driver(&tlan_driver);
42521 - if (tlan_have_eisa)
42522 - TLan_Eisa_Cleanup();
42524 - kfree( TLanPadBuffer );
42528 -/* Module loading/unloading */
42529 -module_init(tlan_probe);
42530 -module_exit(tlan_exit);
42532 - /**************************************************************
42533 - * TLan_EisaProbe
42535 - * Returns: 0 on success, 1 otherwise
42537 - * Parms: None
42540 - * This functions probes for EISA devices and calls
42541 - * TLan_probe1 when one is found.
42543 - *************************************************************/
42545 -static void __init TLan_EisaProbe (void)
42546 +/**************************************************************************
42547 +POLL - Wait for a frame
42548 +***************************************************************************/
42549 +static int tlan_poll(struct nic *nic, int retrieve)
42551 - long ioaddr;
42552 - int rc = -ENODEV;
42553 - int irq;
42554 - u16 device_id;
42556 - if (!EISA_bus) {
42557 - TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
42558 - return;
42561 - /* Loop through all slots of the EISA bus */
42562 - for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
42564 - TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));
42565 - TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
42566 + /* return true if there's an ethernet packet ready to read */
42567 + /* nic->packet should contain data on return */
42568 + /* nic->packetlen should contain length of data */
42569 + u32 framesize;
42570 + u32 host_cmd = 0;
42571 + u32 ack = 1;
42572 + int eoc = 0;
42573 + int entry = priv->cur_rx % TLAN_NUM_RX_LISTS;
42574 + u16 tmpCStat = le32_to_cpu(rx_ring[entry].cStat);
42575 + u16 host_int = inw(BASE + TLAN_HOST_INT);
42577 - TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
42578 - (int) ioaddr);
42579 - if (request_region(ioaddr, 0x10, TLanSignature) == NULL)
42580 - goto out;
42582 - if (inw(ioaddr + EISA_ID) != 0x110E) {
42583 - release_region(ioaddr, 0x10);
42584 - goto out;
42587 - device_id = inw(ioaddr + EISA_ID2);
42588 - if (device_id != 0x20F1 && device_id != 0x40F1) {
42589 - release_region (ioaddr, 0x10);
42590 - goto out;
42593 - if (inb(ioaddr + EISA_CR) != 0x1) { /* Check if adapter is enabled */
42594 - release_region (ioaddr, 0x10);
42595 - goto out2;
42598 - if (debug == 0x10)
42599 - printk("Found one\n");
42600 + if ((tmpCStat & TLAN_CSTAT_FRM_CMP) && !retrieve)
42601 + return 1;
42603 - /* Get irq from board */
42604 - switch (inb(ioaddr + 0xCC0)) {
42605 - case(0x10):
42606 - irq=5;
42607 - break;
42608 - case(0x20):
42609 - irq=9;
42610 - break;
42611 - case(0x40):
42612 - irq=10;
42613 - break;
42614 - case(0x80):
42615 - irq=11;
42616 - break;
42617 - default:
42618 - goto out;
42619 - }
42622 - /* Setup the newly found eisa adapter */
42623 - rc = TLan_probe1( NULL, ioaddr, irq,
42624 - 12, NULL);
42625 - continue;
42627 - out:
42628 - if (debug == 0x10)
42629 - printk("None found\n");
42630 - continue;
42632 - out2: if (debug == 0x10)
42633 - printk("Card found but it is not enabled, skipping\n");
42634 - continue;
42637 + outw(host_int, BASE + TLAN_HOST_INT);
42639 -} /* TLan_EisaProbe */
42640 + if (!(tmpCStat & TLAN_CSTAT_FRM_CMP))
42641 + return 0;
42644 + /* printf("PI-1: 0x%hX\n", host_int); */
42645 + if (tmpCStat & TLAN_CSTAT_EOC)
42646 + eoc = 1;
42648 - /***************************************************************
42649 - * TLan_Init
42651 - * Returns:
42652 - * 0 on success, error code otherwise.
42653 - * Parms:
42654 - * dev The structure of the device to be
42655 - * init'ed.
42657 - * This function completes the initialization of the
42658 - * device structure and driver. It reserves the IO
42659 - * addresses, allocates memory for the lists and bounce
42660 - * buffers, retrieves the MAC address from the eeprom
42661 - * and assignes the device's methods.
42662 - *
42663 - **************************************************************/
42664 + framesize = rx_ring[entry].frameSize;
42666 -static int TLan_Init( struct net_device *dev )
42668 - int dma_size;
42669 - int err;
42670 - int i;
42671 - TLanPrivateInfo *priv;
42672 + nic->packetlen = framesize;
42674 - priv = dev->priv;
42676 - if (!priv->is_eisa) /* EISA devices have already requested IO */
42677 - if (!request_region( dev->base_addr, 0x10, TLanSignature )) {
42678 - printk(KERN_ERR "TLAN: %s: IO port region 0x%lx size 0x%x in use.\n",
42679 - dev->name,
42680 - dev->base_addr,
42681 - 0x10 );
42682 - return -EIO;
42683 +#ifdef EBDEBUG
42684 + printf(".%d.", framesize);
42685 +#endif
42687 + memcpy(nic->packet, rxb +
42688 + (priv->cur_rx * TLAN_MAX_FRAME_SIZE), nic->packetlen);
42690 + rx_ring[entry].cStat = 0;
42691 +#ifdef EBDEBUG
42692 + //hex_dump(nic->packet, nic->packetlen);
42693 + printf("%d", entry);
42694 +#endif
42695 + entry = (entry + 1) % TLAN_NUM_RX_LISTS;
42696 + priv->cur_rx = entry;
42697 + if (eoc) {
42698 + if ((rx_ring[entry].cStat & TLAN_CSTAT_READY) ==
42699 + TLAN_CSTAT_READY) {
42700 + ack |= TLAN_HC_GO | TLAN_HC_RT;
42701 + host_cmd = TLAN_HC_ACK | ack | 0x001C0000;
42702 + outl(host_cmd, BASE + TLAN_HOST_CMD);
42705 - if ( bbuf ) {
42706 - dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
42707 - * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );
42708 } else {
42709 - dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
42710 - * ( sizeof(TLanList) );
42712 - priv->dmaStorage = kmalloc(dma_size, GFP_KERNEL | GFP_DMA);
42713 - if ( priv->dmaStorage == NULL ) {
42714 - printk(KERN_ERR "TLAN: Could not allocate lists and buffers for %s.\n",
42715 - dev->name );
42716 - release_region( dev->base_addr, 0x10 );
42717 - return -ENOMEM;
42719 - memset( priv->dmaStorage, 0, dma_size );
42720 - priv->rxList = (TLanList *)
42721 - ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );
42722 - priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
42723 - if ( bbuf ) {
42724 - priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
42725 - priv->txBuffer = priv->rxBuffer
42726 - + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
42729 - err = 0;
42730 - for ( i = 0; i < 6 ; i++ )
42731 - err |= TLan_EeReadByte( dev,
42732 - (u8) priv->adapter->addrOfs + i,
42733 - (u8 *) &dev->dev_addr[i] );
42734 - if ( err ) {
42735 - printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
42736 - dev->name,
42737 - err );
42739 - dev->addr_len = 6;
42741 - /* Device methods */
42742 - dev->open = &TLan_Open;
42743 - dev->hard_start_xmit = &TLan_StartTx;
42744 - dev->stop = &TLan_Close;
42745 - dev->get_stats = &TLan_GetStats;
42746 - dev->set_multicast_list = &TLan_SetMulticastList;
42747 - dev->do_ioctl = &TLan_ioctl;
42748 - dev->tx_timeout = &TLan_tx_timeout;
42749 - dev->watchdog_timeo = TX_TIMEOUT;
42751 - return 0;
42753 -} /* TLan_Init */
42755 - /***************************************************************
42756 - * TLan_Open
42758 - * Returns:
42759 - * 0 on success, error code otherwise.
42760 - * Parms:
42761 - * dev Structure of device to be opened.
42763 - * This routine puts the driver and TLAN adapter in a
42764 - * state where it is ready to send and receive packets.
42765 - * It allocates the IRQ, resets and brings the adapter
42766 - * out of reset, and allows interrupts. It also delays
42767 - * the startup for autonegotiation or sends a Rx GO
42768 - * command to the adapter, as appropriate.
42770 - **************************************************************/
42772 -static int TLan_Open( struct net_device *dev )
42774 - TLanPrivateInfo *priv = dev->priv;
42775 - int err;
42777 - priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
42778 - err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ, TLanSignature, dev );
42780 - if ( err ) {
42781 - printk(KERN_ERR "TLAN: Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
42782 - return err;
42783 + host_cmd = TLAN_HC_ACK | ack | (0x000C0000);
42784 + outl(host_cmd, BASE + TLAN_HOST_CMD);
42785 +#ifdef EBDEBUG
42786 + printf("AC: 0x%hX\n", inw(BASE + TLAN_CH_PARM));
42787 + host_int = inw(BASE + TLAN_HOST_INT);
42788 + printf("PI-2: 0x%hX\n", host_int);
42789 +#endif
42792 - init_timer(&priv->timer);
42793 - netif_start_queue(dev);
42795 - /* NOTE: It might not be necessary to read the stats before a
42796 - reset if you don't care what the values are.
42797 - */
42798 - TLan_ResetLists( dev );
42799 - TLan_ReadAndClearStats( dev, TLAN_IGNORE );
42800 - TLan_ResetAdapter( dev );
42802 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened. TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );
42804 - return 0;
42806 -} /* TLan_Open */
42808 - /**************************************************************
42809 - * TLan_ioctl
42810 - *
42811 - * Returns:
42812 - * 0 on success, error code otherwise
42813 - * Params:
42814 - * dev structure of device to receive ioctl.
42815 - *
42816 - * rq ifreq structure to hold userspace data.
42818 - * cmd ioctl command.
42821 - *************************************************************/
42822 + refill_rx(nic);
42823 + return (1); /* initially as this is called to flush the input */
42826 -static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
42827 +static void refill_rx(struct nic *nic __unused)
42829 - TLanPrivateInfo *priv = dev->priv;
42830 - struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
42831 - u32 phy = priv->phy[priv->phyNum];
42833 - if (!priv->phyOnline)
42834 - return -EAGAIN;
42836 - switch(cmd) {
42837 - case SIOCGMIIPHY: /* Get address of MII PHY in use. */
42838 - case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
42839 - data->phy_id = phy;
42841 - case SIOCGMIIREG: /* Read MII PHY register. */
42842 - case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
42843 - TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out);
42844 - return 0;
42846 + int entry = 0;
42848 - case SIOCSMIIREG: /* Write MII PHY register. */
42849 - case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
42850 - if (!capable(CAP_NET_ADMIN))
42851 - return -EPERM;
42852 - TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
42853 - return 0;
42854 - default:
42855 - return -EOPNOTSUPP;
42856 + for (;
42857 + (priv->cur_rx - priv->dirty_rx +
42858 + TLAN_NUM_RX_LISTS) % TLAN_NUM_RX_LISTS > 0;
42859 + priv->dirty_rx = (priv->dirty_rx + 1) % TLAN_NUM_RX_LISTS) {
42860 + entry = priv->dirty_rx % TLAN_NUM_TX_LISTS;
42861 + rx_ring[entry].frameSize = TLAN_MAX_FRAME_SIZE;
42862 + rx_ring[entry].cStat = TLAN_CSTAT_READY;
42864 -} /* tlan_ioctl */
42866 - /***************************************************************
42867 - * TLan_tx_timeout
42869 - * Returns: nothing
42871 - * Params:
42872 - * dev structure of device which timed out
42873 - * during transmit.
42875 - **************************************************************/
42877 -static void TLan_tx_timeout(struct net_device *dev)
42880 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
42882 - /* Ok so we timed out, lets see what we can do about it...*/
42883 - TLan_FreeLists( dev );
42884 - TLan_ResetLists( dev );
42885 - TLan_ReadAndClearStats( dev, TLAN_IGNORE );
42886 - TLan_ResetAdapter( dev );
42887 - dev->trans_start = jiffies;
42888 - netif_wake_queue( dev );
42893 - /***************************************************************
42894 - * TLan_StartTx
42895 - *
42896 - * Returns:
42897 - * 0 on success, non-zero on failure.
42898 - * Parms:
42899 - * skb A pointer to the sk_buff containing the
42900 - * frame to be sent.
42901 - * dev The device to send the data on.
42903 - * This function adds a frame to the Tx list to be sent
42904 - * ASAP. First it verifies that the adapter is ready and
42905 - * there is room in the queue. Then it sets up the next
42906 - * available list, copies the frame to the corresponding
42907 - * buffer. If the adapter Tx channel is idle, it gives
42908 - * the adapter a Tx Go command on the list, otherwise it
42909 - * sets the forward address of the previous list to point
42910 - * to this one. Then it frees the sk_buff.
42912 - **************************************************************/
42913 +/* #define EBDEBUG */
42914 +/**************************************************************************
42915 +TRANSMIT - Transmit a frame
42916 +***************************************************************************/
42917 +static void tlan_transmit(struct nic *nic, const char *d, /* Destination */
42918 + unsigned int t, /* Type */
42919 + unsigned int s, /* size */
42920 + const char *p)
42921 +{ /* Packet */
42922 + u16 nstype;
42923 + u32 to;
42924 + struct TLanList *tail_list;
42925 + struct TLanList *head_list;
42926 + u8 *tail_buffer;
42927 + u32 ack = 0;
42928 + u32 host_cmd;
42929 + int eoc = 0;
42930 + u16 tmpCStat;
42931 +#ifdef EBDEBUG
42932 + u16 host_int = inw(BASE + TLAN_HOST_INT);
42933 +#endif
42934 + int entry = 0;
42936 -static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
42938 - TLanPrivateInfo *priv = dev->priv;
42939 - TLanList *tail_list;
42940 - u8 *tail_buffer;
42941 - int pad;
42942 - unsigned long flags;
42944 - if ( ! priv->phyOnline ) {
42945 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s PHY is not ready\n", dev->name );
42946 - dev_kfree_skb_any(skb);
42947 - return 0;
42948 +#ifdef EBDEBUG
42949 + printf("INT0-0x%hX\n", host_int);
42950 +#endif
42952 + if (!priv->phyOnline) {
42953 + printf("TRANSMIT: %s PHY is not ready\n", priv->nic_name);
42954 + return;
42957 tail_list = priv->txList + priv->txTail;
42959 - if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) {
42960 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s is busy (Head=%d Tail=%d)\n", dev->name, priv->txHead, priv->txTail );
42961 - netif_stop_queue(dev);
42963 + if (tail_list->cStat != TLAN_CSTAT_UNUSED) {
42964 + printf("TRANSMIT: %s is busy (Head=%d Tail=%d)\n",
42965 + priv->nic_name, priv->txList, priv->txTail);
42966 + tx_ring[entry].cStat = TLAN_CSTAT_UNUSED;
42967 priv->txBusyCount++;
42968 - return 1;
42969 + return;
42972 tail_list->forward = 0;
42974 - if ( bbuf ) {
42975 - tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
42976 - memcpy( tail_buffer, skb->data, skb->len );
42977 - } else {
42978 - tail_list->buffer[0].address = virt_to_bus( skb->data );
42979 - tail_list->buffer[9].address = (u32) skb;
42981 + tail_buffer = txb + (priv->txTail * TLAN_MAX_FRAME_SIZE);
42983 - pad = TLAN_MIN_FRAME_SIZE - skb->len;
42985 - if ( pad > 0 ) {
42986 - tail_list->frameSize = (u16) skb->len + pad;
42987 - tail_list->buffer[0].count = (u32) skb->len;
42988 - tail_list->buffer[1].count = TLAN_LAST_BUFFER | (u32) pad;
42989 - tail_list->buffer[1].address = virt_to_bus( TLanPadBuffer );
42990 - } else {
42991 - tail_list->frameSize = (u16) skb->len;
42992 - tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;
42993 - tail_list->buffer[1].count = 0;
42994 - tail_list->buffer[1].address = 0;
42996 + /* send the packet to destination */
42997 + memcpy(tail_buffer, d, ETH_ALEN);
42998 + memcpy(tail_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
42999 + nstype = htons((u16) t);
43000 + memcpy(tail_buffer + 2 * ETH_ALEN, (u8 *) & nstype, 2);
43001 + memcpy(tail_buffer + ETH_HLEN, p, s);
43003 + s += ETH_HLEN;
43004 + s &= 0x0FFF;
43005 + while (s < ETH_ZLEN)
43006 + tail_buffer[s++] = '\0';
43008 + /*=====================================================*/
43009 + /* Receive
43010 + * 0000 0000 0001 1100
43011 + * 0000 0000 0000 1100
43012 + * 0000 0000 0000 0011 = 0x0003
43014 + * 0000 0000 0000 0000 0000 0000 0000 0011
43015 + * 0000 0000 0000 1100 0000 0000 0000 0000 = 0x000C0000
43017 + * Transmit
43018 + * 0000 0000 0001 1100
43019 + * 0000 0000 0000 0100
43020 + * 0000 0000 0000 0001 = 0x0001
43022 + * 0000 0000 0000 0000 0000 0000 0000 0001
43023 + * 0000 0000 0000 0100 0000 0000 0000 0000 = 0x00040000
43024 + * */
43026 + /* Setup the transmit descriptor */
43027 + tail_list->frameSize = (u16) s;
43028 + tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) s;
43029 + tail_list->buffer[1].count = 0;
43030 + tail_list->buffer[1].address = 0;
43032 - spin_lock_irqsave(&priv->lock, flags);
43033 tail_list->cStat = TLAN_CSTAT_READY;
43034 - if ( ! priv->txInProgress ) {
43036 +#ifdef EBDEBUG
43037 + host_int = inw(BASE + TLAN_HOST_INT);
43038 + printf("INT1-0x%hX\n", host_int);
43039 +#endif
43041 + if (!priv->txInProgress) {
43042 priv->txInProgress = 1;
43043 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Starting TX on buffer %d\n", priv->txTail );
43044 - outl( virt_to_bus( tail_list ), dev->base_addr + TLAN_CH_PARM );
43045 - outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
43046 + outl(virt_to_le32desc(tail_list), BASE + TLAN_CH_PARM);
43047 + outl(TLAN_HC_GO, BASE + TLAN_HOST_CMD);
43048 } else {
43049 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Adding buffer %d to TX channel\n", priv->txTail );
43050 - if ( priv->txTail == 0 ) {
43051 - ( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = virt_to_bus( tail_list );
43052 + if (priv->txTail == 0) {
43053 +#ifdef EBDEBUG
43054 + printf("Out buffer\n");
43055 +#endif
43056 + (priv->txList + (TLAN_NUM_TX_LISTS - 1))->forward =
43057 + virt_to_le32desc(tail_list);
43058 } else {
43059 - ( priv->txList + ( priv->txTail - 1 ) )->forward = virt_to_bus( tail_list );
43060 +#ifdef EBDEBUG
43061 + printf("Fix this \n");
43062 +#endif
43063 + (priv->txList + (priv->txTail - 1))->forward =
43064 + virt_to_le32desc(tail_list);
43067 - spin_unlock_irqrestore(&priv->lock, flags);
43069 - CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
43071 - if ( bbuf )
43072 - dev_kfree_skb_any(skb);
43074 - dev->trans_start = jiffies;
43075 - return 0;
43077 -} /* TLan_StartTx */
43079 - /***************************************************************
43080 - * TLan_HandleInterrupt
43081 - *
43082 - * Returns:
43083 - * Nothing
43084 - * Parms:
43085 - * irq The line on which the interrupt
43086 - * occurred.
43087 - * dev_id A pointer to the device assigned to
43088 - * this irq line.
43089 - * regs ???
43091 - * This function handles an interrupt generated by its
43092 - * assigned TLAN adapter. The function deactivates
43093 - * interrupts on its adapter, records the type of
43094 - * interrupt, executes the appropriate subhandler, and
43095 - * acknowdges the interrupt to the adapter (thus
43096 - * re-enabling adapter interrupts.
43098 - **************************************************************/
43100 -static void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs)
43102 - u32 ack;
43103 - struct net_device *dev;
43104 - u32 host_cmd;
43105 - u16 host_int;
43106 - int type;
43107 - TLanPrivateInfo *priv;
43109 - dev = dev_id;
43110 - priv = dev->priv;
43112 - spin_lock(&priv->lock);
43114 - host_int = inw( dev->base_addr + TLAN_HOST_INT );
43115 - outw( host_int, dev->base_addr + TLAN_HOST_INT );
43117 + CIRC_INC(priv->txTail, TLAN_NUM_TX_LISTS);
43119 - type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
43120 +#ifdef EBDEBUG
43121 + host_int = inw(BASE + TLAN_HOST_INT);
43122 + printf("INT2-0x%hX\n", host_int);
43123 +#endif
43125 - ack = TLanIntVector[type]( dev, host_int );
43126 + to = currticks() + TX_TIME_OUT;
43127 + while ((tail_list->cStat == TLAN_CSTAT_READY) && currticks() < to);
43129 - if ( ack ) {
43130 - host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
43131 - outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
43132 + head_list = priv->txList + priv->txHead;
43133 + while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP)
43134 + && (ack < 255)) {
43135 + ack++;
43136 + if(tmpCStat & TLAN_CSTAT_EOC)
43137 + eoc =1;
43138 + head_list->cStat = TLAN_CSTAT_UNUSED;
43139 + CIRC_INC(priv->txHead, TLAN_NUM_TX_LISTS);
43140 + head_list = priv->txList + priv->txHead;
43143 + if(!ack)
43144 + printf("Incomplete TX Frame\n");
43146 - spin_unlock(&priv->lock);
43148 -} /* TLan_HandleInterrupts */
43150 - /***************************************************************
43151 - * TLan_Close
43152 - *
43153 - * Returns:
43154 - * An error code.
43155 - * Parms:
43156 - * dev The device structure of the device to
43157 - * close.
43159 - * This function shuts down the adapter. It records any
43160 - * stats, puts the adapter into reset state, deactivates
43161 - * its time as needed, and frees the irq it is using.
43163 - **************************************************************/
43165 -static int TLan_Close(struct net_device *dev)
43167 - TLanPrivateInfo *priv = dev->priv;
43169 - netif_stop_queue(dev);
43170 - priv->neg_be_verbose = 0;
43172 - TLan_ReadAndClearStats( dev, TLAN_RECORD );
43173 - outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
43174 - if ( priv->timer.function != NULL ) {
43175 - del_timer_sync( &priv->timer );
43176 - priv->timer.function = NULL;
43177 + if(eoc) {
43178 + head_list = priv->txList + priv->txHead;
43179 + if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) {
43180 + outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM);
43181 + ack |= TLAN_HC_GO;
43182 + } else {
43183 + priv->txInProgress = 0;
43187 - free_irq( dev->irq, dev );
43188 - TLan_FreeLists( dev );
43189 - TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name );
43191 - return 0;
43193 -} /* TLan_Close */
43195 - /***************************************************************
43196 - * TLan_GetStats
43197 - *
43198 - * Returns:
43199 - * A pointer to the device's statistics structure.
43200 - * Parms:
43201 - * dev The device structure to return the
43202 - * stats for.
43204 - * This function updates the devices statistics by reading
43205 - * the TLAN chip's onboard registers. Then it returns the
43206 - * address of the statistics structure.
43208 - **************************************************************/
43210 -static struct net_device_stats *TLan_GetStats( struct net_device *dev )
43212 - TLanPrivateInfo *priv = dev->priv;
43213 - int i;
43215 - /* Should only read stats if open ? */
43216 - TLan_ReadAndClearStats( dev, TLAN_RECORD );
43218 - TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: %s EOC count = %d\n", dev->name, priv->rxEocCount );
43219 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: %s Busy count = %d\n", dev->name, priv->txBusyCount );
43220 - if ( debug & TLAN_DEBUG_GNRL ) {
43221 - TLan_PrintDio( dev->base_addr );
43222 - TLan_PhyPrint( dev );
43224 - if ( debug & TLAN_DEBUG_LIST ) {
43225 - for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ )
43226 - TLan_PrintList( priv->rxList + i, "RX", i );
43227 - for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ )
43228 - TLan_PrintList( priv->txList + i, "TX", i );
43229 + if(ack) {
43230 + host_cmd = TLAN_HC_ACK | ack;
43231 + outl(host_cmd, BASE + TLAN_HOST_CMD);
43234 - return ( &( (TLanPrivateInfo *) dev->priv )->stats );
43236 -} /* TLan_GetStats */
43238 - /***************************************************************
43239 - * TLan_SetMulticastList
43240 - *
43241 - * Returns:
43242 - * Nothing
43243 - * Parms:
43244 - * dev The device structure to set the
43245 - * multicast list for.
43247 - * This function sets the TLAN adaptor to various receive
43248 - * modes. If the IFF_PROMISC flag is set, promiscuous
43249 - * mode is acitviated. Otherwise, promiscuous mode is
43250 - * turned off. If the IFF_ALLMULTI flag is set, then
43251 - * the hash table is set to receive all group addresses.
43252 - * Otherwise, the first three multicast addresses are
43253 - * stored in AREG_1-3, and the rest are selected via the
43254 - * hash table, as necessary.
43256 - **************************************************************/
43258 -static void TLan_SetMulticastList( struct net_device *dev )
43260 - struct dev_mc_list *dmi = dev->mc_list;
43261 - u32 hash1 = 0;
43262 - u32 hash2 = 0;
43263 - int i;
43264 - u32 offset;
43265 - u8 tmp;
43267 - if ( dev->flags & IFF_PROMISC ) {
43268 - tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
43269 - TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
43270 - } else {
43271 - tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
43272 - TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
43273 - if ( dev->flags & IFF_ALLMULTI ) {
43274 - for ( i = 0; i < 3; i++ )
43275 - TLan_SetMac( dev, i + 1, NULL );
43276 - TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
43277 - TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
43278 + if(priv->tlanRev < 0x30 ) {
43279 + ack = 1;
43280 + head_list = priv->txList + priv->txHead;
43281 + if ((head_list->cStat & TLAN_CSTAT_READY) == TLAN_CSTAT_READY) {
43282 + outl(virt_to_le32desc(head_list), BASE + TLAN_CH_PARM);
43283 + ack |= TLAN_HC_GO;
43284 } else {
43285 - for ( i = 0; i < dev->mc_count; i++ ) {
43286 - if ( i < 3 ) {
43287 - TLan_SetMac( dev, i + 1, (char *) &dmi->dmi_addr );
43288 - } else {
43289 - offset = TLan_HashFunc( (u8 *) &dmi->dmi_addr );
43290 - if ( offset < 32 )
43291 - hash1 |= ( 1 << offset );
43292 - else
43293 - hash2 |= ( 1 << ( offset - 32 ) );
43295 - dmi = dmi->next;
43297 - for ( ; i < 3; i++ )
43298 - TLan_SetMac( dev, i + 1, NULL );
43299 - TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 );
43300 - TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 );
43301 + priv->txInProgress = 0;
43303 + host_cmd = TLAN_HC_ACK | ack | 0x00140000;
43304 + outl(host_cmd, BASE + TLAN_HOST_CMD);
43308 + if (currticks() >= to) {
43309 + printf("TX Time Out");
43313 -} /* TLan_SetMulticastList */
43315 -/*****************************************************************************
43316 -******************************************************************************
43318 - ThunderLAN Driver Interrupt Vectors and Table
43320 - Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN
43321 - Programmer's Guide" for more informations on handling interrupts
43322 - generated by TLAN based adapters.
43324 -******************************************************************************
43325 -*****************************************************************************/
43327 - /***************************************************************
43328 - * TLan_HandleInvalid
43330 - * Returns:
43331 - * 0
43332 - * Parms:
43333 - * dev Device assigned the IRQ that was
43334 - * raised.
43335 - * host_int The contents of the HOST_INT
43336 - * port.
43338 - * This function handles invalid interrupts. This should
43339 - * never happen unless some other adapter is trying to use
43340 - * the IRQ line assigned to the device.
43342 - **************************************************************/
43344 -u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
43345 +/**************************************************************************
43346 +DISABLE - Turn off ethernet interface
43347 +***************************************************************************/
43348 +#ifdef EB51
43349 +static void tlan_disable(struct dev *dev __unused)
43350 +#else
43351 +static void tlan_disable(struct nic *nic __unused)
43352 +#endif
43354 - /* printk( "TLAN: Invalid interrupt on %s.\n", dev->name ); */
43355 - return 0;
43357 -} /* TLan_HandleInvalid */
43359 - /***************************************************************
43360 - * TLan_HandleTxEOF
43362 - * Returns:
43363 - * 1
43364 - * Parms:
43365 - * dev Device assigned the IRQ that was
43366 - * raised.
43367 - * host_int The contents of the HOST_INT
43368 - * port.
43370 - * This function handles Tx EOF interrupts which are raised
43371 - * by the adapter when it has completed sending the
43372 - * contents of a buffer. If detemines which list/buffer
43373 - * was completed and resets it. If the buffer was the last
43374 - * in the channel (EOC), then the function checks to see if
43375 - * another buffer is ready to send, and if so, sends a Tx
43376 - * Go command. Finally, the driver activates/continues the
43377 - * activity LED.
43378 + /* put the card in its initial state */
43379 + /* This function serves 3 purposes.
43380 + * This disables DMA and interrupts so we don't receive
43381 + * unexpected packets or interrupts from the card after
43382 + * etherboot has finished.
43383 + * This frees resources so etherboot may use
43384 + * this driver on another interface
43385 + * This allows etherboot to reinitialize the interface
43386 + * if something is something goes wrong.
43388 - **************************************************************/
43389 + */
43390 + outl(TLAN_HC_AD_RST, BASE + TLAN_HOST_CMD);
43393 -u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
43394 +/**************************************************************************
43395 +IRQ - Enable, Disable, or Force interrupts
43396 +***************************************************************************/
43397 +static void tlan_irq(struct nic *nic __unused, irq_action_t action __unused)
43399 - TLanPrivateInfo *priv = dev->priv;
43400 - int eoc = 0;
43401 - TLanList *head_list;
43402 - u32 ack = 0;
43403 - u16 tmpCStat;
43405 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOF (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
43406 - head_list = priv->txList + priv->txHead;
43407 + switch ( action ) {
43408 + case DISABLE :
43409 + break;
43410 + case ENABLE :
43411 + break;
43412 + case FORCE :
43413 + break;
43417 - while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
43418 - ack++;
43419 - if ( ! bbuf ) {
43420 - dev_kfree_skb_any( (struct sk_buff *) head_list->buffer[9].address );
43421 - head_list->buffer[9].address = 0;
43424 - if ( tmpCStat & TLAN_CSTAT_EOC )
43425 - eoc = 1;
43427 - priv->stats.tx_bytes += head_list->frameSize;
43428 +static void TLan_SetMulticastList(struct nic *nic) {
43429 + int i;
43430 + u8 tmp;
43432 - head_list->cStat = TLAN_CSTAT_UNUSED;
43433 - netif_start_queue(dev);
43434 - CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS );
43435 - head_list = priv->txList + priv->txHead;
43437 + /* !IFF_PROMISC */
43438 + tmp = TLan_DioRead8(BASE, TLAN_NET_CMD);
43439 + TLan_DioWrite8(BASE, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF);
43441 + /* IFF_ALLMULTI */
43442 + for(i = 0; i< 3; i++)
43443 + TLan_SetMac(nic, i + 1, NULL);
43444 + TLan_DioWrite32(BASE, TLAN_HASH_1, 0xFFFFFFFF);
43445 + TLan_DioWrite32(BASE, TLAN_HASH_2, 0xFFFFFFFF);
43447 - if (!ack)
43448 - printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
43450 - if ( eoc ) {
43451 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
43452 - head_list = priv->txList + priv->txHead;
43453 - if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
43454 - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
43455 - ack |= TLAN_HC_GO;
43456 - } else {
43457 - priv->txInProgress = 0;
43461 - if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
43462 - TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
43463 - if ( priv->timer.function == NULL ) {
43464 - priv->timer.function = &TLan_Timer;
43465 - priv->timer.data = (unsigned long) dev;
43466 - priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
43467 - priv->timerSetAt = jiffies;
43468 - priv->timerType = TLAN_TIMER_ACTIVITY;
43469 - add_timer(&priv->timer);
43470 - } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
43471 - priv->timerSetAt = jiffies;
43473 +/**************************************************************************
43474 +PROBE - Look for an adapter, this routine's visible to the outside
43475 +***************************************************************************/
43477 +#define board_found 1
43478 +#define valid_link 0
43479 +#ifdef EB51
43480 +static int tlan_probe(struct dev *dev, struct pci_device *pci)
43482 + struct nic *nic = (struct nic *) dev;
43483 +#else
43484 +struct nic *tlan_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
43486 +#endif
43487 + u16 data = 0;
43488 + int err;
43489 + int i;
43491 + if (pci->ioaddr == 0)
43492 + return 0;
43494 + nic->irqno = 0;
43495 + nic->ioaddr = pci->ioaddr & ~3;
43497 + BASE = pci->ioaddr;
43498 + printf("\n");
43499 + printf("tlan.c: %s, %s\n", drv_version, drv_date);
43500 + printf("%s: Probing for Vendor 0x%hX, Device 0x%hX",
43501 + pci->name, pci->vendor, pci->dev_id);
43504 + /* I really must find out what this does */
43505 + adjust_pci_device(pci);
43507 + /* Point to private storage */
43508 + priv = &TLanPrivateInfo;
43509 + /* Figure out which chip we're dealing with */
43510 + i = 0;
43511 + chip_idx = -1;
43513 + while (tlan_pci_tbl[i].name) {
43514 + if ((((u32) pci->dev_id << 16) | pci->vendor) ==
43515 + (tlan_pci_tbl[i].id.pci & 0xffffffff)) {
43516 + chip_idx = i;
43517 + break;
43519 + i++;
43522 - return ack;
43523 + priv->vendor_id = pci->vendor;
43524 + priv->dev_id = pci->dev_id;
43525 + priv->nic_name = pci->name;
43526 + priv->eoc = 0;
43528 -} /* TLan_HandleTxEOF */
43529 + err = 0;
43530 + for (i = 0; i < 6; i++)
43531 + err |= TLan_EeReadByte(BASE,
43532 + (u8) tlan_pci_tbl[chip_idx].
43533 + addrOfs + i,
43534 + (u8 *) & nic->node_addr[i]);
43535 + if (err) {
43536 + printf("TLAN: %s: Error reading MAC from eeprom: %d\n",
43537 + pci->name, err);
43538 + } else
43539 + printf("\nAddress: %!\n", nic->node_addr);
43541 - /***************************************************************
43542 - * TLan_HandleStatOverflow
43544 - * Returns:
43545 - * 1
43546 - * Parms:
43547 - * dev Device assigned the IRQ that was
43548 - * raised.
43549 - * host_int The contents of the HOST_INT
43550 - * port.
43552 - * This function handles the Statistics Overflow interrupt
43553 - * which means that one or more of the TLAN statistics
43554 - * registers has reached 1/2 capacity and needs to be read.
43556 - **************************************************************/
43557 + priv->tlanRev = TLan_DioRead8(BASE, TLAN_DEF_REVISION);
43558 + printf("\nRevision = 0x%hX\n", priv->tlanRev);
43560 -u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
43562 - TLan_ReadAndClearStats( dev, TLAN_RECORD );
43563 + TLan_ResetLists(nic);
43564 + TLan_ResetAdapter(nic);
43566 + data = inl(BASE + TLAN_HOST_CMD);
43567 + data |= TLAN_HC_EOC;
43568 + outw(data, BASE + TLAN_HOST_CMD);
43571 + data = inl(BASE + TLAN_HOST_CMD);
43572 + data |= TLAN_HC_INT_OFF;
43573 + outw(data, BASE + TLAN_HOST_CMD);
43575 + TLan_SetMulticastList(nic);
43576 + udelay(100);
43577 + priv->txList = tx_ring;
43578 + priv->rxList = rx_ring;
43579 +/* if (board_found && valid_link)
43580 + {*/
43581 + /* point to NIC specific routines */
43582 +#ifdef EB51
43583 + dev->disable = tlan_disable;
43584 + nic->poll = tlan_poll;
43585 + nic->transmit = tlan_transmit;
43586 + nic->irq = tlan_irq;
43587 return 1;
43588 +#else
43589 + nic->disable = tlan_disable;
43590 + nic->poll = tlan_poll;
43591 + nic->transmit = tlan_transmit;
43592 + nic->irq = tlan_irq;
43593 + return nic;
43594 +#endif
43598 +/*****************************************************************************
43599 +******************************************************************************
43601 + ThunderLAN Driver Eeprom routines
43603 + The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
43604 + EEPROM. These functions are based on information in Microchip's
43605 + data sheet. I don't know how well this functions will work with
43606 + other EEPROMs.
43608 +******************************************************************************
43609 +*****************************************************************************/
43611 -} /* TLan_HandleStatOverflow */
43613 /***************************************************************
43614 - * TLan_HandleRxEOF
43615 + * TLan_EeSendStart
43617 * Returns:
43618 - * 1
43619 + * Nothing
43620 * Parms:
43621 - * dev Device assigned the IRQ that was
43622 - * raised.
43623 - * host_int The contents of the HOST_INT
43624 - * port.
43626 - * This function handles the Rx EOF interrupt which
43627 - * indicates a frame has been received by the adapter from
43628 - * the net and the frame has been transferred to memory.
43629 - * The function determines the bounce buffer the frame has
43630 - * been loaded into, creates a new sk_buff big enough to
43631 - * hold the frame, and sends it to protocol stack. It
43632 - * then resets the used buffer and appends it to the end
43633 - * of the list. If the frame was the last in the Rx
43634 - * channel (EOC), the function restarts the receive channel
43635 - * by sending an Rx Go command to the adapter. Then it
43636 - * activates/continues the activity LED.
43637 + * io_base The IO port base address for the
43638 + * TLAN device with the EEPROM to
43639 + * use.
43641 + * This function sends a start cycle to an EEPROM attached
43642 + * to a TLAN chip.
43644 **************************************************************/
43646 -u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
43647 +void TLan_EeSendStart(u16 io_base)
43649 - TLanPrivateInfo *priv = dev->priv;
43650 - u32 ack = 0;
43651 - int eoc = 0;
43652 - u8 *head_buffer;
43653 - TLanList *head_list;
43654 - struct sk_buff *skb;
43655 - TLanList *tail_list;
43656 - void *t;
43657 - u32 frameSize;
43658 - u16 tmpCStat;
43660 - TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
43661 - head_list = priv->rxList + priv->rxHead;
43663 - while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
43664 - frameSize = head_list->frameSize;
43665 - ack++;
43666 - if (tmpCStat & TLAN_CSTAT_EOC)
43667 - eoc = 1;
43669 - if (bbuf) {
43670 - skb = dev_alloc_skb(frameSize + 7);
43671 - if (skb == NULL)
43672 - printk(KERN_INFO "TLAN: Couldn't allocate memory for received data.\n");
43673 - else {
43674 - head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
43675 - skb->dev = dev;
43676 - skb_reserve(skb, 2);
43677 - t = (void *) skb_put(skb, frameSize);
43679 - priv->stats.rx_bytes += head_list->frameSize;
43681 - memcpy( t, head_buffer, frameSize );
43682 - skb->protocol = eth_type_trans( skb, dev );
43683 - netif_rx( skb );
43685 - } else {
43686 - struct sk_buff *new_skb;
43688 - /*
43689 - * I changed the algorithm here. What we now do
43690 - * is allocate the new frame. If this fails we
43691 - * simply recycle the frame.
43692 - */
43694 - new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
43696 - if ( new_skb != NULL ) {
43697 - /* If this ever happened it would be a problem */
43698 - /* not any more - ac */
43699 - skb = (struct sk_buff *) head_list->buffer[9].address;
43700 - skb_trim( skb, frameSize );
43702 - priv->stats.rx_bytes += frameSize;
43703 + u16 sio;
43705 - skb->protocol = eth_type_trans( skb, dev );
43706 - netif_rx( skb );
43708 - new_skb->dev = dev;
43709 - skb_reserve( new_skb, 2 );
43710 - t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE );
43711 - head_list->buffer[0].address = virt_to_bus( t );
43712 - head_list->buffer[8].address = (u32) t;
43713 - head_list->buffer[9].address = (u32) new_skb;
43714 - } else
43715 - printk(KERN_WARNING "TLAN: Couldn't allocate memory for received data.\n" );
43717 + outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
43718 + sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
43720 - head_list->forward = 0;
43721 - head_list->cStat = 0;
43722 - tail_list = priv->rxList + priv->rxTail;
43723 - tail_list->forward = virt_to_bus( head_list );
43725 - CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
43726 - CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
43727 - head_list = priv->rxList + priv->rxHead;
43729 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43730 + TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
43731 + TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);
43732 + TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);
43733 + TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
43735 - if (!ack)
43736 - printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
43738 +} /* TLan_EeSendStart */
43740 - if ( eoc ) {
43741 - TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
43742 - head_list = priv->rxList + priv->rxHead;
43743 - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
43744 - ack |= TLAN_HC_GO | TLAN_HC_RT;
43745 - priv->rxEocCount++;
43748 - if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
43749 - TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
43750 - if ( priv->timer.function == NULL ) {
43751 - priv->timer.function = &TLan_Timer;
43752 - priv->timer.data = (unsigned long) dev;
43753 - priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
43754 - priv->timerSetAt = jiffies;
43755 - priv->timerType = TLAN_TIMER_ACTIVITY;
43756 - add_timer(&priv->timer);
43757 - } else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
43758 - priv->timerSetAt = jiffies;
43762 - dev->last_rx = jiffies;
43764 - return ack;
43766 -} /* TLan_HandleRxEOF */
43768 /***************************************************************
43769 - * TLan_HandleDummy
43770 + * TLan_EeSendByte
43772 * Returns:
43773 - * 1
43774 - * Parms:
43775 - * dev Device assigned the IRQ that was
43776 - * raised.
43777 - * host_int The contents of the HOST_INT
43778 - * port.
43780 - * This function handles the Dummy interrupt, which is
43781 - * raised whenever a test interrupt is generated by setting
43782 - * the Req_Int bit of HOST_CMD to 1.
43783 + * If the correct ack was received, 0, otherwise 1
43784 + * Parms: io_base The IO port base address for the
43785 + * TLAN device with the EEPROM to
43786 + * use.
43787 + * data The 8 bits of information to
43788 + * send to the EEPROM.
43789 + * stop If TLAN_EEPROM_STOP is passed, a
43790 + * stop cycle is sent after the
43791 + * byte is sent after the ack is
43792 + * read.
43794 + * This function sends a byte on the serial EEPROM line,
43795 + * driving the clock to send each bit. The function then
43796 + * reverses transmission direction and reads an acknowledge
43797 + * bit.
43799 **************************************************************/
43801 -u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
43802 +int TLan_EeSendByte(u16 io_base, u8 data, int stop)
43804 - printk( "TLAN: Test interrupt on %s.\n", dev->name );
43805 - return 1;
43806 + int err;
43807 + u8 place;
43808 + u16 sio;
43810 -} /* TLan_HandleDummy */
43811 + outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
43812 + sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
43814 - /***************************************************************
43815 - * TLan_HandleTxEOC
43817 - * Returns:
43818 - * 1
43819 - * Parms:
43820 - * dev Device assigned the IRQ that was
43821 - * raised.
43822 - * host_int The contents of the HOST_INT
43823 - * port.
43825 - * This driver is structured to determine EOC occurances by
43826 - * reading the CSTAT member of the list structure. Tx EOC
43827 - * interrupts are disabled via the DIO INTDIS register.
43828 - * However, TLAN chips before revision 3.0 didn't have this
43829 - * functionality, so process EOC events if this is the
43830 - * case.
43832 - **************************************************************/
43833 + /* Assume clock is low, tx is enabled; */
43834 + for (place = 0x80; place != 0; place >>= 1) {
43835 + if (place & data)
43836 + TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
43837 + else
43838 + TLan_ClearBit(TLAN_NET_SIO_EDATA, sio);
43839 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43840 + TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
43842 + TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio);
43843 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43844 + err = TLan_GetBit(TLAN_NET_SIO_EDATA, sio);
43845 + TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
43846 + TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);
43848 -u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
43850 - TLanPrivateInfo *priv = dev->priv;
43851 - TLanList *head_list;
43852 - u32 ack = 1;
43854 - host_int = 0;
43855 - if ( priv->tlanRev < 0x30 ) {
43856 - TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT: Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail );
43857 - head_list = priv->txList + priv->txHead;
43858 - if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
43859 - netif_stop_queue(dev);
43860 - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
43861 - ack |= TLAN_HC_GO;
43862 - } else {
43863 - priv->txInProgress = 0;
43865 + if ((!err) && stop) {
43866 + TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */
43867 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43868 + TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
43871 - return ack;
43872 + return (err);
43874 +} /* TLan_EeSendByte */
43878 -} /* TLan_HandleTxEOC */
43880 /***************************************************************
43881 - * TLan_HandleStatusCheck
43882 + * TLan_EeReceiveByte
43884 * Returns:
43885 - * 0 if Adapter check, 1 if Network Status check.
43886 + * Nothing
43887 * Parms:
43888 - * dev Device assigned the IRQ that was
43889 - * raised.
43890 - * host_int The contents of the HOST_INT
43891 - * port.
43893 - * This function handles Adapter Check/Network Status
43894 - * interrupts generated by the adapter. It checks the
43895 - * vector in the HOST_INT register to determine if it is
43896 - * an Adapter Check interrupt. If so, it resets the
43897 - * adapter. Otherwise it clears the status registers
43898 - * and services the PHY.
43899 + * io_base The IO port base address for the
43900 + * TLAN device with the EEPROM to
43901 + * use.
43902 + * data An address to a char to hold the
43903 + * data sent from the EEPROM.
43904 + * stop If TLAN_EEPROM_STOP is passed, a
43905 + * stop cycle is sent after the
43906 + * byte is received, and no ack is
43907 + * sent.
43909 + * This function receives 8 bits of data from the EEPROM
43910 + * over the serial link. It then sends and ack bit, or no
43911 + * ack and a stop bit. This function is used to retrieve
43912 + * data after the address of a byte in the EEPROM has been
43913 + * sent.
43915 **************************************************************/
43917 -u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
43919 - TLanPrivateInfo *priv = dev->priv;
43920 - u32 ack;
43921 - u32 error;
43922 - u8 net_sts;
43923 - u32 phy;
43924 - u16 tlphy_ctl;
43925 - u16 tlphy_sts;
43927 - ack = 1;
43928 - if ( host_int & TLAN_HI_IV_MASK ) {
43929 - netif_stop_queue( dev );
43930 - error = inl( dev->base_addr + TLAN_CH_PARM );
43931 - printk( "TLAN: %s: Adaptor Error = 0x%x\n", dev->name, error );
43932 - TLan_ReadAndClearStats( dev, TLAN_RECORD );
43933 - outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
43935 - queue_task(&priv->tlan_tqueue, &tq_immediate);
43936 - mark_bh(IMMEDIATE_BH);
43938 - netif_wake_queue(dev);
43939 - ack = 0;
43940 - } else {
43941 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name );
43942 - phy = priv->phy[priv->phyNum];
43943 +void TLan_EeReceiveByte(u16 io_base, u8 * data, int stop)
43945 + u8 place;
43946 + u16 sio;
43948 - net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
43949 - if ( net_sts ) {
43950 - TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
43951 - TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Net_Sts = %x\n", dev->name, (unsigned) net_sts );
43953 - if ( ( net_sts & TLAN_NET_STS_MIRQ ) && ( priv->phyNum == 0 ) ) {
43954 - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
43955 - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
43956 - if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
43957 - tlphy_ctl |= TLAN_TC_SWAPOL;
43958 - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
43959 - } else if ( ( tlphy_sts & TLAN_TS_POLOK ) && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
43960 - tlphy_ctl &= ~TLAN_TC_SWAPOL;
43961 - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
43963 + outw(TLAN_NET_SIO, io_base + TLAN_DIO_ADR);
43964 + sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
43965 + *data = 0;
43967 - if (debug) {
43968 - TLan_PhyPrint( dev );
43971 + /* Assume clock is low, tx is enabled; */
43972 + TLan_ClearBit(TLAN_NET_SIO_ETXEN, sio);
43973 + for (place = 0x80; place; place >>= 1) {
43974 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43975 + if (TLan_GetBit(TLAN_NET_SIO_EDATA, sio))
43976 + *data |= place;
43977 + TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
43980 + TLan_SetBit(TLAN_NET_SIO_ETXEN, sio);
43981 + if (!stop) {
43982 + TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* Ack = 0 */
43983 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43984 + TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
43985 + } else {
43986 + TLan_SetBit(TLAN_NET_SIO_EDATA, sio); /* No ack = 1 (?) */
43987 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43988 + TLan_ClearBit(TLAN_NET_SIO_ECLOK, sio);
43989 + TLan_ClearBit(TLAN_NET_SIO_EDATA, sio); /* STOP, raise data while clock is high */
43990 + TLan_SetBit(TLAN_NET_SIO_ECLOK, sio);
43991 + TLan_SetBit(TLAN_NET_SIO_EDATA, sio);
43994 - return ack;
43995 +} /* TLan_EeReceiveByte */
43998 -} /* TLan_HandleStatusCheck */
44000 /***************************************************************
44001 - * TLan_HandleRxEOC
44002 + * TLan_EeReadByte
44004 * Returns:
44005 - * 1
44006 + * No error = 0, else, the stage at which the error
44007 + * occurred.
44008 * Parms:
44009 - * dev Device assigned the IRQ that was
44010 - * raised.
44011 - * host_int The contents of the HOST_INT
44012 - * port.
44014 - * This driver is structured to determine EOC occurances by
44015 - * reading the CSTAT member of the list structure. Rx EOC
44016 - * interrupts are disabled via the DIO INTDIS register.
44017 - * However, TLAN chips before revision 3.0 didn't have this
44018 - * CSTAT member or a INTDIS register, so if this chip is
44019 - * pre-3.0, process EOC interrupts normally.
44020 + * io_base The IO port base address for the
44021 + * TLAN device with the EEPROM to
44022 + * use.
44023 + * ee_addr The address of the byte in the
44024 + * EEPROM whose contents are to be
44025 + * retrieved.
44026 + * data An address to a char to hold the
44027 + * data obtained from the EEPROM.
44029 + * This function reads a byte of information from an byte
44030 + * cell in the EEPROM.
44032 **************************************************************/
44034 -u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
44035 +int TLan_EeReadByte(u16 io_base, u8 ee_addr, u8 * data)
44037 - TLanPrivateInfo *priv = dev->priv;
44038 - TLanList *head_list;
44039 - u32 ack = 1;
44040 + int err;
44041 + int ret = 0;
44043 - if ( priv->tlanRev < 0x30 ) {
44044 - TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE: Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
44045 - head_list = priv->rxList + priv->rxHead;
44046 - outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
44047 - ack |= TLAN_HC_GO | TLAN_HC_RT;
44048 - priv->rxEocCount++;
44050 + TLan_EeSendStart(io_base);
44051 + err = TLan_EeSendByte(io_base, 0xA0, TLAN_EEPROM_ACK);
44052 + if (err) {
44053 + ret = 1;
44054 + goto fail;
44056 + err = TLan_EeSendByte(io_base, ee_addr, TLAN_EEPROM_ACK);
44057 + if (err) {
44058 + ret = 2;
44059 + goto fail;
44061 + TLan_EeSendStart(io_base);
44062 + err = TLan_EeSendByte(io_base, 0xA1, TLAN_EEPROM_ACK);
44063 + if (err) {
44064 + ret = 3;
44065 + goto fail;
44067 + TLan_EeReceiveByte(io_base, data, TLAN_EEPROM_STOP);
44068 + fail:
44070 - return ack;
44071 + return ret;
44073 +} /* TLan_EeReadByte */
44075 -} /* TLan_HandleRxEOC */
44077 /*****************************************************************************
44078 ******************************************************************************
44080 - ThunderLAN Driver Timer Function
44081 + ThunderLAN Driver MII Routines
44083 + These routines are based on the information in Chap. 2 of the
44084 + "ThunderLAN Programmer's Guide", pp. 15-24.
44086 ******************************************************************************
44087 *****************************************************************************/
44090 /***************************************************************
44091 - * TLan_Timer
44092 + * TLan_MiiReadReg
44094 * Returns:
44095 - * Nothing
44096 + * 0 if ack received ok
44097 + * 1 otherwise.
44099 * Parms:
44100 - * data A value given to add timer when
44101 - * add_timer was called.
44102 + * dev The device structure containing
44103 + * The io address and interrupt count
44104 + * for this device.
44105 + * phy The address of the PHY to be queried.
44106 + * reg The register whose contents are to be
44107 + * retreived.
44108 + * val A pointer to a variable to store the
44109 + * retrieved value.
44111 - * This function handles timed functionality for the
44112 - * TLAN driver. The two current timer uses are for
44113 - * delaying for autonegotionation and driving the ACT LED.
44114 - * - Autonegotiation requires being allowed about
44115 - * 2 1/2 seconds before attempting to transmit a
44116 - * packet. It would be a very bad thing to hang
44117 - * the kernel this long, so the driver doesn't
44118 - * allow transmission 'til after this time, for
44119 - * certain PHYs. It would be much nicer if all
44120 - * PHYs were interrupt-capable like the internal
44121 - * PHY.
44122 - * - The ACT LED, which shows adapter activity, is
44123 - * driven by the driver, and so must be left on
44124 - * for a short period to power up the LED so it
44125 - * can be seen. This delay can be changed by
44126 - * changing the TLAN_TIMER_ACT_DELAY in tlan.h,
44127 - * if desired. 100 ms produces a slightly
44128 - * sluggish response.
44129 + * This function uses the TLAN's MII bus to retreive the contents
44130 + * of a given register on a PHY. It sends the appropriate info
44131 + * and then reads the 16-bit register value from the MII bus via
44132 + * the TLAN SIO register.
44134 **************************************************************/
44136 -void TLan_Timer( unsigned long data )
44137 +int TLan_MiiReadReg(struct nic *nic __unused, u16 phy, u16 reg, u16 * val)
44139 - struct net_device *dev = (struct net_device *) data;
44140 - TLanPrivateInfo *priv = dev->priv;
44141 - u32 elapsed;
44142 - unsigned long flags = 0;
44144 - priv->timer.function = NULL;
44146 - switch ( priv->timerType ) {
44147 -#ifdef MONITOR
44148 - case TLAN_TIMER_LINK_BEAT:
44149 - TLan_PhyMonitor( dev );
44150 - break;
44151 -#endif
44152 - case TLAN_TIMER_PHY_PDOWN:
44153 - TLan_PhyPowerDown( dev );
44154 - break;
44155 - case TLAN_TIMER_PHY_PUP:
44156 - TLan_PhyPowerUp( dev );
44157 - break;
44158 - case TLAN_TIMER_PHY_RESET:
44159 - TLan_PhyReset( dev );
44160 - break;
44161 - case TLAN_TIMER_PHY_START_LINK:
44162 - TLan_PhyStartLink( dev );
44163 - break;
44164 - case TLAN_TIMER_PHY_FINISH_AN:
44165 - TLan_PhyFinishAutoNeg( dev );
44166 - break;
44167 - case TLAN_TIMER_FINISH_RESET:
44168 - TLan_FinishReset( dev );
44169 - break;
44170 - case TLAN_TIMER_ACTIVITY:
44171 - spin_lock_irqsave(&priv->lock, flags);
44172 - if ( priv->timer.function == NULL ) {
44173 - elapsed = jiffies - priv->timerSetAt;
44174 - if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
44175 - TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
44176 - } else {
44177 - priv->timer.function = &TLan_Timer;
44178 - priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
44179 - spin_unlock_irqrestore(&priv->lock, flags);
44180 - add_timer( &priv->timer );
44181 - break;
44184 - spin_unlock_irqrestore(&priv->lock, flags);
44185 - break;
44186 - default:
44187 - break;
44188 + u8 nack;
44189 + u16 sio, tmp;
44190 + u32 i;
44191 + int err;
44192 + int minten;
44194 + err = FALSE;
44195 + outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
44196 + sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
44198 + TLan_MiiSync(BASE);
44200 + minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio);
44201 + if (minten)
44202 + TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
44204 + TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */
44205 + TLan_MiiSendData(BASE, 0x2, 2); /* Read ( 10b ) */
44206 + TLan_MiiSendData(BASE, phy, 5); /* Device # */
44207 + TLan_MiiSendData(BASE, reg, 5); /* Register # */
44210 + TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio); /* Change direction */
44212 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Clock Idle bit */
44213 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44214 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Wait 300ns */
44216 + nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio); /* Check for ACK */
44217 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio); /* Finish ACK */
44218 + if (nack) { /* No ACK, so fake it */
44219 + for (i = 0; i < 16; i++) {
44220 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
44221 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44223 + tmp = 0xffff;
44224 + err = TRUE;
44225 + } else { /* ACK, so read data */
44226 + for (tmp = 0, i = 0x8000; i; i >>= 1) {
44227 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
44228 + if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
44229 + tmp |= i;
44230 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44234 -} /* TLan_Timer */
44236 -/*****************************************************************************
44237 -******************************************************************************
44238 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */
44239 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44241 - ThunderLAN Driver Adapter Related Routines
44242 + if (minten)
44243 + TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
44245 -******************************************************************************
44246 -*****************************************************************************/
44247 + *val = tmp;
44249 + return err;
44251 +} /* TLan_MiiReadReg */
44253 /***************************************************************
44254 - * TLan_ResetLists
44255 - *
44256 + * TLan_MiiSendData
44258 * Returns:
44259 * Nothing
44260 * Parms:
44261 - * dev The device structure with the list
44262 - * stuctures to be reset.
44263 + * base_port The base IO port of the adapter in
44264 + * question.
44265 + * dev The address of the PHY to be queried.
44266 + * data The value to be placed on the MII bus.
44267 + * num_bits The number of bits in data that are to
44268 + * be placed on the MII bus.
44270 - * This routine sets the variables associated with managing
44271 - * the TLAN lists to their initial values.
44272 + * This function sends on sequence of bits on the MII
44273 + * configuration bus.
44275 **************************************************************/
44277 -void TLan_ResetLists( struct net_device *dev )
44278 +void TLan_MiiSendData(u16 base_port, u32 data, unsigned num_bits)
44280 - TLanPrivateInfo *priv = dev->priv;
44281 - int i;
44282 - TLanList *list;
44283 - struct sk_buff *skb;
44284 - void *t = NULL;
44285 + u16 sio;
44286 + u32 i;
44288 - priv->txHead = 0;
44289 - priv->txTail = 0;
44290 - for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
44291 - list = priv->txList + i;
44292 - list->cStat = TLAN_CSTAT_UNUSED;
44293 - if ( bbuf ) {
44294 - list->buffer[0].address = virt_to_bus( priv->txBuffer + ( i * TLAN_MAX_FRAME_SIZE ) );
44295 - } else {
44296 - list->buffer[0].address = 0;
44298 - list->buffer[2].count = 0;
44299 - list->buffer[2].address = 0;
44300 - list->buffer[9].address = 0;
44302 + if (num_bits == 0)
44303 + return;
44305 + outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
44306 + sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
44307 + TLan_SetBit(TLAN_NET_SIO_MTXEN, sio);
44309 - priv->rxHead = 0;
44310 - priv->rxTail = TLAN_NUM_RX_LISTS - 1;
44311 - for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
44312 - list = priv->rxList + i;
44313 - list->cStat = TLAN_CSTAT_READY;
44314 - list->frameSize = TLAN_MAX_FRAME_SIZE;
44315 - list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
44316 - if ( bbuf ) {
44317 - list->buffer[0].address = virt_to_bus( priv->rxBuffer + ( i * TLAN_MAX_FRAME_SIZE ) );
44318 - } else {
44319 - skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
44320 - if ( skb == NULL ) {
44321 - printk( "TLAN: Couldn't allocate memory for received data.\n" );
44322 - /* If this ever happened it would be a problem */
44323 - } else {
44324 - skb->dev = dev;
44325 - skb_reserve( skb, 2 );
44326 - t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE );
44328 - list->buffer[0].address = virt_to_bus( t );
44329 - list->buffer[8].address = (u32) t;
44330 - list->buffer[9].address = (u32) skb;
44332 - list->buffer[1].count = 0;
44333 - list->buffer[1].address = 0;
44334 - if ( i < TLAN_NUM_RX_LISTS - 1 )
44335 - list->forward = virt_to_bus( list + 1 );
44336 + for (i = (0x1 << (num_bits - 1)); i; i >>= 1) {
44337 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
44338 + (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio);
44339 + if (data & i)
44340 + TLan_SetBit(TLAN_NET_SIO_MDATA, sio);
44341 else
44342 - list->forward = 0;
44343 + TLan_ClearBit(TLAN_NET_SIO_MDATA, sio);
44344 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44345 + (void) TLan_GetBit(TLAN_NET_SIO_MCLK, sio);
44348 -} /* TLan_ResetLists */
44349 +} /* TLan_MiiSendData */
44351 -void TLan_FreeLists( struct net_device *dev )
44353 - TLanPrivateInfo *priv = dev->priv;
44354 - int i;
44355 - TLanList *list;
44356 - struct sk_buff *skb;
44358 - if ( ! bbuf ) {
44359 - for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
44360 - list = priv->txList + i;
44361 - skb = (struct sk_buff *) list->buffer[9].address;
44362 - if ( skb ) {
44363 - dev_kfree_skb_any( skb );
44364 - list->buffer[9].address = 0;
44368 - for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
44369 - list = priv->rxList + i;
44370 - skb = (struct sk_buff *) list->buffer[9].address;
44371 - if ( skb ) {
44372 - dev_kfree_skb_any( skb );
44373 - list->buffer[9].address = 0;
44378 -} /* TLan_FreeLists */
44380 /***************************************************************
44381 - * TLan_PrintDio
44382 - *
44383 + * TLan_MiiSync
44385 * Returns:
44386 * Nothing
44387 * Parms:
44388 - * io_base Base IO port of the device of
44389 - * which to print DIO registers.
44390 + * base_port The base IO port of the adapter in
44391 + * question.
44393 - * This function prints out all the internal (DIO)
44394 - * registers of a TLAN chip.
44395 + * This functions syncs all PHYs in terms of the MII configuration
44396 + * bus.
44398 **************************************************************/
44400 -void TLan_PrintDio( u16 io_base )
44401 +void TLan_MiiSync(u16 base_port)
44403 - u32 data0, data1;
44404 - int i;
44405 + int i;
44406 + u16 sio;
44408 - printk( "TLAN: Contents of internal registers for io base 0x%04hx.\n", io_base );
44409 - printk( "TLAN: Off. +0 +4\n" );
44410 - for ( i = 0; i < 0x4C; i+= 8 ) {
44411 - data0 = TLan_DioRead32( io_base, i );
44412 - data1 = TLan_DioRead32( io_base, i + 0x4 );
44413 - printk( "TLAN: 0x%02x 0x%08x 0x%08x\n", i, data0, data1 );
44414 + outw(TLAN_NET_SIO, base_port + TLAN_DIO_ADR);
44415 + sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
44417 + TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);
44418 + for (i = 0; i < 32; i++) {
44419 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
44420 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44423 -} /* TLan_PrintDio */
44424 +} /* TLan_MiiSync */
44429 /***************************************************************
44430 - * TLan_PrintList
44431 - *
44432 + * TLan_MiiWriteReg
44434 * Returns:
44435 * Nothing
44436 * Parms:
44437 - * list A pointer to the TLanList structure to
44438 - * be printed.
44439 - * type A string to designate type of list,
44440 - * "Rx" or "Tx".
44441 - * num The index of the list.
44442 + * dev The device structure for the device
44443 + * to write to.
44444 + * phy The address of the PHY to be written to.
44445 + * reg The register whose contents are to be
44446 + * written.
44447 + * val The value to be written to the register.
44449 - * This function prints out the contents of the list
44450 - * pointed to by the list parameter.
44451 + * This function uses the TLAN's MII bus to write the contents of a
44452 + * given register on a PHY. It sends the appropriate info and then
44453 + * writes the 16-bit register value from the MII configuration bus
44454 + * via the TLAN SIO register.
44456 **************************************************************/
44458 -void TLan_PrintList( TLanList *list, char *type, int num)
44459 +void TLan_MiiWriteReg(struct nic *nic __unused, u16 phy, u16 reg, u16 val)
44461 - int i;
44462 + u16 sio;
44463 + int minten;
44465 + outw(TLAN_NET_SIO, BASE + TLAN_DIO_ADR);
44466 + sio = BASE + TLAN_DIO_DATA + TLAN_NET_SIO;
44468 + TLan_MiiSync(BASE);
44470 + minten = TLan_GetBit(TLAN_NET_SIO_MINTEN, sio);
44471 + if (minten)
44472 + TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
44474 + TLan_MiiSendData(BASE, 0x1, 2); /* Start ( 01b ) */
44475 + TLan_MiiSendData(BASE, 0x1, 2); /* Write ( 01b ) */
44476 + TLan_MiiSendData(BASE, phy, 5); /* Device # */
44477 + TLan_MiiSendData(BASE, reg, 5); /* Register # */
44479 + TLan_MiiSendData(BASE, 0x2, 2); /* Send ACK */
44480 + TLan_MiiSendData(BASE, val, 16); /* Send Data */
44482 + TLan_ClearBit(TLAN_NET_SIO_MCLK, sio); /* Idle cycle */
44483 + TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
44485 + if (minten)
44486 + TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
44488 - printk( "TLAN: %s List %d at 0x%08x\n", type, num, (u32) list );
44489 - printk( "TLAN: Forward = 0x%08x\n", list->forward );
44490 - printk( "TLAN: CSTAT = 0x%04hx\n", list->cStat );
44491 - printk( "TLAN: Frame Size = 0x%04hx\n", list->frameSize );
44492 - /* for ( i = 0; i < 10; i++ ) { */
44493 - for ( i = 0; i < 2; i++ ) {
44494 - printk( "TLAN: Buffer[%d].count, addr = 0x%08x, 0x%08x\n", i, list->buffer[i].count, list->buffer[i].address );
44497 -} /* TLan_PrintList */
44498 +} /* TLan_MiiWriteReg */
44500 /***************************************************************
44501 - * TLan_ReadAndClearStats
44502 + * TLan_SetMac
44504 * Returns:
44505 * Nothing
44506 * Parms:
44507 * dev Pointer to device structure of adapter
44508 - * to which to read stats.
44509 - * record Flag indicating whether to add
44510 + * on which to change the AREG.
44511 + * areg The AREG to set the address in (0 - 3).
44512 + * mac A pointer to an array of chars. Each
44513 + * element stores one byte of the address.
44514 + * IE, it isn't in ascii.
44516 - * This functions reads all the internal status registers
44517 - * of the TLAN chip, which clears them as a side effect.
44518 - * It then either adds the values to the device's status
44519 - * struct, or discards them, depending on whether record
44520 - * is TLAN_RECORD (!=0) or TLAN_IGNORE (==0).
44521 + * This function transfers a MAC address to one of the
44522 + * TLAN AREGs (address registers). The TLAN chip locks
44523 + * the register on writing to offset 0 and unlocks the
44524 + * register after writing to offset 5. If NULL is passed
44525 + * in mac, then the AREG is filled with 0's.
44527 **************************************************************/
44529 -void TLan_ReadAndClearStats( struct net_device *dev, int record )
44530 +void TLan_SetMac(struct nic *nic __unused, int areg, char *mac)
44532 - TLanPrivateInfo *priv = dev->priv;
44533 - u32 tx_good, tx_under;
44534 - u32 rx_good, rx_over;
44535 - u32 def_tx, crc, code;
44536 - u32 multi_col, single_col;
44537 - u32 excess_col, late_col, loss;
44539 - outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR );
44540 - tx_good = inb( dev->base_addr + TLAN_DIO_DATA );
44541 - tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
44542 - tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
44543 - tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
44545 - outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR );
44546 - rx_good = inb( dev->base_addr + TLAN_DIO_DATA );
44547 - rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
44548 - rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
44549 - rx_over = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
44551 - outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR );
44552 - def_tx = inb( dev->base_addr + TLAN_DIO_DATA );
44553 - def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
44554 - crc = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
44555 - code = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
44557 - outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
44558 - multi_col = inb( dev->base_addr + TLAN_DIO_DATA );
44559 - multi_col += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
44560 - single_col = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
44561 - single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8;
44563 - outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
44564 - excess_col = inb( dev->base_addr + TLAN_DIO_DATA );
44565 - late_col = inb( dev->base_addr + TLAN_DIO_DATA + 1 );
44566 - loss = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
44568 - if ( record ) {
44569 - priv->stats.rx_packets += rx_good;
44570 - priv->stats.rx_errors += rx_over + crc + code;
44571 - priv->stats.tx_packets += tx_good;
44572 - priv->stats.tx_errors += tx_under + loss;
44573 - priv->stats.collisions += multi_col + single_col + excess_col + late_col;
44575 - priv->stats.rx_over_errors += rx_over;
44576 - priv->stats.rx_crc_errors += crc;
44577 - priv->stats.rx_frame_errors += code;
44578 + int i;
44580 - priv->stats.tx_aborted_errors += tx_under;
44581 - priv->stats.tx_carrier_errors += loss;
44582 + areg *= 6;
44584 + if (mac != NULL) {
44585 + for (i = 0; i < 6; i++)
44586 + TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i,
44587 + mac[i]);
44588 + } else {
44589 + for (i = 0; i < 6; i++)
44590 + TLan_DioWrite8(BASE, TLAN_AREG_0 + areg + i, 0);
44593 -} /* TLan_ReadAndClearStats */
44595 - /***************************************************************
44596 - * TLan_Reset
44597 +} /* TLan_SetMac */
44599 + /*********************************************************************
44600 + * TLan_PhyDetect
44602 * Returns:
44603 - * 0
44604 + * Nothing
44605 * Parms:
44606 - * dev Pointer to device structure of adapter
44607 - * to be reset.
44608 + * dev A pointer to the device structure of the adapter
44609 + * for which the PHY needs determined.
44611 - * This function resets the adapter and it's physical
44612 - * device. See Chap. 3, pp. 9-10 of the "ThunderLAN
44613 - * Programmer's Guide" for details. The routine tries to
44614 - * implement what is detailed there, though adjustments
44615 - * have been made.
44616 + * So far I've found that adapters which have external PHYs
44617 + * may also use the internal PHY for part of the functionality.
44618 + * (eg, AUI/Thinnet). This function finds out if this TLAN
44619 + * chip has an internal PHY, and then finds the first external
44620 + * PHY (starting from address 0) if it exists).
44622 - **************************************************************/
44623 + ********************************************************************/
44625 -void
44626 -TLan_ResetAdapter( struct net_device *dev )
44627 +void TLan_PhyDetect(struct nic *nic)
44629 - TLanPrivateInfo *priv = dev->priv;
44630 - int i;
44631 - u32 addr;
44632 - u32 data;
44633 - u8 data8;
44634 + u16 control;
44635 + u16 hi;
44636 + u16 lo;
44637 + u32 phy;
44639 - priv->tlanFullDuplex = FALSE;
44640 - priv->phyOnline=0;
44641 -/* 1. Assert reset bit. */
44642 + if (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_UNMANAGED_PHY) {
44643 + priv->phyNum = 0xFFFF;
44644 + return;
44647 - data = inl(dev->base_addr + TLAN_HOST_CMD);
44648 - data |= TLAN_HC_AD_RST;
44649 - outl(data, dev->base_addr + TLAN_HOST_CMD);
44651 - udelay(1000);
44652 + TLan_MiiReadReg(nic, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi);
44654 -/* 2. Turn off interrupts. ( Probably isn't necessary ) */
44655 + if (hi != 0xFFFF) {
44656 + priv->phy[0] = TLAN_PHY_MAX_ADDR;
44657 + } else {
44658 + priv->phy[0] = TLAN_PHY_NONE;
44661 - data = inl(dev->base_addr + TLAN_HOST_CMD);
44662 - data |= TLAN_HC_INT_OFF;
44663 - outl(data, dev->base_addr + TLAN_HOST_CMD);
44664 + priv->phy[1] = TLAN_PHY_NONE;
44665 + for (phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++) {
44666 + TLan_MiiReadReg(nic, phy, MII_GEN_CTL, &control);
44667 + TLan_MiiReadReg(nic, phy, MII_GEN_ID_HI, &hi);
44668 + TLan_MiiReadReg(nic, phy, MII_GEN_ID_LO, &lo);
44669 + if ((control != 0xFFFF) || (hi != 0xFFFF)
44670 + || (lo != 0xFFFF)) {
44671 + printf("PHY found at %hX %hX %hX %hX\n", phy,
44672 + control, hi, lo);
44673 + if ((priv->phy[1] == TLAN_PHY_NONE)
44674 + && (phy != TLAN_PHY_MAX_ADDR)) {
44675 + priv->phy[1] = phy;
44680 -/* 3. Clear AREGs and HASHs. */
44681 + if (priv->phy[1] != TLAN_PHY_NONE) {
44682 + priv->phyNum = 1;
44683 + } else if (priv->phy[0] != TLAN_PHY_NONE) {
44684 + priv->phyNum = 0;
44685 + } else {
44686 + printf
44687 + ("TLAN: Cannot initialize device, no PHY was found!\n");
44690 +} /* TLan_PhyDetect */
44692 - for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) {
44693 - TLan_DioWrite32( dev->base_addr, (u16) i, 0 );
44694 +void TLan_PhyPowerDown(struct nic *nic)
44697 + u16 value;
44698 + printf("%s: Powering down PHY(s).\n", priv->nic_name);
44699 + value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
44700 + TLan_MiiSync(BASE);
44701 + TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_GEN_CTL, value);
44702 + if ((priv->phyNum == 0) && (priv->phy[1] != TLAN_PHY_NONE)
44703 + &&
44704 + (!(tlan_pci_tbl[chip_idx].
44705 + flags & TLAN_ADAPTER_USE_INTERN_10))) {
44706 + TLan_MiiSync(BASE);
44707 + TLan_MiiWriteReg(nic, priv->phy[1], MII_GEN_CTL, value);
44710 -/* 4. Setup NetConfig register. */
44711 + /* Wait for 50 ms and powerup
44712 + * This is abitrary. It is intended to make sure the
44713 + * tranceiver settles.
44714 + */
44715 + /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP ); */
44716 + mdelay(50);
44717 + TLan_PhyPowerUp(nic);
44719 - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
44720 - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
44721 +} /* TLan_PhyPowerDown */
44723 -/* 5. Load Ld_Tmr and Ld_Thr in HOST_CMD. */
44725 - outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD );
44726 - outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD );
44727 +void TLan_PhyPowerUp(struct nic *nic)
44729 + u16 value;
44731 -/* 6. Unreset the MII by setting NMRST (in NetSio) to 1. */
44732 + printf("%s: Powering up PHY.\n", priv->nic_name);
44733 + TLan_MiiSync(BASE);
44734 + value = MII_GC_LOOPBK;
44735 + TLan_MiiWriteReg(nic, priv->phy[priv->phyNum], MII_GEN_CTL, value);
44736 + TLan_MiiSync(BASE);
44737 + /* Wait for 500 ms and reset the
44738 + * tranceiver. The TLAN docs say both 50 ms and
44739 + * 500 ms, so do the longer, just in case.
44740 + */
44741 + mdelay(500);
44742 + TLan_PhyReset(nic);
44743 + /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET ); */
44745 - outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR );
44746 - addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
44747 - TLan_SetBit( TLAN_NET_SIO_NMRST, addr );
44748 +} /* TLan_PhyPowerUp */
44750 -/* 7. Setup the remaining registers. */
44751 +void TLan_PhyReset(struct nic *nic)
44753 + u16 phy;
44754 + u16 value;
44756 - if ( priv->tlanRev >= 0x30 ) {
44757 - data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
44758 - TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 );
44759 + phy = priv->phy[priv->phyNum];
44761 + printf("%s: Reseting PHY.\n", priv->nic_name);
44762 + TLan_MiiSync(BASE);
44763 + value = MII_GC_LOOPBK | MII_GC_RESET;
44764 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, value);
44765 + TLan_MiiReadReg(nic, phy, MII_GEN_CTL, &value);
44766 + while (value & MII_GC_RESET) {
44767 + TLan_MiiReadReg(nic, phy, MII_GEN_CTL, &value);
44769 - TLan_PhyDetect( dev );
44770 - data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
44772 - if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) {
44773 - data |= TLAN_NET_CFG_BIT;
44774 - if ( priv->aui == 1 ) {
44775 - TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
44776 - } else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
44777 - TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
44779 + /* Wait for 500 ms and initialize.
44780 + * I don't remember why I wait this long.
44781 + * I've changed this to 50ms, as it seems long enough.
44782 + */
44783 + /* TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK ); */
44784 + mdelay(50);
44785 + TLan_PhyStartLink(nic);
44787 +} /* TLan_PhyReset */
44790 +void TLan_PhyStartLink(struct nic *nic)
44793 + u16 ability;
44794 + u16 control;
44795 + u16 data;
44796 + u16 phy;
44797 + u16 status;
44798 + u16 tctl;
44800 + phy = priv->phy[priv->phyNum];
44801 + printf("%s: Trying to activate link.\n", priv->nic_name);
44802 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &status);
44803 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &ability);
44805 + if ((status & MII_GS_AUTONEG) && (!priv->aui)) {
44806 + ability = status >> 11;
44807 + if (priv->speed == TLAN_SPEED_10 &&
44808 + priv->duplex == TLAN_DUPLEX_HALF) {
44809 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, 0x0000);
44810 + } else if (priv->speed == TLAN_SPEED_10 &&
44811 + priv->duplex == TLAN_DUPLEX_FULL) {
44812 + priv->tlanFullDuplex = TRUE;
44813 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, 0x0100);
44814 + } else if (priv->speed == TLAN_SPEED_100 &&
44815 + priv->duplex == TLAN_DUPLEX_HALF) {
44816 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, 0x2000);
44817 + } else if (priv->speed == TLAN_SPEED_100 &&
44818 + priv->duplex == TLAN_DUPLEX_FULL) {
44819 priv->tlanFullDuplex = TRUE;
44820 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, 0x2100);
44821 } else {
44822 - TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
44824 + /* Set Auto-Neg advertisement */
44825 + TLan_MiiWriteReg(nic, phy, MII_AN_ADV,
44826 + (ability << 5) | 1);
44827 + /* Enablee Auto-Neg */
44828 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, 0x1000);
44829 + /* Restart Auto-Neg */
44830 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, 0x1200);
44831 + /* Wait for 4 sec for autonegotiation
44832 + * to complete. The max spec time is less than this
44833 + * but the card need additional time to start AN.
44834 + * .5 sec should be plenty extra.
44835 + */
44836 + printf("TLAN: %s: Starting autonegotiation.\n",
44837 + priv->nic_name);
44838 + mdelay(4000);
44839 + TLan_PhyFinishAutoNeg(nic);
44840 + /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN ); */
44841 + return;
44845 - if ( priv->phyNum == 0 ) {
44846 - data |= TLAN_NET_CFG_PHY_EN;
44848 - TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
44850 - if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
44851 - TLan_FinishReset( dev );
44852 - } else {
44853 - TLan_PhyPowerDown( dev );
44854 + if ((priv->aui) && (priv->phyNum != 0)) {
44855 + priv->phyNum = 0;
44856 + data =
44857 + TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN |
44858 + TLAN_NET_CFG_PHY_EN;
44859 + TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data);
44860 + mdelay(50);
44861 + /* TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */
44862 + TLan_PhyPowerDown(nic);
44863 + return;
44864 + } else if (priv->phyNum == 0) {
44865 + control = 0;
44866 + TLan_MiiReadReg(nic, phy, TLAN_TLPHY_CTL, &tctl);
44867 + if (priv->aui) {
44868 + tctl |= TLAN_TC_AUISEL;
44869 + } else {
44870 + tctl &= ~TLAN_TC_AUISEL;
44871 + if (priv->duplex == TLAN_DUPLEX_FULL) {
44872 + control |= MII_GC_DUPLEX;
44873 + priv->tlanFullDuplex = TRUE;
44875 + if (priv->speed == TLAN_SPEED_100) {
44876 + control |= MII_GC_SPEEDSEL;
44879 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL, control);
44880 + TLan_MiiWriteReg(nic, phy, TLAN_TLPHY_CTL, tctl);
44883 -} /* TLan_ResetAdapter */
44884 + /* Wait for 2 sec to give the tranceiver time
44885 + * to establish link.
44886 + */
44887 + /* TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET ); */
44888 + mdelay(2000);
44889 + TLan_FinishReset(nic);
44891 +} /* TLan_PhyStartLink */
44893 -void
44894 -TLan_FinishReset( struct net_device *dev )
44895 +void TLan_PhyFinishAutoNeg(struct nic *nic)
44897 - TLanPrivateInfo *priv = dev->priv;
44898 - u8 data;
44899 - u32 phy;
44900 - u8 sio;
44901 - u16 status;
44902 - u16 partner;
44903 - u16 tlphy_ctl;
44904 - u16 tlphy_par;
44905 - u16 tlphy_id1, tlphy_id2;
44906 - int i;
44908 + u16 an_adv;
44909 + u16 an_lpa;
44910 + u16 data;
44911 + u16 mode;
44912 + u16 phy;
44913 + u16 status;
44915 phy = priv->phy[priv->phyNum];
44917 - data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
44918 - if ( priv->tlanFullDuplex ) {
44919 - data |= TLAN_NET_CMD_DUPLEX;
44920 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &status);
44921 + udelay(1000);
44922 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &status);
44924 + if (!(status & MII_GS_AUTOCMPLT)) {
44925 + /* Wait for 8 sec to give the process
44926 + * more time. Perhaps we should fail after a while.
44927 + */
44928 + if (!priv->neg_be_verbose++) {
44929 + printf
44930 + ("TLAN: Giving autonegotiation more time.\n");
44931 + printf
44932 + ("TLAN: Please check that your adapter has\n");
44933 + printf
44934 + ("TLAN: been properly connected to a HUB or Switch.\n");
44935 + printf
44936 + ("TLAN: Trying to establish link in the background...\n");
44938 + mdelay(8000);
44939 + TLan_PhyFinishAutoNeg(nic);
44940 + /* TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN ); */
44941 + return;
44943 - TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data );
44944 - data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5;
44945 - if ( priv->phyNum == 0 ) {
44946 - data |= TLAN_NET_MASK_MASK7;
44948 - TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data );
44949 - TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 );
44950 - TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
44951 - TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
44953 - if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
44954 - status = MII_GS_LINK;
44955 - printk( "TLAN: %s: Link forced.\n", dev->name );
44956 - } else {
44957 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
44958 - udelay( 1000 );
44959 - TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
44960 - if ( (status & MII_GS_LINK) && /* We only support link info on Nat.Sem. PHY's */
44961 - (tlphy_id1 == NAT_SEM_ID1) &&
44962 - (tlphy_id2 == NAT_SEM_ID2) ) {
44963 - TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
44964 - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par );
44966 - printk( "TLAN: %s: Link active with ", dev->name );
44967 - if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
44968 - printk( "forced 10%sMbps %s-Duplex\n",
44969 - tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
44970 - tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
44971 - } else {
44972 - printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
44973 - tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
44974 - tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
44975 - printk("TLAN: Partner capability: ");
44976 - for (i = 5; i <= 10; i++)
44977 - if (partner & (1<<i))
44978 - printk("%s", media[i-5]);
44979 - printk("\n");
44982 - TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
44983 -#ifdef MONITOR
44984 - /* We have link beat..for now anyway */
44985 - priv->link = 1;
44986 - /*Enabling link beat monitoring */
44987 - TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
44988 -#endif
44989 - } else if (status & MII_GS_LINK) {
44990 - printk( "TLAN: %s: Link active\n", dev->name );
44991 - TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
44993 + printf("TLAN: %s: Autonegotiation complete.\n", priv->nic_name);
44994 + TLan_MiiReadReg(nic, phy, MII_AN_ADV, &an_adv);
44995 + TLan_MiiReadReg(nic, phy, MII_AN_LPA, &an_lpa);
44996 + mode = an_adv & an_lpa & 0x03E0;
44997 + if (mode & 0x0100) {
44998 + printf("Full Duplex\n");
44999 + priv->tlanFullDuplex = TRUE;
45000 + } else if (!(mode & 0x0080) && (mode & 0x0040)) {
45001 + priv->tlanFullDuplex = TRUE;
45002 + printf("Full Duplex\n");
45005 - if ( priv->phyNum == 0 ) {
45006 - TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
45007 - tlphy_ctl |= TLAN_TC_INTEN;
45008 - TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl );
45009 - sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO );
45010 - sio |= TLAN_NET_SIO_MINTEN;
45011 - TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio );
45012 + if ((!(mode & 0x0180))
45013 + && (tlan_pci_tbl[chip_idx].flags & TLAN_ADAPTER_USE_INTERN_10)
45014 + && (priv->phyNum != 0)) {
45015 + priv->phyNum = 0;
45016 + data =
45017 + TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN |
45018 + TLAN_NET_CFG_PHY_EN;
45019 + TLan_DioWrite16(BASE, TLAN_NET_CONFIG, data);
45020 + /* TLan_SetTimer( nic, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN ); */
45021 + mdelay(400);
45022 + TLan_PhyPowerDown(nic);
45023 + return;
45026 - if ( status & MII_GS_LINK ) {
45027 - TLan_SetMac( dev, 0, dev->dev_addr );
45028 - priv->phyOnline = 1;
45029 - outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
45030 - if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
45031 - outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
45032 + if (priv->phyNum == 0) {
45033 + if ((priv->duplex == TLAN_DUPLEX_FULL)
45034 + || (an_adv & an_lpa & 0x0040)) {
45035 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL,
45036 + MII_GC_AUTOENB | MII_GC_DUPLEX);
45037 + printf
45038 + ("TLAN: Starting internal PHY with FULL-DUPLEX\n");
45039 + } else {
45040 + TLan_MiiWriteReg(nic, phy, MII_GEN_CTL,
45041 + MII_GC_AUTOENB);
45042 + printf
45043 + ("TLAN: Starting internal PHY with HALF-DUPLEX\n");
45045 - outl( virt_to_bus( priv->rxList ), dev->base_addr + TLAN_CH_PARM );
45046 - outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
45047 - } else {
45048 - printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
45049 - TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
45050 - return;
45053 -} /* TLan_FinishReset */
45054 + /* Wait for 100 ms. No reason in partiticular.
45055 + */
45056 + /* TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET ); */
45057 + mdelay(100);
45058 + TLan_FinishReset(nic);
45060 - /***************************************************************
45061 - * TLan_SetMac
45063 - * Returns:
45064 - * Nothing
45065 - * Parms:
45066 - * dev Pointer to device structure of adapter
45067 - * on which to change the AREG.
45068 - * areg The AREG to set the address in (0 - 3).
45069 - * mac A pointer to an array of chars. Each
45070 - * element stores one byte of the address.
45071 - * IE, it isn't in ascii.
45073 - * This function transfers a MAC address to one of the
45074 - * TLAN AREGs (address registers). The TLAN chip locks
45075 - * the register on writing to offset 0 and unlocks the
45076 - * register after writing to offset 5. If NULL is passed
45077 - * in mac, then the AREG is filled with 0's.
45079 - **************************************************************/
45080 +} /* TLan_PhyFinishAutoNeg */
45082 +#ifdef MONITOR
45084 + /*********************************************************************
45086 + * TLan_phyMonitor
45088 + * Returns:
45089 + * None
45091 + * Params:
45092 + * dev The device structure of this device.
45095 + * This function monitors PHY condition by reading the status
45096 + * register via the MII bus. This can be used to give info
45097 + * about link changes (up/down), and possible switch to alternate
45098 + * media.
45100 + * ******************************************************************/
45102 -void TLan_SetMac( struct net_device *dev, int areg, char *mac )
45103 +void TLan_PhyMonitor(struct net_device *dev)
45105 - int i;
45107 - areg *= 6;
45108 + TLanPrivateInfo *priv = dev->priv;
45109 + u16 phy;
45110 + u16 phy_status;
45112 - if ( mac != NULL ) {
45113 - for ( i = 0; i < 6; i++ )
45114 - TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, mac[i] );
45115 - } else {
45116 - for ( i = 0; i < 6; i++ )
45117 - TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, 0 );
45118 + phy = priv->phy[priv->phyNum];
45120 + /* Get PHY status register */
45121 + TLan_MiiReadReg(nic, phy, MII_GEN_STS, &phy_status);
45123 + /* Check if link has been lost */
45124 + if (!(phy_status & MII_GS_LINK)) {
45125 + if (priv->link) {
45126 + priv->link = 0;
45127 + printf("TLAN: %s has lost link\n", priv->nic_name);
45128 + priv->flags &= ~IFF_RUNNING;
45129 + mdelay(2000);
45130 + TLan_PhyMonitor(nic);
45131 + /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */
45132 + return;
45136 -} /* TLan_SetMac */
45137 + /* Link restablished? */
45138 + if ((phy_status & MII_GS_LINK) && !priv->link) {
45139 + priv->link = 1;
45140 + printf("TLAN: %s has reestablished link\n",
45141 + priv->nic_name);
45142 + priv->flags |= IFF_RUNNING;
45145 + /* Setup a new monitor */
45146 + /* TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT ); */
45147 + mdelay(2000);
45148 + TLan_PhyMonitor(nic);
45151 +#endif /* MONITOR */
45153 +#ifdef EB51
45154 +static struct pci_id tlan_nics[] = {
45155 + PCI_ROM(0x0e11, 0xae34, "netel10", "Compaq Netelligent 10 T PCI UTP"),
45156 + PCI_ROM(0x0e11, 0xae32, "netel100","Compaq Netelligent 10/100 TX PCI UTP"),
45157 + PCI_ROM(0x0e11, 0xae35, "netflex3i", "Compaq Integrated NetFlex-3/P"),
45158 + PCI_ROM(0x0e11, 0xf130, "thunder", "Compaq NetFlex-3/P"),
45159 + PCI_ROM(0x0e11, 0xf150, "netflex3b", "Compaq NetFlex-3/P"),
45160 + PCI_ROM(0x0e11, 0xae43, "netel100pi", "Compaq Netelligent Integrated 10/100 TX UTP"),
45161 + PCI_ROM(0x0e11, 0xae40, "netel100d", "Compaq Netelligent Dual 10/100 TX PCI UTP"),
45162 + PCI_ROM(0x0e11, 0xb011, "netel100i", "Compaq Netelligent 10/100 TX Embedded UTP"),
45163 + PCI_ROM(0x108d, 0x0013, "oc2183", "Olicom OC-2183/2185"),
45164 + PCI_ROM(0x108d, 0x0012, "oc2325", "Olicom OC-2325"),
45165 + PCI_ROM(0x108d, 0x0014, "oc2326", "Olicom OC-2326"),
45166 + PCI_ROM(0x0e11, 0xb030, "netelligent_10_100_ws_5100", "Compaq Netelligent 10/100 TX UTP"),
45167 + PCI_ROM(0x0e11, 0xb012, "netelligent_10_t2", "Compaq Netelligent 10 T/2 PCI UTP/Coax"),
45170 +struct pci_driver tlan_driver = {
45171 + .type = NIC_DRIVER,
45172 + .name = "TLAN/PCI",
45173 + .probe = tlan_probe,
45174 + .ids = tlan_nics,
45175 + .id_count = sizeof(tlan_nics) / sizeof(tlan_nics[0]),
45176 + .class = 0,
45178 #endif
45179 Index: b/netboot/tlan.h
45180 ===================================================================
45181 --- /dev/null
45182 +++ b/netboot/tlan.h
45183 @@ -0,0 +1,536 @@
45184 +/**************************************************************************
45186 +* tlan.c -- Etherboot device driver for the Texas Instruments ThunderLAN
45187 +* Written 2003-2003 by Timothy Legge <tlegge@rogers.com>
45189 +* This program is free software; you can redistribute it and/or modify
45190 +* it under the terms of the GNU General Public License as published by
45191 +* the Free Software Foundation; either version 2 of the License, or
45192 +* (at your option) any later version.
45194 +* This program is distributed in the hope that it will be useful,
45195 +* but WITHOUT ANY WARRANTY; without even the implied warranty of
45196 +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45197 +* GNU General Public License for more details.
45199 +* You should have received a copy of the GNU General Public License
45200 +* along with this program; if not, write to the Free Software
45201 +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45203 +* Portions of this code (almost all) based on:
45204 +* tlan.c: Linux ThunderLan Driver:
45206 +* by James Banks
45208 +* (C) 1997-1998 Caldera, Inc.
45209 +* (C) 1998 James Banks
45210 +* (C) 1999-2001 Torben Mathiasen
45211 +* (C) 2002 Samuel Chessman
45213 +* REVISION HISTORY:
45214 +* ================
45215 +* v1.0 07-08-2003 timlegge Initial not quite working version
45217 +* Indent Style: indent -kr -i8
45218 +***************************************************************************/
45221 +#include <asm/io.h>
45222 +#include <asm/types.h>
45223 +#include <linux/netdevice.h>
45226 +typedef unsigned char u8;
45227 +typedef signed char s8;
45228 +typedef unsigned short u16;
45229 +typedef signed short s16;
45230 +typedef unsigned int u32;
45231 +typedef signed int s32;
45232 + /*****************************************************************
45233 + * TLan Definitions
45235 + ****************************************************************/
45237 +#define FALSE 0
45238 +#define TRUE 1
45240 +#define TLAN_MIN_FRAME_SIZE 64
45241 +#define TLAN_MAX_FRAME_SIZE 1600
45243 +#define TLAN_NUM_RX_LISTS 4
45244 +#define TLAN_NUM_TX_LISTS 2
45246 +#define TLAN_IGNORE 0
45247 +#define TLAN_RECORD 1
45249 +#define TLAN_DBG(lvl, format, args...) if (debug&lvl) printf("TLAN: " format, ##args );
45251 +#define TLAN_DEBUG_GNRL 0x0001
45252 +#define TLAN_DEBUG_TX 0x0002
45253 +#define TLAN_DEBUG_RX 0x0004
45254 +#define TLAN_DEBUG_LIST 0x0008
45255 +#define TLAN_DEBUG_PROBE 0x0010
45257 +#define TX_TIMEOUT (10*HZ) /* We need time for auto-neg */
45258 +#define MAX_TLAN_BOARDS 8 /* Max number of boards installed at a time */
45261 + /*****************************************************************
45262 + * Device Identification Definitions
45264 + ****************************************************************/
45266 +#define PCI_DEVICE_ID_NETELLIGENT_10_T2 0xB012
45267 +#define PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100 0xB030
45268 +#ifndef PCI_DEVICE_ID_OLICOM_OC2183
45269 +#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
45270 +#endif
45271 +#ifndef PCI_DEVICE_ID_OLICOM_OC2325
45272 +#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
45273 +#endif
45274 +#ifndef PCI_DEVICE_ID_OLICOM_OC2326
45275 +#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
45276 +#endif
45278 +typedef struct tlan_adapter_entry {
45279 + u16 vendorId;
45280 + u16 deviceId;
45281 + char *deviceLabel;
45282 + u32 flags;
45283 + u16 addrOfs;
45284 +} TLanAdapterEntry;
45286 +#define TLAN_ADAPTER_NONE 0x00000000
45287 +#define TLAN_ADAPTER_UNMANAGED_PHY 0x00000001
45288 +#define TLAN_ADAPTER_BIT_RATE_PHY 0x00000002
45289 +#define TLAN_ADAPTER_USE_INTERN_10 0x00000004
45290 +#define TLAN_ADAPTER_ACTIVITY_LED 0x00000008
45292 +#define TLAN_SPEED_DEFAULT 0
45293 +#define TLAN_SPEED_10 10
45294 +#define TLAN_SPEED_100 100
45296 +#define TLAN_DUPLEX_DEFAULT 0
45297 +#define TLAN_DUPLEX_HALF 1
45298 +#define TLAN_DUPLEX_FULL 2
45302 + /*****************************************************************
45303 + * EISA Definitions
45305 + ****************************************************************/
45307 +#define EISA_ID 0xc80 /* EISA ID Registers */
45308 +#define EISA_ID0 0xc80 /* EISA ID Register 0 */
45309 +#define EISA_ID1 0xc81 /* EISA ID Register 1 */
45310 +#define EISA_ID2 0xc82 /* EISA ID Register 2 */
45311 +#define EISA_ID3 0xc83 /* EISA ID Register 3 */
45312 +#define EISA_CR 0xc84 /* EISA Control Register */
45313 +#define EISA_REG0 0xc88 /* EISA Configuration Register 0 */
45314 +#define EISA_REG1 0xc89 /* EISA Configuration Register 1 */
45315 +#define EISA_REG2 0xc8a /* EISA Configuration Register 2 */
45316 +#define EISA_REG3 0xc8f /* EISA Configuration Register 3 */
45317 +#define EISA_APROM 0xc90 /* Ethernet Address PROM */
45321 + /*****************************************************************
45322 + * Rx/Tx List Definitions
45324 + ****************************************************************/
45326 +#define TLAN_BUFFERS_PER_LIST 10
45327 +#define TLAN_LAST_BUFFER 0x80000000
45328 +#define TLAN_CSTAT_UNUSED 0x8000
45329 +#define TLAN_CSTAT_FRM_CMP 0x4000
45330 +#define TLAN_CSTAT_READY 0x3000
45331 +#define TLAN_CSTAT_EOC 0x0800
45332 +#define TLAN_CSTAT_RX_ERROR 0x0400
45333 +#define TLAN_CSTAT_PASS_CRC 0x0200
45334 +#define TLAN_CSTAT_DP_PR 0x0100
45341 + /*****************************************************************
45342 + * PHY definitions
45344 + ****************************************************************/
45346 +#define TLAN_PHY_MAX_ADDR 0x1F
45347 +#define TLAN_PHY_NONE 0x20
45351 + /*****************************************************************
45352 + * TLan Driver Timer Definitions
45354 + ****************************************************************/
45356 +#define TLAN_TIMER_LINK_BEAT 1
45357 +#define TLAN_TIMER_ACTIVITY 2
45358 +#define TLAN_TIMER_PHY_PDOWN 3
45359 +#define TLAN_TIMER_PHY_PUP 4
45360 +#define TLAN_TIMER_PHY_RESET 5
45361 +#define TLAN_TIMER_PHY_START_LINK 6
45362 +#define TLAN_TIMER_PHY_FINISH_AN 7
45363 +#define TLAN_TIMER_FINISH_RESET 8
45365 +#define TLAN_TIMER_ACT_DELAY (HZ/10)
45370 + /*****************************************************************
45371 + * TLan Driver Eeprom Definitions
45373 + ****************************************************************/
45375 +#define TLAN_EEPROM_ACK 0
45376 +#define TLAN_EEPROM_STOP 1
45381 + /*****************************************************************
45382 + * Host Register Offsets and Contents
45384 + ****************************************************************/
45386 +#define TLAN_HOST_CMD 0x00
45387 +#define TLAN_HC_GO 0x80000000
45388 +#define TLAN_HC_STOP 0x40000000
45389 +#define TLAN_HC_ACK 0x20000000
45390 +#define TLAN_HC_CS_MASK 0x1FE00000
45391 +#define TLAN_HC_EOC 0x00100000
45392 +#define TLAN_HC_RT 0x00080000
45393 +#define TLAN_HC_NES 0x00040000
45394 +#define TLAN_HC_AD_RST 0x00008000
45395 +#define TLAN_HC_LD_TMR 0x00004000
45396 +#define TLAN_HC_LD_THR 0x00002000
45397 +#define TLAN_HC_REQ_INT 0x00001000
45398 +#define TLAN_HC_INT_OFF 0x00000800
45399 +#define TLAN_HC_INT_ON 0x00000400
45400 +#define TLAN_HC_AC_MASK 0x000000FF
45401 +#define TLAN_CH_PARM 0x04
45402 +#define TLAN_DIO_ADR 0x08
45403 +#define TLAN_DA_ADR_INC 0x8000
45404 +#define TLAN_DA_RAM_ADR 0x4000
45405 +#define TLAN_HOST_INT 0x0A
45406 +#define TLAN_HI_IV_MASK 0x1FE0
45407 +#define TLAN_HI_IT_MASK 0x001C
45408 +#define TLAN_DIO_DATA 0x0C
45411 +/* ThunderLAN Internal Register DIO Offsets */
45413 +#define TLAN_NET_CMD 0x00
45414 +#define TLAN_NET_CMD_NRESET 0x80
45415 +#define TLAN_NET_CMD_NWRAP 0x40
45416 +#define TLAN_NET_CMD_CSF 0x20
45417 +#define TLAN_NET_CMD_CAF 0x10
45418 +#define TLAN_NET_CMD_NOBRX 0x08
45419 +#define TLAN_NET_CMD_DUPLEX 0x04
45420 +#define TLAN_NET_CMD_TRFRAM 0x02
45421 +#define TLAN_NET_CMD_TXPACE 0x01
45422 +#define TLAN_NET_SIO 0x01
45423 +#define TLAN_NET_SIO_MINTEN 0x80
45424 +#define TLAN_NET_SIO_ECLOK 0x40
45425 +#define TLAN_NET_SIO_ETXEN 0x20
45426 +#define TLAN_NET_SIO_EDATA 0x10
45427 +#define TLAN_NET_SIO_NMRST 0x08
45428 +#define TLAN_NET_SIO_MCLK 0x04
45429 +#define TLAN_NET_SIO_MTXEN 0x02
45430 +#define TLAN_NET_SIO_MDATA 0x01
45431 +#define TLAN_NET_STS 0x02
45432 +#define TLAN_NET_STS_MIRQ 0x80
45433 +#define TLAN_NET_STS_HBEAT 0x40
45434 +#define TLAN_NET_STS_TXSTOP 0x20
45435 +#define TLAN_NET_STS_RXSTOP 0x10
45436 +#define TLAN_NET_STS_RSRVD 0x0F
45437 +#define TLAN_NET_MASK 0x03
45438 +#define TLAN_NET_MASK_MASK7 0x80
45439 +#define TLAN_NET_MASK_MASK6 0x40
45440 +#define TLAN_NET_MASK_MASK5 0x20
45441 +#define TLAN_NET_MASK_MASK4 0x10
45442 +#define TLAN_NET_MASK_RSRVD 0x0F
45443 +#define TLAN_NET_CONFIG 0x04
45444 +#define TLAN_NET_CFG_RCLK 0x8000
45445 +#define TLAN_NET_CFG_TCLK 0x4000
45446 +#define TLAN_NET_CFG_BIT 0x2000
45447 +#define TLAN_NET_CFG_RXCRC 0x1000
45448 +#define TLAN_NET_CFG_PEF 0x0800
45449 +#define TLAN_NET_CFG_1FRAG 0x0400
45450 +#define TLAN_NET_CFG_1CHAN 0x0200
45451 +#define TLAN_NET_CFG_MTEST 0x0100
45452 +#define TLAN_NET_CFG_PHY_EN 0x0080
45453 +#define TLAN_NET_CFG_MSMASK 0x007F
45454 +#define TLAN_MAN_TEST 0x06
45455 +#define TLAN_DEF_VENDOR_ID 0x08
45456 +#define TLAN_DEF_DEVICE_ID 0x0A
45457 +#define TLAN_DEF_REVISION 0x0C
45458 +#define TLAN_DEF_SUBCLASS 0x0D
45459 +#define TLAN_DEF_MIN_LAT 0x0E
45460 +#define TLAN_DEF_MAX_LAT 0x0F
45461 +#define TLAN_AREG_0 0x10
45462 +#define TLAN_AREG_1 0x16
45463 +#define TLAN_AREG_2 0x1C
45464 +#define TLAN_AREG_3 0x22
45465 +#define TLAN_HASH_1 0x28
45466 +#define TLAN_HASH_2 0x2C
45467 +#define TLAN_GOOD_TX_FRMS 0x30
45468 +#define TLAN_TX_UNDERUNS 0x33
45469 +#define TLAN_GOOD_RX_FRMS 0x34
45470 +#define TLAN_RX_OVERRUNS 0x37
45471 +#define TLAN_DEFERRED_TX 0x38
45472 +#define TLAN_CRC_ERRORS 0x3A
45473 +#define TLAN_CODE_ERRORS 0x3B
45474 +#define TLAN_MULTICOL_FRMS 0x3C
45475 +#define TLAN_SINGLECOL_FRMS 0x3E
45476 +#define TLAN_EXCESSCOL_FRMS 0x40
45477 +#define TLAN_LATE_COLS 0x41
45478 +#define TLAN_CARRIER_LOSS 0x42
45479 +#define TLAN_ACOMMIT 0x43
45480 +#define TLAN_LED_REG 0x44
45481 +#define TLAN_LED_ACT 0x10
45482 +#define TLAN_LED_LINK 0x01
45483 +#define TLAN_BSIZE_REG 0x45
45484 +#define TLAN_MAX_RX 0x46
45485 +#define TLAN_INT_DIS 0x48
45486 +#define TLAN_ID_TX_EOC 0x04
45487 +#define TLAN_ID_RX_EOF 0x02
45488 +#define TLAN_ID_RX_EOC 0x01
45492 +/* ThunderLAN Interrupt Codes */
45494 +#define TLAN_INT_NUMBER_OF_INTS 8
45496 +#define TLAN_INT_NONE 0x0000
45497 +#define TLAN_INT_TX_EOF 0x0001
45498 +#define TLAN_INT_STAT_OVERFLOW 0x0002
45499 +#define TLAN_INT_RX_EOF 0x0003
45500 +#define TLAN_INT_DUMMY 0x0004
45501 +#define TLAN_INT_TX_EOC 0x0005
45502 +#define TLAN_INT_STATUS_CHECK 0x0006
45503 +#define TLAN_INT_RX_EOC 0x0007
45507 +/* ThunderLAN MII Registers */
45509 +/* Generic MII/PHY Registers */
45511 +#define MII_GEN_CTL 0x00
45512 +#define MII_GC_RESET 0x8000
45513 +#define MII_GC_LOOPBK 0x4000
45514 +#define MII_GC_SPEEDSEL 0x2000
45515 +#define MII_GC_AUTOENB 0x1000
45516 +#define MII_GC_PDOWN 0x0800
45517 +#define MII_GC_ISOLATE 0x0400
45518 +#define MII_GC_AUTORSRT 0x0200
45519 +#define MII_GC_DUPLEX 0x0100
45520 +#define MII_GC_COLTEST 0x0080
45521 +#define MII_GC_RESERVED 0x007F
45522 +#define MII_GEN_STS 0x01
45523 +#define MII_GS_100BT4 0x8000
45524 +#define MII_GS_100BTXFD 0x4000
45525 +#define MII_GS_100BTXHD 0x2000
45526 +#define MII_GS_10BTFD 0x1000
45527 +#define MII_GS_10BTHD 0x0800
45528 +#define MII_GS_RESERVED 0x07C0
45529 +#define MII_GS_AUTOCMPLT 0x0020
45530 +#define MII_GS_RFLT 0x0010
45531 +#define MII_GS_AUTONEG 0x0008
45532 +#define MII_GS_LINK 0x0004
45533 +#define MII_GS_JABBER 0x0002
45534 +#define MII_GS_EXTCAP 0x0001
45535 +#define MII_GEN_ID_HI 0x02
45536 +#define MII_GEN_ID_LO 0x03
45537 +#define MII_GIL_OUI 0xFC00
45538 +#define MII_GIL_MODEL 0x03F0
45539 +#define MII_GIL_REVISION 0x000F
45540 +#define MII_AN_ADV 0x04
45541 +#define MII_AN_LPA 0x05
45542 +#define MII_AN_EXP 0x06
45544 +/* ThunderLAN Specific MII/PHY Registers */
45546 +#define TLAN_TLPHY_ID 0x10
45547 +#define TLAN_TLPHY_CTL 0x11
45548 +#define TLAN_TC_IGLINK 0x8000
45549 +#define TLAN_TC_SWAPOL 0x4000
45550 +#define TLAN_TC_AUISEL 0x2000
45551 +#define TLAN_TC_SQEEN 0x1000
45552 +#define TLAN_TC_MTEST 0x0800
45553 +#define TLAN_TC_RESERVED 0x07F8
45554 +#define TLAN_TC_NFEW 0x0004
45555 +#define TLAN_TC_INTEN 0x0002
45556 +#define TLAN_TC_TINT 0x0001
45557 +#define TLAN_TLPHY_STS 0x12
45558 +#define TLAN_TS_MINT 0x8000
45559 +#define TLAN_TS_PHOK 0x4000
45560 +#define TLAN_TS_POLOK 0x2000
45561 +#define TLAN_TS_TPENERGY 0x1000
45562 +#define TLAN_TS_RESERVED 0x0FFF
45563 +#define TLAN_TLPHY_PAR 0x19
45564 +#define TLAN_PHY_CIM_STAT 0x0020
45565 +#define TLAN_PHY_SPEED_100 0x0040
45566 +#define TLAN_PHY_DUPLEX_FULL 0x0080
45567 +#define TLAN_PHY_AN_EN_STAT 0x0400
45569 +/* National Sem. & Level1 PHY id's */
45570 +#define NAT_SEM_ID1 0x2000
45571 +#define NAT_SEM_ID2 0x5C01
45572 +#define LEVEL1_ID1 0x7810
45573 +#define LEVEL1_ID2 0x0000
45575 +#define CIRC_INC( a, b ) if ( ++a >= b ) a = 0
45577 +/* Routines to access internal registers. */
45579 +inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
45581 + outw(internal_addr, base_addr + TLAN_DIO_ADR);
45582 + return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)));
45584 +} /* TLan_DioRead8 */
45589 +inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
45591 + outw(internal_addr, base_addr + TLAN_DIO_ADR);
45592 + return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)));
45594 +} /* TLan_DioRead16 */
45599 +inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr)
45601 + outw(internal_addr, base_addr + TLAN_DIO_ADR);
45602 + return (inl(base_addr + TLAN_DIO_DATA));
45604 +} /* TLan_DioRead32 */
45609 +inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data)
45611 + outw(internal_addr, base_addr + TLAN_DIO_ADR);
45612 + outb(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x3));
45619 +inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data)
45621 + outw(internal_addr, base_addr + TLAN_DIO_ADR);
45622 + outw(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
45629 +inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data)
45631 + outw(internal_addr, base_addr + TLAN_DIO_ADR);
45632 + outl(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
45638 +#if 0
45639 +inline void TLan_ClearBit(u8 bit, u16 port)
45641 + outb_p(inb_p(port) & ~bit, port);
45647 +inline int TLan_GetBit(u8 bit, u16 port)
45649 + return ((int) (inb_p(port) & bit));
45655 +inline void TLan_SetBit(u8 bit, u16 port)
45657 + outb_p(inb_p(port) | bit, port);
45659 +#endif
45661 +#define TLan_ClearBit( bit, port ) outb_p(inb_p(port) & ~bit, port)
45662 +#define TLan_GetBit( bit, port ) ((int) (inb_p(port) & bit))
45663 +#define TLan_SetBit( bit, port ) outb_p(inb_p(port) | bit, port)
45665 +#ifdef I_LIKE_A_FAST_HASH_FUNCTION
45666 +/* given 6 bytes, view them as 8 6-bit numbers and return the XOR of those */
45667 +/* the code below is about seven times as fast as the original code */
45668 +inline u32 TLan_HashFunc(u8 * a)
45670 + u8 hash;
45672 + hash = (a[0] ^ a[3]); /* & 077 */
45673 + hash ^= ((a[0] ^ a[3]) >> 6); /* & 003 */
45674 + hash ^= ((a[1] ^ a[4]) << 2); /* & 074 */
45675 + hash ^= ((a[1] ^ a[4]) >> 4); /* & 017 */
45676 + hash ^= ((a[2] ^ a[5]) << 4); /* & 060 */
45677 + hash ^= ((a[2] ^ a[5]) >> 2); /* & 077 */
45679 + return (hash & 077);
45682 +#else /* original code */
45684 +inline u32 xor(u32 a, u32 b)
45686 + return ((a && !b) || (!a && b));
45689 +#define XOR8( a, b, c, d, e, f, g, h ) xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) )
45690 +#define DA( a, bit ) ( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) )
45692 +inline u32 TLan_HashFunc(u8 * a)
45694 + u32 hash;
45696 + hash =
45697 + XOR8(DA(a, 0), DA(a, 6), DA(a, 12), DA(a, 18), DA(a, 24),
45698 + DA(a, 30), DA(a, 36), DA(a, 42));
45699 + hash |=
45700 + XOR8(DA(a, 1), DA(a, 7), DA(a, 13), DA(a, 19), DA(a, 25),
45701 + DA(a, 31), DA(a, 37), DA(a, 43)) << 1;
45702 + hash |=
45703 + XOR8(DA(a, 2), DA(a, 8), DA(a, 14), DA(a, 20), DA(a, 26),
45704 + DA(a, 32), DA(a, 38), DA(a, 44)) << 2;
45705 + hash |=
45706 + XOR8(DA(a, 3), DA(a, 9), DA(a, 15), DA(a, 21), DA(a, 27),
45707 + DA(a, 33), DA(a, 39), DA(a, 45)) << 3;
45708 + hash |=
45709 + XOR8(DA(a, 4), DA(a, 10), DA(a, 16), DA(a, 22), DA(a, 28),
45710 + DA(a, 34), DA(a, 40), DA(a, 46)) << 4;
45711 + hash |=
45712 + XOR8(DA(a, 5), DA(a, 11), DA(a, 17), DA(a, 23), DA(a, 29),
45713 + DA(a, 35), DA(a, 41), DA(a, 47)) << 5;
45715 + return hash;
45719 +#endif /* I_LIKE_A_FAST_HASH_FUNCTION */
45720 Index: b/netboot/tulip.c
45721 ===================================================================
45722 --- a/netboot/tulip.c
45723 +++ b/netboot/tulip.c
45724 @@ -48,6 +48,7 @@
45725 /*********************************************************************/
45728 + 07 Sep 2003 timlegge Multicast Support Added
45729 11 Apr 2001 mdc [patch to etherboot 4.7.24]
45730 Major rewrite to include Linux tulip driver media detection
45731 code. This driver should support a lot more cards now.
45732 @@ -98,7 +99,6 @@
45733 and thinguin mailing lists.
45737 /*********************************************************************/
45738 /* Declarations */
45739 /*********************************************************************/
45740 @@ -106,31 +106,29 @@
45741 #include "etherboot.h"
45742 #include "nic.h"
45743 #include "pci.h"
45744 -#include "cards.h"
45746 /* User settable parameters */
45748 -#undef TULIP_DEBUG
45749 -#undef TULIP_DEBUG_WHERE
45750 +#undef TULIP_DEBUG
45751 +#undef TULIP_DEBUG_WHERE
45752 +#ifdef TULIP_DEBUG
45753 static int tulip_debug = 2; /* 1 normal messages, 0 quiet .. 7 verbose. */
45754 +#endif
45756 #define TX_TIME_OUT 2*TICKS_PER_SEC
45758 -typedef unsigned char u8;
45759 -typedef signed char s8;
45760 -typedef unsigned short u16;
45761 -typedef signed short s16;
45762 -typedef unsigned int u32;
45763 -typedef signed int s32;
45764 +typedef uint8_t u8;
45765 +typedef int8_t s8;
45766 +typedef uint16_t u16;
45767 +typedef int16_t s16;
45768 +typedef uint32_t u32;
45769 +typedef int32_t s32;
45771 /* helpful macros if on a big_endian machine for changing byte order.
45772 not strictly needed on Intel */
45773 -#define le16_to_cpu(val) (val)
45774 -#define cpu_to_le32(val) (val)
45775 #define get_unaligned(ptr) (*(ptr))
45776 #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
45777 #define get_u16(ptr) (*(u16 *)(ptr))
45778 -#define virt_to_bus(x) ((unsigned long)x)
45779 #define virt_to_le32desc(addr) virt_to_bus(addr)
45781 #define TULIP_IOTYPE PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0
45782 @@ -212,6 +210,8 @@
45783 TULIP_IOTYPE, 256, PNIC2 },
45784 { "ADMtek AN981 Comet", { 0x09811317, 0xffffffff, 0, 0, 0, 0 },
45785 TULIP_IOTYPE, 256, COMET },
45786 + { "ADMTek AN983 Comet", { 0x12161113, 0xffffffff, 0, 0, 0, 0 },
45787 + TULIP_IOTYPE, 256, COMET },
45788 { "ADMtek Centaur-P", { 0x09851317, 0xffffffff, 0, 0, 0, 0 },
45789 TULIP_IOTYPE, 256, COMET },
45790 { "ADMtek Centaur-C", { 0x19851317, 0xffffffff, 0, 0, 0, 0 },
45791 @@ -280,9 +280,13 @@
45792 static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
45793 static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
45795 +/* not used
45796 static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
45798 static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
45799 +/* not used
45800 static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
45803 /* Offsets to the Command and Status Registers, "CSRs". All accesses
45804 must be longword instructions and quadword aligned. */
45805 @@ -300,6 +304,14 @@
45806 TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
45809 +/* The configuration bits in CSR6. */
45810 +enum csr6_mode_bits {
45811 + TxOn=0x2000, RxOn=0x0002, FullDuplex=0x0200,
45812 + AcceptBroadcast=0x0100, AcceptAllMulticast=0x0080,
45813 + AcceptAllPhys=0x0040, AcceptRunt=0x0008,
45817 enum desc_status_bits {
45818 DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
45820 @@ -384,21 +396,11 @@
45822 #define TX_RING_SIZE 2
45823 static struct tulip_tx_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned(4)));
45825 -#ifdef USE_LOWMEM_BUFFER
45826 -#define txb ((char *)0x10000 - BUFLEN)
45827 -#else
45828 static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
45829 -#endif
45831 #define RX_RING_SIZE 4
45832 static struct tulip_rx_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned(4)));
45834 -#ifdef USE_LOWMEM_BUFFER
45835 -#define rxb ((char *)0x10000 - RX_RING_SIZE * BUFLEN - BUFLEN)
45836 -#else
45837 static unsigned char rxb[RX_RING_SIZE * BUFLEN] __attribute__ ((aligned(4)));
45838 -#endif
45840 static struct tulip_private {
45841 int cur_rx;
45842 @@ -471,7 +473,6 @@
45843 static const char * block_name[] = {"21140 non-MII", "21140 MII PHY",
45844 "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"};
45847 /*********************************************************************/
45848 /* Function Prototypes */
45849 /*********************************************************************/
45850 @@ -479,14 +480,13 @@
45851 static void mdio_write(struct nic *nic, int phy_id, int location, int value);
45852 static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
45853 static void parse_eeprom(struct nic *nic);
45854 -struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
45855 - struct pci_device *pci);
45856 +static int tulip_probe(struct dev *dev, struct pci_device *pci);
45857 static void tulip_init_ring(struct nic *nic);
45858 static void tulip_reset(struct nic *nic);
45859 static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
45860 unsigned int s, const char *p);
45861 -static int tulip_poll(struct nic *nic);
45862 -static void tulip_disable(struct nic *nic);
45863 +static int tulip_poll(struct nic *nic, int retrieve);
45864 +static void tulip_disable(struct dev *dev);
45865 static void nway_start(struct nic *nic);
45866 static void pnic_do_nway(struct nic *nic);
45867 static void select_media(struct nic *nic, int startup);
45868 @@ -504,7 +504,6 @@
45869 static void tulip_more(void);
45870 #endif
45873 /*********************************************************************/
45874 /* Utility Routines */
45875 /*********************************************************************/
45876 @@ -535,7 +534,6 @@
45877 /* wait */ ;
45881 /*********************************************************************/
45882 /* Media Descriptor Code */
45883 /*********************************************************************/
45884 @@ -565,7 +563,7 @@
45885 MDIO protocol. See the MII specifications or DP83840A data sheet
45886 for details. */
45888 -int mdio_read(struct nic *nic, int phy_id, int location)
45889 +int mdio_read(struct nic *nic __unused, int phy_id, int location)
45891 int i;
45892 int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
45893 @@ -626,7 +624,7 @@
45894 return (retval>>1) & 0xffff;
45897 -void mdio_write(struct nic *nic, int phy_id, int location, int value)
45898 +void mdio_write(struct nic *nic __unused, int phy_id, int location, int value)
45900 int i;
45901 int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
45902 @@ -682,7 +680,6 @@
45907 /*********************************************************************/
45908 /* EEPROM Reading Code */
45909 /*********************************************************************/
45910 @@ -727,7 +724,6 @@
45911 return retval;
45915 /*********************************************************************/
45916 /* EEPROM Parsing Code */
45917 /*********************************************************************/
45918 @@ -895,11 +891,10 @@
45923 /*********************************************************************/
45924 /* tulip_init_ring - setup the tx and rx descriptors */
45925 /*********************************************************************/
45926 -static void tulip_init_ring(struct nic *nic)
45927 +static void tulip_init_ring(struct nic *nic __unused)
45929 int i;
45931 @@ -935,7 +930,22 @@
45932 /* Mark the last entry as wrapping the ring, though this should never happen */
45933 tx_ring[1].length = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
45937 +static void set_rx_mode(struct nic *nic __unused) {
45938 + int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
45940 + tp->csr6 &= ~0x00D5;
45942 + /* !IFF_PROMISC */
45943 + tp->csr6 |= AcceptAllMulticast;
45944 + csr6 |= AcceptAllMulticast;
45946 + outl(csr6, ioaddr + CSR6);
45952 /*********************************************************************/
45953 /* eth_reset - Reset adapter */
45954 /*********************************************************************/
45955 @@ -943,7 +953,6 @@
45957 int i;
45958 unsigned long to;
45959 - u32 addr_low, addr_high;
45961 #ifdef TULIP_DEBUG_WHERE
45962 whereami("tulip_reset\n");
45963 @@ -956,7 +965,7 @@
45964 if (tp->mii_cnt || (tp->mtable && tp->mtable->has_mii)) {
45965 outl(0x814C0000, ioaddr + CSR6);
45969 /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
45970 outl(0x00000001, ioaddr + CSR0);
45971 tulip_wait(1);
45972 @@ -1022,8 +1031,8 @@
45975 /* Point to rx and tx descriptors */
45976 - outl((unsigned long)&rx_ring[0], ioaddr + CSR3);
45977 - outl((unsigned long)&tx_ring[0], ioaddr + CSR4);
45978 + outl(virt_to_le32desc(&rx_ring[0]), ioaddr + CSR3);
45979 + outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4);
45981 init_media(nic);
45983 @@ -1049,11 +1058,12 @@
45984 if (tp->chip_id == LC82C168)
45985 tulip_check_duplex(nic);
45987 + set_rx_mode(nic);
45989 /* enable transmit and receive */
45990 outl(tp->csr6 | 0x00002002, ioaddr + CSR6);
45994 /*********************************************************************/
45995 /* eth_transmit - Transmit a frame */
45996 /*********************************************************************/
45997 @@ -1095,7 +1105,7 @@
45998 tx_ring[0].status = cpu_to_le32(0x80000000);
46000 /* Point to transmit descriptor */
46001 - outl((u32)&tx_ring[0], ioaddr + CSR4);
46002 + outl(virt_to_le32desc(&tx_ring[0]), ioaddr + CSR4);
46004 /* Enable Tx */
46005 outl(csr6 | 0x00002000, ioaddr + CSR6);
46006 @@ -1113,11 +1123,11 @@
46007 /* Disable Tx */
46008 outl(csr6 & ~0x00002000, ioaddr + CSR6);
46012 /*********************************************************************/
46013 /* eth_poll - Wait for a frame */
46014 /*********************************************************************/
46015 -static int tulip_poll(struct nic *nic)
46016 +static int tulip_poll(struct nic *nic, int retrieve)
46019 #ifdef TULIP_DEBUG_WHERE
46020 @@ -1128,6 +1138,8 @@
46021 if (rx_ring[tp->cur_rx].status & 0x80000000)
46022 return 0;
46024 + if ( ! retrieve ) return 1;
46026 #ifdef TULIP_DEBUG_WHERE
46027 whereami("tulip_poll got one\n");
46028 #endif
46029 @@ -1151,17 +1163,20 @@
46031 return 1;
46035 /*********************************************************************/
46036 /* eth_disable - Disable the interface */
46037 /*********************************************************************/
46038 -static void tulip_disable(struct nic *nic)
46039 +static void tulip_disable(struct dev *dev)
46042 + struct nic *nic = (struct nic *)dev;
46043 #ifdef TULIP_DEBUG_WHERE
46044 whereami("tulip_disable\n");
46045 #endif
46047 + /* merge reset and disable */
46048 + tulip_reset(nic);
46050 /* disable interrupts */
46051 outl(0x00000000, ioaddr + CSR7);
46053 @@ -1171,24 +1186,41 @@
46054 /* Clear the missed-packet counter. */
46055 (volatile unsigned long)inl(ioaddr + CSR8);
46059 +/*********************************************************************/
46060 +/*IRQ - Enable, Disable, or Force interrupts */
46061 +/*********************************************************************/
46062 +static void tulip_irq(struct nic *nic __unused, irq_action_t action __unused)
46064 + switch ( action ) {
46065 + case DISABLE :
46066 + break;
46067 + case ENABLE :
46068 + break;
46069 + case FORCE :
46070 + break;
46074 /*********************************************************************/
46075 /* eth_probe - Look for an adapter */
46076 /*********************************************************************/
46077 -struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
46078 - struct pci_device *pci)
46079 +static int tulip_probe(struct dev *dev, struct pci_device *pci)
46081 - u32 i, l1, l2;
46082 + struct nic *nic = (struct nic *)dev;
46083 + u32 i;
46084 u8 chip_rev;
46085 u8 ee_data[EEPROM_SIZE];
46086 unsigned short sum;
46087 int chip_idx;
46088 static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'};
46090 - if (io_addrs == 0 || *io_addrs == 0)
46091 + if (pci->ioaddr == 0)
46092 return 0;
46094 - ioaddr = *io_addrs;
46095 + ioaddr = pci->ioaddr;
46096 + nic->ioaddr = pci->ioaddr & ~3;
46097 + nic->irqno = 0;
46099 /* point to private storage */
46100 tp = &tpx;
46101 @@ -1378,15 +1410,15 @@
46102 /* reset the device and make ready for tx and rx of packets */
46103 tulip_reset(nic);
46105 - nic->reset = tulip_reset;
46106 + dev->disable = tulip_disable;
46107 nic->poll = tulip_poll;
46108 nic->transmit = tulip_transmit;
46109 - nic->disable = tulip_disable;
46110 + nic->irq = tulip_irq;
46112 /* give the board a chance to reset before returning */
46113 tulip_wait(4*TICKS_PER_SEC);
46115 - return nic;
46116 + return 1;
46119 static void start_link(struct nic *nic)
46120 @@ -1508,7 +1540,7 @@
46124 -static void nway_start(struct nic *nic)
46125 +static void nway_start(struct nic *nic __unused)
46127 int csr14 = ((tp->sym_advertise & 0x0780) << 9) |
46128 ((tp->sym_advertise&0x0020)<<1) | 0xffbf;
46129 @@ -1662,7 +1694,7 @@
46133 -static void pnic_do_nway(struct nic *nic)
46134 +static void pnic_do_nway(struct nic *nic __unused)
46136 u32 phy_reg = inl(ioaddr + 0xB8);
46137 u32 new_csr6 = tp->csr6 & ~0x40C40200;
46138 @@ -1886,8 +1918,8 @@
46140 } else if (tp->chip_id == DC21040) { /* 21040 */
46141 /* Turn on the xcvr interface. */
46142 - int csr12 = inl(ioaddr + CSR12);
46143 #ifdef TULIP_DEBUG
46144 + int csr12 = inl(ioaddr + CSR12);
46145 if (tulip_debug > 1)
46146 printf("%s: 21040 media type is %s, CSR12 is %hhX.\n",
46147 tp->nic_name, medianame[tp->if_port], csr12);
46148 @@ -1987,3 +2019,51 @@
46150 return 0;
46153 +static struct pci_id tulip_nics[] = {
46154 +PCI_ROM(0x1011, 0x0002, "dc21040", "Digital Tulip"),
46155 +PCI_ROM(0x1011, 0x0009, "ds21140", "Digital Tulip Fast"),
46156 +PCI_ROM(0x1011, 0x0014, "dc21041", "Digital Tulip+"),
46157 +PCI_ROM(0x1011, 0x0019, "ds21142", "Digital Tulip 21142"),
46158 +PCI_ROM(0x10b7, 0x9300, "3csoho100b-tx","3ComSOHO100B-TX"),
46159 +PCI_ROM(0x10b9, 0x5261, "ali1563", "ALi 1563 integrated ethernet"),
46160 +PCI_ROM(0x10d9, 0x0512, "mx98713", "Macronix MX987x3"),
46161 +PCI_ROM(0x10d9, 0x0531, "mx98715", "Macronix MX987x5"),
46162 +PCI_ROM(0x1113, 0x1217, "mxic-98715", "Macronix MX987x5"),
46163 +PCI_ROM(0x11ad, 0xc115, "lc82c115", "LinkSys LNE100TX"),
46164 +PCI_ROM(0x11ad, 0x0002, "82c168", "Netgear FA310TX"),
46165 +PCI_ROM(0x1282, 0x9100, "dm9100", "Davicom 9100"),
46166 +PCI_ROM(0x1282, 0x9102, "dm9102", "Davicom 9102"),
46167 +PCI_ROM(0x1282, 0x9009, "dm9009", "Davicom 9009"),
46168 +PCI_ROM(0x1282, 0x9132, "dm9132", "Davicom 9132"),
46169 +PCI_ROM(0x1317, 0x0985, "centaur-p", "ADMtek Centaur-P"),
46170 +PCI_ROM(0x1317, 0x0981, "an981", "ADMtek AN981 Comet"), /* ADMTek Centaur-P (stmicro) */
46171 +PCI_ROM(0x1113, 0x1216, "an983", "ADMTek AN983 Comet"),
46172 +PCI_ROM(0x1317, 0x9511, "an983b", "ADMTek Comet 983b"),
46173 +PCI_ROM(0x1317, 0x1985, "centaur-c", "ADMTek Centaur-C"),
46174 +PCI_ROM(0x8086, 0x0039, "intel21145", "Intel Tulip"),
46175 +PCI_ROM(0x125b, 0x1400, "ax88140", "ASIX AX88140"),
46176 +PCI_ROM(0x11f6, 0x9881, "rl100tx", "Compex RL100-TX"),
46177 +PCI_ROM(0x115d, 0x0003, "xircomtulip", "Xircom Tulip"),
46178 +PCI_ROM(0x104a, 0x0981, "tulip-0981", "Tulip 0x104a 0x0981"),
46179 +PCI_ROM(0x104a, 0x2774, "tulip-2774", "Tulip 0x104a 0x2774"),
46180 +PCI_ROM(0x1113, 0x9511, "tulip-9511", "Tulip 0x1113 0x9511"),
46181 +PCI_ROM(0x1186, 0x1561, "tulip-1561", "Tulip 0x1186 0x1561"),
46182 +PCI_ROM(0x1259, 0xa120, "tulip-a120", "Tulip 0x1259 0xa120"),
46183 +PCI_ROM(0x13d1, 0xab02, "tulip-ab02", "Tulip 0x13d1 0xab02"),
46184 +PCI_ROM(0x13d1, 0xab03, "tulip-ab03", "Tulip 0x13d1 0xab03"),
46185 +PCI_ROM(0x13d1, 0xab08, "tulip-ab08", "Tulip 0x13d1 0xab08"),
46186 +PCI_ROM(0x14f1, 0x1803, "lanfinity", "Conexant LANfinity"),
46187 +PCI_ROM(0x1626, 0x8410, "tulip-8410", "Tulip 0x1626 0x8410"),
46188 +PCI_ROM(0x1737, 0xab08, "tulip-1737-ab08","Tulip 0x1737 0xab08"),
46189 +PCI_ROM(0x1737, 0xab09, "tulip-ab09", "Tulip 0x1737 0xab09"),
46192 +struct pci_driver tulip_driver = {
46193 + .type = NIC_DRIVER,
46194 + .name = "Tulip",
46195 + .probe = tulip_probe,
46196 + .ids = tulip_nics,
46197 + .id_count = sizeof(tulip_nics)/sizeof(tulip_nics[0]),
46198 + .class = 0,
46200 Index: b/netboot/tulip.txt
46201 ===================================================================
46202 --- a/netboot/tulip.txt
46203 +++ /dev/null
46204 @@ -1,53 +0,0 @@
46205 -This software may be used and distributed according to the terms of
46206 -the GNU Public License, incorporated herein by reference.
46208 -This is a tulip and clone driver for Etherboot. See the revision
46209 -history in the tulip.c file for information on changes. This version
46210 -of the driver incorporates changes from Bob Edwards and Paul Mackerras
46211 -who cantributed changes to support the TRENDnet TE100-PCIA NIC which
46212 -uses a genuine Intel 21143-PD chipset. There are also various code
46213 -cleanups to make time-based activities more reliable.
46215 -Of course you have to have all the usual Etherboot environment
46216 -(bootp/dhcp/NFS) set up, and you need a Linux kernel with v0.91g
46217 -(7.16.99) or later of the tulip.c driver compiled in to support some
46218 -MX98715 based cards. That file is available at:
46220 - http://cesdis.gsfc.nasa.gov/linux/drivers/test/tulip.c
46222 -NOTES
46224 -I've tested this driver with a SOHOware Fast 10/100 Model SDA110A,
46225 -a Linksys LNE100TX v2.0, and a Netgear FA310TX card, and it worked at
46226 -both 10 and 100 mbits. Other cards based on the tulip family may work as
46227 -well.
46229 -These cards are about 20$US, are supported by Linux and now Etherboot,
46230 -and being PCI, they auto-configure IRQ and IOADDR and auto-negotiate
46231 -10/100 half/full duplex. It seems like a pretty good value compared to
46232 -some of the pricier cards, and can lower the cost of building/adapting
46233 -thin client workstations substantially while giving a considerable
46234 -performance increase.
46236 -On some PCI tulip clone chipsets (MX987x5, LC82C115, LC82C168) this driver
46237 -lets the card choose the fastest speed it can negotiate with the peer
46238 -device. On other cards, it chooses 10mbit half-duplex.
46240 -I burned an AM27C256 (32KByte) EPROM with mx987x5.lzrom and it worked.
46241 -According to the data sheet the MX98715A supports up to 64K (27C512)
46242 -EPROMs,
46244 -I've liberally commented the code and header files in the hope that it
46245 -will help the next person who hacks the code or needs to support some
46246 -tulip clone card, or wishes to add functionality.
46248 -Anyway, please test this if you can on your tulip based card, and let
46249 -me (mdc@thinguin.org) and the netboot list (netboot@baghira.han.de)
46250 -know how things go. I also would appreciate code review by people who
46251 -program. I'm a strong believer in "another set of eyes".
46253 -Regards,
46255 -Marty Connor
46256 -mdc@thinguin.org
46257 -http://www.thinguin.org/
46258 Index: b/netboot/types.h
46259 ===================================================================
46260 --- /dev/null
46261 +++ b/netboot/types.h
46262 @@ -0,0 +1,44 @@
46263 +#ifndef _TYPES_H
46264 +#define _TYPES_H
46266 +/* I'm architecture independed :-) */
46268 +/*
46269 + * It's architecture depended headers for common integer types
46270 + */
46271 +#include "stdint.h"
46273 +/*
46274 + * Here are some RPC types define from linux /usr/include/rpc/types.h
46275 + */
46276 +typedef int bool_t;
46277 +typedef int enum_t;
46278 +typedef uint32_t rpcprog_t;
46279 +typedef uint32_t rpcvers_t;
46280 +typedef uint32_t rpcproc_t;
46281 +typedef uint32_t rpcprot_t;
46282 +typedef uint32_t rpcport_t;
46284 +/* For bool_t */
46285 +/* typedef enum { */
46286 +/* FALSE = 0, */
46287 +/* TRUE = 1 */
46288 +/* } boolean_t; */
46292 +/* Some BSD or RPC style types */
46293 +typedef unsigned char u_char;
46294 +typedef unsigned short u_short;
46295 +typedef unsigned int u_int;
46296 +typedef unsigned long u_long;
46297 +typedef long long quad_t;
46298 +typedef unsigned long long u_quad_t;
46299 +typedef struct {
46300 + int __val[2];
46301 +}fsid_t; /* Type of file system IDs, from bits/types.h */
46303 +typedef int daddr_t; /* The type of a disk address, from bits/types.h */
46304 +typedef char * caddr_t;
46306 +#endif /* _TYPES_H */
46307 Index: b/netboot/udp.h
46308 ===================================================================
46309 --- /dev/null
46310 +++ b/netboot/udp.h
46311 @@ -0,0 +1,30 @@
46312 +#ifndef _UDP_H
46313 +#define _UDP_H
46315 +/* We need 'uint16_t' and 'uint8_t' */
46316 +#include "types.h"
46317 +/* We need 'in_addr' */
46318 +#include "in.h"
46320 +struct udp_pseudo_hdr {
46321 + in_addr src;
46322 + in_addr dest;
46323 + uint8_t unused;
46324 + uint8_t protocol;
46325 + uint16_t len;
46327 +struct udphdr {
46328 + uint16_t src;
46329 + uint16_t dest;
46330 + uint16_t len;
46331 + uint16_t chksum;
46334 +extern void build_udp_hdr(unsigned long __destip, unsigned int __srcsock,
46335 + unsigned int __destsock, int __ttl, int __len,
46336 + const void * __buf);
46338 +extern int udp_transmit(unsigned long __destip, unsigned int __srcsock,
46339 + unsigned int __destsock, int __len, const void * __buf);
46341 +#endif /* _UDP_H */
46342 Index: b/netboot/via-rhine.c
46343 ===================================================================
46344 --- a/netboot/via-rhine.c
46345 +++ b/netboot/via-rhine.c
46346 @@ -18,7 +18,7 @@
46350 -static const char *version = "rhine.c v1.0.0 2000-01-07\n";
46351 +static const char *version = "rhine.c v1.0.1 2003-02-06\n";
46353 /* A few user-configurable values. */
46355 @@ -46,7 +46,6 @@
46356 #include "etherboot.h"
46357 #include "nic.h"
46358 #include "pci.h"
46359 -#include "cards.h"
46361 /* define all ioaddr */
46363 @@ -103,6 +102,11 @@
46364 #define byCFGD ioaddr + 0x7b
46365 #define wTallyCntMPA ioaddr + 0x7c
46366 #define wTallyCntCRC ioaddr + 0x7d
46367 +#define bySTICKHW ioaddr + 0x83
46368 +#define byWOLcrClr ioaddr + 0xA4
46369 +#define byWOLcgClr ioaddr + 0xA7
46370 +#define byPwrcsrClr ioaddr + 0xAC
46372 /*--------------------- Exioaddr Definitions -------------------------*/
46375 @@ -617,9 +621,6 @@
46379 -#define PCI_VENDOR_ID_FET 0x1106
46380 -#define PCI_DEVICE_ID_FET_3043 0x3043
46382 /* The rest of these values should never change. */
46383 #define NUM_TX_DESC 2 /* Number of Tx descriptor registers. */
46385 @@ -652,23 +653,19 @@
46387 rhine;
46389 -static struct nic *rhine_probe1 (struct nic *dev, int ioaddr,
46390 +static void rhine_probe1 (struct nic *nic, int ioaddr,
46391 int chip_id, int options);
46392 static int QueryAuto (int);
46393 static int ReadMII (int byMIIIndex, int);
46394 static void WriteMII (char, char, char, int);
46395 static void MIIDelay (void);
46396 static void rhine_init_ring (struct nic *dev);
46397 -static void rhine_disable (struct nic *nic);
46398 +static void rhine_disable (struct dev *dev);
46399 static void rhine_reset (struct nic *nic);
46400 -static int rhine_poll (struct nic *nic);
46401 +static int rhine_poll (struct nic *nic, int retreive);
46402 static void rhine_transmit (struct nic *nic, const char *d, unsigned int t,
46403 unsigned int s, const char *p);
46405 -/* Linux support functions */
46406 -#define virt_to_bus(x) ((unsigned long)x)
46407 -#define bus_to_virt(x) ((void *)x)
46409 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
46410 static void
46411 rhine_init_ring (struct nic *nic)
46412 @@ -854,26 +851,99 @@
46416 -struct nic *
46417 -rhine_probe (struct nic *nic, unsigned short *probeaddrs,
46418 - struct pci_device *pci)
46419 +/* Offsets to the device registers. */
46420 +enum register_offsets {
46421 + StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
46422 + IntrStatus=0x0C, IntrEnable=0x0E,
46423 + MulticastFilter0=0x10, MulticastFilter1=0x14,
46424 + RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
46425 + MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E,
46426 + MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
46427 + ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
46428 + RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
46429 + StickyHW=0x83, IntrStatus2=0x84, WOLcrClr=0xA4, WOLcgClr=0xA7,
46430 + PwrcsrClr=0xAC,
46433 +/* Bits in the interrupt status/mask registers. */
46434 +enum intr_status_bits {
46435 + IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
46436 + IntrTxDone=0x0002, IntrTxError=0x0008, IntrTxUnderrun=0x0210,
46437 + IntrPCIErr=0x0040,
46438 + IntrStatsMax=0x0080, IntrRxEarly=0x0100,
46439 + IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000,
46440 + IntrTxAborted=0x2000, IntrLinkChange=0x4000,
46441 + IntrRxWakeUp=0x8000,
46442 + IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260,
46443 + IntrTxDescRace=0x080000, /* mapped from IntrStatus2 */
46444 + IntrTxErrSummary=0x082218,
46446 +#define DEFAULT_INTR (IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | \
46447 + IntrRxDropped | IntrRxNoBuf)
46449 +/***************************************************************************
46450 + IRQ - PXE IRQ Handler
46451 +***************************************************************************/
46452 +void rhine_irq ( struct nic *nic, irq_action_t action ) {
46453 + struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
46454 + /* Enable interrupts by setting the interrupt mask. */
46455 + unsigned int intr_status;
46457 + switch ( action ) {
46458 + case DISABLE :
46459 + case ENABLE :
46460 + intr_status = inw(nic->ioaddr + IntrStatus);
46461 + /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
46462 + if (tp->chip_id == 0x3065)
46463 + intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
46464 + intr_status = (intr_status & ~DEFAULT_INTR);
46465 + if ( action == ENABLE )
46466 + intr_status = intr_status | DEFAULT_INTR;
46467 + outw(intr_status, nic->ioaddr + IntrEnable);
46468 + break;
46469 + case FORCE :
46470 + outw(0x0010, nic->ioaddr + 0x84);
46471 + break;
46475 +static int
46476 +rhine_probe (struct dev *dev, struct pci_device *pci)
46478 + struct nic *nic = (struct nic *)dev;
46479 + struct rhine_private *tp = &rhine;
46480 if (!pci->ioaddr)
46481 - return NULL;
46482 - nic = rhine_probe1 (nic, pci->ioaddr, 0, -1);
46483 + return 0;
46484 + rhine_probe1 (nic, pci->ioaddr, pci->dev_id, -1);
46486 - if (nic)
46487 - adjust_pci_device(pci);
46488 - nic->poll = rhine_poll;
46489 - nic->transmit = rhine_transmit;
46490 - nic->reset = rhine_reset;
46491 - nic->disable = rhine_disable;
46492 + adjust_pci_device(pci);
46493 rhine_reset (nic);
46495 - return nic;
46496 + dev->disable = rhine_disable;
46497 + nic->poll = rhine_poll;
46498 + nic->transmit = rhine_transmit;
46499 + nic->irqno = pci->irq;
46500 + nic->irq = rhine_irq;
46501 + nic->ioaddr = tp->ioaddr;
46504 + return 1;
46507 +static void set_rx_mode(struct nic *nic __unused) {
46508 + struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
46509 + unsigned char rx_mode;
46510 + int ioaddr = tp->ioaddr;
46512 + /* ! IFF_PROMISC */
46513 + outl(0xffffffff, byMAR0);
46514 + outl(0xffffffff, byMAR4);
46515 + rx_mode = 0x0C;
46517 + outb(0x60 /* thresh */ | rx_mode, byRCR );
46520 -static struct nic *
46521 +static void
46522 rhine_probe1 (struct nic *nic, int ioaddr, int chip_id, int options)
46524 struct rhine_private *tp;
46525 @@ -885,6 +955,29 @@
46527 if (rhine_debug > 0 && did_version++ == 0)
46528 printf (version);
46530 + /* D-Link provided reset code (with comment additions) */
46531 + if((chip_id != 0x3043) && (chip_id != 0x6100)) {
46532 + unsigned char byOrgValue;
46534 + if(rhine_debug > 0)
46535 + printf("Enabling Sticky Bit Workaround for Chip_id: 0x%hX\n"
46536 + , chip_id);
46537 + /* clear sticky bit before reset & read ethernet address */
46538 + byOrgValue = inb(bySTICKHW);
46539 + byOrgValue = byOrgValue & 0xFC;
46540 + outb(byOrgValue, bySTICKHW);
46542 + /* (bits written are cleared?) */
46543 + /* disable force PME-enable */
46544 + outb(0x80, byWOLcgClr);
46545 + /* disable power-event config bit */
46546 + outb(0xFF, byWOLcrClr);
46547 + /* clear power status (undocumented in vt6102 docs?) */
46548 + outb(0xFF, byPwrcsrClr);
46552 /* Perhaps this should be read from the EEPROM? */
46553 for (i = 0; i < ETH_ALEN; i++)
46554 nic->node_addr[i] = inb (byPAR0 + i);
46555 @@ -920,6 +1013,7 @@
46557 #endif
46560 /* query MII to know LineSpeed,duplex mode */
46561 byMIIvalue = inb (ioaddr + 0x6d);
46562 LineSpeed = byMIIvalue & MIISR_SPEED;
46563 @@ -971,15 +1065,19 @@
46564 if (tp->default_port)
46565 tp->medialock = 1;
46567 - return nic;
46568 + return;
46571 -static void
46572 -rhine_disable (struct nic *nic)
46573 +static void
46574 +rhine_disable (struct dev *dev)
46576 + struct nic *nic = (struct nic *)dev;
46577 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
46578 int ioaddr = tp->ioaddr;
46580 + /* merge reset and disable */
46581 + rhine_reset(nic);
46583 printf ("rhine disable\n");
46584 /* Switch to loopback mode to avoid hardware races. */
46585 writeb(0x60 | 0x01, byTCR);
46586 @@ -1002,17 +1100,10 @@
46587 int rx_bufs_tmp, rx_bufs_tmp1;
46588 int tx_bufs_tmp, tx_bufs_tmp1;
46590 -#ifdef USE_LOWMEM_BUFFER
46591 -#define buf1 (0x10000 - (RX_RING_SIZE * PKT_BUF_SZ + 32))
46592 -#define buf2 (buf1 - (RX_RING_SIZE * PKT_BUF_SZ + 32))
46593 -#define desc1 (buf2 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))
46594 -#define desc2 (desc1 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))
46595 -#else
46596 static char buf1[RX_RING_SIZE * PKT_BUF_SZ + 32];
46597 static char buf2[RX_RING_SIZE * PKT_BUF_SZ + 32];
46598 static char desc1[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
46599 static char desc2[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
46600 -#endif
46602 /* printf ("rhine_reset\n"); */
46603 /* Soft reset the chip. */
46604 @@ -1069,6 +1160,9 @@
46605 outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);
46606 outl (virt_to_bus (tp->tx_ring), dwCurrentTxDescAddr);
46608 + /* Setup Multicast */
46609 + set_rx_mode(nic);
46611 /* close IMR */
46612 outw (0x0000, byIMR0);
46614 @@ -1093,15 +1187,34 @@
46615 /*set IMR to work */
46616 outw (IMRShadow, byIMR0);
46618 +/* Beware of PCI posted writes */
46619 +#define IOSYNC do { readb(nic->ioaddr + StationAddr); } while (0)
46621 static int
46622 -rhine_poll (struct nic *nic)
46623 +rhine_poll (struct nic *nic, int retreive)
46625 struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
46626 int rxstatus, good = 0;;
46628 if (tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit == 0)
46630 + unsigned int intr_status;
46631 + /* There is a packet ready */
46632 + if(!retreive)
46633 + return 1;
46635 + intr_status = inw(nic->ioaddr + IntrStatus);
46636 + /* On Rhine-II, Bit 3 indicates Tx descriptor write-back race. */
46637 +#if 0
46638 + if (tp->chip_id == 0x3065)
46639 + intr_status |= inb(nic->ioaddr + IntrStatus2) << 16;
46640 +#endif
46641 + /* Acknowledge all of the current interrupt sources ASAP. */
46642 + if (intr_status & IntrTxDescRace)
46643 + outb(0x08, nic->ioaddr + IntrStatus2);
46644 + outw(intr_status & 0xffff, nic->ioaddr + IntrStatus);
46645 + IOSYNC;
46647 rxstatus = tp->rx_ring[tp->cur_rx].rx_status.lw;
46648 if ((rxstatus & 0x0300) != 0x0300)
46650 @@ -1124,6 +1237,11 @@
46651 tp->cur_rx++;
46652 tp->cur_rx = tp->cur_rx % RX_RING_SIZE;
46654 + /* Acknowledge all of the current interrupt sources ASAP. */
46655 + outw(DEFAULT_INTR & ~IntrRxDone, nic->ioaddr + IntrStatus);
46657 + IOSYNC;
46659 return good;
46662 @@ -1152,7 +1270,7 @@
46663 while (s < ETH_ZLEN)
46664 *((char *) tp->tx_buffs[entry] + ETH_HLEN + (s++)) = 0;
46666 - tp->tx_ring[entry].tx_ctrl.bits.tx_buf_size = ETH_HLEN + s;
46667 + tp->tx_ring[entry].tx_ctrl.bits.tx_buf_size = s;
46669 tp->tx_ring[entry].tx_status.bits.own_bit = 1;
46671 @@ -1170,6 +1288,9 @@
46672 /*printf("td4=[%X]",inl(dwCurrentTDSE3)); */
46674 outb (CR1bak, byCR1);
46675 + /* Wait until transmit is finished */
46676 + while (tp->tx_ring[entry].tx_status.bits.own_bit != 0)
46678 tp->cur_tx++;
46680 /*outw(IMRShadow,byIMR0); */
46681 @@ -1177,4 +1298,21 @@
46682 /*tp->tx_skbuff[entry] = 0; */
46685 +static struct pci_id rhine_nics[] = {
46686 +PCI_ROM(0x1106, 0x3065, "dlink-530tx", "VIA 6102"),
46687 +PCI_ROM(0x1106, 0x3106, "via-rhine-6105", "VIA 6105"),
46688 +PCI_ROM(0x1106, 0x3043, "dlink-530tx-old", "VIA 3043"), /* Rhine-I 86c100a */
46689 +PCI_ROM(0x1106, 0x3053, "via6105m", "VIA 6105M"),
46690 +PCI_ROM(0x1106, 0x6100, "via-rhine-old", "VIA 86C100A"), /* Rhine-II */
46693 +struct pci_driver rhine_driver = {
46694 + .type = NIC_DRIVER,
46695 + .name = "VIA 86C100",
46696 + .probe = rhine_probe,
46697 + .ids = rhine_nics,
46698 + .id_count = sizeof(rhine_nics)/sizeof(rhine_nics[0]),
46699 + .class = 0,
46702 /* EOF via-rhine.c */
46703 Index: b/netboot/w89c840.c
46704 ===================================================================
46705 --- a/netboot/w89c840.c
46706 +++ b/netboot/w89c840.c
46707 @@ -43,6 +43,9 @@
46708 * using timer2 routines. Proposed
46709 * by Ken Yap to eliminate CPU speed
46710 * dependency.
46711 + * Dec 12 2003 V0.94 timlegge Fixed issues in 5.2, removed
46712 + * interrupt usage, enabled
46713 + * multicast support
46715 * This is the etherboot driver for cards based on Winbond W89c840F chip.
46717 @@ -77,10 +80,9 @@
46718 #include "etherboot.h"
46719 #include "nic.h"
46720 #include "pci.h"
46721 -#include "cards.h"
46722 #include "timer.h"
46724 -static const char *w89c840_version = "diver Version 0.92 - August 27, 2000";
46725 +static const char *w89c840_version = "driver Version 0.94 - December 12, 2003";
46727 typedef unsigned char u8;
46728 typedef signed char s8;
46729 @@ -90,9 +92,6 @@
46730 typedef signed int s32;
46732 /* Linux support functions */
46733 -#define virt_to_bus(x) ((unsigned long)x)
46734 -#define bus_to_virt(x) ((void *)x)
46736 #define virt_to_le32desc(addr) virt_to_bus(addr)
46737 #define le32desc_to_virt(addr) bus_to_virt(addr)
46739 @@ -109,7 +108,6 @@
46740 bonding and packet priority.
46741 There are no ill effects from too-large receive rings. */
46742 #define TX_RING_SIZE 2
46744 #define RX_RING_SIZE 2
46746 /* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
46747 @@ -260,32 +258,20 @@
46749 static int ioaddr;
46750 static unsigned short eeprom [0x40];
46752 -#ifdef USE_LOWMEM_BUFFER
46753 -#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
46754 -#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
46755 -#else
46756 static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
46757 static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
46758 -#endif
46760 static int eeprom_read(long ioaddr, int location);
46761 static int mdio_read(int base_address, int phy_id, int location);
46762 +#if 0
46763 static void mdio_write(int base_address, int phy_id, int location, int value);
46764 +#endif
46766 static void check_duplex(void);
46767 static void set_rx_mode(void);
46768 static void init_ring(void);
46771 -static void wait_long_time(void)
46773 - printf("Paused - please read output above this line\n");
46774 - sleep(3);
46778 -#if defined W89C840_DEBUG
46779 +#if defined(W89C840_DEBUG)
46780 static void decode_interrupt(u32 intr_status)
46782 printf("Interrupt status: ");
46783 @@ -349,15 +335,17 @@
46784 check_duplex();
46785 set_rx_mode();
46787 - /* Clear and Enable interrupts by setting the interrupt mask. */
46788 + /* Do not enable the interrupts Etherboot doesn't need them */
46790 writel(0x1A0F5, ioaddr + IntrStatus);
46791 writel(0x1A0F5, ioaddr + IntrEnable);
46794 #if defined(W89C840_DEBUG)
46795 printf("winbond-840 : Done reset.\n");
46796 #endif
46799 +#if 0
46800 static void handle_intr(u32 intr_stat)
46802 if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
46803 @@ -372,7 +360,7 @@
46804 /* There was an abnormal interrupt */
46805 printf("\n-=- Abnormal interrupt.\n");
46807 -#if defined (W89C840_DEBUG)
46808 +#if defined(W89C840_DEBUG)
46809 decode_interrupt(intr_stat);
46810 #endif
46812 @@ -383,19 +371,21 @@
46816 +#endif
46818 /**************************************************************************
46819 w89c840_poll - Wait for a frame
46820 ***************************************************************************/
46821 -static int w89c840_poll(struct nic *nic)
46822 +static int w89c840_poll(struct nic *nic, int retrieve)
46824 /* return true if there's an ethernet packet ready to read */
46825 /* nic->packet should contain data on return */
46826 /* nic->packetlen should contain length of data */
46827 int packet_received = 0;
46829 +#if defined(W89C840_DEBUG)
46830 u32 intr_status = readl(ioaddr + IntrStatus);
46831 - /* handle_intr(intr_status); */ /* -- handled later */
46832 +#endif
46834 do {
46835 /* Code from netdev_rx(dev) */
46836 @@ -411,6 +401,11 @@
46837 break;
46840 + if ( !retrieve ) {
46841 + packet_received = 1;
46842 + break;
46845 if ((status & 0x38008300) != 0x0300) {
46846 if ((status & 0x38000300) != 0x0300) {
46847 /* Ingore earlier buffers. */
46848 @@ -478,11 +473,7 @@
46849 entry = (++w840private.cur_rx) % RX_RING_SIZE;
46850 w840private.rx_head_desc = &w840private.rx_ring[entry];
46851 } while (0);
46853 - if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) {
46854 - handle_intr(intr_status);
46858 return packet_received;
46861 @@ -521,13 +512,13 @@
46863 w840private.tx_ring[entry].buffer1 = virt_to_le32desc(tx_packet);
46865 - w840private.tx_ring[entry].length = (DescWholePkt | s);
46866 + w840private.tx_ring[entry].length = (DescWholePkt | (u32) s);
46867 if (entry >= TX_RING_SIZE-1) /* Wrap ring */
46868 w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
46869 w840private.tx_ring[entry].status = (DescOwn);
46870 w840private.cur_tx++;
46872 - w840private.tx_q_bytes += s;
46873 + w840private.tx_q_bytes = (u16) s;
46874 writel(0, ioaddr + TxStartDemand);
46876 /* Work around horrible bug in the chip by marking the queue as full
46877 @@ -550,33 +541,29 @@
46878 load_timer2(TX_TIMEOUT);
46881 +#if defined W89C840_DEBUG
46882 u32 intr_stat = 0;
46884 +#endif
46885 while (1) {
46887 - intr_stat = readl(ioaddr + IntrStatus);
46888 #if defined(W89C840_DEBUG)
46889 - decode_interrupt(intr_stat);
46890 + decode_interrupt(intr_stat);
46891 #endif
46893 - if (intr_stat & (NormalIntr | IntrTxDone)) {
46895 while ( (transmit_status & DescOwn) && timer2_running()) {
46897 transmit_status = w840private.tx_ring[entry].status;
46900 - writel(intr_stat & 0x0001ffff, ioaddr + IntrStatus);
46901 break;
46906 if ((transmit_status & DescOwn) == 0) {
46908 #if defined(W89C840_DEBUG)
46909 - printf("winbond-840 : transmission complete after %d wait loop iterations, status %X\n",
46910 - TX_LOOP_COUNT - transmit_loop_counter, w840private.tx_ring[entry].status);
46911 + printf("winbond-840 : transmission complete after wait loop iterations, status %X\n",
46912 + w840private.tx_ring[entry].status);
46913 #endif
46915 return;
46916 @@ -592,8 +579,12 @@
46917 /**************************************************************************
46918 w89c840_disable - Turn off ethernet interface
46919 ***************************************************************************/
46920 -static void w89c840_disable(struct nic *nic)
46921 +static void w89c840_disable(struct dev *dev)
46923 + struct nic *nic = (struct nic *)dev;
46924 + /* merge reset and disable */
46925 + w89c840_reset(nic);
46927 /* Don't know what to do to disable the board. Is this needed at all? */
46928 /* Yes, a live NIC can corrupt the loaded memory later [Ken] */
46929 /* Stop the chip's Tx and Rx processes. */
46930 @@ -601,20 +592,37 @@
46933 /**************************************************************************
46934 +w89c840_irq - Enable, Disable, or Force interrupts
46935 +***************************************************************************/
46936 +static void w89c840_irq(struct nic *nic __unused, irq_action_t action __unused)
46938 + switch ( action ) {
46939 + case DISABLE :
46940 + break;
46941 + case ENABLE :
46942 + break;
46943 + case FORCE :
46944 + break;
46948 +/**************************************************************************
46949 w89c840_probe - Look for an adapter, this routine's visible to the outside
46950 ***************************************************************************/
46951 -struct nic *w89c840_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *p)
46952 +static int w89c840_probe(struct dev *dev, struct pci_device *p)
46954 + struct nic *nic = (struct nic *)dev;
46955 u16 sum = 0;
46956 - int i, j, to;
46957 + int i, j;
46958 unsigned short value;
46959 - int options;
46960 - int promisc;
46962 - if (probe_addrs == 0 || probe_addrs[0] == 0)
46963 + if (p->ioaddr == 0)
46964 return 0;
46966 - ioaddr = probe_addrs[0]; /* Mask the bit that says "this is an io addr" */
46967 + ioaddr = p->ioaddr;
46968 + nic->ioaddr = p->ioaddr & ~3;
46969 + nic->irqno = 0;
46972 #if defined(W89C840_DEBUG)
46973 printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
46974 @@ -622,8 +630,6 @@
46976 ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
46978 - /* if probe_addrs is 0, then routine can use a hardwired default */
46980 /* From Matt Hortman <mbhortman@acpthinclient.com> */
46981 if (p->vendor == PCI_VENDOR_ID_WINBOND2
46982 && p->dev_id == PCI_DEVICE_ID_WINBOND2_89C840) {
46983 @@ -689,14 +695,14 @@
46986 /* point to NIC specific routines */
46987 - nic->reset = w89c840_reset;
46988 - nic->poll = w89c840_poll;
46989 + dev->disable = w89c840_disable;
46990 + nic->poll = w89c840_poll;
46991 nic->transmit = w89c840_transmit;
46992 - nic->disable = w89c840_disable;
46993 + nic->irq = w89c840_irq;
46995 w89c840_reset(nic);
46997 - return nic;
46998 + return 1;
47001 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. These are
47002 @@ -814,6 +820,7 @@
47003 return (retval>>1) & 0xffff;
47006 +#if 0
47007 static void mdio_write(int base_address, int phy_id, int location, int value)
47009 long mdio_addr = base_address + MIICtrl;
47010 @@ -844,6 +851,7 @@
47012 return;
47014 +#endif
47016 static void check_duplex(void)
47018 @@ -877,12 +885,10 @@
47019 memset(mc_filter, 0xff, sizeof(mc_filter));
47022 - * Actually, should work OK with multicast enabled. -- iko
47023 - */
47025 - * rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
47026 + * works OK with multicast enabled.
47028 - rx_mode = AcceptBroadcast | AcceptMyPhys;
47030 + rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
47032 writel(mc_filter[0], ioaddr + MulticastFilter0);
47033 writel(mc_filter[1], ioaddr + MulticastFilter1);
47034 @@ -932,3 +938,18 @@
47036 return;
47040 +static struct pci_id w89c840_nics[] = {
47041 +PCI_ROM(0x1050, 0x0840, "winbond840", "Winbond W89C840F"),
47042 +PCI_ROM(0x11f6, 0x2011, "compexrl100atx", "Compex RL100ATX"),
47045 +struct pci_driver w89c840_driver = {
47046 + .type = NIC_DRIVER,
47047 + .name = "W89C840F",
47048 + .probe = w89c840_probe,
47049 + .ids = w89c840_nics,
47050 + .id_count = sizeof(w89c840_nics)/sizeof(w89c840_nics[0]),
47051 + .class = 0,
47053 Index: b/stage2/disk_io.c
47054 ===================================================================
47055 --- a/stage2/disk_io.c
47056 +++ b/stage2/disk_io.c
47057 @@ -25,6 +25,7 @@
47058 #ifdef SUPPORT_NETBOOT
47059 # define GRUB 1
47060 # include <etherboot.h>
47061 +# include <grub.h>
47062 #endif
47064 #ifdef GRUB_UTIL