linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
@ 2004-12-17 14:54 Richard Ems
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Ems @ 2004-12-17 14:54 UTC (permalink / raw)
  To: linux-kernel, linux-net, Feedback, edward_peng

Hi list!

[1.] One line summary of the problem:
Network hang: "eth0: Tx timed out (f0080), is buffer full?"


[2.] Full description of the problem/report:

We had to reboot a server twice after a network card hang.
The first time was after one day uptime.
The second time, yesterday, after 8 days uptime.
The server is a dual AMD Athlon(tm) MP 2200+ with 1 GB RAM and is 
running SuSE Linux 9.2.

There are 2 NIC's on this system, a 10/100 Mbit/s 3Com Corporation 
3c905C-TX/TX-M [Tornado] which is not being used and a D-Link System Inc 
DL2000-based Gigabit Ethernet card.
The problem seems to be the dl2k driver for this second NIC.
The last minutes previous to the network hang and system hard reset 
(local login is not possible because of nfs mounts hang) the following 
lines were logged in /var/log/messages:

Dec  8 10:36:55 urutu kernel: eth0: HostError! IntStatus 0002.
Dec  8 10:36:55 urutu kernel: klogd 1.4.1, ---------- state change 
----------
Dec  8 10:38:48 urutu kernel: nfs: server jupiter not responding, still 
trying
Dec  8 10:39:48 urutu kernel: nfs: server diablo not responding, still 
trying

Dec  8 10:40:21 urutu kernel: eth0: Tx timed out (f0080), is buffer full?
Dec  8 10:43:25 urutu kernel: NETDEV WATCHDOG: eth0: transmit timed out
Dec  8 10:43:25 urutu kernel: eth0: Tx timed out (d0080), is buffer full?
Dec  8 10:46:57 urutu kernel: NETDEV WATCHDOG: eth0: transmit timed out
Dec  8 10:46:57 urutu kernel: eth0: Tx timed out (b0080), is buffer full?

On another thread I read that doing a ifconfg eth? down and up again 
would be enough to regain connectivity again.
Also just ping flooding the card will hang it.
See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=281819

The hardware wasn't changed the last months. The problem appeared after 
updating the 4th December from SuSE 9.0 (kernel 2.4.xx) to SuSE 9.2 
(kernel 2.6.8).

The card is configured as eth1 but the error above shows eth0! The 3Com 
card was detected as eth0 and it's down.

The dl2k driver was last updated 2002/10/03. I didn't find any 
maintainer listed in the Maintainers file.

Any idea what's happening? Should I go back to 2.4.xx? This is a 
production server with different people logged in using VNC, so testing 
changes is not so easy.


Many thanks, Richard





[3.] Keywords (i.e., modules, networking, kernel):
networking, d-link dl2k

[4.] Kernel version (from /proc/version):
Linux version 2.6.8-24.5-smp (geeko@buildhost) (gcc version 3.3.4 (pre 
3.3.5 20040809)) #1 SMP Wed Nov 17 11:10:06 UTC 2004

[5.] Output of Oops.. message (if applicable) with symbolic information
      resolved (see Documentation/oops-tracing.txt)
no oops

[6.] A small shell script or example program which triggers the
      problem (if possible)


[7.] Environment
[7.1.] Software (add the output of the ver_linux script here)

If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.

Linux urutu 2.6.8-24.5-smp #1 SMP Wed Nov 17 11:10:06 UTC 2004 i686 
athlon i386 GNU/Linux

Gnu C                  3.3.4
Gnu make               3.80
binutils               2.15.91.0.2
util-linux             2.12c
mount                  2.12c
module-init-tools      3.1-pre5
e2fsprogs              1.35
jfsutils               1.1.7
reiserfsprogs          3.6.18
reiser4progs           line
xfsprogs               2.6.13
PPP                    2.4.2
isdn4k-utils           3.5
nfs-utils              1.0.6
Linux C Library        x  1 root root 1359489 Oct  5 14:21 
/lib/tls/libc.so.6
Dynamic linker (ldd)   2.3.3
Linux C++ Library      5.0.7
Procps                 3.2.3
Net-tools              1.60
Kbd                    1.12
Sh-utils               5.2.1
Modules Loaded         nfsd exportfs autofs4 dl2k 3c59x edd joydev sg st 
sd_mod sr_mod scsi_mod ide_cd cdrom subfs amd_k7_agp agpgart hw_random 
evdevdm_mod usbcore ext3 jbd


[7.2.] Processor information (from /proc/cpuinfo):
processor       : 0
vendor_id       : AuthenticAMD
cpu family      : 6
model           : 8
model name      : AMD Athlon(tm) MP 2200+
stepping        : 1
cpu MHz         : 1800.416
cache size      : 256 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge 
mca cmov pat pse36 mmx fxsr sse pni syscall mp mmxext 3dnowext 3dnow
bogomips        : 3555.32

processor       : 1
vendor_id       : AuthenticAMD
cpu family      : 6
model           : 8
model name      : AMD Athlon(tm) Processor
stepping        : 1
cpu MHz         : 1800.416
cache size      : 256 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 1
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge 
mca cmov pat pse36 mmx fxsr sse pni syscall mp mmxext 3dnowext 3dnow
bogomips        : 3596.28


[7.3.] Module information (from /proc/modules):
nfsd 117960 9 - Live 0xf919a000
exportfs 10368 1 nfsd, Live 0xf90fc000
autofs4 23940 1 - Live 0xf9165000
dl2k 27044 0 - Live 0xf915d000
3c59x 43432 0 - Live 0xf916c000
edd 14620 0 - Live 0xf90e2000
joydev 13760 0 - Live 0xf90f2000
sg 42528 0 - Live 0xf9132000
st 43164 0 - Live 0xf9126000
sd_mod 22144 0 - Live 0xf911f000
sr_mod 21156 0 - Live 0xf9118000
scsi_mod 121412 4 sg,st,sd_mod,sr_mod, Live 0xf913e000
ide_cd 44448 0 - Live 0xf910c000
cdrom 42652 2 sr_mod,ide_cd, Live 0xf9100000
subfs 12672 2 - Live 0xf90e7000
amd_k7_agp 11788 1 - Live 0xf8865000
agpgart 37804 1 amd_k7_agp, Live 0xf8873000
hw_random 9620 0 - Live 0xf883b000
evdev 13184 0 - Live 0xf8836000
dm_mod 63104 6 - Live 0xf8854000
usbcore 120164 1 - Live 0xf90a5000
ext3 128744 7 - Live 0xf9002000
jbd 76964 1 ext3, Live 0xf8840000

[7.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)

# cat /proc/ioports
0000-001f : dma1
0020-0021 : pic1
0040-0043 : timer0
0050-0053 : timer1
0060-006f : keyboard
0070-0077 : rtc
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0170-0177 : ide1
01f0-01f7 : ide0
02f8-02ff : serial
0376-0376 : ide1
03c0-03df : vesafb
03f6-03f6 : ide0
03f8-03ff : serial
0cf8-0cff : PCI conf1
1000-10ff : 0000:00:08.0
   1000-10ff : dl2k
1410-1413 : 0000:00:00.0
2000-2fff : PCI Bus #01
   2000-20ff : 0000:01:05.0
3000-3fff : PCI Bus #02
   3000-307f : 0000:02:08.0
     3000-307f : 0000:02:08.0
8000-8003 : PM1a_EVT_BLK
8004-8005 : PM1a_CNT_BLK
8008-800b : PM_TMR
8020-8023 : GPE0_BLK
f000-f00f : 0000:00:07.1
   f000-f007 : ide0
   f008-f00f : ide1

# cat /proc/iomem
00000000-0009efff : System RAM
0009f000-0009ffff : reserved
000a0000-000bffff : Video RAM area
000c0000-000c7fff : Video ROM
000c8000-000c87ff : Adapter ROM
000f0000-000fffff : System ROM
00100000-3feeffff : System RAM
   00100000-0034888d : Kernel code
   0034888e-00416eff : Kernel data
3fef0000-3fefefff : ACPI Tables
3feff000-3fefffff : ACPI Non-volatile Storage
3ff00000-3fffffff : System RAM
f4000000-f40001ff : 0000:00:08.0
   f4000000-f40001ff : dl2k
f4100000-f5ffffff : PCI Bus #01
   f4100000-f4100fff : 0000:01:05.0
   f5000000-f5ffffff : 0000:01:05.0
     f5000000-f57effff : vesafb
f6000000-f60fffff : PCI Bus #02
   f6001000-f600107f : 0000:02:08.0
f6300000-f6300fff : 0000:00:00.0
f8000000-fbffffff : 0000:00:00.0
fec00000-fec07fff : reserved
fee00000-fee00fff : reserved
fff80000-ffffffff : reserved

[7.5.] PCI information ('lspci -vvv' as root)
0000:00:00.0 Host bridge: Advanced Micro Devices [AMD] AMD-760 MP 
[IGD4-2P] System Controller (rev 11)
         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap+ 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
         Latency: 64
         Region 0: Memory at f8000000 (32-bit, prefetchable)
         Region 1: Memory at f6300000 (32-bit, prefetchable) [size=4K]
         Region 2: I/O ports at 1410 [disabled] [size=4]
         Capabilities: [a0] AGP version 2.0
                 Status: RQ=16 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64- 
HTrans- 64bit- FW- AGP3- Rate=x1,x2
                 Command: RQ=1 ArqSz=0 Cal=0 SBA+ AGP+ GART64- 64bit- 
FW- Rate=x4

0000:00:01.0 PCI bridge: Advanced Micro Devices [AMD] AMD-760 MP 
[IGD4-2P] AGP Bridge (prog-if 00 [Normal decode])
         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-
         Latency: 99
         Bus: primary=00, secondary=01, subordinate=01, sec-latency=68
         I/O behind bridge: 00002000-00002fff
         Memory behind bridge: f4100000-f5ffffff
         Prefetchable memory behind bridge: fff00000-000fffff
         Expansion ROM at 00002000 [disabled] [size=4K]
         BridgeCtl: Parity- SERR- NoISA+ VGA+ MAbort- >Reset- FastB2B-

0000:00:07.0 ISA bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] ISA 
(rev 04)
         Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV- VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-
         Latency: 0

0000:00:07.1 IDE interface: Advanced Micro Devices [AMD] AMD-768 [Opus] 
IDE (rev 04) (prog-if 8a [Master SecP PriP])
         Subsystem: Advanced Micro Devices [AMD] AMD-768 [Opus] IDE
         Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-
         Latency: 0
         Region 4: I/O ports at f000 [size=16]

0000:00:07.3 Bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] ACPI 
(rev 03)
         Subsystem: Advanced Micro Devices [AMD] AMD-768 [Opus] ACPI
         Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-

0000:00:08.0 Ethernet controller: D-Link System Inc DL2000-based Gigabit 
Ethernet (rev 0c)
         Subsystem: D-Link System Inc DL2000-based Gigabit Ethernet
         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap+ 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-
         Latency: 64 (20000ns min, 2500ns max), cache line size 10
         Interrupt: pin A routed to IRQ 169
         Region 0: I/O ports at 1000
         Region 1: Memory at f4000000 (32-bit, non-prefetchable) [size=512]
         Capabilities: [50] Power Management version 2
                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA 
PME(D0-,D1+,D2+,D3hot+,D3cold-)
                 Status: D0 PME-Enable- DSel=0 DScale=2 PME-

0000:00:10.0 PCI bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] PCI 
(rev 04) (prog-if 00 [Normal decode])
         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
         Latency: 64
         Bus: primary=00, secondary=02, subordinate=02, sec-latency=168
         I/O behind bridge: 00003000-00003fff
         Memory behind bridge: f6000000-f60fffff
         Prefetchable memory behind bridge: fff00000-000fffff
         Expansion ROM at 00003000 [disabled] [size=4K]
         BridgeCtl: Parity- SERR- NoISA+ VGA- MAbort- >Reset- FastB2B-

0000:01:05.0 VGA compatible controller: ATI Technologies Inc Rage XL AGP 
2X (rev 27) (prog-if 00 [VGA])
         Subsystem: ATI Technologies Inc Xpert 98 RXL AGP 2X
         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping+ SERR- FastB2B-
         Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-
         Latency: 66 (2000ns min), cache line size 10
         Interrupt: pin A routed to IRQ 177
         Region 0: Memory at f5000000 (32-bit, non-prefetchable)
         Region 1: I/O ports at 2000 [size=256]
         Region 2: Memory at f4100000 (32-bit, non-prefetchable) [size=4K]
         Capabilities: [50] AGP version 1.0
                 Status: RQ=256 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64- 
HTrans- 64bit- FW- AGP3- Rate=x1,x2
                 Command: RQ=1 ArqSz=0 Cal=0 SBA- AGP- GART64- 64bit- 
FW- Rate=<none>
         Capabilities: [5c] Power Management version 2
                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA 
PME(D0-,D1-,D2-,D3hot-,D3cold-)
                 Status: D0 PME-Enable- DSel=0 DScale=0 PME-

0000:02:08.0 Ethernet controller: 3Com Corporation 3c905C-TX/TX-M 
[Tornado] (rev 78)
         Subsystem: Tyan Computer Tiger MPX S2466 (3C920 Integrated Fast 
Ethernet Controller)
         Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
         Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium 
 >TAbort- <TAbort- <MAbort- >SERR- <PERR-
         Latency: 80 (2500ns min, 2500ns max), cache line size 10
         Interrupt: pin A routed to IRQ 185
         Region 0: I/O ports at 3000
         Region 1: Memory at f6001000 (32-bit, non-prefetchable) [size=128]
         Capabilities: [dc] Power Management version 2
                 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA 
PME(D0+,D1+,D2+,D3hot+,D3cold+)
                 Status: D0 PME-Enable- DSel=0 DScale=2 PME-


[7.6.] SCSI information (from /proc/scsi/scsi)
(no scsi chip/card)

# cat /proc/scsi/scsi
Attached devices:

[7.7.] Other information that might be relevant to the problem
        (please look in /proc and include all information that you
        think to be relevant):

[X.] Other notes, patches, fixes, workarounds:


-- 
Richard Ems

MTG Marinetechnik GmbH
Wandsbeker Königstr. 62
22041 Hamburg
Telefon: +49 40 65803 312
TeleFax: +49 40 65803 392
mail: richard.ems@mtg-marinetechnik.de


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
  2005-01-04 21:32                           ` Jon Mason
@ 2005-01-04 22:09                             ` Francois Romieu
  0 siblings, 0 replies; 11+ messages in thread
From: Francois Romieu @ 2005-01-04 22:09 UTC (permalink / raw)
  To: Jon Mason; +Cc: Richard Ems, linux-kernel, linux-net

Jon Mason <jdmason@gmail.com> :
[...]
> @@ -1005,10 +1018,36 @@ rio_error (struct net_device *dev, int i
>         /* PCI Error, a catastronphic error related to the bus interface
>            occurs, set GlobalReset and HostReset to reset. */
>         if (int_status & HostError) {
> -               printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
> -                       dev->name, int_status);
> +               printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d
> %d %x %x\n",
> +                       dev->name, int_status, np->cur_tx, np->cur_rx,
> +                       readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
>                 writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
> +
> +               /* Free all the skbuffs in the queue. */
> +               for (i = 0; i < RX_RING_SIZE; i++) {
> +                       np->rx_ring[i].status = 0;
> +                       np->rx_ring[i].fraginfo = 0;
> +                       skb = np->rx_skbuff[i];
> +                       if (skb) {
> +                               pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo,
> +                                                 skb->len, PCI_DMA_FROMDEVICE);
> +                               dev_kfree_skb (skb);

It is probably a minor issue right now but skb->len seems inaccurate
(there is no guaranty that skb_put() was issued).

--
Ueimor

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
  2004-12-29 17:53                         ` Richard Ems
@ 2005-01-04 21:32                           ` Jon Mason
  2005-01-04 22:09                             ` Francois Romieu
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Mason @ 2005-01-04 21:32 UTC (permalink / raw)
  To: Richard Ems; +Cc: linux-kernel, linux-net

[-- Attachment #1: Type: text/plain, Size: 5469 bytes --]

Hello Richard,
Sorry for the long delay in responding.  I have found an error in the
patch I sent you, and I think I missed something.  The error was a
function defined twice.  The erro was lack of cleanup of the tx and rx
queues are the adapter reset.  The patch below (and attached) should
fix both of these errors.  Please apply it to the original driver.

Thanks,
Jon

--- dl2k.c,orig-save-2004.12.20 2004-12-21 09:43:19.000000000 -0600
+++ dl2k.c      2005-01-04 15:26:57.162033944 -0600
@@ -429,23 +429,16 @@ parse_eeprom (struct net_device *dev)
        return 0;
 }

-static int
-rio_open (struct net_device *dev)
+static void
+rio_up (struct net_device *dev)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int i;
        u16 macctrl;

-       i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
-       if (i)
-               return i;
-
-       /* Reset all logic functions */
-       writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
-               ioaddr + ASICCtrl + 2);
-       mdelay(10);
-
+       alloc_list (dev);
+
        /* DebugCtrl bit 4, 5, 9 must set */
        writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);

@@ -453,8 +446,6 @@ rio_open (struct net_device *dev)
        if (np->jumbo != 0)
                writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);

-       alloc_list (dev);
-
        /* Get station address */
        for (i = 0; i < 6; i++)
                writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
@@ -488,12 +479,6 @@ rio_open (struct net_device *dev)
                        ioaddr + MACCtrl);
        }

-       init_timer (&np->timer);
-       np->timer.expires = jiffies + 1*HZ;
-       np->timer.data = (unsigned long) dev;
-       np->timer.function = &rio_timer;
-       add_timer (&np->timer);
-
        /* Start Tx/Rx */
        writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
                        ioaddr + MACCtrl);
@@ -505,10 +490,36 @@ rio_open (struct net_device *dev)
        macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
        writew(macctrl, ioaddr + MACCtrl);

-       netif_start_queue (dev);
-
        /* Enable default interrupts */
        EnableInt ();
+}
+
+static int
+rio_open (struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       long ioaddr = dev->base_addr;
+       int i;
+
+       i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
+       if (i)
+               return i;
+
+       /* Reset all logic functions */
+       writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
+               ioaddr + ASICCtrl + 2);
+       mdelay(10);
+
+       rio_up (dev);
+
+       init_timer (&np->timer);
+       np->timer.expires = jiffies + 1*HZ;
+       np->timer.data = (unsigned long) dev;
+       np->timer.function = &rio_timer;
+       add_timer (&np->timer);
+
+       netif_start_queue (dev);
+
        return 0;
 }

@@ -562,9 +573,11 @@ static void
 rio_tx_timeout (struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
+       struct netdev_private *np = dev->priv;

-       printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-               dev->name, readl (ioaddr + TxStatus));
+       printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+               dev->name, readl (ioaddr + TxStatus), np->cur_tx, np->cur_rx,
+               readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
        rio_free_tx(dev, 0);
        dev->if_port = 0;
        dev->trans_start = jiffies;
@@ -1005,10 +1018,36 @@ rio_error (struct net_device *dev, int i
        /* PCI Error, a catastronphic error related to the bus interface
           occurs, set GlobalReset and HostReset to reset. */
        if (int_status & HostError) {
-               printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-                       dev->name, int_status);
+               printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d
%d %x %x\n",
+                       dev->name, int_status, np->cur_tx, np->cur_rx,
+                       readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
                writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
+
+               /* Free all the skbuffs in the queue. */
+               for (i = 0; i < RX_RING_SIZE; i++) {
+                       np->rx_ring[i].status = 0;
+                       np->rx_ring[i].fraginfo = 0;
+                       skb = np->rx_skbuff[i];
+                       if (skb) {
+                               pci_unmap_single (np->pdev,
np->rx_ring[i].fraginfo,
+                                                 skb->len, PCI_DMA_FROMDEVICE);
+                               dev_kfree_skb (skb);
+                               np->rx_skbuff[i] = NULL;
+                       }
+               }
+               for (i = 0; i < TX_RING_SIZE; i++) {
+                       skb = np->tx_skbuff[i];
+                       if (skb) {
+                               pci_unmap_single (np->pdev,
np->tx_ring[i].fraginfo,
+                                                 skb->len, PCI_DMA_TODEVICE);
+                               dev_kfree_skb (skb);
+                               np->tx_skbuff[i] = NULL;
+                       }
+               }
+
                mdelay (500);
+
+               rio_up(dev);
        }
 }

[-- Attachment #2: dl2k.patch3 --]
[-- Type: application/octet-stream, Size: 4015 bytes --]

--- dl2k.c,orig-save-2004.12.20	2004-12-21 09:43:19.000000000 -0600
+++ dl2k.c	2005-01-04 15:26:57.162033944 -0600
@@ -429,23 +429,16 @@ parse_eeprom (struct net_device *dev)
 	return 0;
 }
 
-static int
-rio_open (struct net_device *dev)
+static void
+rio_up (struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int i;
 	u16 macctrl;
 	
-	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
-	if (i)
-		return i;
-	
-	/* Reset all logic functions */
-	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
-		ioaddr + ASICCtrl + 2);
-	mdelay(10);
-	
+	alloc_list (dev);
+
 	/* DebugCtrl bit 4, 5, 9 must set */
 	writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
 
@@ -453,8 +446,6 @@ rio_open (struct net_device *dev)
 	if (np->jumbo != 0)
 		writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
 
-	alloc_list (dev);
-
 	/* Get station address */
 	for (i = 0; i < 6; i++)
 		writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
@@ -488,12 +479,6 @@ rio_open (struct net_device *dev)
 			ioaddr + MACCtrl);
 	}
 
-	init_timer (&np->timer);
-	np->timer.expires = jiffies + 1*HZ;
-	np->timer.data = (unsigned long) dev;
-	np->timer.function = &rio_timer;
-	add_timer (&np->timer);
-
 	/* Start Tx/Rx */
 	writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable, 
 			ioaddr + MACCtrl);
@@ -505,10 +490,36 @@ rio_open (struct net_device *dev)
 	macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
 	writew(macctrl,	ioaddr + MACCtrl);
 
-	netif_start_queue (dev);
-	
 	/* Enable default interrupts */
 	EnableInt ();
+}
+
+static int
+rio_open (struct net_device *dev)
+{
+	struct netdev_private *np = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	int i;
+	
+	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
+	if (i)
+		return i;
+	
+	/* Reset all logic functions */
+	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
+		ioaddr + ASICCtrl + 2);
+	mdelay(10);
+	
+	rio_up (dev);
+	
+	init_timer (&np->timer);
+	np->timer.expires = jiffies + 1*HZ;
+	np->timer.data = (unsigned long) dev;
+	np->timer.function = &rio_timer;
+	add_timer (&np->timer);
+
+	netif_start_queue (dev);
+	
 	return 0;
 }
 
@@ -562,9 +573,11 @@ static void
 rio_tx_timeout (struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 
-	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-		dev->name, readl (ioaddr + TxStatus));
+	printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+		dev->name, readl (ioaddr + TxStatus), np->cur_tx, np->cur_rx,
+		readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
 	rio_free_tx(dev, 0);
 	dev->if_port = 0;
 	dev->trans_start = jiffies;
@@ -1005,10 +1018,36 @@ rio_error (struct net_device *dev, int i
 	/* PCI Error, a catastronphic error related to the bus interface 
 	   occurs, set GlobalReset and HostReset to reset. */
 	if (int_status & HostError) {
-		printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-			dev->name, int_status);
+		printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d %d %x %x\n",
+			dev->name, int_status, np->cur_tx, np->cur_rx,
+			readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
 		writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
+		
+		/* Free all the skbuffs in the queue. */
+		for (i = 0; i < RX_RING_SIZE; i++) {
+			np->rx_ring[i].status = 0;
+			np->rx_ring[i].fraginfo = 0;
+			skb = np->rx_skbuff[i];
+			if (skb) {
+				pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo,
+						  skb->len, PCI_DMA_FROMDEVICE);
+				dev_kfree_skb (skb);
+				np->rx_skbuff[i] = NULL;
+			}
+		}
+		for (i = 0; i < TX_RING_SIZE; i++) {
+			skb = np->tx_skbuff[i];
+			if (skb) {
+				pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo,
+						  skb->len, PCI_DMA_TODEVICE);
+				dev_kfree_skb (skb);
+				np->tx_skbuff[i] = NULL;
+			}
+		}
+
 		mdelay (500);
+
+		rio_up(dev);
 	}
 }
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer  full?"
  2004-12-22 14:54                       ` Jon Mason
@ 2004-12-29 17:53                         ` Richard Ems
  2005-01-04 21:32                           ` Jon Mason
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Ems @ 2004-12-29 17:53 UTC (permalink / raw)
  To: Jon Mason; +Cc: linux-kernel, linux-net

Jon Mason wrote:
> Richard,
> Yes, I need the tx timeout lines.  Those tell me if the patch was
> successfull in solving the interrupt enablement issue.  From your
> statement below, it appears that it was either unsucessful (and you
> didn't wait long enough for it to timeout) or the root problem lies
> somewhere else.
> 
> Please give it a good 20 minutes (if you can get away with it being
> down for that long) to timeout, as it has been taking 5-10 minutes in
> your previous errors.  There is no set timeframe for it to timeout. 
> It will only timeout after netif_stop_queue has true for a minute.  if
> this never happens, then it leads me to believe that the adapter is
> still functioning.  I know you can't log in to the system because of
> the nfs mounts, but can you see if the system is pingable before you
> reboot it?

Hi Jon!

No, the system is not pingable from the outside but it still responds to 
pings from the inside after the hang happens if i'm logged in.

Here the last hang data. I can't get it to print the "tx timeout" lines.
Two hangs today, I waited 35/40 min and still no "tx timeout". But I got 
"Transmit error, TxStatus ..." lines which were not there in the past 
hangs. I must admit that I did a SuSE kernel update.
I had 2.6.8-24.5 installed now I have 2.6.8-24.10.
The dl2k driver is the same on both versions, your patch applied 
cleanly, the hang is still there.

How can I get "netif_stop_queue to have true for a minute" as you 
described to get the "tx timed out" lines? I can login before the hang 
and stay logged in to give some commands or get any more data that you 
could use to continue searching ...

Thanks, Richard


Dec 29 17:31:08 urutu kernel: eth1: Transmit error, TxStatus 0001, 
FrameId 0.
Dec 29 17:32:03 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:33:07 urutu kernel: eth1: Transmit error, TxStatus 0005, 
FrameId 0.
Dec 29 17:35:01 urutu /usr/sbin/cron[12663]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 17:37:02 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:37:32 urutu last message repeated 2 times
Dec 29 17:37:56 urutu kdm: urutu.mtg-marinetechnik.de:6[13087]: 
pam_unix2: session started for user ems2, service xdm
Dec 29 17:38:08 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:38:09 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:38:24 urutu kdm: urutu.mtg-marinetechnik.de:7[13254]: 
pam_unix2: session started for user ems2, service xdm
Dec 29 17:38:32 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:38:32 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:38:53 urutu kdm: urutu.mtg-marinetechnik.de:8[13548]: 
pam_unix2: session started for user ems2, service xdm
Dec 29 17:40:01 urutu /usr/sbin/cron[14078]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 17:42:03 urutu kdm[4064]: XDMCP socket creation failed, errno 97
Dec 29 17:42:03 urutu kernel: eth1: Transmit error, TxStatus 0007, 
FrameId 0.
Dec 29 17:42:20 urutu kernel: eth1: HostError! IntStatus 0002. 119 107 0 7c2
Dec 29 17:44:06 urutu kernel: nfs: server jupiter not responding, still 
trying
Dec 29 17:44:38 urutu last message repeated 3 times
Dec 29 17:44:38 urutu kernel: nfs: server jupiter not responding, still 
trying
Dec 29 17:45:01 urutu /usr/sbin/cron[15081]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 17:45:07 urutu kernel: nfs: server jupiter not responding, still 
trying
Dec 29 17:50:01 urutu /usr/sbin/cron[15163]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 17:55:01 urutu /usr/sbin/cron[15202]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 17:59:01 urutu /usr/sbin/cron[15211]: (root) CMD ( rm -f 
/var/spool/cron/lastrun/cron.hourly)
Dec 29 18:00:01 urutu /usr/sbin/cron[15218]: (root) CMD ( 
/usr/lib/sa/sa2 -A)
Dec 29 18:00:01 urutu /usr/sbin/cron[15215]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 18:05:01 urutu /usr/sbin/cron[15265]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 18:09:02 urutu login[4286]: FAILED LOGIN 1 FROM /dev/tty3 FOR 
root, Authentication failure
Dec 29 18:10:01 urutu /usr/sbin/cron[15325]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 18:15:01 urutu /usr/sbin/cron[15342]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 18:20:01 urutu /usr/sbin/cron[15376]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 18:25:01 urutu /usr/sbin/cron[15393]: (root) CMD ( 
/root/scripts/reboot-on-network-hang.sh)
Dec 29 18:29:14 urutu syslogd 1.4.1: restart.

-- 
Richard Ems
Tel: +49 40 65803 312
Fax: +49 40 65803 392
Richard.Ems@mtg-marinetechnik.de

MTG Marinetechnik GmbH - Wandsbeker Königstr. 62 - D 22041 Hamburg

GF Dipl.-Ing. Ullrich Keil
Handelsregister: Abt. B Nr. 11 500 - Amtsgericht Hamburg Abt. 66
USt.-IdNr.: DE 1186 70571


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
  2004-12-22  9:29                     ` Richard Ems
@ 2004-12-22 14:54                       ` Jon Mason
  2004-12-29 17:53                         ` Richard Ems
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Mason @ 2004-12-22 14:54 UTC (permalink / raw)
  To: Richard Ems; +Cc: linux-kernel, linux-net

Richard,
Yes, I need the tx timeout lines.  Those tell me if the patch was
successfull in solving the interrupt enablement issue.  From your
statement below, it appears that it was either unsucessful (and you
didn't wait long enough for it to timeout) or the root problem lies
somewhere else.

Please give it a good 20 minutes (if you can get away with it being
down for that long) to timeout, as it has been taking 5-10 minutes in
your previous errors.  There is no set timeframe for it to timeout. 
It will only timeout after netif_stop_queue has true for a minute.  if
this never happens, then it leads me to believe that the adapter is
still functioning.  I know you can't log in to the system because of
the nfs mounts, but can you see if the system is pingable before you
reboot it?

Thanks,
Jon

On Wed, 22 Dec 2004 10:29:55 +0100, Richard Ems
<richard.ems@mtg-marinetechnik.de> wrote:
> Jon, thanks for the last patch, it applied without errors or warnings.
> But the NIC is still hanging.
> Here the last hang data. Do you need the "Tx timed out" lines? I
> apparently didn't wait long enough for this timeout to trigger ...
> Is it a 5 min timeout?
> 
> Dec 22 10:00:37 urutu kernel: eth0: HostError! IntStatus 0082. 216 59
> 248001a0 7c2
> Dec 22 10:02:24 urutu kernel: nfs: server jupiter not responding, still
> trying
> Dec 22 10:02:55 urutu last message repeated 7 times
> Dec 22 10:03:52 urutu last message repeated 3 times
> Dec 22 10:04:14 urutu kernel: nfs: server jupiter not responding, still
> trying
> Dec 22 10:06:07 urutu syslogd 1.4.1: restart.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer  full?"
  2004-12-21 16:02                   ` Jon Mason
@ 2004-12-22  9:29                     ` Richard Ems
  2004-12-22 14:54                       ` Jon Mason
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Ems @ 2004-12-22  9:29 UTC (permalink / raw)
  To: Jon Mason; +Cc: linux-kernel, linux-net

Jon, thanks for the last patch, it applied without errors or warnings.
But the NIC is still hanging.
Here the last hang data. Do you need the "Tx timed out" lines? I 
apparently didn't wait long enough for this timeout to trigger ...
Is it a 5 min timeout?


Dec 22 10:00:37 urutu kernel: eth0: HostError! IntStatus 0082. 216 59 
248001a0 7c2
Dec 22 10:02:24 urutu kernel: nfs: server jupiter not responding, still 
trying
Dec 22 10:02:55 urutu last message repeated 7 times
Dec 22 10:03:52 urutu last message repeated 3 times
Dec 22 10:04:14 urutu kernel: nfs: server jupiter not responding, still 
trying
Dec 22 10:06:07 urutu syslogd 1.4.1: restart.



The folks at SuSE corrected several bugs in a new kernel just released, 
some of them are IP related. Is something related to the problem you are 
seeing?

1) problem description, brief discussion

     Linux kernel

         Several vulnerabilities have been found and fixed in the Linux
         kernel.


         Paul Starzetz reported that the missing serialization in
         unix_dgram_recvmsg() which was added to kernel 2.4.28 can
         be used by a local attacker to gain elevated privileges (root
         access). This issue is tracked by the Mitre CVE ID CAN-2004-1068.

         Paul Starzetz and Georgi Guninski reported independently that bad
         argument handling and bad integer arithmetics in the IPv4 sendmsg
         handling of control messages could lead to a local attacker 
crashing
         the machine.
         This problem was fixed by Herbert Xu and is tracked by the Mitre
         CVE ID CAN-2004-1016.

         Georgi Guninski reported a memory leak in the IP option handling
         of the IPv4 sendmsg call.

         Paul Starzetz found bad handling in the kernel IGMP code, which
         could lead to a local attacker being able to crash the machine.
         This problem was fixed by Chris Wright and is tracked by the Mitre
         CVE ID CAN-2004-1137.

         Olaf Kirch found and fixed a problem in the RPC handling in the
         kernel of SUSE Linux 9.1, 9.2, and SUSE Linux Enterprise Server 9
         which could lead to a remote attacker crashing the machine.

         A local denial of service problem in the aio_free_ring system call
         could allow a local attacker to crash the machine.

         A problem in the memory management handling of ELF executables 
could
         lead to a local attacker crashing the machine with a handcrafted
         ELF binary. (This is a VMA overlap problem and not related to
         earlier ELF problems.)

         A buffer overflow in the system call handling in the 32bit system
         call emulation on AMD64 / Intel EM64T systems was fixed. It is not
         thought to be exploitable.

         A memory leak in the ip_conntrack_ftp firewalling module was fixed
         in the 2.6 kernels.

         Various UML security issues in the SUSE Linux 9.2 UML setup
         were fixed.


         Additionally some non-security bugs were fixed in the released
         kernels:

	SUSE Linux Enterprise Server 8 and SUSE Linux 8.1:
	- A memory leak in addition / removal of SCSI target devices was
           fixed.

         - A race condition in SCSI I/O accounting which could lead to
           erroneous reports on SCSI disk I/O was fixed.

         - S390: Patches from IBM have been installed in the S/390
           architecture, both for 32 and 64bit.
           Refer to the maintenance information mail for the full change 
log.

	- The "memfrac" and "lower_zone_reserve" kernel parameters had
           no effect since they were used before kernel command line 
parsing.

         - PowerPC: Missing synchronization that could lead to processes
           hanging in signal delivery was added.


	SUSE Linux Enterprise Server 9 and SUSE Linux 9.1:
         - A vfree() was called with interrupts disabled in the SCSI generic
           device handling, which could lead to a hanging machine.

         - A race condition between a file unlink and umount could lead to a
           machine crash.

         - Fixed a small memory leak in bio_copy_user().

         - cdrecord -scanbus could crash the kernel when using the 
"gdth" SCSI
           driver.

         - Allow reading from zero page (/dev/zero) using O_DIRECT/rawio.

         - Fixed some LSB issues in the fcntl compatibility handling.

         - The st (SCSI tape) driver did not pass on generic SCSI ioctl
           commands to the SCSI mid layer.


         SUSE Linux 9.2:
         - The kernel installation routines did not call depmod for the 
modules
           in the -nongpl RPMs, so they could not be loaded.
           This lead to non working USB modem drivers and similar.
           This problem was fixed.

         - A Problem with mounting iPods over FireWire was fixed.

         - A data corruption problem in the megaraid driver was fixed.

         - A pageattr overflow condition in the memory subsystem
           and missing TLB flush if multiple pages were passed were fixed.

         - Allow reading from zeropage with O_DIRECT/rawio.

         - Do not restart the system on ACPI events after power down.
           (Make it no longer start on opening the lid of just shutdown
            laptops for instance.)

         - New memory imbalance handling handling by Andrea leading
           to better Out Of Memory (OOM) handling was added.




-- 
Richard Ems
Tel: +49 40 65803 312
Fax: +49 40 65803 392
Richard.Ems@mtg-marinetechnik.de

MTG Marinetechnik GmbH - Wandsbeker Königstr. 62 - D 22041 Hamburg

GF Dipl.-Ing. Ullrich Keil
Handelsregister: Abt. B Nr. 11 500 - Amtsgericht Hamburg Abt. 66
USt.-IdNr.: DE 1186 70571


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
  2004-12-21  9:51                 ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" Richard Ems
@ 2004-12-21 16:02                   ` Jon Mason
  2004-12-22  9:29                     ` Richard Ems
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Mason @ 2004-12-21 16:02 UTC (permalink / raw)
  To: Richard Ems; +Cc: linux-kernel, linux-net

[-- Attachment #1: Type: text/plain, Size: 5290 bytes --]

Sorry, I was working off of the mm driver.  I have verified that the
patch below will apply cleanly with the driver you provided (and the
previous patch applies cleanly to the 2.6.10-rc2-mm4 driver).

  
--- /root/dl2k.c,orig-save-2004.12.20   2004-12-21 09:46:56.877062552 -0600
+++ dl2k.c      2004-12-20 14:22:31.000000000 -0600
@@ -429,23 +431,14 @@ parse_eeprom (struct net_device *dev)
        return 0;
 }

-static int
-rio_open (struct net_device *dev)
+static void
+rio_up (struct net_device *dev)
 {
-       struct netdev_private *np = dev->priv;
+       struct netdev_private *np = netdev_priv(dev);
        long ioaddr = dev->base_addr;
        int i;
        u16 macctrl;

-       i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
-       if (i)
-               return i;
-
-       /* Reset all logic functions */
-       writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
-               ioaddr + ASICCtrl + 2);
-       mdelay(10);
-
        /* DebugCtrl bit 4, 5, 9 must set */
        writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);

@@ -453,8 +446,6 @@ rio_open (struct net_device *dev)
        if (np->jumbo != 0)
                writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);

-       alloc_list (dev);
-
        /* Get station address */
        for (i = 0; i < 6; i++)
                writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
@@ -488,12 +479,6 @@ rio_open (struct net_device *dev)
                        ioaddr + MACCtrl);
        }

-       init_timer (&np->timer);
-       np->timer.expires = jiffies + 1*HZ;
-       np->timer.data = (unsigned long) dev;
-       np->timer.function = &rio_timer;
-       add_timer (&np->timer);
-
        /* Start Tx/Rx */
        writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable,
                        ioaddr + MACCtrl);
@@ -505,10 +490,38 @@ rio_open (struct net_device *dev)
        macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
        writew(macctrl, ioaddr + MACCtrl);

-       netif_start_queue (dev);
-
        /* Enable default interrupts */
        EnableInt ();
+}
+
+static int
+rio_open (struct net_device *dev)
+{
+       struct netdev_private *np = netdev_priv(dev);
+       long ioaddr = dev->base_addr;
+       int i;
+
+       i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
+       if (i)
+               return i;
+
+       /* Reset all logic functions */
+       writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
+               ioaddr + ASICCtrl + 2);
+       mdelay(10);
+
+       alloc_list (dev);
+
+       rio_up (dev);
+
+       init_timer (&np->timer);
+       np->timer.expires = jiffies + 1*HZ;
+       np->timer.data = (unsigned long) dev;
+       np->timer.function = &rio_timer;
+       add_timer (&np->timer);
+
+       netif_start_queue (dev);
+
        return 0;
 }

@@ -562,9 +575,11 @@ static void
 rio_tx_timeout (struct net_device *dev)
 {
        long ioaddr = dev->base_addr;
+       struct netdev_private *np = dev->priv;

-       printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-               dev->name, readl (ioaddr + TxStatus));
+       printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+               dev->name, readl (ioaddr + TxStatus), np->cur_tx, np->cur_rx,
+               readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
        rio_free_tx(dev, 0);
        dev->if_port = 0;
        dev->trans_start = jiffies;
@@ -1005,10 +1020,13 @@ rio_error (struct net_device *dev, int i
        /* PCI Error, a catastronphic error related to the bus interface
           occurs, set GlobalReset and HostReset to reset. */
        if (int_status & HostError) {
-               printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-                       dev->name, int_status);
+               printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d
%d %x %x\n",
+                       dev->name, int_status, np->cur_tx, np->cur_rx,
+                       readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
                writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
                mdelay (500);
+
+               rio_up(dev);
        }
 }

On Tue, 21 Dec 2004 10:51:00 +0100, Richard Ems
<richard.ems@mtg-marinetechnik.de> wrote:
> The patch fails:
> 
> # patch -p0 < ~ems/dl2k.patch
> patching file dl2k.c
> Hunk #1 FAILED at 431.
> Hunk #2 succeeded at 444 (offset -2 lines).
> Hunk #3 succeeded at 477 (offset -2 lines).
> Hunk #4 succeeded at 488 (offset -2 lines).
> Hunk #5 succeeded at 573 (offset -2 lines).
> Hunk #6 succeeded at 1018 (offset -2 lines).
> 1 out of 6 hunks FAILED -- saving rejects to file dl2k.c.rej
> 
> I tried with --fuzz 9 but it didn't help.
> 
> I attached SuSE's original dl2k.c
> 
> Thanks, Richard
> 
> --
> Richard Ems
> Tel: +49 40 65803 312
> Fax: +49 40 65803 392
> Richard.Ems@mtg-marinetechnik.de
> 
> MTG Marinetechnik GmbH - Wandsbeker Königstr. 62 - D 22041 Hamburg
> 
> GF Dipl.-Ing. Ullrich Keil
> Handelsregister: Abt. B Nr. 11 500 - Amtsgericht Hamburg Abt. 66
> USt.-IdNr.: DE 1186 70571

[-- Attachment #2: dl2k.patch2 --]
[-- Type: application/octet-stream, Size: 3411 bytes --]

--- /root/dl2k.c,orig-save-2004.12.20	2004-12-21 09:46:56.877062552 -0600
+++ dl2k.c	2004-12-20 14:22:31.000000000 -0600
@@ -429,23 +431,14 @@ parse_eeprom (struct net_device *dev)
 	return 0;
 }
 
-static int
-rio_open (struct net_device *dev)
+static void
+rio_up (struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 	int i;
 	u16 macctrl;
 	
-	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
-	if (i)
-		return i;
-	
-	/* Reset all logic functions */
-	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
-		ioaddr + ASICCtrl + 2);
-	mdelay(10);
-	
 	/* DebugCtrl bit 4, 5, 9 must set */
 	writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);
 
@@ -453,8 +446,6 @@ rio_open (struct net_device *dev)
 	if (np->jumbo != 0)
 		writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);
 
-	alloc_list (dev);
-
 	/* Get station address */
 	for (i = 0; i < 6; i++)
 		writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);
@@ -488,12 +479,6 @@ rio_open (struct net_device *dev)
 			ioaddr + MACCtrl);
 	}
 
-	init_timer (&np->timer);
-	np->timer.expires = jiffies + 1*HZ;
-	np->timer.data = (unsigned long) dev;
-	np->timer.function = &rio_timer;
-	add_timer (&np->timer);
-
 	/* Start Tx/Rx */
 	writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable, 
 			ioaddr + MACCtrl);
@@ -505,10 +490,38 @@ rio_open (struct net_device *dev)
 	macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
 	writew(macctrl,	ioaddr + MACCtrl);
 
-	netif_start_queue (dev);
-	
 	/* Enable default interrupts */
 	EnableInt ();
+}
+
+static int
+rio_open (struct net_device *dev)
+{
+	struct netdev_private *np = netdev_priv(dev);
+	long ioaddr = dev->base_addr;
+	int i;
+	
+	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
+	if (i)
+		return i;
+	
+	/* Reset all logic functions */
+	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
+		ioaddr + ASICCtrl + 2);
+	mdelay(10);
+	
+	alloc_list (dev);
+
+	rio_up (dev);
+	
+	init_timer (&np->timer);
+	np->timer.expires = jiffies + 1*HZ;
+	np->timer.data = (unsigned long) dev;
+	np->timer.function = &rio_timer;
+	add_timer (&np->timer);
+
+	netif_start_queue (dev);
+	
 	return 0;
 }
 
@@ -562,9 +575,11 @@ static void
 rio_tx_timeout (struct net_device *dev)
 {
 	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
 
-	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-		dev->name, readl (ioaddr + TxStatus));
+	printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+		dev->name, readl (ioaddr + TxStatus), np->cur_tx, np->cur_rx,
+		readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
 	rio_free_tx(dev, 0);
 	dev->if_port = 0;
 	dev->trans_start = jiffies;
@@ -1005,10 +1020,13 @@ rio_error (struct net_device *dev, int i
 	/* PCI Error, a catastronphic error related to the bus interface 
 	   occurs, set GlobalReset and HostReset to reset. */
 	if (int_status & HostError) {
-		printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-			dev->name, int_status);
+		printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d %d %x %x\n",
+			dev->name, int_status, np->cur_tx, np->cur_rx,
+			readl (ioaddr + MACCtrl), readw(ioaddr + IntEnable));
 		writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
 		mdelay (500);
+
+		rio_up(dev);
 	}
 }

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer  full?"
  2004-12-20 20:31               ` Jon Mason
@ 2004-12-21  9:51                 ` Richard Ems
  2004-12-21 16:02                   ` Jon Mason
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Ems @ 2004-12-21  9:51 UTC (permalink / raw)
  To: Jon Mason; +Cc: linux-kernel, linux-net

[-- Attachment #1: Type: text/plain, Size: 751 bytes --]

The patch fails:

# patch -p0 < ~ems/dl2k.patch
patching file dl2k.c
Hunk #1 FAILED at 431.
Hunk #2 succeeded at 444 (offset -2 lines).
Hunk #3 succeeded at 477 (offset -2 lines).
Hunk #4 succeeded at 488 (offset -2 lines).
Hunk #5 succeeded at 573 (offset -2 lines).
Hunk #6 succeeded at 1018 (offset -2 lines).
1 out of 6 hunks FAILED -- saving rejects to file dl2k.c.rej

I tried with --fuzz 9 but it didn't help.

I attached SuSE's original dl2k.c

Thanks, Richard


-- 
Richard Ems
Tel: +49 40 65803 312
Fax: +49 40 65803 392
Richard.Ems@mtg-marinetechnik.de

MTG Marinetechnik GmbH - Wandsbeker Königstr. 62 - D 22041 Hamburg

GF Dipl.-Ing. Ullrich Keil
Handelsregister: Abt. B Nr. 11 500 - Amtsgericht Hamburg Abt. 66
USt.-IdNr.: DE 1186 70571

[-- Attachment #2: dl2k.c,orig-save-2004.12.20 --]
[-- Type: text/plain, Size: 51268 bytes --]

/*  D-Link DL2000-based Gigabit Ethernet Adapter Linux driver */
/*
    Copyright (c) 2001, 2002 by D-Link Corporation
    Written by Edward Peng.<edward_peng@dlink.com.tw>
    Created 03-May-2001, base on Linux' sundance.c.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
*/
/*
    Rev		Date		Description
    ==========================================================================
    0.01	2001/05/03	Created DL2000-based linux driver
    0.02	2001/05/21	Added VLAN and hardware checksum support.
    1.00	2001/06/26	Added jumbo frame support.
    1.01	2001/08/21	Added two parameters, rx_coalesce and rx_timeout.
    1.02	2001/10/08	Supported fiber media.
    				Added flow control parameters.
    1.03	2001/10/12	Changed the default media to 1000mbps_fd for 
    				the fiber devices.
    1.04	2001/11/08	Fixed Tx stopped when tx very busy.
    1.05	2001/11/22	Fixed Tx stopped when unidirectional tx busy.
    1.06	2001/12/13	Fixed disconnect bug at 10Mbps mode.
    				Fixed tx_full flag incorrect.
				Added tx_coalesce paramter.
    1.07	2002/01/03	Fixed miscount of RX frame error.
    1.08	2002/01/17	Fixed the multicast bug.
    1.09	2002/03/07	Move rx-poll-now to re-fill loop.	
    				Added rio_timer() to watch rx buffers. 
    1.10	2002/04/16	Fixed miscount of carrier error.
    1.11	2002/05/23	Added ISR schedule scheme
    				Fixed miscount of rx frame error for DGE-550SX.
    				Fixed VLAN bug.
    1.12	2002/06/13	Lock tx_coalesce=1 on 10/100Mbps mode.
    1.13	2002/08/13	1. Fix disconnection (many tx:carrier/rx:frame
    				   errs) with some mainboards.
    				2. Use definition "DRV_NAME" "DRV_VERSION" 
				   "DRV_RELDATE" for flexibility.	
    1.14	2002/08/14	Support ethtool.	
    1.15	2002/08/27	Changed the default media to Auto-Negotiation
				for the fiber devices.    
    1.16	2002/09/04      More power down time for fiber devices auto-
    				negotiation.
				Fix disconnect bug after ifup and ifdown.
    1.17	2002/10/03	Fix RMON statistics overflow. 
			     	Always use I/O mapping to access eeprom, 
				avoid system freezing with some chipsets.

*/
#define DRV_NAME	"D-Link DL2000-based linux driver"
#define DRV_VERSION	"v1.17a"
#define DRV_RELDATE	"2002/10/04"
#include "dl2k.h"

static char version[] __devinitdata =
      KERN_INFO DRV_NAME " " DRV_VERSION " " DRV_RELDATE "\n";	
#define MAX_UNITS 8
static int mtu[MAX_UNITS];
static int vlan[MAX_UNITS];
static int jumbo[MAX_UNITS];
static char *media[MAX_UNITS];
static int tx_flow=-1;
static int rx_flow=-1;
static int copy_thresh;
static int rx_coalesce=10;	/* Rx frame count each interrupt */
static int rx_timeout=200;	/* Rx DMA wait time in 640ns increments */
static int tx_coalesce=16;	/* HW xmit count each TxDMAComplete */


MODULE_AUTHOR ("Edward Peng");
MODULE_DESCRIPTION ("D-Link DL2000-based Gigabit Ethernet Adapter");
MODULE_LICENSE("GPL");
MODULE_PARM (mtu, "1-" __MODULE_STRING (MAX_UNITS) "i");
MODULE_PARM (media, "1-" __MODULE_STRING (MAX_UNITS) "s");
MODULE_PARM (vlan, "1-" __MODULE_STRING (MAX_UNITS) "i");
MODULE_PARM (jumbo, "1-" __MODULE_STRING (MAX_UNITS) "i");
MODULE_PARM (tx_flow, "i");
MODULE_PARM (rx_flow, "i");
MODULE_PARM (copy_thresh, "i");
MODULE_PARM (rx_coalesce, "i");	/* Rx frame count each interrupt */
MODULE_PARM (rx_timeout, "i");	/* Rx DMA wait time in 64ns increments */
MODULE_PARM (tx_coalesce, "i"); /* HW xmit count each TxDMAComplete */


/* Enable the default interrupts */
#define DEFAULT_INTR (RxDMAComplete | HostError | IntRequested | TxDMAComplete| \
       UpdateStats | LinkEvent)
#define EnableInt() \
writew(DEFAULT_INTR, ioaddr + IntEnable)

static int max_intrloop = 50;
static int multicast_filter_limit = 0x40;

static int rio_open (struct net_device *dev);
static void rio_timer (unsigned long data);
static void rio_tx_timeout (struct net_device *dev);
static void alloc_list (struct net_device *dev);
static int start_xmit (struct sk_buff *skb, struct net_device *dev);
static irqreturn_t rio_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void rio_free_tx (struct net_device *dev, int irq);
static void tx_error (struct net_device *dev, int tx_status);
static int receive_packet (struct net_device *dev);
static void rio_error (struct net_device *dev, int int_status);
static int change_mtu (struct net_device *dev, int new_mtu);
static void set_multicast (struct net_device *dev);
static struct net_device_stats *get_stats (struct net_device *dev);
static int clear_stats (struct net_device *dev);
static int rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr);
static int rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static int rio_close (struct net_device *dev);
static int find_miiphy (struct net_device *dev);
static int parse_eeprom (struct net_device *dev);
static int read_eeprom (long ioaddr, int eep_addr);
static int mii_wait_link (struct net_device *dev, int wait);
static int mii_set_media (struct net_device *dev);
static int mii_get_media (struct net_device *dev);
static int mii_set_media_pcs (struct net_device *dev);
static int mii_get_media_pcs (struct net_device *dev);
static int mii_read (struct net_device *dev, int phy_addr, int reg_num);
static int mii_write (struct net_device *dev, int phy_addr, int reg_num,
		      u16 data);

static int __devinit
rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev;
	struct netdev_private *np;
	static int card_idx;
	int chip_idx = ent->driver_data;
	int err, irq;
	long ioaddr;
	static int version_printed;
	void *ring_space;
	dma_addr_t ring_dma;

	if (!version_printed++)
		printk ("%s", version);

	err = pci_enable_device (pdev);
	if (err)
		return err;

	irq = pdev->irq;
	err = pci_request_regions (pdev, "dl2k");
	if (err)
		goto err_out_disable;

	pci_set_master (pdev);
	dev = alloc_etherdev (sizeof (*np));
	if (!dev) {
		err = -ENOMEM;
		goto err_out_res;
	}
	SET_MODULE_OWNER (dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

#ifdef MEM_MAPPING
	ioaddr = pci_resource_start (pdev, 1);
	ioaddr = (long) ioremap (ioaddr, RIO_IO_SIZE);
	if (!ioaddr) {
		err = -ENOMEM;
		goto err_out_dev;
	}
#else
	ioaddr = pci_resource_start (pdev, 0);
#endif
	dev->base_addr = ioaddr;
	dev->irq = irq;
	np = dev->priv;
	np->chip_id = chip_idx;
	np->pdev = pdev;
	spin_lock_init (&np->tx_lock);
	spin_lock_init (&np->rx_lock);

	/* Parse manual configuration */
	np->an_enable = 1;
	np->tx_coalesce = 1;
	if (card_idx < MAX_UNITS) {
		if (media[card_idx] != NULL) {
			np->an_enable = 0;
			if (strcmp (media[card_idx], "auto") == 0 ||
			    strcmp (media[card_idx], "autosense") == 0 || 
			    strcmp (media[card_idx], "0") == 0 ) {
				np->an_enable = 2; 
			} else if (strcmp (media[card_idx], "100mbps_fd") == 0 ||
			    strcmp (media[card_idx], "4") == 0) {
				np->speed = 100;
				np->full_duplex = 1;
			} else if (strcmp (media[card_idx], "100mbps_hd") == 0
				   || strcmp (media[card_idx], "3") == 0) {
				np->speed = 100;
				np->full_duplex = 0;
			} else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||
				   strcmp (media[card_idx], "2") == 0) {
				np->speed = 10;
				np->full_duplex = 1;
			} else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||
				   strcmp (media[card_idx], "1") == 0) {
				np->speed = 10;
				np->full_duplex = 0;
			} else if (strcmp (media[card_idx], "1000mbps_fd") == 0 ||
				 strcmp (media[card_idx], "6") == 0) {
				np->speed=1000;
				np->full_duplex=1;
			} else if (strcmp (media[card_idx], "1000mbps_hd") == 0 ||
				 strcmp (media[card_idx], "5") == 0) {
				np->speed = 1000;
				np->full_duplex = 0;
			} else {
				np->an_enable = 1;
			}
		}
		if (jumbo[card_idx] != 0) {
			np->jumbo = 1;
			dev->mtu = MAX_JUMBO;
		} else {
			np->jumbo = 0;
			if (mtu[card_idx] > 0 && mtu[card_idx] < PACKET_SIZE)
				dev->mtu = mtu[card_idx];
		}
		np->vlan = (vlan[card_idx] > 0 && vlan[card_idx] < 4096) ?
		    vlan[card_idx] : 0;
		if (rx_coalesce > 0 && rx_timeout > 0) {
			np->rx_coalesce = rx_coalesce;
			np->rx_timeout = rx_timeout;
			np->coalesce = 1;
		}
		np->tx_flow = (tx_flow == 0) ? 0 : 1;
		np->rx_flow = (rx_flow == 0) ? 0 : 1;

		if (tx_coalesce < 1)
			tx_coalesce = 1;
		else if (tx_coalesce > TX_RING_SIZE-1)
			tx_coalesce = TX_RING_SIZE - 1;
	}
	dev->open = &rio_open;
	dev->hard_start_xmit = &start_xmit;
	dev->stop = &rio_close;
	dev->get_stats = &get_stats;
	dev->set_multicast_list = &set_multicast;
	dev->do_ioctl = &rio_ioctl;
	dev->tx_timeout = &rio_tx_timeout;
	dev->watchdog_timeo = TX_TIMEOUT;
	dev->change_mtu = &change_mtu;
#if 0
	dev->features = NETIF_F_IP_CSUM;
#endif
	pci_set_drvdata (pdev, dev);

	ring_space = pci_alloc_consistent (pdev, TX_TOTAL_SIZE, &ring_dma);
	if (!ring_space)
		goto err_out_iounmap;
	np->tx_ring = (struct netdev_desc *) ring_space;
	np->tx_ring_dma = ring_dma;

	ring_space = pci_alloc_consistent (pdev, RX_TOTAL_SIZE, &ring_dma);
	if (!ring_space)
		goto err_out_unmap_tx;
	np->rx_ring = (struct netdev_desc *) ring_space;
	np->rx_ring_dma = ring_dma;

	/* Parse eeprom data */
	parse_eeprom (dev);

	/* Find PHY address */
	err = find_miiphy (dev);
	if (err)
		goto err_out_unmap_rx;
	
	/* Fiber device? */
	np->phy_media = (readw(ioaddr + ASICCtrl) & PhyMedia) ? 1 : 0;
	np->link_status = 0;
	/* Set media and reset PHY */
	if (np->phy_media) {
		/* default Auto-Negotiation for fiber deivices */
	 	if (np->an_enable == 2) {
			np->an_enable = 1;
		}
		mii_set_media_pcs (dev);
	} else {
		/* Auto-Negotiation is mandatory for 1000BASE-T,
		   IEEE 802.3ab Annex 28D page 14 */
		if (np->speed == 1000)
			np->an_enable = 1;
		mii_set_media (dev);
	}
	pci_read_config_byte(pdev, PCI_REVISION_ID, &np->pci_rev_id);

	err = register_netdev (dev);
	if (err)
		goto err_out_unmap_rx;

	card_idx++;

	printk (KERN_INFO "%s: %s, %02x:%02x:%02x:%02x:%02x:%02x, IRQ %d\n",
		dev->name, np->name,
		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], irq);
	if (tx_coalesce > 1)
		printk(KERN_INFO "tx_coalesce:\t%d packets\n", 
				tx_coalesce);
	if (np->coalesce)
		printk(KERN_INFO "rx_coalesce:\t%d packets\n"
		       KERN_INFO "rx_timeout: \t%d ns\n", 
				np->rx_coalesce, np->rx_timeout*640);
	if (np->vlan)
		printk(KERN_INFO "vlan(id):\t%d\n", np->vlan);
	return 0;

      err_out_unmap_rx:
	pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);
      err_out_unmap_tx:
	pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);
      err_out_iounmap:
#ifdef MEM_MAPPING
	iounmap ((void *) ioaddr);

      err_out_dev:
#endif
	free_netdev (dev);

      err_out_res:
	pci_release_regions (pdev);

      err_out_disable:
	pci_disable_device (pdev);
	return err;
}

int
find_miiphy (struct net_device *dev)
{
	int i, phy_found = 0;
	struct netdev_private *np;
	long ioaddr;
	np = dev->priv;
	ioaddr = dev->base_addr;
	np->phy_addr = 1;

	for (i = 31; i >= 0; i--) {
		int mii_status = mii_read (dev, i, 1);
		if (mii_status != 0xffff && mii_status != 0x0000) {
			np->phy_addr = i;
			phy_found++;
		}
	}
	if (!phy_found) {
		printk (KERN_ERR "%s: No MII PHY found!\n", dev->name);
		return -ENODEV;
	}
	return 0;
}

int
parse_eeprom (struct net_device *dev)
{
	int i, j;
	long ioaddr = dev->base_addr;
	u8 sromdata[256];
	u8 *psib;
	u32 crc;
	PSROM_t psrom = (PSROM_t) sromdata;
	struct netdev_private *np = dev->priv;

	int cid, next;

#ifdef	MEM_MAPPING
	ioaddr = pci_resource_start (np->pdev, 0);
#endif
	/* Read eeprom */
	for (i = 0; i < 128; i++) {
		((u16 *) sromdata)[i] = le16_to_cpu (read_eeprom (ioaddr, i));
	}
#ifdef	MEM_MAPPING
	ioaddr = dev->base_addr;
#endif	
	/* Check CRC */
	crc = ~ether_crc_le (256 - 4, sromdata);
	if (psrom->crc != crc) {
		printk (KERN_ERR "%s: EEPROM data CRC error.\n", dev->name);
		return -1;
	}

	/* Set MAC address */
	for (i = 0; i < 6; i++)
		dev->dev_addr[i] = psrom->mac_addr[i];

	/* Parse Software Infomation Block */
	i = 0x30;
	psib = (u8 *) sromdata;
	do {
		cid = psib[i++];
		next = psib[i++];
		if ((cid == 0 && next == 0) || (cid == 0xff && next == 0xff)) {
			printk (KERN_ERR "Cell data error\n");
			return -1;
		}
		switch (cid) {
		case 0:	/* Format version */
			break;
		case 1:	/* End of cell */
			return 0;
		case 2:	/* Duplex Polarity */
			np->duplex_polarity = psib[i];
			writeb (readb (ioaddr + PhyCtrl) | psib[i],
				ioaddr + PhyCtrl);
			break;
		case 3:	/* Wake Polarity */
			np->wake_polarity = psib[i];
			break;
		case 9:	/* Adapter description */
			j = (next - i > 255) ? 255 : next - i;
			memcpy (np->name, &(psib[i]), j);
			break;
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:	/* Reversed */
			break;
		default:	/* Unknown cell */
			return -1;
		}
		i = next;
	} while (1);

	return 0;
}

static int
rio_open (struct net_device *dev)
{
	struct netdev_private *np = dev->priv;
	long ioaddr = dev->base_addr;
	int i;
	u16 macctrl;
	
	i = request_irq (dev->irq, &rio_interrupt, SA_SHIRQ, dev->name, dev);
	if (i)
		return i;
	
	/* Reset all logic functions */
	writew (GlobalReset | DMAReset | FIFOReset | NetworkReset | HostReset,
		ioaddr + ASICCtrl + 2);
	mdelay(10);
	
	/* DebugCtrl bit 4, 5, 9 must set */
	writel (readl (ioaddr + DebugCtrl) | 0x0230, ioaddr + DebugCtrl);

	/* Jumbo frame */
	if (np->jumbo != 0)
		writew (MAX_JUMBO+14, ioaddr + MaxFrameSize);

	alloc_list (dev);

	/* Get station address */
	for (i = 0; i < 6; i++)
		writeb (dev->dev_addr[i], ioaddr + StationAddr0 + i);

	set_multicast (dev);
	if (np->coalesce) {
		writel (np->rx_coalesce | np->rx_timeout << 16,
			ioaddr + RxDMAIntCtrl);
	}
	/* Set RIO to poll every N*320nsec. */
	writeb (0x20, ioaddr + RxDMAPollPeriod);
	writeb (0xff, ioaddr + TxDMAPollPeriod);
	writeb (0x30, ioaddr + RxDMABurstThresh);
	writeb (0x30, ioaddr + RxDMAUrgentThresh);
	writel (0x0007ffff, ioaddr + RmonStatMask);
	/* clear statistics */
	clear_stats (dev);

	/* VLAN supported */
	if (np->vlan) {
		/* priority field in RxDMAIntCtrl  */
		writel (readl(ioaddr + RxDMAIntCtrl) | 0x7 << 10, 
			ioaddr + RxDMAIntCtrl);
		/* VLANId */
		writew (np->vlan, ioaddr + VLANId);
		/* Length/Type should be 0x8100 */
		writel (0x8100 << 16 | np->vlan, ioaddr + VLANTag);
		/* Enable AutoVLANuntagging, but disable AutoVLANtagging.
		   VLAN information tagged by TFC' VID, CFI fields. */
		writel (readl (ioaddr + MACCtrl) | AutoVLANuntagging,
			ioaddr + MACCtrl);
	}

	init_timer (&np->timer);
	np->timer.expires = jiffies + 1*HZ;
	np->timer.data = (unsigned long) dev;
	np->timer.function = &rio_timer;
	add_timer (&np->timer);

	/* Start Tx/Rx */
	writel (readl (ioaddr + MACCtrl) | StatsEnable | RxEnable | TxEnable, 
			ioaddr + MACCtrl);
	
	macctrl = 0;
	macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
	macctrl |= (np->full_duplex) ? DuplexSelect : 0;
	macctrl |= (np->tx_flow) ? TxFlowControlEnable : 0;
	macctrl |= (np->rx_flow) ? RxFlowControlEnable : 0;
	writew(macctrl,	ioaddr + MACCtrl);

	netif_start_queue (dev);
	
	/* Enable default interrupts */
	EnableInt ();
	return 0;
}

static void 
rio_timer (unsigned long data)
{
	struct net_device *dev = (struct net_device *)data;
	struct netdev_private *np = dev->priv;
	unsigned int entry;
	int next_tick = 1*HZ;
	unsigned long flags;

	spin_lock_irqsave(&np->rx_lock, flags);
	/* Recover rx ring exhausted error */
	if (np->cur_rx - np->old_rx >= RX_RING_SIZE) {
		printk(KERN_INFO "Try to recover rx ring exhausted...\n");
		/* Re-allocate skbuffs to fill the descriptor ring */
		for (; np->cur_rx - np->old_rx > 0; np->old_rx++) {
			struct sk_buff *skb;
			entry = np->old_rx % RX_RING_SIZE;
			/* Dropped packets don't need to re-allocate */
			if (np->rx_skbuff[entry] == NULL) {
				skb = dev_alloc_skb (np->rx_buf_sz);
				if (skb == NULL) {
					np->rx_ring[entry].fraginfo = 0;
					printk (KERN_INFO
						"%s: Still unable to re-allocate Rx skbuff.#%d\n",
						dev->name, entry);
					break;
				}
				np->rx_skbuff[entry] = skb;
				skb->dev = dev;
				/* 16 byte align the IP header */
				skb_reserve (skb, 2);
				np->rx_ring[entry].fraginfo =
				    cpu_to_le64 (pci_map_single
					 (np->pdev, skb->tail, np->rx_buf_sz,
					  PCI_DMA_FROMDEVICE));
			}
			np->rx_ring[entry].fraginfo |=
			    cpu_to_le64 (np->rx_buf_sz) << 48;
			np->rx_ring[entry].status = 0;
		} /* end for */
	} /* end if */
	spin_unlock_irqrestore (&np->rx_lock, flags);
	np->timer.expires = jiffies + next_tick;
	add_timer(&np->timer);
}
	
static void
rio_tx_timeout (struct net_device *dev)
{
	long ioaddr = dev->base_addr;

	printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
		dev->name, readl (ioaddr + TxStatus));
	rio_free_tx(dev, 0);
	dev->if_port = 0;
	dev->trans_start = jiffies;
}

 /* allocate and initialize Tx and Rx descriptors */
static void
alloc_list (struct net_device *dev)
{
	struct netdev_private *np = dev->priv;
	int i;

	np->cur_rx = np->cur_tx = 0;
	np->old_rx = np->old_tx = 0;
	np->rx_buf_sz = (dev->mtu <= 1500 ? PACKET_SIZE : dev->mtu + 32);

	/* Initialize Tx descriptors, TFDListPtr leaves in start_xmit(). */
	for (i = 0; i < TX_RING_SIZE; i++) {
		np->tx_skbuff[i] = NULL;
		np->tx_ring[i].status = cpu_to_le64 (TFDDone);
		np->tx_ring[i].next_desc = cpu_to_le64 (np->tx_ring_dma +
					      ((i+1)%TX_RING_SIZE) *
					      sizeof (struct netdev_desc));
	}

	/* Initialize Rx descriptors */
	for (i = 0; i < RX_RING_SIZE; i++) {
		np->rx_ring[i].next_desc = cpu_to_le64 (np->rx_ring_dma +
						((i + 1) % RX_RING_SIZE) *
						sizeof (struct netdev_desc));
		np->rx_ring[i].status = 0;
		np->rx_ring[i].fraginfo = 0;
		np->rx_skbuff[i] = NULL;
	}

	/* Allocate the rx buffers */
	for (i = 0; i < RX_RING_SIZE; i++) {
		/* Allocated fixed size of skbuff */
		struct sk_buff *skb = dev_alloc_skb (np->rx_buf_sz);
		np->rx_skbuff[i] = skb;
		if (skb == NULL) {
			printk (KERN_ERR
				"%s: alloc_list: allocate Rx buffer error! ",
				dev->name);
			break;
		}
		skb->dev = dev;	/* Mark as being used by this device. */
		skb_reserve (skb, 2);	/* 16 byte align the IP header. */
		/* Rubicon now supports 40 bits of addressing space. */
		np->rx_ring[i].fraginfo =
		    cpu_to_le64 ( pci_map_single (
			 	  np->pdev, skb->tail, np->rx_buf_sz,
				  PCI_DMA_FROMDEVICE));
		np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48;
	}

	/* Set RFDListPtr */
	writel (cpu_to_le32 (np->rx_ring_dma), dev->base_addr + RFDListPtr0);
	writel (0, dev->base_addr + RFDListPtr1);

	return;
}

static int
start_xmit (struct sk_buff *skb, struct net_device *dev)
{
	struct netdev_private *np = dev->priv;
	struct netdev_desc *txdesc;
	unsigned entry;
	u32 ioaddr;
	u64 tfc_vlan_tag = 0;

	if (np->link_status == 0) {	/* Link Down */
		dev_kfree_skb(skb);
		return 0;
	}
	ioaddr = dev->base_addr;
	entry = np->cur_tx % TX_RING_SIZE;
	np->tx_skbuff[entry] = skb;
	txdesc = &np->tx_ring[entry];

#if 0
	if (skb->ip_summed == CHECKSUM_HW) {
		txdesc->status |=
		    cpu_to_le64 (TCPChecksumEnable | UDPChecksumEnable |
				 IPChecksumEnable);
	}
#endif
	if (np->vlan) {
		tfc_vlan_tag =
		    cpu_to_le64 (VLANTagInsert) |
		    (cpu_to_le64 (np->vlan) << 32) |
		    (cpu_to_le64 (skb->priority) << 45);
	}
	txdesc->fraginfo = cpu_to_le64 (pci_map_single (np->pdev, skb->data,
							skb->len,
							PCI_DMA_TODEVICE));
	txdesc->fraginfo |= cpu_to_le64 (skb->len) << 48;

	/* DL2K bug: DMA fails to get next descriptor ptr in 10Mbps mode
	 * Work around: Always use 1 descriptor in 10Mbps mode */
	if (entry % np->tx_coalesce == 0 || np->speed == 10)
		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
					      WordAlignDisable | 
					      TxDMAIndicate |
					      (1 << FragCountShift));
	else
		txdesc->status = cpu_to_le64 (entry | tfc_vlan_tag |
					      WordAlignDisable | 
					      (1 << FragCountShift));

	/* TxDMAPollNow */
	writel (readl (ioaddr + DMACtrl) | 0x00001000, ioaddr + DMACtrl);
	/* Schedule ISR */
	writel(10000, ioaddr + CountDown);
	np->cur_tx = (np->cur_tx + 1) % TX_RING_SIZE;
	if ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE
			< TX_QUEUE_LEN - 1 && np->speed != 10) {
		/* do nothing */
	} else if (!netif_queue_stopped(dev)) {
		netif_stop_queue (dev);
	}

	/* The first TFDListPtr */
	if (readl (dev->base_addr + TFDListPtr0) == 0) {
		writel (np->tx_ring_dma + entry * sizeof (struct netdev_desc),
			dev->base_addr + TFDListPtr0);
		writel (0, dev->base_addr + TFDListPtr1);
	}
	
	/* NETDEV WATCHDOG timer */
	dev->trans_start = jiffies;
	return 0;
}

static irqreturn_t
rio_interrupt (int irq, void *dev_instance, struct pt_regs *rgs)
{
	struct net_device *dev = dev_instance;
	struct netdev_private *np;
	unsigned int_status;
	long ioaddr;
	int cnt = max_intrloop;
	int handled = 0;

	ioaddr = dev->base_addr;
	np = dev->priv;
	while (1) {
		int_status = readw (ioaddr + IntStatus); 
		writew (int_status, ioaddr + IntStatus);
		int_status &= DEFAULT_INTR;
		if (int_status == 0 || --cnt < 0)
			break;
		handled = 1;
		/* Processing received packets */
		if (int_status & RxDMAComplete)
			receive_packet (dev);
		/* TxDMAComplete interrupt */
		if ((int_status & (TxDMAComplete|IntRequested))) {
			int tx_status;
			tx_status = readl (ioaddr + TxStatus);
			if (tx_status & 0x01)
				tx_error (dev, tx_status);
			/* Free used tx skbuffs */
			rio_free_tx (dev, 1);		
		}

		/* Handle uncommon events */
		if (int_status &
		    (HostError | LinkEvent | UpdateStats))
			rio_error (dev, int_status);
	}
	if (np->cur_tx != np->old_tx)
		writel (100, ioaddr + CountDown);
	return IRQ_RETVAL(handled);
}

static void 
rio_free_tx (struct net_device *dev, int irq) 
{
	struct netdev_private *np = dev->priv;
	int entry = np->old_tx % TX_RING_SIZE;
	int tx_use = 0;
	unsigned long flag = 0;
	
	if (irq)
		spin_lock(&np->tx_lock);
	else
		spin_lock_irqsave(&np->tx_lock, flag);
			
	/* Free used tx skbuffs */
	while (entry != np->cur_tx) {
		struct sk_buff *skb;

		if (!(np->tx_ring[entry].status & TFDDone))
			break;
		skb = np->tx_skbuff[entry];
		pci_unmap_single (np->pdev,
				  np->tx_ring[entry].fraginfo,
				  skb->len, PCI_DMA_TODEVICE);
		if (irq)
			dev_kfree_skb_irq (skb);
		else
			dev_kfree_skb (skb);

		np->tx_skbuff[entry] = NULL;
		entry = (entry + 1) % TX_RING_SIZE;
		tx_use++;
	}
	if (irq)
		spin_unlock(&np->tx_lock);
	else
		spin_unlock_irqrestore(&np->tx_lock, flag);
	np->old_tx = entry;

	/* If the ring is no longer full, clear tx_full and 
	   call netif_wake_queue() */

	if (netif_queue_stopped(dev) &&
	    ((np->cur_tx - np->old_tx + TX_RING_SIZE) % TX_RING_SIZE 
	    < TX_QUEUE_LEN - 1 || np->speed == 10)) {
		netif_wake_queue (dev);
	}
}

static void
tx_error (struct net_device *dev, int tx_status)
{
	struct netdev_private *np;
	long ioaddr = dev->base_addr;
	int frame_id;
	int i;

	np = dev->priv;

	frame_id = (tx_status & 0xffff0000);
	printk (KERN_ERR "%s: Transmit error, TxStatus %4.4x, FrameId %d.\n",
		dev->name, tx_status, frame_id);
	np->stats.tx_errors++;
	/* Ttransmit Underrun */
	if (tx_status & 0x10) {
		np->stats.tx_fifo_errors++;
		writew (readw (ioaddr + TxStartThresh) + 0x10,
			ioaddr + TxStartThresh);
		/* Transmit Underrun need to set TxReset, DMARest, FIFOReset */
		writew (TxReset | DMAReset | FIFOReset | NetworkReset,
			ioaddr + ASICCtrl + 2);
		/* Wait for ResetBusy bit clear */
		for (i = 50; i > 0; i--) {
			if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
				break;
			mdelay (1);
		}
		rio_free_tx (dev, 1);
		/* Reset TFDListPtr */
		writel (np->tx_ring_dma +
			np->old_tx * sizeof (struct netdev_desc),
			dev->base_addr + TFDListPtr0);
		writel (0, dev->base_addr + TFDListPtr1);

		/* Let TxStartThresh stay default value */
	}
	/* Late Collision */
	if (tx_status & 0x04) {
		np->stats.tx_fifo_errors++;
		/* TxReset and clear FIFO */
		writew (TxReset | FIFOReset, ioaddr + ASICCtrl + 2);
		/* Wait reset done */
		for (i = 50; i > 0; i--) {
			if ((readw (ioaddr + ASICCtrl + 2) & ResetBusy) == 0)
				break;
			mdelay (1);
		}
		/* Let TxStartThresh stay default value */
	}
	/* Maximum Collisions */
#ifdef ETHER_STATS	
	if (tx_status & 0x08) 
		np->stats.collisions16++;
#else
	if (tx_status & 0x08) 
		np->stats.collisions++;
#endif
	/* Restart the Tx */
	writel (readw (dev->base_addr + MACCtrl) | TxEnable, ioaddr + MACCtrl);
}

static int
receive_packet (struct net_device *dev)
{
	struct netdev_private *np = dev->priv;
	int entry = np->cur_rx % RX_RING_SIZE;
	int cnt = 30;

	/* If RFDDone, FrameStart and FrameEnd set, there is a new packet in. */
	while (1) {
		struct netdev_desc *desc = &np->rx_ring[entry];
		int pkt_len;
		u64 frame_status;

		if (!(desc->status & RFDDone) ||
		    !(desc->status & FrameStart) || !(desc->status & FrameEnd))
			break;

		/* Chip omits the CRC. */
		pkt_len = le64_to_cpu (desc->status & 0xffff);
		frame_status = le64_to_cpu (desc->status);
		if (--cnt < 0)
			break;
		/* Update rx error statistics, drop packet. */
		if (frame_status & RFS_Errors) {
			np->stats.rx_errors++;
			if (frame_status & (RxRuntFrame | RxLengthError))
				np->stats.rx_length_errors++;
			if (frame_status & RxFCSError)
				np->stats.rx_crc_errors++;
			if (frame_status & RxAlignmentError && np->speed != 1000)
				np->stats.rx_frame_errors++;
			if (frame_status & RxFIFOOverrun)
	 			np->stats.rx_fifo_errors++;
		} else {
			struct sk_buff *skb;

			/* Small skbuffs for short packets */
			if (pkt_len > copy_thresh) {
				pci_unmap_single (np->pdev, desc->fraginfo,
						  np->rx_buf_sz,
						  PCI_DMA_FROMDEVICE);
				skb_put (skb = np->rx_skbuff[entry], pkt_len);
				np->rx_skbuff[entry] = NULL;
			} else if ((skb = dev_alloc_skb (pkt_len + 2)) != NULL) {
				pci_dma_sync_single_for_cpu(np->pdev,
							    desc->fraginfo,
							    np->rx_buf_sz,
							    PCI_DMA_FROMDEVICE);
				skb->dev = dev;
				/* 16 byte align the IP header */
				skb_reserve (skb, 2);
				eth_copy_and_sum (skb,
						  np->rx_skbuff[entry]->tail,
						  pkt_len, 0);
				skb_put (skb, pkt_len);
				pci_dma_sync_single_for_device(np->pdev,
							       desc->fraginfo,
							       np->rx_buf_sz,
							       PCI_DMA_FROMDEVICE);
			}
			skb->protocol = eth_type_trans (skb, dev);
#if 0			
			/* Checksum done by hw, but csum value unavailable. */
			if (np->pci_rev_id >= 0x0c && 
				!(frame_status & (TCPError | UDPError | IPError))) {
				skb->ip_summed = CHECKSUM_UNNECESSARY;
			} 
#endif
			netif_rx (skb);
			dev->last_rx = jiffies;
		}
		entry = (entry + 1) % RX_RING_SIZE;
	}
	spin_lock(&np->rx_lock);
	np->cur_rx = entry;
	/* Re-allocate skbuffs to fill the descriptor ring */
	entry = np->old_rx;
	while (entry != np->cur_rx) {
		struct sk_buff *skb;
		/* Dropped packets don't need to re-allocate */
		if (np->rx_skbuff[entry] == NULL) {
			skb = dev_alloc_skb (np->rx_buf_sz);
			if (skb == NULL) {
				np->rx_ring[entry].fraginfo = 0;
				printk (KERN_INFO
					"%s: receive_packet: "
					"Unable to re-allocate Rx skbuff.#%d\n",
					dev->name, entry);
				break;
			}
			np->rx_skbuff[entry] = skb;
			skb->dev = dev;
			/* 16 byte align the IP header */
			skb_reserve (skb, 2);
			np->rx_ring[entry].fraginfo =
			    cpu_to_le64 (pci_map_single
					 (np->pdev, skb->tail, np->rx_buf_sz,
					  PCI_DMA_FROMDEVICE));
		}
		np->rx_ring[entry].fraginfo |=
		    cpu_to_le64 (np->rx_buf_sz) << 48;
		np->rx_ring[entry].status = 0;
		entry = (entry + 1) % RX_RING_SIZE;
	}
	np->old_rx = entry;
	spin_unlock(&np->rx_lock);
	return 0;
}

static void
rio_error (struct net_device *dev, int int_status)
{
	long ioaddr = dev->base_addr;
	struct netdev_private *np = dev->priv;
	u16 macctrl;

	/* Link change event */
	if (int_status & LinkEvent) {
		if (mii_wait_link (dev, 10) == 0) {
			printk (KERN_INFO "%s: Link up\n", dev->name);
			if (np->phy_media)
				mii_get_media_pcs (dev);
			else
				mii_get_media (dev);
			if (np->speed == 1000)
				np->tx_coalesce = tx_coalesce;
			else 
				np->tx_coalesce = 1;
			macctrl = 0;
			macctrl |= (np->vlan) ? AutoVLANuntagging : 0;
			macctrl |= (np->full_duplex) ? DuplexSelect : 0;
			macctrl |= (np->tx_flow) ? 
				TxFlowControlEnable : 0;
			macctrl |= (np->rx_flow) ? 
				RxFlowControlEnable : 0;
			writew(macctrl,	ioaddr + MACCtrl);
			np->link_status = 1;
			netif_carrier_on(dev);
		} else {
			printk (KERN_INFO "%s: Link off\n", dev->name);
			np->link_status = 0;
			netif_carrier_off(dev);
		}
	}

	/* UpdateStats statistics registers */
	if (int_status & UpdateStats) {
		get_stats (dev);
	}

	/* PCI Error, a catastronphic error related to the bus interface 
	   occurs, set GlobalReset and HostReset to reset. */
	if (int_status & HostError) {
		printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
			dev->name, int_status);
		writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
		mdelay (500);
	}
}

static struct net_device_stats *
get_stats (struct net_device *dev)
{
	long ioaddr = dev->base_addr;
	struct netdev_private *np = dev->priv;
#ifdef MEM_MAPPING
	int i;
#endif
	unsigned int stat_reg;

	/* All statistics registers need to be acknowledged,
	   else statistic overflow could cause problems */
	
	np->stats.rx_packets += readl (ioaddr + FramesRcvOk);
	np->stats.tx_packets += readl (ioaddr + FramesXmtOk);
	np->stats.rx_bytes += readl (ioaddr + OctetRcvOk);
	np->stats.tx_bytes += readl (ioaddr + OctetXmtOk);

	np->stats.multicast = readl (ioaddr + McstFramesRcvdOk);
	np->stats.collisions += readl (ioaddr + SingleColFrames) 
			     +  readl (ioaddr + MultiColFrames); 
	
	/* detailed tx errors */
	stat_reg = readw (ioaddr + FramesAbortXSColls);
	np->stats.tx_aborted_errors += stat_reg;
	np->stats.tx_errors += stat_reg;

	stat_reg = readw (ioaddr + CarrierSenseErrors);
	np->stats.tx_carrier_errors += stat_reg;
	np->stats.tx_errors += stat_reg;

	/* Clear all other statistic register. */
	readl (ioaddr + McstOctetXmtOk);
	readw (ioaddr + BcstFramesXmtdOk);
	readl (ioaddr + McstFramesXmtdOk);
	readw (ioaddr + BcstFramesRcvdOk);
	readw (ioaddr + MacControlFramesRcvd);
	readw (ioaddr + FrameTooLongErrors);
	readw (ioaddr + InRangeLengthErrors);
	readw (ioaddr + FramesCheckSeqErrors);
	readw (ioaddr + FramesLostRxErrors);
	readl (ioaddr + McstOctetXmtOk);
	readl (ioaddr + BcstOctetXmtOk);
	readl (ioaddr + McstFramesXmtdOk);
	readl (ioaddr + FramesWDeferredXmt);
	readl (ioaddr + LateCollisions);
	readw (ioaddr + BcstFramesXmtdOk);
	readw (ioaddr + MacControlFramesXmtd);
	readw (ioaddr + FramesWEXDeferal);

#ifdef MEM_MAPPING
	for (i = 0x100; i <= 0x150; i += 4)
		readl (ioaddr + i);
#endif
	readw (ioaddr + TxJumboFrames);
	readw (ioaddr + RxJumboFrames);
	readw (ioaddr + TCPCheckSumErrors);
	readw (ioaddr + UDPCheckSumErrors);
	readw (ioaddr + IPCheckSumErrors);
	return &np->stats;
}

static int
clear_stats (struct net_device *dev)
{
	long ioaddr = dev->base_addr;
#ifdef MEM_MAPPING
	int i;
#endif 

	/* All statistics registers need to be acknowledged,
	   else statistic overflow could cause problems */
	readl (ioaddr + FramesRcvOk);
	readl (ioaddr + FramesXmtOk);
	readl (ioaddr + OctetRcvOk);
	readl (ioaddr + OctetXmtOk);

	readl (ioaddr + McstFramesRcvdOk);
	readl (ioaddr + SingleColFrames);
	readl (ioaddr + MultiColFrames);
	readl (ioaddr + LateCollisions);
	/* detailed rx errors */		
	readw (ioaddr + FrameTooLongErrors);
	readw (ioaddr + InRangeLengthErrors);
	readw (ioaddr + FramesCheckSeqErrors);
	readw (ioaddr + FramesLostRxErrors);

	/* detailed tx errors */
	readw (ioaddr + FramesAbortXSColls);
	readw (ioaddr + CarrierSenseErrors);

	/* Clear all other statistic register. */
	readl (ioaddr + McstOctetXmtOk);
	readw (ioaddr + BcstFramesXmtdOk);
	readl (ioaddr + McstFramesXmtdOk);
	readw (ioaddr + BcstFramesRcvdOk);
	readw (ioaddr + MacControlFramesRcvd);
	readl (ioaddr + McstOctetXmtOk);
	readl (ioaddr + BcstOctetXmtOk);
	readl (ioaddr + McstFramesXmtdOk);
	readl (ioaddr + FramesWDeferredXmt);
	readw (ioaddr + BcstFramesXmtdOk);
	readw (ioaddr + MacControlFramesXmtd);
	readw (ioaddr + FramesWEXDeferal);
#ifdef MEM_MAPPING
	for (i = 0x100; i <= 0x150; i += 4)
		readl (ioaddr + i);
#endif 
	readw (ioaddr + TxJumboFrames);
	readw (ioaddr + RxJumboFrames);
	readw (ioaddr + TCPCheckSumErrors);
	readw (ioaddr + UDPCheckSumErrors);
	readw (ioaddr + IPCheckSumErrors);
	return 0;
}


int
change_mtu (struct net_device *dev, int new_mtu)
{
	struct netdev_private *np = dev->priv;
	int max = (np->jumbo) ? MAX_JUMBO : 1536;

	if ((new_mtu < 68) || (new_mtu > max)) {
		return -EINVAL;
	}

	dev->mtu = new_mtu;

	return 0;
}

static void
set_multicast (struct net_device *dev)
{
	long ioaddr = dev->base_addr;
	u32 hash_table[2];
	u16 rx_mode = 0;
	struct netdev_private *np = dev->priv;
	
	hash_table[0] = hash_table[1] = 0;
	/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
	hash_table[1] |= cpu_to_le32(0x02000000);
	if (dev->flags & IFF_PROMISC) {
		/* Receive all frames promiscuously. */
		rx_mode = ReceiveAllFrames;
	} else if ((dev->flags & IFF_ALLMULTI) || 
			(dev->mc_count > multicast_filter_limit)) {
		/* Receive broadcast and multicast frames */
		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
	} else if (dev->mc_count > 0) {
		int i;
		struct dev_mc_list *mclist;
		/* Receive broadcast frames and multicast frames filtering 
		   by Hashtable */
		rx_mode =
		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; 
				i++, mclist=mclist->next) 
		{
			int bit, index = 0;
			int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
			/* The inverted high significant 6 bits of CRC are
			   used as an index to hashtable */
			for (bit = 0; bit < 6; bit++)
				if (crc & (1 << (31 - bit)))
					index |= (1 << bit);
			hash_table[index / 32] |= (1 << (index % 32));
		}
	} else {
		rx_mode = ReceiveBroadcast | ReceiveUnicast;
	}
	if (np->vlan) {
		/* ReceiveVLANMatch field in ReceiveMode */
		rx_mode |= ReceiveVLANMatch;
	}

	writel (hash_table[0], ioaddr + HashTable0);
	writel (hash_table[1], ioaddr + HashTable1);
	writew (rx_mode, ioaddr + ReceiveMode);
}

static int
rio_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
{
	struct netdev_private *np = dev->priv;
       	u32 ethcmd;
	
	if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
		return -EFAULT;
	switch (ethcmd) {
		case ETHTOOL_GDRVINFO: {
			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
			strcpy(info.driver, "DL2K");
			strcpy(info.version, DRV_VERSION);
			strcpy(info.bus_info, pci_name(np->pdev));
			memset(&info.fw_version, 0, sizeof(info.fw_version));
			if (copy_to_user(useraddr, &info, sizeof(info)))
				return -EFAULT;
			return 0;
		}	
 	
		case ETHTOOL_GSET: {
			struct ethtool_cmd cmd = { ETHTOOL_GSET };
			if (np->phy_media) {
				/* fiber device */
				cmd.supported = SUPPORTED_Autoneg | 
							SUPPORTED_FIBRE;
				cmd.advertising= ADVERTISED_Autoneg |
							ADVERTISED_FIBRE;
				cmd.port = PORT_FIBRE;
				cmd.transceiver = XCVR_INTERNAL;	
			} else {
				/* copper device */
				cmd.supported = SUPPORTED_10baseT_Half | 
					SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half
					| SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full |
					SUPPORTED_Autoneg | SUPPORTED_MII;
				cmd.advertising = ADVERTISED_10baseT_Half |
					ADVERTISED_10baseT_Full | ADVERTISED_100baseT_Half |
					ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Full|
					ADVERTISED_Autoneg | ADVERTISED_MII;
				cmd.port = PORT_MII;
				cmd.transceiver = XCVR_INTERNAL;
			}
			if ( np->link_status ) { 
				cmd.speed = np->speed;
				cmd.duplex = np->full_duplex ? 
						    DUPLEX_FULL : DUPLEX_HALF;
			} else {
				cmd.speed = -1;
				cmd.duplex = -1;
			}
			if ( np->an_enable)
				cmd.autoneg = AUTONEG_ENABLE;
			else
				cmd.autoneg = AUTONEG_DISABLE;
			
			cmd.phy_address = np->phy_addr;

			if (copy_to_user(useraddr, &cmd,
					sizeof(cmd)))
				return -EFAULT;
			return 0;				   
		}
		case ETHTOOL_SSET: {
			struct ethtool_cmd cmd;
			if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
				return -EFAULT;
			netif_carrier_off(dev);
			if (cmd.autoneg == AUTONEG_ENABLE) {
				if (np->an_enable)
					return 0;
				else {
					np->an_enable = 1;
					mii_set_media(dev);
					return 0;	
				}	
			} else {
				np->an_enable = 0;
				if (np->speed == 1000){
					cmd.speed = SPEED_100;			
					cmd.duplex = DUPLEX_FULL;
					printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manul 100Mbps, Full duplex.\n");
					}
				switch(cmd.speed + cmd.duplex){
				
				case SPEED_10 + DUPLEX_HALF:
					np->speed = 10;
					np->full_duplex = 0;
					break;
				
				case SPEED_10 + DUPLEX_FULL:
					np->speed = 10;
					np->full_duplex = 1;
					break;
				case SPEED_100 + DUPLEX_HALF:
					np->speed = 100;
					np->full_duplex = 0;
					break;
				case SPEED_100 + DUPLEX_FULL:
					np->speed = 100;
					np->full_duplex = 1;
					break;
				case SPEED_1000 + DUPLEX_HALF:/* not supported */
				case SPEED_1000 + DUPLEX_FULL:/* not supported */
				default:
					return -EINVAL;	
				}
				mii_set_media(dev);
			}
		return 0;		   
		}
#ifdef ETHTOOL_GLINK		
		case ETHTOOL_GLINK:{
		struct ethtool_value link = { ETHTOOL_GLINK };
		link.data = np->link_status;
		if (copy_to_user(useraddr, &link, sizeof(link)))
			return -EFAULT;
		return 0;
		}			   
#endif
		default:
		return -EOPNOTSUPP;
	}	
}


static int
rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
	int phy_addr;
	struct netdev_private *np = dev->priv;
	struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru;
	
	struct netdev_desc *desc;
	int i;

	phy_addr = np->phy_addr;
	switch (cmd) {
	case SIOCETHTOOL:
		return rio_ethtool_ioctl(dev, rq->ifr_data);		
	case SIOCDEVPRIVATE:
		break;
	
	case SIOCDEVPRIVATE + 1:
		miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num);
		break;
	case SIOCDEVPRIVATE + 2:
		mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value);
		break;
	case SIOCDEVPRIVATE + 3:
		break;
	case SIOCDEVPRIVATE + 4:
		break;
	case SIOCDEVPRIVATE + 5:
		netif_stop_queue (dev);
		break;
	case SIOCDEVPRIVATE + 6:
		netif_wake_queue (dev);
		break;
	case SIOCDEVPRIVATE + 7:
		printk
		    ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n",
		     netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx,
		     np->old_rx);
		break;
	case SIOCDEVPRIVATE + 8:
		printk("TX ring:\n");
		for (i = 0; i < TX_RING_SIZE; i++) {
			desc = &np->tx_ring[i];
			printk
			    ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x",
			     i,
			     (u32) (np->tx_ring_dma + i * sizeof (*desc)),
			     (u32) desc->next_desc,
			     (u32) desc->status, (u32) (desc->fraginfo >> 32),
			     (u32) desc->fraginfo);
			printk ("\n");
		}
		printk ("\n");
		break;

	default:
		return -EOPNOTSUPP;
	}
	return 0;
}

#define EEP_READ 0x0200
#define EEP_BUSY 0x8000
/* Read the EEPROM word */
/* We use I/O instruction to read/write eeprom to avoid fail on some machines */
int
read_eeprom (long ioaddr, int eep_addr)
{
	int i = 1000;
	outw (EEP_READ | (eep_addr & 0xff), ioaddr + EepromCtrl);
	while (i-- > 0) {
		if (!(inw (ioaddr + EepromCtrl) & EEP_BUSY)) {
			return inw (ioaddr + EepromData);
		}
	}
	return 0;
}

enum phy_ctrl_bits {
	MII_READ = 0x00, MII_CLK = 0x01, MII_DATA1 = 0x02, MII_WRITE = 0x04,
	MII_DUPLEX = 0x08,
};

#define mii_delay() readb(ioaddr)
static void
mii_sendbit (struct net_device *dev, u32 data)
{
	long ioaddr = dev->base_addr + PhyCtrl;
	data = (data) ? MII_DATA1 : 0;
	data |= MII_WRITE;
	data |= (readb (ioaddr) & 0xf8) | MII_WRITE;
	writeb (data, ioaddr);
	mii_delay ();
	writeb (data | MII_CLK, ioaddr);
	mii_delay ();
}

static int
mii_getbit (struct net_device *dev)
{
	long ioaddr = dev->base_addr + PhyCtrl;
	u8 data;

	data = (readb (ioaddr) & 0xf8) | MII_READ;
	writeb (data, ioaddr);
	mii_delay ();
	writeb (data | MII_CLK, ioaddr);
	mii_delay ();
	return ((readb (ioaddr) >> 1) & 1);
}

static void
mii_send_bits (struct net_device *dev, u32 data, int len)
{
	int i;
	for (i = len - 1; i >= 0; i--) {
		mii_sendbit (dev, data & (1 << i));
	}
}

static int
mii_read (struct net_device *dev, int phy_addr, int reg_num)
{
	u32 cmd;
	int i;
	u32 retval = 0;

	/* Preamble */
	mii_send_bits (dev, 0xffffffff, 32);
	/* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */
	/* ST,OP = 0110'b for read operation */
	cmd = (0x06 << 10 | phy_addr << 5 | reg_num);
	mii_send_bits (dev, cmd, 14);
	/* Turnaround */
	if (mii_getbit (dev))
		goto err_out;
	/* Read data */
	for (i = 0; i < 16; i++) {
		retval |= mii_getbit (dev);
		retval <<= 1;
	}
	/* End cycle */
	mii_getbit (dev);
	return (retval >> 1) & 0xffff;

      err_out:
	return 0;
}
static int
mii_write (struct net_device *dev, int phy_addr, int reg_num, u16 data)
{
	u32 cmd;

	/* Preamble */
	mii_send_bits (dev, 0xffffffff, 32);
	/* ST(2), OP(2), ADDR(5), REG#(5), TA(2), Data(16) total 32 bits */
	/* ST,OP,AAAAA,RRRRR,TA = 0101xxxxxxxxxx10'b = 0x5002 for write */
	cmd = (0x5002 << 16) | (phy_addr << 23) | (reg_num << 18) | data;
	mii_send_bits (dev, cmd, 32);
	/* End cycle */
	mii_getbit (dev);
	return 0;
}
static int
mii_wait_link (struct net_device *dev, int wait)
{
	BMSR_t bmsr;
	int phy_addr;
	struct netdev_private *np;

	np = dev->priv;
	phy_addr = np->phy_addr;

	do {
		bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
		if (bmsr.bits.link_status)
			return 0;
		mdelay (1);
	} while (--wait > 0);
	return -1;
}
static int
mii_get_media (struct net_device *dev)
{
	ANAR_t negotiate;
	BMSR_t bmsr;
	BMCR_t bmcr;
	MSCR_t mscr;
	MSSR_t mssr;
	int phy_addr;
	struct netdev_private *np;

	np = dev->priv;
	phy_addr = np->phy_addr;

	bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
	if (np->an_enable) {
		if (!bmsr.bits.an_complete) {
			/* Auto-Negotiation not completed */
			return -1;
		}
		negotiate.image = mii_read (dev, phy_addr, MII_ANAR) & 
			mii_read (dev, phy_addr, MII_ANLPAR);
		mscr.image = mii_read (dev, phy_addr, MII_MSCR);
		mssr.image = mii_read (dev, phy_addr, MII_MSSR);
		if (mscr.bits.media_1000BT_FD & mssr.bits.lp_1000BT_FD) {
			np->speed = 1000;
			np->full_duplex = 1;
			printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
		} else if (mscr.bits.media_1000BT_HD & mssr.bits.lp_1000BT_HD) {
			np->speed = 1000;
			np->full_duplex = 0;
			printk (KERN_INFO "Auto 1000 Mbps, Half duplex\n");
		} else if (negotiate.bits.media_100BX_FD) {
			np->speed = 100;
			np->full_duplex = 1;
			printk (KERN_INFO "Auto 100 Mbps, Full duplex\n");
		} else if (negotiate.bits.media_100BX_HD) {
			np->speed = 100;
			np->full_duplex = 0;
			printk (KERN_INFO "Auto 100 Mbps, Half duplex\n");
		} else if (negotiate.bits.media_10BT_FD) {
			np->speed = 10;
			np->full_duplex = 1;
			printk (KERN_INFO "Auto 10 Mbps, Full duplex\n");
		} else if (negotiate.bits.media_10BT_HD) {
			np->speed = 10;
			np->full_duplex = 0;
			printk (KERN_INFO "Auto 10 Mbps, Half duplex\n");
		}
		if (negotiate.bits.pause) {
			np->tx_flow &= 1;
			np->rx_flow &= 1;
		} else if (negotiate.bits.asymmetric) {
			np->tx_flow = 0;
			np->rx_flow &= 1;
		}
		/* else tx_flow, rx_flow = user select  */
	} else {
		bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
		if (bmcr.bits.speed100 == 1 && bmcr.bits.speed1000 == 0) {
			printk (KERN_INFO "Operating at 100 Mbps, ");
		} else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 0) {
			printk (KERN_INFO "Operating at 10 Mbps, ");
		} else if (bmcr.bits.speed100 == 0 && bmcr.bits.speed1000 == 1) {
			printk (KERN_INFO "Operating at 1000 Mbps, ");
		}
		if (bmcr.bits.duplex_mode) {
			printk ("Full duplex\n");
		} else {
			printk ("Half duplex\n");
		}
	}
	if (np->tx_flow) 
		printk(KERN_INFO "Enable Tx Flow Control\n");
	else	
		printk(KERN_INFO "Disable Tx Flow Control\n");
	if (np->rx_flow)
		printk(KERN_INFO "Enable Rx Flow Control\n");
	else
		printk(KERN_INFO "Disable Rx Flow Control\n");

	return 0;
}

static int
mii_set_media (struct net_device *dev)
{
	PHY_SCR_t pscr;
	BMCR_t bmcr;
	BMSR_t bmsr;
	ANAR_t anar;
	int phy_addr;
	struct netdev_private *np;
	np = dev->priv;
	phy_addr = np->phy_addr;

	/* Does user set speed? */
	if (np->an_enable) {
		/* Advertise capabilities */
		bmsr.image = mii_read (dev, phy_addr, MII_BMSR);
		anar.image = mii_read (dev, phy_addr, MII_ANAR);
		anar.bits.media_100BX_FD = bmsr.bits.media_100BX_FD;
		anar.bits.media_100BX_HD = bmsr.bits.media_100BX_HD;
		anar.bits.media_100BT4 = bmsr.bits.media_100BT4;
		anar.bits.media_10BT_FD = bmsr.bits.media_10BT_FD;
		anar.bits.media_10BT_HD = bmsr.bits.media_10BT_HD;
		anar.bits.pause = 1;
		anar.bits.asymmetric = 1;
		mii_write (dev, phy_addr, MII_ANAR, anar.image);

		/* Enable Auto crossover */
		pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
		pscr.bits.mdi_crossover_mode = 3;	/* 11'b */
		mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);
		
		/* Soft reset PHY */
		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
		bmcr.image = 0;
		bmcr.bits.an_enable = 1;
		bmcr.bits.restart_an = 1;
		bmcr.bits.reset = 1;
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
		mdelay(1);
	} else {
		/* Force speed setting */
		/* 1) Disable Auto crossover */
		pscr.image = mii_read (dev, phy_addr, MII_PHY_SCR);
		pscr.bits.mdi_crossover_mode = 0;
		mii_write (dev, phy_addr, MII_PHY_SCR, pscr.image);

		/* 2) PHY Reset */
		bmcr.image = mii_read (dev, phy_addr, MII_BMCR);
		bmcr.bits.reset = 1;
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);

		/* 3) Power Down */
		bmcr.image = 0x1940;	/* must be 0x1940 */
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
		mdelay (100);	/* wait a certain time */

		/* 4) Advertise nothing */
		mii_write (dev, phy_addr, MII_ANAR, 0);

		/* 5) Set media and Power Up */
		bmcr.image = 0;
		bmcr.bits.power_down = 1;
		if (np->speed == 100) {
			bmcr.bits.speed100 = 1;
			bmcr.bits.speed1000 = 0;
			printk (KERN_INFO "Manual 100 Mbps, ");
		} else if (np->speed == 10) {
			bmcr.bits.speed100 = 0;
			bmcr.bits.speed1000 = 0;
			printk (KERN_INFO "Manual 10 Mbps, ");
		}
		if (np->full_duplex) {
			bmcr.bits.duplex_mode = 1;
			printk ("Full duplex\n");
		} else {
			bmcr.bits.duplex_mode = 0;
			printk ("Half duplex\n");
		}
#if 0
		/* Set 1000BaseT Master/Slave setting */
		mscr.image = mii_read (dev, phy_addr, MII_MSCR);
		mscr.bits.cfg_enable = 1;
		mscr.bits.cfg_value = 0;
#endif
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
		mdelay(10);
	}
	return 0;
}

static int
mii_get_media_pcs (struct net_device *dev)
{
	ANAR_PCS_t negotiate;
	BMSR_t bmsr;
	BMCR_t bmcr;
	int phy_addr;
	struct netdev_private *np;

	np = dev->priv;
	phy_addr = np->phy_addr;

	bmsr.image = mii_read (dev, phy_addr, PCS_BMSR);
	if (np->an_enable) {
		if (!bmsr.bits.an_complete) {
			/* Auto-Negotiation not completed */
			return -1;
		}
		negotiate.image = mii_read (dev, phy_addr, PCS_ANAR) & 
			mii_read (dev, phy_addr, PCS_ANLPAR);
		np->speed = 1000;
		if (negotiate.bits.full_duplex) {
			printk (KERN_INFO "Auto 1000 Mbps, Full duplex\n");
			np->full_duplex = 1;
		} else {
			printk (KERN_INFO "Auto 1000 Mbps, half duplex\n");
			np->full_duplex = 0;
		}
		if (negotiate.bits.pause) {
			np->tx_flow &= 1;
			np->rx_flow &= 1;
		} else if (negotiate.bits.asymmetric) {
			np->tx_flow = 0;
			np->rx_flow &= 1;
		}
		/* else tx_flow, rx_flow = user select  */
	} else {
		bmcr.image = mii_read (dev, phy_addr, PCS_BMCR);
		printk (KERN_INFO "Operating at 1000 Mbps, ");
		if (bmcr.bits.duplex_mode) {
			printk ("Full duplex\n");
		} else {
			printk ("Half duplex\n");
		}
	}
	if (np->tx_flow) 
		printk(KERN_INFO "Enable Tx Flow Control\n");
	else	
		printk(KERN_INFO "Disable Tx Flow Control\n");
	if (np->rx_flow)
		printk(KERN_INFO "Enable Rx Flow Control\n");
	else
		printk(KERN_INFO "Disable Rx Flow Control\n");

	return 0;
}

static int
mii_set_media_pcs (struct net_device *dev)
{
	BMCR_t bmcr;
	ESR_t esr;
	ANAR_PCS_t anar;
	int phy_addr;
	struct netdev_private *np;
	np = dev->priv;
	phy_addr = np->phy_addr;

	/* Auto-Negotiation? */
	if (np->an_enable) {
		/* Advertise capabilities */
		esr.image = mii_read (dev, phy_addr, PCS_ESR);
		anar.image = mii_read (dev, phy_addr, MII_ANAR);
		anar.bits.half_duplex = 
			esr.bits.media_1000BT_HD | esr.bits.media_1000BX_HD;
		anar.bits.full_duplex = 
			esr.bits.media_1000BT_FD | esr.bits.media_1000BX_FD;
		anar.bits.pause = 1;
		anar.bits.asymmetric = 1;
		mii_write (dev, phy_addr, MII_ANAR, anar.image);

		/* Soft reset PHY */
		mii_write (dev, phy_addr, MII_BMCR, MII_BMCR_RESET);
		bmcr.image = 0;
		bmcr.bits.an_enable = 1;
		bmcr.bits.restart_an = 1;
		bmcr.bits.reset = 1;
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
		mdelay(1);
	} else {
		/* Force speed setting */
		/* PHY Reset */
		bmcr.image = 0;
		bmcr.bits.reset = 1;
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
		mdelay(10);
		bmcr.image = 0;
		bmcr.bits.an_enable = 0;
		if (np->full_duplex) {
			bmcr.bits.duplex_mode = 1;
			printk (KERN_INFO "Manual full duplex\n");
		} else {
			bmcr.bits.duplex_mode = 0;
			printk (KERN_INFO "Manual half duplex\n");
		}
		mii_write (dev, phy_addr, MII_BMCR, bmcr.image);
		mdelay(10);

		/*  Advertise nothing */
		mii_write (dev, phy_addr, MII_ANAR, 0);
	}
	return 0;
}


static int
rio_close (struct net_device *dev)
{
	long ioaddr = dev->base_addr;
	struct netdev_private *np = dev->priv;
	struct sk_buff *skb;
	int i;

	netif_stop_queue (dev);

	/* Disable interrupts */
	writew (0, ioaddr + IntEnable);

	/* Stop Tx and Rx logics */
	writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
	synchronize_irq (dev->irq);
	free_irq (dev->irq, dev);
	del_timer_sync (&np->timer);
	
	/* Free all the skbuffs in the queue. */
	for (i = 0; i < RX_RING_SIZE; i++) {
		np->rx_ring[i].status = 0;
		np->rx_ring[i].fraginfo = 0;
		skb = np->rx_skbuff[i];
		if (skb) {
			pci_unmap_single (np->pdev, np->rx_ring[i].fraginfo,
					  skb->len, PCI_DMA_FROMDEVICE);
			dev_kfree_skb (skb);
			np->rx_skbuff[i] = NULL;
		}
	}
	for (i = 0; i < TX_RING_SIZE; i++) {
		skb = np->tx_skbuff[i];
		if (skb) {
			pci_unmap_single (np->pdev, np->tx_ring[i].fraginfo,
					  skb->len, PCI_DMA_TODEVICE);
			dev_kfree_skb (skb);
			np->tx_skbuff[i] = NULL;
		}
	}

	return 0;
}

static void __devexit
rio_remove1 (struct pci_dev *pdev)
{
	struct net_device *dev = pci_get_drvdata (pdev);

	if (dev) {
		struct netdev_private *np = dev->priv;

		unregister_netdev (dev);
		pci_free_consistent (pdev, RX_TOTAL_SIZE, np->rx_ring,
				     np->rx_ring_dma);
		pci_free_consistent (pdev, TX_TOTAL_SIZE, np->tx_ring,
				     np->tx_ring_dma);
#ifdef MEM_MAPPING
		iounmap ((char *) (dev->base_addr));
#endif
		free_netdev (dev);
		pci_release_regions (pdev);
		pci_disable_device (pdev);
	}
	pci_set_drvdata (pdev, NULL);
}

static struct pci_driver rio_driver = {
	.name		= "dl2k",
	.id_table	= rio_pci_tbl,
	.probe		= rio_probe1,
	.remove		= __devexit_p(rio_remove1),
};

static int __init
rio_init (void)
{
	return pci_module_init (&rio_driver);
}

static void __exit
rio_exit (void)
{
	pci_unregister_driver (&rio_driver);
}

module_init (rio_init);
module_exit (rio_exit);

/*
 
Compile command: 
 
gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -c dl2k.c

Read Documentation/networking/dl2k.txt for details.

*/


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
  2004-12-20 14:34         ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" Richard Ems
@ 2004-12-20 17:12           ` Jon Mason
  2004-12-20 18:03             ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" (Plain) Richard Ems
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Mason @ 2004-12-20 17:12 UTC (permalink / raw)
  To: Richard Ems; +Cc: linux-kernel, linux-net

It looks correct to me.  I apologize for the oversight.


On Mon, 20 Dec 2004 15:34:09 +0100, Richard Ems
<richard.ems@mtg-marinetechnik.de> wrote:
> Hi Jon, hi list.
> 
> The following patch is what I'm trying now:
> (I added the *np declaration to your patch, is this correct?)
> 
> Thanks, Richard
> 
> --- dl2k.c,orig-save-2004.12.20 2004-12-20 09:32:19.000000000 +0100
> +++ dl2k.c      2004-12-20 15:24:39.051556188 +0100
> @@ -562,9 +562,11 @@
>   rio_tx_timeout (struct net_device *dev)
>   {
>          long ioaddr = dev->base_addr;
> +       struct netdev_private *np = dev->priv;
> 
> -       printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
> -               dev->name, readl (ioaddr + TxStatus));
> +       printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
> +               dev->name, readl (ioaddr + TxStatus), np->cur_tx,
> np->cur_rx,
> +               readl (ioaddr + DMACtrl), readw(ioaddr + IntEnable));
>          rio_free_tx(dev, 0);
>          dev->if_port = 0;
>          dev->trans_start = jiffies;
> @@ -1005,8 +1007,9 @@
>          /* PCI Error, a catastronphic error related to the bus interface
>             occurs, set GlobalReset and HostReset to reset. */
>          if (int_status & HostError) {
> -               printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
> -                       dev->name, int_status);
> +               printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d %d
> %x %x\n",
> +                       dev->name, int_status, np->cur_tx, np->cur_rx,
> +                       readl (ioaddr + DMACtrl), readw(ioaddr +
> IntEnable));
>                  writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
>                  mdelay (500);
>          }
> 
> --
> Richard Ems
> Tel: +49 40 65803 312
> Fax: +49 40 65803 392
> Richard.Ems@mtg-marinetechnik.de
> 
> MTG Marinetechnik GmbH - Wandsbeker Königstr. 62 - D 22041 Hamburg
> 
> GF Dipl.-Ing. Ullrich Keil
> Handelsregister: Abt. B Nr. 11 500 - Amtsgericht Hamburg Abt. 66
> USt.-IdNr.: DE 1186 70571
> 
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer  full?"
  2004-12-17 20:52       ` Jon Mason
@ 2004-12-20 14:34         ` Richard Ems
  2004-12-20 17:12           ` Jon Mason
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Ems @ 2004-12-20 14:34 UTC (permalink / raw)
  To: Jon Mason; +Cc: linux-kernel, linux-net

Hi Jon, hi list.

The following patch is what I'm trying now:
(I added the *np declaration to your patch, is this correct?)

Thanks, Richard

--- dl2k.c,orig-save-2004.12.20 2004-12-20 09:32:19.000000000 +0100
+++ dl2k.c      2004-12-20 15:24:39.051556188 +0100
@@ -562,9 +562,11 @@
  rio_tx_timeout (struct net_device *dev)
  {
         long ioaddr = dev->base_addr;
+       struct netdev_private *np = dev->priv;

-       printk (KERN_INFO "%s: Tx timed out (%4.4x), is buffer full?\n",
-               dev->name, readl (ioaddr + TxStatus));
+       printk (KERN_INFO "%s: Tx timed out (%4.4x) %d %d %x %x\n",
+               dev->name, readl (ioaddr + TxStatus), np->cur_tx, 
np->cur_rx,
+               readl (ioaddr + DMACtrl), readw(ioaddr + IntEnable));
         rio_free_tx(dev, 0);
         dev->if_port = 0;
         dev->trans_start = jiffies;
@@ -1005,8 +1007,9 @@
         /* PCI Error, a catastronphic error related to the bus interface
            occurs, set GlobalReset and HostReset to reset. */
         if (int_status & HostError) {
-               printk (KERN_ERR "%s: HostError! IntStatus %4.4x.\n",
-                       dev->name, int_status);
+               printk (KERN_ERR "%s: HostError! IntStatus %4.4x. %d %d 
%x %x\n",
+                       dev->name, int_status, np->cur_tx, np->cur_rx,
+                       readl (ioaddr + DMACtrl), readw(ioaddr + 
IntEnable));
                 writew (GlobalReset | HostReset, ioaddr + ASICCtrl + 2);
                 mdelay (500);
         }

-- 
Richard Ems
Tel: +49 40 65803 312
Fax: +49 40 65803 392
Richard.Ems@mtg-marinetechnik.de

MTG Marinetechnik GmbH - Wandsbeker Königstr. 62 - D 22041 Hamburg

GF Dipl.-Ing. Ullrich Keil
Handelsregister: Abt. B Nr. 11 500 - Amtsgericht Hamburg Abt. 66
USt.-IdNr.: DE 1186 70571


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?"
       [not found] <200412171100.16601.richard.ems@mtg-marinetechnik.de>
@ 2004-12-17 17:07 ` Jon Mason
  2004-12-17 17:15   ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" (Plain) Richard Ems
  0 siblings, 1 reply; 11+ messages in thread
From: Jon Mason @ 2004-12-17 17:07 UTC (permalink / raw)
  To: Richard Ems; +Cc: linux-kernel, linux-net, Feedback, edward_peng

It seems to me the cause of the tx timeouts is the "HostError", which
is a PCI bus error.  This most likely caused the adapter to hang and
then the transmits started timing out.

As far as I can tell, the dl2k driver code is common between 2.4 and
2.6.  So, some other change in the kernel is causing the driver to
behave differently and expose this problem.

I am not the maintainer, but I can try to assist you. However, it will
require running debug drivers (as I am not able to find any
documentation on this adapter).  If you are not willing or able to do
this, then I would suggest going back to the 2.4 kernel.

Thanks,
Jon


On Fri, 17 Dec 2004 11:00:16 -0600, Richard Ems
<richard.ems@mtg-marinetechnik.de> wrote:
> Hi list!
> 
> [1.] One line summary of the problem:
> Network hang: "eth0: Tx timed out (f0080), is buffer full?"
> 
> [2.] Full description of the problem/report:
> 
> We had to reboot a server twice after a network card hang.
> The first time was after one day uptime.
> The second time, yesterday, after 8 days uptime.
> The server is a dual AMD Athlon(tm) MP 2200+ with 1 GB RAM and is
> running SuSE Linux 9.2.
> 
> There are 2 NIC's on this system, a 10/100 Mbit/s 3Com Corporation
> 3c905C-TX/TX-M [Tornado] which is not being used and a D-Link System Inc
> DL2000-based Gigabit Ethernet card.
> The problem seems to be the dl2k driver for this second NIC.
> The last minutes previous to the network hang and system hard reset
> (local login is not possible because of nfs mounts hang) the following
> lines were logged in /var/log/messages:
> 
> Dec  8 10:36:55 urutu kernel: eth0: HostError! IntStatus 0002.
> Dec  8 10:36:55 urutu kernel: klogd 1.4.1, ---------- state change
> ----------
> Dec  8 10:38:48 urutu kernel: nfs: server jupiter not responding, still
> trying
> Dec  8 10:39:48 urutu kernel: nfs: server diablo not responding, still
> trying
> 
> Dec  8 10:40:21 urutu kernel: eth0: Tx timed out (f0080), is buffer full?
> Dec  8 10:43:25 urutu kernel: NETDEV WATCHDOG: eth0: transmit timed out
> Dec  8 10:43:25 urutu kernel: eth0: Tx timed out (d0080), is buffer full?
> Dec  8 10:46:57 urutu kernel: NETDEV WATCHDOG: eth0: transmit timed out
> Dec  8 10:46:57 urutu kernel: eth0: Tx timed out (b0080), is buffer full?
> 
> On another thread I read that doing a ifconfg eth? down and up again
> would be enough to regain connectivity again.
> Also just ping flooding the card will hang it.
> See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=281819
> 
> The hardware wasn't changed the last months. The problem appeared after
> updating the 4th December from SuSE 9.0 (kernel 2.4.xx) to SuSE 9.2
> (kernel 2.6.8).
> 
> The card is configured as eth1 but the error above shows eth0! The 3Com
> card was detected as eth0 and it's down.
> 
> The dl2k driver was last updated 2002/10/03. I didn't find any
> maintainer listed in the Maintainers file.
> 
> Any idea what's happening? Should I go back to 2.4.xx? This is a
> production server with different people logged in using VNC, so testing
> changes is not so easy.
> 
> Many thanks, Richard
> 
> [3.] Keywords (i.e., modules, networking, kernel):
> networking, d-link dl2k
> 
> [4.] Kernel version (from /proc/version):
> Linux version 2.6.8-24.5-smp (geeko@buildhost) (gcc version 3.3.4 (pre
> 3.3.5 20040809)) #1 SMP Wed Nov 17 11:10:06 UTC 2004
> 
> [5.] Output of Oops.. message (if applicable) with symbolic information
>       resolved (see Documentation/oops-tracing.txt)
> no oops
> 
> [6.] A small shell script or example program which triggers the
>       problem (if possible)
> 
> [7.] Environment
> [7.1.] Software (add the output of the ver_linux script here)
> 
> If some fields are empty or look unusual you may have an old version.
> Compare to the current minimal requirements in Documentation/Changes.
> 
> Linux urutu 2.6.8-24.5-smp #1 SMP Wed Nov 17 11:10:06 UTC 2004 i686
> athlon i386 GNU/Linux
> 
> Gnu C                  3.3.4
> Gnu make               3.80
> binutils               2.15.91.0.2
> util-linux             2.12c
> mount                  2.12c
> module-init-tools      3.1-pre5
> e2fsprogs              1.35
> jfsutils               1.1.7
> reiserfsprogs          3.6.18
> reiser4progs           line
> xfsprogs               2.6.13
> PPP                    2.4.2
> isdn4k-utils           3.5
> nfs-utils              1.0.6
> Linux C Library        x  1 root root 1359489 Oct  5 14:21
> /lib/tls/libc.so.6
> Dynamic linker (ldd)   2.3.3
> Linux C++ Library      5.0.7
> Procps                 3.2.3
> Net-tools              1.60
> Kbd                    1.12
> Sh-utils               5.2.1
> Modules Loaded         nfsd exportfs autofs4 dl2k 3c59x edd joydev sg st
> sd_mod sr_mod scsi_mod ide_cd cdrom subfs amd_k7_agp agpgart hw_random
> evdevdm_mod usbcore ext3 jbd
> 
> [7.2.] Processor information (from /proc/cpuinfo):
> processor       : 0
> vendor_id       : AuthenticAMD
> cpu family      : 6
> model           : 8
> model name      : AMD Athlon(tm) MP 2200+
> stepping        : 1
> cpu MHz         : 1800.416
> cache size      : 256 KB
> fdiv_bug        : no
> hlt_bug         : no
> f00f_bug        : no
> coma_bug        : no
> fpu             : yes
> fpu_exception   : yes
> cpuid level     : 1
> wp              : yes
> flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
> mca cmov pat pse36 mmx fxsr sse pni syscall mp mmxext 3dnowext 3dnow
> bogomips        : 3555.32
> 
> processor       : 1
> vendor_id       : AuthenticAMD
> cpu family      : 6
> model           : 8
> model name      : AMD Athlon(tm) Processor
> stepping        : 1
> cpu MHz         : 1800.416
> cache size      : 256 KB
> fdiv_bug        : no
> hlt_bug         : no
> f00f_bug        : no
> coma_bug        : no
> fpu             : yes
> fpu_exception   : yes
> cpuid level     : 1
> wp              : yes
> flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge
> mca cmov pat pse36 mmx fxsr sse pni syscall mp mmxext 3dnowext 3dnow
> bogomips        : 3596.28
> 
> [7.3.] Module information (from /proc/modules):
> nfsd 117960 9 - Live 0xf919a000
> exportfs 10368 1 nfsd, Live 0xf90fc000
> autofs4 23940 1 - Live 0xf9165000
> dl2k 27044 0 - Live 0xf915d000
> 3c59x 43432 0 - Live 0xf916c000
> edd 14620 0 - Live 0xf90e2000
> joydev 13760 0 - Live 0xf90f2000
> sg 42528 0 - Live 0xf9132000
> st 43164 0 - Live 0xf9126000
> sd_mod 22144 0 - Live 0xf911f000
> sr_mod 21156 0 - Live 0xf9118000
> scsi_mod 121412 4 sg,st,sd_mod,sr_mod, Live 0xf913e000
> ide_cd 44448 0 - Live 0xf910c000
> cdrom 42652 2 sr_mod,ide_cd, Live 0xf9100000
> subfs 12672 2 - Live 0xf90e7000
> amd_k7_agp 11788 1 - Live 0xf8865000
> agpgart 37804 1 amd_k7_agp, Live 0xf8873000
> hw_random 9620 0 - Live 0xf883b000
> evdev 13184 0 - Live 0xf8836000
> dm_mod 63104 6 - Live 0xf8854000
> usbcore 120164 1 - Live 0xf90a5000
> ext3 128744 7 - Live 0xf9002000
> jbd 76964 1 ext3, Live 0xf8840000
> 
> [7.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
> 
> # cat /proc/ioports
> 0000-001f : dma1
> 0020-0021 : pic1
> 0040-0043 : timer0
> 0050-0053 : timer1
> 0060-006f : keyboard
> 0070-0077 : rtc
> 0080-008f : dma page reg
> 00a0-00a1 : pic2
> 00c0-00df : dma2
> 00f0-00ff : fpu
> 0170-0177 : ide1
> 01f0-01f7 : ide0
> 02f8-02ff : serial
> 0376-0376 : ide1
> 03c0-03df : vesafb
> 03f6-03f6 : ide0
> 03f8-03ff : serial
> 0cf8-0cff : PCI conf1
> 1000-10ff : 0000:00:08.0
>    1000-10ff : dl2k
> 1410-1413 : 0000:00:00.0
> 2000-2fff : PCI Bus #01
>    2000-20ff : 0000:01:05.0
> 3000-3fff : PCI Bus #02
>    3000-307f : 0000:02:08.0
>      3000-307f : 0000:02:08.0
> 8000-8003 : PM1a_EVT_BLK
> 8004-8005 : PM1a_CNT_BLK
> 8008-800b : PM_TMR
> 8020-8023 : GPE0_BLK
> f000-f00f : 0000:00:07.1
>    f000-f007 : ide0
>    f008-f00f : ide1
> 
> # cat /proc/iomem
> 00000000-0009efff : System RAM
> 0009f000-0009ffff : reserved
> 000a0000-000bffff : Video RAM area
> 000c0000-000c7fff : Video ROM
> 000c8000-000c87ff : Adapter ROM
> 000f0000-000fffff : System ROM
> 00100000-3feeffff : System RAM
>    00100000-0034888d : Kernel code
>    0034888e-00416eff : Kernel data
> 3fef0000-3fefefff : ACPI Tables
> 3feff000-3fefffff : ACPI Non-volatile Storage
> 3ff00000-3fffffff : System RAM
> f4000000-f40001ff : 0000:00:08.0
>    f4000000-f40001ff : dl2k
> f4100000-f5ffffff : PCI Bus #01
>    f4100000-f4100fff : 0000:01:05.0
>    f5000000-f5ffffff : 0000:01:05.0
>      f5000000-f57effff : vesafb
> f6000000-f60fffff : PCI Bus #02
>    f6001000-f600107f : 0000:02:08.0
> f6300000-f6300fff : 0000:00:00.0
> f8000000-fbffffff : 0000:00:00.0
> fec00000-fec07fff : reserved
> fee00000-fee00fff : reserved
> fff80000-ffffffff : reserved
> 
> [7.5.] PCI information ('lspci -vvv' as root)
> 0000:00:00.0 Host bridge: Advanced Micro Devices [AMD] AMD-760 MP
> [IGD4-2P] System Controller (rev 11)
>          Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap+ 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
> 
>          Latency: 64
>          Region 0: Memory at f8000000 (32-bit, prefetchable)
>          Region 1: Memory at f6300000 (32-bit, prefetchable) [size=4K]
>          Region 2: I/O ports at 1410 [disabled] [size=4]
>          Capabilities: [a0] AGP version 2.0
>                  Status: RQ=16 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64-
> HTrans- 64bit- FW- AGP3- Rate=x1,x2
>                  Command: RQ=1 ArqSz=0 Cal=0 SBA+ AGP+ GART64- 64bit-
> FW- Rate=x4
> 
> 0000:00:01.0 PCI bridge: Advanced Micro Devices [AMD] AMD-760 MP
> [IGD4-2P] AGP Bridge (prog-if 00 [Normal decode])
>          Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
>          Latency: 99
>          Bus: primary=00, secondary=01, subordinate=01, sec-latency=68
>          I/O behind bridge: 00002000-00002fff
>          Memory behind bridge: f4100000-f5ffffff
>          Prefetchable memory behind bridge: fff00000-000fffff
>          Expansion ROM at 00002000 [disabled] [size=4K]
>          BridgeCtl: Parity- SERR- NoISA+ VGA+ MAbort- >Reset- FastB2B-
> 
> 0000:00:07.0 ISA bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] ISA
> (rev 04)
>          Control: I/O+ Mem+ BusMaster+ SpecCycle+ MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
>          Latency: 0
> 
> 0000:00:07.1 IDE interface: Advanced Micro Devices [AMD] AMD-768 [Opus]
> IDE (rev 04) (prog-if 8a [Master SecP PriP])
>          Subsystem: Advanced Micro Devices [AMD] AMD-768 [Opus] IDE
>          Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
>          Latency: 0
>          Region 4: I/O ports at f000 [size=16]
> 
> 0000:00:07.3 Bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] ACPI
> (rev 03)
>          Subsystem: Advanced Micro Devices [AMD] AMD-768 [Opus] ACPI
>          Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
> 0000:00:08.0 Ethernet controller: D-Link System Inc DL2000-based Gigabit
> Ethernet (rev 0c)
>          Subsystem: D-Link System Inc DL2000-based Gigabit Ethernet
>          Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap+ 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
>          Latency: 64 (20000ns min, 2500ns max), cache line size 10
>          Interrupt: pin A routed to IRQ 169
>          Region 0: I/O ports at 1000
>          Region 1: Memory at f4000000 (32-bit, non-prefetchable) [size=512]
>          Capabilities: [50] Power Management version 2
>                  Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA
> PME(D0-,D1+,D2+,D3hot+,D3cold-)
>                  Status: D0 PME-Enable- DSel=0 DScale=2 PME-
> 
> 0000:00:10.0 PCI bridge: Advanced Micro Devices [AMD] AMD-768 [Opus] PCI
> (rev 04) (prog-if 00 [Normal decode])
>          Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap- 66Mhz+ UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort+ >SERR- <PERR-
> 
>          Latency: 64
>          Bus: primary=00, secondary=02, subordinate=02, sec-latency=168
>          I/O behind bridge: 00003000-00003fff
>          Memory behind bridge: f6000000-f60fffff
>          Prefetchable memory behind bridge: fff00000-000fffff
>          Expansion ROM at 00003000 [disabled] [size=4K]
>          BridgeCtl: Parity- SERR- NoISA+ VGA- MAbort- >Reset- FastB2B-
> 
> 0000:01:05.0 VGA compatible controller: ATI Technologies Inc Rage XL AGP
> 2X (rev 27) (prog-if 00 [VGA])
>          Subsystem: ATI Technologies Inc Xpert 98 RXL AGP 2X
>          Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping+ SERR- FastB2B-
>          Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
>          Latency: 66 (2000ns min), cache line size 10
>          Interrupt: pin A routed to IRQ 177
>          Region 0: Memory at f5000000 (32-bit, non-prefetchable)
>          Region 1: I/O ports at 2000 [size=256]
>          Region 2: Memory at f4100000 (32-bit, non-prefetchable) [size=4K]
>          Capabilities: [50] AGP version 1.0
>                  Status: RQ=256 Iso- ArqSz=0 Cal=0 SBA+ ITACoh- GART64-
> HTrans- 64bit- FW- AGP3- Rate=x1,x2
>                  Command: RQ=1 ArqSz=0 Cal=0 SBA- AGP- GART64- 64bit-
> FW- Rate=<none>
>          Capabilities: [5c] Power Management version 2
>                  Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA
> PME(D0-,D1-,D2-,D3hot-,D3cold-)
>                  Status: D0 PME-Enable- DSel=0 DScale=0 PME-
> 
> 0000:02:08.0 Ethernet controller: 3Com Corporation 3c905C-TX/TX-M
> [Tornado] (rev 78)
>          Subsystem: Tyan Computer Tiger MPX S2466 (3C920 Integrated Fast
> Ethernet Controller)
>          Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop-
> ParErr- Stepping- SERR- FastB2B-
>          Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium
> 
>  >TAbort- <TAbort- <MAbort- >SERR- <PERR-
> 
>          Latency: 80 (2500ns min, 2500ns max), cache line size 10
>          Interrupt: pin A routed to IRQ 185
>          Region 0: I/O ports at 3000
>          Region 1: Memory at f6001000 (32-bit, non-prefetchable) [size=128]
>          Capabilities: [dc] Power Management version 2
>                  Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA
> PME(D0+,D1+,D2+,D3hot+,D3cold+)
>                  Status: D0 PME-Enable- DSel=0 DScale=2 PME-
> 
> [7.6.] SCSI information (from /proc/scsi/scsi)
> (no scsi chip/card)
> 
> # cat /proc/scsi/scsi
> Attached devices:
> 
> [7.7.] Other information that might be relevant to the problem
>         (please look in /proc and include all information that you
>         think to be relevant):
> 
> [X.] Other notes, patches, fixes, workarounds:
> 
> --
> Richard Ems
> 
> MTG Marinetechnik GmbH
> Wandsbeker Königstr. 62
> 22041 Hamburg
> Telefon: +49 40 65803 312
> TeleFax: +49 40 65803 392
> mail: richard.ems@mtg-marinetechnik.de
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-net" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2005-01-04 22:13 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-12-17 14:54 PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" Richard Ems
     [not found] <200412171100.16601.richard.ems@mtg-marinetechnik.de>
2004-12-17 17:07 ` Jon Mason
2004-12-17 17:15   ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" (Plain) Richard Ems
2004-12-17 18:05     ` Jon Mason
2004-12-17 20:52       ` Jon Mason
2004-12-20 14:34         ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" Richard Ems
2004-12-20 17:12           ` Jon Mason
2004-12-20 18:03             ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" (Plain) Richard Ems
2004-12-20 20:31               ` Jon Mason
2004-12-21  9:51                 ` PROBLEM: Network hang: "eth0: Tx timed out (f0080), is buffer full?" Richard Ems
2004-12-21 16:02                   ` Jon Mason
2004-12-22  9:29                     ` Richard Ems
2004-12-22 14:54                       ` Jon Mason
2004-12-29 17:53                         ` Richard Ems
2005-01-04 21:32                           ` Jon Mason
2005-01-04 22:09                             ` Francois Romieu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).