Port of 3c575_cb to 2.3.43pre8

From: Jakob Østergaard (jakob@ostenfeld.dk)
Date: Sun Feb 13 2000 - 16:01:01 EST


Since my previous mail seems to have been eaten by something
on it's way to linux-kernel, I'm resending:

If you have the time, please test the following, which is a
port of the 3c575_cb driver to the 2.3.43pre8 kernel.

It's not completely stable for me, but it is as stable as the
driver has ever been, most likely because of my crappy notebook
playing silly tricks with me.

Here goes...

--- drivers/net/pcmcia/3c575_cb.c.orig Sat Feb 12 02:04:10 2000
+++ drivers/net/pcmcia/3c575_cb.c Sat Feb 12 19:46:46 2000
@@ -17,6 +17,12 @@
 static char *version =
 "3c59x.c:v0.99L 5/28/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n";
 
+/* 12/02/2000: Ported to 2.3.44 by Jakob Oestergaard (jakob@ostenfeld.dk)
+ * The driver is still not completely stable, on my system it will lock
+ * up after the Tx queue fills. But the driver has never worked better
+ * for me.
+ */
+
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
@@ -503,6 +509,7 @@
 static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void acpi_wake(int pci_bus, int pci_devfn);
 static void acpi_set_WOL(struct net_device *dev);
+static void vortex_tx_timeout(struct net_device *dev);
 
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Option count limit only -- unlimited interfaces are supported. */
@@ -1157,9 +1164,7 @@
         outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 
         vp->in_interrupt = 0;
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
+ netif_start_queue(dev);
 
         outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
         outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
@@ -1190,6 +1195,9 @@
         if (vp->reap)
                 return -ENODEV;
 #endif
+ dev->tx_timeout = vortex_tx_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+
         /* Use the now-standard shared IRQ implementation. */
         if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ, dev->name, dev)) {
                 return -EAGAIN;
@@ -1345,7 +1353,7 @@
                 printk(KERN_ERR "%s: Interrupt posted but not delivered --"
                            " IRQ blocked by another device?\n", dev->name);
                 /* Bad idea here.. but we might as well handle a few events. */
- vortex_interrupt(dev->irq, dev, 0);
+/* vortex_interrupt(dev->irq, dev, 0);*/
         }
 
 #if ! defined(final_version)
@@ -1377,7 +1385,7 @@
                                  ioaddr + DownListPtr);
                 if (vp->tx_full && (vp->cur_tx - vp->dirty_tx <= TX_RING_SIZE - 1)) {
                         vp->tx_full = 0;
- clear_bit(0, (void*)&dev->tbusy);
+ netif_wake_queue(dev);
                 }
                 outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
                 outw(DownUnstall, ioaddr + EL3_CMD);
@@ -1387,7 +1395,7 @@
         /* Issue Tx Enable */
         outw(TxEnable, ioaddr + EL3_CMD);
         dev->trans_start = jiffies;
-
+
         /* Switch to register set 7 for normal use. */
         EL3WINDOW(7);
 }
@@ -1478,12 +1486,6 @@
         struct vortex_private *vp = (struct vortex_private *)dev->priv;
         long ioaddr = dev->base_addr;
 
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- if (jiffies - dev->trans_start >= TX_TIMEOUT)
- vortex_tx_timeout(dev);
- return 1;
- }
-
         /* Put out the doubleword header... */
         outl(skb->len, ioaddr + TX_FIFO);
         if (vp->bus_master) {
@@ -1498,7 +1500,7 @@
                 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
                 DEV_FREE_SKB(skb);
                 if (inw(ioaddr + TxFree) > 1536) {
- clear_bit(0, (void*)&dev->tbusy);
+ netif_start_queue(dev);
                 } else
                         /* Interrupt us when the FIFO has room for max-sized packet. */
                         outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
@@ -1535,11 +1537,8 @@
         struct vortex_private *vp = (struct vortex_private *)dev->priv;
         long ioaddr = dev->base_addr;
 
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- if (jiffies - dev->trans_start >= TX_TIMEOUT)
- vortex_tx_timeout(dev);
- return 1;
- } else {
+ netif_stop_queue(dev);
+ {
                 /* Calculate the next Tx descriptor entry. */
                 int entry = vp->cur_tx % TX_RING_SIZE;
                 struct boom_tx_desc *prev_entry =
@@ -1580,7 +1579,7 @@
 #if defined(tx_interrupt_mitigation)
                         prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
 #endif
- clear_bit(0, (void*)&dev->tbusy);
+ netif_start_queue(dev);
                 }
                 dev->trans_start = jiffies;
                 return 0;
@@ -1597,23 +1596,6 @@
         int latency, status;
         int work_done = 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
-
- dev->interrupt = 1;
         ioaddr = dev->base_addr;
         latency = inb(ioaddr + Timer);
         status = inw(ioaddr + EL3_STATUS);
@@ -1643,8 +1625,7 @@
                                 printk(KERN_DEBUG " TX room bit was handled.\n");
                         /* There's room in the FIFO for a full-sized packet. */
                         outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
- clear_bit(0, (void*)&dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
                 }
 
                 if (status & DownComplete) {
@@ -1657,7 +1638,7 @@
                                         virt_to_bus(&vp->tx_ring[entry]))
                                         break; /* It still hasn't been processed. */
                                 if (vp->tx_skbuff[entry]) {
- DEV_FREE_SKB(vp->tx_skbuff[entry]);
+ dev_kfree_skb_irq(vp->tx_skbuff[entry]);
                                         vp->tx_skbuff[entry] = 0;
                                 }
                                 /* vp->stats.tx_packets++; Counted below. */
@@ -1666,17 +1647,15 @@
                         vp->dirty_tx = dirty_tx;
                         if (vp->tx_full && (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
                                 vp->tx_full = 0;
- clear_bit(0, (void*)&dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
                         }
                 }
                 if (status & DMADone) {
                         if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
                                 outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
- DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
+ dev_kfree_skb_irq(vp->tx_skb); /* Release the transfered buffer */
                                 if (inw(ioaddr + TxFree) > 1536) {
- clear_bit(0, (void*)&dev->tbusy);
- mark_bh(NET_BH);
+ netif_wake_queue(dev);
                                 } else /* Interrupt when FIFO has room for max-sized packet. */
                                         outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
                         }
@@ -1715,11 +1694,6 @@
                 printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
                            dev->name, status);
 handler_exit:
-#if defined(__i386__)
- clear_bit(0, (void*)&dev->interrupt);
-#else
- dev->interrupt = 0;
-#endif
         return;
 }
 
@@ -1891,8 +1865,7 @@
         struct vortex_private *vp = (struct vortex_private *)dev->priv;
         long ioaddr = dev->base_addr;
 
- dev->start = 0;
- dev->tbusy = 1;
+ netif_stop_queue(dev);
 
         del_timer(&vp->timer);
 
@@ -1926,7 +1899,7 @@
         long ioaddr = dev->base_addr;
         int i;
 
- if (dev->start)
+ if(test_bit(LINK_STATE_START, &dev->state))
                 vortex_down(dev);
 
         if (vortex_debug > 1) {
@@ -1964,7 +1937,7 @@
         struct vortex_private *vp = (struct vortex_private *)dev->priv;
         unsigned long flags;
 
- if (dev->start) {
+ if(test_bit(LINK_STATE_START, &dev->state)) {
                 save_flags(flags);
                 cli();
                 update_stats(dev->base_addr, dev);

-- 
................................................................
: jakob@ostenfeld.dtu.dk  : And I see the elder races,         :
:.........................: putrid forms of man                :
:   Jakob Østergaard      : See him rise and claim the earth,  :
:        OZ9ABN           : his downfall is at hand.           :
:.........................:............{Konkhra}...............:

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Feb 15 2000 - 21:00:25 EST