Commit 40346461 authored by Marc Zyngier's avatar Marc Zyngier Committed by Jeff Garzik

More znet net driver updates. Driver now survives plug/unplug of cable.

parent 8ad09275
......@@ -72,7 +72,10 @@
- Use proper resources management.
- Use wireless/i82593.h as much as possible (structure, constants)
- Compiles as module or build-in.
- Now survives unplugging/replugging cable.
Some code was taken from wavelan_cs.
Tested on a vintage Zenith Z-Note 433Lnp+. Probably broken on
anything else. Testers (and detailed bug reports) are welcome :-).
......@@ -105,7 +108,7 @@
/* This include could be elsewhere, since it is not wireless specific */
#include "wireless/i82593.h"
static const char version[] __initdata = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
static const char version[] __initdata = "znet.c:v1.02 9/23/94 becker@scyld.com\n";
#ifndef ZNET_DEBUG
#define ZNET_DEBUG 1
......@@ -299,7 +302,7 @@ static void znet_set_multicast_list (struct net_device *dev)
cfblk->cd_filter = 0; /* CD is recognized immediately */
/* Byte 9 */
cfblk->min_fr_len = 64 >> 2; /* Minimum frame length 64 bytes */
cfblk->min_fr_len = ETH_ZLEN >> 2; /* Minimum frame length */
/* Byte A */
cfblk->lng_typ = 1; /* Type/length checks OFF */
......@@ -544,10 +547,14 @@ static int znet_send_packet(struct sk_buff *skb, struct net_device *dev)
/* Check that the part hasn't reset itself, probably from suspend. */
outb(CR0_STATUS_0, ioaddr);
if (inw(ioaddr) == 0x0010
&& inw(ioaddr) == 0x0000
&& inw(ioaddr) == 0x0010)
hardware_init(dev);
if (inw(ioaddr) == 0x0010 &&
inw(ioaddr) == 0x0000 &&
inw(ioaddr) == 0x0010) {
if (znet_debug > 1)
printk (KERN_WARNING "%s : waking up\n", dev->name);
hardware_init(dev);
znet_transceiver_power (dev, 1);
}
if (1) {
short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
......@@ -624,7 +631,9 @@ static void znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if ((status & SR0_INTERRUPT) == 0)
break;
if ((status & 0x0F) == SR0_TRANSMIT_DONE) {
if ((status & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
(status & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
(status & SR0_EVENT_MASK) == SR0_TRANSMIT_NO_CRC_DONE) {
int tx_status;
outb(CR0_STATUS_1, ioaddr);
tx_status = inw(ioaddr);
......@@ -644,6 +653,15 @@ static void znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
/* ...and the catch-all. */
if ((tx_status | (TX_LOST_CRS | TX_LOST_CTS | TX_UND_RUN | TX_HRT_BEAT | TX_MAX_COL)) != (TX_LOST_CRS | TX_LOST_CTS | TX_UND_RUN | TX_HRT_BEAT | TX_MAX_COL))
znet->stats.tx_errors++;
/* Transceiver may be stuck if cable
* was removed while emiting a
* packet. Flip it off, then on to
* reset it. This is very empirical,
* but it seems to work. */
znet_transceiver_power (dev, 0);
znet_transceiver_power (dev, 1);
}
netif_wake_queue (dev);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment