patch-2.3.45 linux/drivers/net/epic100.c

Next file: linux/drivers/net/eth16i.c
Previous file: linux/drivers/net/eepro100.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.44/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
@@ -79,7 +79,6 @@
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
-#define DEV_FREE_SKB(skb) dev_kfree_skb(skb);
 
 /* The I/O extent. */
 #define EPIC_TOTAL_SIZE 0x100
@@ -425,6 +424,8 @@
 	dev->do_ioctl = &mii_ioctl;
 	dev->tx_timeout = epic_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+	
+	netif_stop_queue (dev);
 
 	return dev;
 }
@@ -527,13 +528,15 @@
 	int mii_reg5;
 	ep->full_duplex = ep->force_fd;
 
+	MOD_INC_USE_COUNT;
+
 	/* Soft reset the chip. */
 	outl(0x4001, ioaddr + GENCTL);
 
-	if (request_irq(dev->irq, &epic_interrupt, SA_SHIRQ, "SMC EPIC/100", dev))
-		return -EAGAIN;
-
-	MOD_INC_USE_COUNT;
+	if (request_irq(dev->irq, &epic_interrupt, SA_SHIRQ, "SMC EPIC/100", dev)) {
+		MOD_DEC_USE_COUNT;
+		return -EBUSY;
+	}
 
 	epic_init_ring(dev);
 
@@ -581,8 +584,6 @@
 	set_rx_mode(dev);
 	outl(0x000A, ioaddr + COMMAND);
 
-	netif_start_queue(dev);
-
 	/* Enable interrupts by setting the interrupt mask. */
 	outl((ep->chip_id == 6 ? PCIBusErr175 : PCIBusErr170)
 		 | CntFull | TxUnderrun | TxDone
@@ -595,10 +596,12 @@
 			   dev->name, ioaddr, dev->irq, inl(ioaddr + GENCTL),
 			   ep->full_duplex ? "full" : "half");
 
+	netif_start_queue(dev);
+
 	/* Set the timer to switch to check for link beat and perhaps switch
 	   to an alternate media type. */
 	init_timer(&ep->timer);
-	ep->timer.expires = RUN_AT((24*HZ)/10);			/* 2.4 sec. */
+	ep->timer.expires = RUN_AT(3*HZ);			/* 3 sec. */
 	ep->timer.data = (unsigned long)dev;
 	ep->timer.function = &epic_timer;				/* timer handler */
 	add_timer(&ep->timer);
@@ -613,6 +616,8 @@
 	long ioaddr = dev->base_addr;
 	struct epic_private *ep = (struct epic_private *)dev->priv;
 
+	netif_stop_queue (dev);
+	
 	/* Disable interrupts by clearing the interrupt mask. */
 	outl(0x00000000, ioaddr + INTMASK);
 	/* Stop the chip's Tx and Rx DMA processes. */
@@ -671,11 +676,13 @@
 		 | CntFull | TxUnderrun | TxDone
 		 | RxError | RxOverflow | RxFull | RxHeader | RxDone,
 		 ioaddr + INTMASK);
+
+	netif_start_queue (dev);
+	
 	printk(KERN_DEBUG "%s: epic_restart() done, cmd status %4.4x, ctl %4.4x"
 		   " interrupt %4.4x.\n",
 			   dev->name, inl(ioaddr + COMMAND), inl(ioaddr + GENCTL),
 		   inl(ioaddr + INTSTAT));
-	return;
 }
 
 static void epic_timer(unsigned long data)
@@ -738,7 +745,8 @@
 
 	dev->trans_start = jiffies;
 	ep->stats.tx_errors++;
-	return;
+	
+	netif_start_queue (dev);
 }
 
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
@@ -790,6 +798,8 @@
 	int entry;
 	u32 flag;
 
+	netif_stop_queue (dev);
+
 	/* Caution: the write order is important here, set the base address
 	   with the "ownership" bits last. */
 
@@ -806,13 +816,10 @@
 	
 	if (ep->cur_tx - ep->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
 	  flag = 0x10; /* No interrupt */
-	  netif_start_queue(dev);
 	} else if (ep->cur_tx - ep->dirty_tx == TX_RING_SIZE/2) {
 	  flag = 0x14; /* Tx-done intr. */
-	  netif_start_queue(dev);
 	} else if (ep->cur_tx - ep->dirty_tx < TX_RING_SIZE - 2) {
 	  flag = 0x10; /* No Tx-done intr. */
-	  netif_start_queue(dev);
 	} else {
 	  /* Leave room for two additional entries. */
 	  flag = 0x14; /* Tx-done intr. */
@@ -826,6 +833,10 @@
 	outl(0x0004, dev->base_addr + COMMAND);
 
 	dev->trans_start = jiffies;
+
+	if (! ep->tx_full)
+		netif_start_queue (dev);
+
 	if (epic_debug > 4)
 		printk(KERN_DEBUG "%s: Queued Tx packet size %d to slot %d, "
 			   "flag %2.2x Tx status %8.8x.\n",
@@ -895,7 +906,7 @@
 				}
 
 				/* Free the original skb. */
-				DEV_FREE_SKB(ep->tx_skbuff[entry]);
+				dev_kfree_skb_irq(ep->tx_skbuff[entry]);
 				ep->tx_skbuff[entry] = 0;
 			}
 
@@ -912,8 +923,12 @@
 			    dirty_tx > ep->cur_tx - TX_RING_SIZE + 2) {
 				/* The ring is no longer full, clear tbusy. */
 				ep->tx_full = 0;
-				netif_wake_queue (dev);
 			}
+			
+			if (ep->tx_full)
+				netif_stop_queue (dev);
+			else
+				netif_wake_queue (dev);
 
 			ep->dirty_tx = dirty_tx;
 		}
@@ -1073,12 +1088,12 @@
 		ep->rx_ring[i].buflength = 0;
 		ep->rx_ring[i].bufaddr = 0xBADF00D0; /* An invalid address. */
 		if (skb) {
-			DEV_FREE_SKB(skb);
+			dev_kfree_skb(skb);
 		}
 	}
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		if (ep->tx_skbuff[i])
-			DEV_FREE_SKB(ep->tx_skbuff[i]);
+			dev_kfree_skb(ep->tx_skbuff[i]);
 		ep->tx_skbuff[i] = 0;
 	}
 
@@ -1224,13 +1239,14 @@
 	struct net_device *dev;
 	u16 dev_id;
 	u32 io;
-	u8 bus, devfn, irq;
+	u8 irq;
 	struct pci_dev *pdev;
 
 	if (loc->bus != LOC_PCI) return NULL;
 	pdev = pci_find_slot (loc->b.pci.bus, loc->b.pci.devfn);
 	if (!pdev) return NULL;
-	printk(KERN_DEBUG "epic_attach(bus %d, function %d)\n", bus, devfn);
+	printk(KERN_DEBUG "epic_attach(bus %d, function %d)\n",
+	       pdev->bus->number, pdev->devfn);
 	io = pdev->resource[0].start;
 	irq = pdev->irq;
 	dev_id = pdev->device;
@@ -1241,7 +1257,7 @@
 			   io == 0 ? "I/O address" : "IRQ");
 		return NULL;
 	}
-	dev = epic_probe1(bus, devfn, io, irq, 2, -1);
+	dev = epic_probe1(pdev, io, irq, 2, -1);
 	if (dev) {
 		dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
 		strcpy(node->dev_name, dev->name);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)