patch-2.3.49 linux/drivers/net/arlan.c
Next file: linux/drivers/net/bonding.c
Previous file: linux/drivers/net/am79c961a.c
Back to the patch index
Back to the overall index
- Lines: 353
- Date:
Mon Feb 28 07:16:54 2000
- Orig file:
v2.3.48/linux/drivers/net/arlan.c
- Orig date:
Mon Dec 20 18:48:21 1999
diff -u --recursive --new-file v2.3.48/linux/drivers/net/arlan.c linux/drivers/net/arlan.c
@@ -102,6 +102,7 @@
static void arlan_tx_done_interrupt (struct net_device * dev, int status);
static void arlan_rx_interrupt (struct net_device * dev, u_char rxStatus, u_short, u_short);
static void arlan_process_interrupt (struct net_device * dev);
+static void arlan_tx_timeout (struct net_device *dev);
int arlan_command(struct net_device * dev, int command);
EXPORT_SYMBOL(arlan_command);
@@ -182,10 +183,7 @@
priv->txOffset = 0;
priv->bad = 0;
if (!priv->under_reset && !priv->under_config)
- {
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
+ netif_wake_queue (dev);
}
return 1;
};
@@ -288,15 +286,9 @@
}
}
if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
- {
priv->under_reset = 1;
- dev->start = 0;
- }
if (priv->waiting_command_mask & ARLAN_COMMAND_CONF)
- {
priv->under_config = 1;
- dev->start = 0;
- }
/* Issuing command */
arlan_lock_card_access(dev);
@@ -341,14 +333,14 @@
else if (priv->waiting_command_mask & ARLAN_COMMAND_RESET)
{
priv->under_reset=1;
- dev->tbusy = 1;
+ netif_stop_queue (dev);
arlan_drop_tx(dev);
if (priv->tx_command_given || priv->rx_command_given)
{
printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
};
- dev->tbusy = 1;
+ netif_stop_queue (dev);
if (arlan_debug & ARLAN_DEBUG_RESET)
printk(KERN_ERR "%s: Doing chip reset\n", dev->name);
priv->lastReset = jiffies;
@@ -388,7 +380,6 @@
{
printk(KERN_ERR "%s: Reset under tx or rx command \n", dev->name);
}
- dev->start = 0;
arlan_drop_tx(dev);
setInterruptEnable(dev);
arlan_hw_config(dev);
@@ -437,13 +428,11 @@
}
else if (priv->waiting_command_mask & ARLAN_COMMAND_TBUSY_CLEAR)
{
- if ( !registrationBad(dev) && (dev->tbusy || !dev->start) )
+ if ( !registrationBad(dev) &&
+ (netif_queue_stopped(dev) || !netif_running(dev)) )
{
priv->waiting_command_mask &= ~ARLAN_COMMAND_TBUSY_CLEAR;
-
- dev->tbusy = 0;
- dev->start = 1;
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
};
}
else if (priv->waiting_command_mask & ARLAN_COMMAND_TX)
@@ -587,8 +576,7 @@
else
IFDEBUG(ARLAN_DEBUG_TX_CHAIN) printk(KERN_ERR "ReTransmit buff empty");
priv->txOffset = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
return;
}
@@ -650,11 +638,8 @@
priv->registrationLastSeen = jiffies;
priv->registrationLostCount = 0;
priv->reRegisterExp = 1;
- if (dev->start == 0)
- {
- dev->start = 1;
- mark_bh(NET_BH);
- }
+ if (!netif_running(dev))
+ netif_wake_queue(dev);
}
@@ -682,8 +667,7 @@
if (!(TXHEAD(dev).offset && TXTAIL(dev).offset))
{
priv->txOffset = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
}
priv->tx_done_delayed = 0;
bh_mark_needed = 1;
@@ -691,8 +675,7 @@
if (bh_mark_needed)
{
priv->txOffset = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
}
arlan_process_interrupt(dev);
@@ -788,7 +771,7 @@
}
else
{
- dev->tbusy = 1;
+ netif_stop_queue (dev);
return -1;
IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds);
@@ -811,11 +794,11 @@
}
if (TXHEAD(dev).offset && TXTAIL(dev).offset)
{
- dev->tbusy = 1;
+ netif_stop_queue (dev);
return 0;
}
else
- dev->tbusy = 0;
+ netif_start_queue (dev);
IFDEBUG(ARLAN_DEBUG_HEADER_DUMP)
@@ -1161,7 +1144,7 @@
ARLAN_DEBUG_ENTRY("arlan_mac_addr");
return -EINVAL;
- if (dev->start)
+ if (!netif_running(dev))
return -EBUSY;
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
@@ -1223,8 +1206,8 @@
dev->set_multicast_list = arlan_set_multicast;
dev->change_mtu = arlan_change_mtu;
dev->set_mac_address = arlan_mac_addr;
- dev->tbusy = 1;
- dev->start = 0;
+ dev->tx_timeout = arlan_tx_timeout;
+ dev->watchdog_timeo = 3*HZ;
((struct arlan_private *) dev->priv)->irq_test_done = 0;
arlan_device[num] = dev;
@@ -1302,14 +1285,13 @@
priv->open_time = jiffies;
memcpy_fromio(dev->dev_addr, arlan->lanCardNodeId, 6);
memset(dev->broadcast, 0xff, 6);
- dev->tbusy = 1;
priv->txOffset = 0;
- dev->interrupt = 0;
- dev->start = 0;
dev->tx_queue_len = tx_queue_len;
priv->interrupt_processing_active = 0;
priv->command_lock = 0;
+ netif_start_queue (dev);
+
init_MUTEX(&priv->card_lock);
myATOMIC_INIT(priv->card_users, 1); /* damn 2.0.33 */
priv->registrationLostCount = 0;
@@ -1327,7 +1309,6 @@
priv->Conf->writeEEPROM = 0;
priv->Conf->registrationInterrupts = 1;
- dev->tbusy = 0;
init_timer(&priv->timer);
priv->timer.expires = jiffies + HZ / 10;
priv->timer.data = (unsigned long) dev;
@@ -1335,8 +1316,6 @@
arlan_command(dev, ARLAN_COMMAND_POWERUP | ARLAN_COMMAND_LONG_WAIT_NOW);
udelay(200000);
- dev->tbusy = 0;
- dev->start = 1;
add_timer(&priv->timer);
MOD_INC_USE_COUNT;
@@ -1351,69 +1330,43 @@
}
+static void arlan_tx_timeout (struct net_device *dev)
+{
+ printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name);
+ /* Try to restart the adaptor. */
+ arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
+ dev->trans_start = jiffies;
+ netif_start_queue (dev);
+}
static int arlan_tx(struct sk_buff *skb, struct net_device *dev)
{
struct arlan_private *priv = ((struct arlan_private *) dev->priv);
- struct arlan_conf_stru *conf = ((struct arlan_private *) dev->priv)->Conf;
+ short length;
+ unsigned char *buf;
ARLAN_DEBUG_ENTRY("arlan_tx");
-
- if (dev->tbusy)
- {
- /*
- * If we get here, some higher level has decided we are broken.
- * There should really be a "kick me" function call instead.
- */
- int tickssofar = jiffies - dev->trans_start;
-
- if (((tickssofar * 1000) / HZ) * 2 > conf->txTimeoutMs)
- arlan_command(dev, ARLAN_COMMAND_TX_ABORT);
-
- if (((tickssofar * 1000) / HZ) < conf->txTimeoutMs)
- {
- // up(&priv->card_lock);
- goto bad_end;
- }
- printk(KERN_ERR "%s: arlan transmit timed out, kernel decided\n", dev->name);
- /* Try to restart the adaptor. */
- arlan_command(dev, ARLAN_COMMAND_CLEAN_AND_RESET);
- dev->trans_start = jiffies;
- goto bad_end;
-
- }
+
/*
- * 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 some higher layer thinks we've missed an tx-done interrupt
+ * we are passed NULL. Caution: dev_tint() handles the cli()/sti()
+ * itself.
*/
- if (test_and_set_bit(0, (void *) &dev->tbusy) != 0)
- {
- printk(KERN_ERR "%s: Transmitter access conflict.\n",
- dev->name);
+
+ length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+ buf = skb->data;
+
+ if (priv->txOffset + length + 0x12 > 0x800) {
+ printk(KERN_ERR "TX RING overflow \n");
+ netif_stop_queue (dev);
}
- else
- {
- short length;
- unsigned char *buf;
-
- /*
- * If some higher layer thinks we've missed an tx-done interrupt
- * we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- * itself.
- */
-
- length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- buf = skb->data;
- if (priv->txOffset + length + 0x12 > 0x800)
- printk(KERN_ERR "TX RING overflow \n");
+ if (arlan_hw_tx(dev, buf, length) == -1)
+ goto bad_end;
- if (arlan_hw_tx(dev, buf, length) == -1)
- goto bad_end;
+ dev->trans_start = jiffies;
- dev->trans_start = jiffies;
- }
dev_kfree_skb(skb);
arlan_process_interrupt(dev);
@@ -1424,6 +1377,7 @@
bad_end:
arlan_process_interrupt(dev);
priv->tx_chain_active = 0;
+ netif_stop_queue (dev);
ARLAN_DEBUG_EXIT("arlan_tx");
return 1;
}
@@ -1522,8 +1476,7 @@
if (!TXHEAD(dev).offset || !TXTAIL(dev).offset)
{
priv->txOffset = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue (dev);
}
}
}
@@ -1852,15 +1805,12 @@
WRITESHMB(arlan->rxStatus, 0x00);
arlan_command(dev, ARLAN_COMMAND_RX);
if (registrationBad(dev))
- dev->start = 0;
+ netif_device_detach(dev);
if (!registrationBad(dev))
{
priv->registrationLastSeen = jiffies;
- if (!dev->tbusy && !priv->under_reset && !priv->under_config)
- {
- mark_bh(NET_BH);
- dev->start = 1;
- }
+ if (!netif_queue_stopped(dev) && !priv->under_reset && !priv->under_config)
+ netif_wake_queue (dev);
}
goto ends;
}
@@ -1900,12 +1850,10 @@
if (!rxStatus && !txStatus)
priv->interrupt_ack_requested++;
- dev->interrupt++;
arlan_process_interrupt(dev);
priv->irq_test_done = 1;
- dev->interrupt--;
ARLAN_DEBUG_EXIT("arlan_interrupt");
return;
@@ -1938,8 +1886,7 @@
printk(KERN_NOTICE "%s: Closing device\n", dev->name);
priv->open_time = 0;
- dev->tbusy = 1;
- dev->start = 0;
+ netif_stop_queue(dev);
free_irq(dev->irq, dev);
MOD_DEC_USE_COUNT;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)