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
- Lines: 192
- Date:
Sun Feb 13 18:24:12 2000
- Orig file:
v2.3.44/linux/drivers/net/epic100.c
- Orig date:
Thu Feb 10 17:11:10 2000
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)