From f8bf1ae5261dc1da3fc2529a5cf6bff88e8635a7 Mon Sep 17 00:00:00 2001 From: Detlef Wengorz Date: Fri, 26 Nov 1999 15:54:59 +0000 Subject: [PATCH] added compression (isdn_bsdcompress) for rawip interfaces with x75i B2-protocol. --- drivers/isdn/Config.in | 4 + drivers/isdn/isdn_dwabc.c | 362 ++++++++++++++++++++++++++++++++++++++ drivers/isdn/isdn_net.c | 124 +++++++++++-- include/linux/isdn.h | 50 +++++- 4 files changed, 520 insertions(+), 20 deletions(-) diff --git a/drivers/isdn/Config.in b/drivers/isdn/Config.in index 6839f511..669934e9 100644 --- a/drivers/isdn/Config.in +++ b/drivers/isdn/Config.in @@ -96,5 +96,9 @@ if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then bool ' Enable Hangup-Support with UDP-INFO' CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP bool ' Enable Dial-Support with UDP-INFO' CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL fi + + if [ "$CONFIG_ISDN_PPP" != "n" ]; then + bool ' Enable Compression with rawip and x75i' CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS + fi fi fi diff --git a/drivers/isdn/isdn_dwabc.c b/drivers/isdn/isdn_dwabc.c index d66a3f98..73baf409 100644 --- a/drivers/isdn/isdn_dwabc.c +++ b/drivers/isdn/isdn_dwabc.c @@ -20,6 +20,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log$ + * Revision 1.6 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.5 1999/11/07 21:57:04 detabc * added dwabc-udpinfo-dial support * @@ -79,6 +95,16 @@ static char *dwabcrevison = "$Revision$"; #include #include +#if CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS && CONFIG_ISDN_PPP +#include +extern struct isdn_ppp_compressor *isdn_ippp_comp_head; +#define ipc_head isdn_ippp_comp_head +static struct isdn_ppp_comp_data BSD_COMP_INIT_DATA; +#ifndef CI_BSD_COMPRESS +#define CI_BSD_COMPRESS 21 +#endif +#endif + #define NBYTEORDER_30BYTES 0x1e00 #define DWABC_TMRES (HZ) @@ -1273,6 +1299,9 @@ void isdn_dw_abc_init_func(void) #endif #ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR "CONFIG_ISDN_WITH_ABC_CONN_ERROR\n" +#endif +#ifdef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS + "CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS\n" #endif "loaded\n", dwabcrevison); @@ -1350,6 +1379,7 @@ void isdn_dwabc_test_phone(isdn_net_local *lp) case 'e': lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_CONN_ERROR; break; case 'D': lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_DYNADDR; break; + case 'B': lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_BSD_COMPRESS; break; case '"': case ' ': @@ -1588,5 +1618,337 @@ int isdn_dw_abc_reset_interface(isdn_net_local *lp,int with_message) } +#if CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS && CONFIG_ISDN_PPP +#define DWBSD_PKT_FIRST_LEN 16 +#define DWBSD_PKT_SWITCH 165 +#define DWBSD_PKT_BSD 189 + +#define DWBSD_VERSION 0x1 + +void dwabc_bsd_first_gen(isdn_net_local *lp) +{ + if(lp != NULL && lp->p_encap == ISDN_NET_ENCAP_RAWIP && + (lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS)) { + + struct sk_buff *skb = NULL; + char *p = NULL; + char *ep = NULL; + + if(lp->dw_abc_next_skb != NULL) + dev_kfree_skb(lp->dw_abc_next_skb); + + lp->dw_abc_next_skb = NULL; + + if((skb =(struct sk_buff *)dev_alloc_skb(128)) == NULL) { + + printk(KERN_INFO "%s: dwabc: alloc-skb failed for 128 bytes\n",lp->name); + return; + } + + skb_reserve(skb,64); + p = skb_put(skb,DWBSD_PKT_FIRST_LEN); + ep = p + DWBSD_PKT_FIRST_LEN; + + *(p++) = DWBSD_PKT_SWITCH; + *(p++) = DWBSD_VERSION; + for(;p < ep;p++) *(p++) = 0; + lp->dw_abc_next_skb = skb; + + if(dev->net_verbose > 2) + printk(KERN_INFO "%s: dwabc: sending comm-header version 0x%x\n",lp->name,DWBSD_VERSION); + } +} + + +void dwabc_bsd_free(isdn_net_local *lp) +{ + if(lp != NULL) { + + if(lp->dw_abc_bsd_stat_rx || lp->dw_abc_bsd_stat_tx) { + + struct isdn_ppp_compressor *c = NULL; + + if(!(c = (struct isdn_ppp_compressor *)lp->dw_abc_bsd_compressor)) { + + printk(KERN_WARNING + "%s: PANIC: freeing bsd compressmemory without compressor\n", + lp->name); + + } else { + + if(lp->dw_abc_bsd_stat_rx) (*c->free)(lp->dw_abc_bsd_stat_rx); + if(lp->dw_abc_bsd_stat_tx) (*c->free)(lp->dw_abc_bsd_stat_tx); + + if(dev->net_verbose > 2) + printk(KERN_INFO "%s: free bsd compress-memory\n",lp->name); + } + } + + lp->dw_abc_bsd_compressor = NULL; + lp->dw_abc_bsd_stat_rx = NULL; + lp->dw_abc_bsd_stat_tx = NULL; + lp->dw_abc_if_flags &= ~ISDN_DW_ABC_IFFLAG_BSDAKTIV; + + if(dev->net_verbose > 0) { + + if(lp->dw_abc_bsd_rcv != lp->dw_abc_bsd_bsd_rcv) { + + printk(KERN_INFO "%s: Receive %lu<-%lu kb\n",lp->name, + lp->dw_abc_bsd_rcv >> 10 , lp->dw_abc_bsd_bsd_rcv >> 10); + } + + + if(lp->dw_abc_bsd_snd != lp->dw_abc_bsd_bsd_snd) { + + printk(KERN_INFO "%s: Send %lu->%lu kb\n",lp->name, + lp->dw_abc_bsd_snd >> 10 , lp->dw_abc_bsd_bsd_snd >> 10); + } + } + + lp->dw_abc_bsd_rcv = + lp->dw_abc_bsd_bsd_rcv = + lp->dw_abc_bsd_snd = + lp->dw_abc_bsd_bsd_snd = 0; + + if(lp->dw_abc_next_skb) { + + dev_kfree_skb(lp->dw_abc_next_skb); + lp->dw_abc_next_skb = NULL; + } + } +} + + +int dwabc_bsd_init(isdn_net_local *lp) +{ + int r = 1; + + if(lp != NULL) { + + dwabc_bsd_free(lp); + + if(lp->p_encap == ISDN_NET_ENCAP_RAWIP) { + + if(lp->l2_proto == ISDN_PROTO_L2_X75I) { + + if(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS) { + + ulong flags = 0; + struct isdn_ppp_compressor *c = ipc_head; + + save_flags(flags); + cli(); + for(;c != NULL && c->num != CI_BSD_COMPRESS; c = c->next); + + if(c == NULL) { + + printk(KERN_INFO "%s: Module isdn_bsdcompress not loaded\n",lp->name); + r = -1; + + } else { + + void *rx = NULL; + void *tx = NULL; + struct isdn_ppp_comp_data *cp = &BSD_COMP_INIT_DATA; + + memset(cp,0,sizeof(*cp)); + cp->num = CI_BSD_COMPRESS; + cp->optlen = 1; + + /* + ** set BSD_VERSION 1 and 12 bits compressmode + */ + *cp->options = (1 << 5) | 12; + + if((rx = (*c->alloc)(cp)) == NULL) { + + printk(KERN_INFO "%s: allocation of bsd rx-memory failed\n",lp->name); + r = -1; + + } else if(!(*c->init)(rx,cp,0,1)) { + + printk(KERN_INFO "%s: init of bsd rx-stream failed\n",lp->name); + (*c->free)(rx); + rx = NULL; + } + + if(rx != NULL) { + + cp->flags = IPPP_COMP_FLAG_XMIT; + + if((tx = (*c->alloc)(cp)) == NULL) { + + printk(KERN_INFO "%s: allocation of bsd tx-memory failed\n",lp->name); + r = -1; + + } else if(!(*c->init)(tx,cp,0,1)) { + + printk(KERN_INFO "%s: init of bsd tx-stream failed\n",lp->name); + (*c->free)(tx); + tx = NULL; + } + } + + if(tx != NULL) { + + lp->dw_abc_bsd_compressor = (void *)c; + lp->dw_abc_bsd_stat_rx = rx; + lp->dw_abc_bsd_stat_tx = tx; + r = 0; + + if(dev->net_verbose > 2) + printk(KERN_INFO "%s: bsd compress-memory and init ok\n",lp->name); + } + } + + restore_flags(flags); + } + + } else printk(KERN_INFO "%s: bsd-compress only with L2-Protocol x75i allowed\n",lp->name); + + } else printk(KERN_INFO "%s: bsd-compress only with encapsulation rawip allowed\n",lp->name); + } + + return(r); +} + +struct sk_buff *dwabc_bsd_compress(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev) +{ + if(lp != NULL && lp->p_encap == ISDN_NET_ENCAP_RAWIP && + (lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS) && + (lp->dw_abc_if_flags & ISDN_DW_ABC_IFFLAG_BSDAKTIV)) { + + if(lp->dw_abc_bsd_stat_tx != NULL && lp->dw_abc_bsd_compressor) { + + struct isdn_ppp_compressor *cp = (struct isdn_ppp_compressor *)lp->dw_abc_bsd_compressor; + struct sk_buff *nskb = (struct sk_buff *)dev_alloc_skb(skb->len * 2 + ndev->hard_header_len); + int l = 0; + + if(nskb == NULL) { + + (void)(*cp->reset)(lp->dw_abc_bsd_stat_tx,0,0,NULL,0,NULL); + printk(KERN_INFO "%s: dwabc-compress no memory\n",lp->name); + + } else { + + skb_reserve(nskb,ndev->hard_header_len); + *(unsigned char *)skb_put(nskb,1) = DWBSD_PKT_BSD; + l = (*cp->compress)(lp->dw_abc_bsd_stat_tx,skb,nskb,0x21); + + if(l < 1 || l > skb->len) { + + (void)(*cp->reset)(lp->dw_abc_bsd_stat_tx,0,0,NULL,0,NULL); + dev_kfree_skb(nskb); + + } else { + + dev_kfree_skb(skb); + skb = nskb; + } + } + } + } + return(skb); +} + +struct sk_buff *dwabc_bsd_rx_pkt(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev) +{ + struct sk_buff *r = skb; + + if(lp != NULL && lp->p_encap == ISDN_NET_ENCAP_RAWIP && + (lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS)) { + + unsigned char *p = (unsigned char *)skb->data; + struct isdn_ppp_compressor *cp = (struct isdn_ppp_compressor *)lp->dw_abc_bsd_compressor; + + if(*p == DWBSD_PKT_SWITCH) { + + if(skb->len == DWBSD_PKT_FIRST_LEN) { + + lp->dw_abc_remote_version = p[1]; + lp->dw_abc_if_flags |= ISDN_DW_ABC_IFFLAG_BSDAKTIV; + kfree_skb(skb); + + if(dev->net_verbose > 2) + printk(KERN_INFO "%s: receive comm-header rem-version 0x%02x\n", + lp->name,lp->dw_abc_remote_version); + + return(NULL); + } + + } else if(*p != DWBSD_PKT_BSD) { + + if(lp->dw_abc_bsd_stat_rx != NULL && cp && lp->dw_abc_bsd_is_rx) { + + (void)(*cp->reset)(lp->dw_abc_bsd_stat_rx,0,0,NULL,0,NULL); + lp->dw_abc_bsd_is_rx = 0; + } + + } else if(lp->dw_abc_bsd_stat_rx != NULL && cp) { + + struct sk_buff *nskb = NULL; + + if(test_and_set_bit(ISDN_DW_ABC_BITLOCK_RECEIVE,&lp->dw_abc_bitlocks)) { + + printk(KERN_INFO "%s: bsd-decomp called recursivly\n",lp->name); + kfree_skb(skb); + return(NULL); + } + + nskb = (struct sk_buff *)dev_alloc_skb(2048 + ndev->hard_header_len); + + if(nskb != NULL) { + + int l = 0; + + skb_reserve(nskb,ndev->hard_header_len); + skb_pull(skb, 1); + + if((l = (*cp->decompress)(lp->dw_abc_bsd_stat_rx,skb,nskb,NULL)) < 1 || l>8000) { + + printk(KERN_INFO "%s: abc-decomp failed\n",lp->name); + dev_kfree_skb(nskb); + dev_kfree_skb(skb); + nskb = NULL; + + } else { + + if (nskb->data[0] & 0x1) + skb_pull(nskb, 1); /* protocol ID is only 8 bit */ + else + skb_pull(nskb, 2); + + nskb->dev = skb->dev; + nskb->pkt_type = skb->pkt_type; + nskb->mac.raw = nskb->data; + dev_kfree_skb(skb); + lp->dw_abc_bsd_is_rx = 1; + } + + } else { + + printk(KERN_INFO "%s: PANIC abc-decomp no memory\n",lp->name); + dev_kfree_skb(skb); + } + + clear_bit(ISDN_DW_ABC_BITLOCK_RECEIVE,&lp->dw_abc_bitlocks); + r = nskb; + } + } + + return(r); +} + +#else +int dwabc_bsd_init(isdn_net_local *lp) { return(1); } +void dwabc_bsd_free(isdn_net_local *lp) { return; } +void dwabc_bsd_first_gen(isdn_net_local *lp) { return ; } + +struct sk_buff *dwabc_bsd_compress(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev) +{ return(skb); } + +struct sk_buff *dwabc_bsd_rx_pkt(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev) +{ return(skb); } +#endif #endif diff --git a/drivers/isdn/isdn_net.c b/drivers/isdn/isdn_net.c index ae8bdfa3..84a9ab18 100644 --- a/drivers/isdn/isdn_net.c +++ b/drivers/isdn/isdn_net.c @@ -21,6 +21,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log$ + * 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. @@ -495,12 +511,12 @@ static int isdn_dwabc_is_interface_disabled(isdn_net_local *lp) #ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CONN_ERROR) && isdn_dwabc_encap_with_conerr(lp)) { - if(lp->dw_abc_bchan_errcnt && !(lp->dw_abc_bchan_errcnt & 3)) { + if(lp->dw_abc_bchan_errcnt > 3 && !(lp->dw_abc_bchan_errcnt & 3)) { ulong nj = jiffies; ulong delay = lp->dw_abc_bchan_errcnt * lp->dw_abc_bchan_errcnt * - lp->dw_abc_bchan_errcnt * 2; + lp->dw_abc_bchan_errcnt; if(delay > 86400) delay = 86400; delay = (lp->dw_abc_bchan_last_connect + delay * HZ); @@ -639,6 +655,7 @@ isdn_net_unbind_channel(isdn_net_local * lp) isdn_dw_clear_if(0l,lp); lp->dw_abc_if_flags &= ~ISDN_DW_ABC_IFFLAG_NODCHAN; lp->dw_abc_inuse_secure = 0; + dwabc_bsd_free(lp); #endif if (lp->first_skb) { dev_kfree_skb(lp->first_skb); @@ -700,15 +717,17 @@ isdn_net_autohup() if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) { anymore = 1; l->huptimer++; +#ifdef CONFIG_ISDN_WITH_ABC + if(l->dw_abc_next_skb != NULL) + isdn_net_send_skb(&p->dev,l,NULL); #ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR - if( isdn_dwabc_encap_with_conerr(l) && - l->dw_abc_bchan_errcnt > 0) { + if( isdn_dwabc_encap_with_conerr(l) && l->dw_abc_bchan_errcnt > 0) { - int n = 115; + int n = 180; - if(l->dw_abc_bchan_errcnt > 2) n = 86; - if(l->dw_abc_bchan_errcnt > 4) n = 56; - if(l->dw_abc_bchan_errcnt > 8) n = 30; + if(l->dw_abc_bchan_errcnt > 3) n = 120; + if(l->dw_abc_bchan_errcnt > 6) n = 90; + if(l->dw_abc_bchan_errcnt > 9) n = 60; if(l->huptimer > n) { @@ -718,6 +737,7 @@ isdn_net_autohup() continue; } } +#endif #endif /* * if there is some dialmode where timeout-hangup @@ -867,7 +887,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c) if((lp->dialstate == 4 || lp->dialstate == 12) && lp->dw_abc_dialstart && (idx < ISDN_MAX_CHANNELS)) { - if((jiffies - lp->dw_abc_dialstart) < (HZ >>1)) { + if((jiffies - lp->dw_abc_dialstart) < (HZ >>2)) { lp->dw_abc_if_flags |= ISDN_DW_ABC_IFFLAG_NODCHAN; lp->dialstate = 1; @@ -911,6 +931,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c) isdn_timer_ctrl(ISDN_TIMER_KEEPALIVE, 1); printk(KERN_INFO "isdn_net: %s connected\n", lp->name); #ifdef CONFIG_ISDN_WITH_ABC + if(!dwabc_bsd_init(lp)) dwabc_bsd_first_gen(lp); lp->dw_abc_bchan_last_connect = jiffies; #ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CONN_ERROR)) { @@ -1547,12 +1568,13 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp) strcpy(addinfo, " IDP"); break; } + printk(KERN_INFO #ifdef CONFIG_ISDN_WITH_ABC - printk(KERN_INFO "%s %s: %d.%d.%d.%d -> %d.%d.%d.%d%s\n", + "%s %s: %d.%d.%d.%d -> %d.%d.%d.%d%s\n", (reason == NULL) ? "OPEN" : reason, (lp != NULL) ? lp->name : "", #else - printk(KERN_INFO "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n", + "OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n", #endif p[12], p[13], p[14], p[15], @@ -1560,12 +1582,13 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp) addinfo); break; case ETH_P_ARP: + printk(KERN_INFO #ifdef CONFIG_ISDN_WITH_ABC - printk(KERN_INFO "%s %s: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n", + "%s %s: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n", (reason == NULL) ? "OPEN" : reason, (lp != NULL) ? lp->name : "", #else - printk(KERN_INFO "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n", + "OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n", #endif p[14], p[15], p[16], p[17], p[24], p[25], p[26], p[27]); @@ -1585,9 +1608,67 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp) * Side-effects: ndev->tbusy is cleared on success. */ #endif +#ifdef CONFIG_ISDN_WITH_ABC +static int dwabc_helper_isdn_net_send_skb(struct net_device *,isdn_net_local *,struct sk_buff *); + +int isdn_net_send_skb(struct net_device *ndev, isdn_net_local * lp,struct sk_buff *skb) +{ + int r = 0; + + if(lp == NULL || ndev == NULL) { + + printk(KERN_WARNING "send_skb called with lp 0x%x ndev 0x%x\n", + (char *)lp - (char *)0,(char *)ndev - (char *)0); + + return(1); + } + + if(test_and_set_bit(ISDN_DW_ABC_BITLOCK_SEND,&lp->dw_abc_bitlocks)) { + + if(dev->net_verbose > 2) + printk(KERN_INFO "%s: send_skb called recursivly\n",lp->name); + + return(1); + } + + if(lp->dw_abc_next_skb != NULL) { + + skb = lp->dw_abc_next_skb; + lp->dw_abc_next_skb = NULL; + + if(dwabc_helper_isdn_net_send_skb(ndev,lp,skb)) + lp->dw_abc_next_skb = skb; + + r = 1; + + } else if(skb != NULL) { + + if(lp->dw_abc_if_flags & ISDN_DW_ABC_IFFLAG_BSDAKTIV) { + + int l = skb->len; + + if((skb = dwabc_bsd_compress(lp,skb,ndev)) != NULL) { + + lp->dw_abc_bsd_snd += l; + lp->dw_abc_bsd_bsd_snd += skb->len; + + if(dwabc_helper_isdn_net_send_skb(ndev,lp,skb)) + lp->dw_abc_next_skb = skb; + } + + } else r = dwabc_helper_isdn_net_send_skb(ndev,lp,skb); + } + + clear_bit(ISDN_DW_ABC_BITLOCK_SEND,&lp->dw_abc_bitlocks); + return(r); +} + +static int dwabc_helper_isdn_net_send_skb +#else int -isdn_net_send_skb(struct net_device *ndev, isdn_net_local * lp, - struct sk_buff *skb) +isdn_net_send_skb +#endif + (struct net_device *ndev, isdn_net_local * lp,struct sk_buff *skb) { int ret; int len = skb->len; /* save len */ @@ -2175,6 +2256,18 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb) /* Fall through */ case ISDN_NET_ENCAP_RAWIP: /* RAW-IP without MAC-Header */ +#ifdef CONFIG_ISDN_WITH_ABC + if(lp->p_encap == ISDN_NET_ENCAP_RAWIP) { + + ulong l = skb->len; + + if((skb = dwabc_bsd_rx_pkt(lp,skb,ndev)) == NULL) + return; + + lp->dw_abc_bsd_bsd_rcv += l; + lp->dw_abc_bsd_rcv += skb->len; + } +#endif #ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER if(!(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER)) { #endif @@ -3802,6 +3895,7 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q) isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0); #ifdef CONFIG_ISDN_WITH_ABC isdn_dw_clear_if(~0l,p->local); + dwabc_bsd_free(p->local); #endif restore_flags(flags); kfree(p->local); diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 1dd9f549..bd242480 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -21,6 +21,22 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log$ + * Revision 1.82 1999/11/20 22:14:14 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.81 1999/10/27 21:21:18 detabc * Added support for building logically-bind-group's per interface. * usefull for outgoing call's with more then one isdn-card. @@ -337,6 +353,7 @@ #undef CONFIG_ISDN_WITH_ABC_ICALL_BIND #undef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE #undef CONFIG_ISDN_WITH_ABC_CONN_ERROR +#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS #else #include @@ -348,8 +365,13 @@ #define ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER 0x00000020L #define ISDN_DW_ABC_FLAG_NO_CH_EXTINUSE 0x00000040L #define ISDN_DW_ABC_FLAG_NO_CONN_ERROR 0x00000080L +#define ISDN_DW_ABC_FLAG_BSD_COMPRESS 0x00000100L #define ISDN_DW_ABC_IFFLAG_NODCHAN 0x00000001L +#define ISDN_DW_ABC_IFFLAG_BSDAKTIV 0x00000002L + +#define ISDN_DW_ABC_BITLOCK_SEND 0 +#define ISDN_DW_ABC_BITLOCK_RECEIVE 1 #endif @@ -696,11 +718,14 @@ typedef struct isdn_net_local_s { ulong cisco_myseq; /* Local keepalive seq. for Cisco */ ulong cisco_yourseq; /* Remote keepalive seq. for Cisco */ #ifdef CONFIG_ISDN_WITH_ABC - ulong dw_abc_flags; - ulong dw_abc_if_flags; - int dw_abc_inuse_secure; - ulong dw_abc_dialstart; - int dw_abc_old_onhtime; + ulong dw_abc_flags; + ulong dw_abc_if_flags; + int dw_abc_inuse_secure; + ulong dw_abc_dialstart; + int dw_abc_old_onhtime; + struct sk_buff *dw_abc_next_skb; + int dw_abc_remote_version; + int dw_abc_bitlocks; #ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ char dw_out_msn[ISDN_MSNLEN]; /* eaz for outgoing call if *out_msn != 0 */ #endif @@ -715,6 +740,16 @@ typedef struct isdn_net_local_s { #ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR short dw_abc_bchan_errcnt; #endif +#ifdef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS + void *dw_abc_bsd_compressor; + void *dw_abc_bsd_stat_rx; + void *dw_abc_bsd_stat_tx; + short dw_abc_bsd_is_rx; + ulong dw_abc_bsd_snd; + ulong dw_abc_bsd_bsd_snd; + ulong dw_abc_bsd_rcv; + ulong dw_abc_bsd_bsd_rcv; +#endif #endif } isdn_net_local; @@ -1009,6 +1044,11 @@ extern void isdn_dwabc_test_phone(isdn_net_local *); extern void isdn_dw_abc_init_func(void); extern void isdn_dw_abc_release_func(void); extern int isdn_dw_abc_reset_interface(isdn_net_local *,int); +extern int dwabc_bsd_init(isdn_net_local *lp); +extern void dwabc_bsd_free(isdn_net_local *lp); +extern struct sk_buff *dwabc_bsd_compress(isdn_net_local *,struct sk_buff *,struct net_device *); +extern void dwabc_bsd_first_gen(isdn_net_local *); +extern struct sk_buff *dwabc_bsd_rx_pkt(isdn_net_local *,struct sk_buff *,struct net_device *); #ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT extern size_t isdn_dw_abc_lcr_readstat(char *,size_t); extern ulong isdn_dw_abc_lcr_call_number(isdn_net_local *,isdn_ctrl *);