hi!
When I download big files with a win-client from my linux-server with samba 2.07 and
kernel 2.4.1 (just downloaded to test the new driver) after a random
time there is a connection-error! ..when I just download a few
megabytes there is no problem.
/var/log/messages on the linux-server with the d-link dfe-530 tx:
[THIS IS THE ERROR-MESSAGE!]
Feb 1 17:25:56 Nethost kernel: NETDEV WATCHDOG: eth0: transmit timed out
Feb 1 17:25:56 Nethost kernel: eth0: Transmit timed out, status 0000, PHY status 782d, resetting...
after booting everthing is fine (..until the big smb-transfer):
/var/log/messages (good):
via-rhine.c:v1.08b-LK1.1.6 8/9/2000 Written by Donald Becker
http://www.scyld.com/network/via-rhine.html
PCI: Assigned IRQ 9 for device 00:0a.0
PCI: Setting latency timer of device 00:0a.0 to 64
eth0: VIA VT6102 Rhine-II at 0xe000, 00:50:ba:68:59:9c, IRQ 9.
eth0: MII PHY found at address 8, status 0x7829 advertising 01e1 Link 0081.
I hope you can fix this problem.
bye.
additional informations:
lspci -vvv:
00:0a.0 Ethernet controller: VIA Technologies, Inc.: Unknown device 3065 (rev 42
)
Subsystem: D-Link System Inc: Unknown device 1401
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Step
ping+ SERR- FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort
- <MAbort- >SERR- <PERR-
Latency: 64 (750ns min, 2000ns max), cache line size 08
Interrupt: pin A routed to IRQ 9
Region 0: I/O ports at e000 [size=256]
Region 1: Memory at e5000000 (32-bit, non-prefetchable) [size=256]
Expansion ROM at <unassigned> [disabled] [size=64K]
Capabilities: [40] 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-
cat /proc/cpuinfo:
processor : 0
vendor_id : GenuineIntel
cpu family : 5
model : 4
model name : Pentium MMX
stepping : 3
cpu MHz : 192.107
fdiv_bug : no
hlt_bug : no
f00f_bug : yes
coma_bug : no
fpu : yes
fpu_exception : yes
cpuid level : 1
wp : yes
flags : fpu vme de pse tsc msr mce cx8 mmx
bogomips : 383.38
cat /proc/ioports:
0000-001f : dma1
0020-003f : pic1
0040-005f : timer
0060-006f : keyboard
0080-008f : dma page reg
00a0-00bf : pic2
00c0-00df : dma2
00f0-00ff : fpu
0170-0177 : ide1
01f0-01f7 : ide0
0280-029f : eth1
0376-0376 : ide1
03c0-03df : vga+
03f6-03f6 : ide0
03f8-03ff : serial(auto)
0cf8-0cff : PCI conf1
e000-e0ff : VIA Technologies, Inc. Ethernet Controller
e000-e0ff : eth0
e800-e80f : Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]
e800-e807 : ide0
e808-e80f : ide1
cat /proc/interrupts:
CPU0
0: 59686 XT-PIC timer
1: 2 XT-PIC keyboard
2: 0 XT-PIC cascade
4: 21 XT-PIC serial
9: 3276 XT-PIC eth0
10: 93 XT-PIC eth1
11: 11704 XT-PIC HiSax
14: 9771 XT-PIC ide0
15: 13 XT-PIC ide1
NMI: 0
ERR: 0
cat /proc/modules:
smc-ultra 4784 1 (autoclean)
via-rhine 9616 1 (autoclean)
hisax 140176 4
isdn 89904 5 [hisax]
>/var/log/messages on the linux-server with the d-link dfe-530 tx:
>[THIS IS THE ERROR-MESSAGE!]
>Feb 1 17:25:56 Nethost kernel: NETDEV WATCHDOG: eth0: transmit timed out
>Feb 1 17:25:56 Nethost kernel: eth0: Transmit timed out, status 0000,
>PHY status 782d, resetting...
>
>after booting everthing is fine (..until the big smb-transfer):
>/var/log/messages (good):
>
>via-rhine.c:v1.08b-LK1.1.6 8/9/2000 Written by Donald Becker
> http://www.scyld.com/network/via-rhine.html
>PCI: Assigned IRQ 9 for device 00:0a.0
>PCI: Setting latency timer of device 00:0a.0 to 64
>eth0: VIA VT6102 Rhine-II at 0xe000, 00:50:ba:68:59:9c, IRQ 9.
>eth0: MII PHY found at address 8, status 0x7829 advertising 01e1 Link 0081.
This sounds every much like it's related to the problems we're having with
the card not initialising on reboot from Windows.
What's the bets we're looking at a new revision of the chip which VIA
haven't (publically) released documentation for yet? I'd say they're
pretty high...
--------------------------------------------------------------
from: Jonathan "Chromatix" Morton
mail: [email protected] (not for attachments)
big-mail: [email protected]
uni-mail: [email protected]
The key to knowledge is not to rely on people to teach you it.
Get VNC Server for Macintosh from http://www.chromatix.uklinux.net/vnc/
-----BEGIN GEEK CODE BLOCK-----
Version 3.12
GCS$/E/S dpu(!) s:- a20 C+++ UL++ P L+++ E W+ N- o? K? w--- O-- M++$ V? PS
PE- Y+ PGP++ t- 5- X- R !tv b++ DI+++ D G e+ h+ r- y+
-----END GEEK CODE BLOCK-----
Hi,
>This sounds every much like it's related to the problems we're having with
>the card not initialising on reboot from Windows.
>
>What's the bets we're looking at a new revision of the chip which VIA
>haven't (publically) released documentation for yet? I'd say they're
>pretty high...
I had the same problem yesterday. I don't have any Windows crap in my
network, the affected machine hasn't rebooted in a week, and my card is
not new. There may be another problem.
via-rhine.c:v1.08b-LK1.1.6 8/9/2000 Written by Donald Becker
http://www.scyld.com/network/via-rhine.html
PCI: Found IRQ 10 for device 00:0a.0
eth0: VIA VT3043 Rhine at 0xd800, 00:40:05:a4:3d:84, IRQ 10.
eth0: MII PHY found at address 8, status 0x782d advertising 05e1 Link 0000.
Kernel 2.4.1-pre9. I loaded the module like this:
insmod via-rhine options=28
00:0a.0 Ethernet controller: VIA Technologies, Inc. VT86C100A [Rhine 10/100] (rev 06)
Subsystem: Elecom Co Ltd: Unknown device 1420
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 (29500ns min, 38000ns max), cache line size 08
Interrupt: pin A routed to IRQ 10
Region 0: I/O ports at d800 [size=128]
Region 1: Memory at de000000 (32-bit, non-prefetchable) [size=128]
Expansion ROM at <unassigned> [disabled] [size=64K]
I wonder about the subsystem: Unknown device. It's the first time I see
this (lspci 2.1.8).
BTW why do I have to "strings /sbin/lspci" to find out its version?
Regards,
hjb
--
Pro-Linux - Germany's largest volunteer Linux support site
http://www.pro-linux.de/
> This sounds every much like it's related to the problems we're having with
> the card not initialising on reboot from Windows.
It's not the same problem. Here the card initializes just fine. And it
works for a while.
The "transmit timed out" message is simply saying that we told the card to
send something but it hasn't generated an interrupt or anything allowing
the driver to know the packet was actually sent.
> What's the bets we're looking at a new revision of the chip which VIA
> haven't (publically) released documentation for yet? I'd say they're
> pretty high...
Oh, that's known already. They haven't released any info on the older
"VT3043" chip either, afaik. And the vt86c100a.pdf document is just a
preliminary version.
/Urban
Urban Widmark wrote:
>
> The "transmit timed out" message is simply saying that we told the card to
> send something but it hasn't generated an interrupt or anything allowing
> the driver to know the packet was actually sent.
>
check via_rhine_tx_timeout():
the function is basically empty.
>
> Oh, that's known already. They haven't released any info on the older
> "VT3043" chip either, afaik. And the vt86c100a.pdf document is just a
> preliminary version.
>
Where can I find that file?
I'll try to implement tx_timeout()
--
Manfred
On Sun, 4 Feb 2001, Manfred Spraul wrote:
> > Oh, that's known already. They haven't released any info on the older
> > "VT3043" chip either, afaik. And the vt86c100a.pdf document is just a
> > preliminary version.
> >
> Where can I find that file?
> I'll try to implement tx_timeout()
http://www.via.com.tw/pdf/productinfo/vt86c100a.pdf
/Urban
--- 2.4/drivers/net/via-rhine.c Sat Feb 3 14:02:54 2001
+++ build-2.4/drivers/net/via-rhine.c Sun Feb 4 15:58:38 2001
@@ -380,6 +380,7 @@
CmdNoTxPoll=0x0800, CmdReset=0x8000,
};
+#define MAX_MII_CNT 4
struct netdev_private {
/* Descriptor rings */
struct rx_desc *rx_ring;
@@ -421,7 +422,8 @@
/* MII transceiver section. */
u16 advertising; /* NWay media advertisement */
- unsigned char phys[2]; /* MII device addresses. */
+ unsigned char phys[MAX_MII_CNT]; /* MII device addresses. */
+ unsigned int mii_cnt; /* number of MIIs found, but only the first one is used */
u16 mii_status; /* last read MII status */
};
@@ -431,7 +433,6 @@
static void via_rhine_check_duplex(struct net_device *dev);
static void via_rhine_timer(unsigned long data);
static void via_rhine_tx_timeout(struct net_device *dev);
-static void via_rhine_init_ring(struct net_device *dev);
static int via_rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
static void via_rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static void via_rhine_tx(struct net_device *dev);
@@ -451,14 +452,11 @@
struct netdev_private *np;
int i, option;
int chip_id = (int) ent->driver_data;
- int irq = pdev->irq;
static int card_idx = -1;
static int did_version = 0;
long ioaddr;
int io_size;
int pci_flags;
- void *ring;
- dma_addr_t ring_dma;
/* print version once and once only */
if (! did_version++) {
@@ -471,6 +469,10 @@
io_size = via_rhine_chip_info[chip_id].io_size;
pci_flags = via_rhine_chip_info[chip_id].pci_flags;
+ if (pci_enable_device (pdev))
+ goto err_out;
+
+
/* this should always be supported */
if (!pci_dma_supported(pdev, 0xffffffff)) {
printk(KERN_ERR "32-bit PCI DMA addresses not supported by the card!?\n");
@@ -484,20 +486,7 @@
goto err_out;
}
- /* allocate pci dma space for rx and tx descriptor rings */
- ring = pci_alloc_consistent(pdev,
- RX_RING_SIZE * sizeof(struct rx_desc) +
- TX_RING_SIZE * sizeof(struct tx_desc),
- &ring_dma);
- if (!ring) {
- printk(KERN_ERR "Could not allocate DMA memory.\n");
- goto err_out;
- }
-
ioaddr = pci_resource_start (pdev, pci_flags & PCI_ADDR0 ? 0 : 1);
-
- if (pci_enable_device (pdev))
- goto err_out_free_dma;
if (pci_flags & PCI_USES_MASTER)
pci_set_master (pdev);
@@ -506,7 +495,7 @@
if (dev == NULL) {
printk (KERN_ERR "init_ethernet failed for card #%d\n",
card_idx);
- goto err_out_free_dma;
+ goto err_out;
}
SET_MODULE_OWNER(dev);
@@ -545,23 +534,18 @@
dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
for (i = 0; i < 5; i++)
printk("%2.2x:", dev->dev_addr[i]);
- printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], pdev->irq);
/* Reset the chip to erase previous misconfiguration. */
writew(CmdReset, ioaddr + ChipCmd);
dev->base_addr = ioaddr;
- dev->irq = irq;
np = dev->priv;
spin_lock_init (&np->lock);
np->chip_id = chip_id;
np->drv_flags = via_rhine_chip_info[chip_id].drv_flags;
np->pdev = pdev;
- np->rx_ring = ring;
- np->tx_ring = ring + RX_RING_SIZE * sizeof(struct rx_desc);
- np->rx_ring_dma = ring_dma;
- np->tx_ring_dma = ring_dma + RX_RING_SIZE * sizeof(struct rx_desc);
if (dev->mem_start)
option = dev->mem_start;
@@ -593,7 +577,7 @@
if (np->drv_flags & CanHaveMII) {
int phy, phy_idx = 0;
np->phys[0] = 1; /* Standard for this chip. */
- for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
+ for (phy = 1; phy < 32 && phy_idx < MAX_MII_CNT; phy++) {
int mii_status = mdio_read(dev, phy, 1);
if (mii_status != 0xffff && mii_status != 0x0000) {
np->phys[phy_idx++] = phy;
@@ -610,6 +594,7 @@
netif_carrier_off(dev);
}
}
+ np->mii_cnt = phy_idx;
}
return 0;
@@ -628,16 +613,202 @@
err_out_free_netdev:
unregister_netdev (dev);
kfree (dev);
-err_out_free_dma:
- pci_free_consistent(pdev,
+err_out:
+ return -ENODEV;
+}
+
+static int alloc_ring(struct net_device* dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ void *ring;
+ dma_addr_t ring_dma;
+
+ ring = pci_alloc_consistent(np->pdev,
+ RX_RING_SIZE * sizeof(struct rx_desc) +
+ TX_RING_SIZE * sizeof(struct tx_desc),
+ &ring_dma);
+ if (!ring) {
+ printk(KERN_ERR "Could not allocate DMA memory.\n");
+ return -ENOMEM;
+ }
+ np->tx_bufs = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
+ &np->tx_bufs_dma);
+ if (np->tx_bufs == NULL) {
+ pci_free_consistent(np->pdev,
RX_RING_SIZE * sizeof(struct rx_desc) +
TX_RING_SIZE * sizeof(struct tx_desc),
ring, ring_dma);
-err_out:
- return -ENODEV;
+ return -ENOMEM;
+ }
+
+ np->rx_ring = ring;
+ np->tx_ring = ring + RX_RING_SIZE * sizeof(struct rx_desc);
+ np->rx_ring_dma = ring_dma;
+ np->tx_ring_dma = ring_dma + RX_RING_SIZE * sizeof(struct rx_desc);
+
+
+ return 0;
+}
+
+void free_ring(struct net_device* dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+
+ pci_free_consistent(np->pdev,
+ RX_RING_SIZE * sizeof(struct rx_desc) +
+ TX_RING_SIZE * sizeof(struct tx_desc),
+ np->rx_ring, np->rx_ring_dma);
+
+ pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
+ np->tx_bufs, np->tx_bufs_dma);
+
+}
+
+static void alloc_rbufs(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ dma_addr_t next;
+ int i;
+
+ np->dirty_rx = np->cur_rx = 0;
+
+ np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+ np->rx_head_desc = &np->rx_ring[0];
+ next = np->rx_ring_dma;
+
+ /* Init the ring entries */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].rx_status = 0;
+ np->rx_ring[i].desc_length = cpu_to_le32(np->rx_buf_sz);
+ next += sizeof(struct rx_desc);
+ np->rx_ring[i].next_desc = cpu_to_le32(next);
+ np->rx_skbuff[i] = 0;
+ }
+ /* Mark the last entry as wrapping the ring. */
+ np->rx_ring[i-1].next_desc = cpu_to_le32(np->rx_ring_dma);
+
+ /* Fill in the Rx buffers. Handle allocation failure gracefully. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break;
+ skb->dev = dev; /* Mark as being used by this device. */
+
+ np->rx_skbuff_dma[i] =
+ pci_map_single(np->pdev, skb->tail, np->rx_buf_sz,
+ PCI_DMA_FROMDEVICE);
+
+ np->rx_ring[i].addr = cpu_to_le32(np->rx_skbuff_dma[i]);
+ np->rx_ring[i].rx_status = cpu_to_le32(DescOwn);
+ }
+ np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
}
+static void free_rbufs(struct net_device* dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].rx_status = 0;
+ np->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
+ if (np->rx_skbuff[i]) {
+ pci_unmap_single(np->pdev,
+ np->rx_skbuff_dma[i],
+ np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ dev_kfree_skb(np->rx_skbuff[i]);
+ }
+ np->rx_skbuff[i] = 0;
+ }
+}
+
+static void alloc_tbufs(struct net_device* dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ dma_addr_t next;
+ int i;
+
+ np->dirty_tx = np->cur_tx = 0;
+ next = np->tx_ring_dma;
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ np->tx_skbuff[i] = 0;
+ np->tx_ring[i].tx_status = 0;
+ np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
+ next += sizeof(struct tx_desc);
+ np->tx_ring[i].next_desc = cpu_to_le32(next);
+ np->tx_buf[i] = &np->tx_bufs[i * PKT_BUF_SZ];
+ }
+ np->tx_ring[i-1].next_desc = cpu_to_le32(np->tx_ring_dma);
+
+}
+
+static void free_tbufs(struct net_device* dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ np->tx_ring[i].tx_status = 0;
+ np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
+ np->tx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
+ if (np->tx_skbuff[i]) {
+ if (np->tx_skbuff_dma[i]) {
+ pci_unmap_single(np->pdev,
+ np->tx_skbuff_dma[i],
+ np->tx_skbuff[i]->len, PCI_DMA_TODEVICE);
+ }
+ dev_kfree_skb(np->tx_skbuff[i]);
+ }
+ np->tx_skbuff[i] = 0;
+ np->tx_buf[i] = 0;
+ }
+}
+
+static void init_registers(struct net_device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int i;
+
+ for (i = 0; i < 6; i++)
+ writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
+
+ /* Initialize other registers. */
+ writew(0x0006, ioaddr + PCIBusConfig); /* Tune configuration??? */
+ /* Configure the FIFO thresholds. */
+ writeb(0x20, ioaddr + TxConfig); /* Initial threshold 32 bytes */
+ np->tx_thresh = 0x20;
+ np->rx_thresh = 0x60; /* Written in via_rhine_set_rx_mode(). */
+
+ if (dev->if_port == 0)
+ dev->if_port = np->default_port;
+
+ writel(np->rx_ring_dma, ioaddr + RxRingPtr);
+ writel(np->tx_ring_dma, ioaddr + TxRingPtr);
+
+ via_rhine_set_rx_mode(dev);
+
+ /* Enable interrupts by setting the interrupt mask. */
+ writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow| IntrRxDropped|
+ IntrTxDone | IntrTxAbort | IntrTxUnderrun |
+ IntrPCIErr | IntrStatsMax | IntrLinkChange | IntrMIIChange,
+ ioaddr + IntrEnable);
+
+ np->chip_cmd = CmdStart|CmdTxOn|CmdRxOn|CmdNoTxPoll;
+ if (np->duplex_lock)
+ np->chip_cmd |= CmdFDuplex;
+ writew(np->chip_cmd, ioaddr + ChipCmd);
+ via_rhine_check_duplex(dev);
+
+ /* The LED outputs of various MII xcvrs should be configured. */
+ /* For NS or Mison phys, turn on bit 1 in register 0x17 */
+ /* For ESI phys, turn on bit 7 in register 0x17. */
+ mdio_write(dev, np->phys[0], 0x17, mdio_read(dev, np->phys[0], 0x17) |
+ (np->drv_flags & HasESIPhy) ? 0x0080 : 0x0001);
+}
/* Read and write over the MII Management Data I/O (MDIO) interface. */
static int mdio_read(struct net_device *dev, int phy_id, int regnum)
@@ -698,68 +869,28 @@
/* Reset the chip. */
writew(CmdReset, ioaddr + ChipCmd);
- i = request_irq(dev->irq, &via_rhine_interrupt, SA_SHIRQ, dev->name, dev);
+ i = request_irq(np->pdev->irq, &via_rhine_interrupt, SA_SHIRQ, dev->name, dev);
if (i)
return i;
if (debug > 1)
printk(KERN_DEBUG "%s: via_rhine_open() irq %d.\n",
- dev->name, dev->irq);
-
- np->tx_bufs = pci_alloc_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
- &np->tx_bufs_dma);
- if (np->tx_bufs == NULL) {
- free_irq(dev->irq, dev);
- return -ENOMEM;
- }
-
- via_rhine_init_ring(dev);
-
- writel(np->rx_ring_dma, ioaddr + RxRingPtr);
- writel(np->tx_ring_dma, ioaddr + TxRingPtr);
-
- for (i = 0; i < 6; i++)
- writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
-
- /* Initialize other registers. */
- writew(0x0006, ioaddr + PCIBusConfig); /* Tune configuration??? */
- /* Configure the FIFO thresholds. */
- writeb(0x20, ioaddr + TxConfig); /* Initial threshold 32 bytes */
- np->tx_thresh = 0x20;
- np->rx_thresh = 0x60; /* Written in via_rhine_set_rx_mode(). */
-
- if (dev->if_port == 0)
- dev->if_port = np->default_port;
-
- netif_start_queue(dev);
-
- via_rhine_set_rx_mode(dev);
-
- /* Enable interrupts by setting the interrupt mask. */
- writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow| IntrRxDropped|
- IntrTxDone | IntrTxAbort | IntrTxUnderrun |
- IntrPCIErr | IntrStatsMax | IntrLinkChange | IntrMIIChange,
- ioaddr + IntrEnable);
-
- np->chip_cmd = CmdStart|CmdTxOn|CmdRxOn|CmdNoTxPoll;
- if (np->duplex_lock)
- np->chip_cmd |= CmdFDuplex;
- writew(np->chip_cmd, ioaddr + ChipCmd);
-
- via_rhine_check_duplex(dev);
-
- /* The LED outputs of various MII xcvrs should be configured. */
- /* For NS or Mison phys, turn on bit 1 in register 0x17 */
- /* For ESI phys, turn on bit 7 in register 0x17. */
- mdio_write(dev, np->phys[0], 0x17, mdio_read(dev, np->phys[0], 0x17) |
- (np->drv_flags & HasESIPhy) ? 0x0080 : 0x0001);
-
+ dev->name, np->pdev->irq);
+
+ i = alloc_ring(dev);
+ if (i)
+ return i;
+ alloc_rbufs(dev);
+ alloc_tbufs(dev);
+ init_registers(dev);
if (debug > 2)
printk(KERN_DEBUG "%s: Done via_rhine_open(), status %4.4x "
"MII status: %4.4x.\n",
dev->name, readw(ioaddr + ChipCmd),
mdio_read(dev, np->phys[0], 1));
+ netif_start_queue(dev);
+
/* Set the timer to check for link beat. */
init_timer(&np->timer);
np->timer.expires = jiffies + 2;
@@ -835,84 +966,34 @@
struct netdev_private *np = (struct netdev_private *) dev->priv;
long ioaddr = dev->base_addr;
- /* Lock to protect mdio_read and access to stats. A friendly
- advice to the implementor of the XXXs in this function is to be
- sure not to spin too long (whatever that means :) */
- spin_lock_irq (&np->lock);
-
printk (KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
"%4.4x, resetting...\n",
dev->name, readw (ioaddr + IntrStatus),
mdio_read (dev, np->phys[0], 1));
- /* XXX Perhaps we should reinitialize the hardware here. */
dev->if_port = 0;
- /* Stop and restart the chip's Tx processes . */
- /* XXX to do */
-
- /* Trigger an immediate transmit demand. */
- /* XXX to do */
-
- dev->trans_start = jiffies;
- np->stats.tx_errors++;
-
- spin_unlock_irq (&np->lock);
-}
-
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void via_rhine_init_ring(struct net_device *dev)
-{
- struct netdev_private *np = (struct netdev_private *)dev->priv;
- int i;
- dma_addr_t next = np->rx_ring_dma;
-
- np->cur_rx = np->cur_tx = 0;
- np->dirty_rx = np->dirty_tx = 0;
+ /* protect against concurrent rx interrupts */
+ disable_irq(np->pdev->irq);
- np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
- np->rx_head_desc = &np->rx_ring[0];
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- np->rx_ring[i].rx_status = 0;
- np->rx_ring[i].desc_length = cpu_to_le32(np->rx_buf_sz);
- next += sizeof(struct rx_desc);
- np->rx_ring[i].next_desc = cpu_to_le32(next);
- np->rx_skbuff[i] = 0;
- }
- /* Mark the last entry as wrapping the ring. */
- np->rx_ring[i-1].next_desc = cpu_to_le32(np->rx_ring_dma);
+ spin_lock(&np->lock);
- /* Fill in the Rx buffers. Handle allocation failure gracefully. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
- np->rx_skbuff[i] = skb;
- if (skb == NULL)
- break;
- skb->dev = dev; /* Mark as being used by this device. */
-
- np->rx_skbuff_dma[i] =
- pci_map_single(np->pdev, skb->tail, np->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
-
- np->rx_ring[i].addr = cpu_to_le32(np->rx_skbuff_dma[i]);
- np->rx_ring[i].rx_status = cpu_to_le32(DescOwn);
- }
- np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+ /* Reset the chip. */
+ writew(CmdReset, ioaddr + ChipCmd);
- next = np->tx_ring_dma;
- for (i = 0; i < TX_RING_SIZE; i++) {
- np->tx_skbuff[i] = 0;
- np->tx_ring[i].tx_status = 0;
- np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
- next += sizeof(struct tx_desc);
- np->tx_ring[i].next_desc = cpu_to_le32(next);
- np->tx_buf[i] = &np->tx_bufs[i * PKT_BUF_SZ];
- }
- np->tx_ring[i-1].next_desc = cpu_to_le32(np->tx_ring_dma);
+ /* Reinitialize the hardware. */
+ free_tbufs(dev);
+ free_rbufs(dev);
+ alloc_tbufs(dev);
+ alloc_rbufs(dev);
+ init_registers(dev);
+
+ spin_unlock(&np->lock);
+ enable_irq(np->pdev->irq);
- return;
+ dev->trans_start = jiffies;
+ np->stats.tx_errors++;
+ netif_wake_queue(dev);
}
static int via_rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
@@ -1339,12 +1420,10 @@
{
long ioaddr = dev->base_addr;
struct netdev_private *np = (struct netdev_private *)dev->priv;
- int i;
- unsigned long flags;
del_timer_sync(&np->timer);
- spin_lock_irqsave(&np->lock, flags);
+ spin_lock_irq(&np->lock);
netif_stop_queue(dev);
@@ -1361,44 +1440,12 @@
/* Stop the chip's Tx and Rx processes. */
writew(CmdStop, ioaddr + ChipCmd);
- spin_unlock_irqrestore(&np->lock, flags);
-
- /* Make sure there is no irq-handler running on a different CPU. */
- synchronize_irq();
-
- free_irq(dev->irq, dev);
-
- /* Free all the skbuffs in the Rx queue. */
- for (i = 0; i < RX_RING_SIZE; i++) {
- np->rx_ring[i].rx_status = 0;
- np->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
- if (np->rx_skbuff[i]) {
- pci_unmap_single(np->pdev,
- np->rx_skbuff_dma[i],
- np->rx_buf_sz, PCI_DMA_FROMDEVICE);
- dev_kfree_skb(np->rx_skbuff[i]);
- }
- np->rx_skbuff[i] = 0;
- }
+ spin_unlock_irq(&np->lock);
- /* Free all the skbuffs in the Tx queue, and also any bounce buffers. */
- for (i = 0; i < TX_RING_SIZE; i++) {
- np->tx_ring[i].tx_status = 0;
- np->tx_ring[i].desc_length = cpu_to_le32(0x00e08000);
- np->tx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
- if (np->tx_skbuff[i]) {
- if (np->tx_skbuff_dma[i]) {
- pci_unmap_single(np->pdev,
- np->tx_skbuff_dma[i],
- np->tx_skbuff[i]->len, PCI_DMA_TODEVICE);
- }
- dev_kfree_skb(np->tx_skbuff[i]);
- }
- np->tx_skbuff[i] = 0;
- np->tx_buf[i] = 0;
- }
- pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
- np->tx_bufs, np->tx_bufs_dma);
+ free_irq(np->pdev->irq, dev);
+ free_rbufs(dev);
+ free_tbufs(dev);
+ free_ring(dev);
return 0;
}
On 4 Feb 2001, at 23:31, Urban Widmark wrote:
> On Sun, 4 Feb 2001, Manfred wrote:
>
> > Ok, I've attached a patch that performs an unconditional reset in
> > tx_timeout().
> >
> > I don't have the hardware, could you test it?
>
> The changed startup code doesn't break anything for me.
>
> > I also found newer via documentation on via's ftp site:
> > ftp.via.com.tw/public/lan/Products/NIC/VT86C100A, from Sept 98
>
> You've done even better than that:
> ftp.via.com.tw/public/lan/Products/NIC/VT6102
> :)
>
>
> For those of you with vt6102s that don't like being rebooted from
> win98 I have modified Manfred's patch to try and really reset the card
> at startup.
>
> CmdReset is not instant, it may need a delay. There is also a "force
> software reset" operation that sounds good, I assume that one also
> could use a delay so I gave it 6ms.
>
> This will probably not fix things, but it would be nice if you could
> test it as well as Manfred's variant. (I know it's painful to reboot
> into win98 all the time :)
>
> You shouldn't have to reboot between testing each of the patches
> (assumes via-rhine.o as a module). Just make sure the module is
> unloaded and reloaded. So a single win98 trip would allow testing both
> of them.
>
> The via-diag.c program has a bug when looking at vt6102's. They have
> 256 bytes of registers, not just 128. The attached patch fixes this
> (no need to use the -Ii switches). Checking the output again when the
> card is working and not working could give some clue. There are some
> power save states in the higher registers that look suspicious.
>
> 0x96 contains "PHY address at suspend well"
> 0x94-0x95 contains "MII address at suspend well"
> (at suspend well == in power save mode?)
>
> Finally, MII PHYs can be reset by setting bit15 in MII register 0.
> During the search for the PHY it could try resetting each address.
>
> /Urban
>
Right, i patched the via-diag and its showing more regs.
I applyed Manfred's patch but that changed nothing.
Then I applyed your patch and still changed nothing as you suspected.
But there are regs that are different.
Not working:-
via-diag.c:v2.04 7/14/2000 Donald Becker ([email protected])
http://www.scyld.com/diag/index.html
Index #1: Found a VIA VT3065 Rhine-II adapter at 0xd400.
Station address 00:00:00:00:00:00.
Tx disabled, Rx disabled, half-duplex (0x0004).
Receive mode is 0x6c: Normal unicast and hashed multicast.
Transmit mode is 0x21: Normal transmit, 256 byte threshold.
VIA VT3065 Rhine-II chip registers at 0xd400
0x000: 00000000 216c0000 00000004 00000000 00000000 00000000
07c62000 07c62120
0x020: 00000400 00000600 07c61010 07c62010 00000000 00000600
07c61810 07c62020
0x040: c0000000 00e0824e 07c80402 07c62120 00000000 00000000
00000000 feffffff
0x060: 00000000 00000000 00000000 0006131f 00008100 08000080
02470000 00000000
0x080: 03012000 00000000 00000000 00000000 06000080 00000000
00000000 00000000
0x0A0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
0x0C0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
0x0E0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
No interrupt sources are pending (0000).
Access to the EEPROM has been disabled (0x80).
Direct reading or writing is not possible.
EEPROM contents (Assumed from chip registers):
0x100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x110: 00 00 00 00 00 00 00 00 06 00 00 00 47 02 73 73
***WARNING***: No MII transceivers found!
Working:-
via-diag.c:v2.04 7/14/2000 Donald Becker ([email protected])
http://www.scyld.com/diag/index.html
Index #1: Found a VIA VT3065 Rhine-II adapter at 0xd400.
Station address 00:50:ba:6e:d8:55.
Tx disabled, Rx disabled, half-duplex (0x0004).
Receive mode is 0x6c: Normal unicast and hashed multicast.
Transmit mode is 0x21: Normal transmit, 256 byte threshold.
VIA VT3065 Rhine-II chip registers at 0xd400
0x000: 6eba5000 216c55d8 00000004 00000000 80000000 00000000
07c620e0 07c62180
0x020: 00000400 00000600 07c85010 07c620f0 00000000 00000600
07c85810 07c62000
0x040: 00000000 00e08000 00000000 07c62190 00000000 00000000
00000000 fefffffd
0x060: 00000000 00000000 00000000 00061108 ffff9f00 08000080
02470000 00000000
0x080: 00012000 00000000 00000000 00000000 06000080 00080000
00000000 00000000
0x0A0: 01010000 01010000 00000000 00000000 ffffffff ffffffff
ffffffff ffffffff
0x0C0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
0x0E0: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
No interrupt sources are pending (0000).
Access to the EEPROM has been disabled (0x80).
Direct reading or writing is not possible.
EEPROM contents (Assumed from chip registers):
0x100: 00 50 ba 6e d8 55 00 00 00 00 00 00 00 00 00 00
0x110: 00 00 00 00 00 00 00 00 06 00 00 00 47 02 73 73
MII PHY found at address 8, status 0x782d.
MII PHY #8 transceiver registers:
3000 782d 0016 f880 01e1 4461 ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff
0022 ff40 0050 ffc0 00a0 ffff ffff ffff
ffff ffff ffff ffff ffff ffff ffff ffff.
regards
tom
---------------------------------------------------------
This message is ROT-13 encoded twice for extra security
Thomas Stewart - [email protected]
This should contain no attachments
---------------------------------------------------------
Thomas Stewart wrote:
>
> >
> > CmdReset is not instant, it may need a delay. There is also a "force
> > software reset" operation that sounds good, I assume that one also
> > could use a delay so I gave it 6ms.
> >
6 ms is quite long:
I added a reset into tx_timeout, and that function should not take more
than 1 ms or so.
Did you find something about the delay in the documentation? Is it
possible to poll for reset completion?
I know that the winbond-840 chipset resets in 4 pci cycles - perhaps the
via-rhine is also fast?
>
> I applyed Manfred's patch but that changed nothing.
>
That's expected, my patch fixes another bug.
The NIC now recover from "Tx timeout" messages. ksa confirmed that, but
there is still a delay of a few seconds. I'll try to fix that.
> Then I applyed your patch and still changed nothing as you suspected.
> But there are regs that are different.
>
Did you run via-diag before or after loading the via-rhine module?
--
Manfred
On Mon, 5 Feb 2001, Manfred Spraul wrote:
> 6 ms is quite long:
> I added a reset into tx_timeout, and that function should not take more
> than 1 ms or so.
> Did you find something about the delay in the documentation? Is it
> possible to poll for reset completion?
I don't know how long. For testing I figured it might be nice with a long
delay, and I was hoping 6ms is long enough. If it changes anything, then
you can start working on getting it right. :)
There is a flag that may indicate reset complete (that's why the while
loop is there). It is supposed to do that for normal "CmdReset" so maybe
it does the same for "forced reset". I have no idea if it does.
But the reset doesn't seem to change much anyway.
The MII PHY (miffy?) is not responding but there are a few registers to
play with there. One clear difference is the PHY address, 8 vs 31 (and 31
has some special meaning for some other register).
The new register dumps needs to be examined for any vt6102 specifics that
are disabled.
/Urban
On 5 Feb 2001, at 9:38, Manfred Spraul wrote:
> That's expected, my patch fixes another bug.
> The NIC now recover from "Tx timeout" messages. ksa confirmed that,
> but there is still a delay of a few seconds. I'll try to fix that.
>
> > Then I applyed your patch and still changed nothing as you
> > suspected. But there are regs that are different.
> >
> Did you run via-diag before or after loading the via-rhine module?
I compiled it into the kernel, I ran via-diag when it was working and
when it was not working.
regards
tom
---------------------------------------------------------
This message is ROT-13 encoded twice for extra security
Thomas Stewart - [email protected]
This should contain no attachments
---------------------------------------------------------
Thomas Stewart wrote:
>
> Right, i patched the via-diag and its showing more regs.
>
> I applyed Manfred's patch but that changed nothing.
> Then I applyed your patch and still changed nothing as you suspected.
> But there are regs that are different.
>
Several regs are just the wakeup frames, but some look suspicious.
Could you try Urban's patch, but add
<<<<<<<<
writeb(0x00, ioaddr + 0x83);
writel(0x01010000, ioaddr + 0xa0);
writel(0x01010000, ioaddr + 0xa4)
writew(0xffff, ioaddr + 0x72);
writeb(0x08, ioaddr + 0x96);
>>>>>>>>>
just before
+ writeb(0x40, ioaddr + 0x81); /* Force software reset */
(around line 540)
--
Manfred
hi!
..I installed Manfred's patch and the d-link-card was now able to
reset after the tx-timeout-error. that means that the card was again
reachable after the error. but the smb-transfer-connection-error still
appeared. then I set "static int debug = 2;" in the patched
via-rhine.c to get more debug-informations but from then on the card
worked without errors!? I tested this several times and produced a lot
of network traffic - but there was no more error-message!
..but I will do some more tests to get sure. ;-)
bye.
--
Kristof mailto:[email protected]
On 5 Feb 2001, at 11:58, Manfred Spraul wrote:
> Thomas Stewart wrote:
> Several regs are just the wakeup frames, but some look suspicious.
>
> Could you try Urban's patch, but add
>
> <<<<<<<<
> writeb(0x00, ioaddr + 0x83);
> writel(0x01010000, ioaddr + 0xa0);
> writel(0x01010000, ioaddr + 0xa4)
> writew(0xffff, ioaddr + 0x72);
> writeb(0x08, ioaddr + 0x96);
> >>>>>>>>>
>
> just before
> + writeb(0x40, ioaddr + 0x81); /* Force software reset */
> (around line 540)
Right, I tryed that, mac address still reported as 00:00:00:00:00:00
on boot.
I also turned on a bios option to try to reset pnp things.
Also now I cant get the card to do the dhcpcd stuff now, oh why
didn't I just buy an ne2000 :)
regards
tom
---------------------------------------------------------
This message is ROT-13 encoded twice for extra security
Thomas Stewart - [email protected]
This should contain no attachments
---------------------------------------------------------
I just installed Urban's most recent patch, and I still get much the same
problems when I reboot from Windows. The main difference appears to be
that there's a few seconds' pause during the via-rhine driver
initialisation (presumably while it tries to find PHY devices), and there
aren't quite so many "transmit timed out" messages in the system log after
booting. They do still appear though, and the network is not accessible.
This happens when I reboot from Windows, and when I subsequently soft-power
the machine and turn it back on. If also happens if I soft-power the
machine from Windows and switch on straight into Linux.
In short, the card still needs a hard power-off for Linux to get it working
after Windows.
--------------------------------------------------------------
from: Jonathan "Chromatix" Morton
mail: [email protected] (not for attachments)
big-mail: [email protected]
uni-mail: [email protected]
The key to knowledge is not to rely on people to teach you it.
Get VNC Server for Macintosh from http://www.chromatix.uklinux.net/vnc/
-----BEGIN GEEK CODE BLOCK-----
Version 3.12
GCS$/E/S dpu(!) s:- a20 C+++ UL++ P L+++ E W+ N- o? K? w--- O-- M++$ V? PS
PE- Y+ PGP++ t- 5- X- R !tv b++ DI+++ D G e+ h+ r- y+
-----END GEEK CODE BLOCK-----