Commit 0066476b authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: More sorting out of members for isdn_net_local / isdn_net_dev

There is a one-to-one relation between struct net_device and
isdn_net_local, so reflect that in the declaration. There is
one list of active channels per network interface, so put
the list head into isdn_net_local, the list members are isdn_net_dev's.
parent 2f1efd68
...@@ -240,7 +240,7 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp) ...@@ -240,7 +240,7 @@ isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
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) {
...@@ -337,10 +337,9 @@ isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb) ...@@ -337,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;
...@@ -373,7 +372,7 @@ isdn_ciscohdlck_receive(isdn_net_dev *idev, isdn_net_local *olp, ...@@ -373,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;
......
...@@ -93,15 +93,15 @@ LIST_HEAD(isdn_net_devs); /* Linked list of isdn_net_dev's */ ...@@ -93,15 +93,15 @@ LIST_HEAD(isdn_net_devs); /* Linked list of isdn_net_dev's */
* For slaves, look at the corresponding master. * For slaves, look at the corresponding master.
*/ */
static inline int static inline int
isdn_net_device_started(isdn_net_dev *n) 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);
} }
...@@ -112,12 +112,10 @@ isdn_net_device_started(isdn_net_dev *n) ...@@ -112,12 +112,10 @@ isdn_net_device_started(isdn_net_dev *n)
static inline void static inline void
isdn_net_dev_stop_queue(isdn_net_dev *idev) isdn_net_dev_stop_queue(isdn_net_dev *idev)
{ {
isdn_net_local *lp = &idev->local; if (idev->master)
netif_stop_queue(&idev->master->dev);
if (lp->master)
netif_stop_queue(lp->master);
else else
netif_stop_queue(&lp->netdev->dev); netif_stop_queue(&idev->local.dev);
} }
/* /*
...@@ -128,30 +126,28 @@ isdn_net_dev_stop_queue(isdn_net_dev *idev) ...@@ -128,30 +126,28 @@ isdn_net_dev_stop_queue(isdn_net_dev *idev)
static inline int static inline int
isdn_net_device_busy(isdn_net_dev *idev) isdn_net_device_busy(isdn_net_dev *idev)
{ {
isdn_net_local *lp, *nlp; isdn_net_dev *ndev;
isdn_net_dev *nd; isdn_net_local *mlp;
unsigned long flags; unsigned long flags;
if (!isdn_net_dev_busy(idev)) if (!isdn_net_dev_busy(idev))
return 0; return 0;
lp = &idev->local; if (idev->master)
mlp = idev->master;
if (lp->master)
nd = ((isdn_net_local *) lp->master->priv)->netdev;
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_dev_busy(nlp->netdev)) { 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;
} }
...@@ -281,12 +277,12 @@ isdn_net_unbind_channel(isdn_net_local * lp) ...@@ -281,12 +277,12 @@ isdn_net_unbind_channel(isdn_net_local * lp)
skb_queue_purge(&idev->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) {
...@@ -386,23 +382,23 @@ static void isdn_net_hup_timer(unsigned long data) ...@@ -386,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);
...@@ -580,7 +576,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -580,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,
...@@ -647,7 +643,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -647,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);
...@@ -686,7 +682,7 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg) ...@@ -686,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);
...@@ -726,21 +722,20 @@ isdn_net_hangup(isdn_net_dev *idev) ...@@ -726,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);
...@@ -947,23 +942,18 @@ void isdn_net_writebuf_skb(isdn_net_dev *idev, struct sk_buff *skb) ...@@ -947,23 +942,18 @@ void isdn_net_writebuf_skb(isdn_net_dev *idev, 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;
idev = isdn_net_get_locked_dev(nd); idev = isdn_net_get_locked_dev(mlp);
if (!idev) { 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;
...@@ -990,7 +980,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) ...@@ -990,7 +980,7 @@ 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 (!idev->sqfull) { if (!idev->sqfull) {
/* First time overload: set timestamp only */ /* First time overload: set timestamp only */
idev->sqfull = 1; idev->sqfull = 1;
...@@ -998,9 +988,9 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) ...@@ -998,9 +988,9 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
} else { } else {
/* subsequent overload: if slavedelay exceeded, start dialing */ /* subsequent overload: if slavedelay exceeded, start dialing */
if (time_after(jiffies, idev->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_idev(((isdn_net_local *) lp->slave->priv)->netdev); isdn_net_force_dial_idev(sdev);
} }
} }
} }
...@@ -1010,7 +1000,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) ...@@ -1010,7 +1000,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
idev->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;
...@@ -1124,18 +1114,19 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) ...@@ -1124,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;
} }
...@@ -1154,31 +1145,29 @@ isdn_net_get_stats(struct net_device *dev) ...@@ -1154,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);
} }
/* /*
...@@ -1197,7 +1186,7 @@ isdn_net_rcv_skb(int idx, struct sk_buff *skb) ...@@ -1197,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;
} }
...@@ -1405,23 +1394,23 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup) ...@@ -1405,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;
} }
} }
...@@ -1557,6 +1546,7 @@ int ...@@ -1557,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 */
...@@ -1570,29 +1560,25 @@ isdn_net_new(char *name, struct net_device *master) ...@@ -1570,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);
...@@ -1601,12 +1587,12 @@ isdn_net_new(char *name, struct net_device *master) ...@@ -1601,12 +1587,12 @@ 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->tqueue.sync = 0; netdev->tqueue.sync = 0;
netdev->tqueue.routine = isdn_net_softint; netdev->tqueue.routine = isdn_net_softint;
...@@ -1669,19 +1655,19 @@ isdn_net_newslave(char *parm) ...@@ -1669,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){
...@@ -1689,7 +1675,7 @@ isdn_net_set_encap(isdn_net_dev *p, int encap) ...@@ -1689,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;
} }
...@@ -1706,11 +1692,11 @@ isdn_net_set_encap(isdn_net_dev *p, int encap) ...@@ -1706,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);
...@@ -1941,12 +1927,12 @@ isdn_net_getcfg(isdn_net_ioctl_cfg * cfg) ...@@ -1941,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';
...@@ -2103,7 +2089,7 @@ int ...@@ -2103,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;
...@@ -2111,11 +2097,11 @@ isdn_net_force_hangup(char *name) ...@@ -2111,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;
...@@ -2142,19 +2128,19 @@ isdn_net_realrm(isdn_net_dev *p) ...@@ -2142,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) {
...@@ -2204,7 +2190,7 @@ isdn_net_rmall(void) ...@@ -2204,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;
...@@ -2229,10 +2215,10 @@ isdn_iptyp_header(struct sk_buff *skb, struct net_device *dev, ...@@ -2229,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);
...@@ -2260,10 +2246,10 @@ isdn_uihdlc_header(struct sk_buff *skb, struct net_device *dev, ...@@ -2260,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);
...@@ -2282,10 +2268,10 @@ static struct isdn_netif_ops uihdlc_ops = { ...@@ -2282,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);
} }
...@@ -2355,10 +2341,10 @@ isdn_eth_type_trans(struct sk_buff *skb, struct net_device *dev) ...@@ -2355,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);
} }
...@@ -2366,7 +2352,7 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp, ...@@ -2366,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;
...@@ -2386,7 +2372,7 @@ isdn_ether_open(isdn_net_local *lp) ...@@ -2386,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;
......
...@@ -58,10 +58,10 @@ extern void isdn_net_write_super(isdn_net_dev *, struct sk_buff *skb); ...@@ -58,10 +58,10 @@ extern void isdn_net_write_super(isdn_net_dev *, struct sk_buff *skb);
extern int isdn_net_online(isdn_net_dev *); 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
...@@ -83,76 +83,75 @@ isdn_net_dev_busy(isdn_net_dev *idev) ...@@ -83,76 +83,75 @@ isdn_net_dev_busy(isdn_net_dev *idev)
* corresponding bundle. The returned channel is locked. * corresponding bundle. The returned channel is locked.
*/ */
static inline isdn_net_dev * static inline isdn_net_dev *
isdn_net_get_locked_dev(isdn_net_dev *nd) 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 *idev;
isdn_net_dev *head;
spin_lock_irqsave(&nd->queue_lock, flags); spin_lock_irqsave(&mlp->queue_lock, flags);
lp = nd->queue; /* get lp on top of queue */ head = mlp->queue;
idev = nd->queue->netdev; idev = head;
spin_lock_bh(&idev->xmit_lock); spin_lock_bh(&idev->xmit_lock);
while (isdn_net_dev_busy(idev)) { while (isdn_net_dev_busy(idev)) {
spin_unlock_bh(&idev->xmit_lock); spin_unlock_bh(&idev->xmit_lock);
nd->queue = nd->queue->next; mlp->queue = mlp->queue->next;
idev = nd->queue->netdev; idev = mlp->queue;
if (nd->queue == lp) { /* not found -- should never happen */ if (idev == head) { /* not found -- should never happen */
lp = NULL; idev = NULL;
goto errout; goto errout;
} }
spin_lock_bh(&idev->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 ? lp->netdev : NULL; return idev;
} }
/* /*
* add a channel to a bundle * add a channel to a bundle
*/ */
static inline void static inline void
isdn_net_add_to_bundle(isdn_net_dev *nd, isdn_net_local *nlp) 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 static inline void
isdn_net_rm_from_bundle(isdn_net_local *lp) 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);
} }
/* /*
...@@ -162,12 +161,10 @@ isdn_net_rm_from_bundle(isdn_net_local *lp) ...@@ -162,12 +161,10 @@ isdn_net_rm_from_bundle(isdn_net_local *lp)
static inline void static inline void
isdn_net_dev_wake_queue(isdn_net_dev *idev) isdn_net_dev_wake_queue(isdn_net_dev *idev)
{ {
isdn_net_local *lp = &idev->local; if (idev->master)
netif_wake_queue(&idev->master->dev);
if (lp->master)
netif_wake_queue(lp->master);
else else
netif_wake_queue(&lp->netdev->dev); netif_wake_queue(&idev->local.dev);
} }
static inline int static inline int
......
...@@ -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);
...@@ -477,7 +477,7 @@ isdn_ppp_ioctl(struct inode *ino, struct file *file, unsigned int cmd, unsigned ...@@ -477,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;
...@@ -902,10 +902,9 @@ static int isdn_ppp_strip_proto(struct sk_buff *skb) ...@@ -902,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;
...@@ -915,7 +914,7 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -915,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) {
...@@ -951,12 +950,12 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -951,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);
} }
/* /*
...@@ -965,10 +964,10 @@ static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -965,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;
...@@ -980,8 +979,8 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -980,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);
...@@ -1018,12 +1017,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1018,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;
} }
...@@ -1044,12 +1043,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1044,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)
...@@ -1062,7 +1061,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1062,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 ||
...@@ -1085,7 +1084,7 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff ...@@ -1085,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);
} }
...@@ -1133,7 +1132,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1133,7 +1132,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
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;
...@@ -1165,7 +1164,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) ...@@ -1165,7 +1164,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
return 0; return 0;
} }
idev = isdn_net_get_locked_dev(nd); idev = isdn_net_get_locked_dev(mlp);
if (!idev) { 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;
...@@ -1397,7 +1396,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) ...@@ -1397,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;
...@@ -1417,12 +1416,12 @@ static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1417,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;
...@@ -1430,8 +1429,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1430,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) {
...@@ -1469,8 +1468,8 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1469,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);
...@@ -1479,7 +1478,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1479,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))
...@@ -1569,7 +1568,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1569,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;
...@@ -1746,7 +1745,7 @@ void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, ...@@ -1746,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)
...@@ -1782,7 +1781,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit) ...@@ -1782,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",
...@@ -1792,7 +1791,7 @@ isdn_ppp_bundle(struct ippp_struct *is, int unit) ...@@ -1792,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;
...@@ -1916,7 +1915,7 @@ isdn_ppp_dial_slave(char *name) ...@@ -1916,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)
...@@ -1926,17 +1925,16 @@ isdn_ppp_dial_slave(char *name) ...@@ -1926,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)->netdev); isdn_net_dial_req(sdev);
return 0; return 0;
#else #else
return -1; return -1;
...@@ -1947,35 +1945,20 @@ int ...@@ -1947,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;
...@@ -2495,8 +2478,8 @@ static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, ...@@ -2495,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);
...@@ -2683,8 +2666,8 @@ static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct ...@@ -2683,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);
...@@ -334,12 +334,13 @@ typedef struct isdn_net_local_s { ...@@ -334,12 +334,13 @@ typedef struct isdn_net_local_s {
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 isdn_net_dev_s *queue; /* circular list of all bundled
channels, which are currently
online */
spinlock_t queue_lock; /* lock to protect queue */
#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 */
#endif #endif
...@@ -351,8 +352,11 @@ typedef struct isdn_net_local_s { ...@@ -351,8 +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 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 */
...@@ -397,13 +401,15 @@ typedef struct isdn_net_dev_s { ...@@ -397,13 +401,15 @@ typedef struct isdn_net_dev_s {
/* queued in HL driver */ /* queued in HL driver */
struct tq_struct tqueue; struct tq_struct tqueue;
isdn_net_local *queue; /* circular list of all bundled isdn_net_local *master; /* Ptr to Master device for slaves */
channels, which are currently struct isdn_net_dev_s *slave; /* Ptr to Slave device for masters */
online */
spinlock_t queue_lock; /* lock to protect queue */ 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 */
......
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