patch-2.2.15 linux/drivers/isdn/isdn_net.c
Next file: linux/drivers/isdn/isdn_ppp.c
Previous file: linux/drivers/isdn/isdn_common.h
Back to the patch index
Back to the overall index
- Lines: 675
- Date:
Fri Apr 21 12:46:12 2000
- Orig file:
v2.2.14/drivers/isdn/isdn_net.c
- Orig date:
Tue Jan 4 21:18:50 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.95 1999/10/27 21:21:17 detabc Exp $
+/* $Id: isdn_net.c,v 1.114 2000/03/16 16:37:41 kai Exp $
* Linux ISDN subsystem, network interfaces and related functions (linklevel).
*
@@ -21,6 +21,91 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_net.c,v $
+ * Revision 1.114 2000/03/16 16:37:41 kai
+ * Allow phone numbers starting with "*" as outgoing numbers for
+ * networking interface. Some PBX's need this to allow dialing internal
+ * numbers (mine, for example ;-)
+ *
+ * Revision 1.113 2000/03/16 15:46:37 kai
+ * a little bugfix and cosmetic changes
+ *
+ * Revision 1.112 2000/03/04 16:20:42 detabc
+ * copy frames before rewriting frame's saddr
+ *
+ * Revision 1.111 2000/02/28 22:28:24 he
+ * moved tx_timeout warning messages in old (2.2.x) branch where it really only
+ * indicates problems.
+ *
+ * Revision 1.110 2000/02/26 01:00:53 keil
+ * changes from 2.3.47
+ *
+ * Revision 1.109 2000/02/25 11:29:17 paul
+ * changed chargetime to ulong from int (after about 20 days the "chargetime of
+ * ipppX is now 1234" message displays a negative number on alpha).
+ *
+ * Revision 1.108 2000/02/15 12:54:01 kai
+ * set TX timeout back to 2 secs for 2.2.x, just to be safe
+ *
+ * Revision 1.107 2000/02/13 09:52:05 kai
+ * increased TX_TIMEOUT to 20sec
+ *
+ * Revision 1.106 2000/02/12 19:26:55 kai
+ * adopted to latest 2.3 softnet changes.
+ *
+ * tested with PPP and MPPP, it works here.
+ * can somebody check raw-ip?
+ *
+ * also changed std2kern, stddiff for bash-1 compatibility,
+ * hope this doesn't break anything.
+ *
+ * Revision 1.105 2000/02/12 11:43:26 he
+ * SOFTNET related changes, first try. Compatible with linux 2.2.x, but
+ * not tested for kernels with softnet (>= 2.3.43) yet.
+ *
+ * Revision 1.104 2000/02/06 21:49:59 detabc
+ * add rewriting of socket's and frame's saddr for udp-ipv4 dynip-connections.
+ * Include checksum-recompute of ip- and udp-header's.
+ *
+ * Revision 1.103 2000/01/23 18:45:37 keil
+ * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
+ *
+ * Revision 1.102 2000/01/09 20:43:14 detabc
+ * exand logical bind-group's for both call's (in and out).
+ * add first part of kernel-config-help for abc-extension.
+ *
+ * Revision 1.101 1999/12/05 16:06:08 detabc
+ * add resethandling for rawip-compression.
+ * at now all B2-Protocols are usable with rawip-compression
+ *
+ * Revision 1.100 1999/12/04 15:05:25 detabc
+ * bugfix abc-rawip-bsdcompress with channel-bundeling
+ *
+ * Revision 1.99 1999/11/30 11:29:06 detabc
+ * add a on the fly frame-counter and limit
+ *
+ * Revision 1.98 1999/11/28 14:49:07 detabc
+ * In case of rawip-compress adjust dev[x]->ibytes/obytes to reflect the
+ * uncompressed size.
+ *
+ * Revision 1.97 1999/11/26 15:54:59 detabc
+ * added compression (isdn_bsdcompress) for rawip interfaces with x75i B2-protocol.
+ *
+ * Revision 1.96 1999/11/20 22:14:13 detabc
+ * added channel dial-skip in case of external use
+ * (isdn phone or another isdn device) on the same NTBA.
+ * usefull with two or more card's connected the different NTBA's.
+ * global switchable in kernel-config and also per netinterface.
+ *
+ * add auto disable of netinterface's in case of:
+ * to many connection's in short time.
+ * config mistakes (wrong encapsulation, B2-protokoll or so on) on local
+ * or remote side.
+ * wrong password's or something else to a ISP (syncppp).
+ *
+ * possible encapsulations for this future are:
+ * ISDN_NET_ENCAP_SYNCPPP, ISDN_NET_ENCAP_UIHDLC, ISDN_NET_ENCAP_RAWIP,
+ * and ISDN_NET_ENCAP_CISCOHDLCK.
+ *
* Revision 1.95 1999/10/27 21:21:17 detabc
* Added support for building logically-bind-group's per interface.
* usefull for outgoing call's with more then one isdn-card.
@@ -393,10 +478,6 @@
#endif
-#ifndef ISDN_NEW_TBUSY
-#define ISDN_NEW_TBUSY
-#endif
-#ifdef ISDN_NEW_TBUSY
/*
* Outline of new tbusy handling:
*
@@ -413,29 +494,55 @@
*/
/*
- * Tell upper layers that the network device is ready to xmit more frames.
+ * About SOFTNET:
+ * Most of the changes were pretty obvious and basically done by HE already.
+ *
+ * One problem of the isdn net device code is that is uses struct net_device
+ * for masters and slaves. However, only master interface are registered to
+ * the network layer, and therefore, it only makes sense to call netif_*
+ * functions on them.
+ *
+ * --KG
*/
-static void __inline__ isdn_net_dev_xon(struct device * dev)
-{
- dev->tbusy = 0;
- mark_bh(NET_BH);
-}
-static void __inline__ isdn_net_lp_xon(isdn_net_local * lp)
+/*
+ * Find out if the netdevice has been ifup-ed yet.
+ * For slaves, look at the corresponding master.
+ */
+static int __inline__ isdn_net_started(isdn_net_dev *n)
{
- lp->netdev->dev.tbusy = 0;
- if(lp->master) lp->master->tbusy = 0;
- mark_bh(NET_BH);
+ isdn_net_local *lp = n->local;
+ struct device *dev;
+
+ if (lp->master)
+ dev = lp->master;
+ else
+ dev = &n->dev;
+ return dev->start;
}
/*
- * Ask upper layers to temporarily cease passing us more xmit frames.
+ * wake up the network -> net_device queue.
+ * For slaves, wake the corresponding master interface.
*/
-static void __inline__ isdn_net_dev_xoff(struct device * dev)
+static void __inline__ isdn_net_lp_xon(isdn_net_local * lp)
{
- dev->tbusy = 1;
+ if (lp->master)
+ netif_wake_queue(lp->master);
+ else
+ netif_wake_queue(&lp->netdev->dev);
}
-#endif
+
+/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just
+ * to be safe.
+ * For 2.3.x we push it up to 20 secs, because call establishment
+ * (in particular callback) may take such a long time, and we
+ * don't want confusing messages in the log. However, there is a slight
+ * possibility that this large timeout will break other things like MPPP,
+ * which might rely on the tx timeout. If so, we'll find out this way...
+ */
+
+#define ISDN_NET_TX_TIMEOUT (2*HZ)
/* Prototypes */
@@ -443,7 +550,7 @@
static int isdn_net_start_xmit(struct sk_buff *, struct device *);
static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *);
-char *isdn_net_revision = "$Revision: 1.95 $";
+char *isdn_net_revision = "$Revision: 1.114 $";
/*
* Code for raw-networking over ISDN
@@ -482,14 +589,9 @@
#endif
ulong flags;
+ /* not sure if the cli() is needed at all --KG */
save_flags(flags);
cli(); /* Avoid glitch on writes to CMD regs */
- dev->interrupt = 0;
-#ifdef ISDN_NEW_TBUSY
- isdn_net_dev_xon(dev);
-#else
- dev->tbusy = 0;
-#endif
#ifdef CONFIG_ISDN_X25
if( cprot && cprot -> pops && dops )
cprot -> pops -> restart ( cprot, dev, dops );
@@ -505,8 +607,12 @@
struct device *p;
struct in_device *in_dev;
+ /* moved here from isdn_net_reset, because only the master has an
+ interface associated which is supposed to be started. BTW:
+ we need to call netif_start_queue, not netif_wake_queue here */
+ netif_start_queue(dev);
+
isdn_net_reset(dev);
- dev->start = 1;
/* Fill in the MAC-level header (not needed, but for compatibility... */
for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
dev->dev_addr[i] = 0xfc;
@@ -524,7 +630,6 @@
if ((p = (((isdn_net_local *) dev->priv)->slave))) {
while (p) {
isdn_net_reset(p);
- p->start = 1;
p = (((isdn_net_local *) p->priv)->slave);
}
}
@@ -642,7 +747,7 @@
isdn_net_hangup(&p->dev);
} else if (jiffies - l->chargetime > l->chargeint) {
printk(KERN_DEBUG
- "isdn_net: %s: chtime = %d, chint = %d\n",
+ "isdn_net: %s: chtime = %lu, chint = %d\n",
l->name, l->chargetime, l->chargeint);
isdn_net_hangup(&p->dev);
}
@@ -703,19 +808,11 @@
mdev = &lp->netdev->dev;
if (!isdn_net_send_skb(mdev, lp, lp->sav_skb)) {
lp->sav_skb = NULL;
-#ifndef ISDN_NEW_TBUSY
- mark_bh(NET_BH);
-#endif
} else {
return 1;
}
}
-#ifdef ISDN_NEW_TBUSY
isdn_net_lp_xon(lp);
-#else
- if (test_and_clear_bit(0, (void *) &(p->dev.tbusy)))
- mark_bh(NET_BH);
-#endif
}
return 1;
case ISDN_STAT_DCONN:
@@ -791,7 +888,7 @@
* we correct the timestamp here.
*/
lp->chargetime = jiffies;
- printk(KERN_DEBUG "isdn_net: chargetime of %s now %d\n",
+ printk(KERN_DEBUG "isdn_net: chargetime of %s now %lu\n",
lp->name, lp->chargetime);
/* reset dial-timeout */
@@ -814,18 +911,7 @@
if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb)))
lp->first_skb = NULL;
}
-#ifdef ISDN_NEW_TBUSY
if(! lp->first_skb) isdn_net_lp_xon(lp);
-#else
- else {
- /*
- * dev.tbusy is usually cleared implicitly by isdn_net_xmit(,,lp->first_skb).
- * With an empty lp->first_skb, we need to do this ourselves
- */
- lp->netdev->dev.tbusy = 0;
- mark_bh(NET_BH);
- }
-#endif /* ISDN_NEW_TBUSY */
return 1;
}
break;
@@ -849,7 +935,7 @@
if (lp->hupflags & ISDN_WAITCHARGE)
lp->hupflags |= ISDN_HAVECHARGE;
lp->chargetime = jiffies;
- printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %d\n",
+ printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
lp->name, lp->chargetime);
return 1;
}
@@ -858,20 +944,6 @@
}
/*
- * Check, if a number contains wildcard-characters, in which case it
- * is for incoming purposes only.
- */
-static int
-isdn_net_checkwild(char *num)
-{
- return ((strchr(num, '?')) ||
- (strchr(num, '*')) ||
- (strchr(num, '[')) ||
- (strchr(num, ']')) ||
- (strchr(num, '^')));
-}
-
-/*
* Perform dialout for net-interfaces and timeout-handling for
* D-Channel-up and B-Channel-up Messages.
* This function is initially called from within isdn_net_start_xmit() or
@@ -1259,14 +1331,16 @@
strcpy(addinfo, " IDP");
break;
}
- printk(KERN_INFO "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
+ printk(KERN_INFO
+ "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
p[12], p[13], p[14], p[15],
p[16], p[17], p[18], p[19],
addinfo);
break;
case ETH_P_ARP:
- printk(KERN_INFO "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
+ printk(KERN_INFO
+ "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
p[14], p[15], p[16], p[17],
p[24], p[25], p[26], p[27]);
break;
@@ -1280,14 +1354,8 @@
*
* Return: 0 on success, !0 on failure.
*/
-#ifndef ISDN_NEW_TBUSY
-/*
- * Side-effects: ndev->tbusy is cleared on success.
- */
-#endif
-int
-isdn_net_send_skb(struct device *ndev, isdn_net_local * lp,
- struct sk_buff *skb)
+int isdn_net_send_skb
+ (struct device *ndev, isdn_net_local * lp,struct sk_buff *skb)
{
int ret;
int len = skb->len; /* save len */
@@ -1295,17 +1363,11 @@
ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
if (ret == len) {
lp->transcount += len;
-#ifndef ISDN_NEW_TBUSY
- clear_bit(0, (void *) &(ndev->tbusy));
-#endif
return 0;
}
if (ret < 0) {
dev_kfree_skb(skb);
lp->stats.tx_errors++;
-#ifndef ISDN_NEW_TBUSY
- clear_bit(0, (void *) &(ndev->tbusy));
-#endif
return 0;
}
return 1;
@@ -1351,11 +1413,7 @@
if (lp->srobin == ndev)
ret = isdn_net_send_skb(ndev, lp, skb);
else
-#ifdef ISDN_NEW_TBUSY
ret = isdn_net_start_xmit(skb, lp->srobin);
-#else
- ret = ndev->tbusy = isdn_net_start_xmit(skb, lp->srobin);
-#endif
lp->srobin = (slp->slave) ? slp->slave : ndev;
slp = (isdn_net_local *) (lp->srobin->priv);
if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0)))
@@ -1397,6 +1455,8 @@
}
}
+
+
/*
* Try sending a packet.
* If this interface isn't connected to a ISDN-Channel, find a free channel,
@@ -1409,19 +1469,24 @@
#ifdef CONFIG_ISDN_X25
struct concap_proto * cprot = lp -> netdev -> cprot;
#endif
+ /* some comment as with the softnet TX timeout
+ when this happens, it's a bug in the HL card driver
+ and should be fixed there, so we can supposedly get rid of
+ this here at all.
+ I added a debugging message to find out if it ever occurs --KG
+ */
+
if (ndev->tbusy) {
- if (jiffies - ndev->trans_start < (2 * HZ))
+ if (jiffies - ndev->trans_start < ISDN_NET_TX_TIMEOUT)
return 1;
- if (!lp->dialstate)
+ if (!lp->dialstate){
lp->stats.tx_errors++;
+ printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n",
+ ndev->name, lp->dialstate);
+ }
ndev->trans_start = jiffies;
-#ifdef ISDN_NEW_TBUSY
- isdn_net_dev_xon(ndev);
-#endif
+ netif_wake_queue(ndev);
}
-#ifndef ISDN_NEW_TBUSY
- ndev->tbusy = 1; /* left instead of obsolete test_and_set_bit() */
-#endif
#ifdef CONFIG_ISDN_X25
/* At this point hard_start_xmit() passes control to the encapsulation
protocol (if present).
@@ -1436,9 +1501,7 @@
*/
if( cprot ) {
int ret = cprot -> pops -> encap_and_xmit ( cprot , skb);
-#ifdef ISDN_NEW_TBUSY
- if(ret) isdn_net_dev_xoff(ndev);
-#endif
+ if(ret) netif_stop_queue(ndev);
return ret;
} else
#endif
@@ -1458,9 +1521,6 @@
if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
- ndev->tbusy = 0;
-#endif
return 0;
}
if (lp->phone[1]) {
@@ -1476,15 +1536,11 @@
if(jiffies < lp->dialwait_timer) {
isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
- ndev->tbusy = 0;
-#endif
restore_flags(flags);
return 0;
} else
lp->dialwait_timer = 0;
}
-
/* Grab a free ISDN-Channel */
if (((chi =
isdn_get_free_channel(
@@ -1492,7 +1548,8 @@
lp->l2_proto,
lp->l3_proto,
lp->pre_device,
- lp->pre_channel)
+ lp->pre_channel,
+ lp->msn)
) < 0) &&
((chi =
isdn_get_free_channel(
@@ -1500,15 +1557,13 @@
lp->l2_proto,
lp->l3_proto,
lp->pre_device,
- lp->pre_channel^1)
+ lp->pre_channel^1,
+ lp->msn)
) < 0)) {
restore_flags(flags);
isdn_net_unreachable(ndev, skb,
"No channel");
dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
- ndev->tbusy = 0;
-#endif
return 0;
}
/* Log packet, which triggered dialing */
@@ -1528,9 +1583,7 @@
}
restore_flags(flags);
isdn_net_dial(); /* Initiate dialing */
-#ifdef ISDN_NEW_TBUSY
- isdn_net_dev_xoff(ndev);
-#endif
+ netif_stop_queue(ndev);
return 1; /* let upper layer requeue skb packet */
}
#endif
@@ -1544,9 +1597,6 @@
}
lp->first_skb = skb;
/* Initiate dialing */
-#ifndef ISDN_NEW_TBUSY
- ndev->tbusy = 0;
-#endif
restore_flags(flags);
isdn_net_dial();
return 0;
@@ -1554,9 +1604,6 @@
isdn_net_unreachable(ndev, skb,
"No phone number");
dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
- ndev->tbusy = 0;
-#endif
return 0;
}
} else {
@@ -1567,24 +1614,16 @@
int ret;
if (lp->first_skb) {
if (isdn_net_xmit(ndev, lp, lp->first_skb)){
-#ifdef ISDN_NEW_TBUSY
- isdn_net_dev_xoff(ndev);
-#endif
+ netif_stop_queue(ndev);
return 1;
}
lp->first_skb = NULL;
}
ret = (isdn_net_xmit(ndev, lp, skb));
-#ifdef ISDN_NEW_TBUSY
- if(ret) isdn_net_dev_xoff(ndev);
-#endif
+ if(ret) netif_stop_queue(ndev);
return ret;
} else
-#ifdef ISDN_NEW_TBUSY
- isdn_net_dev_xoff(ndev);
-#else
- ndev->tbusy = 1;
-#endif
+ netif_stop_queue(ndev);
}
}
return 1;
@@ -1606,7 +1645,7 @@
#ifdef CONFIG_ISDN_X25
if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
#endif
- dev->tbusy = 1;
+ netif_stop_queue(dev);
dev->start = 0;
if ((p = (((isdn_net_local *) dev->priv)->slave))) {
/* If this interface has slaves, stop them also */
@@ -1618,8 +1657,6 @@
cprot -> pops -> close( cprot );
#endif
isdn_net_hangup(p);
- p->tbusy = 1;
- p->start = 0;
p = (((isdn_net_local *) p->priv)->slave);
}
}
@@ -2360,7 +2397,7 @@
* Is the interface up?
* If not, reject the call actively.
*/
- if (!p->dev.start) {
+ if (!isdn_net_started(p)) {
restore_flags(flags);
printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
lp->name);
@@ -2389,7 +2426,7 @@
p = (isdn_net_dev *) p->next;
continue;
}
- }
+ }
if (lp->flags & ISDN_NET_CALLBACK) {
int chi;
/*
@@ -2411,9 +2448,10 @@
isdn_get_free_channel(
ISDN_USAGE_NET,
lp->l2_proto,
- lp->l3_proto,
+ lp->l3_proto,
lp->pre_device,
- lp->pre_channel)
+ lp->pre_channel,
+ lp->msn)
) < 0) {
printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n", lp->name);
@@ -2528,7 +2566,8 @@
lp->l2_proto,
lp->l3_proto,
lp->pre_device,
- lp->pre_channel)
+ lp->pre_channel,
+ lp->msn)
) < 0) {
printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
restore_flags(flags);
@@ -2626,9 +2665,6 @@
p = (((isdn_net_local *) p->priv)->slave);
}
((isdn_net_local *) q->priv)->slave = &(netdev->dev);
- q->interrupt = 0;
- q->tbusy = 0;
- q->start = master->start;
} else {
/* Device shall be a master */
if (register_netdev(&netdev->dev) != 0) {
@@ -2701,7 +2737,7 @@
if (n->local->master)
return NULL;
/* Master must not be started yet */
- if (n->dev.start)
+ if (isdn_net_started(n))
return NULL;
return (isdn_net_new(newname, &(n->dev)));
}
@@ -2744,9 +2780,8 @@
#ifdef CONFIG_ISDN_X25
struct concap_proto * cprot = p -> cprot;
#endif
- if (p->dev.start) {
- printk(KERN_WARNING
- "%s: cannot change encap when if is up\n",
+ if (isdn_net_started(p)) {
+ printk(KERN_WARNING "%s: cannot change encap when if is up\n",
lp->name);
return -EBUSY;
}
@@ -2837,10 +2872,9 @@
/* If binding is exclusive, try to grab the channel */
save_flags(flags);
- if ((i = isdn_get_free_channel(ISDN_USAGE_NET, lp->l2_proto,
- lp->l3_proto,
- drvidx,
- chidx)) < 0) {
+ if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
+ lp->l2_proto, lp->l3_proto, drvidx,
+ chidx, lp->msn)) < 0) {
/* Grab failed, because desired channel is in use */
lp->exclusive = -1;
restore_flags(flags);
@@ -3007,8 +3041,6 @@
isdn_net_dev *p = isdn_net_findif(phone->name);
isdn_net_phone *n;
- if (isdn_net_checkwild(phone->phone) && (phone->outgoing & 1))
- return -EINVAL;
if (p) {
if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
return -ENOMEM;
@@ -3181,14 +3213,8 @@
save_flags(flags);
cli();
- if (p->local->master) {
- /* If it's a slave, it may be removed even if it is busy. However
- * it has to be hung up first.
- */
- isdn_net_hangup(&p->dev);
- p->dev.start = 0;
- }
- if (p->dev.start) {
+
+ if (isdn_net_started(p)) {
restore_flags(flags);
return -EBUSY;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)