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
- Lines: 249
- Date:
Sun Feb 13 10:23:26 2000
- Orig file:
v2.3.44/linux/drivers/net/pcmcia/nmclan_cs.c
- Orig date:
Fri Jan 21 18:19:16 2000
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)