aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wan
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wan')
-rw-r--r--drivers/net/wan/Kconfig4
-rw-r--r--drivers/net/wan/cosa.c14
-rw-r--r--drivers/net/wan/hdlc.c19
-rw-r--r--drivers/net/wan/hdlc_cisco.c82
-rw-r--r--drivers/net/wan/hdlc_ppp.c2
-rw-r--r--drivers/net/wan/hostess_sv11.c12
-rw-r--r--drivers/net/wan/lmc/lmc_main.c1
-rw-r--r--drivers/net/wan/sealevel.c1
8 files changed, 77 insertions, 58 deletions
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 8005dd16fb4..d5140aed7b7 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -150,11 +150,9 @@ config HDLC_FR
config HDLC_PPP
tristate "Synchronous Point-to-Point Protocol (PPP) support"
- depends on HDLC && BROKEN
+ depends on HDLC
help
Generic HDLC driver supporting PPP over WAN connections.
- This module is currently broken and will cause a kernel panic
- when a device configured in PPP mode is activated.
It will be replaced by new PPP implementation in Linux 2.6.26.
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 45ddfc9763c..b0fce1387ea 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -629,7 +629,7 @@ static void sppp_channel_init(struct channel_data *chan)
d->base_addr = chan->cosa->datareg;
d->irq = chan->cosa->irq;
d->dma = chan->cosa->dma;
- d->priv = chan;
+ d->ml_priv = chan;
sppp_attach(&chan->pppdev);
if (register_netdev(d)) {
printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
@@ -650,7 +650,7 @@ static void sppp_channel_delete(struct channel_data *chan)
static int cosa_sppp_open(struct net_device *d)
{
- struct channel_data *chan = d->priv;
+ struct channel_data *chan = d->ml_priv;
int err;
unsigned long flags;
@@ -690,7 +690,7 @@ static int cosa_sppp_open(struct net_device *d)
static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
{
- struct channel_data *chan = dev->priv;
+ struct channel_data *chan = dev->ml_priv;
netif_stop_queue(dev);
@@ -701,7 +701,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
static void cosa_sppp_timeout(struct net_device *dev)
{
- struct channel_data *chan = dev->priv;
+ struct channel_data *chan = dev->ml_priv;
if (test_bit(RXBIT, &chan->cosa->rxtx)) {
chan->stats.rx_errors++;
@@ -720,7 +720,7 @@ static void cosa_sppp_timeout(struct net_device *dev)
static int cosa_sppp_close(struct net_device *d)
{
- struct channel_data *chan = d->priv;
+ struct channel_data *chan = d->ml_priv;
unsigned long flags;
netif_stop_queue(d);
@@ -800,7 +800,7 @@ static int sppp_tx_done(struct channel_data *chan, int size)
static struct net_device_stats *cosa_net_stats(struct net_device *dev)
{
- struct channel_data *chan = dev->priv;
+ struct channel_data *chan = dev->ml_priv;
return &chan->stats;
}
@@ -1217,7 +1217,7 @@ static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr,
int cmd)
{
int rv;
- struct channel_data *chan = dev->priv;
+ struct channel_data *chan = dev->ml_priv;
rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data);
if (rv == -ENOIOCTLCMD) {
return sppp_do_ioctl(dev, ifr, cmd);
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index 9a83c9d5b8c..7f984895b0d 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -43,8 +43,7 @@ static const char* version = "HDLC support module revision 1.22";
#undef DEBUG_LINK
-static struct hdlc_proto *first_proto = NULL;
-
+static struct hdlc_proto *first_proto;
static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
{
@@ -314,21 +313,25 @@ void detach_hdlc_protocol(struct net_device *dev)
void register_hdlc_protocol(struct hdlc_proto *proto)
{
+ rtnl_lock();
proto->next = first_proto;
first_proto = proto;
+ rtnl_unlock();
}
void unregister_hdlc_protocol(struct hdlc_proto *proto)
{
- struct hdlc_proto **p = &first_proto;
- while (*p) {
- if (*p == proto) {
- *p = proto->next;
- return;
- }
+ struct hdlc_proto **p;
+
+ rtnl_lock();
+ p = &first_proto;
+ while (*p != proto) {
+ BUG_ON(!*p);
p = &((*p)->next);
}
+ *p = proto->next;
+ rtnl_unlock();
}
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 7133c688cf2..762d21c1c70 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -56,6 +56,7 @@ struct cisco_state {
cisco_proto settings;
struct timer_list timer;
+ spinlock_t lock;
unsigned long last_poll;
int up;
int request_sent;
@@ -158,6 +159,7 @@ static int cisco_rx(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
hdlc_device *hdlc = dev_to_hdlc(dev);
+ struct cisco_state *st = state(hdlc);
struct hdlc_header *data = (struct hdlc_header*)skb->data;
struct cisco_packet *cisco_data;
struct in_device *in_dev;
@@ -220,11 +222,12 @@ static int cisco_rx(struct sk_buff *skb)
goto rx_error;
case CISCO_KEEPALIVE_REQ:
- state(hdlc)->rxseq = ntohl(cisco_data->par1);
- if (state(hdlc)->request_sent &&
- ntohl(cisco_data->par2) == state(hdlc)->txseq) {
- state(hdlc)->last_poll = jiffies;
- if (!state(hdlc)->up) {
+ spin_lock(&st->lock);
+ st->rxseq = ntohl(cisco_data->par1);
+ if (st->request_sent &&
+ ntohl(cisco_data->par2) == st->txseq) {
+ st->last_poll = jiffies;
+ if (!st->up) {
u32 sec, min, hrs, days;
sec = ntohl(cisco_data->time) / 1000;
min = sec / 60; sec -= min * 60;
@@ -232,12 +235,12 @@ static int cisco_rx(struct sk_buff *skb)
days = hrs / 24; hrs -= days * 24;
printk(KERN_INFO "%s: Link up (peer "
"uptime %ud%uh%um%us)\n",
- dev->name, days, hrs,
- min, sec);
+ dev->name, days, hrs, min, sec);
netif_dormant_off(dev);
- state(hdlc)->up = 1;
+ st->up = 1;
}
}
+ spin_unlock(&st->lock);
dev_kfree_skb_any(skb);
return NET_RX_SUCCESS;
@@ -261,24 +264,25 @@ static void cisco_timer(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
hdlc_device *hdlc = dev_to_hdlc(dev);
+ struct cisco_state *st = state(hdlc);
- if (state(hdlc)->up &&
- time_after(jiffies, state(hdlc)->last_poll +
- state(hdlc)->settings.timeout * HZ)) {
- state(hdlc)->up = 0;
+ spin_lock(&st->lock);
+ if (st->up &&
+ time_after(jiffies, st->last_poll + st->settings.timeout * HZ)) {
+ st->up = 0;
printk(KERN_INFO "%s: Link down\n", dev->name);
netif_dormant_on(dev);
}
- cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ,
- htonl(++state(hdlc)->txseq),
- htonl(state(hdlc)->rxseq));
- state(hdlc)->request_sent = 1;
- state(hdlc)->timer.expires = jiffies +
- state(hdlc)->settings.interval * HZ;
- state(hdlc)->timer.function = cisco_timer;
- state(hdlc)->timer.data = arg;
- add_timer(&state(hdlc)->timer);
+ cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq),
+ htonl(st->rxseq));
+ st->request_sent = 1;
+ spin_unlock(&st->lock);
+
+ st->timer.expires = jiffies + st->settings.interval * HZ;
+ st->timer.function = cisco_timer;
+ st->timer.data = arg;
+ add_timer(&st->timer);
}
@@ -286,15 +290,20 @@ static void cisco_timer(unsigned long arg)
static void cisco_start(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
- state(hdlc)->up = 0;
- state(hdlc)->request_sent = 0;
- state(hdlc)->txseq = state(hdlc)->rxseq = 0;
-
- init_timer(&state(hdlc)->timer);
- state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/
- state(hdlc)->timer.function = cisco_timer;
- state(hdlc)->timer.data = (unsigned long)dev;
- add_timer(&state(hdlc)->timer);
+ struct cisco_state *st = state(hdlc);
+ unsigned long flags;
+
+ spin_lock_irqsave(&st->lock, flags);
+ st->up = 0;
+ st->request_sent = 0;
+ st->txseq = st->rxseq = 0;
+ spin_unlock_irqrestore(&st->lock, flags);
+
+ init_timer(&st->timer);
+ st->timer.expires = jiffies + HZ; /* First poll after 1 s */
+ st->timer.function = cisco_timer;
+ st->timer.data = (unsigned long)dev;
+ add_timer(&st->timer);
}
@@ -302,10 +311,16 @@ static void cisco_start(struct net_device *dev)
static void cisco_stop(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
- del_timer_sync(&state(hdlc)->timer);
+ struct cisco_state *st = state(hdlc);
+ unsigned long flags;
+
+ del_timer_sync(&st->timer);
+
+ spin_lock_irqsave(&st->lock, flags);
netif_dormant_on(dev);
- state(hdlc)->up = 0;
- state(hdlc)->request_sent = 0;
+ st->up = 0;
+ st->request_sent = 0;
+ spin_unlock_irqrestore(&st->lock, flags);
}
@@ -367,6 +382,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
return result;
memcpy(&state(hdlc)->settings, &new_settings, size);
+ spin_lock_init(&state(hdlc)->lock);
dev->hard_start_xmit = hdlc->xmit;
dev->header_ops = &cisco_header_ops;
dev->type = ARPHRD_CISCO;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 10396d9686f..00308337928 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -45,7 +45,7 @@ static int ppp_open(struct net_device *dev)
int (*old_ioctl)(struct net_device *, struct ifreq *, int);
int result;
- dev->priv = &state(hdlc)->syncppp_ptr;
+ dev->ml_priv = &state(hdlc)->syncppp_ptr;
state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
state(hdlc)->pppdev.dev = dev;
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index 83dbc924fcb..f3065d3473f 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -75,7 +75,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
static int hostess_open(struct net_device *d)
{
- struct sv11_device *sv11=d->priv;
+ struct sv11_device *sv11=d->ml_priv;
int err = -1;
/*
@@ -128,7 +128,7 @@ static int hostess_open(struct net_device *d)
static int hostess_close(struct net_device *d)
{
- struct sv11_device *sv11=d->priv;
+ struct sv11_device *sv11=d->ml_priv;
/*
* Discard new frames
*/
@@ -159,14 +159,14 @@ static int hostess_close(struct net_device *d)
static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
{
- /* struct sv11_device *sv11=d->priv;
+ /* struct sv11_device *sv11=d->ml_priv;
z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
return sppp_do_ioctl(d, ifr,cmd);
}
static struct net_device_stats *hostess_get_stats(struct net_device *d)
{
- struct sv11_device *sv11=d->priv;
+ struct sv11_device *sv11=d->ml_priv;
if(sv11)
return z8530_get_stats(&sv11->sync.chanA);
else
@@ -179,7 +179,7 @@ static struct net_device_stats *hostess_get_stats(struct net_device *d)
static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
{
- struct sv11_device *sv11=d->priv;
+ struct sv11_device *sv11=d->ml_priv;
return z8530_queue_xmit(&sv11->sync.chanA, skb);
}
@@ -325,6 +325,7 @@ static struct sv11_device *sv11_init(int iobase, int irq)
/*
* Initialise the PPP components
*/
+ d->ml_priv = sv;
sppp_attach(&sv->netdev);
/*
@@ -333,7 +334,6 @@ static struct sv11_device *sv11_init(int iobase, int irq)
d->base_addr = iobase;
d->irq = irq;
- d->priv = sv;
if(register_netdev(d))
{
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 6635ecef36e..62133cee446 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -891,6 +891,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
/* Initialize the sppp layer */
/* An ioctl can cause a subsequent detach for raw frame interface */
+ dev->ml_priv = sc;
sc->if_type = LMC_PPP;
sc->check = 0xBEAFCAFE;
dev->base_addr = pci_resource_start(pdev, 0);
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 11276bf3149..44a89df1b8b 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -241,6 +241,7 @@ static inline struct slvl_device *slvl_alloc(int iobase, int irq)
return NULL;
sv = d->priv;
+ d->ml_priv = sv;
sv->if_ptr = &sv->pppdev;
sv->pppdev.dev = d;
d->base_addr = iobase;