patch-2.3.45 linux/drivers/net/a2065.c
Next file: linux/drivers/net/arcnet/arc-rimi.c
Previous file: linux/drivers/net/Makefile
Back to the patch index
Back to the overall index
- Lines: 290
- Date:
Sun Feb 13 10:42:42 2000
- Orig file:
v2.3.44/linux/drivers/net/a2065.c
- Orig date:
Fri Jan 28 15:09:07 2000
diff -u --recursive --new-file v2.3.44/linux/drivers/net/a2065.c linux/drivers/net/a2065.c
@@ -164,7 +164,6 @@
#define ZERO 0
/* Setup the Lance Rx and Tx rings */
-/* Sets dev->tbusy */
static void lance_init_ring (struct net_device *dev)
{
struct lance_private *lp = (struct lance_private *) dev->priv;
@@ -176,7 +175,7 @@
aib = lp->lance_init_block;
/* Lock out other processes while setting up hardware */
- dev->tbusy = 1;
+ netif_stop_queue(dev);
lp->rx_new = lp->tx_new = 0;
lp->rx_old = lp->tx_old = 0;
@@ -442,11 +441,6 @@
if (!(csr0 & LE_C0_INTR)) /* Check if any interrupt has */
return; /* been generated by the Lance. */
- if (dev->interrupt)
- printk ("%s: again", dev->name);
-
- dev->interrupt = 1;
-
/* Acknowledge all the interrupt sources ASAP */
ll->rdp = csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|
LE_C0_INIT);
@@ -473,15 +467,14 @@
ll->rdp = LE_C0_STRT;
}
- if ((TX_BUFFS_AVAIL >= 0) && dev->tbusy) {
- dev->tbusy = 0;
- mark_bh (NET_BH);
- }
+ if (test_bit(LINK_STATE_XOFF, &dev->state) &&
+ TX_BUFFS_AVAIL > 0)
+ netif_wake_queue(dev);
+
ll->rap = LE_CSR0;
ll->rdp = LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|
LE_C0_IDON|LE_C0_INEA;
- dev->interrupt = 0;
}
struct net_device *last_dev = 0;
@@ -506,9 +499,7 @@
load_csrs (lp);
lance_init_ring (dev);
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
+ netif_start_queue(dev);
status = init_restart_lance (lp);
@@ -522,9 +513,8 @@
struct lance_private *lp = (struct lance_private *) dev->priv;
volatile struct lance_regs *ll = lp->ll;
- dev->start = 0;
- dev->tbusy = 1;
- del_timer(&lp->multicast_timer);
+ netif_stop_queue(dev);
+ del_timer_sync(&lp->multicast_timer);
/* Stop the card */
ll->rap = LE_CSR0;
@@ -548,11 +538,11 @@
ll->rdp = LE_C0_STOP;
load_csrs (lp);
+
lance_init_ring (dev);
dev->trans_start = jiffies;
- dev->interrupt = 0;
- dev->start = 1;
- dev->tbusy = 0;
+ netif_start_queue(dev);
+
status = init_restart_lance (lp);
#ifdef DEBUG_DRIVER
printk ("Lance restart=%d\n", status);
@@ -560,6 +550,17 @@
return status;
}
+static void lance_tx_timeout(struct net_device *dev)
+{
+ struct lance_private *lp = (struct lance_private *) dev->priv;
+ volatile struct lance_regs *ll = lp->ll;
+
+ printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n",
+ dev->name, ll->rdp);
+ lance_reset(dev);
+ netif_wake_queue(dev);
+}
+
static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
struct lance_private *lp = (struct lance_private *)dev->priv;
@@ -570,26 +571,6 @@
static int outs;
unsigned long flags;
- /* Transmitter timeout, serious problems */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
-
- if (tickssofar < 100) {
- status = -1;
- } else {
- printk ("%s: transmit timed out, status %04x, resetting\n",
- dev->name, ll->rdp);
- lance_reset (dev);
- }
- return status;
- }
-
- /* Block a timer-based transmit from overlapping. */
- if (test_and_set_bit (0, (void *) &dev->tbusy) != 0) {
- printk ("Transmitter access conflict.\n");
- return -1;
- }
-
skblen = skb->len;
save_flags(flags);
@@ -628,13 +609,15 @@
lp->tx_new = (lp->tx_new+1) & lp->tx_ring_mod_mask;
outs++;
+
+ if (TX_BUFFS_AVAIL <= 0)
+ netif_stop_queue(dev);
+
/* Kick the lance: transmit now */
ll->rdp = LE_C0_INEA | LE_C0_TDMD;
dev->trans_start = jiffies;
dev_kfree_skb (skb);
- if (TX_BUFFS_AVAIL)
- dev->tbusy = 0;
restore_flags(flags);
return status;
@@ -704,21 +687,17 @@
volatile struct lance_init_block *ib = lp->init_block;
volatile struct lance_regs *ll = lp->ll;
- if (!dev->start)
+ if (!test_bit(LINK_STATE_START, &dev->state))
return;
- if (dev->tbusy) {
- mod_timer(&lp->multicast_timer, jiffies + 2);
- return;
- }
- set_bit (0, (void *) &dev->tbusy);
-
if (lp->tx_old != lp->tx_new) {
mod_timer(&lp->multicast_timer, jiffies + 4);
- dev->tbusy = 0;
+ netif_wake_queue(dev);
return;
}
+ netif_stop_queue(dev);
+
ll->rap = LE_CSR0;
ll->rdp = LE_C0_STOP;
lance_init_ring (dev);
@@ -731,14 +710,19 @@
}
load_csrs (lp);
init_restart_lance (lp);
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
}
-int __init a2065_probe(struct net_device *dev)
+static int __init a2065_probe(void)
{
+ struct net_device *dev = NULL;
+ static int called = 0;
struct zorro_dev *z = NULL;
+ if (called)
+ return -ENODEV;
+ called++;
+
while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
unsigned long board, base_addr, ram_start;
int is_cbm;
@@ -765,6 +749,18 @@
continue;
}
strcpy(z->name, "A2065 Ethernet Card");
+
+ dev = init_etherdev(NULL, sizeof(struct lance_private));
+
+ if (dev == NULL) {
+ release_mem_region(base_addr,
+ sizeof(struct lance_regs));
+ release_mem_region(ram_start, A2065_RAM_SIZE);
+ return -ENOMEM;
+ }
+ priv = (struct lance_private *)dev->priv;
+ memset(priv, 0, sizeof(struct lance_private));
+
if (is_cbm) { /* Commodore */
dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x80;
@@ -782,18 +778,6 @@
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
- init_etherdev(dev, 0);
-
- dev->priv = kmalloc(sizeof(struct lance_private), GFP_KERNEL);
- if (dev->priv == NULL) {
- release_mem_region(base_addr,
- sizeof(struct lance_regs));
- release_mem_region(ram_start, A2065_RAM_SIZE);
- return -ENOMEM;
- }
- priv = (struct lance_private *)dev->priv;
- memset(priv, 0, sizeof(struct lance_private));
-
dev->base_addr = ZTWO_VADDR(base_addr);
dev->mem_start = ZTWO_VADDR(ram_start);
dev->mem_end = dev->mem_start+A2065_RAM_SIZE;
@@ -812,6 +796,8 @@
dev->open = &lance_open;
dev->stop = &lance_close;
dev->hard_start_xmit = &lance_start_xmit;
+ dev->tx_timeout = &lance_tx_timeout;
+ dev->watchdog_timeo = 5*HZ;
dev->get_stats = &lance_get_stats;
dev->set_multicast_list = &lance_set_multicast;
dev->dma = 0;
@@ -828,31 +814,9 @@
}
-#ifdef MODULE
-static char devicename[9] = { 0, };
-
-static struct net_device a2065_dev =
-{
- devicename, /* filled in by register_netdev() */
- 0, 0, 0, 0, /* memory */
- 0, 0, /* base, irq */
- 0, 0, 0, NULL, a2065_probe,
-};
-
-int init_module(void)
-{
- int err;
-
- if ((err = register_netdev(&a2065_dev))) {
- if (err == -EIO)
- printk("No A2065 board found. Module not loaded.\n");
- return(err);
- }
- return(0);
-}
-
-void cleanup_module(void)
+static void __exit a2065_cleanup(void)
{
+#ifdef MODULE
struct lance_private *priv = (struct lance_private *)a2065_dev.priv;
unregister_netdev(&a2065_dev);
@@ -860,6 +824,8 @@
sizeof(struct lance_regs));
release_mem_region(ZTWO_PADDR(a2065_dev.mem_start), A2065_RAM_SIZE);
kfree(priv);
+#endif
}
-#endif /* MODULE */
+module_init(a2065_probe);
+module_exit(a2065_cleanup);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)