patch-2.3.43 linux/drivers/net/yellowfin.c
Next file: linux/drivers/parport/ieee1284_ops.c
Previous file: linux/drivers/net/wan/cosa.c
Back to the patch index
Back to the overall index
- Lines: 318
- Date:
Thu Feb 10 12:28:01 2000
- Orig file:
v2.3.42/linux/drivers/net/yellowfin.c
- Orig date:
Thu Nov 11 20:11:42 1999
diff -u --recursive --new-file v2.3.42/linux/drivers/net/yellowfin.c linux/drivers/net/yellowfin.c
@@ -74,6 +74,7 @@
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/init.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/bitops.h>
#include <asm/unaligned.h>
@@ -83,27 +84,9 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-/* Kernel compatibility defines, most common to the PCCard package. */
-#include <linux/version.h> /* Evil and unneccessary */
-
#define RUN_AT(x) (jiffies + (x))
-#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 < 0x20155
-#define PCI_SUPPORT_VER1
-#define pci_present pcibios_present
-#endif
-#if LINUX_VERSION_CODE < 0x20159
-#define DEV_FREE_SKB(skb) dev_kfree_skb(skb, FREE_WRITE);
-#else
#define DEV_FREE_SKB(skb) dev_kfree_skb(skb);
-#endif
/* The PCI I/O space extent. */
#define YELLOWFIN_TOTAL_SIZE 0x100
@@ -280,9 +263,9 @@
struct tx_status_words tx_status[TX_RING_SIZE];
struct timer_list timer; /* Media selection timer. */
struct enet_statistics stats;
+ spinlock_t lock;
/* Frequently used and paired value: keep adjacent for cache effect. */
int chip_id;
- int in_interrupt;
struct yellowfin_desc *rx_head_desc;
struct tx_status_words *tx_tail_desc;
unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
@@ -300,9 +283,6 @@
u32 pad[4]; /* Used for 32-byte alignment */
};
-#ifdef MODULE
-
-#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
MODULE_PARM(max_interrupt_work, "i");
@@ -312,9 +292,6 @@
MODULE_PARM(rx_copybreak, "i");
MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-#endif
-
-#endif
static struct net_device *yellowfin_probe1(long ioaddr, int irq, int chip_id, int options);
static int read_eeprom(long ioaddr, int location);
@@ -340,7 +317,7 @@
/* A list of all installed Yellowfin devices, for removing the driver module. */
static struct net_device *root_yellowfin_dev = NULL;
-int yellowfin_probe(void)
+static int __init yellowfin_probe(void)
{
int cards_found = 0;
int pci_index = 0;
@@ -355,6 +332,7 @@
int chip_idx;
int irq;
long ioaddr;
+ struct pci_dev *pdev;
if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
pci_index,
@@ -362,10 +340,10 @@
!= 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);
+ pdev = pci_find_slot (pci_bus, pci_device_fn);
+ if (!pdev) break;
+ vendor = pdev->vendor;
+ device = pdev->device;
for (chip_idx = 0; chip_tbl[chip_idx].vendor_id; chip_idx++)
if (vendor == chip_tbl[chip_idx].vendor_id
@@ -388,28 +366,24 @@
if (check_region(ioaddr, YELLOWFIN_TOTAL_SIZE))
continue;
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
+ pci_read_config_word(pdev, 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 the"
" device at %d/%d! Updating PCI command %4.4x->%4.4x.\n",
pci_bus, pci_device_fn, pci_command, new_command);
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, new_command);
+ pci_write_config_word(pdev, PCI_COMMAND, new_command);
}
if(yellowfin_probe1(ioaddr, irq, chip_idx, cards_found))
{
/* Get and check the bus-master and latency values. */
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < min_pci_latency) {
printk(KERN_INFO " PCI latency timer (CFLT) is "
"unreasonably low at %d. Setting to %d clocks.\n",
pci_latency, min_pci_latency);
- pcibios_write_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, min_pci_latency);
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, min_pci_latency);
} else if (yellowfin_debug > 1)
printk(KERN_INFO " PCI latency timer (CFLT) is %#x.\n",
pci_latency);
@@ -465,6 +439,7 @@
root_yellowfin_dev = dev;
yp->chip_id = chip_id;
+ yp->lock = SPIN_LOCK_UNLOCKED;
option = card_idx < MAX_UNITS ? options[card_idx] : 0;
if (dev->mem_start)
@@ -493,6 +468,9 @@
#ifdef HAVE_PRIVATE_IOCTL
dev->do_ioctl = &mii_ioctl;
#endif
+ dev->tx_timeout = yellowfin_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+
if (mtu)
dev->mtu = mtu;
@@ -602,9 +580,7 @@
if (dev->if_port == 0)
dev->if_port = yp->default_port;
- dev->tbusy = 0;
- dev->interrupt = 0;
- yp->in_interrupt = 0;
+ netif_start_queue(dev);
/* Setting the Rx mode will start the Rx process. */
if (yp->chip_id == 0) {
@@ -618,8 +594,6 @@
}
set_rx_mode(dev);
- dev->start = 1;
-
/* Enable interrupts by setting the interrupt mask. */
outw(0x81ff, ioaddr + IntrEnb); /* See enum intr_status_bits */
outw(0x0000, ioaddr + EventStatus); /* Clear non-interrupting events */
@@ -787,15 +761,6 @@
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
unsigned entry;
- /* 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;
- yellowfin_tx_timeout(dev);
- return 1;
- }
-
/* Caution: the write order is important here, set the base address
with the "ownership" bits last. */
@@ -840,7 +805,7 @@
outl(0x10001000, dev->base_addr + TxCtrl);
if (yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 1)
- clear_bit(0, (void*)&dev->tbusy); /* Typical path */
+ netif_start_queue(dev); /* Typical path */
else
yp->tx_full = 1;
dev->trans_start = jiffies;
@@ -869,11 +834,8 @@
ioaddr = dev->base_addr;
yp = (struct yellowfin_private *)dev->priv;
- if (test_and_set_bit(0, (void*)&yp->in_interrupt)) {
- dev->interrupt = 1;
- printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
- return;
- }
+
+ spin_lock (&yp->lock);
do {
u16 intr_status = inw(ioaddr + IntrClear);
@@ -900,12 +862,12 @@
yp->tx_skbuff[entry] = 0;
yp->stats.tx_packets++;
}
- if (yp->tx_full && dev->tbusy
- && yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 4) {
+ if (yp->tx_full &&
+ test_bit(LINK_STATE_XOFF, &dev->flags) &&
+ yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 4) {
/* The ring is no longer full, clear tbusy. */
yp->tx_full = 0;
- clear_bit(0, (void*)&dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
}
#else
if (intr_status & IntrTxDone
@@ -973,12 +935,12 @@
}
#endif
- if (yp->tx_full && dev->tbusy
- && yp->cur_tx - dirty_tx < TX_RING_SIZE - 2) {
+ if (yp->tx_full &&
+ test_bit(LINK_STATE_XOFF, &dev->flags) &&
+ yp->cur_tx - dirty_tx < TX_RING_SIZE - 2) {
/* The ring is no longer full, clear tbusy. */
yp->tx_full = 0;
- clear_bit(0, (void*)&dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
}
yp->dirty_tx = dirty_tx;
@@ -1004,15 +966,14 @@
/* Code that should never be run! Perhaps remove after testing.. */
{
static int stopit = 10;
- if (dev->start == 0 && --stopit < 0) {
+ if ((!test_bit(LINK_STATE_START, &dev->state)) && --stopit < 0) {
printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n",
dev->name);
free_irq(irq, dev);
}
}
- dev->interrupt = 0;
- clear_bit(0, (void*)&yp->in_interrupt);
+ spin_lock (&yp->lock);
return;
}
@@ -1171,8 +1132,7 @@
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
int i;
- dev->start = 0;
- dev->tbusy = 1;
+ netif_stop_queue(dev);
if (yellowfin_debug > 1) {
printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n",
@@ -1233,9 +1193,6 @@
yp->rx_ring[i].cmd = CMD_STOP;
yp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
if (yp->rx_skbuff[i]) {
-#if LINUX_VERSION_CODE < 0x20100
- yp->rx_skbuff[i]->free = 1;
-#endif
DEV_FREE_SKB(yp->rx_skbuff[i]);
}
yp->rx_skbuff[i] = 0;
@@ -1358,13 +1315,11 @@
}
#endif /* HAVE_PRIVATE_IOCTL */
-
-#ifdef MODULE
/* An additional parameter that may be passed in... */
static int debug = -1;
-int init_module(void)
+static int __init yellowfin_init_module(void)
{
if (debug >= 0)
yellowfin_debug = debug;
@@ -1372,7 +1327,7 @@
return yellowfin_probe();
}
-void cleanup_module(void)
+static void __exit yellowfin_cleanup_module (void)
{
struct net_device *next_dev;
@@ -1386,8 +1341,10 @@
}
}
-#endif /* MODULE */
-
+module_init(yellowfin_init_module);
+module_exit(yellowfin_cleanup_module);
+
+
/*
* Local variables:
* compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.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)