Commit b2b109e8 authored by Kai Germaschewski's avatar Kai Germaschewski

Merge zephyr:src/kernel/v2.5/linux-2.5.isdn

into tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linux-2.5.isdn
parents 2b9fa51a 0066476b
...@@ -164,7 +164,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) ...@@ -164,7 +164,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
p += put_u32(p, lp->cisco_yourseq); p += put_u32(p, lp->cisco_yourseq);
p += put_u16(p, 0xffff); // reliablity, always 0xffff p += put_u16(p, 0xffff); // reliablity, always 0xffff
isdn_net_write_super(lp, skb); isdn_net_write_super(idev, skb);
lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ; lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
...@@ -174,6 +174,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data) ...@@ -174,6 +174,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
static void static void
isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp) isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
{ {
isdn_net_dev *idev = lp->netdev;
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *p; unsigned char *p;
...@@ -194,7 +195,7 @@ isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp) ...@@ -194,7 +195,7 @@ isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
p += put_u32(p, 0); // netmask p += put_u32(p, 0); // netmask
p += put_u16(p, 0); // unused p += put_u16(p, 0); // unused
isdn_net_write_super(lp, skb); isdn_net_write_super(idev, skb);
} }
static void static void
...@@ -218,7 +219,7 @@ isdn_ciscohdlck_connected(isdn_net_local *lp) ...@@ -218,7 +219,7 @@ isdn_ciscohdlck_connected(isdn_net_local *lp)
lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ; lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
add_timer(&lp->cisco_timer); add_timer(&lp->cisco_timer);
} }
isdn_net_device_wake_queue(lp); isdn_net_dev_wake_queue(lp->netdev);
} }
static void static void
...@@ -232,13 +233,14 @@ isdn_ciscohdlck_disconnected(isdn_net_local *lp) ...@@ -232,13 +233,14 @@ isdn_ciscohdlck_disconnected(isdn_net_local *lp)
static void static void
isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp) isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
{ {
isdn_net_dev *idev = lp->netdev;
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *p; unsigned char *p;
struct in_device *in_dev = NULL; struct in_device *in_dev = NULL;
u32 addr = 0; /* local ipv4 address */ u32 addr = 0; /* local ipv4 address */
u32 mask = 0; /* local netmask */ u32 mask = 0; /* local netmask */
if ((in_dev = lp->netdev->dev.ip_ptr) != NULL) { if ((in_dev = lp->dev.ip_ptr) != NULL) {
/* take primary(first) address of interface */ /* take primary(first) address of interface */
struct in_ifaddr *ifa = in_dev->ifa_list; struct in_ifaddr *ifa = in_dev->ifa_list;
if (ifa != NULL) { if (ifa != NULL) {
...@@ -265,7 +267,7 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp) ...@@ -265,7 +267,7 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
p += put_u32(p, mask); // netmask p += put_u32(p, mask); // netmask
p += put_u16(p, 0); // unused p += put_u16(p, 0); // unused
isdn_net_write_super(lp, skb); isdn_net_write_super(idev, skb);
} }
static void static void
...@@ -335,10 +337,9 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb) ...@@ -335,10 +337,9 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
} }
static void static void
isdn_ciscohdlck_receive(isdn_net_dev *idev, isdn_net_local *olp, isdn_ciscohdlck_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_local *lp = &idev->local;
unsigned char *p; unsigned char *p;
u8 addr; u8 addr;
u8 ctrl; u8 ctrl;
...@@ -371,7 +372,7 @@ isdn_ciscohdlck_receive(isdn_net_dev *idev, isdn_net_local *olp, ...@@ -371,7 +372,7 @@ isdn_ciscohdlck_receive(isdn_net_dev *idev, isdn_net_local *olp,
goto out_free; goto out_free;
default: default:
/* no special cisco protocol */ /* no special cisco protocol */
isdn_net_reset_huptimer(idev, olp->netdev); isdn_net_reset_huptimer(lp, idev);
skb->protocol = htons(type); skb->protocol = htons(type);
netif_rx(skb); netif_rx(skb);
return; return;
......
...@@ -92,15 +92,16 @@ LIST_HEAD(isdn_net_devs); /* Linked list of isdn_net_dev's */ ...@@ -92,15 +92,16 @@ LIST_HEAD(isdn_net_devs); /* Linked list of isdn_net_dev's */
* Find out if the netdevice has been ifup-ed yet. * Find out if the netdevice has been ifup-ed yet.
* For slaves, look at the corresponding master. * For slaves, look at the corresponding master.
*/ */
static __inline__ int isdn_net_device_started(isdn_net_dev *n) static inline int
isdn_net_device_started(isdn_net_dev *idev)
{ {
isdn_net_local *lp = &n->local;
struct net_device *dev; struct net_device *dev;
if (lp->master) if (idev->master)
dev = lp->master; dev = &idev->master->dev;
else else
dev = &n->dev; dev = &idev->local.dev;
return netif_running(dev); return netif_running(dev);
} }
...@@ -108,12 +109,13 @@ static __inline__ int isdn_net_device_started(isdn_net_dev *n) ...@@ -108,12 +109,13 @@ static __inline__ int isdn_net_device_started(isdn_net_dev *n)
* stop the network -> net_device queue. * stop the network -> net_device queue.
* For slaves, stop the corresponding master interface. * For slaves, stop the corresponding master interface.
*/ */
static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp) static inline void
isdn_net_dev_stop_queue(isdn_net_dev *idev)
{ {
if (lp->master) if (idev->master)
netif_stop_queue(lp->master); netif_stop_queue(&idev->master->dev);
else else
netif_stop_queue(&lp->netdev->dev); netif_stop_queue(&idev->local.dev);
} }
/* /*
...@@ -121,57 +123,61 @@ static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp) ...@@ -121,57 +123,61 @@ static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp)
* master or slave) is busy. It's busy iff all (master and slave) * master or slave) is busy. It's busy iff all (master and slave)
* queues are busy * queues are busy
*/ */
static __inline__ int isdn_net_device_busy(isdn_net_local *lp) static inline int
isdn_net_device_busy(isdn_net_dev *idev)
{ {
isdn_net_local *nlp; isdn_net_dev *ndev;
isdn_net_dev *nd; isdn_net_local *mlp;
unsigned long flags; unsigned long flags;
if (!isdn_net_lp_busy(lp)) if (!isdn_net_dev_busy(idev))
return 0; return 0;
if (lp->master) if (idev->master)
nd = ((isdn_net_local *) lp->master->priv)->netdev; mlp = idev->master;
else else
nd = lp->netdev; mlp = &idev->local;
spin_lock_irqsave(&nd->queue_lock, flags); spin_lock_irqsave(&mlp->queue_lock, flags);
nlp = lp->next; ndev = idev->next;
while (nlp != lp) { while (ndev != idev) {
if (!isdn_net_lp_busy(nlp)) { if (!isdn_net_dev_busy(ndev)) {
spin_unlock_irqrestore(&nd->queue_lock, flags); spin_unlock_irqrestore(&mlp->queue_lock, flags);
return 0; return 0;
} }
nlp = nlp->next; ndev = ndev->next;
} }
spin_unlock_irqrestore(&nd->queue_lock, flags); spin_unlock_irqrestore(&mlp->queue_lock, flags);
return 1; return 1;
} }
static __inline__ void isdn_net_inc_frame_cnt(isdn_net_local *lp) static inline
void isdn_net_inc_frame_cnt(isdn_net_dev *idev)
{ {
atomic_inc(&lp->frame_cnt); atomic_inc(&idev->frame_cnt);
if (isdn_net_device_busy(lp)) if (isdn_net_device_busy(idev))
isdn_net_device_stop_queue(lp); isdn_net_dev_stop_queue(idev);
} }
static __inline__ void isdn_net_dec_frame_cnt(isdn_net_local *lp) static inline void
isdn_net_dec_frame_cnt(isdn_net_dev *idev)
{ {
atomic_dec(&lp->frame_cnt); atomic_dec(&idev->frame_cnt);
if (!(isdn_net_device_busy(lp))) { if (!(isdn_net_device_busy(idev))) {
if (!skb_queue_empty(&lp->super_tx_queue)) { if (!skb_queue_empty(&idev->super_tx_queue)) {
queue_task(&lp->tqueue, &tq_immediate); queue_task(&idev->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH); mark_bh(IMMEDIATE_BH);
} else { } else {
isdn_net_device_wake_queue(lp); isdn_net_dev_wake_queue(idev);
} }
} }
} }
static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp) static inline
void isdn_net_zero_frame_cnt(isdn_net_dev *idev)
{ {
atomic_set(&lp->frame_cnt, 0); atomic_set(&idev->frame_cnt, 0);
} }
/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just /* For 2.2.x we leave the transmitter busy timeout at 2 secs, just
...@@ -208,7 +214,7 @@ int isdn_net_online(isdn_net_dev *idev) ...@@ -208,7 +214,7 @@ int isdn_net_online(isdn_net_dev *idev)
/* Prototypes */ /* Prototypes */
static int isdn_net_force_dial_lp(isdn_net_local *); static int isdn_net_force_dial_idev(isdn_net_dev *);
static int isdn_net_start_xmit(struct sk_buff *, struct net_device *); static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
static void do_dialout(isdn_net_local *lp); static void do_dialout(isdn_net_local *lp);
static int isdn_net_set_encap(isdn_net_dev *p, int encap); static int isdn_net_set_encap(isdn_net_dev *p, int encap);
...@@ -269,14 +275,14 @@ isdn_net_unbind_channel(isdn_net_local * lp) ...@@ -269,14 +275,14 @@ isdn_net_unbind_channel(isdn_net_local * lp)
if (lp->ops->unbind) if (lp->ops->unbind)
lp->ops->unbind(lp); lp->ops->unbind(lp);
skb_queue_purge(&lp->super_tx_queue); skb_queue_purge(&idev->super_tx_queue);
if (!lp->master) { /* reset only master device */ if (!idev->master) { /* reset only master device */
/* Moral equivalent of dev_purge_queues(): /* Moral equivalent of dev_purge_queues():
BEWARE! This chunk of code cannot be called from hardware BEWARE! This chunk of code cannot be called from hardware
interrupt handler. I hope it is true. --ANK interrupt handler. I hope it is true. --ANK
*/ */
qdisc_reset(lp->netdev->dev.qdisc); qdisc_reset(lp->dev.qdisc);
} }
idev->dialstate = ST_NULL; idev->dialstate = ST_NULL;
if (idev->isdn_slot >= 0) { if (idev->isdn_slot >= 0) {
...@@ -376,23 +382,23 @@ static void isdn_net_hup_timer(unsigned long data) ...@@ -376,23 +382,23 @@ static void isdn_net_hup_timer(unsigned long data)
mod_timer(&idev->hup_timer, idev->hup_timer.expires + HZ); mod_timer(&idev->hup_timer, idev->hup_timer.expires + HZ);
} }
static void isdn_net_lp_disconnected(isdn_net_local *lp) static void isdn_net_lp_disconnected(isdn_net_dev *idev)
{ {
isdn_net_rm_from_bundle(lp); isdn_net_rm_from_bundle(idev);
} }
static void isdn_net_connected(isdn_net_local *lp) static void isdn_net_connected(isdn_net_dev *idev)
{ {
isdn_net_dev *idev = lp->netdev; isdn_net_local *lp = &idev->local;
idev->dialstate = ST_ACTIVE; idev->dialstate = ST_ACTIVE;
idev->hup_timer.expires = jiffies + HZ; idev->hup_timer.expires = jiffies + HZ;
add_timer(&idev->hup_timer); add_timer(&idev->hup_timer);
if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) { if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
if (lp->master) { /* is lp a slave? */ if (idev->master) { /* is lp a slave? */
isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev; isdn_net_local *mlp = idev->master;
isdn_net_add_to_bundle(nd, lp); isdn_net_add_to_bundle(mlp, idev);
} }
} }
printk(KERN_INFO "isdn_net: %s connected\n", idev->name); printk(KERN_INFO "isdn_net: %s connected\n", idev->name);
...@@ -412,7 +418,7 @@ static void isdn_net_connected(isdn_net_local *lp) ...@@ -412,7 +418,7 @@ static void isdn_net_connected(isdn_net_local *lp)
if (lp->ops->connected) if (lp->ops->connected)
lp->ops->connected(lp); lp->ops->connected(lp);
else else
isdn_net_device_wake_queue(lp); isdn_net_dev_wake_queue(idev);
} }
/* /*
...@@ -562,7 +568,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -562,7 +568,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
switch (pr) { switch (pr) {
case ISDN_STAT_BSENT: case ISDN_STAT_BSENT:
/* A packet has successfully been sent out */ /* A packet has successfully been sent out */
isdn_net_dec_frame_cnt(lp); isdn_net_dec_frame_cnt(idev);
lp->stats.tx_packets++; lp->stats.tx_packets++;
lp->stats.tx_bytes += c->parm.length; lp->stats.tx_bytes += c->parm.length;
return 1; return 1;
...@@ -570,7 +576,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -570,7 +576,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
if (lp->ops->disconnected) if (lp->ops->disconnected)
lp->ops->disconnected(lp); lp->ops->disconnected(lp);
isdn_net_lp_disconnected(lp); isdn_net_lp_disconnected(idev);
isdn_slot_all_eaz(idev->isdn_slot); isdn_slot_all_eaz(idev->isdn_slot);
printk(KERN_INFO "%s: remote hangup\n", idev->name); printk(KERN_INFO "%s: remote hangup\n", idev->name);
printk(KERN_INFO "%s: Chargesum is %d\n", idev->name, printk(KERN_INFO "%s: Chargesum is %d\n", idev->name,
...@@ -637,7 +643,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -637,7 +643,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
case ISDN_STAT_BCONN: case ISDN_STAT_BCONN:
del_timer(&idev->dial_timer); del_timer(&idev->dial_timer);
isdn_slot_set_usage(idev->isdn_slot, isdn_slot_usage(idev->isdn_slot) | ISDN_USAGE_OUTGOING); isdn_slot_set_usage(idev->isdn_slot, isdn_slot_usage(idev->isdn_slot) | ISDN_USAGE_OUTGOING);
isdn_net_connected(lp); isdn_net_connected(idev);
return 1; return 1;
case ISDN_STAT_DHUP: case ISDN_STAT_DHUP:
del_timer(&idev->dial_timer); del_timer(&idev->dial_timer);
...@@ -676,7 +682,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -676,7 +682,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
case ISDN_STAT_BCONN: case ISDN_STAT_BCONN:
del_timer(&idev->dial_timer); del_timer(&idev->dial_timer);
isdn_slot_set_rx_netdev(idev->isdn_slot, idev); isdn_slot_set_rx_netdev(idev->isdn_slot, idev);
isdn_net_connected(lp); isdn_net_connected(idev);
return 1; return 1;
case ISDN_STAT_DHUP: case ISDN_STAT_DHUP:
del_timer(&idev->dial_timer); del_timer(&idev->dial_timer);
...@@ -716,21 +722,20 @@ isdn_net_hangup(isdn_net_dev *idev) ...@@ -716,21 +722,20 @@ isdn_net_hangup(isdn_net_dev *idev)
return; return;
// FIXME ugly and recursive // FIXME ugly and recursive
if (lp->slave != NULL) { if (idev->slave) {
isdn_net_local *slp = (isdn_net_local *)lp->slave->priv; isdn_net_dev *sdev = idev->slave;
isdn_net_dev *sidev = slp->netdev; if (isdn_net_bound(sdev)) {
if (isdn_net_bound(sidev)) {
printk(KERN_INFO printk(KERN_INFO
"isdn_net: hang up slave %s before %s\n", "isdn_net: hang up slave %s before %s\n",
sidev->name, idev->name); sdev->name, idev->name);
isdn_net_hangup(sidev); isdn_net_hangup(sdev);
} }
} }
printk(KERN_INFO "isdn_net: local hangup %s\n", idev->name); printk(KERN_INFO "isdn_net: local hangup %s\n", idev->name);
if (lp->ops->disconnected) if (lp->ops->disconnected)
lp->ops->disconnected(lp); lp->ops->disconnected(lp);
isdn_net_lp_disconnected(lp); isdn_net_lp_disconnected(idev);
isdn_slot_command(idev->isdn_slot, ISDN_CMD_HANGUP, &cmd); isdn_slot_command(idev->isdn_slot, ISDN_CMD_HANGUP, &cmd);
printk(KERN_INFO "%s: Chargesum is %d\n", idev->name, idev->charge); printk(KERN_INFO "%s: Chargesum is %d\n", idev->name, idev->charge);
...@@ -846,24 +851,25 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp) ...@@ -846,24 +851,25 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
* not received from the network layer, but e.g. frames from ipppd, CCP * not received from the network layer, but e.g. frames from ipppd, CCP
* reset frames etc. * reset frames etc.
*/ */
void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb) void
isdn_net_write_super(isdn_net_dev *idev, struct sk_buff *skb)
{ {
if (in_irq()) { if (in_irq()) {
// we can't grab the lock from irq context, // we can't grab the lock from irq context,
// so we just queue the packet // so we just queue the packet
skb_queue_tail(&lp->super_tx_queue, skb); skb_queue_tail(&idev->super_tx_queue, skb);
queue_task(&lp->tqueue, &tq_immediate); queue_task(&idev->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH); mark_bh(IMMEDIATE_BH);
return; return;
} }
spin_lock_bh(&lp->xmit_lock); spin_lock_bh(&idev->xmit_lock);
if (!isdn_net_lp_busy(lp)) { if (!isdn_net_dev_busy(idev)) {
isdn_net_writebuf_skb(lp, skb); isdn_net_writebuf_skb(idev, skb);
} else { } else {
skb_queue_tail(&lp->super_tx_queue, skb); skb_queue_tail(&idev->super_tx_queue, skb);
} }
spin_unlock_bh(&lp->xmit_lock); spin_unlock_bh(&idev->xmit_lock);
} }
/* /*
...@@ -871,32 +877,32 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb) ...@@ -871,32 +877,32 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
*/ */
static void isdn_net_softint(void *private) static void isdn_net_softint(void *private)
{ {
isdn_net_local *lp = private; isdn_net_dev *idev = private;
struct sk_buff *skb; struct sk_buff *skb;
spin_lock_bh(&lp->xmit_lock); spin_lock_bh(&idev->xmit_lock);
while (!isdn_net_lp_busy(lp)) { while (!isdn_net_dev_busy(idev)) {
skb = skb_dequeue(&lp->super_tx_queue); skb = skb_dequeue(&idev->super_tx_queue);
if (!skb) if (!skb)
break; break;
isdn_net_writebuf_skb(lp, skb); isdn_net_writebuf_skb(idev, skb);
} }
spin_unlock_bh(&lp->xmit_lock); spin_unlock_bh(&idev->xmit_lock);
} }
/* /*
* all frames sent from the (net) LL to a HL driver should go via this function * all frames sent from the (net) LL to a HL driver should go via this function
* it's serialized by the caller holding the lp->xmit_lock spinlock * it's serialized by the caller holding the idev->xmit_lock spinlock
*/ */
void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb) void isdn_net_writebuf_skb(isdn_net_dev *idev, struct sk_buff *skb)
{ {
isdn_net_dev *idev = lp->netdev; isdn_net_local *lp = &idev->local;
int ret; int ret;
int len = skb->len; /* save len */ int len = skb->len; /* save len */
/* before obtaining the lock the caller should have checked that /* before obtaining the lock the caller should have checked that
the lp isn't busy */ the lp isn't busy */
if (isdn_net_lp_busy(lp)) { if (isdn_net_dev_busy(idev)) {
isdn_BUG(); isdn_BUG();
goto error; goto error;
} }
...@@ -913,7 +919,7 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb) ...@@ -913,7 +919,7 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
} }
idev->transcount += len; idev->transcount += len;
isdn_net_inc_frame_cnt(lp); isdn_net_inc_frame_cnt(idev);
return; return;
error: error:
...@@ -936,34 +942,29 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb) ...@@ -936,34 +942,29 @@ void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
static int static int
isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
{ {
isdn_net_dev *nd, *idev; isdn_net_local *mlp;
isdn_net_local *slp; isdn_net_dev *sdev;
isdn_net_local *lp = ndev->priv; isdn_net_local *lp = ndev->priv;
isdn_net_dev *idev = lp->netdev;
int retv = 0; int retv = 0;
if (lp->master) {
isdn_BUG();
dev_kfree_skb(skb);
return 0;
}
/* For the other encaps the header has already been built */ /* For the other encaps the header has already been built */
if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) { if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
return isdn_ppp_xmit(skb, ndev); return isdn_ppp_xmit(skb, ndev);
} }
nd = ((isdn_net_local *) ndev->priv)->netdev; mlp = ndev->priv;
lp = isdn_net_get_locked_lp(nd); idev = isdn_net_get_locked_dev(mlp);
if (!lp) { if (!idev) {
printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name); printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
return 1; return 1;
} }
idev = lp->netdev; /* we have our idev locked from now on */
/* we have our lp locked from now on */ lp = &idev->local;
/* Reset hangup-timeout */ /* Reset hangup-timeout */
idev->huptimer = 0; // FIXME? idev->huptimer = 0; // FIXME?
isdn_net_writebuf_skb(lp, skb); isdn_net_writebuf_skb(idev, skb);
spin_unlock_bh(&lp->xmit_lock); spin_unlock_bh(&idev->xmit_lock);
/* the following stuff is here for backwards compatibility. /* the following stuff is here for backwards compatibility.
* in future, start-up and hangup of slaves (based on current load) * in future, start-up and hangup of slaves (based on current load)
...@@ -979,27 +980,27 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) ...@@ -979,27 +980,27 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
printk(KERN_DEBUG "%s: %d bogocps\n", idev->name, idev->cps); printk(KERN_DEBUG "%s: %d bogocps\n", idev->name, idev->cps);
if (idev->cps > lp->triggercps) { if (idev->cps > lp->triggercps) {
if (lp->slave) { if (idev->slave) {
if (!lp->sqfull) { if (!idev->sqfull) {
/* First time overload: set timestamp only */ /* First time overload: set timestamp only */
lp->sqfull = 1; idev->sqfull = 1;
lp->sqfull_stamp = jiffies; idev->sqfull_stamp = jiffies;
} else { } else {
/* subsequent overload: if slavedelay exceeded, start dialing */ /* subsequent overload: if slavedelay exceeded, start dialing */
if (time_after(jiffies, lp->sqfull_stamp + lp->slavedelay)) { if (time_after(jiffies, idev->sqfull_stamp + lp->slavedelay)) {
slp = lp->slave->priv; sdev = idev->slave;
if (!isdn_net_bound(slp->netdev)) { if (!isdn_net_bound(sdev)) {
isdn_net_force_dial_lp((isdn_net_local *) lp->slave->priv); isdn_net_force_dial_idev(sdev);
} }
} }
} }
} }
} else { } else {
if (lp->sqfull && time_after(jiffies, lp->sqfull_stamp + lp->slavedelay + (10 * HZ))) { if (idev->sqfull && time_after(jiffies, idev->sqfull_stamp + lp->slavedelay + 10 * HZ)) {
lp->sqfull = 0; idev->sqfull = 0;
} }
/* this is a hack to allow auto-hangup for slaves on moderate loads */ /* this is a hack to allow auto-hangup for slaves on moderate loads */
nd->queue = &nd->local; mlp->queue = mlp->netdev;
} }
return retv; return retv;
...@@ -1053,7 +1054,7 @@ isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev) ...@@ -1053,7 +1054,7 @@ isdn_net_autodial(struct sk_buff *skb, struct net_device *ndev)
idev->dialwait_timer = 0; idev->dialwait_timer = 0;
} }
if (isdn_net_force_dial_lp(lp) < 0) if (isdn_net_force_dial_idev(idev) < 0)
goto discard; goto discard;
/* Log packet, which triggered dialing */ /* Log packet, which triggered dialing */
...@@ -1113,18 +1114,19 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1113,18 +1114,19 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static int static int
isdn_net_close(struct net_device *dev) isdn_net_close(struct net_device *dev)
{ {
struct net_device *p;
isdn_net_local *lp = dev->priv; isdn_net_local *lp = dev->priv;
isdn_net_dev *idev = lp->netdev;
isdn_net_dev *sdev;
if (lp->ops->close) if (lp->ops->close)
lp->ops->close(lp); lp->ops->close(lp);
netif_stop_queue(dev); netif_stop_queue(dev);
for (p = lp->slave; p; p = ((isdn_net_local *) p->priv)->slave) for (sdev = idev->slave; sdev; sdev = sdev->slave)
isdn_net_hangup(p->priv); isdn_net_hangup(sdev);
isdn_net_hangup(dev->priv); isdn_net_hangup(idev);
isdn_MOD_DEC_USE_COUNT(); isdn_MOD_DEC_USE_COUNT();
return 0; return 0;
} }
...@@ -1143,31 +1145,29 @@ isdn_net_get_stats(struct net_device *dev) ...@@ -1143,31 +1145,29 @@ isdn_net_get_stats(struct net_device *dev)
* Got a packet from ISDN-Channel. * Got a packet from ISDN-Channel.
*/ */
static void static void
isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) isdn_net_receive(isdn_net_dev *idev, struct sk_buff *skb)
{ {
isdn_net_local *lp = (isdn_net_local *) ndev->priv; isdn_net_local *lp;
isdn_net_dev *idev = lp->netdev; struct net_device *ndev;
isdn_net_local *olp = lp; /* original 'lp' */
idev->transcount += skb->len; idev->transcount += skb->len;
if (idev->master) {
lp->stats.rx_packets++;
lp->stats.rx_bytes += skb->len;
if (lp->master) {
/* Bundling: If device is a slave-device, deliver to master, also /* Bundling: If device is a slave-device, deliver to master, also
* handle master's statistics and hangup-timeout * handle master's statistics and hangup-timeout
*/ */
ndev = lp->master; ndev = &idev->master->dev;
lp = (isdn_net_local *) ndev->priv; } else {
lp->stats.rx_packets++; ndev = &idev->local.dev;
lp->stats.rx_bytes += skb->len;
} }
lp = ndev->priv;
lp->stats.rx_packets++;
lp->stats.rx_bytes += skb->len;
skb->dev = ndev; skb->dev = ndev;
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
skb->mac.raw = skb->data; skb->mac.raw = skb->data;
isdn_dumppkt("R:", skb->data, skb->len, 40); isdn_dumppkt("R:", skb->data, skb->len, 40);
lp->ops->receive(lp->netdev, olp, skb); lp->ops->receive(lp, idev, skb);
} }
/* /*
...@@ -1186,7 +1186,7 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb) ...@@ -1186,7 +1186,7 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb)
if (!isdn_net_online(idev)) if (!isdn_net_online(idev))
return 0; return 0;
isdn_net_receive(&idev->dev, skb); isdn_net_receive(idev, skb);
return 0; return 0;
} }
...@@ -1394,23 +1394,23 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) ...@@ -1394,23 +1394,23 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
/* Interface is up, now see if it's a slave. If so, see if /* Interface is up, now see if it's a slave. If so, see if
* it's master and parent slave is online. If not, reject the call. * it's master and parent slave is online. If not, reject the call.
*/ */
if (lp->master) { if (idev->master) {
isdn_net_local *mlp = (isdn_net_local *) lp->master->priv; isdn_net_dev *pdev = idev->master->netdev;
printk(KERN_DEBUG "ICALLslv: %s\n", idev->name); printk(KERN_DEBUG "ICALLslv: %s\n", idev->name);
printk(KERN_DEBUG "master=%s\n", mlp->netdev->name); printk(KERN_DEBUG "master=%s\n", pdev->name);
if (isdn_net_bound(mlp->netdev)) { if (isdn_net_bound(pdev)) {
printk(KERN_DEBUG "master online\n"); printk(KERN_DEBUG "master online\n");
/* Master is online, find parent-slave (master if first slave) */ /* Master is online, find parent-slave (master if first slave) */
while (mlp->slave) { while (pdev->slave) {
if ((isdn_net_local *) mlp->slave->priv == lp) if (pdev->slave == idev)
break; break;
mlp = (isdn_net_local *) mlp->slave->priv; pdev = pdev->slave;
} }
} else } else
printk(KERN_DEBUG "master offline\n"); printk(KERN_DEBUG "master offline\n");
/* Found parent, if it's offline iterate next device */ /* Found parent, if it's offline iterate next device */
printk(KERN_DEBUG "mlpf: %d\n", isdn_net_bound(mlp->netdev)); printk(KERN_DEBUG "mlpf: %d\n", isdn_net_bound(pdev));
if (!isdn_net_bound(mlp->netdev)) { if (!isdn_net_bound(pdev)) {
continue; continue;
} }
} }
...@@ -1474,11 +1474,11 @@ isdn_net_findif(char *name) ...@@ -1474,11 +1474,11 @@ isdn_net_findif(char *name)
* from isdn_net_start_xmit(). * from isdn_net_start_xmit().
*/ */
static int static int
isdn_net_force_dial_lp(isdn_net_local *lp) isdn_net_force_dial_idev(isdn_net_dev *idev)
{ {
isdn_net_dev *idev = lp->netdev;
int slot; int slot;
unsigned long flags; unsigned long flags;
isdn_net_local *lp = &idev->local;
if (isdn_net_bound(idev)) if (isdn_net_bound(idev))
return -EBUSY; return -EBUSY;
...@@ -1515,12 +1515,13 @@ isdn_net_force_dial_lp(isdn_net_local *lp) ...@@ -1515,12 +1515,13 @@ isdn_net_force_dial_lp(isdn_net_local *lp)
* themselves. * themselves.
*/ */
int int
isdn_net_dial_req(isdn_net_local * lp) isdn_net_dial_req(isdn_net_dev *idev)
{ {
isdn_net_local *lp = &idev->local;
/* is there a better error code? */ /* is there a better error code? */
if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) return -EBUSY; if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) return -EBUSY;
return isdn_net_force_dial_lp(lp); return isdn_net_force_dial_idev(idev);
} }
/* /*
...@@ -1534,7 +1535,8 @@ isdn_net_force_dial(char *name) ...@@ -1534,7 +1535,8 @@ isdn_net_force_dial(char *name)
if (!p) if (!p)
return -ENODEV; return -ENODEV;
return (isdn_net_force_dial_lp(&p->local));
return isdn_net_force_dial_idev(p);
} }
/* /*
...@@ -1544,6 +1546,7 @@ int ...@@ -1544,6 +1546,7 @@ int
isdn_net_new(char *name, struct net_device *master) isdn_net_new(char *name, struct net_device *master)
{ {
int retval; int retval;
isdn_net_local *mlp = master->priv;
isdn_net_dev *netdev; isdn_net_dev *netdev;
/* Avoid creating an existing interface */ /* Avoid creating an existing interface */
...@@ -1557,29 +1560,25 @@ isdn_net_new(char *name, struct net_device *master) ...@@ -1557,29 +1560,25 @@ isdn_net_new(char *name, struct net_device *master)
} }
memset(netdev, 0, sizeof(isdn_net_dev)); memset(netdev, 0, sizeof(isdn_net_dev));
strcpy(netdev->name, name); strcpy(netdev->name, name);
strcpy(netdev->dev.name, name); strcpy(netdev->local.dev.name, name);
netdev->dev.priv = &netdev->local; netdev->local.dev.priv = &netdev->local;
netdev->dev.init = isdn_net_init; netdev->local.dev.init = isdn_net_init;
if (master) { if (master) {
/* Device shall be a slave */ /* Device shall be a slave */
struct net_device *p = (((isdn_net_local *) master->priv)->slave); isdn_net_dev *p = mlp->netdev;
struct net_device *q = master;
while (p->slave)
netdev->local.master = master; p = p->slave;
/* Put device at end of slave-chain */
while (p) { p->slave = netdev;
q = p;
p = (((isdn_net_local *) p->priv)->slave);
}
((isdn_net_local *) q->priv)->slave = &(netdev->dev);
} else { } else {
/* Device shall be a master */ /* Device shall be a master */
/* /*
* Watchdog timer (currently) for master only. * Watchdog timer (currently) for master only.
*/ */
netdev->dev.tx_timeout = isdn_net_tx_timeout; netdev->local.dev.tx_timeout = isdn_net_tx_timeout;
netdev->dev.watchdog_timeo = ISDN_NET_TX_TIMEOUT; netdev->local.dev.watchdog_timeo = ISDN_NET_TX_TIMEOUT;
retval = register_netdev(&netdev->dev); retval = register_netdev(&netdev->local.dev);
if (retval) { if (retval) {
printk(KERN_WARNING "isdn_net: Could not register net-device\n"); printk(KERN_WARNING "isdn_net: Could not register net-device\n");
kfree(netdev); kfree(netdev);
...@@ -1588,17 +1587,17 @@ isdn_net_new(char *name, struct net_device *master) ...@@ -1588,17 +1587,17 @@ isdn_net_new(char *name, struct net_device *master)
} }
netdev->local.magic = ISDN_NET_MAGIC; netdev->local.magic = ISDN_NET_MAGIC;
netdev->queue = &netdev->local; netdev->local.queue = netdev;
spin_lock_init(&netdev->queue_lock); spin_lock_init(&netdev->local.queue_lock);
netdev->local.last = &netdev->local; netdev->last = netdev;
netdev->next = netdev;
netdev->local.netdev = netdev; netdev->local.netdev = netdev;
netdev->local.next = &netdev->local;
netdev->local.tqueue.sync = 0; netdev->tqueue.sync = 0;
netdev->local.tqueue.routine = isdn_net_softint; netdev->tqueue.routine = isdn_net_softint;
netdev->local.tqueue.data = &netdev->local; netdev->tqueue.data = netdev;
spin_lock_init(&netdev->local.xmit_lock); spin_lock_init(&netdev->xmit_lock);
netdev->isdn_slot = -1; netdev->isdn_slot = -1;
netdev->pre_device = -1; netdev->pre_device = -1;
...@@ -1609,7 +1608,7 @@ isdn_net_new(char *name, struct net_device *master) ...@@ -1609,7 +1608,7 @@ isdn_net_new(char *name, struct net_device *master)
netdev->pppbind = -1; netdev->pppbind = -1;
netdev->local.p_encap = -1; netdev->local.p_encap = -1;
skb_queue_head_init(&netdev->local.super_tx_queue); skb_queue_head_init(&netdev->super_tx_queue);
netdev->local.l2_proto = ISDN_PROTO_L2_X75I; netdev->local.l2_proto = ISDN_PROTO_L2_X75I;
netdev->local.l3_proto = ISDN_PROTO_L3_TRANS; netdev->local.l3_proto = ISDN_PROTO_L3_TRANS;
netdev->local.triggercps = 6000; netdev->local.triggercps = 6000;
...@@ -1656,19 +1655,19 @@ isdn_net_newslave(char *parm) ...@@ -1656,19 +1655,19 @@ isdn_net_newslave(char *parm)
if (!(m = isdn_net_findif(parm))) if (!(m = isdn_net_findif(parm)))
return -ESRCH; return -ESRCH;
/* Master must be a real interface, not a slave */ /* Master must be a real interface, not a slave */
if (m->local.master) if (m->master)
return -ENXIO; return -ENXIO;
/* Master must not be started yet */ /* Master must not be started yet */
if (isdn_net_device_started(m)) if (isdn_net_device_started(m))
return -EBUSY; return -EBUSY;
return isdn_net_new(p+1, &m->dev); return isdn_net_new(p+1, &m->local.dev);
} }
static int static int
isdn_net_set_encap(isdn_net_dev *p, int encap) isdn_net_set_encap(isdn_net_dev *idev, int encap)
{ {
isdn_net_local *lp = &p->local; isdn_net_local *lp = &idev->local;
int retval = 0; int retval = 0;
if (lp->p_encap == encap){ if (lp->p_encap == encap){
...@@ -1676,7 +1675,7 @@ isdn_net_set_encap(isdn_net_dev *p, int encap) ...@@ -1676,7 +1675,7 @@ isdn_net_set_encap(isdn_net_dev *p, int encap)
retval = 0; retval = 0;
goto out; goto out;
} }
if (isdn_net_device_started(p)) { if (isdn_net_device_started(idev)) {
retval = -EBUSY; retval = -EBUSY;
goto out; goto out;
} }
...@@ -1693,11 +1692,11 @@ isdn_net_set_encap(isdn_net_dev *p, int encap) ...@@ -1693,11 +1692,11 @@ isdn_net_set_encap(isdn_net_dev *p, int encap)
lp->p_encap = encap; lp->p_encap = encap;
lp->ops = netif_ops[encap]; lp->ops = netif_ops[encap];
p->dev.hard_header = lp->ops->hard_header; lp->dev.hard_header = lp->ops->hard_header;
p->dev.do_ioctl = lp->ops->do_ioctl; lp->dev.do_ioctl = lp->ops->do_ioctl;
p->dev.flags = lp->ops->flags; lp->dev.flags = lp->ops->flags;
p->dev.type = lp->ops->type; lp->dev.type = lp->ops->type;
p->dev.addr_len = lp->ops->addr_len; lp->dev.addr_len = lp->ops->addr_len;
if (lp->ops->init) if (lp->ops->init)
retval = lp->ops->init(lp); retval = lp->ops->init(lp);
...@@ -1928,12 +1927,12 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg) ...@@ -1928,12 +1927,12 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
cfg->pppbind = idev->pppbind; cfg->pppbind = idev->pppbind;
cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1; cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
cfg->dialwait = lp->dialwait / HZ; cfg->dialwait = lp->dialwait / HZ;
if (lp->slave) if (idev->slave)
strcpy(cfg->slave, ((isdn_net_local *) lp->slave->priv)->netdev->name); strcpy(cfg->slave, idev->slave->name);
else else
cfg->slave[0] = '\0'; cfg->slave[0] = '\0';
if (lp->master) if (idev->master)
strcpy(cfg->master, ((isdn_net_local *) lp->master->priv)->netdev->name); strcpy(cfg->master, idev->master->netdev->name);
else else
cfg->master[0] = '\0'; cfg->master[0] = '\0';
...@@ -2090,7 +2089,7 @@ int ...@@ -2090,7 +2089,7 @@ int
isdn_net_force_hangup(char *name) isdn_net_force_hangup(char *name)
{ {
isdn_net_dev *idev = isdn_net_findif(name); isdn_net_dev *idev = isdn_net_findif(name);
struct net_device *q; isdn_net_dev *p;
if (!idev) if (!idev)
return -ENODEV; return -ENODEV;
...@@ -2098,11 +2097,11 @@ isdn_net_force_hangup(char *name) ...@@ -2098,11 +2097,11 @@ isdn_net_force_hangup(char *name)
if (idev->isdn_slot < 0) if (idev->isdn_slot < 0)
return -ENOTCONN; return -ENOTCONN;
q = idev->local.slave; p = idev->slave;
/* If this interface has slaves, do a hangup for them also. */ /* If this interface has slaves, do a hangup for them also. */
while (q) { while (p) {
isdn_net_hangup(((isdn_net_local *) q->priv)->netdev); isdn_net_hangup(p);
q = (((isdn_net_local *) q->priv)->slave); p = p->slave;
} }
isdn_net_hangup(idev); isdn_net_hangup(idev);
return 0; return 0;
...@@ -2129,19 +2128,19 @@ isdn_net_realrm(isdn_net_dev *p) ...@@ -2129,19 +2128,19 @@ isdn_net_realrm(isdn_net_dev *p)
/* If interface is bound exclusive, free channel-usage */ /* If interface is bound exclusive, free channel-usage */
if (p->exclusive >= 0) if (p->exclusive >= 0)
isdn_unexclusive_channel(p->pre_device, p->pre_channel); isdn_unexclusive_channel(p->pre_device, p->pre_channel);
if (p->local.master) { if (p->master) {
/* It's a slave-device, so update master's slave-pointer if necessary */ /* It's a slave-device, so update master's slave-pointer if necessary */
if (((isdn_net_local *) (p->local.master->priv))->slave == &p->dev) if (p->master->netdev->slave == p)
((isdn_net_local *) (p->local.master->priv))->slave = p->local.slave; p->master->netdev->slave = p->slave;
} else { } else {
/* Unregister only if it's a master-device */ /* Unregister only if it's a master-device */
unregister_netdev(&p->dev); unregister_netdev(&p->local.dev);
} }
/* Unlink device from chain */ /* Unlink device from chain */
list_del(&p->global_list); list_del(&p->global_list);
if (p->local.slave) { if (p->slave) {
/* If this interface has a slave, remove it also */ /* If this interface has a slave, remove it also */
char *slavename = ((isdn_net_local *) (p->local.slave->priv))->netdev->name; char *slavename = p->slave->name;
struct list_head *l; struct list_head *l;
list_for_each(l, &isdn_net_devs) { list_for_each(l, &isdn_net_devs) {
...@@ -2191,7 +2190,7 @@ isdn_net_rmall(void) ...@@ -2191,7 +2190,7 @@ isdn_net_rmall(void)
isdn_net_dev *p = list_entry(isdn_net_devs.next, isdn_net_dev, global_list); isdn_net_dev *p = list_entry(isdn_net_devs.next, isdn_net_dev, global_list);
/* Remove master-devices only, slaves get removed with their master */ /* Remove master-devices only, slaves get removed with their master */
if (!p->local.master) { if (!p->master) {
if ((ret = isdn_net_realrm(p))) { if ((ret = isdn_net_realrm(p))) {
restore_flags(flags); restore_flags(flags);
return ret; return ret;
...@@ -2216,10 +2215,10 @@ isdn_iptyp_header(struct sk_buff *skb, struct net_device *dev, ...@@ -2216,10 +2215,10 @@ isdn_iptyp_header(struct sk_buff *skb, struct net_device *dev,
} }
static void static void
isdn_iptyp_receive(isdn_net_dev *p, isdn_net_local *olp, isdn_iptyp_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_reset_huptimer(p, olp->netdev); isdn_net_reset_huptimer(lp, idev);
get_u16(skb->data, &skb->protocol); get_u16(skb->data, &skb->protocol);
skb_pull(skb, 2); skb_pull(skb, 2);
netif_rx(skb); netif_rx(skb);
...@@ -2247,10 +2246,10 @@ isdn_uihdlc_header(struct sk_buff *skb, struct net_device *dev, ...@@ -2247,10 +2246,10 @@ isdn_uihdlc_header(struct sk_buff *skb, struct net_device *dev,
} }
static void static void
isdn_uihdlc_receive(isdn_net_dev *p, isdn_net_local *olp, isdn_uihdlc_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_reset_huptimer(p, olp->netdev); isdn_net_reset_huptimer(lp, idev);
skb_pull(skb, 2); skb_pull(skb, 2);
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
netif_rx(skb); netif_rx(skb);
...@@ -2269,10 +2268,10 @@ static struct isdn_netif_ops uihdlc_ops = { ...@@ -2269,10 +2268,10 @@ static struct isdn_netif_ops uihdlc_ops = {
// ====================================================================== // ======================================================================
static void static void
isdn_rawip_receive(isdn_net_dev *p, isdn_net_local *olp, isdn_rawip_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_reset_huptimer(p, olp->netdev); isdn_net_reset_huptimer(lp, idev);
skb->protocol = htons(ETH_P_IP); skb->protocol = htons(ETH_P_IP);
netif_rx(skb); netif_rx(skb);
} }
...@@ -2342,10 +2341,10 @@ isdn_eth_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -2342,10 +2341,10 @@ isdn_eth_type_trans(struct sk_buff *skb, struct net_device *dev)
} }
static void static void
isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp, isdn_ether_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_reset_huptimer(p, olp->netdev); isdn_net_reset_huptimer(lp, idev);
skb->protocol = isdn_eth_type_trans(skb, skb->dev); skb->protocol = isdn_eth_type_trans(skb, skb->dev);
netif_rx(skb); netif_rx(skb);
} }
...@@ -2353,7 +2352,7 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp, ...@@ -2353,7 +2352,7 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp,
static int static int
isdn_ether_open(isdn_net_local *lp) isdn_ether_open(isdn_net_local *lp)
{ {
struct net_device *dev = &lp->netdev->dev; struct net_device *dev = &lp->dev;
struct in_device *in_dev; struct in_device *in_dev;
int i; int i;
...@@ -2373,7 +2372,7 @@ isdn_ether_open(isdn_net_local *lp) ...@@ -2373,7 +2372,7 @@ isdn_ether_open(isdn_net_local *lp)
static int static int
isdn_ether_init(isdn_net_local *lp) isdn_ether_init(isdn_net_local *lp)
{ {
struct net_device *dev = &lp->netdev->dev; struct net_device *dev = &lp->dev;
ether_setup(dev); ether_setup(dev);
dev->tx_queue_len = 10; dev->tx_queue_len = 10;
......
...@@ -52,16 +52,16 @@ extern int isdn_net_force_hangup(char *); ...@@ -52,16 +52,16 @@ extern int isdn_net_force_hangup(char *);
extern int isdn_net_force_dial(char *); extern int isdn_net_force_dial(char *);
extern isdn_net_dev *isdn_net_findif(char *); extern isdn_net_dev *isdn_net_findif(char *);
extern int isdn_net_rcv_skb(int, struct sk_buff *); extern int isdn_net_rcv_skb(int, struct sk_buff *);
extern int isdn_net_dial_req(isdn_net_local *); extern int isdn_net_dial_req(isdn_net_dev *);
extern void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb); extern void isdn_net_writebuf_skb(isdn_net_dev *, struct sk_buff *skb);
extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb); extern void isdn_net_write_super(isdn_net_dev *, struct sk_buff *skb);
extern int isdn_net_online(isdn_net_dev *idev); extern int isdn_net_online(isdn_net_dev *);
static inline void static inline void
isdn_net_reset_huptimer(isdn_net_dev *idev, isdn_net_dev *idev2) isdn_net_reset_huptimer(isdn_net_local *lp, isdn_net_dev *idev)
{ {
lp->netdev->huptimer = 0;
idev->huptimer = 0; idev->huptimer = 0;
idev2->huptimer = 0;
} }
#define ISDN_NET_MAX_QUEUE_LENGTH 2 #define ISDN_NET_MAX_QUEUE_LENGTH 2
...@@ -69,9 +69,10 @@ isdn_net_reset_huptimer(isdn_net_dev *idev, isdn_net_dev *idev2) ...@@ -69,9 +69,10 @@ isdn_net_reset_huptimer(isdn_net_dev *idev, isdn_net_dev *idev2)
/* /*
* is this particular channel busy? * is this particular channel busy?
*/ */
static __inline__ int isdn_net_lp_busy(isdn_net_local *lp) static inline int
isdn_net_dev_busy(isdn_net_dev *idev)
{ {
if (atomic_read(&lp->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH) if (atomic_read(&idev->frame_cnt) < ISDN_NET_MAX_QUEUE_LENGTH)
return 0; return 0;
else else
return 1; return 1;
...@@ -81,86 +82,93 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp) ...@@ -81,86 +82,93 @@ static __inline__ int isdn_net_lp_busy(isdn_net_local *lp)
* For the given net device, this will get a non-busy channel out of the * For the given net device, this will get a non-busy channel out of the
* corresponding bundle. The returned channel is locked. * corresponding bundle. The returned channel is locked.
*/ */
static __inline__ isdn_net_local * isdn_net_get_locked_lp(isdn_net_dev *nd) static inline isdn_net_dev *
isdn_net_get_locked_dev(isdn_net_local *mlp)
{ {
unsigned long flags; unsigned long flags;
isdn_net_local *lp; isdn_net_dev *idev;
isdn_net_dev *head;
spin_lock_irqsave(&nd->queue_lock, flags);
lp = nd->queue; /* get lp on top of queue */ spin_lock_irqsave(&mlp->queue_lock, flags);
spin_lock_bh(&nd->queue->xmit_lock); head = mlp->queue;
while (isdn_net_lp_busy(nd->queue)) { idev = head;
spin_unlock_bh(&nd->queue->xmit_lock); spin_lock_bh(&idev->xmit_lock);
nd->queue = nd->queue->next; while (isdn_net_dev_busy(idev)) {
if (nd->queue == lp) { /* not found -- should never happen */ spin_unlock_bh(&idev->xmit_lock);
lp = NULL; mlp->queue = mlp->queue->next;
idev = mlp->queue;
if (idev == head) { /* not found -- should never happen */
idev = NULL;
goto errout; goto errout;
} }
spin_lock_bh(&nd->queue->xmit_lock); spin_lock_bh(&idev->xmit_lock);
} }
lp = nd->queue; idev = mlp->queue;
nd->queue = nd->queue->next; mlp->queue = mlp->queue->next;
errout: errout:
spin_unlock_irqrestore(&nd->queue_lock, flags); spin_unlock_irqrestore(&mlp->queue_lock, flags);
return lp; return idev;
} }
/* /*
* add a channel to a bundle * add a channel to a bundle
*/ */
static __inline__ void isdn_net_add_to_bundle(isdn_net_dev *nd, isdn_net_local *nlp) static inline void
isdn_net_add_to_bundle(isdn_net_local *mlp, isdn_net_dev *idev)
{ {
isdn_net_local *lp; isdn_net_dev *qdev;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&nd->queue_lock, flags); spin_lock_irqsave(&mlp->queue_lock, flags);
lp = nd->queue; qdev = mlp->queue;
nlp->last = lp->last; idev->last = qdev->last;
lp->last->next = nlp; qdev->last->next = idev;
lp->last = nlp; qdev->last = idev;
nlp->next = lp; idev->next = qdev;
nd->queue = nlp; mlp->queue = idev;
spin_unlock_irqrestore(&nd->queue_lock, flags); spin_unlock_irqrestore(&mlp->queue_lock, flags);
} }
/* /*
* remove a channel from the bundle it belongs to * remove a channel from the bundle it belongs to
*/ */
static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp) static inline void
isdn_net_rm_from_bundle(isdn_net_dev *idev)
{ {
isdn_net_local *master_lp = lp; isdn_net_local *mlp;
unsigned long flags; unsigned long flags;
if (lp->master) if (idev->master)
master_lp = (isdn_net_local *) lp->master->priv; mlp = idev->master;
else
mlp = &idev->local;
spin_lock_irqsave(&master_lp->netdev->queue_lock, flags); spin_lock_irqsave(&mlp->queue_lock, flags);
lp->last->next = lp->next; idev->last->next = idev->next;
lp->next->last = lp->last; idev->next->last = idev->last;
if (master_lp->netdev->queue == lp) { if (mlp->queue == idev) {
master_lp->netdev->queue = lp->next; mlp->queue = idev->next;
if (lp->next == lp) { /* last in queue */
master_lp->netdev->queue = &master_lp->netdev->local;
}
} }
lp->next = lp->last = lp; /* (re)set own pointers */ idev->next = idev->last = idev; /* (re)set own pointers */
spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags); spin_unlock_irqrestore(&mlp->queue_lock, flags);
} }
/* /*
* wake up the network -> net_device queue. * wake up the network -> net_device queue.
* For slaves, wake the corresponding master interface. * For slaves, wake the corresponding master interface.
*/ */
static inline void isdn_net_device_wake_queue(isdn_net_local *lp) static inline void
isdn_net_dev_wake_queue(isdn_net_dev *idev)
{ {
if (lp->master) if (idev->master)
netif_wake_queue(lp->master); netif_wake_queue(&idev->master->dev);
else else
netif_wake_queue(&lp->netdev->dev); netif_wake_queue(&idev->local.dev);
} }
static inline int isdn_net_bound(isdn_net_dev *idev) static inline int
isdn_net_bound(isdn_net_dev *idev)
{ {
return idev->isdn_slot >= 0; return idev->isdn_slot >= 0;
} }
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* Prototypes */ /* Prototypes */
static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot); static int isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot);
static int isdn_ppp_closewait(int slot); static int isdn_ppp_closewait(int slot);
static void isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_push_higher(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb, int proto); struct sk_buff *skb, int proto);
static int isdn_ppp_if_get_unit(char *namebuf); static int isdn_ppp_if_get_unit(char *namebuf);
static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *); static int isdn_ppp_set_compressor(struct ippp_struct *is,struct isdn_ppp_comp_data *);
...@@ -59,10 +59,10 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is, ...@@ -59,10 +59,10 @@ static void isdn_ppp_ccp_reset_ack_rcvd(struct ippp_struct *is,
static ippp_bundle * isdn_ppp_bundle_arr = NULL; static ippp_bundle * isdn_ppp_bundle_arr = NULL;
static int isdn_ppp_mp_bundle_array_init(void); static int isdn_ppp_mp_bundle_array_init(void);
static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ); static int isdn_ppp_mp_init(isdn_net_local *lp, ippp_bundle *add_to);
static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb); struct sk_buff *skb);
static void isdn_ppp_mp_cleanup( isdn_net_local * lp ); static void isdn_ppp_mp_cleanup(isdn_net_local *lp );
static int isdn_ppp_bundle(struct ippp_struct *, int unit); static int isdn_ppp_bundle(struct ippp_struct *, int unit);
#endif /* CONFIG_ISDN_MPP */ #endif /* CONFIG_ISDN_MPP */
...@@ -118,7 +118,7 @@ isdn_ppp_free(isdn_net_local * lp) ...@@ -118,7 +118,7 @@ isdn_ppp_free(isdn_net_local * lp)
#ifdef CONFIG_ISDN_MPP #ifdef CONFIG_ISDN_MPP
spin_lock(&lp->netdev->pb->lock); spin_lock(&lp->netdev->pb->lock);
#endif #endif
isdn_net_rm_from_bundle(lp); isdn_net_rm_from_bundle(idev);
#ifdef CONFIG_ISDN_MPP #ifdef CONFIG_ISDN_MPP
if (lp->netdev->pb->ref_ct == 1) /* last link in queue? */ if (lp->netdev->pb->ref_ct == 1) /* last link in queue? */
isdn_ppp_mp_cleanup(lp); isdn_ppp_mp_cleanup(lp);
...@@ -314,8 +314,6 @@ isdn_ppp_open(struct inode *ino, struct file *file) ...@@ -314,8 +314,6 @@ isdn_ppp_open(struct inode *ino, struct file *file)
is->maxcid = 16; /* VJ: maxcid */ is->maxcid = 16; /* VJ: maxcid */
is->tk = current; is->tk = current;
init_waitqueue_head(&is->wq); init_waitqueue_head(&is->wq);
is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
is->last = is->rq;
is->minor = minor; is->minor = minor;
#ifdef CONFIG_ISDN_PPP_VJ #ifdef CONFIG_ISDN_PPP_VJ
/* /*
...@@ -337,7 +335,6 @@ static int ...@@ -337,7 +335,6 @@ static int
isdn_ppp_release(struct inode *ino, struct file *file) isdn_ppp_release(struct inode *ino, struct file *file)
{ {
uint minor = minor(ino->i_rdev) - ISDN_MINOR_PPP; uint minor = minor(ino->i_rdev) - ISDN_MINOR_PPP;
int i;
struct ippp_struct *is; struct ippp_struct *is;
lock_kernel(); lock_kernel();
...@@ -356,14 +353,7 @@ isdn_ppp_release(struct inode *ino, struct file *file) ...@@ -356,14 +353,7 @@ isdn_ppp_release(struct inode *ino, struct file *file)
is->state &= ~IPPP_CONNECT; is->state &= ~IPPP_CONNECT;
isdn_net_hangup(is->idev); isdn_net_hangup(is->idev);
} }
for (i = 0; i < NUM_RCV_BUFFS; i++) { skb_queue_purge(&is->rq);
if (is->rq[i].buf) {
kfree(is->rq[i].buf);
is->rq[i].buf = NULL;
}
}
is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
is->last = is->rq;
#ifdef CONFIG_ISDN_PPP_VJ #ifdef CONFIG_ISDN_PPP_VJ
/* TODO: if this was the previous master: link the slcomp to the new master */ /* TODO: if this was the previous master: link the slcomp to the new master */
...@@ -487,7 +477,7 @@ isdn_ppp_ioctl(struct inode *ino, struct file *file, unsigned int cmd, unsigned ...@@ -487,7 +477,7 @@ isdn_ppp_ioctl(struct inode *ino, struct file *file, unsigned int cmd, unsigned
if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) { if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
if (idev) { if (idev) {
/* OK .. we are ready to send buffers */ /* OK .. we are ready to send buffers */
netif_wake_queue(&idev->dev); netif_wake_queue(&idev->local.dev);
} }
} }
is->pppcfg = val; is->pppcfg = val;
...@@ -595,12 +585,8 @@ static unsigned int ...@@ -595,12 +585,8 @@ static unsigned int
isdn_ppp_poll(struct file *file, poll_table * wait) isdn_ppp_poll(struct file *file, poll_table * wait)
{ {
unsigned int mask; unsigned int mask;
struct ippp_buf_queue *bf;
struct ippp_buf_queue *bl;
unsigned long flags;
struct ippp_struct *is; struct ippp_struct *is;
lock_kernel();
is = file->private_data; is = file->private_data;
if (is->debug & 0x2) if (is->debug & 0x2)
...@@ -622,21 +608,15 @@ isdn_ppp_poll(struct file *file, poll_table * wait) ...@@ -622,21 +608,15 @@ isdn_ppp_poll(struct file *file, poll_table * wait)
/* we're always ready to send .. */ /* we're always ready to send .. */
mask = POLLOUT | POLLWRNORM; mask = POLLOUT | POLLWRNORM;
save_flags(flags);
cli();
bl = is->last;
bf = is->first;
/* /*
* if IPPP_NOBLOCK is set we return even if we have nothing to read * if IPPP_NOBLOCK is set we return even if we have nothing to read
*/ */
if (bf->next != bl || (is->state & IPPP_NOBLOCK)) { if (!skb_queue_empty(&is->rq) || is->state & IPPP_NOBLOCK) {
is->state &= ~IPPP_NOBLOCK; is->state &= ~IPPP_NOBLOCK;
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
} }
restore_flags(flags);
out: out:
unlock_kernel();
return mask; return mask;
} }
...@@ -647,10 +627,8 @@ isdn_ppp_poll(struct file *file, poll_table * wait) ...@@ -647,10 +627,8 @@ isdn_ppp_poll(struct file *file, poll_table * wait)
static int static int
isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot) isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
{ {
struct ippp_buf_queue *bf, struct sk_buff *skb;
*bl; unsigned char *p;
unsigned long flags;
unsigned char *nbuf;
struct ippp_struct *is; struct ippp_struct *is;
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
...@@ -663,36 +641,23 @@ isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot) ...@@ -663,36 +641,23 @@ isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
printk(KERN_DEBUG "ippp: device not activated.\n"); printk(KERN_DEBUG "ippp: device not activated.\n");
return 0; return 0;
} }
nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC); if (skb_queue_len(&is->rq) > IPPP_MAX_RQ_LEN) {
if (!nbuf) { printk(KERN_WARNING "ippp: Queue is full\n");
printk(KERN_WARNING "ippp: Can't alloc buf\n");
return 0; return 0;
} }
nbuf[0] = PPP_ALLSTATIONS; skb = dev_alloc_skb(len + 4);
nbuf[1] = PPP_UI; if (!skb) {
nbuf[2] = proto >> 8; printk(KERN_WARNING "ippp: Can't alloc buf\n");
nbuf[3] = proto & 0xff; return 0;
memcpy(nbuf + 4, buf, len);
save_flags(flags);
cli();
bf = is->first;
bl = is->last;
if (bf == bl) {
printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
bf = bf->next;
kfree(bf->buf);
is->first = bf;
} }
bl->buf = (char *) nbuf; p = skb_put(skb, 4);
bl->len = len + 4; p += put_u8(p, PPP_ALLSTATIONS);
p += put_u8(p, PPP_UI);
is->last = bl->next; p += put_u16(p, proto);
restore_flags(flags); memcpy(skb_put(skb, len), buf, len);
wake_up_interruptible(&is->wq); skb_queue_tail(&is->rq, skb);
wake_up_interruptible(&is->wq);
return len; return len;
} }
...@@ -706,54 +671,36 @@ static ssize_t ...@@ -706,54 +671,36 @@ static ssize_t
isdn_ppp_read(struct file *file, char *buf, size_t count, loff_t *off) isdn_ppp_read(struct file *file, char *buf, size_t count, loff_t *off)
{ {
struct ippp_struct *is; struct ippp_struct *is;
struct ippp_buf_queue *b; struct sk_buff *skb;
unsigned long flags;
unsigned char *save_buf;
int retval; int retval;
if (off != &file->f_pos) if (off != &file->f_pos)
return -ESPIPE; return -ESPIPE;
lock_kernel();
is = file->private_data; is = file->private_data;
if (!(is->state & IPPP_OPEN)) { if (!(is->state & IPPP_OPEN)) {
retval = 0; retval = 0;
goto out; goto out;
} }
retval = verify_area(VERIFY_WRITE, (void *) buf, count); skb = skb_dequeue(&is->rq);
if (retval) if (!skb) {
goto out;
save_flags(flags);
cli();
b = is->first->next;
save_buf = b->buf;
if (!save_buf) {
restore_flags(flags);
retval = -EAGAIN; retval = -EAGAIN;
goto out; goto out;
} }
if (b->len < count) if (skb->len > count) {
count = b->len; retval = -EMSGSIZE;
b->buf = NULL; goto out_free;
is->first = b; }
if (copy_to_user(buf, skb->data, skb->len)) {
restore_flags(flags);
if (copy_to_user(buf, save_buf, count)) {
kfree(save_buf);
retval = -EFAULT; retval = -EFAULT;
goto out; goto out_free;
} }
kfree(save_buf); retval = skb->len;
retval = count;
out_free:
dev_kfree_skb(skb);
out: out:
unlock_kernel();
return retval; return retval;
} }
...@@ -834,7 +781,7 @@ isdn_ppp_write(struct file *file, const char *buf, size_t count, loff_t *off) ...@@ -834,7 +781,7 @@ isdn_ppp_write(struct file *file, const char *buf, size_t count, loff_t *off)
isdn_ppp_send_ccp(idev,&idev->local,skb); /* keeps CCP/compression states in sync */ isdn_ppp_send_ccp(idev,&idev->local,skb); /* keeps CCP/compression states in sync */
isdn_net_write_super(&idev->local, skb); isdn_net_write_super(idev, skb);
} }
} }
retval = count; retval = count;
...@@ -881,15 +828,7 @@ isdn_ppp_init(void) ...@@ -881,15 +828,7 @@ isdn_ppp_init(void)
} }
memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct)); memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
ippp_table[i]->state = 0; ippp_table[i]->state = 0;
ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1; skb_queue_head_init(&ippp_table[i]->rq);
ippp_table[i]->last = ippp_table[i]->rq;
for (j = 0; j < NUM_RCV_BUFFS; j++) {
ippp_table[i]->rq[j].buf = NULL;
ippp_table[i]->rq[j].last = ippp_table[i]->rq +
(NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
}
} }
return 0; return 0;
} }
...@@ -963,10 +902,9 @@ static int isdn_ppp_strip_proto(struct sk_buff *skb) ...@@ -963,10 +902,9 @@ static int isdn_ppp_strip_proto(struct sk_buff *skb)
/* /*
* handler for incoming packets on a syncPPP interface * handler for incoming packets on a syncPPP interface
*/ */
static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, static void isdn_ppp_receive(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_dev *idev = lp->netdev;
struct ippp_struct *is; struct ippp_struct *is;
int slot; int slot;
int proto; int proto;
...@@ -976,7 +914,7 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -976,7 +914,7 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
* huptimer on LCP packets. * huptimer on LCP packets.
*/ */
if (PPP_PROTOCOL(skb->data) != PPP_LCP) if (PPP_PROTOCOL(skb->data) != PPP_LCP)
isdn_net_reset_huptimer(net_dev,lp->netdev); isdn_net_reset_huptimer(lp, idev);
slot = idev->ppp_slot; slot = idev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
...@@ -1012,12 +950,12 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -1012,12 +950,12 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP if (!(is->mpppcfg & SC_REJ_MP_PROT)) { // we agreed to receive MPPP
if (proto == PPP_MP) { if (proto == PPP_MP) {
isdn_ppp_mp_receive(net_dev, lp, skb); isdn_ppp_mp_receive(lp, idev, skb);
return; return;
} }
} }
#endif #endif
isdn_ppp_push_higher(net_dev, lp, skb, proto); isdn_ppp_push_higher(lp, idev, skb, proto);
} }
/* /*
...@@ -1026,10 +964,10 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -1026,10 +964,10 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
* note: net_dev has to be master net_dev * note: net_dev has to be master net_dev
*/ */
static void static void
isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb, int proto) isdn_ppp_push_higher(isdn_net_local *lp, isdn_net_dev *idev,
struct sk_buff *skb, int proto)
{ {
isdn_net_dev *idev = lp->netdev; struct net_device *dev = &lp->dev;
struct net_device *dev = &net_dev->dev;
struct ippp_struct *is, *mis; struct ippp_struct *is, *mis;
int slot; int slot;
...@@ -1041,8 +979,8 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1041,8 +979,8 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
} }
is = ippp_table[slot]; is = ippp_table[slot];
if (lp->master) { // FIXME? if (idev->master) { // FIXME?
slot = ((isdn_net_local *) (lp->master->priv))->netdev->ppp_slot; slot = idev->master->netdev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n", printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
slot); slot);
...@@ -1079,12 +1017,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1079,12 +1017,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
case PPP_VJC_UNCOMP: case PPP_VJC_UNCOMP:
if (is->debug & 0x20) if (is->debug & 0x20)
printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n"); printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
if (net_dev->ppp_slot < 0) { if (lp->netdev->ppp_slot < 0) {
printk(KERN_ERR "%s: net_dev->ppp_slot(%d) out of range\n", printk(KERN_ERR "%s: net_dev->ppp_slot(%d) out of range\n",
__FUNCTION__ , net_dev->ppp_slot); __FUNCTION__ , lp->netdev->ppp_slot);
goto drop_packet; goto drop_packet;
} }
if (slhc_remember(ippp_table[net_dev->ppp_slot]->slcomp, skb->data, skb->len) <= 0) { if (slhc_remember(ippp_table[lp->netdev->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n"); printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
goto drop_packet; goto drop_packet;
} }
...@@ -1105,12 +1043,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1105,12 +1043,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
} }
skb_put(skb, skb_old->len + 128); skb_put(skb, skb_old->len + 128);
memcpy(skb->data, skb_old->data, skb_old->len); memcpy(skb->data, skb_old->data, skb_old->len);
if (net_dev->ppp_slot < 0) { if (lp->netdev->ppp_slot < 0) {
printk(KERN_ERR "%s: net_dev->ppp_slot(%d) out of range\n", printk(KERN_ERR "%s: net_dev->ppp_slot(%d) out of range\n",
__FUNCTION__ , net_dev->ppp_slot); __FUNCTION__ , lp->netdev->ppp_slot);
goto drop_packet; goto drop_packet;
} }
pkt_len = slhc_uncompress(ippp_table[net_dev->ppp_slot]->slcomp, pkt_len = slhc_uncompress(ippp_table[lp->netdev->ppp_slot]->slcomp,
skb->data, skb_old->len); skb->data, skb_old->len);
kfree_skb(skb_old); kfree_skb(skb_old);
if (pkt_len < 0) if (pkt_len < 0)
...@@ -1123,7 +1061,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1123,7 +1061,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
#endif #endif
case PPP_CCP: case PPP_CCP:
case PPP_CCPFRAG: case PPP_CCPFRAG:
isdn_ppp_receive_ccp(net_dev,lp,skb,proto); isdn_ppp_receive_ccp(lp->netdev,lp,skb,proto);
/* Dont pop up ResetReq/Ack stuff to the daemon any /* Dont pop up ResetReq/Ack stuff to the daemon any
longer - the job is done already */ longer - the job is done already */
if(skb->data[0] == CCP_RESETREQ || if(skb->data[0] == CCP_RESETREQ ||
...@@ -1146,7 +1084,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1146,7 +1084,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
return; return;
drop_packet: drop_packet:
net_dev->local.stats.rx_dropped++; lp->stats.rx_dropped++;
kfree_skb(skb); kfree_skb(skb);
} }
...@@ -1187,14 +1125,14 @@ static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len) ...@@ -1187,14 +1125,14 @@ static unsigned char *isdn_ppp_skb_push(struct sk_buff **skb_p,int len)
int int
isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
{ {
isdn_net_local *lp,*mlp; isdn_net_local *mlp;
isdn_net_dev *idev; isdn_net_dev *idev;
isdn_net_dev *nd; isdn_net_dev *nd;
unsigned int proto = PPP_IP; /* 0x21 */ unsigned int proto = PPP_IP; /* 0x21 */
struct ippp_struct *ipt,*ipts; struct ippp_struct *ipt,*ipts;
int slot; int slot;
mlp = (isdn_net_local *) (netdev->priv); mlp = netdev->priv;
nd = mlp->netdev; /* get master lp */ nd = mlp->netdev; /* get master lp */
slot = nd->ppp_slot; slot = nd->ppp_slot;
...@@ -1226,13 +1164,12 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1226,13 +1164,12 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
return 0; return 0;
} }
lp = isdn_net_get_locked_lp(nd); idev = isdn_net_get_locked_dev(mlp);
if (!lp) { if (!idev) {
printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name); printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
return 1; return 1;
} }
/* we have our lp locked from now on */ /* we have our lp locked from now on */
idev = lp->netdev;
slot = idev->ppp_slot; slot = idev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n", printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
...@@ -1385,10 +1322,10 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1385,10 +1322,10 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,idev->ppp_slot); isdn_ppp_frame_log("xmit", skb->data, skb->len, 32,ipt->unit,idev->ppp_slot);
} }
isdn_net_writebuf_skb(lp, skb); isdn_net_writebuf_skb(idev, skb);
unlock: unlock:
spin_unlock_bh(&lp->xmit_lock); spin_unlock_bh(&idev->xmit_lock);
return 0; return 0;
} }
...@@ -1459,7 +1396,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) ...@@ -1459,7 +1396,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
is->mp_seqno = 0; is->mp_seqno = 0;
if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
return -ENOMEM; return -ENOMEM;
lp->next = lp->last = lp; /* nobody else in a queue */ idev->next = idev->last = idev; /* nobody else in a queue */
lp->netdev->pb->frags = NULL; lp->netdev->pb->frags = NULL;
lp->netdev->pb->frames = 0; lp->netdev->pb->frames = 0;
lp->netdev->pb->seq = LONG_MAX; lp->netdev->pb->seq = LONG_MAX;
...@@ -1479,12 +1416,12 @@ static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1479,12 +1416,12 @@ static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, static void isdn_ppp_mp_receive(isdn_net_local *lp, isdn_net_dev *dev,
struct sk_buff *skb) struct sk_buff *skb)
{ {
isdn_net_dev *idev = lp->netdev; isdn_net_dev *idev = lp->netdev;
struct ippp_struct *is; struct ippp_struct *is;
isdn_net_local * lpq; isdn_net_dev *qdev;
ippp_bundle * mp; ippp_bundle * mp;
isdn_mppp_stats * stats; isdn_mppp_stats * stats;
struct sk_buff * newfrag, * frag, * start, *nextf; struct sk_buff * newfrag, * frag, * start, *nextf;
...@@ -1492,8 +1429,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1492,8 +1429,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
unsigned long flags; unsigned long flags;
int slot; int slot;
spin_lock_irqsave(&net_dev->pb->lock, flags); spin_lock_irqsave(&lp->netdev->pb->lock, flags);
mp = net_dev->pb; mp = lp->netdev->pb;
stats = &mp->stats; stats = &mp->stats;
slot = idev->ppp_slot; slot = idev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
...@@ -1531,8 +1468,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1531,8 +1468,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
/* find the minimum received sequence number over all links */ /* find the minimum received sequence number over all links */
is->last_link_seqno = minseq = newseq; is->last_link_seqno = minseq = newseq;
for (lpq = net_dev->queue;;) { for (qdev = lp->queue;;) {
slot = lpq->netdev->ppp_slot; slot = qdev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n", printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n",
__FUNCTION__ ,slot); __FUNCTION__ ,slot);
...@@ -1541,7 +1478,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1541,7 +1478,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
if (MP_LT(lls, minseq)) if (MP_LT(lls, minseq))
minseq = lls; minseq = lls;
} }
if ((lpq = lpq->next) == net_dev->queue) if ((qdev = qdev->next) == lp->queue)
break; break;
} }
if (MP_LT(minseq, mp->seq)) if (MP_LT(minseq, mp->seq))
...@@ -1631,7 +1568,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1631,7 +1568,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
/* Reassemble the packet then dispatch it */ /* Reassemble the packet then dispatch it */
isdn_ppp_mp_reassembly(net_dev, lp, start, nextf); isdn_ppp_mp_reassembly(lp->netdev, lp, start, nextf);
start = NULL; start = NULL;
frag = NULL; frag = NULL;
...@@ -1808,7 +1745,7 @@ void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1808,7 +1745,7 @@ void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
} }
} }
proto = isdn_ppp_strip_proto(skb); proto = isdn_ppp_strip_proto(skb);
isdn_ppp_push_higher(net_dev, lp, skb, proto); isdn_ppp_push_higher(lp, idev, skb, proto);
} }
static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb) static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
...@@ -1844,7 +1781,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit) ...@@ -1844,7 +1781,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit)
spin_lock_irqsave(&p->pb->lock, flags); spin_lock_irqsave(&p->pb->lock, flags);
nidev = is->idev; nidev = is->idev;
idev = p->queue->netdev; idev = p->local.queue;
if( nidev->ppp_slot < 0 || nidev->ppp_slot >= ISDN_MAX_CHANNELS || if( nidev->ppp_slot < 0 || nidev->ppp_slot >= ISDN_MAX_CHANNELS ||
idev ->ppp_slot < 0 || idev ->ppp_slot >= ISDN_MAX_CHANNELS ) { idev ->ppp_slot < 0 || idev ->ppp_slot >= ISDN_MAX_CHANNELS ) {
printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n", printk(KERN_ERR "ippp_bundle: binding to invalid slot %d\n",
...@@ -1854,7 +1791,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit) ...@@ -1854,7 +1791,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit)
goto out; goto out;
} }
isdn_net_add_to_bundle(p, &nidev->local); isdn_net_add_to_bundle(&p->local, nidev);
ippp_table[nidev->ppp_slot]->unit = ippp_table[idev->ppp_slot]->unit; ippp_table[nidev->ppp_slot]->unit = ippp_table[idev->ppp_slot]->unit;
...@@ -1978,7 +1915,7 @@ isdn_ppp_dial_slave(char *name) ...@@ -1978,7 +1915,7 @@ isdn_ppp_dial_slave(char *name)
#ifdef CONFIG_ISDN_MPP #ifdef CONFIG_ISDN_MPP
isdn_net_dev *idev; isdn_net_dev *idev;
isdn_net_local *lp; isdn_net_local *lp;
struct net_device *sdev; isdn_net_dev *sdev;
idev = isdn_net_findif(name); idev = isdn_net_findif(name);
if (!idev) if (!idev)
...@@ -1988,17 +1925,16 @@ isdn_ppp_dial_slave(char *name) ...@@ -1988,17 +1925,16 @@ isdn_ppp_dial_slave(char *name)
if (!isdn_net_bound(idev)) if (!isdn_net_bound(idev))
return 5; return 5;
sdev = lp->slave; sdev = idev->slave;
while (sdev) { while (sdev) {
isdn_net_local *mlp = (isdn_net_local *) sdev->priv; if (!isdn_net_bound(sdev))
if (!isdn_net_bound(mlp->netdev))
break; break;
sdev = mlp->slave; sdev = sdev->slave;
} }
if (!sdev) if (!sdev)
return 2; return 2;
isdn_net_dial_req((isdn_net_local *) sdev->priv); isdn_net_dial_req(sdev);
return 0; return 0;
#else #else
return -1; return -1;
...@@ -2009,35 +1945,20 @@ int ...@@ -2009,35 +1945,20 @@ int
isdn_ppp_hangup_slave(char *name) isdn_ppp_hangup_slave(char *name)
{ {
#ifdef CONFIG_ISDN_MPP #ifdef CONFIG_ISDN_MPP
isdn_net_dev *idev; isdn_net_dev *idev, *sdev;
isdn_net_local *lp, *mlp = NULL;
struct net_device *sdev;
idev = isdn_net_findif(name); idev = isdn_net_findif(name);
if (!idev) if (!idev)
return 1; return 1;
lp = &idev->local;
if (!isdn_net_bound(idev)) if (!isdn_net_bound(idev))
return 5; return 5;
sdev = lp->slave; sdev = idev->slave;
while (sdev) { if (!sdev || !isdn_net_bound(sdev))
mlp = (isdn_net_local *) sdev->priv;
if (mlp->slave) { /* find last connected link in chain */
isdn_net_local *nlp = (isdn_net_local *) mlp->slave->priv;
if (!isdn_net_bound(nlp->netdev))
break;
} else if (isdn_net_bound(mlp->netdev))
break;
sdev = mlp->slave;
}
if (!sdev)
return 2; return 2;
isdn_net_hangup(mlp->netdev); isdn_net_hangup(sdev);
return 0; return 0;
#else #else
return -1; return -1;
...@@ -2139,7 +2060,7 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto, ...@@ -2139,7 +2060,7 @@ static void isdn_ppp_ccp_xmit_reset(struct ippp_struct *is, int proto,
printk(KERN_DEBUG "Sending CCP Frame:\n"); printk(KERN_DEBUG "Sending CCP Frame:\n");
isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,idev->ppp_slot); isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,idev->ppp_slot);
isdn_net_write_super(&idev->local, skb); isdn_net_write_super(idev, skb);
} }
/* Allocate the reset state vector */ /* Allocate the reset state vector */
...@@ -2557,8 +2478,8 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -2557,8 +2478,8 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
is = ippp_table[idev->ppp_slot]; is = ippp_table[idev->ppp_slot];
isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,idev->ppp_slot); isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,idev->ppp_slot);
if(lp->master) { if (idev->master) {
int slot = ((isdn_net_local *) (lp->master->priv))->netdev->ppp_slot; int slot = idev->master->netdev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: slot(%d) out of range\n", printk(KERN_ERR "%s: slot(%d) out of range\n",
__FUNCTION__ , slot); __FUNCTION__ , slot);
...@@ -2745,8 +2666,8 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct ...@@ -2745,8 +2666,8 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct
printk(KERN_DEBUG "Received CCP frame from daemon:\n"); printk(KERN_DEBUG "Received CCP frame from daemon:\n");
isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,idev->ppp_slot); isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,idev->ppp_slot);
if (lp->master) { if (idev->master) {
slot = ((isdn_net_local *) (lp->master->priv))->netdev->ppp_slot; slot = idev->master->netdev->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) { if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: slot(%d) out of range\n", printk(KERN_ERR "%s: slot(%d) out of range\n",
__FUNCTION__ , slot); __FUNCTION__ , slot);
......
...@@ -294,8 +294,8 @@ struct isdn_netif_ops { ...@@ -294,8 +294,8 @@ struct isdn_netif_ops {
unsigned short flags; /* interface flags (a la BSD) */ unsigned short flags; /* interface flags (a la BSD) */
unsigned short type; /* interface hardware type */ unsigned short type; /* interface hardware type */
unsigned char addr_len;/* hardware address length */ unsigned char addr_len;/* hardware address length */
void (*receive)(struct isdn_net_dev_s *p, void (*receive)(struct isdn_net_local_s *lp,
struct isdn_net_local_s *olp, struct isdn_net_dev_s *idev,
struct sk_buff *skb); struct sk_buff *skb);
void (*connected)(struct isdn_net_local_s *lp); void (*connected)(struct isdn_net_local_s *lp);
void (*disconnected)(struct isdn_net_local_s *lp); void (*disconnected)(struct isdn_net_local_s *lp);
...@@ -329,26 +329,17 @@ typedef struct isdn_net_local_s { ...@@ -329,26 +329,17 @@ typedef struct isdn_net_local_s {
u_char l2_proto; /* Layer-2-protocol */ u_char l2_proto; /* Layer-2-protocol */
u_char l3_proto; /* Layer-3-protocol */ u_char l3_proto; /* Layer-3-protocol */
int sqfull; /* Flag: netdev-queue overloaded */
ulong sqfull_stamp; /* Start-Time of overload */
ulong slavedelay; /* Dynamic bundling delaytime */ ulong slavedelay; /* Dynamic bundling delaytime */
int triggercps; /* BogoCPS needed for trigger slave */ int triggercps; /* BogoCPS needed for trigger slave */
struct list_head phone[2]; /* List of remote-phonenumbers */ struct list_head phone[2]; /* List of remote-phonenumbers */
/* phone[0] = Incoming Numbers */ /* phone[0] = Incoming Numbers */
/* phone[1] = Outgoing Numbers */ /* phone[1] = Outgoing Numbers */
struct net_device *master; /* Ptr to Master device for slaves */
struct net_device *slave; /* Ptr to Slave device for masters */
struct isdn_net_local_s *next; /* Ptr to next link in bundle */
struct isdn_net_local_s *last; /* Ptr to last link in bundle */
struct isdn_net_dev_s *netdev; /* Ptr to netdev */ struct isdn_net_dev_s *netdev; /* Ptr to netdev */
struct sk_buff_head super_tx_queue; /* List of supervisory frames to */
/* be transmitted asap */ struct isdn_net_dev_s *queue; /* circular list of all bundled
atomic_t frame_cnt; /* number of frames currently */ channels, which are currently
/* queued in HL driver */ online */
/* Ptr to orig. hard_header_cache */ spinlock_t queue_lock; /* lock to protect queue */
spinlock_t xmit_lock; /* used to protect the xmit path of */
/* a particular channel (including */
/* the frame_cnt */
#ifdef CONFIG_ISDN_X25 #ifdef CONFIG_ISDN_X25
struct concap_device_ops *dops; /* callbacks used by encapsulator */ struct concap_device_ops *dops; /* callbacks used by encapsulator */
...@@ -361,9 +352,11 @@ typedef struct isdn_net_local_s { ...@@ -361,9 +352,11 @@ typedef struct isdn_net_local_s {
ulong cisco_last_slarp_in; /* jiffie of last keepalive packet we received */ ulong cisco_last_slarp_in; /* jiffie of last keepalive packet we received */
char cisco_line_state; /* state of line according to keepalive packets */ char cisco_line_state; /* state of line according to keepalive packets */
char cisco_debserint; /* debugging flag of cisco hdlc with slarp */ char cisco_debserint; /* debugging flag of cisco hdlc with slarp */
struct timer_list cisco_timer; struct timer_list cisco_timer;
struct tq_struct tqueue;
struct isdn_netif_ops *ops; struct isdn_netif_ops *ops;
struct net_device dev; /* interface to upper levels */
} isdn_net_local; } isdn_net_local;
/* the interface itself */ /* the interface itself */
...@@ -386,6 +379,8 @@ typedef struct isdn_net_dev_s { ...@@ -386,6 +379,8 @@ typedef struct isdn_net_dev_s {
int cps; /* current speed of this interface */ int cps; /* current speed of this interface */
int transcount; /* byte-counter for cps-calculation */ int transcount; /* byte-counter for cps-calculation */
int last_jiffies; /* when transcount was reset */ int last_jiffies; /* when transcount was reset */
int sqfull; /* Flag: netdev-queue overloaded */
ulong sqfull_stamp; /* Start-Time of overload */
struct timer_list hup_timer; /* auto hangup timer */ struct timer_list hup_timer; /* auto hangup timer */
int huptimer; /* Timeout-counter for auto-hangup */ int huptimer; /* Timeout-counter for auto-hangup */
...@@ -397,13 +392,24 @@ typedef struct isdn_net_dev_s { ...@@ -397,13 +392,24 @@ typedef struct isdn_net_dev_s {
int pppbind; /* ippp device for bindings */ int pppbind; /* ippp device for bindings */
int ppp_slot; /* PPPD device slot number */ int ppp_slot; /* PPPD device slot number */
isdn_net_local *queue; /* circular list of all bundled spinlock_t xmit_lock; /* used to protect the xmit path of */
channels, which are currently /* a particular channel (including */
online */ /* the frame_cnt */
spinlock_t queue_lock; /* lock to protect queue */ struct sk_buff_head super_tx_queue; /* List of supervisory frames to */
/* be transmitted asap */
atomic_t frame_cnt; /* number of frames currently */
/* queued in HL driver */
struct tq_struct tqueue;
isdn_net_local *master; /* Ptr to Master device for slaves */
struct isdn_net_dev_s *slave; /* Ptr to Slave device for masters */
struct isdn_net_dev_s *next; /* Ptr to next link in bundle */
struct isdn_net_dev_s *last; /* Ptr to last link in bundle */
char name[10]; /* Name of device */ char name[10]; /* Name of device */
struct list_head global_list; /* global list of all isdn_net_devs */ struct list_head global_list; /* global list of all isdn_net_devs */
struct net_device dev; /* interface to upper levels */
#ifdef CONFIG_ISDN_PPP #ifdef CONFIG_ISDN_PPP
ippp_bundle * pb; /* pointer to the common bundle structure ippp_bundle * pb; /* pointer to the common bundle structure
* with the per-bundle data */ * with the per-bundle data */
......
...@@ -159,14 +159,7 @@ typedef struct { ...@@ -159,14 +159,7 @@ typedef struct {
isdn_mppp_stats stats; isdn_mppp_stats stats;
} ippp_bundle; } ippp_bundle;
#define NUM_RCV_BUFFS 64 #define IPPP_MAX_RQ_LEN 8
struct ippp_buf_queue {
struct ippp_buf_queue *next;
struct ippp_buf_queue *last;
char *buf; /* NULL here indicates end of queue */
int len;
};
/* The data structure for one CCP reset transaction */ /* The data structure for one CCP reset transaction */
enum ippp_ccp_reset_states { enum ippp_ccp_reset_states {
...@@ -201,9 +194,7 @@ struct ippp_ccp_reset { ...@@ -201,9 +194,7 @@ struct ippp_ccp_reset {
struct ippp_struct { struct ippp_struct {
struct ippp_struct *next_link; struct ippp_struct *next_link;
int state; int state;
struct ippp_buf_queue rq[NUM_RCV_BUFFS]; /* packet queue for isdn_ppp_read() */ struct sk_buff_head rq;
struct ippp_buf_queue *first; /* pointer to (current) first packet */
struct ippp_buf_queue *last; /* pointer to (current) last used packet in queue */
wait_queue_head_t wq; wait_queue_head_t wq;
struct task_struct *tk; struct task_struct *tk;
unsigned int mpppcfg; unsigned int mpppcfg;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment