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

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)