patch-2.3.43 linux/drivers/net/epic100.c
Next file: linux/drivers/net/ethertap.c
Previous file: linux/drivers/net/eepro100.c
Back to the patch index
Back to the overall index
- Lines: 444
- Date:
Thu Feb 10 12:22:03 2000
- Orig file:
v2.3.42/linux/drivers/net/epic100.c
- Orig date:
Thu Nov 11 20:11:40 1999
diff -u --recursive --new-file v2.3.42/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
@@ -46,17 +46,7 @@
#define TX_FIFO_THRESH 256 /* Rounded down to 4 byte units. */
#define RX_FIFO_THRESH 1 /* 0-3, 0==32, 64,96, or 3==128 bytes */
-#include <linux/version.h> /* Evil, but neccessary */
-#ifdef MODULE
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
#include <linux/module.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
-
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/timer.h>
@@ -65,11 +55,8 @@
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#if LINUX_VERSION_CODE >= 0x20155
+#include <linux/init.h>
#define PCI_SUPPORT_VER2
-#else
-#include <linux/bios32.h>
-#endif
#include <linux/delay.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
@@ -83,13 +70,8 @@
/* Kernel compatibility defines, common to David Hind's PCMCIA package.
This is only in the support-all-kernels source code. */
-#if ! defined (LINUX_VERSION_CODE) || LINUX_VERSION_CODE < 0x20000
-#warning This driver version is only for kernel versions 2.0.0 and later.
-#endif
-
#define RUN_AT(x) (jiffies + (x))
-#if defined(MODULE) && (LINUX_VERSION_CODE >= 0x20115)
MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
MODULE_DESCRIPTION("SMC 83c170 EPIC series Ethernet driver");
MODULE_PARM(debug, "i");
@@ -97,19 +79,7 @@
MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
MODULE_PARM(rx_copybreak, "i");
MODULE_PARM(max_interrupt_work, "i");
-#endif
-#if LINUX_VERSION_CODE < 0x20123
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#endif
-#if LINUX_VERSION_CODE <= 0x20139
-#define net_device_stats enet_statistics
-#define NETSTATS_VER2
-#endif
-#if LINUX_VERSION_CODE < 0x20159
-#define DEV_FREE_SKB(skb) dev_kfree_skb(skb, FREE_WRITE);
-#else /* Grrr, unneeded incompatible change. */
#define DEV_FREE_SKB(skb) dev_kfree_skb(skb);
-#endif
/* The I/O extent. */
#define EPIC_TOTAL_SIZE 0x100
@@ -151,7 +121,7 @@
/* The rest of these values should never change. */
-static struct net_device *epic_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq,
+static struct net_device *epic_probe1(struct pci_dev *pdev, long ioaddr, int irq,
int chip_id, int card_idx);
enum pci_flags_bit {
@@ -163,8 +133,9 @@
const char *name;
u16 vendor_id, device_id, device_id_mask, pci_flags;
int io_size, min_latency;
- struct net_device *(*probe1)(int pci_bus, int pci_devfn,
- long ioaddr, int irq, int chip_idx, int fnd_cnt);
+ struct net_device *(*probe1)(struct pci_dev *pdev,
+ long ioaddr, int irq, int chip_idx,
+ int fnd_cnt);
} chip_tbl[] = {
{"SMSC EPIC/100 83c170", 0x10B8, 0x0005, 0x7fff,
PCI_USES_IO|PCI_USES_MASTER|PCI_ADDR0, EPIC_TOTAL_SIZE, 32, epic_probe1},
@@ -217,6 +188,8 @@
char devname[8]; /* Used only for kernel debugging. */
const char *product_name;
struct net_device *next_module;
+
+ spinlock_t lock;
/* Tx and Rx rings here so that they remain paragraph aligned. */
struct epic_rx_desc rx_ring[RX_RING_SIZE];
@@ -273,7 +246,7 @@
static struct net_device *root_epic_dev = NULL;
#ifndef CARDBUS
-int epic100_probe(void)
+static int __init epic100_probe(void)
{
int cards_found = 0;
int chip_idx, irq;
@@ -281,7 +254,6 @@
unsigned char pci_bus, pci_device_fn;
struct net_device *dev;
-#ifdef PCI_SUPPORT_VER2
struct pci_dev *pcidev = NULL;
while ((pcidev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pcidev))
!= NULL) {
@@ -300,76 +272,33 @@
pci_bus = pcidev->bus->number;
pci_device_fn = pcidev->devfn;
irq = pcidev->irq;
-#else
- int pci_index;
-
- if ( ! pcibios_present())
- return -ENODEV;
-
- for (pci_index = 0; pci_index < 0xff; pci_index++) {
- u8 pci_irq_line;
- u16 vendor, device;
- u32 pci_ioaddr;
-
- if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
- pci_index, &pci_bus, &pci_device_fn)
- != PCIBIOS_SUCCESSFUL)
- break;
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_DEVICE_ID, &device);
-
- for (chip_idx = 0; chip_tbl[chip_idx].vendor_id; chip_idx++)
- if (vendor == chip_tbl[chip_idx].vendor_id
- && (device & chip_tbl[chip_idx].device_id_mask) ==
- chip_tbl[chip_idx].device_id)
- break;
- if (chip_tbl[chip_idx].vendor_id == 0) /* Compiled out! */
- continue;
-
- pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
- irq = pci_irq_line;
-
- if (check_region(pci_ioaddr, chip_tbl[chip_idx].io_size))
- continue;
-#endif
/* EPIC-specific code: Soft-reset the chip ere setting as master. */
outl(0x0001, pci_ioaddr + GENCTL);
/* Activate the card: fix for brain-damaged Win98 BIOSes. */
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
+ pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
if (pci_command != new_command) {
printk(KERN_INFO " The PCI BIOS has not enabled Ethernet"
" device %4.4x-%4.4x."
" Updating PCI command %4.4x->%4.4x.\n",
vendor, device, pci_command, new_command);
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, new_command);
+ pci_write_config_word(pcidev, PCI_COMMAND, new_command);
}
- dev = chip_tbl[chip_idx].probe1(pci_bus, pci_device_fn, pci_ioaddr,
- irq, chip_idx, cards_found);
+ dev = chip_tbl[chip_idx].probe1(pcidev, pci_ioaddr, irq,
+ chip_idx, cards_found);
/* Check the latency timer. */
if (dev) {
u8 pci_latency;
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < chip_tbl[chip_idx].min_latency) {
printk(KERN_INFO " PCI latency timer (CFLT) value of %d is "
"unreasonably low, setting to %d.\n", pci_latency,
chip_tbl[chip_idx].min_latency);
- pcibios_write_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER,
+ pci_write_config_byte(pcidev, PCI_LATENCY_TIMER,
chip_tbl[chip_idx].min_latency);
}
dev = 0;
@@ -381,8 +310,8 @@
}
#endif /* not CARDBUS */
-static struct net_device *epic_probe1(int pci_bus, int pci_devfn, long ioaddr, int irq,
- int chip_idx, int card_idx)
+static struct net_device *epic_probe1(struct pci_dev *pdev, long ioaddr, int irq,
+ int chip_idx, int card_idx)
{
struct epic_private *ep;
int i, option = 0, duplex = 0;
@@ -444,13 +373,10 @@
ep->next_module = root_epic_dev;
root_epic_dev = dev;
- ep->pci_bus = pci_bus;
- ep->pci_dev_fn = pci_devfn;
-#if defined(PCI_SUPPORT_VER2)
- ep->chip_id = pci_find_slot(pci_bus, pci_devfn)->device;
-#else
- ep->chip_id = chip_tbl[chip_idx].device_id;
-#endif
+ ep->lock = SPIN_LOCK_UNLOCKED;
+ ep->pci_bus = pdev->bus->number;
+ ep->pci_dev_fn = pdev->devfn;
+ ep->chip_id = pdev->device;
/* Find the connected MII xcvrs.
Doing this in open() would allow detecting external xcvrs later, but
@@ -497,6 +423,8 @@
dev->get_stats = &epic_get_stats;
dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = &mii_ioctl;
+ dev->tx_timeout = epic_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
return dev;
}
@@ -653,9 +581,7 @@
set_rx_mode(dev);
outl(0x000A, ioaddr + COMMAND);
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
+ netif_start_queue(dev);
/* Enable interrupts by setting the interrupt mask. */
outl((ep->chip_id == 6 ? PCIBusErr175 : PCIBusErr170)
@@ -864,15 +790,6 @@
int entry;
u32 flag;
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- if (jiffies - dev->trans_start < TX_TIMEOUT)
- return 1;
- epic_tx_timeout(dev);
- return 1;
- }
-
/* Caution: the write order is important here, set the base address
with the "ownership" bits last. */
@@ -889,13 +806,13 @@
if (ep->cur_tx - ep->dirty_tx < TX_RING_SIZE/2) {/* Typical path */
flag = 0x10; /* No interrupt */
- clear_bit(0, (void*)&dev->tbusy);
+ netif_start_queue(dev);
} else if (ep->cur_tx - ep->dirty_tx == TX_RING_SIZE/2) {
flag = 0x14; /* Tx-done intr. */
- clear_bit(0, (void*)&dev->tbusy);
+ netif_start_queue(dev);
} else if (ep->cur_tx - ep->dirty_tx < TX_RING_SIZE - 2) {
flag = 0x10; /* No Tx-done intr. */
- clear_bit(0, (void*)&dev->tbusy);
+ netif_start_queue(dev);
} else {
/* Leave room for two additional entries. */
flag = 0x14; /* Tx-done intr. */
@@ -927,21 +844,7 @@
long ioaddr = dev->base_addr;
int status, boguscnt = max_interrupt_work;
-#if defined(__i386__)
- /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
- if (test_and_set_bit(0, (void*)&dev->interrupt)) {
- printk(KERN_ERR "%s: SMP simultaneous entry of an interrupt handler.\n",
- dev->name);
- dev->interrupt = 0; /* Avoid halting machine. */
- return;
- }
-#else
- if (dev->interrupt) {
- printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
- return;
- }
- dev->interrupt = 1;
-#endif
+ spin_lock (&ep->lock);
do {
status = inl(ioaddr + INTSTAT);
@@ -1004,12 +907,12 @@
}
#endif
- if (ep->tx_full && dev->tbusy
- && dirty_tx > ep->cur_tx - TX_RING_SIZE + 2) {
+ if (ep->tx_full &&
+ test_bit(LINK_STATE_XOFF, &dev->flags) &&
+ dirty_tx > ep->cur_tx - TX_RING_SIZE + 2) {
/* The ring is no longer full, clear tbusy. */
ep->tx_full = 0;
- clear_bit(0, (void*)&dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
}
ep->dirty_tx = dirty_tx;
@@ -1057,12 +960,7 @@
printk(KERN_DEBUG "%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, inl(ioaddr + INTSTAT));
-#if defined(__i386__)
- clear_bit(0, (void*)&dev->interrupt);
-#else
- dev->interrupt = 0;
-#endif
- return;
+ spin_unlock (&ep->lock);
}
static int epic_rx(struct net_device *dev)
@@ -1147,8 +1045,7 @@
struct epic_private *ep = (struct epic_private *)dev->priv;
int i;
- dev->start = 0;
- dev->tbusy = 1;
+ netif_stop_queue(dev);
if (epic_debug > 1)
printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
@@ -1176,9 +1073,6 @@
ep->rx_ring[i].buflength = 0;
ep->rx_ring[i].bufaddr = 0xBADF00D0; /* An invalid address. */
if (skb) {
-#if LINUX_VERSION_CODE < 0x20100
- skb->free = 1;
-#endif
DEV_FREE_SKB(skb);
}
}
@@ -1202,7 +1096,7 @@
struct epic_private *ep = (struct epic_private *)dev->priv;
long ioaddr = dev->base_addr;
- if (dev->start) {
+ if (test_bit(LINK_STATE_START, &dev->state)) {
/* Update the error counts. */
ep->stats.rx_missed_errors += inb(ioaddr + MPCNT);
ep->stats.rx_frame_errors += inb(ioaddr + ALICNT);
@@ -1288,12 +1182,12 @@
data[0] = ((struct epic_private *)dev->priv)->phys[0] & 0x1f;
/* Fall Through */
case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
- if (! dev->start) {
+ if (! test_bit(LINK_STATE_START, &dev->state)) {
outl(0x0200, ioaddr + GENCTL);
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
}
data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
- if (! dev->start) {
+ if (! test_bit(LINK_STATE_START, &dev->state)) {
#ifdef notdef
outl(0x0008, ioaddr + GENCTL);
outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
@@ -1303,12 +1197,12 @@
case SIOCDEVPRIVATE+2: /* Write the specified MII register */
if (!suser())
return -EPERM;
- if (! dev->start) {
+ if (! test_bit(LINK_STATE_START, &dev->state)) {
outl(0x0200, ioaddr + GENCTL);
outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
}
mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
- if (! dev->start) {
+ if (! test_bit(LINK_STATE_START, &dev->state)) {
#ifdef notdef
outl(0x0008, ioaddr + GENCTL);
outl((inl(ioaddr + NVCTL) & ~0x483C) | 0x0000, ioaddr + NVCTL);
@@ -1331,13 +1225,15 @@
u16 dev_id;
u32 io;
u8 bus, devfn, irq;
+ struct pci_dev *pdev;
if (loc->bus != LOC_PCI) return NULL;
- bus = loc->b.pci.bus; devfn = loc->b.pci.devfn;
+ 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);
- pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &io);
- pcibios_read_config_byte(bus, devfn, PCI_INTERRUPT_LINE, &irq);
- pcibios_read_config_word(bus, devfn, PCI_DEVICE_ID, &dev_id);
+ io = pdev->resource[0].start;
+ irq = pdev->irq;
+ dev_id = pdev->device;
io &= ~3;
if (io == 0 || irq == 0) {
printk(KERN_ERR "The EPIC/C CardBus Ethernet interface was not "
@@ -1407,10 +1303,8 @@
#endif /* Cardbus support */
-
-#ifdef MODULE
-int init_module(void)
+static int __init epic100_init_module(void)
{
if (epic_debug)
printk(KERN_INFO "%s", version);
@@ -1423,7 +1317,7 @@
#endif
}
-void cleanup_module(void)
+static void __exit epic100_cleanup_module(void)
{
struct net_device *next_dev;
@@ -1443,8 +1337,10 @@
}
}
-#endif /* MODULE */
-
+module_init(epic100_init_module);
+module_exit(epic100_cleanup_module);
+
+
/*
* Local variables:
* compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c epic100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)