summaryrefslogtreecommitdiffstats
path: root/drivers/net/wan
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-02 02:36:47 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-02 02:36:47 +0000
commit8624512aa908741ba2795200133eae0d7f4557ea (patch)
treed5d3036fccf2604f4c98dedc11e8adb929d6b52e /drivers/net/wan
parent7b8f5d6f1d45d9f9de1d26e7d3c32aa5af11b488 (diff)
Merge with 2.3.48.
Diffstat (limited to 'drivers/net/wan')
-rw-r--r--drivers/net/wan/cosa.c70
-rw-r--r--drivers/net/wan/syncppp.c17
2 files changed, 48 insertions, 39 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;
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 6113365c1..e039bbc28 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -50,6 +50,7 @@
#include <linux/random.h>
#include <linux/pkt_sched.h>
#include <asm/byteorder.h>
+#include <linux/spinlock.h>
#include "syncppp.h"
#define MAXALIVECNT 6 /* max. alive packets */
@@ -126,6 +127,7 @@ struct cisco_packet {
static struct sppp *spppq;
static struct timer_list sppp_keepalive_timer;
+static spinlock_t spppq_lock;
static void sppp_keepalive (unsigned long dummy);
static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
@@ -359,8 +361,8 @@ static void sppp_keepalive (unsigned long dummy)
{
struct sppp *sp;
unsigned long flags;
- save_flags(flags);
- cli();
+
+ spin_lock_irqsave(&spppq_lock, flags);
for (sp=spppq; sp; sp=sp->pp_next)
{
@@ -402,7 +404,7 @@ static void sppp_keepalive (unsigned long dummy)
sp->lcp.echoid, 4, &nmagic);
}
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&spppq_lock, flags);
sppp_keepalive_timer.expires=jiffies+10*HZ;
add_timer(&sppp_keepalive_timer);
}
@@ -915,7 +917,9 @@ void sppp_attach(struct ppp_device *pd)
{
struct net_device *dev = pd->dev;
struct sppp *sp = &pd->sppp;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&spppq_lock, flags);
/* Initialize keepalive handler. */
if (! spppq)
{
@@ -927,6 +931,7 @@ void sppp_attach(struct ppp_device *pd)
/* Insert new entry into the keepalive list. */
sp->pp_next = spppq;
spppq = sp;
+ spin_unlock_irqrestore(&spppq_lock, flags);
sp->pp_loopcnt = 0;
sp->pp_alivecnt = 0;
@@ -971,7 +976,9 @@ EXPORT_SYMBOL(sppp_attach);
void sppp_detach (struct net_device *dev)
{
struct sppp **q, *p, *sp = (struct sppp *)sppp_of(dev);
+ unsigned long flags;
+ spin_lock_irqsave(&spppq_lock, flags);
/* Remove the entry from the keepalive list. */
for (q = &spppq; (p = *q); q = &p->pp_next)
if (p == sp) {
@@ -983,6 +990,7 @@ void sppp_detach (struct net_device *dev)
if (! spppq)
del_timer(&sppp_keepalive_timer);
sppp_clear_timeout (sp);
+ spin_unlock_irqrestore(&spppq_lock, flags);
}
EXPORT_SYMBOL(sppp_detach);
@@ -1292,6 +1300,7 @@ void sync_ppp_init(void)
{
printk(KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n");
printk(KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & Jan \"Yenya\" Kasprzak.\n");
+ spin_lock_init(&spppq_lock);
sppp_packet_type.type=htons(ETH_P_WAN_PPP);
dev_add_pack(&sppp_packet_type);
}