patch-2.3.45 linux/drivers/net/pcmcia/nmclan_cs.c

Next file: linux/drivers/net/pcmcia/smc91c92_cs.c
Previous file: linux/drivers/net/pcmcia/netwave_cs.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.44/linux/drivers/net/pcmcia/nmclan_cs.c linux/drivers/net/pcmcia/nmclan_cs.c
@@ -307,6 +307,10 @@
 #undef MACE_IMR_DEFAULT
 #define MACE_IMR_DEFAULT 0x00 /* New statistics handling: grab everything */
 
+#define TX_TIMEOUT (5*HZ)
+
+
+
 /* ----------------------------------------------------------------------------
 Type Definitions
 ---------------------------------------------------------------------------- */
@@ -360,6 +364,7 @@
     dev_link_t link;
     struct net_device dev;
     dev_node_t node;
+    spinlock_t lock;
     struct net_device_stats linux_stats; /* Linux statistics counters */
     mace_statistics mace_stats; /* MACE chip statistics counters */
 
@@ -432,6 +437,7 @@
 static struct net_device_stats *mace_get_stats(struct net_device *dev);
 static int mace_rx(struct net_device *dev, unsigned char RxCnt);
 static void restore_multicast_list(struct net_device *dev);
+static void mace_tx_timeout (struct net_device *dev);
 
 static void set_multicast_list(struct net_device *dev);
 
@@ -498,6 +504,8 @@
     lp = kmalloc(sizeof(*lp), GFP_KERNEL);
     if (!lp) return NULL;
     memset(lp, 0, sizeof(*lp));
+    
+    lp->lock = SPIN_LOCK_UNLOCKED;
     link = &lp->link; dev = &lp->dev;
     link->priv = dev->priv = link->irq.Instance = lp;
 
@@ -531,7 +539,10 @@
     dev->init = &nmclan_init;
     dev->open = &mace_open;
     dev->stop = &mace_close;
-    dev->tbusy = 0xFF;
+    dev->tx_timeout = mace_tx_timeout;
+    dev->watchdog_timeo = TX_TIMEOUT;
+
+    netif_start_queue (dev);
 
     /* Register with Card Services */
     link->next = dev_list;
@@ -752,7 +763,7 @@
   CS_CHECK(RequestConfiguration, handle, &link->conf);
   dev->irq = link->irq.AssignedIRQ;
   dev->base_addr = link->io.BasePort1;
-  dev->tbusy = 0;
+  netif_start_queue (dev);
   i = register_netdev(dev);
   if (i != 0) {
     printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n");
@@ -859,7 +870,7 @@
     case CS_EVENT_CARD_REMOVAL:
       link->state &= ~DEV_PRESENT;
       if (link->state & DEV_CONFIG) {
-	dev->tbusy = 0xFF; dev->start = 0;
+	netif_stop_queue (dev);
 	link->release.expires = jiffies + HZ/20;
 	add_timer(&link->release);
       }
@@ -874,7 +885,7 @@
     case CS_EVENT_RESET_PHYSICAL:
       if (link->state & DEV_CONFIG) {
 	if (link->open) {
-	  dev->tbusy = 0xFF; dev->start = 0;
+	  netif_stop_queue (dev);
 	}
 	CardServices(ReleaseConfiguration, link->handle);
       }
@@ -886,9 +897,8 @@
       if (link->state & DEV_CONFIG) {
 	CardServices(RequestConfiguration, link->handle, &link->conf);
 	if (link->open) {
-	  dev->tbusy = 0;
-	  dev->start = 1;
 	  nmclan_reset(dev);
+	  netif_start_queue (dev);
 	}
       }
       break;
@@ -987,10 +997,7 @@
 
   MACEBANK(0);
 
-  dev->interrupt = 0;
-  dev->tbusy = 0;
-  dev->start = 1;
-
+  netif_start_queue (dev);
   nmclan_reset(dev);
 
   return 0; /* Always succeed */
@@ -1007,12 +1014,13 @@
   dev_link_t *link = &lp->link;
 
   DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+  
+  netif_stop_queue (dev);
 
   /* Mask off all interrupts from the MACE chip. */
   outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
 
   link->open--;
-  dev->start = 0;
   if (link->state & DEV_STALE_CONFIG) {
     link->release.expires = jiffies + HZ/20;
     link->state |= DEV_RELEASE_PENDING;
@@ -1024,6 +1032,24 @@
   return 0;
 } /* mace_close */
 
+
+static void mace_tx_timeout (struct net_device *dev)
+{
+	mace_private *lp = (mace_private *)dev->priv;
+	dev_link_t *link = &lp->link;
+
+	printk (KERN_NOTICE "%s: transmit timed out -- ", dev->name);
+#if RESET_ON_TIMEOUT
+	printk ("resetting card\n");
+	CardServices (ResetCard, link->handle);
+#else				/* #if RESET_ON_TIMEOUT */
+	printk ("NOT resetting card\n");
+#endif				/* #if RESET_ON_TIMEOUT */
+	dev->trans_start = jiffies;
+	netif_start_queue (dev);
+}
+
+
 /* ----------------------------------------------------------------------------
 mace_start_xmit
 	This routine begins the packet transmit function.  When completed,
@@ -1038,39 +1064,11 @@
 {
   mace_private *lp = (mace_private *)dev->priv;
   ioaddr_t ioaddr = dev->base_addr;
-  dev_link_t *link = &lp->link;
-
-#if TIMEOUT_TX
-  /* Transmitter timeout. */
-  if (dev->tbusy) {
-    int tickssofar = jiffies - dev->trans_start;
-
-    if (tickssofar < (HZ/5))
-      return 1;
-    printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name);
-#if RESET_ON_TIMEOUT
-    printk("resetting card\n");
-    CardServices(ResetCard, link->handle);
-#else /* #if RESET_ON_TIMEOUT */
-    printk("NOT resetting card\n");
-#endif /* #if RESET_ON_TIMEOUT */
-    dev->trans_start = jiffies;
-    return 1;
-  }
-#else /* #if TIMEOUT_TX */
-  if (dev->tbusy)
-    return 1;
-#endif /* #if TIMEOUT_TX */
 
   DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
 	dev->name, (long)skb->len);
 
-  /* Avoid timer-based retransmission conflicts. */
-  if (test_and_set_bit(TBUSY_UNSPECIFIED, (void*)&dev->tbusy) != 0) {
-    printk(KERN_NOTICE "%s: transmitter access conflict.\n",
-	   dev->name);
-    return 1;
-  }
+  netif_stop_queue (dev);
 
 #if (!TX_INTERRUPTABLE)
   /* Disable MACE TX interrupts. */
@@ -1085,11 +1083,9 @@
        the upper layers.  The interrupt handler is guaranteed never to
        service a transmit interrupt while we are in here.
     */
-    set_bit(TBUSY_PARTIAL_TX_FRAME, (void*)&dev->tbusy);
 
     lp->linux_stats.tx_bytes += skb->len;
     lp->tx_free_frames--;
-    set_bit(TBUSY_NO_FREE_TX_FRAMES, (void*)&dev->tbusy);
 
     /* WARNING: Write the _exact_ number of bytes written in the header! */
     /* Put out the word header [must be an outw()] . . . */
@@ -1105,11 +1101,10 @@
 
     if (lp->tx_free_frames > 0) {
 #if MULTI_TX
-      clear_bit(TBUSY_NO_FREE_TX_FRAMES, (void*)&dev->tbusy);
+      netif_start_queue (dev);
 #endif /* #if MULTI_TX */
     }
 
-    clear_bit(TBUSY_PARTIAL_TX_FRAME, (void*)&dev->tbusy);
   }
 
 #if (!TX_INTERRUPTABLE)
@@ -1140,8 +1135,10 @@
 	  irq);
     return;
   }
+  
+  spin_lock (&lp->lock);
 
-  if (dev->interrupt || lp->tx_irq_disabled) {
+  if (lp->tx_irq_disabled) {
     printk(
       (lp->tx_irq_disabled?
        KERN_NOTICE "%s: Interrupt with tx_irq_disabled "
@@ -1155,12 +1152,6 @@
     /* WARNING: MACE_IR has been read! */
     return;
   }
-  dev->interrupt = 1;
-
-  if (dev->start == 0) {
-    DEBUG(2, "%s: interrupt from dead card\n", dev->name);
-    goto exception;
-  }
 
   do {
     /* WARNING: MACE_IR is a READ/CLEAR port! */
@@ -1230,8 +1221,7 @@
 
       lp->linux_stats.tx_packets++;
       lp->tx_free_frames++;
-      clear_bit(TBUSY_NO_FREE_TX_FRAMES, (void*)&dev->tbusy);
-      mark_bh(NET_BH);
+      netif_wake_queue (dev);
     } /* if (status & MACE_IR_XMTINT) */
 
     if (status & ~MACE_IMR_DEFAULT & ~MACE_IR_RCVINT & ~MACE_IR_XMTINT) {
@@ -1266,8 +1256,7 @@
   } while ((status & ~MACE_IMR_DEFAULT) && (--IntrCnt));
 
 exception:
-  dev->interrupt = 0;
-  return;
+  spin_unlock (&lp->lock);
 } /* mace_interrupt */
 
 /* ----------------------------------------------------------------------------

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