summaryrefslogtreecommitdiffstats
path: root/drivers/net/wan/cosa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wan/cosa.c')
-rw-r--r--drivers/net/wan/cosa.c70
1 files changed, 35 insertions, 35 deletions
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 873a561ef..72aeae112 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -1,4 +1,4 @@
-/* $Id: cosa.c,v 1.28 1999/10/11 21:06:58 kas Exp $ */
+/* $Id: cosa.c,v 1.30 2000/02/21 15:19:49 kas Exp $ */
/*
* Copyright (C) 1995-1997 Jan "Yenya" Kasprzak <kas@fi.muni.cz>
@@ -222,6 +222,8 @@ static int cosa_major = 117;
#undef DEBUG_IRQS 1 /* Print the message when the IRQ is received */
#undef DEBUG_IO 1 /* Dump the I/O traffic */
+#define TX_TIMEOUT (5*HZ)
+
/* Maybe the following should be allocated dynamically */
static struct cosa_data cosa_cards[MAX_CARDS];
static int nr_cards = 0;
@@ -286,6 +288,7 @@ static void sppp_channel_init(struct channel_data *chan);
static void sppp_channel_delete(struct channel_data *chan);
static int cosa_sppp_open(struct net_device *d);
static int cosa_sppp_close(struct net_device *d);
+static void cosa_sppp_timeout(struct net_device *d);
static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *d);
static char *sppp_setup_rx(struct channel_data *channel, int size);
static int sppp_rx_done(struct channel_data *channel);
@@ -370,7 +373,7 @@ static int __init cosa_init(void)
{
int i;
- printk(KERN_INFO "cosa v1.06 (c) 1997-8 Jan Kasprzak <kas@fi.muni.cz>\n");
+ printk(KERN_INFO "cosa v1.07 (c) 1997-2000 Jan Kasprzak <kas@fi.muni.cz>\n");
#ifdef __SMP__
printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n");
#endif
@@ -406,7 +409,6 @@ static int __init cosa_init(void)
#ifdef MODULE
void cleanup_module (void)
{
- int i;
struct cosa_data *cosa;
printk(KERN_INFO "Unloading the cosa module\n");
@@ -595,6 +597,8 @@ static void sppp_channel_init(struct channel_data *chan)
d->hard_start_xmit = cosa_sppp_tx;
d->do_ioctl = cosa_sppp_ioctl;
d->get_stats = cosa_net_stats;
+ d->tx_timeout = cosa_sppp_timeout;
+ d->watchdog_timeo = TX_TIMEOUT;
dev_init_buffers(d);
if (register_netdev(d) == -1) {
printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
@@ -609,7 +613,6 @@ static void sppp_channel_delete(struct channel_data *chan)
unregister_netdev(chan->pppdev.dev);
}
-
static int cosa_sppp_open(struct net_device *d)
{
struct channel_data *chan = d->priv;
@@ -646,7 +649,7 @@ static int cosa_sppp_open(struct net_device *d)
return err;
}
- d->tbusy = 0;
+ netif_start_queue(d);
cosa_enable_rx(chan);
return 0;
}
@@ -655,41 +658,39 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
{
struct channel_data *chan = dev->priv;
- if (dev->tbusy) {
- if (time_before(jiffies, dev->trans_start+2*HZ))
- return 1; /* Two seconds timeout */
- if (test_bit(RXBIT, &chan->cosa->rxtx)) {
- chan->stats.rx_errors++;
- chan->stats.rx_missed_errors++;
- } else {
- chan->stats.tx_errors++;
- chan->stats.tx_aborted_errors++;
- }
- cosa_kick(chan->cosa);
- if (chan->tx_skb) {
- dev_kfree_skb(chan->tx_skb);
- chan->tx_skb = 0;
- }
- dev->tbusy = 0;
- }
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
- return 1;
- }
-
+ netif_stop_queue(dev);
+
chan->tx_skb = skb;
- dev->trans_start = jiffies;
cosa_start_tx(chan, skb->data, skb->len);
return 0;
}
+static void cosa_sppp_timeout(struct net_device *dev)
+{
+ struct channel_data *chan = dev->priv;
+
+ if (test_bit(RXBIT, &chan->cosa->rxtx)) {
+ chan->stats.rx_errors++;
+ chan->stats.rx_missed_errors++;
+ } else {
+ chan->stats.tx_errors++;
+ chan->stats.tx_aborted_errors++;
+ }
+ cosa_kick(chan->cosa);
+ if (chan->tx_skb) {
+ dev_kfree_skb(chan->tx_skb);
+ chan->tx_skb = 0;
+ }
+ netif_wake_queue(dev);
+}
+
static int cosa_sppp_close(struct net_device *d)
{
struct channel_data *chan = d->priv;
int flags;
+ netif_stop_queue(d);
sppp_close(d);
- d->tbusy = 1;
cosa_disable_rx(chan);
spin_lock_irqsave(&chan->cosa->lock, flags);
if (chan->rx_skb) {
@@ -760,8 +761,7 @@ static int sppp_tx_done(struct channel_data *chan, int size)
chan->tx_skb = 0;
chan->stats.tx_packets++;
chan->stats.tx_bytes += size;
- chan->pppdev.dev->tbusy = 0;
- mark_bh(NET_BH);
+ netif_wake_queue(chan->pppdev.dev);
return 1;
}
@@ -1350,14 +1350,14 @@ static void put_driver_status_nolock(struct cosa_data *cosa)
static void cosa_kick(struct cosa_data *cosa)
{
unsigned flags, flags1;
- char *s = "Unknown";
+ char *s = "(probably) IRQ";
if (test_bit(RXBIT, &cosa->rxtx))
- s = "RX";
+ s = "RX DMA";
if (test_bit(TXBIT, &cosa->rxtx))
- s = "TX";
+ s = "TX DMA";
- printk(KERN_INFO "%s: %s DMA timeout - restarting.\n", cosa->name, s);
+ printk(KERN_INFO "%s: %s timeout - restarting.\n", cosa->name, s);
spin_lock_irqsave(&cosa->lock, flags);
cosa->rxtx = 0;