aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/mISDN
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN')
-rw-r--r--drivers/isdn/mISDN/Kconfig44
-rw-r--r--drivers/isdn/mISDN/Makefile13
-rw-r--r--drivers/isdn/mISDN/core.c244
-rw-r--r--drivers/isdn/mISDN/core.h77
-rw-r--r--drivers/isdn/mISDN/dsp.h263
-rw-r--r--drivers/isdn/mISDN/dsp_audio.c434
-rw-r--r--drivers/isdn/mISDN/dsp_biquad.h65
-rw-r--r--drivers/isdn/mISDN/dsp_blowfish.c672
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c1886
-rw-r--r--drivers/isdn/mISDN/dsp_core.c1191
-rw-r--r--drivers/isdn/mISDN/dsp_dtmf.c303
-rw-r--r--drivers/isdn/mISDN/dsp_ecdis.h110
-rw-r--r--drivers/isdn/mISDN/dsp_hwec.c138
-rw-r--r--drivers/isdn/mISDN/dsp_hwec.h10
-rw-r--r--drivers/isdn/mISDN/dsp_pipeline.c348
-rw-r--r--drivers/isdn/mISDN/dsp_tones.c551
-rw-r--r--drivers/isdn/mISDN/fsm.c183
-rw-r--r--drivers/isdn/mISDN/fsm.h67
-rw-r--r--drivers/isdn/mISDN/hwchannel.c365
-rw-r--r--drivers/isdn/mISDN/l1oip.h91
-rw-r--r--drivers/isdn/mISDN/l1oip_codec.c374
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c1518
-rw-r--r--drivers/isdn/mISDN/layer1.c403
-rw-r--r--drivers/isdn/mISDN/layer1.h26
-rw-r--r--drivers/isdn/mISDN/layer2.c2216
-rw-r--r--drivers/isdn/mISDN/layer2.h140
-rw-r--r--drivers/isdn/mISDN/socket.c781
-rw-r--r--drivers/isdn/mISDN/stack.c674
-rw-r--r--drivers/isdn/mISDN/tei.c1340
-rw-r--r--drivers/isdn/mISDN/timerdev.c301
30 files changed, 14828 insertions, 0 deletions
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
new file mode 100644
index 000000000000..4938355c4072
--- /dev/null
+++ b/drivers/isdn/mISDN/Kconfig
@@ -0,0 +1,44 @@
1#
2# modularer ISDN driver
3#
4
5menuconfig MISDN
6 tristate "Modular ISDN driver"
7 help
8 Enable support for the modular ISDN driver.
9
10if MISDN != n
11
12config MISDN_DSP
13 tristate "Digital Audio Processing of transparent data"
14 depends on MISDN
15 help
16 Enable support for digital audio processing capability.
17 This module may be used for special applications that require
18 cross connecting of bchannels, conferencing, dtmf decoding
19 echo cancelation, tone generation, and Blowfish encryption and
20 decryption.
21 It may use hardware features if available.
22 E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
23 and get more informations about this module and it's usage.
24 If unsure, say 'N'.
25
26config MISDN_L1OIP
27 tristate "ISDN over IP tunnel"
28 depends on MISDN
29 help
30 Enable support for ISDN over IP tunnel.
31
32 It features:
33 - dynamic IP exchange, if one or both peers have dynamic IPs
34 - BRI (S0) and PRI (S2M) interface
35 - layer 1 control via network keepalive frames
36 - direct tunneling of physical interface via IP
37
38 NOTE: This protocol is called 'Layer 1 over IP' and is not
39 compatible with ISDNoIP (Agfeo) or TDMoIP. Protocol description is
40 provided in the source code.
41
42source "drivers/isdn/hardware/mISDN/Kconfig"
43
44endif #MISDN
diff --git a/drivers/isdn/mISDN/Makefile b/drivers/isdn/mISDN/Makefile
new file mode 100644
index 000000000000..1cb5e633cf75
--- /dev/null
+++ b/drivers/isdn/mISDN/Makefile
@@ -0,0 +1,13 @@
1#
2# Makefile for the modular ISDN driver
3#
4
5obj-$(CONFIG_MISDN) += mISDN_core.o
6obj-$(CONFIG_MISDN_DSP) += mISDN_dsp.o
7obj-$(CONFIG_MISDN_L1OIP) += l1oip.o
8
9# multi objects
10
11mISDN_core-objs := core.o fsm.o socket.o hwchannel.o stack.o layer1.o layer2.o tei.o timerdev.o
12mISDN_dsp-objs := dsp_core.o dsp_cmx.o dsp_tones.o dsp_dtmf.o dsp_audio.o dsp_blowfish.o dsp_pipeline.o dsp_hwec.o
13l1oip-objs := l1oip_core.o l1oip_codec.o
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
new file mode 100644
index 000000000000..33068177b7c9
--- /dev/null
+++ b/drivers/isdn/mISDN/core.c
@@ -0,0 +1,244 @@
1/*
2 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/types.h>
16#include <linux/stddef.h>
17#include <linux/module.h>
18#include <linux/spinlock.h>
19#include <linux/mISDNif.h>
20#include "core.h"
21
22static u_int debug;
23
24MODULE_AUTHOR("Karsten Keil");
25MODULE_LICENSE("GPL");
26module_param(debug, uint, S_IRUGO | S_IWUSR);
27
28static LIST_HEAD(devices);
29DEFINE_RWLOCK(device_lock);
30static u64 device_ids;
31#define MAX_DEVICE_ID 63
32
33static LIST_HEAD(Bprotocols);
34DEFINE_RWLOCK(bp_lock);
35
36struct mISDNdevice
37*get_mdevice(u_int id)
38{
39 struct mISDNdevice *dev;
40
41 read_lock(&device_lock);
42 list_for_each_entry(dev, &devices, D.list)
43 if (dev->id == id) {
44 read_unlock(&device_lock);
45 return dev;
46 }
47 read_unlock(&device_lock);
48 return NULL;
49}
50
51int
52get_mdevice_count(void)
53{
54 struct mISDNdevice *dev;
55 int cnt = 0;
56
57 read_lock(&device_lock);
58 list_for_each_entry(dev, &devices, D.list)
59 cnt++;
60 read_unlock(&device_lock);
61 return cnt;
62}
63
64static int
65get_free_devid(void)
66{
67 u_int i;
68
69 for (i = 0; i <= MAX_DEVICE_ID; i++)
70 if (!test_and_set_bit(i, (u_long *)&device_ids))
71 return i;
72 return -1;
73}
74
75int
76mISDN_register_device(struct mISDNdevice *dev, char *name)
77{
78 u_long flags;
79 int err;
80
81 dev->id = get_free_devid();
82 if (dev->id < 0)
83 return -EBUSY;
84 if (name && name[0])
85 strcpy(dev->name, name);
86 else
87 sprintf(dev->name, "mISDN%d", dev->id);
88 if (debug & DEBUG_CORE)
89 printk(KERN_DEBUG "mISDN_register %s %d\n",
90 dev->name, dev->id);
91 err = create_stack(dev);
92 if (err)
93 return err;
94 write_lock_irqsave(&device_lock, flags);
95 list_add_tail(&dev->D.list, &devices);
96 write_unlock_irqrestore(&device_lock, flags);
97 return 0;
98}
99EXPORT_SYMBOL(mISDN_register_device);
100
101void
102mISDN_unregister_device(struct mISDNdevice *dev) {
103 u_long flags;
104
105 if (debug & DEBUG_CORE)
106 printk(KERN_DEBUG "mISDN_unregister %s %d\n",
107 dev->name, dev->id);
108 write_lock_irqsave(&device_lock, flags);
109 list_del(&dev->D.list);
110 write_unlock_irqrestore(&device_lock, flags);
111 test_and_clear_bit(dev->id, (u_long *)&device_ids);
112 delete_stack(dev);
113}
114EXPORT_SYMBOL(mISDN_unregister_device);
115
116u_int
117get_all_Bprotocols(void)
118{
119 struct Bprotocol *bp;
120 u_int m = 0;
121
122 read_lock(&bp_lock);
123 list_for_each_entry(bp, &Bprotocols, list)
124 m |= bp->Bprotocols;
125 read_unlock(&bp_lock);
126 return m;
127}
128
129struct Bprotocol *
130get_Bprotocol4mask(u_int m)
131{
132 struct Bprotocol *bp;
133
134 read_lock(&bp_lock);
135 list_for_each_entry(bp, &Bprotocols, list)
136 if (bp->Bprotocols & m) {
137 read_unlock(&bp_lock);
138 return bp;
139 }
140 read_unlock(&bp_lock);
141 return NULL;
142}
143
144struct Bprotocol *
145get_Bprotocol4id(u_int id)
146{
147 u_int m;
148
149 if (id < ISDN_P_B_START || id > 63) {
150 printk(KERN_WARNING "%s id not in range %d\n",
151 __func__, id);
152 return NULL;
153 }
154 m = 1 << (id & ISDN_P_B_MASK);
155 return get_Bprotocol4mask(m);
156}
157
158int
159mISDN_register_Bprotocol(struct Bprotocol *bp)
160{
161 u_long flags;
162 struct Bprotocol *old;
163
164 if (debug & DEBUG_CORE)
165 printk(KERN_DEBUG "%s: %s/%x\n", __func__,
166 bp->name, bp->Bprotocols);
167 old = get_Bprotocol4mask(bp->Bprotocols);
168 if (old) {
169 printk(KERN_WARNING
170 "register duplicate protocol old %s/%x new %s/%x\n",
171 old->name, old->Bprotocols, bp->name, bp->Bprotocols);
172 return -EBUSY;
173 }
174 write_lock_irqsave(&bp_lock, flags);
175 list_add_tail(&bp->list, &Bprotocols);
176 write_unlock_irqrestore(&bp_lock, flags);
177 return 0;
178}
179EXPORT_SYMBOL(mISDN_register_Bprotocol);
180
181void
182mISDN_unregister_Bprotocol(struct Bprotocol *bp)
183{
184 u_long flags;
185
186 if (debug & DEBUG_CORE)
187 printk(KERN_DEBUG "%s: %s/%x\n", __func__, bp->name,
188 bp->Bprotocols);
189 write_lock_irqsave(&bp_lock, flags);
190 list_del(&bp->list);
191 write_unlock_irqrestore(&bp_lock, flags);
192}
193EXPORT_SYMBOL(mISDN_unregister_Bprotocol);
194
195int
196mISDNInit(void)
197{
198 int err;
199
200 printk(KERN_INFO "Modular ISDN core version %d.%d.%d\n",
201 MISDN_MAJOR_VERSION, MISDN_MINOR_VERSION, MISDN_RELEASE);
202 mISDN_initstack(&debug);
203 err = mISDN_inittimer(&debug);
204 if (err)
205 goto error;
206 err = l1_init(&debug);
207 if (err) {
208 mISDN_timer_cleanup();
209 goto error;
210 }
211 err = Isdnl2_Init(&debug);
212 if (err) {
213 mISDN_timer_cleanup();
214 l1_cleanup();
215 goto error;
216 }
217 err = misdn_sock_init(&debug);
218 if (err) {
219 mISDN_timer_cleanup();
220 l1_cleanup();
221 Isdnl2_cleanup();
222 }
223error:
224 return err;
225}
226
227void mISDN_cleanup(void)
228{
229 misdn_sock_cleanup();
230 mISDN_timer_cleanup();
231 l1_cleanup();
232 Isdnl2_cleanup();
233
234 if (!list_empty(&devices))
235 printk(KERN_ERR "%s devices still registered\n", __func__);
236
237 if (!list_empty(&Bprotocols))
238 printk(KERN_ERR "%s Bprotocols still registered\n", __func__);
239 printk(KERN_DEBUG "mISDNcore unloaded\n");
240}
241
242module_init(mISDNInit);
243module_exit(mISDN_cleanup);
244
diff --git a/drivers/isdn/mISDN/core.h b/drivers/isdn/mISDN/core.h
new file mode 100644
index 000000000000..7da7233b4c1a
--- /dev/null
+++ b/drivers/isdn/mISDN/core.h
@@ -0,0 +1,77 @@
1/*
2 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#ifndef mISDN_CORE_H
16#define mISDN_CORE_H
17
18extern struct mISDNdevice *get_mdevice(u_int);
19extern int get_mdevice_count(void);
20
21/* stack status flag */
22#define mISDN_STACK_ACTION_MASK 0x0000ffff
23#define mISDN_STACK_COMMAND_MASK 0x000f0000
24#define mISDN_STACK_STATUS_MASK 0xfff00000
25/* action bits 0-15 */
26#define mISDN_STACK_WORK 0
27#define mISDN_STACK_SETUP 1
28#define mISDN_STACK_CLEARING 2
29#define mISDN_STACK_RESTART 3
30#define mISDN_STACK_WAKEUP 4
31#define mISDN_STACK_ABORT 15
32/* command bits 16-19 */
33#define mISDN_STACK_STOPPED 16
34#define mISDN_STACK_INIT 17
35#define mISDN_STACK_THREADSTART 18
36/* status bits 20-31 */
37#define mISDN_STACK_BCHANNEL 20
38#define mISDN_STACK_ACTIVE 29
39#define mISDN_STACK_RUNNING 30
40#define mISDN_STACK_KILLED 31
41
42
43/* manager options */
44#define MGR_OPT_USER 24
45#define MGR_OPT_NETWORK 25
46
47extern int connect_Bstack(struct mISDNdevice *, struct mISDNchannel *,
48 u_int, struct sockaddr_mISDN *);
49extern int connect_layer1(struct mISDNdevice *, struct mISDNchannel *,
50 u_int, struct sockaddr_mISDN *);
51extern int create_l2entity(struct mISDNdevice *, struct mISDNchannel *,
52 u_int, struct sockaddr_mISDN *);
53
54extern int create_stack(struct mISDNdevice *);
55extern int create_teimanager(struct mISDNdevice *);
56extern void delete_teimanager(struct mISDNchannel *);
57extern void delete_channel(struct mISDNchannel *);
58extern void delete_stack(struct mISDNdevice *);
59extern void mISDN_initstack(u_int *);
60extern int misdn_sock_init(u_int *);
61extern void misdn_sock_cleanup(void);
62extern void add_layer2(struct mISDNchannel *, struct mISDNstack *);
63extern void __add_layer2(struct mISDNchannel *, struct mISDNstack *);
64
65extern u_int get_all_Bprotocols(void);
66struct Bprotocol *get_Bprotocol4mask(u_int);
67struct Bprotocol *get_Bprotocol4id(u_int);
68
69extern int mISDN_inittimer(u_int *);
70extern void mISDN_timer_cleanup(void);
71
72extern int l1_init(u_int *);
73extern void l1_cleanup(void);
74extern int Isdnl2_Init(u_int *);
75extern void Isdnl2_cleanup(void);
76
77#endif
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h
new file mode 100644
index 000000000000..6c3fed6b8d4f
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp.h
@@ -0,0 +1,263 @@
1/*
2 * Audio support data for ISDN4Linux.
3 *
4 * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
5 *
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
8 *
9 */
10
11#define DEBUG_DSP_CTRL 0x0001
12#define DEBUG_DSP_CORE 0x0002
13#define DEBUG_DSP_DTMF 0x0004
14#define DEBUG_DSP_CMX 0x0010
15#define DEBUG_DSP_TONE 0x0020
16#define DEBUG_DSP_BLOWFISH 0x0040
17#define DEBUG_DSP_DELAY 0x0100
18#define DEBUG_DSP_DTMFCOEFF 0x8000 /* heavy output */
19
20/* options may be:
21 *
22 * bit 0 = use ulaw instead of alaw
23 * bit 1 = enable hfc hardware accelleration for all channels
24 *
25 */
26#define DSP_OPT_ULAW (1<<0)
27#define DSP_OPT_NOHARDWARE (1<<1)
28
29#include <linux/timer.h>
30#include <linux/workqueue.h>
31
32#include "dsp_ecdis.h"
33
34extern int dsp_options;
35extern int dsp_debug;
36extern int dsp_poll;
37extern int dsp_tics;
38extern spinlock_t dsp_lock;
39extern struct work_struct dsp_workq;
40extern u32 dsp_poll_diff; /* calculated fix-comma corrected poll value */
41
42/***************
43 * audio stuff *
44 ***************/
45
46extern s32 dsp_audio_alaw_to_s32[256];
47extern s32 dsp_audio_ulaw_to_s32[256];
48extern s32 *dsp_audio_law_to_s32;
49extern u8 dsp_audio_s16_to_law[65536];
50extern u8 dsp_audio_alaw_to_ulaw[256];
51extern u8 dsp_audio_mix_law[65536];
52extern u8 dsp_audio_seven2law[128];
53extern u8 dsp_audio_law2seven[256];
54extern void dsp_audio_generate_law_tables(void);
55extern void dsp_audio_generate_s2law_table(void);
56extern void dsp_audio_generate_seven(void);
57extern void dsp_audio_generate_mix_table(void);
58extern void dsp_audio_generate_ulaw_samples(void);
59extern void dsp_audio_generate_volume_changes(void);
60extern u8 dsp_silence;
61
62
63/*************
64 * cmx stuff *
65 *************/
66
67#define MAX_POLL 256 /* maximum number of send-chunks */
68
69#define CMX_BUFF_SIZE 0x8000 /* must be 2**n (0x1000 about 1/2 second) */
70#define CMX_BUFF_HALF 0x4000 /* CMX_BUFF_SIZE / 2 */
71#define CMX_BUFF_MASK 0x7fff /* CMX_BUFF_SIZE - 1 */
72
73/* how many seconds will we check the lowest delay until the jitter buffer
74 is reduced by that delay */
75#define MAX_SECONDS_JITTER_CHECK 5
76
77extern struct timer_list dsp_spl_tl;
78extern u32 dsp_spl_jiffies;
79
80/* the structure of conferences:
81 *
82 * each conference has a unique number, given by user space.
83 * the conferences are linked in a chain.
84 * each conference has members linked in a chain.
85 * each dsplayer points to a member, each member points to a dsplayer.
86 */
87
88/* all members within a conference (this is linked 1:1 with the dsp) */
89struct dsp;
90struct dsp_conf_member {
91 struct list_head list;
92 struct dsp *dsp;
93};
94
95/* the list of all conferences */
96struct dsp_conf {
97 struct list_head list;
98 u32 id;
99 /* all cmx stacks with the same ID are
100 connected */
101 struct list_head mlist;
102 int software; /* conf is processed by software */
103 int hardware; /* conf is processed by hardware */
104 /* note: if both unset, has only one member */
105};
106
107
108/**************
109 * DTMF stuff *
110 **************/
111
112#define DSP_DTMF_NPOINTS 102
113
114#define ECHOCAN_BUFLEN (4*128)
115
116struct dsp_dtmf {
117 int treshold; /* above this is dtmf (square of) */
118 int software; /* dtmf uses software decoding */
119 int hardware; /* dtmf uses hardware decoding */
120 int size; /* number of bytes in buffer */
121 signed short buffer[DSP_DTMF_NPOINTS];
122 /* buffers one full dtmf frame */
123 u8 lastwhat, lastdigit;
124 int count;
125 u8 digits[16]; /* just the dtmf result */
126};
127
128
129/******************
130 * pipeline stuff *
131 ******************/
132struct dsp_pipeline {
133 rwlock_t lock;
134 struct list_head list;
135 int inuse;
136};
137
138/***************
139 * tones stuff *
140 ***************/
141
142struct dsp_tone {
143 int software; /* tones are generated by software */
144 int hardware; /* tones are generated by hardware */
145 int tone;
146 void *pattern;
147 int count;
148 int index;
149 struct timer_list tl;
150};
151
152/*****************
153 * general stuff *
154 *****************/
155
156struct dsp {
157 struct list_head list;
158 struct mISDNchannel ch;
159 struct mISDNchannel *up;
160 unsigned char name[64];
161 int b_active;
162 int echo; /* echo is enabled */
163 int rx_disabled; /* what the user wants */
164 int rx_is_off; /* what the card is */
165 int tx_mix;
166 struct dsp_tone tone;
167 struct dsp_dtmf dtmf;
168 int tx_volume, rx_volume;
169
170 /* queue for sending frames */
171 struct work_struct workq;
172 struct sk_buff_head sendq;
173 int hdlc; /* if mode is hdlc */
174 int data_pending; /* currently an unconfirmed frame */
175
176 /* conference stuff */
177 u32 conf_id;
178 struct dsp_conf *conf;
179 struct dsp_conf_member
180 *member;
181
182 /* buffer stuff */
183 int rx_W; /* current write pos for data without timestamp */
184 int rx_R; /* current read pos for transmit clock */
185 int rx_init; /* if set, pointers will be adjusted first */
186 int tx_W; /* current write pos for transmit data */
187 int tx_R; /* current read pos for transmit clock */
188 int rx_delay[MAX_SECONDS_JITTER_CHECK];
189 int tx_delay[MAX_SECONDS_JITTER_CHECK];
190 u8 tx_buff[CMX_BUFF_SIZE];
191 u8 rx_buff[CMX_BUFF_SIZE];
192 int last_tx; /* if set, we transmitted last poll interval */
193 int cmx_delay; /* initial delay of buffers,
194 or 0 for dynamic jitter buffer */
195 int tx_dejitter; /* if set, dejitter tx buffer */
196 int tx_data; /* enables tx-data of CMX to upper layer */
197
198 /* hardware stuff */
199 struct dsp_features features;
200 int features_rx_off; /* set if rx_off is featured */
201 int pcm_slot_rx; /* current PCM slot (or -1) */
202 int pcm_bank_rx;
203 int pcm_slot_tx;
204 int pcm_bank_tx;
205 int hfc_conf; /* unique id of current conference (or -1) */
206
207 /* encryption stuff */
208 int bf_enable;
209 u32 bf_p[18];
210 u32 bf_s[1024];
211 int bf_crypt_pos;
212 u8 bf_data_in[9];
213 u8 bf_crypt_out[9];
214 int bf_decrypt_in_pos;
215 int bf_decrypt_out_pos;
216 u8 bf_crypt_inring[16];
217 u8 bf_data_out[9];
218 int bf_sync;
219
220 struct dsp_pipeline
221 pipeline;
222};
223
224/* functions */
225
226extern void dsp_change_volume(struct sk_buff *skb, int volume);
227
228extern struct list_head dsp_ilist;
229extern struct list_head conf_ilist;
230extern void dsp_cmx_debug(struct dsp *dsp);
231extern void dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp);
232extern int dsp_cmx_conf(struct dsp *dsp, u32 conf_id);
233extern void dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb);
234extern void dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb);
235extern void dsp_cmx_send(void *arg);
236extern void dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb);
237extern int dsp_cmx_del_conf_member(struct dsp *dsp);
238extern int dsp_cmx_del_conf(struct dsp_conf *conf);
239
240extern void dsp_dtmf_goertzel_init(struct dsp *dsp);
241extern void dsp_dtmf_hardware(struct dsp *dsp);
242extern u8 *dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len,
243 int fmt);
244
245extern int dsp_tone(struct dsp *dsp, int tone);
246extern void dsp_tone_copy(struct dsp *dsp, u8 *data, int len);
247extern void dsp_tone_timeout(void *arg);
248
249extern void dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len);
250extern void dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len);
251extern int dsp_bf_init(struct dsp *dsp, const u8 *key, unsigned int keylen);
252extern void dsp_bf_cleanup(struct dsp *dsp);
253
254extern int dsp_pipeline_module_init(void);
255extern void dsp_pipeline_module_exit(void);
256extern int dsp_pipeline_init(struct dsp_pipeline *pipeline);
257extern void dsp_pipeline_destroy(struct dsp_pipeline *pipeline);
258extern int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
259extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
260 int len);
261extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
262 int len);
263
diff --git a/drivers/isdn/mISDN/dsp_audio.c b/drivers/isdn/mISDN/dsp_audio.c
new file mode 100644
index 000000000000..1c2dd5694773
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_audio.c
@@ -0,0 +1,434 @@
1/*
2 * Audio support data for mISDN_dsp.
3 *
4 * Copyright 2002/2003 by Andreas Eversberg (jolly@eversberg.eu)
5 * Rewritten by Peter
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/delay.h>
13#include <linux/mISDNif.h>
14#include <linux/mISDNdsp.h>
15#include "core.h"
16#include "dsp.h"
17
18/* ulaw[unsigned char] -> signed 16-bit */
19s32 dsp_audio_ulaw_to_s32[256];
20/* alaw[unsigned char] -> signed 16-bit */
21s32 dsp_audio_alaw_to_s32[256];
22
23s32 *dsp_audio_law_to_s32;
24EXPORT_SYMBOL(dsp_audio_law_to_s32);
25
26/* signed 16-bit -> law */
27u8 dsp_audio_s16_to_law[65536];
28EXPORT_SYMBOL(dsp_audio_s16_to_law);
29
30/* alaw -> ulaw */
31u8 dsp_audio_alaw_to_ulaw[256];
32/* ulaw -> alaw */
33u8 dsp_audio_ulaw_to_alaw[256];
34u8 dsp_silence;
35
36
37/*****************************************************
38 * generate table for conversion of s16 to alaw/ulaw *
39 *****************************************************/
40
41#define AMI_MASK 0x55
42
43static inline unsigned char linear2alaw(short int linear)
44{
45 int mask;
46 int seg;
47 int pcm_val;
48 static int seg_end[8] = {
49 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
50 };
51
52 pcm_val = linear;
53 if (pcm_val >= 0) {
54 /* Sign (7th) bit = 1 */
55 mask = AMI_MASK | 0x80;
56 } else {
57 /* Sign bit = 0 */
58 mask = AMI_MASK;
59 pcm_val = -pcm_val;
60 }
61
62 /* Convert the scaled magnitude to segment number. */
63 for (seg = 0; seg < 8; seg++) {
64 if (pcm_val <= seg_end[seg])
65 break;
66 }
67 /* Combine the sign, segment, and quantization bits. */
68 return ((seg << 4) |
69 ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
70}
71
72
73static inline short int alaw2linear(unsigned char alaw)
74{
75 int i;
76 int seg;
77
78 alaw ^= AMI_MASK;
79 i = ((alaw & 0x0F) << 4) + 8 /* rounding error */;
80 seg = (((int) alaw & 0x70) >> 4);
81 if (seg)
82 i = (i + 0x100) << (seg - 1);
83 return (short int) ((alaw & 0x80) ? i : -i);
84}
85
86static inline short int ulaw2linear(unsigned char ulaw)
87{
88 short mu, e, f, y;
89 static short etab[] = {0, 132, 396, 924, 1980, 4092, 8316, 16764};
90
91 mu = 255 - ulaw;
92 e = (mu & 0x70) / 16;
93 f = mu & 0x0f;
94 y = f * (1 << (e + 3));
95 y += etab[e];
96 if (mu & 0x80)
97 y = -y;
98 return y;
99}
100
101#define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
102
103static unsigned char linear2ulaw(short sample)
104{
105 static int exp_lut[256] = {
106 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
107 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
108 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
109 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
110 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
111 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
112 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
113 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
114 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
115 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
116 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
117 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
118 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
119 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
120 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
121 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
122 int sign, exponent, mantissa;
123 unsigned char ulawbyte;
124
125 /* Get the sample into sign-magnitude. */
126 sign = (sample >> 8) & 0x80; /* set aside the sign */
127 if (sign != 0)
128 sample = -sample; /* get magnitude */
129
130 /* Convert from 16 bit linear to ulaw. */
131 sample = sample + BIAS;
132 exponent = exp_lut[(sample >> 7) & 0xFF];
133 mantissa = (sample >> (exponent + 3)) & 0x0F;
134 ulawbyte = ~(sign | (exponent << 4) | mantissa);
135
136 return ulawbyte;
137}
138
139static int reverse_bits(int i)
140{
141 int z, j;
142 z = 0;
143
144 for (j = 0; j < 8; j++) {
145 if ((i & (1 << j)) != 0)
146 z |= 1 << (7 - j);
147 }
148 return z;
149}
150
151
152void dsp_audio_generate_law_tables(void)
153{
154 int i;
155 for (i = 0; i < 256; i++)
156 dsp_audio_alaw_to_s32[i] = alaw2linear(reverse_bits(i));
157
158 for (i = 0; i < 256; i++)
159 dsp_audio_ulaw_to_s32[i] = ulaw2linear(reverse_bits(i));
160
161 for (i = 0; i < 256; i++) {
162 dsp_audio_alaw_to_ulaw[i] =
163 linear2ulaw(dsp_audio_alaw_to_s32[i]);
164 dsp_audio_ulaw_to_alaw[i] =
165 linear2alaw(dsp_audio_ulaw_to_s32[i]);
166 }
167}
168
169void
170dsp_audio_generate_s2law_table(void)
171{
172 int i;
173
174 if (dsp_options & DSP_OPT_ULAW) {
175 /* generating ulaw-table */
176 for (i = -32768; i < 32768; i++) {
177 dsp_audio_s16_to_law[i & 0xffff] =
178 reverse_bits(linear2ulaw(i));
179 }
180 } else {
181 /* generating alaw-table */
182 for (i = -32768; i < 32768; i++) {
183 dsp_audio_s16_to_law[i & 0xffff] =
184 reverse_bits(linear2alaw(i));
185 }
186 }
187}
188
189
190/*
191 * the seven bit sample is the number of every second alaw-sample ordered by
192 * aplitude. 0x00 is negative, 0x7f is positive amplitude.
193 */
194u8 dsp_audio_seven2law[128];
195u8 dsp_audio_law2seven[256];
196
197/********************************************************************
198 * generate table for conversion law from/to 7-bit alaw-like sample *
199 ********************************************************************/
200
201void
202dsp_audio_generate_seven(void)
203{
204 int i, j, k;
205 u8 spl;
206 u8 sorted_alaw[256];
207
208 /* generate alaw table, sorted by the linear value */
209 for (i = 0; i < 256; i++) {
210 j = 0;
211 for (k = 0; k < 256; k++) {
212 if (dsp_audio_alaw_to_s32[k]
213 < dsp_audio_alaw_to_s32[i]) {
214 j++;
215 }
216 }
217 sorted_alaw[j] = i;
218 }
219
220 /* generate tabels */
221 for (i = 0; i < 256; i++) {
222 /* spl is the source: the law-sample (converted to alaw) */
223 spl = i;
224 if (dsp_options & DSP_OPT_ULAW)
225 spl = dsp_audio_ulaw_to_alaw[i];
226 /* find the 7-bit-sample */
227 for (j = 0; j < 256; j++) {
228 if (sorted_alaw[j] == spl)
229 break;
230 }
231 /* write 7-bit audio value */
232 dsp_audio_law2seven[i] = j >> 1;
233 }
234 for (i = 0; i < 128; i++) {
235 spl = sorted_alaw[i << 1];
236 if (dsp_options & DSP_OPT_ULAW)
237 spl = dsp_audio_alaw_to_ulaw[spl];
238 dsp_audio_seven2law[i] = spl;
239 }
240}
241
242
243/* mix 2*law -> law */
244u8 dsp_audio_mix_law[65536];
245
246/******************************************************
247 * generate mix table to mix two law samples into one *
248 ******************************************************/
249
250void
251dsp_audio_generate_mix_table(void)
252{
253 int i, j;
254 s32 sample;
255
256 i = 0;
257 while (i < 256) {
258 j = 0;
259 while (j < 256) {
260 sample = dsp_audio_law_to_s32[i];
261 sample += dsp_audio_law_to_s32[j];
262 if (sample > 32767)
263 sample = 32767;
264 if (sample < -32768)
265 sample = -32768;
266 dsp_audio_mix_law[(i<<8)|j] =
267 dsp_audio_s16_to_law[sample & 0xffff];
268 j++;
269 }
270 i++;
271 }
272}
273
274
275/*************************************
276 * generate different volume changes *
277 *************************************/
278
279static u8 dsp_audio_reduce8[256];
280static u8 dsp_audio_reduce7[256];
281static u8 dsp_audio_reduce6[256];
282static u8 dsp_audio_reduce5[256];
283static u8 dsp_audio_reduce4[256];
284static u8 dsp_audio_reduce3[256];
285static u8 dsp_audio_reduce2[256];
286static u8 dsp_audio_reduce1[256];
287static u8 dsp_audio_increase1[256];
288static u8 dsp_audio_increase2[256];
289static u8 dsp_audio_increase3[256];
290static u8 dsp_audio_increase4[256];
291static u8 dsp_audio_increase5[256];
292static u8 dsp_audio_increase6[256];
293static u8 dsp_audio_increase7[256];
294static u8 dsp_audio_increase8[256];
295
296static u8 *dsp_audio_volume_change[16] = {
297 dsp_audio_reduce8,
298 dsp_audio_reduce7,
299 dsp_audio_reduce6,
300 dsp_audio_reduce5,
301 dsp_audio_reduce4,
302 dsp_audio_reduce3,
303 dsp_audio_reduce2,
304 dsp_audio_reduce1,
305 dsp_audio_increase1,
306 dsp_audio_increase2,
307 dsp_audio_increase3,
308 dsp_audio_increase4,
309 dsp_audio_increase5,
310 dsp_audio_increase6,
311 dsp_audio_increase7,
312 dsp_audio_increase8,
313};
314
315void
316dsp_audio_generate_volume_changes(void)
317{
318 register s32 sample;
319 int i;
320 int num[] = { 110, 125, 150, 175, 200, 300, 400, 500 };
321 int denum[] = { 100, 100, 100, 100, 100, 100, 100, 100 };
322
323 i = 0;
324 while (i < 256) {
325 dsp_audio_reduce8[i] = dsp_audio_s16_to_law[
326 (dsp_audio_law_to_s32[i] * denum[7] / num[7]) & 0xffff];
327 dsp_audio_reduce7[i] = dsp_audio_s16_to_law[
328 (dsp_audio_law_to_s32[i] * denum[6] / num[6]) & 0xffff];
329 dsp_audio_reduce6[i] = dsp_audio_s16_to_law[
330 (dsp_audio_law_to_s32[i] * denum[5] / num[5]) & 0xffff];
331 dsp_audio_reduce5[i] = dsp_audio_s16_to_law[
332 (dsp_audio_law_to_s32[i] * denum[4] / num[4]) & 0xffff];
333 dsp_audio_reduce4[i] = dsp_audio_s16_to_law[
334 (dsp_audio_law_to_s32[i] * denum[3] / num[3]) & 0xffff];
335 dsp_audio_reduce3[i] = dsp_audio_s16_to_law[
336 (dsp_audio_law_to_s32[i] * denum[2] / num[2]) & 0xffff];
337 dsp_audio_reduce2[i] = dsp_audio_s16_to_law[
338 (dsp_audio_law_to_s32[i] * denum[1] / num[1]) & 0xffff];
339 dsp_audio_reduce1[i] = dsp_audio_s16_to_law[
340 (dsp_audio_law_to_s32[i] * denum[0] / num[0]) & 0xffff];
341 sample = dsp_audio_law_to_s32[i] * num[0] / denum[0];
342 if (sample < -32768)
343 sample = -32768;
344 else if (sample > 32767)
345 sample = 32767;
346 dsp_audio_increase1[i] = dsp_audio_s16_to_law[sample & 0xffff];
347 sample = dsp_audio_law_to_s32[i] * num[1] / denum[1];
348 if (sample < -32768)
349 sample = -32768;
350 else if (sample > 32767)
351 sample = 32767;
352 dsp_audio_increase2[i] = dsp_audio_s16_to_law[sample & 0xffff];
353 sample = dsp_audio_law_to_s32[i] * num[2] / denum[2];
354 if (sample < -32768)
355 sample = -32768;
356 else if (sample > 32767)
357 sample = 32767;
358 dsp_audio_increase3[i] = dsp_audio_s16_to_law[sample & 0xffff];
359 sample = dsp_audio_law_to_s32[i] * num[3] / denum[3];
360 if (sample < -32768)
361 sample = -32768;
362 else if (sample > 32767)
363 sample = 32767;
364 dsp_audio_increase4[i] = dsp_audio_s16_to_law[sample & 0xffff];
365 sample = dsp_audio_law_to_s32[i] * num[4] / denum[4];
366 if (sample < -32768)
367 sample = -32768;
368 else if (sample > 32767)
369 sample = 32767;
370 dsp_audio_increase5[i] = dsp_audio_s16_to_law[sample & 0xffff];
371 sample = dsp_audio_law_to_s32[i] * num[5] / denum[5];
372 if (sample < -32768)
373 sample = -32768;
374 else if (sample > 32767)
375 sample = 32767;
376 dsp_audio_increase6[i] = dsp_audio_s16_to_law[sample & 0xffff];
377 sample = dsp_audio_law_to_s32[i] * num[6] / denum[6];
378 if (sample < -32768)
379 sample = -32768;
380 else if (sample > 32767)
381 sample = 32767;
382 dsp_audio_increase7[i] = dsp_audio_s16_to_law[sample & 0xffff];
383 sample = dsp_audio_law_to_s32[i] * num[7] / denum[7];
384 if (sample < -32768)
385 sample = -32768;
386 else if (sample > 32767)
387 sample = 32767;
388 dsp_audio_increase8[i] = dsp_audio_s16_to_law[sample & 0xffff];
389
390 i++;
391 }
392}
393
394
395/**************************************
396 * change the volume of the given skb *
397 **************************************/
398
399/* this is a helper function for changing volume of skb. the range may be
400 * -8 to 8, which is a shift to the power of 2. 0 == no volume, 3 == volume*8
401 */
402void
403dsp_change_volume(struct sk_buff *skb, int volume)
404{
405 u8 *volume_change;
406 int i, ii;
407 u8 *p;
408 int shift;
409
410 if (volume == 0)
411 return;
412
413 /* get correct conversion table */
414 if (volume < 0) {
415 shift = volume + 8;
416 if (shift < 0)
417 shift = 0;
418 } else {
419 shift = volume + 7;
420 if (shift > 15)
421 shift = 15;
422 }
423 volume_change = dsp_audio_volume_change[shift];
424 i = 0;
425 ii = skb->len;
426 p = skb->data;
427 /* change volume */
428 while (i < ii) {
429 *p = volume_change[*p];
430 p++;
431 i++;
432 }
433}
434
diff --git a/drivers/isdn/mISDN/dsp_biquad.h b/drivers/isdn/mISDN/dsp_biquad.h
new file mode 100644
index 000000000000..038191bc45f5
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_biquad.h
@@ -0,0 +1,65 @@
1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * biquad.h - General telephony bi-quad section routines (currently this just
5 * handles canonic/type 2 form)
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2001 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 *
27 */
28
29struct biquad2_state {
30 int32_t gain;
31 int32_t a1;
32 int32_t a2;
33 int32_t b1;
34 int32_t b2;
35
36 int32_t z1;
37 int32_t z2;
38};
39
40static inline void biquad2_init(struct biquad2_state *bq,
41 int32_t gain, int32_t a1, int32_t a2, int32_t b1, int32_t b2)
42{
43 bq->gain = gain;
44 bq->a1 = a1;
45 bq->a2 = a2;
46 bq->b1 = b1;
47 bq->b2 = b2;
48
49 bq->z1 = 0;
50 bq->z2 = 0;
51}
52
53static inline int16_t biquad2(struct biquad2_state *bq, int16_t sample)
54{
55 int32_t y;
56 int32_t z0;
57
58 z0 = sample*bq->gain + bq->z1*bq->a1 + bq->z2*bq->a2;
59 y = z0 + bq->z1*bq->b1 + bq->z2*bq->b2;
60
61 bq->z2 = bq->z1;
62 bq->z1 = z0 >> 15;
63 y >>= 15;
64 return y;
65}
diff --git a/drivers/isdn/mISDN/dsp_blowfish.c b/drivers/isdn/mISDN/dsp_blowfish.c
new file mode 100644
index 000000000000..18e411e95bba
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_blowfish.c
@@ -0,0 +1,672 @@
1/*
2 * Blowfish encryption/decryption for mISDN_dsp.
3 *
4 * Copyright Andreas Eversberg (jolly@eversberg.eu)
5 *
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
8 *
9 */
10
11#include <linux/mISDNif.h>
12#include <linux/mISDNdsp.h>
13#include "core.h"
14#include "dsp.h"
15
16/*
17 * how to encode a sample stream to 64-bit blocks that will be encryped
18 *
19 * first of all, data is collected until a block of 9 samples are received.
20 * of course, a packet may have much more than 9 sample, but is may have
21 * not excacly the multiple of 9 samples. if there is a rest, the next
22 * received data will complete the block.
23 *
24 * the block is then converted to 9 uLAW samples without the least sigificant
25 * bit. the result is a 7-bit encoded sample.
26 *
27 * the samples will be reoganised to form 8 bytes of data:
28 * (5(6) means: encoded sample no. 5, bit 6)
29 *
30 * 0(6) 0(5) 0(4) 0(3) 0(2) 0(1) 0(0) 1(6)
31 * 1(5) 1(4) 1(3) 1(2) 1(1) 1(0) 2(6) 2(5)
32 * 2(4) 2(3) 2(2) 2(1) 2(0) 3(6) 3(5) 3(4)
33 * 3(3) 3(2) 3(1) 3(0) 4(6) 4(5) 4(4) 4(3)
34 * 4(2) 4(1) 4(0) 5(6) 5(5) 5(4) 5(3) 5(2)
35 * 5(1) 5(0) 6(6) 6(5) 6(4) 6(3) 6(2) 6(1)
36 * 6(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0)
37 * 8(6) 8(5) 8(4) 8(3) 8(2) 8(1) 8(0)
38 *
39 * the missing bit 0 of the last byte is filled with some
40 * random noise, to fill all 8 bytes.
41 *
42 * the 8 bytes will be encrypted using blowfish.
43 *
44 * the result will be converted into 9 bytes. the bit 7 is used for
45 * checksumme (CS) for sync (0, 1) and for the last bit:
46 * (5(6) means: crypted byte 5, bit 6)
47 *
48 * 1 0(7) 0(6) 0(5) 0(4) 0(3) 0(2) 0(1)
49 * 0 0(0) 1(7) 1(6) 1(5) 1(4) 1(3) 1(2)
50 * 0 1(1) 1(0) 2(7) 2(6) 2(5) 2(4) 2(3)
51 * 0 2(2) 2(1) 2(0) 3(7) 3(6) 3(5) 3(4)
52 * 0 3(3) 3(2) 3(1) 3(0) 4(7) 4(6) 4(5)
53 * CS 4(4) 4(3) 4(2) 4(1) 4(0) 5(7) 5(6)
54 * CS 5(5) 5(4) 5(3) 5(2) 5(1) 5(0) 6(7)
55 * CS 6(6) 6(5) 6(4) 6(3) 6(2) 6(1) 6(0)
56 * 7(0) 7(6) 7(5) 7(4) 7(3) 7(2) 7(1) 7(0)
57 *
58 * the checksum is used to detect transmission errors and frame drops.
59 *
60 * synchronisation of received block is done by shifting the upper bit of each
61 * byte (bit 7) to a shift register. if the rigister has the first five bits
62 * (10000), this is used to find the sync. only if sync has been found, the
63 * current block of 9 received bytes are decrypted. before that the check
64 * sum is calculated. if it is incorrect the block is dropped.
65 * this will avoid loud noise due to corrupt encrypted data.
66 *
67 * if the last block is corrupt, the current decoded block is repeated
68 * until a valid block has been received.
69 */
70
71/*
72 * some blowfish parts are taken from the
73 * crypto-api for faster implementation
74 */
75
76struct bf_ctx {
77 u32 p[18];
78 u32 s[1024];
79};
80
81static const u32 bf_pbox[16 + 2] = {
82 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
83 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
84 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
85 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
86 0x9216d5d9, 0x8979fb1b,
87};
88
89static const u32 bf_sbox[256 * 4] = {
90 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
91 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
92 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
93 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
94 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
95 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
96 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
97 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
98 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
99 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
100 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
101 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
102 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
103 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
104 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
105 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
106 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
107 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
108 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
109 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
110 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
111 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
112 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
113 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
114 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
115 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
116 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
117 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
118 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
119 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
120 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
121 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
122 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
123 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
124 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
125 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
126 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
127 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
128 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
129 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
130 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
131 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
132 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
133 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
134 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
135 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
136 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
137 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
138 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
139 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
140 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
141 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
142 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
143 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
144 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
145 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
146 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
147 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
148 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
149 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
150 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
151 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
152 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
153 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
154 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
155 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
156 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
157 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
158 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
159 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
160 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
161 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
162 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
163 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
164 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
165 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
166 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
167 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
168 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
169 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
170 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
171 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
172 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
173 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
174 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
175 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
176 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
177 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
178 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
179 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
180 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
181 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
182 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
183 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
184 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
185 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
186 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
187 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
188 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
189 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
190 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
191 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
192 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
193 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
194 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
195 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
196 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
197 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
198 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
199 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
200 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
201 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
202 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
203 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
204 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
205 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
206 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
207 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
208 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
209 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
210 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
211 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
212 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
213 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
214 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
215 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
216 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
217 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
218 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
219 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
220 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
221 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
222 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
223 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
224 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
225 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
226 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
227 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
228 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
229 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
230 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
231 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
232 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
233 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
234 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
235 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
236 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
237 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
238 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
239 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
240 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
241 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
242 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
243 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
244 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
245 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
246 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
247 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
248 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
249 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
250 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
251 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
252 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
253 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
254 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
255 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
256 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
257 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
258 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
259 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
260 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
261 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
262 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
263 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
264 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
265 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
266 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
267 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
268 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
269 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
270 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
271 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
272 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
273 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
274 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
275 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
276 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
277 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
278 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
279 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
280 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
281 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
282 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
283 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
284 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
285 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
286 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
287 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
288 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
289 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
290 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
291 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
292 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
293 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
294 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
295 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
296 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
297 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
298 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
299 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
300 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
301 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
302 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
303 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
304 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
305 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
306 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
307 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
308 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
309 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
310 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
311 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
312 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
313 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
314 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
315 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
316 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
317 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
318 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
319 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
320 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
321 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
322 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
323 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
324 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
325 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
326 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
327 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
328 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
329 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
330 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
331 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
332 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
333 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
334 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
335 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
336 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
337 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
338 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
339 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
340 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
341 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
342 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
343 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
344 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
345 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
346};
347
348/*
349 * Round loop unrolling macros, S is a pointer to a S-Box array
350 * organized in 4 unsigned longs at a row.
351 */
352#define GET32_3(x) (((x) & 0xff))
353#define GET32_2(x) (((x) >> (8)) & (0xff))
354#define GET32_1(x) (((x) >> (16)) & (0xff))
355#define GET32_0(x) (((x) >> (24)) & (0xff))
356
357#define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \
358 S[512 + GET32_2(x)]) + S[768 + GET32_3(x)])
359
360#define EROUND(a, b, n) do { b ^= P[n]; a ^= bf_F(b); } while (0)
361#define DROUND(a, b, n) do { a ^= bf_F(b); b ^= P[n]; } while (0)
362
363
364/*
365 * encrypt isdn data frame
366 * every block with 9 samples is encrypted
367 */
368void
369dsp_bf_encrypt(struct dsp *dsp, u8 *data, int len)
370{
371 int i = 0, j = dsp->bf_crypt_pos;
372 u8 *bf_data_in = dsp->bf_data_in;
373 u8 *bf_crypt_out = dsp->bf_crypt_out;
374 u32 *P = dsp->bf_p;
375 u32 *S = dsp->bf_s;
376 u32 yl, yr;
377 u32 cs;
378 u8 nibble;
379
380 while (i < len) {
381 /* collect a block of 9 samples */
382 if (j < 9) {
383 bf_data_in[j] = *data;
384 *data++ = bf_crypt_out[j++];
385 i++;
386 continue;
387 }
388 j = 0;
389 /* transcode 9 samples xlaw to 8 bytes */
390 yl = dsp_audio_law2seven[bf_data_in[0]];
391 yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[1]];
392 yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[2]];
393 yl = (yl<<7) | dsp_audio_law2seven[bf_data_in[3]];
394 nibble = dsp_audio_law2seven[bf_data_in[4]];
395 yr = nibble;
396 yl = (yl<<4) | (nibble>>3);
397 yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[5]];
398 yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[6]];
399 yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[7]];
400 yr = (yr<<7) | dsp_audio_law2seven[bf_data_in[8]];
401 yr = (yr<<1) | (bf_data_in[0] & 1);
402
403 /* fill unused bit with random noise of audio input */
404 /* encrypt */
405
406 EROUND(yr, yl, 0);
407 EROUND(yl, yr, 1);
408 EROUND(yr, yl, 2);
409 EROUND(yl, yr, 3);
410 EROUND(yr, yl, 4);
411 EROUND(yl, yr, 5);
412 EROUND(yr, yl, 6);
413 EROUND(yl, yr, 7);
414 EROUND(yr, yl, 8);
415 EROUND(yl, yr, 9);
416 EROUND(yr, yl, 10);
417 EROUND(yl, yr, 11);
418 EROUND(yr, yl, 12);
419 EROUND(yl, yr, 13);
420 EROUND(yr, yl, 14);
421 EROUND(yl, yr, 15);
422 yl ^= P[16];
423 yr ^= P[17];
424
425 /* calculate 3-bit checksumme */
426 cs = yl ^ (yl>>3) ^ (yl>>6) ^ (yl>>9) ^ (yl>>12) ^ (yl>>15)
427 ^ (yl>>18) ^ (yl>>21) ^ (yl>>24) ^ (yl>>27) ^ (yl>>30)
428 ^ (yr<<2) ^ (yr>>1) ^ (yr>>4) ^ (yr>>7) ^ (yr>>10)
429 ^ (yr>>13) ^ (yr>>16) ^ (yr>>19) ^ (yr>>22) ^ (yr>>25)
430 ^ (yr>>28) ^ (yr>>31);
431
432 /*
433 * transcode 8 crypted bytes to 9 data bytes with sync
434 * and checksum information
435 */
436 bf_crypt_out[0] = (yl>>25) | 0x80;
437 bf_crypt_out[1] = (yl>>18) & 0x7f;
438 bf_crypt_out[2] = (yl>>11) & 0x7f;
439 bf_crypt_out[3] = (yl>>4) & 0x7f;
440 bf_crypt_out[4] = ((yl<<3) & 0x78) | ((yr>>29) & 0x07);
441 bf_crypt_out[5] = ((yr>>22) & 0x7f) | ((cs<<5) & 0x80);
442 bf_crypt_out[6] = ((yr>>15) & 0x7f) | ((cs<<6) & 0x80);
443 bf_crypt_out[7] = ((yr>>8) & 0x7f) | (cs<<7);
444 bf_crypt_out[8] = yr;
445 }
446
447 /* write current count */
448 dsp->bf_crypt_pos = j;
449
450}
451
452
453/*
454 * decrypt isdn data frame
455 * every block with 9 bytes is decrypted
456 */
457void
458dsp_bf_decrypt(struct dsp *dsp, u8 *data, int len)
459{
460 int i = 0;
461 u8 j = dsp->bf_decrypt_in_pos;
462 u8 k = dsp->bf_decrypt_out_pos;
463 u8 *bf_crypt_inring = dsp->bf_crypt_inring;
464 u8 *bf_data_out = dsp->bf_data_out;
465 u16 sync = dsp->bf_sync;
466 u32 *P = dsp->bf_p;
467 u32 *S = dsp->bf_s;
468 u32 yl, yr;
469 u8 nibble;
470 u8 cs, cs0, cs1, cs2;
471
472 while (i < len) {
473 /*
474 * shift upper bit and rotate data to buffer ring
475 * send current decrypted data
476 */
477 sync = (sync<<1) | ((*data)>>7);
478 bf_crypt_inring[j++ & 15] = *data;
479 *data++ = bf_data_out[k++];
480 i++;
481 if (k == 9)
482 k = 0; /* repeat if no sync has been found */
483 /* check if not in sync */
484 if ((sync&0x1f0) != 0x100)
485 continue;
486 j -= 9;
487 /* transcode receive data to 64 bit block of encrypted data */
488 yl = bf_crypt_inring[j++ & 15];
489 yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
490 yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
491 yl = (yl<<7) | bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
492 nibble = bf_crypt_inring[j++ & 15]; /* bit7 = 0 */
493 yr = nibble;
494 yl = (yl<<4) | (nibble>>3);
495 cs2 = bf_crypt_inring[j++ & 15];
496 yr = (yr<<7) | (cs2 & 0x7f);
497 cs1 = bf_crypt_inring[j++ & 15];
498 yr = (yr<<7) | (cs1 & 0x7f);
499 cs0 = bf_crypt_inring[j++ & 15];
500 yr = (yr<<7) | (cs0 & 0x7f);
501 yr = (yr<<8) | bf_crypt_inring[j++ & 15];
502
503 /* calculate 3-bit checksumme */
504 cs = yl ^ (yl>>3) ^ (yl>>6) ^ (yl>>9) ^ (yl>>12) ^ (yl>>15)
505 ^ (yl>>18) ^ (yl>>21) ^ (yl>>24) ^ (yl>>27) ^ (yl>>30)
506 ^ (yr<<2) ^ (yr>>1) ^ (yr>>4) ^ (yr>>7) ^ (yr>>10)
507 ^ (yr>>13) ^ (yr>>16) ^ (yr>>19) ^ (yr>>22) ^ (yr>>25)
508 ^ (yr>>28) ^ (yr>>31);
509
510 /* check if frame is valid */
511 if ((cs&0x7) != (((cs2>>5)&4) | ((cs1>>6)&2) | (cs0 >> 7))) {
512 if (dsp_debug & DEBUG_DSP_BLOWFISH)
513 printk(KERN_DEBUG
514 "DSP BLOWFISH: received corrupt frame, "
515 "checksumme is not correct\n");
516 continue;
517 }
518
519 /* decrypt */
520 yr ^= P[17];
521 yl ^= P[16];
522 DROUND(yl, yr, 15);
523 DROUND(yr, yl, 14);
524 DROUND(yl, yr, 13);
525 DROUND(yr, yl, 12);
526 DROUND(yl, yr, 11);
527 DROUND(yr, yl, 10);
528 DROUND(yl, yr, 9);
529 DROUND(yr, yl, 8);
530 DROUND(yl, yr, 7);
531 DROUND(yr, yl, 6);
532 DROUND(yl, yr, 5);
533 DROUND(yr, yl, 4);
534 DROUND(yl, yr, 3);
535 DROUND(yr, yl, 2);
536 DROUND(yl, yr, 1);
537 DROUND(yr, yl, 0);
538
539 /* transcode 8 crypted bytes to 9 sample bytes */
540 bf_data_out[0] = dsp_audio_seven2law[(yl>>25) & 0x7f];
541 bf_data_out[1] = dsp_audio_seven2law[(yl>>18) & 0x7f];
542 bf_data_out[2] = dsp_audio_seven2law[(yl>>11) & 0x7f];
543 bf_data_out[3] = dsp_audio_seven2law[(yl>>4) & 0x7f];
544 bf_data_out[4] = dsp_audio_seven2law[((yl<<3) & 0x78) |
545 ((yr>>29) & 0x07)];
546
547 bf_data_out[5] = dsp_audio_seven2law[(yr>>22) & 0x7f];
548 bf_data_out[6] = dsp_audio_seven2law[(yr>>15) & 0x7f];
549 bf_data_out[7] = dsp_audio_seven2law[(yr>>8) & 0x7f];
550 bf_data_out[8] = dsp_audio_seven2law[(yr>>1) & 0x7f];
551 k = 0; /* start with new decoded frame */
552 }
553
554 /* write current count and sync */
555 dsp->bf_decrypt_in_pos = j;
556 dsp->bf_decrypt_out_pos = k;
557 dsp->bf_sync = sync;
558}
559
560
561/* used to encrypt S and P boxes */
562static inline void
563encrypt_block(const u32 *P, const u32 *S, u32 *dst, u32 *src)
564{
565 u32 yl = src[0];
566 u32 yr = src[1];
567
568 EROUND(yr, yl, 0);
569 EROUND(yl, yr, 1);
570 EROUND(yr, yl, 2);
571 EROUND(yl, yr, 3);
572 EROUND(yr, yl, 4);
573 EROUND(yl, yr, 5);
574 EROUND(yr, yl, 6);
575 EROUND(yl, yr, 7);
576 EROUND(yr, yl, 8);
577 EROUND(yl, yr, 9);
578 EROUND(yr, yl, 10);
579 EROUND(yl, yr, 11);
580 EROUND(yr, yl, 12);
581 EROUND(yl, yr, 13);
582 EROUND(yr, yl, 14);
583 EROUND(yl, yr, 15);
584
585 yl ^= P[16];
586 yr ^= P[17];
587
588 dst[0] = yr;
589 dst[1] = yl;
590}
591
592/*
593 * initialize the dsp for encryption and decryption using the same key
594 * Calculates the blowfish S and P boxes for encryption and decryption.
595 * The margin of keylen must be 4-56 bytes.
596 * returns 0 if ok.
597 */
598int
599dsp_bf_init(struct dsp *dsp, const u8 *key, uint keylen)
600{
601 short i, j, count;
602 u32 data[2], temp;
603 u32 *P = (u32 *)dsp->bf_p;
604 u32 *S = (u32 *)dsp->bf_s;
605
606 if (keylen < 4 || keylen > 56)
607 return 1;
608
609 /* Set dsp states */
610 i = 0;
611 while (i < 9) {
612 dsp->bf_crypt_out[i] = 0xff;
613 dsp->bf_data_out[i] = dsp_silence;
614 i++;
615 }
616 dsp->bf_crypt_pos = 0;
617 dsp->bf_decrypt_in_pos = 0;
618 dsp->bf_decrypt_out_pos = 0;
619 dsp->bf_sync = 0x1ff;
620 dsp->bf_enable = 1;
621
622 /* Copy the initialization s-boxes */
623 for (i = 0, count = 0; i < 256; i++)
624 for (j = 0; j < 4; j++, count++)
625 S[count] = bf_sbox[count];
626
627 /* Set the p-boxes */
628 for (i = 0; i < 16 + 2; i++)
629 P[i] = bf_pbox[i];
630
631 /* Actual subkey generation */
632 for (j = 0, i = 0; i < 16 + 2; i++) {
633 temp = (((u32)key[j] << 24) |
634 ((u32)key[(j + 1) % keylen] << 16) |
635 ((u32)key[(j + 2) % keylen] << 8) |
636 ((u32)key[(j + 3) % keylen]));
637
638 P[i] = P[i] ^ temp;
639 j = (j + 4) % keylen;
640 }
641
642 data[0] = 0x00000000;
643 data[1] = 0x00000000;
644
645 for (i = 0; i < 16 + 2; i += 2) {
646 encrypt_block(P, S, data, data);
647
648 P[i] = data[0];
649 P[i + 1] = data[1];
650 }
651
652 for (i = 0; i < 4; i++) {
653 for (j = 0, count = i * 256; j < 256; j += 2, count += 2) {
654 encrypt_block(P, S, data, data);
655
656 S[count] = data[0];
657 S[count + 1] = data[1];
658 }
659 }
660
661 return 0;
662}
663
664
665/*
666 * turn encryption off
667 */
668void
669dsp_bf_cleanup(struct dsp *dsp)
670{
671 dsp->bf_enable = 0;
672}
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
new file mode 100644
index 000000000000..e92b1ba4b45e
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -0,0 +1,1886 @@
1/*
2 * Audio crossconnecting/conferrencing (hardware level).
3 *
4 * Copyright 2002 by Andreas Eversberg (jolly@eversberg.eu)
5 *
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
8 *
9 */
10
11/*
12 * The process of adding and removing parties to/from a conference:
13 *
14 * There is a chain of struct dsp_conf which has one or more members in a chain
15 * of struct dsp_conf_member.
16 *
17 * After a party is added, the conference is checked for hardware capability.
18 * Also if a party is removed, the conference is checked again.
19 *
20 * There are 3 different solutions: -1 = software, 0 = hardware-crossconnect
21 * 1-n = hardware-conference. The n will give the conference number.
22 *
23 * Depending on the change after removal or insertion of a party, hardware
24 * commands are given.
25 *
26 * The current solution is stored within the struct dsp_conf entry.
27 */
28
29/*
30 * HOW THE CMX WORKS:
31 *
32 * There are 3 types of interaction: One member is alone, in this case only
33 * data flow from upper to lower layer is done.
34 * Two members will also exchange their data so they are crossconnected.
35 * Three or more members will be added in a conference and will hear each
36 * other but will not receive their own speech (echo) if not enabled.
37 *
38 * Features of CMX are:
39 * - Crossconnecting or even conference, if more than two members are together.
40 * - Force mixing of transmit data with other crossconnect/conference members.
41 * - Echo generation to benchmark the delay of audio processing.
42 * - Use hardware to minimize cpu load, disable FIFO load and minimize delay.
43 * - Dejittering and clock generation.
44 *
45 * There are 2 buffers:
46 *
47 *
48 * RX-Buffer
49 * R W
50 * | |
51 * ----------------+-------------+-------------------
52 *
53 * The rx-buffer is a ring buffer used to store the received data for each
54 * individual member. This is only the case if data needs to be dejittered
55 * or in case of a conference where different clocks require reclocking.
56 * The transmit-clock (R) will read the buffer.
57 * If the clock overruns the write-pointer, we will have a buffer underrun.
58 * If the write pointer always has a certain distance from the transmit-
59 * clock, we will have a delay. The delay will dynamically be increased and
60 * reduced.
61 *
62 *
63 * TX-Buffer
64 * R W
65 * | |
66 * -----------------+--------+-----------------------
67 *
68 * The tx-buffer is a ring buffer to queue the transmit data from user space
69 * until it will be mixed or sent. There are two pointers, R and W. If the write
70 * pointer W would reach or overrun R, the buffer would overrun. In this case
71 * (some) data is dropped so that it will not overrun.
72 * Additionally a dynamic dejittering can be enabled. this allows data from
73 * user space that have jitter and different clock source.
74 *
75 *
76 * Clock:
77 *
78 * A Clock is not required, if the data source has exactly one clock. In this
79 * case the data source is forwarded to the destination.
80 *
81 * A Clock is required, because the data source
82 * - has multiple clocks.
83 * - has no usable clock due to jitter or packet loss (VoIP).
84 * In this case the system's clock is used. The clock resolution depends on
85 * the jiffie resolution.
86 *
87 * If a member joins a conference:
88 *
89 * - If a member joins, its rx_buff is set to silence and change read pointer
90 * to transmit clock.
91 *
92 * The procedure of received data from card is explained in cmx_receive.
93 * The procedure of received data from user space is explained in cmx_transmit.
94 * The procedure of transmit data to card is cmx_send.
95 *
96 *
97 * Interaction with other features:
98 *
99 * DTMF:
100 * DTMF decoding is done before the data is crossconnected.
101 *
102 * Volume change:
103 * Changing rx-volume is done before the data is crossconnected. The tx-volume
104 * must be changed whenever data is transmitted to the card by the cmx.
105 *
106 * Tones:
107 * If a tone is enabled, it will be processed whenever data is transmitted to
108 * the card. It will replace the tx-data from the user space.
109 * If tones are generated by hardware, this conference member is removed for
110 * this time.
111 *
112 * Disable rx-data:
113 * If cmx is realized in hardware, rx data will be disabled if requested by
114 * the upper layer. If dtmf decoding is done by software and enabled, rx data
115 * will not be diabled but blocked to the upper layer.
116 *
117 * HFC conference engine:
118 * If it is possible to realize all features using hardware, hardware will be
119 * used if not forbidden by control command. Disabling rx-data provides
120 * absolutely traffic free audio processing. (except for the quick 1-frame
121 * upload of a tone loop, only once for a new tone)
122 *
123 */
124
125/* delay.h is required for hw_lock.h */
126
127#include <linux/delay.h>
128#include <linux/mISDNif.h>
129#include <linux/mISDNdsp.h>
130#include "core.h"
131#include "dsp.h"
132/*
133 * debugging of multi party conference,
134 * by using conference even with two members
135 */
136
137/* #define CMX_CONF_DEBUG */
138
139/*#define CMX_DEBUG * massive read/write pointer output */
140/*#define CMX_TX_DEBUG * massive read/write on tx-buffer with content */
141
142static inline int
143count_list_member(struct list_head *head)
144{
145 int cnt = 0;
146 struct list_head *m;
147
148 list_for_each(m, head)
149 cnt++;
150 return cnt;
151}
152
153/*
154 * debug cmx memory structure
155 */
156void
157dsp_cmx_debug(struct dsp *dsp)
158{
159 struct dsp_conf *conf;
160 struct dsp_conf_member *member;
161 struct dsp *odsp;
162
163 printk(KERN_DEBUG "-----Current DSP\n");
164 list_for_each_entry(odsp, &dsp_ilist, list) {
165 printk(KERN_DEBUG "* %s echo=%d txmix=%d",
166 odsp->name, odsp->echo, odsp->tx_mix);
167 if (odsp->conf)
168 printk(" (Conf %d)", odsp->conf->id);
169 if (dsp == odsp)
170 printk(" *this*");
171 printk("\n");
172 }
173 printk(KERN_DEBUG "-----Current Conf:\n");
174 list_for_each_entry(conf, &conf_ilist, list) {
175 printk(KERN_DEBUG "* Conf %d (%p)\n", conf->id, conf);
176 list_for_each_entry(member, &conf->mlist, list) {
177 printk(KERN_DEBUG
178 " - member = %s (slot_tx %d, bank_tx %d, "
179 "slot_rx %d, bank_rx %d hfc_conf %d)%s\n",
180 member->dsp->name, member->dsp->pcm_slot_tx,
181 member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
182 member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
183 (member->dsp == dsp) ? " *this*" : "");
184 }
185 }
186 printk(KERN_DEBUG "-----end\n");
187}
188
189/*
190 * search conference
191 */
192static struct dsp_conf *
193dsp_cmx_search_conf(u32 id)
194{
195 struct dsp_conf *conf;
196
197 if (!id) {
198 printk(KERN_WARNING "%s: conference ID is 0.\n", __func__);
199 return NULL;
200 }
201
202 /* search conference */
203 list_for_each_entry(conf, &conf_ilist, list)
204 if (conf->id == id)
205 return conf;
206
207 return NULL;
208}
209
210
211/*
212 * add member to conference
213 */
214static int
215dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
216{
217 struct dsp_conf_member *member;
218
219 if (!conf || !dsp) {
220 printk(KERN_WARNING "%s: conf or dsp is 0.\n", __func__);
221 return -EINVAL;
222 }
223 if (dsp->member) {
224 printk(KERN_WARNING "%s: dsp is already member in a conf.\n",
225 __func__);
226 return -EINVAL;
227 }
228
229 if (dsp->conf) {
230 printk(KERN_WARNING "%s: dsp is already in a conf.\n",
231 __func__);
232 return -EINVAL;
233 }
234
235 member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC);
236 if (!member) {
237 printk(KERN_ERR "kmalloc struct dsp_conf_member failed\n");
238 return -ENOMEM;
239 }
240 member->dsp = dsp;
241 /* clear rx buffer */
242 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
243 dsp->rx_init = 1; /* rx_W and rx_R will be adjusted on first frame */
244 dsp->rx_W = 0;
245 dsp->rx_R = 0;
246
247 list_add_tail(&member->list, &conf->mlist);
248
249 dsp->conf = conf;
250 dsp->member = member;
251
252 return 0;
253}
254
255
256/*
257 * del member from conference
258 */
259int
260dsp_cmx_del_conf_member(struct dsp *dsp)
261{
262 struct dsp_conf_member *member;
263
264 if (!dsp) {
265 printk(KERN_WARNING "%s: dsp is 0.\n",
266 __func__);
267 return -EINVAL;
268 }
269
270 if (!dsp->conf) {
271 printk(KERN_WARNING "%s: dsp is not in a conf.\n",
272 __func__);
273 return -EINVAL;
274 }
275
276 if (list_empty(&dsp->conf->mlist)) {
277 printk(KERN_WARNING "%s: dsp has linked an empty conf.\n",
278 __func__);
279 return -EINVAL;
280 }
281
282 /* find us in conf */
283 list_for_each_entry(member, &dsp->conf->mlist, list) {
284 if (member->dsp == dsp) {
285 list_del(&member->list);
286 dsp->conf = NULL;
287 dsp->member = NULL;
288 kfree(member);
289 return 0;
290 }
291 }
292 printk(KERN_WARNING
293 "%s: dsp is not present in its own conf_meber list.\n",
294 __func__);
295
296 return -EINVAL;
297}
298
299
300/*
301 * new conference
302 */
303static struct dsp_conf
304*dsp_cmx_new_conf(u32 id)
305{
306 struct dsp_conf *conf;
307
308 if (!id) {
309 printk(KERN_WARNING "%s: id is 0.\n",
310 __func__);
311 return NULL;
312 }
313
314 conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC);
315 if (!conf) {
316 printk(KERN_ERR "kmalloc struct dsp_conf failed\n");
317 return NULL;
318 }
319 INIT_LIST_HEAD(&conf->mlist);
320 conf->id = id;
321
322 list_add_tail(&conf->list, &conf_ilist);
323
324 return conf;
325}
326
327
328/*
329 * del conference
330 */
331int
332dsp_cmx_del_conf(struct dsp_conf *conf)
333{
334 if (!conf) {
335 printk(KERN_WARNING "%s: conf is null.\n",
336 __func__);
337 return -EINVAL;
338 }
339
340 if (!list_empty(&conf->mlist)) {
341 printk(KERN_WARNING "%s: conf not empty.\n",
342 __func__);
343 return -EINVAL;
344 }
345 list_del(&conf->list);
346 kfree(conf);
347
348 return 0;
349}
350
351
352/*
353 * send HW message to hfc card
354 */
355static void
356dsp_cmx_hw_message(struct dsp *dsp, u32 message, u32 param1, u32 param2,
357 u32 param3, u32 param4)
358{
359 struct mISDN_ctrl_req cq;
360
361 memset(&cq, 0, sizeof(cq));
362 cq.op = message;
363 cq.p1 = param1 | (param2 << 8);
364 cq.p2 = param3 | (param4 << 8);
365 if (dsp->ch.peer)
366 dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq);
367}
368
369
370/*
371 * do hardware update and set the software/hardware flag
372 *
373 * either a conference or a dsp instance can be given
374 * if only dsp instance is given, the instance is not associated with a conf
375 * and therefore removed. if a conference is given, the dsp is expected to
376 * be member of that conference.
377 */
378void
379dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
380{
381 struct dsp_conf_member *member, *nextm;
382 struct dsp *finddsp;
383 int memb = 0, i, ii, i1, i2;
384 int freeunits[8];
385 u_char freeslots[256];
386 int same_hfc = -1, same_pcm = -1, current_conf = -1,
387 all_conf = 1;
388
389 /* dsp gets updated (no conf) */
390 if (!conf) {
391 if (!dsp)
392 return;
393 if (dsp_debug & DEBUG_DSP_CMX)
394 printk(KERN_DEBUG "%s checking dsp %s\n",
395 __func__, dsp->name);
396one_member:
397 /* remove HFC conference if enabled */
398 if (dsp->hfc_conf >= 0) {
399 if (dsp_debug & DEBUG_DSP_CMX)
400 printk(KERN_DEBUG
401 "%s removing %s from HFC conf %d "
402 "because dsp is split\n", __func__,
403 dsp->name, dsp->hfc_conf);
404 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_CONF_SPLIT,
405 0, 0, 0, 0);
406 dsp->hfc_conf = -1;
407 }
408 /* process hw echo */
409 if (dsp->features.pcm_banks < 1)
410 return;
411 if (!dsp->echo) {
412 /* NO ECHO: remove PCM slot if assigned */
413 if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
414 if (dsp_debug & DEBUG_DSP_CMX)
415 printk(KERN_DEBUG "%s removing %s from"
416 " PCM slot %d (TX) %d (RX) because"
417 " dsp is split (no echo)\n",
418 __func__, dsp->name,
419 dsp->pcm_slot_tx, dsp->pcm_slot_rx);
420 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_DISC,
421 0, 0, 0, 0);
422 dsp->pcm_slot_tx = -1;
423 dsp->pcm_bank_tx = -1;
424 dsp->pcm_slot_rx = -1;
425 dsp->pcm_bank_rx = -1;
426 }
427 return;
428 }
429 /* ECHO: already echo */
430 if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
431 dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2)
432 return;
433 /* ECHO: if slot already assigned */
434 if (dsp->pcm_slot_tx >= 0) {
435 dsp->pcm_slot_rx = dsp->pcm_slot_tx;
436 dsp->pcm_bank_tx = 2; /* 2 means loop */
437 dsp->pcm_bank_rx = 2;
438 if (dsp_debug & DEBUG_DSP_CMX)
439 printk(KERN_DEBUG
440 "%s refresh %s for echo using slot %d\n",
441 __func__, dsp->name,
442 dsp->pcm_slot_tx);
443 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
444 dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
445 return;
446 }
447 /* ECHO: find slot */
448 dsp->pcm_slot_tx = -1;
449 dsp->pcm_slot_rx = -1;
450 memset(freeslots, 1, sizeof(freeslots));
451 list_for_each_entry(finddsp, &dsp_ilist, list) {
452 if (finddsp->features.pcm_id == dsp->features.pcm_id) {
453 if (finddsp->pcm_slot_rx >= 0 &&
454 finddsp->pcm_slot_rx < sizeof(freeslots))
455 freeslots[finddsp->pcm_slot_tx] = 0;
456 if (finddsp->pcm_slot_tx >= 0 &&
457 finddsp->pcm_slot_tx < sizeof(freeslots))
458 freeslots[finddsp->pcm_slot_rx] = 0;
459 }
460 }
461 i = 0;
462 ii = dsp->features.pcm_slots;
463 while (i < ii) {
464 if (freeslots[i])
465 break;
466 i++;
467 }
468 if (i == ii) {
469 if (dsp_debug & DEBUG_DSP_CMX)
470 printk(KERN_DEBUG
471 "%s no slot available for echo\n",
472 __func__);
473 /* no more slots available */
474 return;
475 }
476 /* assign free slot */
477 dsp->pcm_slot_tx = i;
478 dsp->pcm_slot_rx = i;
479 dsp->pcm_bank_tx = 2; /* loop */
480 dsp->pcm_bank_rx = 2;
481 if (dsp_debug & DEBUG_DSP_CMX)
482 printk(KERN_DEBUG
483 "%s assign echo for %s using slot %d\n",
484 __func__, dsp->name, dsp->pcm_slot_tx);
485 dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
486 dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
487 return;
488 }
489
490 /* conf gets updated (all members) */
491 if (dsp_debug & DEBUG_DSP_CMX)
492 printk(KERN_DEBUG "%s checking conference %d\n",
493 __func__, conf->id);
494
495 if (list_empty(&conf->mlist)) {
496 printk(KERN_ERR "%s: conference whithout members\n",
497 __func__);
498 return;
499 }
500 member = list_entry(conf->mlist.next, struct dsp_conf_member, list);
501 same_hfc = member->dsp->features.hfc_id;
502 same_pcm = member->dsp->features.pcm_id;
503 /* check all members in our conference */
504 list_for_each_entry(member, &conf->mlist, list) {
505 /* check if member uses mixing */
506 if (member->dsp->tx_mix) {
507 if (dsp_debug & DEBUG_DSP_CMX)
508 printk(KERN_DEBUG
509 "%s dsp %s cannot form a conf, because "
510 "tx_mix is turned on\n", __func__,
511 member->dsp->name);
512conf_software:
513 list_for_each_entry(member, &conf->mlist, list) {
514 dsp = member->dsp;
515 /* remove HFC conference if enabled */
516 if (dsp->hfc_conf >= 0) {
517 if (dsp_debug & DEBUG_DSP_CMX)
518 printk(KERN_DEBUG
519 "%s removing %s from HFC "
520 "conf %d because not "
521 "possible with hardware\n",
522 __func__,
523 dsp->name,
524 dsp->hfc_conf);
525 dsp_cmx_hw_message(dsp,
526 MISDN_CTRL_HFC_CONF_SPLIT,
527 0, 0, 0, 0);
528 dsp->hfc_conf = -1;
529 }
530 /* remove PCM slot if assigned */
531 if (dsp->pcm_slot_tx >= 0 ||
532 dsp->pcm_slot_rx >= 0) {
533 if (dsp_debug & DEBUG_DSP_CMX)
534 printk(KERN_DEBUG "%s removing "
535 "%s from PCM slot %d (TX)"
536 " slot %d (RX) because not"
537 " possible with hardware\n",
538 __func__,
539 dsp->name,
540 dsp->pcm_slot_tx,
541 dsp->pcm_slot_rx);
542 dsp_cmx_hw_message(dsp,
543 MISDN_CTRL_HFC_PCM_DISC,
544 0, 0, 0, 0);
545 dsp->pcm_slot_tx = -1;
546 dsp->pcm_bank_tx = -1;
547 dsp->pcm_slot_rx = -1;
548 dsp->pcm_bank_rx = -1;
549 }
550 }
551 conf->hardware = 0;
552 conf->software = 1;
553 return;
554 }
555 /* check if member has echo turned on */
556 if (member->dsp->echo) {
557 if (dsp_debug & DEBUG_DSP_CMX)
558 printk(KERN_DEBUG
559 "%s dsp %s cannot form a conf, because "
560 "echo is turned on\n", __func__,
561 member->dsp->name);
562 goto conf_software;
563 }
564 /* check if member has tx_mix turned on */
565 if (member->dsp->tx_mix) {
566 if (dsp_debug & DEBUG_DSP_CMX)
567 printk(KERN_DEBUG
568 "%s dsp %s cannot form a conf, because "
569 "tx_mix is turned on\n",
570 __func__, member->dsp->name);
571 goto conf_software;
572 }
573 /* check if member changes volume at an not suppoted level */
574 if (member->dsp->tx_volume) {
575 if (dsp_debug & DEBUG_DSP_CMX)
576 printk(KERN_DEBUG
577 "%s dsp %s cannot form a conf, because "
578 "tx_volume is changed\n",
579 __func__, member->dsp->name);
580 goto conf_software;
581 }
582 if (member->dsp->rx_volume) {
583 if (dsp_debug & DEBUG_DSP_CMX)
584 printk(KERN_DEBUG
585 "%s dsp %s cannot form a conf, because "
586 "rx_volume is changed\n",
587 __func__, member->dsp->name);
588 goto conf_software;
589 }
590 /* check if tx-data turned on */
591 if (member->dsp->tx_data) {
592 if (dsp_debug & DEBUG_DSP_CMX)
593 printk(KERN_DEBUG
594 "%s dsp %s cannot form a conf, because "
595 "tx_data is turned on\n",
596 __func__, member->dsp->name);
597 goto conf_software;
598 }
599 /* check if pipeline exists */
600 if (member->dsp->pipeline.inuse) {
601 if (dsp_debug & DEBUG_DSP_CMX)
602 printk(KERN_DEBUG
603 "%s dsp %s cannot form a conf, because "
604 "pipeline exists\n", __func__,
605 member->dsp->name);
606 goto conf_software;
607 }
608 /* check if encryption is enabled */
609 if (member->dsp->bf_enable) {
610 if (dsp_debug & DEBUG_DSP_CMX)
611 printk(KERN_DEBUG "%s dsp %s cannot form a "
612 "conf, because encryption is enabled\n",
613 __func__, member->dsp->name);
614 goto conf_software;
615 }
616 /* check if member is on a card with PCM support */
617 if (member->dsp->features.pcm_id < 0) {
618 if (dsp_debug & DEBUG_DSP_CMX)
619 printk(KERN_DEBUG
620 "%s dsp %s cannot form a conf, because "
621 "dsp has no PCM bus\n",
622 __func__, member->dsp->name);
623 goto conf_software;
624 }
625 /* check if relations are on the same PCM bus */
626 if (member->dsp->features.pcm_id != same_pcm) {
627 if (dsp_debug & DEBUG_DSP_CMX)
628 printk(KERN_DEBUG
629 "%s dsp %s cannot form a conf, because "
630 "dsp is on a different PCM bus than the "
631 "first dsp\n",
632 __func__, member->dsp->name);
633 goto conf_software;
634 }
635 /* determine if members are on the same hfc chip */
636 if (same_hfc != member->dsp->features.hfc_id)
637 same_hfc = -1;
638 /* if there are members already in a conference */
639 if (current_conf < 0 && member->dsp->hfc_conf >= 0)
640 current_conf = member->dsp->hfc_conf;
641 /* if any member is not in a conference */
642 if (member->dsp->hfc_conf < 0)
643 all_conf = 0;
644
645 memb++;
646 }
647
648 /* if no member, this is an error */
649 if (memb < 1)
650 return;
651
652 /* one member */
653 if (memb == 1) {
654 if (dsp_debug & DEBUG_DSP_CMX)
655 printk(KERN_DEBUG
656 "%s conf %d cannot form a HW conference, "
657 "because dsp is alone\n", __func__, conf->id);
658 conf->hardware = 0;
659 conf->software = 0;
660 member = list_entry(conf->mlist.next, struct dsp_conf_member,
661 list);
662 dsp = member->dsp;
663 goto one_member;
664 }
665
666 /*
667 * ok, now we are sure that all members are on the same pcm.
668 * now we will see if we have only two members, so we can do
669 * crossconnections, which don't have any limitations.
670 */
671
672 /* if we have only two members */
673 if (memb == 2) {
674 member = list_entry(conf->mlist.next, struct dsp_conf_member,
675 list);
676 nextm = list_entry(member->list.next, struct dsp_conf_member,
677 list);
678 /* remove HFC conference if enabled */
679 if (member->dsp->hfc_conf >= 0) {
680 if (dsp_debug & DEBUG_DSP_CMX)
681 printk(KERN_DEBUG
682 "%s removing %s from HFC conf %d because "
683 "two parties require only a PCM slot\n",
684 __func__, member->dsp->name,
685 member->dsp->hfc_conf);
686 dsp_cmx_hw_message(member->dsp,
687 MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
688 member->dsp->hfc_conf = -1;
689 }
690 if (nextm->dsp->hfc_conf >= 0) {
691 if (dsp_debug & DEBUG_DSP_CMX)
692 printk(KERN_DEBUG
693 "%s removing %s from HFC conf %d because "
694 "two parties require only a PCM slot\n",
695 __func__, nextm->dsp->name,
696 nextm->dsp->hfc_conf);
697 dsp_cmx_hw_message(nextm->dsp,
698 MISDN_CTRL_HFC_CONF_SPLIT, 0, 0, 0, 0);
699 nextm->dsp->hfc_conf = -1;
700 }
701 /* if members have two banks (and not on the same chip) */
702 if (member->dsp->features.pcm_banks > 1 &&
703 nextm->dsp->features.pcm_banks > 1 &&
704 member->dsp->features.hfc_id !=
705 nextm->dsp->features.hfc_id) {
706 /* if both members have same slots with crossed banks */
707 if (member->dsp->pcm_slot_tx >= 0 &&
708 member->dsp->pcm_slot_rx >= 0 &&
709 nextm->dsp->pcm_slot_tx >= 0 &&
710 nextm->dsp->pcm_slot_rx >= 0 &&
711 nextm->dsp->pcm_slot_tx ==
712 member->dsp->pcm_slot_rx &&
713 nextm->dsp->pcm_slot_rx ==
714 member->dsp->pcm_slot_tx &&
715 nextm->dsp->pcm_slot_tx ==
716 member->dsp->pcm_slot_tx &&
717 member->dsp->pcm_bank_tx !=
718 member->dsp->pcm_bank_rx &&
719 nextm->dsp->pcm_bank_tx !=
720 nextm->dsp->pcm_bank_rx) {
721 /* all members have same slot */
722 if (dsp_debug & DEBUG_DSP_CMX)
723 printk(KERN_DEBUG
724 "%s dsp %s & %s stay joined on "
725 "PCM slot %d bank %d (TX) bank %d "
726 "(RX) (on different chips)\n",
727 __func__,
728 member->dsp->name,
729 nextm->dsp->name,
730 member->dsp->pcm_slot_tx,
731 member->dsp->pcm_bank_tx,
732 member->dsp->pcm_bank_rx);
733 conf->hardware = 0;
734 conf->software = 1;
735 return;
736 }
737 /* find a new slot */
738 memset(freeslots, 1, sizeof(freeslots));
739 list_for_each_entry(dsp, &dsp_ilist, list) {
740 if (dsp != member->dsp &&
741 dsp != nextm->dsp &&
742 member->dsp->features.pcm_id ==
743 dsp->features.pcm_id) {
744 if (dsp->pcm_slot_rx >= 0 &&
745 dsp->pcm_slot_rx <
746 sizeof(freeslots))
747 freeslots[dsp->pcm_slot_tx] = 0;
748 if (dsp->pcm_slot_tx >= 0 &&
749 dsp->pcm_slot_tx <
750 sizeof(freeslots))
751 freeslots[dsp->pcm_slot_rx] = 0;
752 }
753 }
754 i = 0;
755 ii = member->dsp->features.pcm_slots;
756 while (i < ii) {
757 if (freeslots[i])
758 break;
759 i++;
760 }
761 if (i == ii) {
762 if (dsp_debug & DEBUG_DSP_CMX)
763 printk(KERN_DEBUG
764 "%s no slot available for "
765 "%s & %s\n", __func__,
766 member->dsp->name,
767 nextm->dsp->name);
768 /* no more slots available */
769 goto conf_software;
770 }
771 /* assign free slot */
772 member->dsp->pcm_slot_tx = i;
773 member->dsp->pcm_slot_rx = i;
774 nextm->dsp->pcm_slot_tx = i;
775 nextm->dsp->pcm_slot_rx = i;
776 member->dsp->pcm_bank_rx = 0;
777 member->dsp->pcm_bank_tx = 1;
778 nextm->dsp->pcm_bank_rx = 1;
779 nextm->dsp->pcm_bank_tx = 0;
780 if (dsp_debug & DEBUG_DSP_CMX)
781 printk(KERN_DEBUG
782 "%s adding %s & %s to new PCM slot %d "
783 "(TX and RX on different chips) because "
784 "both members have not same slots\n",
785 __func__,
786 member->dsp->name,
787 nextm->dsp->name,
788 member->dsp->pcm_slot_tx);
789 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
790 member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
791 member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
792 dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
793 nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
794 nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
795 conf->hardware = 1;
796 conf->software = 0;
797 return;
798 /* if members have one bank (or on the same chip) */
799 } else {
800 /* if both members have different crossed slots */
801 if (member->dsp->pcm_slot_tx >= 0 &&
802 member->dsp->pcm_slot_rx >= 0 &&
803 nextm->dsp->pcm_slot_tx >= 0 &&
804 nextm->dsp->pcm_slot_rx >= 0 &&
805 nextm->dsp->pcm_slot_tx ==
806 member->dsp->pcm_slot_rx &&
807 nextm->dsp->pcm_slot_rx ==
808 member->dsp->pcm_slot_tx &&
809 member->dsp->pcm_slot_tx !=
810 member->dsp->pcm_slot_rx &&
811 member->dsp->pcm_bank_tx == 0 &&
812 member->dsp->pcm_bank_rx == 0 &&
813 nextm->dsp->pcm_bank_tx == 0 &&
814 nextm->dsp->pcm_bank_rx == 0) {
815 /* all members have same slot */
816 if (dsp_debug & DEBUG_DSP_CMX)
817 printk(KERN_DEBUG
818 "%s dsp %s & %s stay joined on PCM "
819 "slot %d (TX) %d (RX) on same chip "
820 "or one bank PCM)\n", __func__,
821 member->dsp->name,
822 nextm->dsp->name,
823 member->dsp->pcm_slot_tx,
824 member->dsp->pcm_slot_rx);
825 conf->hardware = 0;
826 conf->software = 1;
827 return;
828 }
829 /* find two new slot */
830 memset(freeslots, 1, sizeof(freeslots));
831 list_for_each_entry(dsp, &dsp_ilist, list) {
832 if (dsp != member->dsp &&
833 dsp != nextm->dsp &&
834 member->dsp->features.pcm_id ==
835 dsp->features.pcm_id) {
836 if (dsp->pcm_slot_rx >= 0 &&
837 dsp->pcm_slot_rx <
838 sizeof(freeslots))
839 freeslots[dsp->pcm_slot_tx] = 0;
840 if (dsp->pcm_slot_tx >= 0 &&
841 dsp->pcm_slot_tx <
842 sizeof(freeslots))
843 freeslots[dsp->pcm_slot_rx] = 0;
844 }
845 }
846 i1 = 0;
847 ii = member->dsp->features.pcm_slots;
848 while (i1 < ii) {
849 if (freeslots[i1])
850 break;
851 i1++;
852 }
853 if (i1 == ii) {
854 if (dsp_debug & DEBUG_DSP_CMX)
855 printk(KERN_DEBUG
856 "%s no slot available "
857 "for %s & %s\n", __func__,
858 member->dsp->name,
859 nextm->dsp->name);
860 /* no more slots available */
861 goto conf_software;
862 }
863 i2 = i1+1;
864 while (i2 < ii) {
865 if (freeslots[i2])
866 break;
867 i2++;
868 }
869 if (i2 == ii) {
870 if (dsp_debug & DEBUG_DSP_CMX)
871 printk(KERN_DEBUG
872 "%s no slot available "
873 "for %s & %s\n",
874 __func__,
875 member->dsp->name,
876 nextm->dsp->name);
877 /* no more slots available */
878 goto conf_software;
879 }
880 /* assign free slots */
881 member->dsp->pcm_slot_tx = i1;
882 member->dsp->pcm_slot_rx = i2;
883 nextm->dsp->pcm_slot_tx = i2;
884 nextm->dsp->pcm_slot_rx = i1;
885 member->dsp->pcm_bank_rx = 0;
886 member->dsp->pcm_bank_tx = 0;
887 nextm->dsp->pcm_bank_rx = 0;
888 nextm->dsp->pcm_bank_tx = 0;
889 if (dsp_debug & DEBUG_DSP_CMX)
890 printk(KERN_DEBUG
891 "%s adding %s & %s to new PCM slot %d "
892 "(TX) %d (RX) on same chip or one bank "
893 "PCM, because both members have not "
894 "crossed slots\n", __func__,
895 member->dsp->name,
896 nextm->dsp->name,
897 member->dsp->pcm_slot_tx,
898 member->dsp->pcm_slot_rx);
899 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
900 member->dsp->pcm_slot_tx, member->dsp->pcm_bank_tx,
901 member->dsp->pcm_slot_rx, member->dsp->pcm_bank_rx);
902 dsp_cmx_hw_message(nextm->dsp, MISDN_CTRL_HFC_PCM_CONN,
903 nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
904 nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
905 conf->hardware = 1;
906 conf->software = 0;
907 return;
908 }
909 }
910
911 /*
912 * if we have more than two, we may check if we have a conference
913 * unit available on the chip. also all members must be on the same
914 */
915
916 /* if not the same HFC chip */
917 if (same_hfc < 0) {
918 if (dsp_debug & DEBUG_DSP_CMX)
919 printk(KERN_DEBUG
920 "%s conference %d cannot be formed, because "
921 "members are on different chips or not "
922 "on HFC chip\n",
923 __func__, conf->id);
924 goto conf_software;
925 }
926
927 /* for more than two members.. */
928
929 /* in case of hdlc, we change to software */
930 if (dsp->hdlc)
931 goto conf_software;
932
933 /* if all members already have the same conference */
934 if (all_conf)
935 return;
936
937 /*
938 * if there is an existing conference, but not all members have joined
939 */
940 if (current_conf >= 0) {
941join_members:
942 list_for_each_entry(member, &conf->mlist, list) {
943 /* join to current conference */
944 if (member->dsp->hfc_conf == current_conf)
945 continue;
946 /* get a free timeslot first */
947 memset(freeslots, 1, sizeof(freeslots));
948 list_for_each_entry(dsp, &dsp_ilist, list) {
949 /*
950 * not checking current member, because
951 * slot will be overwritten.
952 */
953 if (
954 dsp != member->dsp &&
955 /* dsp must be on the same PCM */
956 member->dsp->features.pcm_id ==
957 dsp->features.pcm_id) {
958 /* dsp must be on a slot */
959 if (dsp->pcm_slot_tx >= 0 &&
960 dsp->pcm_slot_tx <
961 sizeof(freeslots))
962 freeslots[dsp->pcm_slot_tx] = 0;
963 if (dsp->pcm_slot_rx >= 0 &&
964 dsp->pcm_slot_rx <
965 sizeof(freeslots))
966 freeslots[dsp->pcm_slot_rx] = 0;
967 }
968 }
969 i = 0;
970 ii = member->dsp->features.pcm_slots;
971 while (i < ii) {
972 if (freeslots[i])
973 break;
974 i++;
975 }
976 if (i == ii) {
977 /* no more slots available */
978 if (dsp_debug & DEBUG_DSP_CMX)
979 printk(KERN_DEBUG
980 "%s conference %d cannot be formed,"
981 " because no slot free\n",
982 __func__, conf->id);
983 goto conf_software;
984 }
985 if (dsp_debug & DEBUG_DSP_CMX)
986 printk(KERN_DEBUG
987 "%s changing dsp %s to HW conference "
988 "%d slot %d\n", __func__,
989 member->dsp->name, current_conf, i);
990 /* assign free slot & set PCM & join conf */
991 member->dsp->pcm_slot_tx = i;
992 member->dsp->pcm_slot_rx = i;
993 member->dsp->pcm_bank_tx = 2; /* loop */
994 member->dsp->pcm_bank_rx = 2;
995 member->dsp->hfc_conf = current_conf;
996 dsp_cmx_hw_message(member->dsp, MISDN_CTRL_HFC_PCM_CONN,
997 i, 2, i, 2);
998 dsp_cmx_hw_message(member->dsp,
999 MISDN_CTRL_HFC_CONF_JOIN, current_conf, 0, 0, 0);
1000 }
1001 return;
1002 }
1003
1004 /*
1005 * no member is in a conference yet, so we find a free one
1006 */
1007 memset(freeunits, 1, sizeof(freeunits));
1008 list_for_each_entry(dsp, &dsp_ilist, list) {
1009 /* dsp must be on the same chip */
1010 if (dsp->features.hfc_id == same_hfc &&
1011 /* dsp must have joined a HW conference */
1012 dsp->hfc_conf >= 0 &&
1013 /* slot must be within range */
1014 dsp->hfc_conf < 8)
1015 freeunits[dsp->hfc_conf] = 0;
1016 }
1017 i = 0;
1018 ii = 8;
1019 while (i < ii) {
1020 if (freeunits[i])
1021 break;
1022 i++;
1023 }
1024 if (i == ii) {
1025 /* no more conferences available */
1026 if (dsp_debug & DEBUG_DSP_CMX)
1027 printk(KERN_DEBUG
1028 "%s conference %d cannot be formed, because "
1029 "no conference number free\n",
1030 __func__, conf->id);
1031 goto conf_software;
1032 }
1033 /* join all members */
1034 current_conf = i;
1035 goto join_members;
1036}
1037
1038
1039/*
1040 * conf_id != 0: join or change conference
1041 * conf_id == 0: split from conference if not already
1042 */
1043int
1044dsp_cmx_conf(struct dsp *dsp, u32 conf_id)
1045{
1046 int err;
1047 struct dsp_conf *conf;
1048 struct dsp_conf_member *member;
1049
1050 /* if conference doesn't change */
1051 if (dsp->conf_id == conf_id)
1052 return 0;
1053
1054 /* first remove us from current conf */
1055 if (dsp->conf_id) {
1056 if (dsp_debug & DEBUG_DSP_CMX)
1057 printk(KERN_DEBUG "removing us from conference %d\n",
1058 dsp->conf->id);
1059 /* remove us from conf */
1060 conf = dsp->conf;
1061 err = dsp_cmx_del_conf_member(dsp);
1062 if (err)
1063 return err;
1064 dsp->conf_id = 0;
1065
1066 /* update hardware */
1067 dsp_cmx_hardware(NULL, dsp);
1068
1069 /* conf now empty? */
1070 if (list_empty(&conf->mlist)) {
1071 if (dsp_debug & DEBUG_DSP_CMX)
1072 printk(KERN_DEBUG
1073 "conference is empty, so we remove it.\n");
1074 err = dsp_cmx_del_conf(conf);
1075 if (err)
1076 return err;
1077 } else {
1078 /* update members left on conf */
1079 dsp_cmx_hardware(conf, NULL);
1080 }
1081 }
1082
1083 /* if split */
1084 if (!conf_id)
1085 return 0;
1086
1087 /* now add us to conf */
1088 if (dsp_debug & DEBUG_DSP_CMX)
1089 printk(KERN_DEBUG "searching conference %d\n",
1090 conf_id);
1091 conf = dsp_cmx_search_conf(conf_id);
1092 if (!conf) {
1093 if (dsp_debug & DEBUG_DSP_CMX)
1094 printk(KERN_DEBUG
1095 "conference doesn't exist yet, creating.\n");
1096 /* the conference doesn't exist, so we create */
1097 conf = dsp_cmx_new_conf(conf_id);
1098 if (!conf)
1099 return -EINVAL;
1100 } else if (!list_empty(&conf->mlist)) {
1101 member = list_entry(conf->mlist.next, struct dsp_conf_member,
1102 list);
1103 if (dsp->hdlc && !member->dsp->hdlc) {
1104 if (dsp_debug & DEBUG_DSP_CMX)
1105 printk(KERN_DEBUG
1106 "cannot join transparent conference.\n");
1107 return -EINVAL;
1108 }
1109 if (!dsp->hdlc && member->dsp->hdlc) {
1110 if (dsp_debug & DEBUG_DSP_CMX)
1111 printk(KERN_DEBUG
1112 "cannot join hdlc conference.\n");
1113 return -EINVAL;
1114 }
1115 }
1116 /* add conference member */
1117 err = dsp_cmx_add_conf_member(dsp, conf);
1118 if (err)
1119 return err;
1120 dsp->conf_id = conf_id;
1121
1122 /* if we are alone, we do nothing! */
1123 if (list_empty(&conf->mlist)) {
1124 if (dsp_debug & DEBUG_DSP_CMX)
1125 printk(KERN_DEBUG
1126 "we are alone in this conference, so exit.\n");
1127 /* update hardware */
1128 dsp_cmx_hardware(NULL, dsp);
1129 return 0;
1130 }
1131
1132 /* update members on conf */
1133 dsp_cmx_hardware(conf, NULL);
1134
1135 return 0;
1136}
1137
1138
1139/*
1140 * audio data is received from card
1141 */
1142void
1143dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb)
1144{
1145 u8 *d, *p;
1146 int len = skb->len;
1147 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1148 int w, i, ii;
1149
1150 /* check if we have sompen */
1151 if (len < 1)
1152 return;
1153
1154 /* half of the buffer should be larger than maximum packet size */
1155 if (len >= CMX_BUFF_HALF) {
1156 printk(KERN_ERR
1157 "%s line %d: packet from card is too large (%d bytes). "
1158 "please make card send smaller packets OR increase "
1159 "CMX_BUFF_SIZE\n", __FILE__, __LINE__, len);
1160 return;
1161 }
1162
1163 /*
1164 * initialize pointers if not already -
1165 * also add delay if requested by PH_SIGNAL
1166 */
1167 if (dsp->rx_init) {
1168 dsp->rx_init = 0;
1169 if (dsp->features.unordered) {
1170 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1171 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1172 & CMX_BUFF_MASK;
1173 } else {
1174 dsp->rx_R = 0;
1175 dsp->rx_W = dsp->cmx_delay;
1176 }
1177 }
1178 /* if frame contains time code, write directly */
1179 if (dsp->features.unordered) {
1180 dsp->rx_W = (hh->id & CMX_BUFF_MASK);
1181 /* printk(KERN_DEBUG "%s %08x\n", dsp->name, hh->id); */
1182 }
1183 /*
1184 * if we underrun (or maybe overrun),
1185 * we set our new read pointer, and write silence to buffer
1186 */
1187 if (((dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK) >= CMX_BUFF_HALF) {
1188 if (dsp_debug & DEBUG_DSP_CMX)
1189 printk(KERN_DEBUG
1190 "cmx_receive(dsp=%lx): UNDERRUN (or overrun the "
1191 "maximum delay), adjusting read pointer! "
1192 "(inst %s)\n", (u_long)dsp, dsp->name);
1193 /* flush buffer */
1194 if (dsp->features.unordered) {
1195 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1196 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1197 & CMX_BUFF_MASK;
1198 } else {
1199 dsp->rx_R = 0;
1200 dsp->rx_W = dsp->cmx_delay;
1201 }
1202 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
1203 }
1204 /* if we have reached double delay, jump back to middle */
1205 if (dsp->cmx_delay)
1206 if (((dsp->rx_W - dsp->rx_R) & CMX_BUFF_MASK) >=
1207 (dsp->cmx_delay << 1)) {
1208 if (dsp_debug & DEBUG_DSP_CMX)
1209 printk(KERN_DEBUG
1210 "cmx_receive(dsp=%lx): OVERRUN (because "
1211 "twice the delay is reached), adjusting "
1212 "read pointer! (inst %s)\n",
1213 (u_long)dsp, dsp->name);
1214 /* flush buffer */
1215 if (dsp->features.unordered) {
1216 dsp->rx_R = (hh->id & CMX_BUFF_MASK);
1217 dsp->rx_W = (dsp->rx_R + dsp->cmx_delay)
1218 & CMX_BUFF_MASK;
1219 } else {
1220 dsp->rx_R = 0;
1221 dsp->rx_W = dsp->cmx_delay;
1222 }
1223 memset(dsp->rx_buff, dsp_silence, sizeof(dsp->rx_buff));
1224 }
1225
1226 /* show where to write */
1227#ifdef CMX_DEBUG
1228 printk(KERN_DEBUG
1229 "cmx_receive(dsp=%lx): rx_R(dsp)=%05x rx_W(dsp)=%05x len=%d %s\n",
1230 (u_long)dsp, dsp->rx_R, dsp->rx_W, len, dsp->name);
1231#endif
1232
1233 /* write data into rx_buffer */
1234 p = skb->data;
1235 d = dsp->rx_buff;
1236 w = dsp->rx_W;
1237 i = 0;
1238 ii = len;
1239 while (i < ii) {
1240 d[w++ & CMX_BUFF_MASK] = *p++;
1241 i++;
1242 }
1243
1244 /* increase write-pointer */
1245 dsp->rx_W = ((dsp->rx_W+len) & CMX_BUFF_MASK);
1246}
1247
1248
1249/*
1250 * send (mixed) audio data to card and control jitter
1251 */
1252static void
1253dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
1254{
1255 struct dsp_conf *conf = dsp->conf;
1256 struct dsp *member, *other;
1257 register s32 sample;
1258 u8 *d, *p, *q, *o_q;
1259 struct sk_buff *nskb, *txskb;
1260 int r, rr, t, tt, o_r, o_rr;
1261 int preload = 0;
1262 struct mISDNhead *hh, *thh;
1263
1264 /* don't process if: */
1265 if (!dsp->b_active) { /* if not active */
1266 dsp->last_tx = 0;
1267 return;
1268 }
1269 if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */
1270 dsp->tx_R == dsp->tx_W && /* AND no tx-data */
1271 !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
1272 dsp->last_tx = 0;
1273 return;
1274 }
1275
1276#ifdef CMX_DEBUG
1277 printk(KERN_DEBUG
1278 "SEND members=%d dsp=%s, conf=%p, rx_R=%05x rx_W=%05x\n",
1279 members, dsp->name, conf, dsp->rx_R, dsp->rx_W);
1280#endif
1281
1282 /* preload if we have delay set */
1283 if (dsp->cmx_delay && !dsp->last_tx) {
1284 preload = len;
1285 if (preload < 128)
1286 preload = 128;
1287 }
1288
1289 /* PREPARE RESULT */
1290 nskb = mI_alloc_skb(len + preload, GFP_ATOMIC);
1291 if (!nskb) {
1292 printk(KERN_ERR
1293 "FATAL ERROR in mISDN_dsp.o: cannot alloc %d bytes\n",
1294 len + preload);
1295 return;
1296 }
1297 hh = mISDN_HEAD_P(nskb);
1298 hh->prim = PH_DATA_REQ;
1299 hh->id = 0;
1300 dsp->last_tx = 1;
1301
1302 /* set pointers, indexes and stuff */
1303 member = dsp;
1304 p = dsp->tx_buff; /* transmit data */
1305 q = dsp->rx_buff; /* received data */
1306 d = skb_put(nskb, preload + len); /* result */
1307 t = dsp->tx_R; /* tx-pointers */
1308 tt = dsp->tx_W;
1309 r = dsp->rx_R; /* rx-pointers */
1310 rr = (r + len) & CMX_BUFF_MASK;
1311
1312 /* preload with silence, if required */
1313 if (preload) {
1314 memset(d, dsp_silence, preload);
1315 d += preload;
1316 }
1317
1318 /* PROCESS TONES/TX-DATA ONLY */
1319 if (dsp->tone.tone && dsp->tone.software) {
1320 /* -> copy tone */
1321 dsp_tone_copy(dsp, d, len);
1322 dsp->tx_R = 0; /* clear tx buffer */
1323 dsp->tx_W = 0;
1324 goto send_packet;
1325 }
1326 /* if we have tx-data but do not use mixing */
1327 if (!dsp->tx_mix && t != tt) {
1328 /* -> send tx-data and continue when not enough */
1329#ifdef CMX_TX_DEBUG
1330 sprintf(debugbuf, "TX sending (%04x-%04x)%p: ", t, tt, p);
1331#endif
1332 while (r != rr && t != tt) {
1333#ifdef CMX_TX_DEBUG
1334 if (strlen(debugbuf) < 48)
1335 sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]);
1336#endif
1337 *d++ = p[t]; /* write tx_buff */
1338 t = (t+1) & CMX_BUFF_MASK;
1339 r = (r+1) & CMX_BUFF_MASK;
1340 }
1341 if (r == rr) {
1342 dsp->tx_R = t;
1343#ifdef CMX_TX_DEBUG
1344 printk(KERN_DEBUG "%s\n", debugbuf);
1345#endif
1346 goto send_packet;
1347 }
1348 }
1349#ifdef CMX_TX_DEBUG
1350 printk(KERN_DEBUG "%s\n", debugbuf);
1351#endif
1352
1353 /* PROCESS DATA (one member / no conf) */
1354 if (!conf || members <= 1) {
1355 /* -> if echo is NOT enabled */
1356 if (!dsp->echo) {
1357 /* -> send tx-data if available or use 0-volume */
1358 while (r != rr && t != tt) {
1359 *d++ = p[t]; /* write tx_buff */
1360 t = (t+1) & CMX_BUFF_MASK;
1361 r = (r+1) & CMX_BUFF_MASK;
1362 }
1363 if (r != rr)
1364 memset(d, dsp_silence, (rr-r)&CMX_BUFF_MASK);
1365 /* -> if echo is enabled */
1366 } else {
1367 /*
1368 * -> mix tx-data with echo if available,
1369 * or use echo only
1370 */
1371 while (r != rr && t != tt) {
1372 *d++ = dsp_audio_mix_law[(p[t]<<8)|q[r]];
1373 t = (t+1) & CMX_BUFF_MASK;
1374 r = (r+1) & CMX_BUFF_MASK;
1375 }
1376 while (r != rr) {
1377 *d++ = q[r]; /* echo */
1378 r = (r+1) & CMX_BUFF_MASK;
1379 }
1380 }
1381 dsp->tx_R = t;
1382 goto send_packet;
1383 }
1384 /* PROCESS DATA (two members) */
1385#ifdef CMX_CONF_DEBUG
1386 if (0) {
1387#else
1388 if (members == 2) {
1389#endif
1390 /* "other" becomes other party */
1391 other = (list_entry(conf->mlist.next,
1392 struct dsp_conf_member, list))->dsp;
1393 if (other == member)
1394 other = (list_entry(conf->mlist.prev,
1395 struct dsp_conf_member, list))->dsp;
1396 o_q = other->rx_buff; /* received data */
1397 o_rr = (other->rx_R + len) & CMX_BUFF_MASK;
1398 /* end of rx-pointer */
1399 o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
1400 /* start rx-pointer at current read position*/
1401 /* -> if echo is NOT enabled */
1402 if (!dsp->echo) {
1403 /*
1404 * -> copy other member's rx-data,
1405 * if tx-data is available, mix
1406 */
1407 while (o_r != o_rr && t != tt) {
1408 *d++ = dsp_audio_mix_law[(p[t]<<8)|o_q[o_r]];
1409 t = (t+1) & CMX_BUFF_MASK;
1410 o_r = (o_r+1) & CMX_BUFF_MASK;
1411 }
1412 while (o_r != o_rr) {
1413 *d++ = o_q[o_r];
1414 o_r = (o_r+1) & CMX_BUFF_MASK;
1415 }
1416 /* -> if echo is enabled */
1417 } else {
1418 /*
1419 * -> mix other member's rx-data with echo,
1420 * if tx-data is available, mix
1421 */
1422 while (r != rr && t != tt) {
1423 sample = dsp_audio_law_to_s32[p[t]] +
1424 dsp_audio_law_to_s32[q[r]] +
1425 dsp_audio_law_to_s32[o_q[o_r]];
1426 if (sample < -32768)
1427 sample = -32768;
1428 else if (sample > 32767)
1429 sample = 32767;
1430 *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1431 /* tx-data + rx_data + echo */
1432 t = (t+1) & CMX_BUFF_MASK;
1433 r = (r+1) & CMX_BUFF_MASK;
1434 o_r = (o_r+1) & CMX_BUFF_MASK;
1435 }
1436 while (r != rr) {
1437 *d++ = dsp_audio_mix_law[(q[r]<<8)|o_q[o_r]];
1438 r = (r+1) & CMX_BUFF_MASK;
1439 o_r = (o_r+1) & CMX_BUFF_MASK;
1440 }
1441 }
1442 dsp->tx_R = t;
1443 goto send_packet;
1444 }
1445#ifdef DSP_NEVER_DEFINED
1446 }
1447#endif
1448 /* PROCESS DATA (three or more members) */
1449 /* -> if echo is NOT enabled */
1450 if (!dsp->echo) {
1451 /*
1452 * -> substract rx-data from conf-data,
1453 * if tx-data is available, mix
1454 */
1455 while (r != rr && t != tt) {
1456 sample = dsp_audio_law_to_s32[p[t]] + *c++ -
1457 dsp_audio_law_to_s32[q[r]];
1458 if (sample < -32768)
1459 sample = -32768;
1460 else if (sample > 32767)
1461 sample = 32767;
1462 *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1463 /* conf-rx+tx */
1464 r = (r+1) & CMX_BUFF_MASK;
1465 t = (t+1) & CMX_BUFF_MASK;
1466 }
1467 while (r != rr) {
1468 sample = *c++ - dsp_audio_law_to_s32[q[r]];
1469 if (sample < -32768)
1470 sample = -32768;
1471 else if (sample > 32767)
1472 sample = 32767;
1473 *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1474 /* conf-rx */
1475 r = (r+1) & CMX_BUFF_MASK;
1476 }
1477 /* -> if echo is enabled */
1478 } else {
1479 /*
1480 * -> encode conf-data, if tx-data
1481 * is available, mix
1482 */
1483 while (r != rr && t != tt) {
1484 sample = dsp_audio_law_to_s32[p[t]] + *c++;
1485 if (sample < -32768)
1486 sample = -32768;
1487 else if (sample > 32767)
1488 sample = 32767;
1489 *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1490 /* conf(echo)+tx */
1491 t = (t+1) & CMX_BUFF_MASK;
1492 r = (r+1) & CMX_BUFF_MASK;
1493 }
1494 while (r != rr) {
1495 sample = *c++;
1496 if (sample < -32768)
1497 sample = -32768;
1498 else if (sample > 32767)
1499 sample = 32767;
1500 *d++ = dsp_audio_s16_to_law[sample & 0xffff];
1501 /* conf(echo) */
1502 r = (r+1) & CMX_BUFF_MASK;
1503 }
1504 }
1505 dsp->tx_R = t;
1506 goto send_packet;
1507
1508send_packet:
1509 /*
1510 * send tx-data if enabled - don't filter,
1511 * becuase we want what we send, not what we filtered
1512 */
1513 if (dsp->tx_data) {
1514 /* PREPARE RESULT */
1515 txskb = mI_alloc_skb(len, GFP_ATOMIC);
1516 if (!txskb) {
1517 printk(KERN_ERR
1518 "FATAL ERROR in mISDN_dsp.o: "
1519 "cannot alloc %d bytes\n", len);
1520 } else {
1521 thh = mISDN_HEAD_P(txskb);
1522 thh->prim = DL_DATA_REQ;
1523 thh->id = 0;
1524 memcpy(skb_put(txskb, len), nskb->data+preload, len);
1525 /* queue (trigger later) */
1526 skb_queue_tail(&dsp->sendq, txskb);
1527 }
1528 }
1529 /* adjust volume */
1530 if (dsp->tx_volume)
1531 dsp_change_volume(nskb, dsp->tx_volume);
1532 /* pipeline */
1533 if (dsp->pipeline.inuse)
1534 dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len);
1535 /* crypt */
1536 if (dsp->bf_enable)
1537 dsp_bf_encrypt(dsp, nskb->data, nskb->len);
1538 /* queue and trigger */
1539 skb_queue_tail(&dsp->sendq, nskb);
1540 schedule_work(&dsp->workq);
1541}
1542
1543u32 samplecount;
1544struct timer_list dsp_spl_tl;
1545u32 dsp_spl_jiffies; /* calculate the next time to fire */
1546u32 dsp_start_jiffies; /* jiffies at the time, the calculation begins */
1547struct timeval dsp_start_tv; /* time at start of calculation */
1548
1549void
1550dsp_cmx_send(void *arg)
1551{
1552 struct dsp_conf *conf;
1553 struct dsp_conf_member *member;
1554 struct dsp *dsp;
1555 int mustmix, members;
1556 s32 mixbuffer[MAX_POLL+100], *c;
1557 u8 *p, *q;
1558 int r, rr;
1559 int jittercheck = 0, delay, i;
1560 u_long flags;
1561 struct timeval tv;
1562 u32 elapsed;
1563 s16 length;
1564
1565 /* lock */
1566 spin_lock_irqsave(&dsp_lock, flags);
1567
1568 if (!dsp_start_tv.tv_sec) {
1569 do_gettimeofday(&dsp_start_tv);
1570 length = dsp_poll;
1571 } else {
1572 do_gettimeofday(&tv);
1573 elapsed = ((tv.tv_sec - dsp_start_tv.tv_sec) * 8000)
1574 + ((s32)(tv.tv_usec / 125) - (dsp_start_tv.tv_usec / 125));
1575 dsp_start_tv.tv_sec = tv.tv_sec;
1576 dsp_start_tv.tv_usec = tv.tv_usec;
1577 length = elapsed;
1578 }
1579 if (length > MAX_POLL + 100)
1580 length = MAX_POLL + 100;
1581/* printk(KERN_DEBUG "len=%d dsp_count=0x%x.%04x dsp_poll_diff=0x%x.%04x\n",
1582 length, dsp_count >> 16, dsp_count & 0xffff, dsp_poll_diff >> 16,
1583 dsp_poll_diff & 0xffff);
1584 */
1585
1586 /*
1587 * check if jitter needs to be checked
1588 * (this is about every second = 8192 samples)
1589 */
1590 samplecount += length;
1591 if ((samplecount & 8191) < length)
1592 jittercheck = 1;
1593
1594 /* loop all members that do not require conference mixing */
1595 list_for_each_entry(dsp, &dsp_ilist, list) {
1596 if (dsp->hdlc)
1597 continue;
1598 conf = dsp->conf;
1599 mustmix = 0;
1600 members = 0;
1601 if (conf) {
1602 members = count_list_member(&conf->mlist);
1603#ifdef CMX_CONF_DEBUG
1604 if (conf->software && members > 1)
1605#else
1606 if (conf->software && members > 2)
1607#endif
1608 mustmix = 1;
1609 }
1610
1611 /* transmission required */
1612 if (!mustmix) {
1613 dsp_cmx_send_member(dsp, length, mixbuffer, members);
1614
1615 /*
1616 * unused mixbuffer is given to prevent a
1617 * potential null-pointer-bug
1618 */
1619 }
1620 }
1621
1622 /* loop all members that require conference mixing */
1623 list_for_each_entry(conf, &conf_ilist, list) {
1624 /* count members and check hardware */
1625 members = count_list_member(&conf->mlist);
1626#ifdef CMX_CONF_DEBUG
1627 if (conf->software && members > 1) {
1628#else
1629 if (conf->software && members > 2) {
1630#endif
1631 /* check for hdlc conf */
1632 member = list_entry(conf->mlist.next,
1633 struct dsp_conf_member, list);
1634 if (member->dsp->hdlc)
1635 continue;
1636 /* mix all data */
1637 memset(mixbuffer, 0, length*sizeof(s32));
1638 list_for_each_entry(member, &conf->mlist, list) {
1639 dsp = member->dsp;
1640 /* get range of data to mix */
1641 c = mixbuffer;
1642 q = dsp->rx_buff;
1643 r = dsp->rx_R;
1644 rr = (r + length) & CMX_BUFF_MASK;
1645 /* add member's data */
1646 while (r != rr) {
1647 *c++ += dsp_audio_law_to_s32[q[r]];
1648 r = (r+1) & CMX_BUFF_MASK;
1649 }
1650 }
1651
1652 /* process each member */
1653 list_for_each_entry(member, &conf->mlist, list) {
1654 /* transmission */
1655 dsp_cmx_send_member(member->dsp, length,
1656 mixbuffer, members);
1657 }
1658 }
1659 }
1660
1661 /* delete rx-data, increment buffers, change pointers */
1662 list_for_each_entry(dsp, &dsp_ilist, list) {
1663 if (dsp->hdlc)
1664 continue;
1665 p = dsp->rx_buff;
1666 q = dsp->tx_buff;
1667 r = dsp->rx_R;
1668 /* move receive pointer when receiving */
1669 if (!dsp->rx_is_off) {
1670 rr = (r + length) & CMX_BUFF_MASK;
1671 /* delete rx-data */
1672 while (r != rr) {
1673 p[r] = dsp_silence;
1674 r = (r+1) & CMX_BUFF_MASK;
1675 }
1676 /* increment rx-buffer pointer */
1677 dsp->rx_R = r; /* write incremented read pointer */
1678 }
1679
1680 /* check current rx_delay */
1681 delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK;
1682 if (delay >= CMX_BUFF_HALF)
1683 delay = 0; /* will be the delay before next write */
1684 /* check for lower delay */
1685 if (delay < dsp->rx_delay[0])
1686 dsp->rx_delay[0] = delay;
1687 /* check current tx_delay */
1688 delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK;
1689 if (delay >= CMX_BUFF_HALF)
1690 delay = 0; /* will be the delay before next write */
1691 /* check for lower delay */
1692 if (delay < dsp->tx_delay[0])
1693 dsp->tx_delay[0] = delay;
1694 if (jittercheck) {
1695 /* find the lowest of all rx_delays */
1696 delay = dsp->rx_delay[0];
1697 i = 1;
1698 while (i < MAX_SECONDS_JITTER_CHECK) {
1699 if (delay > dsp->rx_delay[i])
1700 delay = dsp->rx_delay[i];
1701 i++;
1702 }
1703 /*
1704 * remove rx_delay only if we have delay AND we
1705 * have not preset cmx_delay
1706 */
1707 if (delay && !dsp->cmx_delay) {
1708 if (dsp_debug & DEBUG_DSP_CMX)
1709 printk(KERN_DEBUG
1710 "%s lowest rx_delay of %d bytes for"
1711 " dsp %s are now removed.\n",
1712 __func__, delay,
1713 dsp->name);
1714 r = dsp->rx_R;
1715 rr = (r + delay) & CMX_BUFF_MASK;
1716 /* delete rx-data */
1717 while (r != rr) {
1718 p[r] = dsp_silence;
1719 r = (r+1) & CMX_BUFF_MASK;
1720 }
1721 /* increment rx-buffer pointer */
1722 dsp->rx_R = r;
1723 /* write incremented read pointer */
1724 }
1725 /* find the lowest of all tx_delays */
1726 delay = dsp->tx_delay[0];
1727 i = 1;
1728 while (i < MAX_SECONDS_JITTER_CHECK) {
1729 if (delay > dsp->tx_delay[i])
1730 delay = dsp->tx_delay[i];
1731 i++;
1732 }
1733 /*
1734 * remove delay only if we have delay AND we
1735 * have enabled tx_dejitter
1736 */
1737 if (delay && dsp->tx_dejitter) {
1738 if (dsp_debug & DEBUG_DSP_CMX)
1739 printk(KERN_DEBUG
1740 "%s lowest tx_delay of %d bytes for"
1741 " dsp %s are now removed.\n",
1742 __func__, delay,
1743 dsp->name);
1744 r = dsp->tx_R;
1745 rr = (r + delay) & CMX_BUFF_MASK;
1746 /* delete tx-data */
1747 while (r != rr) {
1748 q[r] = dsp_silence;
1749 r = (r+1) & CMX_BUFF_MASK;
1750 }
1751 /* increment rx-buffer pointer */
1752 dsp->tx_R = r;
1753 /* write incremented read pointer */
1754 }
1755 /* scroll up delays */
1756 i = MAX_SECONDS_JITTER_CHECK - 1;
1757 while (i) {
1758 dsp->rx_delay[i] = dsp->rx_delay[i-1];
1759 dsp->tx_delay[i] = dsp->tx_delay[i-1];
1760 i--;
1761 }
1762 dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
1763 dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */
1764 }
1765 }
1766
1767 /* if next event would be in the past ... */
1768 if ((s32)(dsp_spl_jiffies+dsp_tics-jiffies) <= 0)
1769 dsp_spl_jiffies = jiffies + 1;
1770 else
1771 dsp_spl_jiffies += dsp_tics;
1772
1773 dsp_spl_tl.expires = dsp_spl_jiffies;
1774 add_timer(&dsp_spl_tl);
1775
1776 /* unlock */
1777 spin_unlock_irqrestore(&dsp_lock, flags);
1778}
1779
1780/*
1781 * audio data is transmitted from upper layer to the dsp
1782 */
1783void
1784dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb)
1785{
1786 u_int w, ww;
1787 u8 *d, *p;
1788 int space; /* todo: , l = skb->len; */
1789#ifdef CMX_TX_DEBUG
1790 char debugbuf[256] = "";
1791#endif
1792
1793 /* check if there is enough space, and then copy */
1794 w = dsp->tx_W;
1795 ww = dsp->tx_R;
1796 p = dsp->tx_buff;
1797 d = skb->data;
1798 space = ww-w;
1799 if (space <= 0)
1800 space += CMX_BUFF_SIZE;
1801 /* write-pointer should not overrun nor reach read pointer */
1802 if (space-1 < skb->len)
1803 /* write to the space we have left */
1804 ww = (ww - 1) & CMX_BUFF_MASK;
1805 else
1806 /* write until all byte are copied */
1807 ww = (w + skb->len) & CMX_BUFF_MASK;
1808 dsp->tx_W = ww;
1809
1810 /* show current buffer */
1811#ifdef CMX_DEBUG
1812 printk(KERN_DEBUG
1813 "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n",
1814 (u_long)dsp, (ww-w)&CMX_BUFF_MASK, w, ww, dsp->name);
1815#endif
1816
1817 /* copy transmit data to tx-buffer */
1818#ifdef CMX_TX_DEBUG
1819 sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p);
1820#endif
1821 while (w != ww) {
1822#ifdef CMX_TX_DEBUG
1823 if (strlen(debugbuf) < 48)
1824 sprintf(debugbuf+strlen(debugbuf), " %02x", *d);
1825#endif
1826 p[w] = *d++;
1827 w = (w+1) & CMX_BUFF_MASK;
1828 }
1829#ifdef CMX_TX_DEBUG
1830 printk(KERN_DEBUG "%s\n", debugbuf);
1831#endif
1832
1833}
1834
1835/*
1836 * hdlc data is received from card and sent to all members.
1837 */
1838void
1839dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
1840{
1841 struct sk_buff *nskb = NULL;
1842 struct dsp_conf_member *member;
1843 struct mISDNhead *hh;
1844
1845 /* not if not active */
1846 if (!dsp->b_active)
1847 return;
1848
1849 /* check if we have sompen */
1850 if (skb->len < 1)
1851 return;
1852
1853 /* no conf */
1854 if (!dsp->conf) {
1855 /* in case of hardware (echo) */
1856 if (dsp->pcm_slot_tx >= 0)
1857 return;
1858 if (dsp->echo)
1859 nskb = skb_clone(skb, GFP_ATOMIC);
1860 if (nskb) {
1861 hh = mISDN_HEAD_P(nskb);
1862 hh->prim = PH_DATA_REQ;
1863 hh->id = 0;
1864 skb_queue_tail(&dsp->sendq, nskb);
1865 schedule_work(&dsp->workq);
1866 }
1867 return;
1868 }
1869 /* in case of hardware conference */
1870 if (dsp->conf->hardware)
1871 return;
1872 list_for_each_entry(member, &dsp->conf->mlist, list) {
1873 if (dsp->echo || member->dsp != dsp) {
1874 nskb = skb_clone(skb, GFP_ATOMIC);
1875 if (nskb) {
1876 hh = mISDN_HEAD_P(nskb);
1877 hh->prim = PH_DATA_REQ;
1878 hh->id = 0;
1879 skb_queue_tail(&member->dsp->sendq, nskb);
1880 schedule_work(&member->dsp->workq);
1881 }
1882 }
1883 }
1884}
1885
1886
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
new file mode 100644
index 000000000000..2f10ed82c0db
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -0,0 +1,1191 @@
1/*
2 * Author Andreas Eversberg (jolly@eversberg.eu)
3 * Based on source code structure by
4 * Karsten Keil (keil@isdn4linux.de)
5 *
6 * This file is (c) under GNU PUBLIC LICENSE
7 * For changes and modifications please read
8 * ../../../Documentation/isdn/mISDN.cert
9 *
10 * Thanks to Karsten Keil (great drivers)
11 * Cologne Chip (great chips)
12 *
13 * This module does:
14 * Real-time tone generation
15 * DTMF detection
16 * Real-time cross-connection and conferrence
17 * Compensate jitter due to system load and hardware fault.
18 * All features are done in kernel space and will be realized
19 * using hardware, if available and supported by chip set.
20 * Blowfish encryption/decryption
21 */
22
23/* STRUCTURE:
24 *
25 * The dsp module provides layer 2 for b-channels (64kbit). It provides
26 * transparent audio forwarding with special digital signal processing:
27 *
28 * - (1) generation of tones
29 * - (2) detection of dtmf tones
30 * - (3) crossconnecting and conferences (clocking)
31 * - (4) echo generation for delay test
32 * - (5) volume control
33 * - (6) disable receive data
34 * - (7) pipeline
35 * - (8) encryption/decryption
36 *
37 * Look:
38 * TX RX
39 * ------upper layer------
40 * | ^
41 * | |(6)
42 * v |
43 * +-----+-------------+-----+
44 * |(3)(4) |
45 * | CMX |
46 * | |
47 * | +-------------+
48 * | | ^
49 * | | |
50 * |+---------+| +----+----+
51 * ||(1) || |(2) |
52 * || || | |
53 * || Tones || | DTMF |
54 * || || | |
55 * || || | |
56 * |+----+----+| +----+----+
57 * +-----+-----+ ^
58 * | |
59 * v |
60 * +----+----+ +----+----+
61 * |(5) | |(5) |
62 * | | | |
63 * |TX Volume| |RX Volume|
64 * | | | |
65 * | | | |
66 * +----+----+ +----+----+
67 * | ^
68 * | |
69 * v |
70 * +----+-------------+----+
71 * |(7) |
72 * | |
73 * | Pipeline Processing |
74 * | |
75 * | |
76 * +----+-------------+----+
77 * | ^
78 * | |
79 * v |
80 * +----+----+ +----+----+
81 * |(8) | |(8) |
82 * | | | |
83 * | Encrypt | | Decrypt |
84 * | | | |
85 * | | | |
86 * +----+----+ +----+----+
87 * | ^
88 * | |
89 * v |
90 * ------card layer------
91 * TX RX
92 *
93 * Above you can see the logical data flow. If software is used to do the
94 * process, it is actually the real data flow. If hardware is used, data
95 * may not flow, but hardware commands to the card, to provide the data flow
96 * as shown.
97 *
98 * NOTE: The channel must be activated in order to make dsp work, even if
99 * no data flow to the upper layer is intended. Activation can be done
100 * after and before controlling the setting using PH_CONTROL requests.
101 *
102 * DTMF: Will be detected by hardware if possible. It is done before CMX
103 * processing.
104 *
105 * Tones: Will be generated via software if endless looped audio fifos are
106 * not supported by hardware. Tones will override all data from CMX.
107 * It is not required to join a conference to use tones at any time.
108 *
109 * CMX: Is transparent when not used. When it is used, it will do
110 * crossconnections and conferences via software if not possible through
111 * hardware. If hardware capability is available, hardware is used.
112 *
113 * Echo: Is generated by CMX and is used to check performane of hard and
114 * software CMX.
115 *
116 * The CMX has special functions for conferences with one, two and more
117 * members. It will allow different types of data flow. Receive and transmit
118 * data to/form upper layer may be swithed on/off individually without loosing
119 * features of CMX, Tones and DTMF.
120 *
121 * Echo Cancellation: Sometimes we like to cancel echo from the interface.
122 * Note that a VoIP call may not have echo caused by the IP phone. The echo
123 * is generated by the telephone line connected to it. Because the delay
124 * is high, it becomes an echo. RESULT: Echo Cachelation is required if
125 * both echo AND delay is applied to an interface.
126 * Remember that software CMX always generates a more or less delay.
127 *
128 * If all used features can be realized in hardware, and if transmit and/or
129 * receive data ist disabled, the card may not send/receive any data at all.
130 * Not receiving is usefull if only announcements are played. Not sending is
131 * usefull if an answering machine records audio. Not sending and receiving is
132 * usefull during most states of the call. If supported by hardware, tones
133 * will be played without cpu load. Small PBXs and NT-Mode applications will
134 * not need expensive hardware when processing calls.
135 *
136 *
137 * LOCKING:
138 *
139 * When data is received from upper or lower layer (card), the complete dsp
140 * module is locked by a global lock. This lock MUST lock irq, because it
141 * must lock timer events by DSP poll timer.
142 * When data is ready to be transmitted down, the data is queued and sent
143 * outside lock and timer event.
144 * PH_CONTROL must not change any settings, join or split conference members
145 * during process of data.
146 *
147 * HDLC:
148 *
149 * It works quite the same as transparent, except that HDLC data is forwarded
150 * to all other conference members if no hardware bridging is possible.
151 * Send data will be writte to sendq. Sendq will be sent if confirm is received.
152 * Conference cannot join, if one member is not hdlc.
153 *
154 */
155
156#include <linux/delay.h>
157#include <linux/mISDNif.h>
158#include <linux/mISDNdsp.h>
159#include <linux/module.h>
160#include <linux/vmalloc.h>
161#include "core.h"
162#include "dsp.h"
163
164const char *mISDN_dsp_revision = "2.0";
165
166static int debug;
167static int options;
168static int poll;
169static int dtmfthreshold = 100;
170
171MODULE_AUTHOR("Andreas Eversberg");
172module_param(debug, uint, S_IRUGO | S_IWUSR);
173module_param(options, uint, S_IRUGO | S_IWUSR);
174module_param(poll, uint, S_IRUGO | S_IWUSR);
175module_param(dtmfthreshold, uint, S_IRUGO | S_IWUSR);
176MODULE_LICENSE("GPL");
177
178/*int spinnest = 0;*/
179
180spinlock_t dsp_lock; /* global dsp lock */
181struct list_head dsp_ilist;
182struct list_head conf_ilist;
183int dsp_debug;
184int dsp_options;
185int dsp_poll, dsp_tics;
186
187/* check if rx may be turned off or must be turned on */
188static void
189dsp_rx_off_member(struct dsp *dsp)
190{
191 struct mISDN_ctrl_req cq;
192 int rx_off = 1;
193
194 if (!dsp->features_rx_off)
195 return;
196
197 /* not disabled */
198 if (!dsp->rx_disabled)
199 rx_off = 0;
200 /* software dtmf */
201 else if (dsp->dtmf.software)
202 rx_off = 0;
203 /* echo in software */
204 else if (dsp->echo && dsp->pcm_slot_tx < 0)
205 rx_off = 0;
206 /* bridge in software */
207 else if (dsp->conf) {
208 if (dsp->conf->software)
209 rx_off = 0;
210 }
211
212 if (rx_off == dsp->rx_is_off)
213 return;
214
215 if (!dsp->ch.peer) {
216 if (dsp_debug & DEBUG_DSP_CORE)
217 printk(KERN_DEBUG "%s: no peer, no rx_off\n",
218 __func__);
219 return;
220 }
221 cq.op = MISDN_CTRL_RX_OFF;
222 cq.p1 = rx_off;
223 if (dsp->ch.peer->ctrl(dsp->ch.peer, CONTROL_CHANNEL, &cq)) {
224 printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
225 __func__);
226 return;
227 }
228 dsp->rx_is_off = rx_off;
229 if (dsp_debug & DEBUG_DSP_CORE)
230 printk(KERN_DEBUG "%s: %s set rx_off = %d\n",
231 __func__, dsp->name, rx_off);
232}
233static void
234dsp_rx_off(struct dsp *dsp)
235{
236 struct dsp_conf_member *member;
237
238 if (dsp_options & DSP_OPT_NOHARDWARE)
239 return;
240
241 /* no conf */
242 if (!dsp->conf) {
243 dsp_rx_off_member(dsp);
244 return;
245 }
246 /* check all members in conf */
247 list_for_each_entry(member, &dsp->conf->mlist, list) {
248 dsp_rx_off_member(member->dsp);
249 }
250}
251
252static int
253dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
254{
255 struct sk_buff *nskb;
256 int ret = 0;
257 int cont;
258 u8 *data;
259 int len;
260
261 if (skb->len < sizeof(int))
262 printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__);
263 cont = *((int *)skb->data);
264 len = skb->len - sizeof(int);
265 data = skb->data + sizeof(int);
266
267 switch (cont) {
268 case DTMF_TONE_START: /* turn on DTMF */
269 if (dsp->hdlc) {
270 ret = -EINVAL;
271 break;
272 }
273 if (dsp_debug & DEBUG_DSP_CORE)
274 printk(KERN_DEBUG "%s: start dtmf\n", __func__);
275 if (len == sizeof(int)) {
276 printk(KERN_NOTICE "changing DTMF Threshold "
277 "to %d\n", *((int *)data));
278 dsp->dtmf.treshold = (*(int *)data) * 10000;
279 }
280 /* init goertzel */
281 dsp_dtmf_goertzel_init(dsp);
282
283 /* check dtmf hardware */
284 dsp_dtmf_hardware(dsp);
285 break;
286 case DTMF_TONE_STOP: /* turn off DTMF */
287 if (dsp_debug & DEBUG_DSP_CORE)
288 printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
289 dsp->dtmf.hardware = 0;
290 dsp->dtmf.software = 0;
291 break;
292 case DSP_CONF_JOIN: /* join / update conference */
293 if (len < sizeof(int)) {
294 ret = -EINVAL;
295 break;
296 }
297 if (*((u32 *)data) == 0)
298 goto conf_split;
299 if (dsp_debug & DEBUG_DSP_CORE)
300 printk(KERN_DEBUG "%s: join conference %d\n",
301 __func__, *((u32 *)data));
302 ret = dsp_cmx_conf(dsp, *((u32 *)data));
303 /* dsp_cmx_hardware will also be called here */
304 dsp_rx_off(dsp);
305 if (dsp_debug & DEBUG_DSP_CMX)
306 dsp_cmx_debug(dsp);
307 break;
308 case DSP_CONF_SPLIT: /* remove from conference */
309conf_split:
310 if (dsp_debug & DEBUG_DSP_CORE)
311 printk(KERN_DEBUG "%s: release conference\n", __func__);
312 ret = dsp_cmx_conf(dsp, 0);
313 /* dsp_cmx_hardware will also be called here */
314 if (dsp_debug & DEBUG_DSP_CMX)
315 dsp_cmx_debug(dsp);
316 dsp_rx_off(dsp);
317 break;
318 case DSP_TONE_PATT_ON: /* play tone */
319 if (dsp->hdlc) {
320 ret = -EINVAL;
321 break;
322 }
323 if (len < sizeof(int)) {
324 ret = -EINVAL;
325 break;
326 }
327 if (dsp_debug & DEBUG_DSP_CORE)
328 printk(KERN_DEBUG "%s: turn tone 0x%x on\n",
329 __func__, *((int *)skb->data));
330 ret = dsp_tone(dsp, *((int *)data));
331 if (!ret) {
332 dsp_cmx_hardware(dsp->conf, dsp);
333 dsp_rx_off(dsp);
334 }
335 if (!dsp->tone.tone)
336 goto tone_off;
337 break;
338 case DSP_TONE_PATT_OFF: /* stop tone */
339 if (dsp->hdlc) {
340 ret = -EINVAL;
341 break;
342 }
343 if (dsp_debug & DEBUG_DSP_CORE)
344 printk(KERN_DEBUG "%s: turn tone off\n", __func__);
345 dsp_tone(dsp, 0);
346 dsp_cmx_hardware(dsp->conf, dsp);
347 dsp_rx_off(dsp);
348 /* reset tx buffers (user space data) */
349tone_off:
350 dsp->rx_W = 0;
351 dsp->rx_R = 0;
352 break;
353 case DSP_VOL_CHANGE_TX: /* change volume */
354 if (dsp->hdlc) {
355 ret = -EINVAL;
356 break;
357 }
358 if (len < sizeof(int)) {
359 ret = -EINVAL;
360 break;
361 }
362 dsp->tx_volume = *((int *)data);
363 if (dsp_debug & DEBUG_DSP_CORE)
364 printk(KERN_DEBUG "%s: change tx vol to %d\n",
365 __func__, dsp->tx_volume);
366 dsp_cmx_hardware(dsp->conf, dsp);
367 dsp_dtmf_hardware(dsp);
368 dsp_rx_off(dsp);
369 break;
370 case DSP_VOL_CHANGE_RX: /* change volume */
371 if (dsp->hdlc) {
372 ret = -EINVAL;
373 break;
374 }
375 if (len < sizeof(int)) {
376 ret = -EINVAL;
377 break;
378 }
379 dsp->rx_volume = *((int *)data);
380 if (dsp_debug & DEBUG_DSP_CORE)
381 printk(KERN_DEBUG "%s: change rx vol to %d\n",
382 __func__, dsp->tx_volume);
383 dsp_cmx_hardware(dsp->conf, dsp);
384 dsp_dtmf_hardware(dsp);
385 dsp_rx_off(dsp);
386 break;
387 case DSP_ECHO_ON: /* enable echo */
388 dsp->echo = 1; /* soft echo */
389 if (dsp_debug & DEBUG_DSP_CORE)
390 printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
391 dsp_cmx_hardware(dsp->conf, dsp);
392 dsp_rx_off(dsp);
393 if (dsp_debug & DEBUG_DSP_CMX)
394 dsp_cmx_debug(dsp);
395 break;
396 case DSP_ECHO_OFF: /* disable echo */
397 dsp->echo = 0;
398 if (dsp_debug & DEBUG_DSP_CORE)
399 printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
400 dsp_cmx_hardware(dsp->conf, dsp);
401 dsp_rx_off(dsp);
402 if (dsp_debug & DEBUG_DSP_CMX)
403 dsp_cmx_debug(dsp);
404 break;
405 case DSP_RECEIVE_ON: /* enable receive to user space */
406 if (dsp_debug & DEBUG_DSP_CORE)
407 printk(KERN_DEBUG "%s: enable receive to user "
408 "space\n", __func__);
409 dsp->rx_disabled = 0;
410 dsp_rx_off(dsp);
411 break;
412 case DSP_RECEIVE_OFF: /* disable receive to user space */
413 if (dsp_debug & DEBUG_DSP_CORE)
414 printk(KERN_DEBUG "%s: disable receive to "
415 "user space\n", __func__);
416 dsp->rx_disabled = 1;
417 dsp_rx_off(dsp);
418 break;
419 case DSP_MIX_ON: /* enable mixing of tx data */
420 if (dsp->hdlc) {
421 ret = -EINVAL;
422 break;
423 }
424 if (dsp_debug & DEBUG_DSP_CORE)
425 printk(KERN_DEBUG "%s: enable mixing of "
426 "tx-data with conf mebers\n", __func__);
427 dsp->tx_mix = 1;
428 dsp_cmx_hardware(dsp->conf, dsp);
429 dsp_rx_off(dsp);
430 if (dsp_debug & DEBUG_DSP_CMX)
431 dsp_cmx_debug(dsp);
432 break;
433 case DSP_MIX_OFF: /* disable mixing of tx data */
434 if (dsp->hdlc) {
435 ret = -EINVAL;
436 break;
437 }
438 if (dsp_debug & DEBUG_DSP_CORE)
439 printk(KERN_DEBUG "%s: disable mixing of "
440 "tx-data with conf mebers\n", __func__);
441 dsp->tx_mix = 0;
442 dsp_cmx_hardware(dsp->conf, dsp);
443 dsp_rx_off(dsp);
444 if (dsp_debug & DEBUG_DSP_CMX)
445 dsp_cmx_debug(dsp);
446 break;
447 case DSP_TXDATA_ON: /* enable txdata */
448 dsp->tx_data = 1;
449 if (dsp_debug & DEBUG_DSP_CORE)
450 printk(KERN_DEBUG "%s: enable tx-data\n", __func__);
451 dsp_cmx_hardware(dsp->conf, dsp);
452 dsp_rx_off(dsp);
453 if (dsp_debug & DEBUG_DSP_CMX)
454 dsp_cmx_debug(dsp);
455 break;
456 case DSP_TXDATA_OFF: /* disable txdata */
457 dsp->tx_data = 0;
458 if (dsp_debug & DEBUG_DSP_CORE)
459 printk(KERN_DEBUG "%s: disable tx-data\n", __func__);
460 dsp_cmx_hardware(dsp->conf, dsp);
461 dsp_rx_off(dsp);
462 if (dsp_debug & DEBUG_DSP_CMX)
463 dsp_cmx_debug(dsp);
464 break;
465 case DSP_DELAY: /* use delay algorithm instead of dynamic
466 jitter algorithm */
467 if (dsp->hdlc) {
468 ret = -EINVAL;
469 break;
470 }
471 if (len < sizeof(int)) {
472 ret = -EINVAL;
473 break;
474 }
475 dsp->cmx_delay = (*((int *)data)) << 3;
476 /* miliseconds to samples */
477 if (dsp->cmx_delay >= (CMX_BUFF_HALF>>1))
478 /* clip to half of maximum usable buffer
479 (half of half buffer) */
480 dsp->cmx_delay = (CMX_BUFF_HALF>>1) - 1;
481 if (dsp_debug & DEBUG_DSP_CORE)
482 printk(KERN_DEBUG "%s: use delay algorithm to "
483 "compensate jitter (%d samples)\n",
484 __func__, dsp->cmx_delay);
485 break;
486 case DSP_JITTER: /* use dynamic jitter algorithm instead of
487 delay algorithm */
488 if (dsp->hdlc) {
489 ret = -EINVAL;
490 break;
491 }
492 dsp->cmx_delay = 0;
493 if (dsp_debug & DEBUG_DSP_CORE)
494 printk(KERN_DEBUG "%s: use jitter algorithm to "
495 "compensate jitter\n", __func__);
496 break;
497 case DSP_TX_DEJITTER: /* use dynamic jitter algorithm for tx-buffer */
498 if (dsp->hdlc) {
499 ret = -EINVAL;
500 break;
501 }
502 dsp->tx_dejitter = 1;
503 if (dsp_debug & DEBUG_DSP_CORE)
504 printk(KERN_DEBUG "%s: use dejitter on TX "
505 "buffer\n", __func__);
506 break;
507 case DSP_TX_DEJ_OFF: /* use tx-buffer without dejittering*/
508 if (dsp->hdlc) {
509 ret = -EINVAL;
510 break;
511 }
512 dsp->tx_dejitter = 0;
513 if (dsp_debug & DEBUG_DSP_CORE)
514 printk(KERN_DEBUG "%s: use TX buffer without "
515 "dejittering\n", __func__);
516 break;
517 case DSP_PIPELINE_CFG:
518 if (dsp->hdlc) {
519 ret = -EINVAL;
520 break;
521 }
522 if (len > 0 && ((char *)data)[len - 1]) {
523 printk(KERN_DEBUG "%s: pipeline config string "
524 "is not NULL terminated!\n", __func__);
525 ret = -EINVAL;
526 } else {
527 dsp->pipeline.inuse = 1;
528 dsp_cmx_hardware(dsp->conf, dsp);
529 ret = dsp_pipeline_build(&dsp->pipeline,
530 len > 0 ? (char *)data : NULL);
531 dsp_cmx_hardware(dsp->conf, dsp);
532 dsp_rx_off(dsp);
533 }
534 break;
535 case DSP_BF_ENABLE_KEY: /* turn blowfish on */
536 if (dsp->hdlc) {
537 ret = -EINVAL;
538 break;
539 }
540 if (len < 4 || len > 56) {
541 ret = -EINVAL;
542 break;
543 }
544 if (dsp_debug & DEBUG_DSP_CORE)
545 printk(KERN_DEBUG "%s: turn blowfish on (key "
546 "not shown)\n", __func__);
547 ret = dsp_bf_init(dsp, (u8 *)data, len);
548 /* set new cont */
549 if (!ret)
550 cont = DSP_BF_ACCEPT;
551 else
552 cont = DSP_BF_REJECT;
553 /* send indication if it worked to set it */
554 nskb = _alloc_mISDN_skb(PH_CONTROL_IND, MISDN_ID_ANY,
555 sizeof(int), &cont, GFP_ATOMIC);
556 if (nskb) {
557 if (dsp->up) {
558 if (dsp->up->send(dsp->up, nskb))
559 dev_kfree_skb(nskb);
560 } else
561 dev_kfree_skb(nskb);
562 }
563 if (!ret) {
564 dsp_cmx_hardware(dsp->conf, dsp);
565 dsp_dtmf_hardware(dsp);
566 dsp_rx_off(dsp);
567 }
568 break;
569 case DSP_BF_DISABLE: /* turn blowfish off */
570 if (dsp->hdlc) {
571 ret = -EINVAL;
572 break;
573 }
574 if (dsp_debug & DEBUG_DSP_CORE)
575 printk(KERN_DEBUG "%s: turn blowfish off\n", __func__);
576 dsp_bf_cleanup(dsp);
577 dsp_cmx_hardware(dsp->conf, dsp);
578 dsp_dtmf_hardware(dsp);
579 dsp_rx_off(dsp);
580 break;
581 default:
582 if (dsp_debug & DEBUG_DSP_CORE)
583 printk(KERN_DEBUG "%s: ctrl req %x unhandled\n",
584 __func__, cont);
585 ret = -EINVAL;
586 }
587 return ret;
588}
589
590static void
591get_features(struct mISDNchannel *ch)
592{
593 struct dsp *dsp = container_of(ch, struct dsp, ch);
594 struct mISDN_ctrl_req cq;
595
596 if (dsp_options & DSP_OPT_NOHARDWARE)
597 return;
598 if (!ch->peer) {
599 if (dsp_debug & DEBUG_DSP_CORE)
600 printk(KERN_DEBUG "%s: no peer, no features\n",
601 __func__);
602 return;
603 }
604 memset(&cq, 0, sizeof(cq));
605 cq.op = MISDN_CTRL_GETOP;
606 if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq) < 0) {
607 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
608 __func__);
609 return;
610 }
611 if (cq.op & MISDN_CTRL_RX_OFF)
612 dsp->features_rx_off = 1;
613 if ((cq.op & MISDN_CTRL_HW_FEATURES_OP)) {
614 cq.op = MISDN_CTRL_HW_FEATURES;
615 *((u_long *)&cq.p1) = (u_long)&dsp->features;
616 if (ch->peer->ctrl(ch->peer, CONTROL_CHANNEL, &cq)) {
617 printk(KERN_DEBUG "%s: 2nd CONTROL_CHANNEL failed\n",
618 __func__);
619 }
620 } else
621 if (dsp_debug & DEBUG_DSP_CORE)
622 printk(KERN_DEBUG "%s: features not supported for %s\n",
623 __func__, dsp->name);
624}
625
626static int
627dsp_function(struct mISDNchannel *ch, struct sk_buff *skb)
628{
629 struct dsp *dsp = container_of(ch, struct dsp, ch);
630 struct mISDNhead *hh;
631 int ret = 0;
632 u8 *digits;
633 int cont;
634 struct sk_buff *nskb;
635 u_long flags;
636
637 hh = mISDN_HEAD_P(skb);
638 switch (hh->prim) {
639 /* FROM DOWN */
640 case (PH_DATA_CNF):
641 dsp->data_pending = 0;
642 /* trigger next hdlc frame, if any */
643 if (dsp->hdlc) {
644 spin_lock_irqsave(&dsp_lock, flags);
645 if (dsp->b_active)
646 schedule_work(&dsp->workq);
647 spin_unlock_irqrestore(&dsp_lock, flags);
648 }
649 break;
650 case (PH_DATA_IND):
651 case (DL_DATA_IND):
652 if (skb->len < 1) {
653 ret = -EINVAL;
654 break;
655 }
656 if (dsp->rx_is_off) {
657 if (dsp_debug & DEBUG_DSP_CORE)
658 printk(KERN_DEBUG "%s: rx-data during rx_off"
659 " for %s\n",
660 __func__, dsp->name);
661 }
662 if (dsp->hdlc) {
663 /* hdlc */
664 spin_lock_irqsave(&dsp_lock, flags);
665 dsp_cmx_hdlc(dsp, skb);
666 spin_unlock_irqrestore(&dsp_lock, flags);
667 if (dsp->rx_disabled) {
668 /* if receive is not allowed */
669 break;
670 }
671 hh->prim = DL_DATA_IND;
672 if (dsp->up)
673 return dsp->up->send(dsp->up, skb);
674 break;
675 }
676
677 /* decrypt if enabled */
678 if (dsp->bf_enable)
679 dsp_bf_decrypt(dsp, skb->data, skb->len);
680 /* pipeline */
681 if (dsp->pipeline.inuse)
682 dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
683 skb->len);
684 /* change volume if requested */
685 if (dsp->rx_volume)
686 dsp_change_volume(skb, dsp->rx_volume);
687
688 /* check if dtmf soft decoding is turned on */
689 if (dsp->dtmf.software) {
690 digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
691 skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
692 while (*digits) {
693 if (dsp_debug & DEBUG_DSP_DTMF)
694 printk(KERN_DEBUG "%s: digit"
695 "(%c) to layer %s\n",
696 __func__, *digits, dsp->name);
697 cont = DTMF_TONE_VAL | *digits;
698 nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
699 MISDN_ID_ANY, sizeof(int), &cont,
700 GFP_ATOMIC);
701 if (nskb) {
702 if (dsp->up) {
703 if (dsp->up->send(
704 dsp->up, nskb))
705 dev_kfree_skb(nskb);
706 } else
707 dev_kfree_skb(nskb);
708 }
709 digits++;
710 }
711 }
712 /* we need to process receive data if software */
713 spin_lock_irqsave(&dsp_lock, flags);
714 if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
715 /* process data from card at cmx */
716 dsp_cmx_receive(dsp, skb);
717 }
718 spin_unlock_irqrestore(&dsp_lock, flags);
719
720 if (dsp->rx_disabled) {
721 /* if receive is not allowed */
722 break;
723 }
724 hh->prim = DL_DATA_IND;
725 if (dsp->up)
726 return dsp->up->send(dsp->up, skb);
727 break;
728 case (PH_CONTROL_IND):
729 if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
730 printk(KERN_DEBUG "%s: PH_CONTROL INDICATION "
731 "received: %x (len %d) %s\n", __func__,
732 hh->id, skb->len, dsp->name);
733 switch (hh->id) {
734 case (DTMF_HFC_COEF): /* getting coefficients */
735 if (!dsp->dtmf.hardware) {
736 if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
737 printk(KERN_DEBUG "%s: ignoring DTMF "
738 "coefficients from HFC\n",
739 __func__);
740 break;
741 }
742 digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
743 skb->len, 2);
744 while (*digits) {
745 int k;
746 struct sk_buff *nskb;
747 if (dsp_debug & DEBUG_DSP_DTMF)
748 printk(KERN_DEBUG "%s: digit"
749 "(%c) to layer %s\n",
750 __func__, *digits, dsp->name);
751 k = *digits | DTMF_TONE_VAL;
752 nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
753 MISDN_ID_ANY, sizeof(int), &k,
754 GFP_ATOMIC);
755 if (nskb) {
756 if (dsp->up) {
757 if (dsp->up->send(
758 dsp->up, nskb))
759 dev_kfree_skb(nskb);
760 } else
761 dev_kfree_skb(nskb);
762 }
763 digits++;
764 }
765 break;
766 case (HFC_VOL_CHANGE_TX): /* change volume */
767 if (skb->len != sizeof(int)) {
768 ret = -EINVAL;
769 break;
770 }
771 spin_lock_irqsave(&dsp_lock, flags);
772 dsp->tx_volume = *((int *)skb->data);
773 if (dsp_debug & DEBUG_DSP_CORE)
774 printk(KERN_DEBUG "%s: change tx volume to "
775 "%d\n", __func__, dsp->tx_volume);
776 dsp_cmx_hardware(dsp->conf, dsp);
777 dsp_dtmf_hardware(dsp);
778 dsp_rx_off(dsp);
779 spin_unlock_irqrestore(&dsp_lock, flags);
780 break;
781 default:
782 if (dsp_debug & DEBUG_DSP_CORE)
783 printk(KERN_DEBUG "%s: ctrl ind %x unhandled "
784 "%s\n", __func__, hh->id, dsp->name);
785 ret = -EINVAL;
786 }
787 break;
788 case (PH_ACTIVATE_IND):
789 case (PH_ACTIVATE_CNF):
790 if (dsp_debug & DEBUG_DSP_CORE)
791 printk(KERN_DEBUG "%s: b_channel is now active %s\n",
792 __func__, dsp->name);
793 /* bchannel now active */
794 spin_lock_irqsave(&dsp_lock, flags);
795 dsp->b_active = 1;
796 dsp->data_pending = 0;
797 dsp->rx_init = 1;
798 /* rx_W and rx_R will be adjusted on first frame */
799 dsp->rx_W = 0;
800 dsp->rx_R = 0;
801 memset(dsp->rx_buff, 0, sizeof(dsp->rx_buff));
802 dsp_cmx_hardware(dsp->conf, dsp);
803 dsp_dtmf_hardware(dsp);
804 dsp_rx_off(dsp);
805 spin_unlock_irqrestore(&dsp_lock, flags);
806 if (dsp_debug & DEBUG_DSP_CORE)
807 printk(KERN_DEBUG "%s: done with activation, sending "
808 "confirm to user space. %s\n", __func__,
809 dsp->name);
810 /* send activation to upper layer */
811 hh->prim = DL_ESTABLISH_CNF;
812 if (dsp->up)
813 return dsp->up->send(dsp->up, skb);
814 break;
815 case (PH_DEACTIVATE_IND):
816 case (PH_DEACTIVATE_CNF):
817 if (dsp_debug & DEBUG_DSP_CORE)
818 printk(KERN_DEBUG "%s: b_channel is now inactive %s\n",
819 __func__, dsp->name);
820 /* bchannel now inactive */
821 spin_lock_irqsave(&dsp_lock, flags);
822 dsp->b_active = 0;
823 dsp->data_pending = 0;
824 dsp_cmx_hardware(dsp->conf, dsp);
825 dsp_rx_off(dsp);
826 spin_unlock_irqrestore(&dsp_lock, flags);
827 hh->prim = DL_RELEASE_CNF;
828 if (dsp->up)
829 return dsp->up->send(dsp->up, skb);
830 break;
831 /* FROM UP */
832 case (DL_DATA_REQ):
833 case (PH_DATA_REQ):
834 if (skb->len < 1) {
835 ret = -EINVAL;
836 break;
837 }
838 if (dsp->hdlc) {
839 /* hdlc */
840 spin_lock_irqsave(&dsp_lock, flags);
841 if (dsp->b_active) {
842 skb_queue_tail(&dsp->sendq, skb);
843 schedule_work(&dsp->workq);
844 }
845 spin_unlock_irqrestore(&dsp_lock, flags);
846 return 0;
847 }
848 /* send data to tx-buffer (if no tone is played) */
849 if (!dsp->tone.tone) {
850 spin_lock_irqsave(&dsp_lock, flags);
851 dsp_cmx_transmit(dsp, skb);
852 spin_unlock_irqrestore(&dsp_lock, flags);
853 }
854 break;
855 case (PH_CONTROL_REQ):
856 spin_lock_irqsave(&dsp_lock, flags);
857 ret = dsp_control_req(dsp, hh, skb);
858 spin_unlock_irqrestore(&dsp_lock, flags);
859 break;
860 case (DL_ESTABLISH_REQ):
861 case (PH_ACTIVATE_REQ):
862 if (dsp_debug & DEBUG_DSP_CORE)
863 printk(KERN_DEBUG "%s: activating b_channel %s\n",
864 __func__, dsp->name);
865 if (dsp->dtmf.hardware || dsp->dtmf.software)
866 dsp_dtmf_goertzel_init(dsp);
867 get_features(ch);
868 /* send ph_activate */
869 hh->prim = PH_ACTIVATE_REQ;
870 if (ch->peer)
871 return ch->recv(ch->peer, skb);
872 break;
873 case (DL_RELEASE_REQ):
874 case (PH_DEACTIVATE_REQ):
875 if (dsp_debug & DEBUG_DSP_CORE)
876 printk(KERN_DEBUG "%s: releasing b_channel %s\n",
877 __func__, dsp->name);
878 spin_lock_irqsave(&dsp_lock, flags);
879 dsp->tone.tone = 0;
880 dsp->tone.hardware = 0;
881 dsp->tone.software = 0;
882 if (timer_pending(&dsp->tone.tl))
883 del_timer(&dsp->tone.tl);
884 if (dsp->conf)
885 dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be
886 called here */
887 skb_queue_purge(&dsp->sendq);
888 spin_unlock_irqrestore(&dsp_lock, flags);
889 hh->prim = PH_DEACTIVATE_REQ;
890 if (ch->peer)
891 return ch->recv(ch->peer, skb);
892 break;
893 default:
894 if (dsp_debug & DEBUG_DSP_CORE)
895 printk(KERN_DEBUG "%s: msg %x unhandled %s\n",
896 __func__, hh->prim, dsp->name);
897 ret = -EINVAL;
898 }
899 if (!ret)
900 dev_kfree_skb(skb);
901 return ret;
902}
903
904static int
905dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
906{
907 struct dsp *dsp = container_of(ch, struct dsp, ch);
908 u_long flags;
909 int err = 0;
910
911 if (debug & DEBUG_DSP_CTRL)
912 printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
913
914 switch (cmd) {
915 case OPEN_CHANNEL:
916 break;
917 case CLOSE_CHANNEL:
918 if (dsp->ch.peer)
919 dsp->ch.peer->ctrl(dsp->ch.peer, CLOSE_CHANNEL, NULL);
920
921 /* wait until workqueue has finished,
922 * must lock here, or we may hit send-process currently
923 * queueing. */
924 spin_lock_irqsave(&dsp_lock, flags);
925 dsp->b_active = 0;
926 spin_unlock_irqrestore(&dsp_lock, flags);
927 /* MUST not be locked, because it waits until queue is done. */
928 cancel_work_sync(&dsp->workq);
929 spin_lock_irqsave(&dsp_lock, flags);
930 if (timer_pending(&dsp->tone.tl))
931 del_timer(&dsp->tone.tl);
932 skb_queue_purge(&dsp->sendq);
933 if (dsp_debug & DEBUG_DSP_CTRL)
934 printk(KERN_DEBUG "%s: releasing member %s\n",
935 __func__, dsp->name);
936 dsp->b_active = 0;
937 dsp_cmx_conf(dsp, 0); /* dsp_cmx_hardware will also be called
938 here */
939 dsp_pipeline_destroy(&dsp->pipeline);
940
941 if (dsp_debug & DEBUG_DSP_CTRL)
942 printk(KERN_DEBUG "%s: remove & destroy object %s\n",
943 __func__, dsp->name);
944 list_del(&dsp->list);
945 spin_unlock_irqrestore(&dsp_lock, flags);
946
947 if (dsp_debug & DEBUG_DSP_CTRL)
948 printk(KERN_DEBUG "%s: dsp instance released\n",
949 __func__);
950 vfree(dsp);
951 module_put(THIS_MODULE);
952 break;
953 }
954 return err;
955}
956
957static void
958dsp_send_bh(struct work_struct *work)
959{
960 struct dsp *dsp = container_of(work, struct dsp, workq);
961 struct sk_buff *skb;
962 struct mISDNhead *hh;
963
964 if (dsp->hdlc && dsp->data_pending)
965 return; /* wait until data has been acknowledged */
966
967 /* send queued data */
968 while ((skb = skb_dequeue(&dsp->sendq))) {
969 /* in locked date, we must have still data in queue */
970 if (dsp->data_pending) {
971 if (dsp_debug & DEBUG_DSP_CORE)
972 printk(KERN_DEBUG "%s: fifo full %s, this is "
973 "no bug!\n", __func__, dsp->name);
974 /* flush transparent data, if not acked */
975 dev_kfree_skb(skb);
976 continue;
977 }
978 hh = mISDN_HEAD_P(skb);
979 if (hh->prim == DL_DATA_REQ) {
980 /* send packet up */
981 if (dsp->up) {
982 if (dsp->up->send(dsp->up, skb))
983 dev_kfree_skb(skb);
984 } else
985 dev_kfree_skb(skb);
986 } else {
987 /* send packet down */
988 if (dsp->ch.peer) {
989 dsp->data_pending = 1;
990 if (dsp->ch.recv(dsp->ch.peer, skb)) {
991 dev_kfree_skb(skb);
992 dsp->data_pending = 0;
993 }
994 } else
995 dev_kfree_skb(skb);
996 }
997 }
998}
999
1000static int
1001dspcreate(struct channel_req *crq)
1002{
1003 struct dsp *ndsp;
1004 u_long flags;
1005
1006 if (crq->protocol != ISDN_P_B_L2DSP
1007 && crq->protocol != ISDN_P_B_L2DSPHDLC)
1008 return -EPROTONOSUPPORT;
1009 ndsp = vmalloc(sizeof(struct dsp));
1010 if (!ndsp) {
1011 printk(KERN_ERR "%s: vmalloc struct dsp failed\n", __func__);
1012 return -ENOMEM;
1013 }
1014 memset(ndsp, 0, sizeof(struct dsp));
1015 if (dsp_debug & DEBUG_DSP_CTRL)
1016 printk(KERN_DEBUG "%s: creating new dsp instance\n", __func__);
1017
1018 /* default enabled */
1019 INIT_WORK(&ndsp->workq, (void *)dsp_send_bh);
1020 skb_queue_head_init(&ndsp->sendq);
1021 ndsp->ch.send = dsp_function;
1022 ndsp->ch.ctrl = dsp_ctrl;
1023 ndsp->up = crq->ch;
1024 crq->ch = &ndsp->ch;
1025 if (crq->protocol == ISDN_P_B_L2DSP) {
1026 crq->protocol = ISDN_P_B_RAW;
1027 ndsp->hdlc = 0;
1028 } else {
1029 crq->protocol = ISDN_P_B_HDLC;
1030 ndsp->hdlc = 1;
1031 }
1032 if (!try_module_get(THIS_MODULE))
1033 printk(KERN_WARNING "%s:cannot get module\n",
1034 __func__);
1035
1036 sprintf(ndsp->name, "DSP_C%x(0x%p)",
1037 ndsp->up->st->dev->id + 1, ndsp);
1038 /* set frame size to start */
1039 ndsp->features.hfc_id = -1; /* current PCM id */
1040 ndsp->features.pcm_id = -1; /* current PCM id */
1041 ndsp->pcm_slot_rx = -1; /* current CPM slot */
1042 ndsp->pcm_slot_tx = -1;
1043 ndsp->pcm_bank_rx = -1;
1044 ndsp->pcm_bank_tx = -1;
1045 ndsp->hfc_conf = -1; /* current conference number */
1046 /* set tone timer */
1047 ndsp->tone.tl.function = (void *)dsp_tone_timeout;
1048 ndsp->tone.tl.data = (long) ndsp;
1049 init_timer(&ndsp->tone.tl);
1050
1051 if (dtmfthreshold < 20 || dtmfthreshold > 500)
1052 dtmfthreshold = 200;
1053 ndsp->dtmf.treshold = dtmfthreshold*10000;
1054
1055 /* init pipeline append to list */
1056 spin_lock_irqsave(&dsp_lock, flags);
1057 dsp_pipeline_init(&ndsp->pipeline);
1058 list_add_tail(&ndsp->list, &dsp_ilist);
1059 spin_unlock_irqrestore(&dsp_lock, flags);
1060
1061 return 0;
1062}
1063
1064
1065static struct Bprotocol DSP = {
1066 .Bprotocols = (1 << (ISDN_P_B_L2DSP & ISDN_P_B_MASK))
1067 | (1 << (ISDN_P_B_L2DSPHDLC & ISDN_P_B_MASK)),
1068 .name = "dsp",
1069 .create = dspcreate
1070};
1071
1072static int dsp_init(void)
1073{
1074 int err;
1075 int tics;
1076
1077 printk(KERN_INFO "DSP modul %s\n", mISDN_dsp_revision);
1078
1079 dsp_options = options;
1080 dsp_debug = debug;
1081
1082 /* set packet size */
1083 dsp_poll = poll;
1084 if (dsp_poll) {
1085 if (dsp_poll > MAX_POLL) {
1086 printk(KERN_ERR "%s: Wrong poll value (%d), use %d "
1087 "maximum.\n", __func__, poll, MAX_POLL);
1088 err = -EINVAL;
1089 return err;
1090 }
1091 if (dsp_poll < 8) {
1092 printk(KERN_ERR "%s: Wrong poll value (%d), use 8 "
1093 "minimum.\n", __func__, dsp_poll);
1094 err = -EINVAL;
1095 return err;
1096 }
1097 dsp_tics = poll * HZ / 8000;
1098 if (dsp_tics * 8000 != poll * HZ) {
1099 printk(KERN_INFO "mISDN_dsp: Cannot clock every %d "
1100 "samples (0,125 ms). It is not a multiple of "
1101 "%d HZ.\n", poll, HZ);
1102 err = -EINVAL;
1103 return err;
1104 }
1105 } else {
1106 poll = 8;
1107 while (poll <= MAX_POLL) {
1108 tics = poll * HZ / 8000;
1109 if (tics * 8000 == poll * HZ) {
1110 dsp_tics = tics;
1111 dsp_poll = poll;
1112 if (poll >= 64)
1113 break;
1114 }
1115 poll++;
1116 }
1117 }
1118 if (dsp_poll == 0) {
1119 printk(KERN_INFO "mISDN_dsp: There is no multiple of kernel "
1120 "clock that equals exactly the duration of 8-256 "
1121 "samples. (Choose kernel clock speed like 100, 250, "
1122 "300, 1000)\n");
1123 err = -EINVAL;
1124 return err;
1125 }
1126 printk(KERN_INFO "mISDN_dsp: DSP clocks every %d samples. This equals "
1127 "%d jiffies.\n", dsp_poll, dsp_tics);
1128
1129 spin_lock_init(&dsp_lock);
1130 INIT_LIST_HEAD(&dsp_ilist);
1131 INIT_LIST_HEAD(&conf_ilist);
1132
1133 /* init conversion tables */
1134 dsp_audio_generate_law_tables();
1135 dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a;
1136 dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32:
1137 dsp_audio_alaw_to_s32;
1138 dsp_audio_generate_s2law_table();
1139 dsp_audio_generate_seven();
1140 dsp_audio_generate_mix_table();
1141 if (dsp_options & DSP_OPT_ULAW)
1142 dsp_audio_generate_ulaw_samples();
1143 dsp_audio_generate_volume_changes();
1144
1145 err = dsp_pipeline_module_init();
1146 if (err) {
1147 printk(KERN_ERR "mISDN_dsp: Can't initialize pipeline, "
1148 "error(%d)\n", err);
1149 return err;
1150 }
1151
1152 err = mISDN_register_Bprotocol(&DSP);
1153 if (err) {
1154 printk(KERN_ERR "Can't register %s error(%d)\n", DSP.name, err);
1155 return err;
1156 }
1157
1158 /* set sample timer */
1159 dsp_spl_tl.function = (void *)dsp_cmx_send;
1160 dsp_spl_tl.data = 0;
1161 init_timer(&dsp_spl_tl);
1162 dsp_spl_tl.expires = jiffies + dsp_tics;
1163 dsp_spl_jiffies = dsp_spl_tl.expires;
1164 add_timer(&dsp_spl_tl);
1165
1166 return 0;
1167}
1168
1169
1170static void dsp_cleanup(void)
1171{
1172 mISDN_unregister_Bprotocol(&DSP);
1173
1174 if (timer_pending(&dsp_spl_tl))
1175 del_timer(&dsp_spl_tl);
1176
1177 if (!list_empty(&dsp_ilist)) {
1178 printk(KERN_ERR "mISDN_dsp: Audio DSP object inst list not "
1179 "empty.\n");
1180 }
1181 if (!list_empty(&conf_ilist)) {
1182 printk(KERN_ERR "mISDN_dsp: Conference list not empty. Not "
1183 "all memory freed.\n");
1184 }
1185
1186 dsp_pipeline_module_exit();
1187}
1188
1189module_init(dsp_init);
1190module_exit(dsp_cleanup);
1191
diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c
new file mode 100644
index 000000000000..efc371c1f0dc
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_dtmf.c
@@ -0,0 +1,303 @@
1/*
2 * DTMF decoder.
3 *
4 * Copyright by Andreas Eversberg (jolly@eversberg.eu)
5 * based on different decoders such as ISDN4Linux
6 *
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
9 *
10 */
11
12#include <linux/mISDNif.h>
13#include <linux/mISDNdsp.h>
14#include "core.h"
15#include "dsp.h"
16
17#define NCOEFF 8 /* number of frequencies to be analyzed */
18
19/* For DTMF recognition:
20 * 2 * cos(2 * PI * k / N) precalculated for all k
21 */
22static u64 cos2pik[NCOEFF] =
23{
24 /* k << 15 (source: hfc-4s/8s documentation (www.colognechip.de)) */
25 55960, 53912, 51402, 48438, 38146, 32650, 26170, 18630
26};
27
28/* digit matrix */
29static char dtmf_matrix[4][4] =
30{
31 {'1', '2', '3', 'A'},
32 {'4', '5', '6', 'B'},
33 {'7', '8', '9', 'C'},
34 {'*', '0', '#', 'D'}
35};
36
37/* dtmf detection using goertzel algorithm
38 * init function
39 */
40void dsp_dtmf_goertzel_init(struct dsp *dsp)
41{
42 dsp->dtmf.size = 0;
43 dsp->dtmf.lastwhat = '\0';
44 dsp->dtmf.lastdigit = '\0';
45 dsp->dtmf.count = 0;
46}
47
48/* check for hardware or software features
49 */
50void dsp_dtmf_hardware(struct dsp *dsp)
51{
52 int hardware = 1;
53
54 if (!dsp->features.hfc_dtmf)
55 hardware = 0;
56
57 /* check for volume change */
58 if (dsp->tx_volume) {
59 if (dsp_debug & DEBUG_DSP_DTMF)
60 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
61 "because tx_volume is changed\n",
62 __func__, dsp->name);
63 hardware = 0;
64 }
65 if (dsp->rx_volume) {
66 if (dsp_debug & DEBUG_DSP_DTMF)
67 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
68 "because rx_volume is changed\n",
69 __func__, dsp->name);
70 hardware = 0;
71 }
72 /* check if encryption is enabled */
73 if (dsp->bf_enable) {
74 if (dsp_debug & DEBUG_DSP_DTMF)
75 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
76 "because encryption is enabled\n",
77 __func__, dsp->name);
78 hardware = 0;
79 }
80 /* check if pipeline exists */
81 if (dsp->pipeline.inuse) {
82 if (dsp_debug & DEBUG_DSP_DTMF)
83 printk(KERN_DEBUG "%s dsp %s cannot do hardware DTMF, "
84 "because pipeline exists.\n",
85 __func__, dsp->name);
86 hardware = 0;
87 }
88
89 dsp->dtmf.hardware = hardware;
90 dsp->dtmf.software = !hardware;
91}
92
93
94/*************************************************************
95 * calculate the coefficients of the given sample and decode *
96 *************************************************************/
97
98/* the given sample is decoded. if the sample is not long enough for a
99 * complete frame, the decoding is finished and continued with the next
100 * call of this function.
101 *
102 * the algorithm is very good for detection with a minimum of errors. i
103 * tested it allot. it even works with very short tones (40ms). the only
104 * disadvantage is, that it doesn't work good with different volumes of both
105 * tones. this will happen, if accoustically coupled dialers are used.
106 * it sometimes detects tones during speach, which is normal for decoders.
107 * use sequences to given commands during calls.
108 *
109 * dtmf - points to a structure of the current dtmf state
110 * spl and len - the sample
111 * fmt - 0 = alaw, 1 = ulaw, 2 = coefficients from HFC DTMF hw-decoder
112 */
113
114u8
115*dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, int fmt)
116{
117 u8 what;
118 int size;
119 signed short *buf;
120 s32 sk, sk1, sk2;
121 int k, n, i;
122 s32 *hfccoeff;
123 s32 result[NCOEFF], tresh, treshl;
124 int lowgroup, highgroup;
125 s64 cos2pik_;
126
127 dsp->dtmf.digits[0] = '\0';
128
129 /* Note: The function will loop until the buffer has not enough samples
130 * left to decode a full frame.
131 */
132again:
133 /* convert samples */
134 size = dsp->dtmf.size;
135 buf = dsp->dtmf.buffer;
136 switch (fmt) {
137 case 0: /* alaw */
138 case 1: /* ulaw */
139 while (size < DSP_DTMF_NPOINTS && len) {
140 buf[size++] = dsp_audio_law_to_s32[*data++];
141 len--;
142 }
143 break;
144
145 case 2: /* HFC coefficients */
146 default:
147 if (len < 64) {
148 if (len > 0)
149 printk(KERN_ERR "%s: coefficients have invalid "
150 "size. (is=%d < must=%d)\n",
151 __func__, len, 64);
152 return dsp->dtmf.digits;
153 }
154 hfccoeff = (s32 *)data;
155 for (k = 0; k < NCOEFF; k++) {
156 sk2 = (*hfccoeff++)>>4;
157 sk = (*hfccoeff++)>>4;
158 if (sk > 32767 || sk < -32767 || sk2 > 32767
159 || sk2 < -32767)
160 printk(KERN_WARNING
161 "DTMF-Detection overflow\n");
162 /* compute |X(k)|**2 */
163 result[k] =
164 (sk * sk) -
165 (((cos2pik[k] * sk) >> 15) * sk2) +
166 (sk2 * sk2);
167 }
168 data += 64;
169 len -= 64;
170 goto coefficients;
171 break;
172 }
173 dsp->dtmf.size = size;
174
175 if (size < DSP_DTMF_NPOINTS)
176 return dsp->dtmf.digits;
177
178 dsp->dtmf.size = 0;
179
180 /* now we have a full buffer of signed long samples - we do goertzel */
181 for (k = 0; k < NCOEFF; k++) {
182 sk = 0;
183 sk1 = 0;
184 sk2 = 0;
185 buf = dsp->dtmf.buffer;
186 cos2pik_ = cos2pik[k];
187 for (n = 0; n < DSP_DTMF_NPOINTS; n++) {
188 sk = ((cos2pik_*sk1)>>15) - sk2 + (*buf++);
189 sk2 = sk1;
190 sk1 = sk;
191 }
192 sk >>= 8;
193 sk2 >>= 8;
194 if (sk > 32767 || sk < -32767 || sk2 > 32767 || sk2 < -32767)
195 printk(KERN_WARNING "DTMF-Detection overflow\n");
196 /* compute |X(k)|**2 */
197 result[k] =
198 (sk * sk) -
199 (((cos2pik[k] * sk) >> 15) * sk2) +
200 (sk2 * sk2);
201 }
202
203 /* our (squared) coefficients have been calculated, we need to process
204 * them.
205 */
206coefficients:
207 tresh = 0;
208 for (i = 0; i < NCOEFF; i++) {
209 if (result[i] < 0)
210 result[i] = 0;
211 if (result[i] > dsp->dtmf.treshold) {
212 if (result[i] > tresh)
213 tresh = result[i];
214 }
215 }
216
217 if (tresh == 0) {
218 what = 0;
219 goto storedigit;
220 }
221
222 if (dsp_debug & DEBUG_DSP_DTMFCOEFF)
223 printk(KERN_DEBUG "a %3d %3d %3d %3d %3d %3d %3d %3d"
224 " tr:%3d r %3d %3d %3d %3d %3d %3d %3d %3d\n",
225 result[0]/10000, result[1]/10000, result[2]/10000,
226 result[3]/10000, result[4]/10000, result[5]/10000,
227 result[6]/10000, result[7]/10000, tresh/10000,
228 result[0]/(tresh/100), result[1]/(tresh/100),
229 result[2]/(tresh/100), result[3]/(tresh/100),
230 result[4]/(tresh/100), result[5]/(tresh/100),
231 result[6]/(tresh/100), result[7]/(tresh/100));
232
233 /* calc digit (lowgroup/highgroup) */
234 lowgroup = -1;
235 highgroup = -1;
236 treshl = tresh >> 3; /* tones which are not on, must be below 9 dB */
237 tresh = tresh >> 2; /* touchtones must match within 6 dB */
238 for (i = 0; i < NCOEFF; i++) {
239 if (result[i] < treshl)
240 continue; /* ignore */
241 if (result[i] < tresh) {
242 lowgroup = -1;
243 highgroup = -1;
244 break; /* noise inbetween */
245 }
246 /* good level found. This is allowed only one time per group */
247 if (i < NCOEFF/2) {
248 /* lowgroup */
249 if (lowgroup >= 0) {
250 /* Bad. Another tone found. */
251 lowgroup = -1;
252 break;
253 } else
254 lowgroup = i;
255 } else {
256 /* higroup */
257 if (highgroup >= 0) {
258 /* Bad. Another tone found. */
259 highgroup = -1;
260 break;
261 } else
262 highgroup = i-(NCOEFF/2);
263 }
264 }
265
266 /* get digit or null */
267 what = 0;
268 if (lowgroup >= 0 && highgroup >= 0)
269 what = dtmf_matrix[lowgroup][highgroup];
270
271storedigit:
272 if (what && (dsp_debug & DEBUG_DSP_DTMF))
273 printk(KERN_DEBUG "DTMF what: %c\n", what);
274
275 if (dsp->dtmf.lastwhat != what)
276 dsp->dtmf.count = 0;
277
278 /* the tone (or no tone) must remain 3 times without change */
279 if (dsp->dtmf.count == 2) {
280 if (dsp->dtmf.lastdigit != what) {
281 dsp->dtmf.lastdigit = what;
282 if (what) {
283 if (dsp_debug & DEBUG_DSP_DTMF)
284 printk(KERN_DEBUG "DTMF digit: %c\n",
285 what);
286 if ((strlen(dsp->dtmf.digits)+1)
287 < sizeof(dsp->dtmf.digits)) {
288 dsp->dtmf.digits[strlen(
289 dsp->dtmf.digits)+1] = '\0';
290 dsp->dtmf.digits[strlen(
291 dsp->dtmf.digits)] = what;
292 }
293 }
294 }
295 } else
296 dsp->dtmf.count++;
297
298 dsp->dtmf.lastwhat = what;
299
300 goto again;
301}
302
303
diff --git a/drivers/isdn/mISDN/dsp_ecdis.h b/drivers/isdn/mISDN/dsp_ecdis.h
new file mode 100644
index 000000000000..8a20af43308b
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_ecdis.h
@@ -0,0 +1,110 @@
1/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * ec_disable_detector.h - A detector which should eventually meet the
5 * G.164/G.165 requirements for detecting the
6 * 2100Hz echo cancellor disable tone.
7 *
8 * Written by Steve Underwood <steveu@coppice.org>
9 *
10 * Copyright (C) 2001 Steve Underwood
11 *
12 * All rights reserved.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "dsp_biquad.h"
31
32struct ec_disable_detector_state {
33 struct biquad2_state notch;
34 int notch_level;
35 int channel_level;
36 int tone_present;
37 int tone_cycle_duration;
38 int good_cycles;
39 int hit;
40};
41
42
43#define FALSE 0
44#define TRUE (!FALSE)
45
46static inline void
47echo_can_disable_detector_init(struct ec_disable_detector_state *det)
48{
49 /* Elliptic notch */
50 /* This is actually centred at 2095Hz, but gets the balance we want, due
51 to the asymmetric walls of the notch */
52 biquad2_init(&det->notch,
53 (int32_t) (-0.7600000*32768.0),
54 (int32_t) (-0.1183852*32768.0),
55 (int32_t) (-0.5104039*32768.0),
56 (int32_t) (0.1567596*32768.0),
57 (int32_t) (1.0000000*32768.0));
58
59 det->channel_level = 0;
60 det->notch_level = 0;
61 det->tone_present = FALSE;
62 det->tone_cycle_duration = 0;
63 det->good_cycles = 0;
64 det->hit = 0;
65}
66/*- End of function --------------------------------------------------------*/
67
68static inline int
69echo_can_disable_detector_update(struct ec_disable_detector_state *det,
70int16_t amp)
71{
72 int16_t notched;
73
74 notched = biquad2(&det->notch, amp);
75 /* Estimate the overall energy in the channel, and the energy in
76 the notch (i.e. overall channel energy - tone energy => noise).
77 Use abs instead of multiply for speed (is it really faster?).
78 Damp the overall energy a little more for a stable result.
79 Damp the notch energy a little less, so we don't damp out the
80 blip every time the phase reverses */
81 det->channel_level += ((abs(amp) - det->channel_level) >> 5);
82 det->notch_level += ((abs(notched) - det->notch_level) >> 4);
83 if (det->channel_level > 280) {
84 /* There is adequate energy in the channel.
85 Is it mostly at 2100Hz? */
86 if (det->notch_level*6 < det->channel_level) {
87 /* The notch says yes, so we have the tone. */
88 if (!det->tone_present) {
89 /* Do we get a kick every 450+-25ms? */
90 if (det->tone_cycle_duration >= 425*8
91 && det->tone_cycle_duration <= 475*8) {
92 det->good_cycles++;
93 if (det->good_cycles > 2)
94 det->hit = TRUE;
95 }
96 det->tone_cycle_duration = 0;
97 }
98 det->tone_present = TRUE;
99 } else
100 det->tone_present = FALSE;
101 det->tone_cycle_duration++;
102 } else {
103 det->tone_present = FALSE;
104 det->tone_cycle_duration = 0;
105 det->good_cycles = 0;
106 }
107 return det->hit;
108}
109/*- End of function --------------------------------------------------------*/
110/*- End of file ------------------------------------------------------------*/
diff --git a/drivers/isdn/mISDN/dsp_hwec.c b/drivers/isdn/mISDN/dsp_hwec.c
new file mode 100644
index 000000000000..eb892d9dd5c6
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_hwec.c
@@ -0,0 +1,138 @@
1/*
2 * dsp_hwec.c:
3 * builtin mISDN dsp pipeline element for enabling the hw echocanceller
4 *
5 * Copyright (C) 2007, Nadi Sarrar
6 *
7 * Nadi Sarrar <nadi@beronet.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 * The full GNU General Public License is included in this distribution in the
24 * file called LICENSE.
25 *
26 */
27
28#include <linux/kernel.h>
29#include <linux/string.h>
30#include <linux/mISDNdsp.h>
31#include <linux/mISDNif.h>
32#include "core.h"
33#include "dsp.h"
34#include "dsp_hwec.h"
35
36static struct mISDN_dsp_element_arg args[] = {
37 { "deftaps", "128", "Set the number of taps of cancellation." },
38};
39
40static struct mISDN_dsp_element dsp_hwec_p = {
41 .name = "hwec",
42 .new = NULL,
43 .free = NULL,
44 .process_tx = NULL,
45 .process_rx = NULL,
46 .num_args = sizeof(args) / sizeof(struct mISDN_dsp_element_arg),
47 .args = args,
48};
49struct mISDN_dsp_element *dsp_hwec = &dsp_hwec_p;
50
51void dsp_hwec_enable(struct dsp *dsp, const char *arg)
52{
53 int deftaps = 128,
54 len;
55 struct mISDN_ctrl_req cq;
56
57 if (!dsp) {
58 printk(KERN_ERR "%s: failed to enable hwec: dsp is NULL\n",
59 __func__);
60 return;
61 }
62
63 if (!arg)
64 goto _do;
65
66 len = strlen(arg);
67 if (!len)
68 goto _do;
69
70 {
71 char _dup[len + 1];
72 char *dup, *tok, *name, *val;
73 int tmp;
74
75 strcpy(_dup, arg);
76 dup = _dup;
77
78 while ((tok = strsep(&dup, ","))) {
79 if (!strlen(tok))
80 continue;
81 name = strsep(&tok, "=");
82 val = tok;
83
84 if (!val)
85 continue;
86
87 if (!strcmp(name, "deftaps")) {
88 if (sscanf(val, "%d", &tmp) == 1)
89 deftaps = tmp;
90 }
91 }
92 }
93
94_do:
95 printk(KERN_DEBUG "%s: enabling hwec with deftaps=%d\n",
96 __func__, deftaps);
97 memset(&cq, 0, sizeof(cq));
98 cq.op = MISDN_CTRL_HFC_ECHOCAN_ON;
99 cq.p1 = deftaps;
100 if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
101 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
102 __func__);
103 return;
104 }
105}
106
107void dsp_hwec_disable(struct dsp *dsp)
108{
109 struct mISDN_ctrl_req cq;
110
111 if (!dsp) {
112 printk(KERN_ERR "%s: failed to disable hwec: dsp is NULL\n",
113 __func__);
114 return;
115 }
116
117 printk(KERN_DEBUG "%s: disabling hwec\n", __func__);
118 memset(&cq, 0, sizeof(cq));
119 cq.op = MISDN_CTRL_HFC_ECHOCAN_OFF;
120 if (!dsp->ch.peer->ctrl(&dsp->ch, CONTROL_CHANNEL, &cq)) {
121 printk(KERN_DEBUG "%s: CONTROL_CHANNEL failed\n",
122 __func__);
123 return;
124 }
125}
126
127int dsp_hwec_init(void)
128{
129 mISDN_dsp_element_register(dsp_hwec);
130
131 return 0;
132}
133
134void dsp_hwec_exit(void)
135{
136 mISDN_dsp_element_unregister(dsp_hwec);
137}
138
diff --git a/drivers/isdn/mISDN/dsp_hwec.h b/drivers/isdn/mISDN/dsp_hwec.h
new file mode 100644
index 000000000000..eebe80c3f713
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_hwec.h
@@ -0,0 +1,10 @@
1/*
2 * dsp_hwec.h
3 */
4
5extern struct mISDN_dsp_element *dsp_hwec;
6extern void dsp_hwec_enable(struct dsp *dsp, const char *arg);
7extern void dsp_hwec_disable(struct dsp *dsp);
8extern int dsp_hwec_init(void);
9extern void dsp_hwec_exit(void);
10
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
new file mode 100644
index 000000000000..850260ab57d0
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_pipeline.c
@@ -0,0 +1,348 @@
1/*
2 * dsp_pipeline.c: pipelined audio processing
3 *
4 * Copyright (C) 2007, Nadi Sarrar
5 *
6 * Nadi Sarrar <nadi@beronet.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 * The full GNU General Public License is included in this distribution in the
23 * file called LICENSE.
24 *
25 */
26
27#include <linux/kernel.h>
28#include <linux/list.h>
29#include <linux/string.h>
30#include <linux/mISDNif.h>
31#include <linux/mISDNdsp.h>
32#include "dsp.h"
33#include "dsp_hwec.h"
34
35/* uncomment for debugging */
36/*#define PIPELINE_DEBUG*/
37
38struct dsp_pipeline_entry {
39 struct mISDN_dsp_element *elem;
40 void *p;
41 struct list_head list;
42};
43struct dsp_element_entry {
44 struct mISDN_dsp_element *elem;
45 struct device dev;
46 struct list_head list;
47};
48
49static LIST_HEAD(dsp_elements);
50
51/* sysfs */
52static struct class *elements_class;
53
54static ssize_t
55attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
56{
57 struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
58 ssize_t len = 0;
59 int i = 0;
60
61 *buf = 0;
62 for (; i < elem->num_args; ++i)
63 len = sprintf(buf, "%sName: %s\n%s%s%sDescription: %s\n"
64 "\n", buf,
65 elem->args[i].name,
66 elem->args[i].def ? "Default: " : "",
67 elem->args[i].def ? elem->args[i].def : "",
68 elem->args[i].def ? "\n" : "",
69 elem->args[i].desc);
70
71 return len;
72}
73
74static struct device_attribute element_attributes[] = {
75 __ATTR(args, 0444, attr_show_args, NULL),
76};
77
78int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
79{
80 struct dsp_element_entry *entry;
81 int ret, i;
82
83 if (!elem)
84 return -EINVAL;
85
86 entry = kzalloc(sizeof(struct dsp_element_entry), GFP_KERNEL);
87 if (!entry)
88 return -ENOMEM;
89
90 entry->elem = elem;
91
92 entry->dev.class = elements_class;
93 dev_set_drvdata(&entry->dev, elem);
94 snprintf(entry->dev.bus_id, BUS_ID_SIZE, elem->name);
95 ret = device_register(&entry->dev);
96 if (ret) {
97 printk(KERN_ERR "%s: failed to register %s\n",
98 __func__, elem->name);
99 goto err1;
100 }
101
102 for (i = 0; i < (sizeof(element_attributes)
103 / sizeof(struct device_attribute)); ++i)
104 ret = device_create_file(&entry->dev,
105 &element_attributes[i]);
106 if (ret) {
107 printk(KERN_ERR "%s: failed to create device file\n",
108 __func__);
109 goto err2;
110 }
111
112 list_add_tail(&entry->list, &dsp_elements);
113
114 printk(KERN_DEBUG "%s: %s registered\n", __func__, elem->name);
115
116 return 0;
117
118err2:
119 device_unregister(&entry->dev);
120err1:
121 kfree(entry);
122 return ret;
123}
124EXPORT_SYMBOL(mISDN_dsp_element_register);
125
126void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem)
127{
128 struct dsp_element_entry *entry, *n;
129
130 if (!elem)
131 return;
132
133 list_for_each_entry_safe(entry, n, &dsp_elements, list)
134 if (entry->elem == elem) {
135 list_del(&entry->list);
136 device_unregister(&entry->dev);
137 kfree(entry);
138 printk(KERN_DEBUG "%s: %s unregistered\n",
139 __func__, elem->name);
140 return;
141 }
142 printk(KERN_ERR "%s: element %s not in list.\n", __func__, elem->name);
143}
144EXPORT_SYMBOL(mISDN_dsp_element_unregister);
145
146int dsp_pipeline_module_init(void)
147{
148 elements_class = class_create(THIS_MODULE, "dsp_pipeline");
149 if (IS_ERR(elements_class))
150 return PTR_ERR(elements_class);
151
152#ifdef PIPELINE_DEBUG
153 printk(KERN_DEBUG "%s: dsp pipeline module initialized\n", __func__);
154#endif
155
156 dsp_hwec_init();
157
158 return 0;
159}
160
161void dsp_pipeline_module_exit(void)
162{
163 struct dsp_element_entry *entry, *n;
164
165 dsp_hwec_exit();
166
167 class_destroy(elements_class);
168
169 list_for_each_entry_safe(entry, n, &dsp_elements, list) {
170 list_del(&entry->list);
171 printk(KERN_WARNING "%s: element was still registered: %s\n",
172 __func__, entry->elem->name);
173 kfree(entry);
174 }
175
176 printk(KERN_DEBUG "%s: dsp pipeline module exited\n", __func__);
177}
178
179int dsp_pipeline_init(struct dsp_pipeline *pipeline)
180{
181 if (!pipeline)
182 return -EINVAL;
183
184 INIT_LIST_HEAD(&pipeline->list);
185
186#ifdef PIPELINE_DEBUG
187 printk(KERN_DEBUG "%s: dsp pipeline ready\n", __func__);
188#endif
189
190 return 0;
191}
192
193static inline void _dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
194{
195 struct dsp_pipeline_entry *entry, *n;
196
197 list_for_each_entry_safe(entry, n, &pipeline->list, list) {
198 list_del(&entry->list);
199 if (entry->elem == dsp_hwec)
200 dsp_hwec_disable(container_of(pipeline, struct dsp,
201 pipeline));
202 else
203 entry->elem->free(entry->p);
204 kfree(entry);
205 }
206}
207
208void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
209{
210
211 if (!pipeline)
212 return;
213
214 _dsp_pipeline_destroy(pipeline);
215
216#ifdef PIPELINE_DEBUG
217 printk(KERN_DEBUG "%s: dsp pipeline destroyed\n", __func__);
218#endif
219}
220
221int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
222{
223 int len, incomplete = 0, found = 0;
224 char *dup, *tok, *name, *args;
225 struct dsp_element_entry *entry, *n;
226 struct dsp_pipeline_entry *pipeline_entry;
227 struct mISDN_dsp_element *elem;
228
229 if (!pipeline)
230 return -EINVAL;
231
232 if (!list_empty(&pipeline->list))
233 _dsp_pipeline_destroy(pipeline);
234
235 if (!cfg)
236 return 0;
237
238 len = strlen(cfg);
239 if (!len)
240 return 0;
241
242 dup = kmalloc(len + 1, GFP_KERNEL);
243 if (!dup)
244 return 0;
245 strcpy(dup, cfg);
246 while ((tok = strsep(&dup, "|"))) {
247 if (!strlen(tok))
248 continue;
249 name = strsep(&tok, "(");
250 args = strsep(&tok, ")");
251 if (args && !*args)
252 args = 0;
253
254 list_for_each_entry_safe(entry, n, &dsp_elements, list)
255 if (!strcmp(entry->elem->name, name)) {
256 elem = entry->elem;
257
258 pipeline_entry = kmalloc(sizeof(struct
259 dsp_pipeline_entry), GFP_KERNEL);
260 if (!pipeline_entry) {
261 printk(KERN_DEBUG "%s: failed to add "
262 "entry to pipeline: %s (out of "
263 "memory)\n", __func__, elem->name);
264 incomplete = 1;
265 goto _out;
266 }
267 pipeline_entry->elem = elem;
268
269 if (elem == dsp_hwec) {
270 /* This is a hack to make the hwec
271 available as a pipeline module */
272 dsp_hwec_enable(container_of(pipeline,
273 struct dsp, pipeline), args);
274 list_add_tail(&pipeline_entry->list,
275 &pipeline->list);
276 } else {
277 pipeline_entry->p = elem->new(args);
278 if (pipeline_entry->p) {
279 list_add_tail(&pipeline_entry->
280 list, &pipeline->list);
281#ifdef PIPELINE_DEBUG
282 printk(KERN_DEBUG "%s: created "
283 "instance of %s%s%s\n",
284 __func__, name, args ?
285 " with args " : "", args ?
286 args : "");
287#endif
288 } else {
289 printk(KERN_DEBUG "%s: failed "
290 "to add entry to pipeline: "
291 "%s (new() returned NULL)\n",
292 __func__, elem->name);
293 kfree(pipeline_entry);
294 incomplete = 1;
295 }
296 }
297 found = 1;
298 break;
299 }
300
301 if (found)
302 found = 0;
303 else {
304 printk(KERN_DEBUG "%s: element not found, skipping: "
305 "%s\n", __func__, name);
306 incomplete = 1;
307 }
308 }
309
310_out:
311 if (!list_empty(&pipeline->list))
312 pipeline->inuse = 1;
313 else
314 pipeline->inuse = 0;
315
316#ifdef PIPELINE_DEBUG
317 printk(KERN_DEBUG "%s: dsp pipeline built%s: %s\n",
318 __func__, incomplete ? " incomplete" : "", cfg);
319#endif
320 kfree(dup);
321 return 0;
322}
323
324void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
325{
326 struct dsp_pipeline_entry *entry;
327
328 if (!pipeline)
329 return;
330
331 list_for_each_entry(entry, &pipeline->list, list)
332 if (entry->elem->process_tx)
333 entry->elem->process_tx(entry->p, data, len);
334}
335
336void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len)
337{
338 struct dsp_pipeline_entry *entry;
339
340 if (!pipeline)
341 return;
342
343 list_for_each_entry_reverse(entry, &pipeline->list, list)
344 if (entry->elem->process_rx)
345 entry->elem->process_rx(entry->p, data, len);
346}
347
348
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
new file mode 100644
index 000000000000..23dd0dd21524
--- /dev/null
+++ b/drivers/isdn/mISDN/dsp_tones.c
@@ -0,0 +1,551 @@
1/*
2 * Audio support data for ISDN4Linux.
3 *
4 * Copyright Andreas Eversberg (jolly@eversberg.eu)
5 *
6 * This software may be used and distributed according to the terms
7 * of the GNU General Public License, incorporated herein by reference.
8 *
9 */
10
11#include <linux/mISDNif.h>
12#include <linux/mISDNdsp.h>
13#include "core.h"
14#include "dsp.h"
15
16
17#define DATA_S sample_silence
18#define SIZE_S (&sizeof_silence)
19#define DATA_GA sample_german_all
20#define SIZE_GA (&sizeof_german_all)
21#define DATA_GO sample_german_old
22#define SIZE_GO (&sizeof_german_old)
23#define DATA_DT sample_american_dialtone
24#define SIZE_DT (&sizeof_american_dialtone)
25#define DATA_RI sample_american_ringing
26#define SIZE_RI (&sizeof_american_ringing)
27#define DATA_BU sample_american_busy
28#define SIZE_BU (&sizeof_american_busy)
29#define DATA_S1 sample_special1
30#define SIZE_S1 (&sizeof_special1)
31#define DATA_S2 sample_special2
32#define SIZE_S2 (&sizeof_special2)
33#define DATA_S3 sample_special3
34#define SIZE_S3 (&sizeof_special3)
35
36/***************/
37/* tones loops */
38/***************/
39
40/* all tones are alaw encoded */
41/* the last sample+1 is in phase with the first sample. the error is low */
42
43static u8 sample_german_all[] = {
44 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
45 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
46 0xdc, 0xfc, 0x6c,
47 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
48 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
49 0xdc, 0xfc, 0x6c,
50 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
51 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
52 0xdc, 0xfc, 0x6c,
53 0x80, 0xab, 0x81, 0x6d, 0xfd, 0xdd, 0x5d, 0x9d,
54 0x4d, 0xd1, 0x89, 0x88, 0xd0, 0x4c, 0x9c, 0x5c,
55 0xdc, 0xfc, 0x6c,
56};
57static u32 sizeof_german_all = sizeof(sample_german_all);
58
59static u8 sample_german_old[] = {
60 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
61 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
62 0x8c,
63 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
64 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
65 0x8c,
66 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
67 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
68 0x8c,
69 0xec, 0x68, 0xe1, 0x6d, 0x6d, 0x91, 0x51, 0xed,
70 0x6d, 0x01, 0x1e, 0x10, 0x0c, 0x90, 0x60, 0x70,
71 0x8c,
72};
73static u32 sizeof_german_old = sizeof(sample_german_old);
74
75static u8 sample_american_dialtone[] = {
76 0x2a, 0x18, 0x90, 0x6c, 0x4c, 0xbc, 0x4c, 0x6c,
77 0x10, 0x58, 0x32, 0xb9, 0x31, 0x2d, 0x8d, 0x0d,
78 0x8d, 0x2d, 0x31, 0x99, 0x0f, 0x28, 0x60, 0xf0,
79 0xd0, 0x50, 0xd0, 0x30, 0x60, 0x08, 0x8e, 0x67,
80 0x09, 0x19, 0x21, 0xe1, 0xd9, 0xb9, 0x29, 0x67,
81 0x83, 0x02, 0xce, 0xbe, 0xee, 0x1a, 0x1b, 0xef,
82 0xbf, 0xcf, 0x03, 0x82, 0x66, 0x28, 0xb8, 0xd8,
83 0xe0, 0x20, 0x18, 0x08, 0x66, 0x8f, 0x09, 0x61,
84 0x31, 0xd1, 0x51, 0xd1, 0xf1, 0x61, 0x29, 0x0e,
85 0x98, 0x30, 0x2c, 0x8c, 0x0c, 0x8c, 0x2c, 0x30,
86 0xb8, 0x33, 0x59, 0x11, 0x6d, 0x4d, 0xbd, 0x4d,
87 0x6d, 0x91, 0x19,
88};
89static u32 sizeof_american_dialtone = sizeof(sample_american_dialtone);
90
91static u8 sample_american_ringing[] = {
92 0x2a, 0xe0, 0xac, 0x0c, 0xbc, 0x4c, 0x8c, 0x90,
93 0x48, 0xc7, 0xc1, 0xed, 0xcd, 0x4d, 0xcd, 0xed,
94 0xc1, 0xb7, 0x08, 0x30, 0xec, 0xcc, 0xcc, 0x8c,
95 0x10, 0x58, 0x1a, 0x99, 0x71, 0xed, 0x8d, 0x8d,
96 0x2d, 0x41, 0x89, 0x9e, 0x20, 0x70, 0x2c, 0xec,
97 0x2c, 0x70, 0x20, 0x86, 0x77, 0xe1, 0x31, 0x11,
98 0xd1, 0xf1, 0x81, 0x09, 0xa3, 0x56, 0x58, 0x00,
99 0x40, 0xc0, 0x60, 0x38, 0x46, 0x43, 0x57, 0x39,
100 0xd9, 0x59, 0x99, 0xc9, 0x77, 0x2f, 0x2e, 0xc6,
101 0xd6, 0x28, 0xd6, 0x36, 0x26, 0x2e, 0x8a, 0xa3,
102 0x43, 0x63, 0x4b, 0x4a, 0x62, 0x42, 0xa2, 0x8b,
103 0x2f, 0x27, 0x37, 0xd7, 0x29, 0xd7, 0xc7, 0x2f,
104 0x2e, 0x76, 0xc8, 0x98, 0x58, 0xd8, 0x38, 0x56,
105 0x42, 0x47, 0x39, 0x61, 0xc1, 0x41, 0x01, 0x59,
106 0x57, 0xa2, 0x08, 0x80, 0xf0, 0xd0, 0x10, 0x30,
107 0xe0, 0x76, 0x87, 0x21, 0x71, 0x2d, 0xed, 0x2d,
108 0x71, 0x21, 0x9f, 0x88, 0x40, 0x2c, 0x8c, 0x8c,
109 0xec, 0x70, 0x98, 0x1b, 0x59, 0x11, 0x8d, 0xcd,
110 0xcd, 0xed, 0x31, 0x09, 0xb6, 0xc0, 0xec, 0xcc,
111 0x4c, 0xcc, 0xec, 0xc0, 0xc6, 0x49, 0x91, 0x8d,
112 0x4d, 0xbd, 0x0d, 0xad, 0xe1,
113};
114static u32 sizeof_american_ringing = sizeof(sample_american_ringing);
115
116static u8 sample_american_busy[] = {
117 0x2a, 0x00, 0x6c, 0x4c, 0x4c, 0x6c, 0xb0, 0x66,
118 0x99, 0x11, 0x6d, 0x8d, 0x2d, 0x41, 0xd7, 0x96,
119 0x60, 0xf0, 0x70, 0x40, 0x58, 0xf6, 0x53, 0x57,
120 0x09, 0x89, 0xd7, 0x5f, 0xe3, 0x2a, 0xe3, 0x5f,
121 0xd7, 0x89, 0x09, 0x57, 0x53, 0xf6, 0x58, 0x40,
122 0x70, 0xf0, 0x60, 0x96, 0xd7, 0x41, 0x2d, 0x8d,
123 0x6d, 0x11, 0x99, 0x66, 0xb0, 0x6c, 0x4c, 0x4c,
124 0x6c, 0x00, 0x2a, 0x01, 0x6d, 0x4d, 0x4d, 0x6d,
125 0xb1, 0x67, 0x98, 0x10, 0x6c, 0x8c, 0x2c, 0x40,
126 0xd6, 0x97, 0x61, 0xf1, 0x71, 0x41, 0x59, 0xf7,
127 0x52, 0x56, 0x08, 0x88, 0xd6, 0x5e, 0xe2, 0x2a,
128 0xe2, 0x5e, 0xd6, 0x88, 0x08, 0x56, 0x52, 0xf7,
129 0x59, 0x41, 0x71, 0xf1, 0x61, 0x97, 0xd6, 0x40,
130 0x2c, 0x8c, 0x6c, 0x10, 0x98, 0x67, 0xb1, 0x6d,
131 0x4d, 0x4d, 0x6d, 0x01,
132};
133static u32 sizeof_american_busy = sizeof(sample_american_busy);
134
135static u8 sample_special1[] = {
136 0x2a, 0x2c, 0xbc, 0x6c, 0xd6, 0x71, 0xbd, 0x0d,
137 0xd9, 0x80, 0xcc, 0x4c, 0x40, 0x39, 0x0d, 0xbd,
138 0x11, 0x86, 0xec, 0xbc, 0xec, 0x0e, 0x51, 0xbd,
139 0x8d, 0x89, 0x30, 0x4c, 0xcc, 0xe0, 0xe1, 0xcd,
140 0x4d, 0x31, 0x88, 0x8c, 0xbc, 0x50, 0x0f, 0xed,
141 0xbd, 0xed, 0x87, 0x10, 0xbc, 0x0c, 0x38, 0x41,
142 0x4d, 0xcd, 0x81, 0xd8, 0x0c, 0xbc, 0x70, 0xd7,
143 0x6d, 0xbd, 0x2d,
144};
145static u32 sizeof_special1 = sizeof(sample_special1);
146
147static u8 sample_special2[] = {
148 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
149 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
150 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
151 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
152 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
153 0x2a, 0xcc, 0x8c, 0xd7, 0x4d, 0x2d, 0x18, 0xbc,
154 0x10, 0xc1, 0xbd, 0xc1, 0x10, 0xbc, 0x18, 0x2d,
155 0x4d, 0xd7, 0x8c, 0xcc, 0x2a, 0xcd, 0x8d, 0xd6,
156 0x4c, 0x2c, 0x19, 0xbd, 0x11, 0xc0, 0xbc, 0xc0,
157 0x11, 0xbd, 0x19, 0x2c, 0x4c, 0xd6, 0x8d, 0xcd,
158};
159static u32 sizeof_special2 = sizeof(sample_special2);
160
161static u8 sample_special3[] = {
162 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
163 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
164 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
165 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
166 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
167 0x2a, 0xbc, 0x18, 0xcd, 0x11, 0x2c, 0x8c, 0xc1,
168 0x4d, 0xd6, 0xbc, 0xd6, 0x4d, 0xc1, 0x8c, 0x2c,
169 0x11, 0xcd, 0x18, 0xbc, 0x2a, 0xbd, 0x19, 0xcc,
170 0x10, 0x2d, 0x8d, 0xc0, 0x4c, 0xd7, 0xbd, 0xd7,
171 0x4c, 0xc0, 0x8d, 0x2d, 0x10, 0xcc, 0x19, 0xbd,
172};
173static u32 sizeof_special3 = sizeof(sample_special3);
174
175static u8 sample_silence[] = {
176 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
177 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
178 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
179 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
180 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
181 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
182 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
183 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
184 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
185 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
186 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
187 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
188};
189static u32 sizeof_silence = sizeof(sample_silence);
190
191struct tones_samples {
192 u32 *len;
193 u8 *data;
194};
195static struct
196tones_samples samples[] = {
197 {&sizeof_german_all, sample_german_all},
198 {&sizeof_german_old, sample_german_old},
199 {&sizeof_american_dialtone, sample_american_dialtone},
200 {&sizeof_american_ringing, sample_american_ringing},
201 {&sizeof_american_busy, sample_american_busy},
202 {&sizeof_special1, sample_special1},
203 {&sizeof_special2, sample_special2},
204 {&sizeof_special3, sample_special3},
205 {NULL, NULL},
206};
207
208/***********************************
209 * generate ulaw from alaw samples *
210 ***********************************/
211
212void
213dsp_audio_generate_ulaw_samples(void)
214{
215 int i, j;
216
217 i = 0;
218 while (samples[i].len) {
219 j = 0;
220 while (j < (*samples[i].len)) {
221 samples[i].data[j] =
222 dsp_audio_alaw_to_ulaw[samples[i].data[j]];
223 j++;
224 }
225 i++;
226 }
227}
228
229
230/****************************
231 * tone sequence definition *
232 ****************************/
233
234struct pattern {
235 int tone;
236 u8 *data[10];
237 u32 *siz[10];
238 u32 seq[10];
239} pattern[] = {
240 {TONE_GERMAN_DIALTONE,
241 {DATA_GA, 0, 0, 0, 0, 0, 0, 0, 0, 0},
242 {SIZE_GA, 0, 0, 0, 0, 0, 0, 0, 0, 0},
243 {1900, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
244
245 {TONE_GERMAN_OLDDIALTONE,
246 {DATA_GO, 0, 0, 0, 0, 0, 0, 0, 0, 0},
247 {SIZE_GO, 0, 0, 0, 0, 0, 0, 0, 0, 0},
248 {1998, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
249
250 {TONE_AMERICAN_DIALTONE,
251 {DATA_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0},
252 {SIZE_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0},
253 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
254
255 {TONE_GERMAN_DIALPBX,
256 {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, 0, 0, 0, 0},
257 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, 0, 0, 0, 0},
258 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
259
260 {TONE_GERMAN_OLDDIALPBX,
261 {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, 0, 0, 0, 0},
262 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, 0, 0, 0, 0},
263 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
264
265 {TONE_AMERICAN_DIALPBX,
266 {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, 0, 0, 0, 0},
267 {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, 0, 0, 0, 0},
268 {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
269
270 {TONE_GERMAN_RINGING,
271 {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
272 {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
273 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
274
275 {TONE_GERMAN_OLDRINGING,
276 {DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
277 {SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
278 {8000, 40000, 0, 0, 0, 0, 0, 0, 0, 0} },
279
280 {TONE_AMERICAN_RINGING,
281 {DATA_RI, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
282 {SIZE_RI, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
283 {8000, 32000, 0, 0, 0, 0, 0, 0, 0, 0} },
284
285 {TONE_GERMAN_RINGPBX,
286 {DATA_GA, DATA_S, DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0},
287 {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0},
288 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
289
290 {TONE_GERMAN_OLDRINGPBX,
291 {DATA_GO, DATA_S, DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0},
292 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0},
293 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
294
295 {TONE_AMERICAN_RINGPBX,
296 {DATA_RI, DATA_S, DATA_RI, DATA_S, 0, 0, 0, 0, 0, 0},
297 {SIZE_RI, SIZE_S, SIZE_RI, SIZE_S, 0, 0, 0, 0, 0, 0},
298 {4000, 4000, 4000, 28000, 0, 0, 0, 0, 0, 0} },
299
300 {TONE_GERMAN_BUSY,
301 {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
302 {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
303 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
304
305 {TONE_GERMAN_OLDBUSY,
306 {DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
307 {SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
308 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
309
310 {TONE_AMERICAN_BUSY,
311 {DATA_BU, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
312 {SIZE_BU, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
313 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
314
315 {TONE_GERMAN_HANGUP,
316 {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
317 {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
318 {4000, 4000, 0, 0, 0, 0, 0, 0, 0, 0} },
319
320 {TONE_GERMAN_OLDHANGUP,
321 {DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
322 {SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
323 {1000, 5000, 0, 0, 0, 0, 0, 0, 0, 0} },
324
325 {TONE_AMERICAN_HANGUP,
326 {DATA_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0},
327 {SIZE_DT, 0, 0, 0, 0, 0, 0, 0, 0, 0},
328 {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
329
330 {TONE_SPECIAL_INFO,
331 {DATA_S1, DATA_S2, DATA_S3, DATA_S, 0, 0, 0, 0, 0, 0},
332 {SIZE_S1, SIZE_S2, SIZE_S3, SIZE_S, 0, 0, 0, 0, 0, 0},
333 {2666, 2666, 2666, 8002, 0, 0, 0, 0, 0, 0} },
334
335 {TONE_GERMAN_GASSENBESETZT,
336 {DATA_GA, DATA_S, 0, 0, 0, 0, 0, 0, 0, 0},
337 {SIZE_GA, SIZE_S, 0, 0, 0, 0, 0, 0, 0, 0},
338 {2000, 2000, 0, 0, 0, 0, 0, 0, 0, 0} },
339
340 {TONE_GERMAN_AUFSCHALTTON,
341 {DATA_GO, DATA_S, DATA_GO, DATA_S, 0, 0, 0, 0, 0, 0},
342 {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, 0, 0, 0, 0, 0, 0},
343 {1000, 5000, 1000, 17000, 0, 0, 0, 0, 0, 0} },
344
345 {0,
346 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
347 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
348 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
349};
350
351/******************
352 * copy tone data *
353 ******************/
354
355/* an sk_buff is generated from the number of samples needed.
356 * the count will be changed and may begin from 0 each pattern period.
357 * the clue is to precalculate the pointers and legths to use only one
358 * memcpy per function call, or two memcpy if the tone sequence changes.
359 *
360 * pattern - the type of the pattern
361 * count - the sample from the beginning of the pattern (phase)
362 * len - the number of bytes
363 *
364 * return - the sk_buff with the sample
365 *
366 * if tones has finished (e.g. knocking tone), dsp->tones is turned off
367 */
368void dsp_tone_copy(struct dsp *dsp, u8 *data, int len)
369{
370 int index, count, start, num;
371 struct pattern *pat;
372 struct dsp_tone *tone = &dsp->tone;
373
374 /* if we have no tone, we copy silence */
375 if (!tone->tone) {
376 memset(data, dsp_silence, len);
377 return;
378 }
379
380 /* process pattern */
381 pat = (struct pattern *)tone->pattern;
382 /* points to the current pattern */
383 index = tone->index; /* gives current sequence index */
384 count = tone->count; /* gives current sample */
385
386 /* copy sample */
387 while (len) {
388 /* find sample to start with */
389 while (42) {
390 /* warp arround */
391 if (!pat->seq[index]) {
392 count = 0;
393 index = 0;
394 }
395 /* check if we are currently playing this tone */
396 if (count < pat->seq[index])
397 break;
398 if (dsp_debug & DEBUG_DSP_TONE)
399 printk(KERN_DEBUG "%s: reaching next sequence "
400 "(index=%d)\n", __func__, index);
401 count -= pat->seq[index];
402 index++;
403 }
404 /* calculate start and number of samples */
405 start = count % (*(pat->siz[index]));
406 num = len;
407 if (num+count > pat->seq[index])
408 num = pat->seq[index] - count;
409 if (num+start > (*(pat->siz[index])))
410 num = (*(pat->siz[index])) - start;
411 /* copy memory */
412 memcpy(data, pat->data[index]+start, num);
413 /* reduce length */
414 data += num;
415 count += num;
416 len -= num;
417 }
418 tone->index = index;
419 tone->count = count;
420
421 /* return sk_buff */
422 return;
423}
424
425
426/*******************************
427 * send HW message to hfc card *
428 *******************************/
429
430static void
431dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
432{
433 struct sk_buff *nskb;
434
435 /* unlocking is not required, because we don't expect a response */
436 nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
437 (len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample,
438 GFP_ATOMIC);
439 if (nskb) {
440 if (dsp->ch.peer) {
441 if (dsp->ch.recv(dsp->ch.peer, nskb))
442 dev_kfree_skb(nskb);
443 } else
444 dev_kfree_skb(nskb);
445 }
446}
447
448
449/*****************
450 * timer expires *
451 *****************/
452void
453dsp_tone_timeout(void *arg)
454{
455 struct dsp *dsp = arg;
456 struct dsp_tone *tone = &dsp->tone;
457 struct pattern *pat = (struct pattern *)tone->pattern;
458 int index = tone->index;
459
460 if (!tone->tone)
461 return;
462
463 index++;
464 if (!pat->seq[index])
465 index = 0;
466 tone->index = index;
467
468 /* set next tone */
469 if (pat->data[index] == DATA_S)
470 dsp_tone_hw_message(dsp, 0, 0);
471 else
472 dsp_tone_hw_message(dsp, pat->data[index], *(pat->siz[index]));
473 /* set timer */
474 init_timer(&tone->tl);
475 tone->tl.expires = jiffies + (pat->seq[index] * HZ) / 8000;
476 add_timer(&tone->tl);
477}
478
479
480/********************
481 * set/release tone *
482 ********************/
483
484/*
485 * tones are relaized by streaming or by special loop commands if supported
486 * by hardware. when hardware is used, the patterns will be controlled by
487 * timers.
488 */
489int
490dsp_tone(struct dsp *dsp, int tone)
491{
492 struct pattern *pat;
493 int i;
494 struct dsp_tone *tonet = &dsp->tone;
495
496 tonet->software = 0;
497 tonet->hardware = 0;
498
499 /* we turn off the tone */
500 if (!tone) {
501 if (dsp->features.hfc_loops)
502 if (timer_pending(&tonet->tl))
503 del_timer(&tonet->tl);
504 if (dsp->features.hfc_loops)
505 dsp_tone_hw_message(dsp, NULL, 0);
506 tonet->tone = 0;
507 return 0;
508 }
509
510 pat = NULL;
511 i = 0;
512 while (pattern[i].tone) {
513 if (pattern[i].tone == tone) {
514 pat = &pattern[i];
515 break;
516 }
517 i++;
518 }
519 if (!pat) {
520 printk(KERN_WARNING "dsp: given tone 0x%x is invalid\n", tone);
521 return -EINVAL;
522 }
523 if (dsp_debug & DEBUG_DSP_TONE)
524 printk(KERN_DEBUG "%s: now starting tone %d (index=%d)\n",
525 __func__, tone, 0);
526 tonet->tone = tone;
527 tonet->pattern = pat;
528 tonet->index = 0;
529 tonet->count = 0;
530
531 if (dsp->features.hfc_loops) {
532 tonet->hardware = 1;
533 /* set first tone */
534 dsp_tone_hw_message(dsp, pat->data[0], *(pat->siz[0]));
535 /* set timer */
536 if (timer_pending(&tonet->tl))
537 del_timer(&tonet->tl);
538 init_timer(&tonet->tl);
539 tonet->tl.expires = jiffies + (pat->seq[0] * HZ) / 8000;
540 add_timer(&tonet->tl);
541 } else {
542 tonet->software = 1;
543 }
544
545 return 0;
546}
547
548
549
550
551
diff --git a/drivers/isdn/mISDN/fsm.c b/drivers/isdn/mISDN/fsm.c
new file mode 100644
index 000000000000..b5d6553f2dc8
--- /dev/null
+++ b/drivers/isdn/mISDN/fsm.c
@@ -0,0 +1,183 @@
1/*
2 * finite state machine implementation
3 *
4 * Author Karsten Keil <kkeil@novell.com>
5 *
6 * Thanks to Jan den Ouden
7 * Fritz Elfert
8 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/slab.h>
23#include <linux/module.h>
24#include <linux/string.h>
25#include "fsm.h"
26
27#define FSM_TIMER_DEBUG 0
28
29void
30mISDN_FsmNew(struct Fsm *fsm,
31 struct FsmNode *fnlist, int fncount)
32{
33 int i;
34
35 fsm->jumpmatrix = kzalloc(sizeof(FSMFNPTR) * fsm->state_count *
36 fsm->event_count, GFP_KERNEL);
37
38 for (i = 0; i < fncount; i++)
39 if ((fnlist[i].state >= fsm->state_count) ||
40 (fnlist[i].event >= fsm->event_count)) {
41 printk(KERN_ERR
42 "mISDN_FsmNew Error: %d st(%ld/%ld) ev(%ld/%ld)\n",
43 i, (long)fnlist[i].state, (long)fsm->state_count,
44 (long)fnlist[i].event, (long)fsm->event_count);
45 } else
46 fsm->jumpmatrix[fsm->state_count * fnlist[i].event +
47 fnlist[i].state] = (FSMFNPTR) fnlist[i].routine;
48}
49EXPORT_SYMBOL(mISDN_FsmNew);
50
51void
52mISDN_FsmFree(struct Fsm *fsm)
53{
54 kfree((void *) fsm->jumpmatrix);
55}
56EXPORT_SYMBOL(mISDN_FsmFree);
57
58int
59mISDN_FsmEvent(struct FsmInst *fi, int event, void *arg)
60{
61 FSMFNPTR r;
62
63 if ((fi->state >= fi->fsm->state_count) ||
64 (event >= fi->fsm->event_count)) {
65 printk(KERN_ERR
66 "mISDN_FsmEvent Error st(%ld/%ld) ev(%d/%ld)\n",
67 (long)fi->state, (long)fi->fsm->state_count, event,
68 (long)fi->fsm->event_count);
69 return 1;
70 }
71 r = fi->fsm->jumpmatrix[fi->fsm->state_count * event + fi->state];
72 if (r) {
73 if (fi->debug)
74 fi->printdebug(fi, "State %s Event %s",
75 fi->fsm->strState[fi->state],
76 fi->fsm->strEvent[event]);
77 r(fi, event, arg);
78 return 0;
79 } else {
80 if (fi->debug)
81 fi->printdebug(fi, "State %s Event %s no action",
82 fi->fsm->strState[fi->state],
83 fi->fsm->strEvent[event]);
84 return 1;
85 }
86}
87EXPORT_SYMBOL(mISDN_FsmEvent);
88
89void
90mISDN_FsmChangeState(struct FsmInst *fi, int newstate)
91{
92 fi->state = newstate;
93 if (fi->debug)
94 fi->printdebug(fi, "ChangeState %s",
95 fi->fsm->strState[newstate]);
96}
97EXPORT_SYMBOL(mISDN_FsmChangeState);
98
99static void
100FsmExpireTimer(struct FsmTimer *ft)
101{
102#if FSM_TIMER_DEBUG
103 if (ft->fi->debug)
104 ft->fi->printdebug(ft->fi, "FsmExpireTimer %lx", (long) ft);
105#endif
106 mISDN_FsmEvent(ft->fi, ft->event, ft->arg);
107}
108
109void
110mISDN_FsmInitTimer(struct FsmInst *fi, struct FsmTimer *ft)
111{
112 ft->fi = fi;
113 ft->tl.function = (void *) FsmExpireTimer;
114 ft->tl.data = (long) ft;
115#if FSM_TIMER_DEBUG
116 if (ft->fi->debug)
117 ft->fi->printdebug(ft->fi, "mISDN_FsmInitTimer %lx", (long) ft);
118#endif
119 init_timer(&ft->tl);
120}
121EXPORT_SYMBOL(mISDN_FsmInitTimer);
122
123void
124mISDN_FsmDelTimer(struct FsmTimer *ft, int where)
125{
126#if FSM_TIMER_DEBUG
127 if (ft->fi->debug)
128 ft->fi->printdebug(ft->fi, "mISDN_FsmDelTimer %lx %d",
129 (long) ft, where);
130#endif
131 del_timer(&ft->tl);
132}
133EXPORT_SYMBOL(mISDN_FsmDelTimer);
134
135int
136mISDN_FsmAddTimer(struct FsmTimer *ft,
137 int millisec, int event, void *arg, int where)
138{
139
140#if FSM_TIMER_DEBUG
141 if (ft->fi->debug)
142 ft->fi->printdebug(ft->fi, "mISDN_FsmAddTimer %lx %d %d",
143 (long) ft, millisec, where);
144#endif
145
146 if (timer_pending(&ft->tl)) {
147 if (ft->fi->debug) {
148 printk(KERN_WARNING
149 "mISDN_FsmAddTimer: timer already active!\n");
150 ft->fi->printdebug(ft->fi,
151 "mISDN_FsmAddTimer already active!");
152 }
153 return -1;
154 }
155 init_timer(&ft->tl);
156 ft->event = event;
157 ft->arg = arg;
158 ft->tl.expires = jiffies + (millisec * HZ) / 1000;
159 add_timer(&ft->tl);
160 return 0;
161}
162EXPORT_SYMBOL(mISDN_FsmAddTimer);
163
164void
165mISDN_FsmRestartTimer(struct FsmTimer *ft,
166 int millisec, int event, void *arg, int where)
167{
168
169#if FSM_TIMER_DEBUG
170 if (ft->fi->debug)
171 ft->fi->printdebug(ft->fi, "mISDN_FsmRestartTimer %lx %d %d",
172 (long) ft, millisec, where);
173#endif
174
175 if (timer_pending(&ft->tl))
176 del_timer(&ft->tl);
177 init_timer(&ft->tl);
178 ft->event = event;
179 ft->arg = arg;
180 ft->tl.expires = jiffies + (millisec * HZ) / 1000;
181 add_timer(&ft->tl);
182}
183EXPORT_SYMBOL(mISDN_FsmRestartTimer);
diff --git a/drivers/isdn/mISDN/fsm.h b/drivers/isdn/mISDN/fsm.h
new file mode 100644
index 000000000000..928f5be192c1
--- /dev/null
+++ b/drivers/isdn/mISDN/fsm.h
@@ -0,0 +1,67 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Thanks to Jan den Ouden
6 * Fritz Elfert
7 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#ifndef _MISDN_FSM_H
21#define _MISDN_FSM_H
22
23#include <linux/timer.h>
24
25/* Statemachine */
26
27struct FsmInst;
28
29typedef void (*FSMFNPTR)(struct FsmInst *, int, void *);
30
31struct Fsm {
32 FSMFNPTR *jumpmatrix;
33 int state_count, event_count;
34 char **strEvent, **strState;
35};
36
37struct FsmInst {
38 struct Fsm *fsm;
39 int state;
40 int debug;
41 void *userdata;
42 int userint;
43 void (*printdebug) (struct FsmInst *, char *, ...);
44};
45
46struct FsmNode {
47 int state, event;
48 void (*routine) (struct FsmInst *, int, void *);
49};
50
51struct FsmTimer {
52 struct FsmInst *fi;
53 struct timer_list tl;
54 int event;
55 void *arg;
56};
57
58extern void mISDN_FsmNew(struct Fsm *, struct FsmNode *, int);
59extern void mISDN_FsmFree(struct Fsm *);
60extern int mISDN_FsmEvent(struct FsmInst *, int , void *);
61extern void mISDN_FsmChangeState(struct FsmInst *, int);
62extern void mISDN_FsmInitTimer(struct FsmInst *, struct FsmTimer *);
63extern int mISDN_FsmAddTimer(struct FsmTimer *, int, int, void *, int);
64extern void mISDN_FsmRestartTimer(struct FsmTimer *, int, int, void *, int);
65extern void mISDN_FsmDelTimer(struct FsmTimer *, int);
66
67#endif
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
new file mode 100644
index 000000000000..2596fba4e614
--- /dev/null
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -0,0 +1,365 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/mISDNhw.h>
20
21static void
22dchannel_bh(struct work_struct *ws)
23{
24 struct dchannel *dch = container_of(ws, struct dchannel, workq);
25 struct sk_buff *skb;
26 int err;
27
28 if (test_and_clear_bit(FLG_RECVQUEUE, &dch->Flags)) {
29 while ((skb = skb_dequeue(&dch->rqueue))) {
30 if (likely(dch->dev.D.peer)) {
31 err = dch->dev.D.recv(dch->dev.D.peer, skb);
32 if (err)
33 dev_kfree_skb(skb);
34 } else
35 dev_kfree_skb(skb);
36 }
37 }
38 if (test_and_clear_bit(FLG_PHCHANGE, &dch->Flags)) {
39 if (dch->phfunc)
40 dch->phfunc(dch);
41 }
42}
43
44static void
45bchannel_bh(struct work_struct *ws)
46{
47 struct bchannel *bch = container_of(ws, struct bchannel, workq);
48 struct sk_buff *skb;
49 int err;
50
51 if (test_and_clear_bit(FLG_RECVQUEUE, &bch->Flags)) {
52 while ((skb = skb_dequeue(&bch->rqueue))) {
53 if (bch->rcount >= 64)
54 printk(KERN_WARNING "B-channel %p receive "
55 "queue if full, but empties...\n", bch);
56 bch->rcount--;
57 if (likely(bch->ch.peer)) {
58 err = bch->ch.recv(bch->ch.peer, skb);
59 if (err)
60 dev_kfree_skb(skb);
61 } else
62 dev_kfree_skb(skb);
63 }
64 }
65}
66
67int
68mISDN_initdchannel(struct dchannel *ch, int maxlen, void *phf)
69{
70 test_and_set_bit(FLG_HDLC, &ch->Flags);
71 ch->maxlen = maxlen;
72 ch->hw = NULL;
73 ch->rx_skb = NULL;
74 ch->tx_skb = NULL;
75 ch->tx_idx = 0;
76 ch->phfunc = phf;
77 skb_queue_head_init(&ch->squeue);
78 skb_queue_head_init(&ch->rqueue);
79 INIT_LIST_HEAD(&ch->dev.bchannels);
80 INIT_WORK(&ch->workq, dchannel_bh);
81 return 0;
82}
83EXPORT_SYMBOL(mISDN_initdchannel);
84
85int
86mISDN_initbchannel(struct bchannel *ch, int maxlen)
87{
88 ch->Flags = 0;
89 ch->maxlen = maxlen;
90 ch->hw = NULL;
91 ch->rx_skb = NULL;
92 ch->tx_skb = NULL;
93 ch->tx_idx = 0;
94 skb_queue_head_init(&ch->rqueue);
95 ch->rcount = 0;
96 ch->next_skb = NULL;
97 INIT_WORK(&ch->workq, bchannel_bh);
98 return 0;
99}
100EXPORT_SYMBOL(mISDN_initbchannel);
101
102int
103mISDN_freedchannel(struct dchannel *ch)
104{
105 if (ch->tx_skb) {
106 dev_kfree_skb(ch->tx_skb);
107 ch->tx_skb = NULL;
108 }
109 if (ch->rx_skb) {
110 dev_kfree_skb(ch->rx_skb);
111 ch->rx_skb = NULL;
112 }
113 skb_queue_purge(&ch->squeue);
114 skb_queue_purge(&ch->rqueue);
115 flush_scheduled_work();
116 return 0;
117}
118EXPORT_SYMBOL(mISDN_freedchannel);
119
120int
121mISDN_freebchannel(struct bchannel *ch)
122{
123 if (ch->tx_skb) {
124 dev_kfree_skb(ch->tx_skb);
125 ch->tx_skb = NULL;
126 }
127 if (ch->rx_skb) {
128 dev_kfree_skb(ch->rx_skb);
129 ch->rx_skb = NULL;
130 }
131 if (ch->next_skb) {
132 dev_kfree_skb(ch->next_skb);
133 ch->next_skb = NULL;
134 }
135 skb_queue_purge(&ch->rqueue);
136 ch->rcount = 0;
137 flush_scheduled_work();
138 return 0;
139}
140EXPORT_SYMBOL(mISDN_freebchannel);
141
142static inline u_int
143get_sapi_tei(u_char *p)
144{
145 u_int sapi, tei;
146
147 sapi = *p >> 2;
148 tei = p[1] >> 1;
149 return sapi | (tei << 8);
150}
151
152void
153recv_Dchannel(struct dchannel *dch)
154{
155 struct mISDNhead *hh;
156
157 if (dch->rx_skb->len < 2) { /* at least 2 for sapi / tei */
158 dev_kfree_skb(dch->rx_skb);
159 dch->rx_skb = NULL;
160 return;
161 }
162 hh = mISDN_HEAD_P(dch->rx_skb);
163 hh->prim = PH_DATA_IND;
164 hh->id = get_sapi_tei(dch->rx_skb->data);
165 skb_queue_tail(&dch->rqueue, dch->rx_skb);
166 dch->rx_skb = NULL;
167 schedule_event(dch, FLG_RECVQUEUE);
168}
169EXPORT_SYMBOL(recv_Dchannel);
170
171void
172recv_Bchannel(struct bchannel *bch)
173{
174 struct mISDNhead *hh;
175
176 hh = mISDN_HEAD_P(bch->rx_skb);
177 hh->prim = PH_DATA_IND;
178 hh->id = MISDN_ID_ANY;
179 if (bch->rcount >= 64) {
180 dev_kfree_skb(bch->rx_skb);
181 bch->rx_skb = NULL;
182 return;
183 }
184 bch->rcount++;
185 skb_queue_tail(&bch->rqueue, bch->rx_skb);
186 bch->rx_skb = NULL;
187 schedule_event(bch, FLG_RECVQUEUE);
188}
189EXPORT_SYMBOL(recv_Bchannel);
190
191void
192recv_Dchannel_skb(struct dchannel *dch, struct sk_buff *skb)
193{
194 skb_queue_tail(&dch->rqueue, skb);
195 schedule_event(dch, FLG_RECVQUEUE);
196}
197EXPORT_SYMBOL(recv_Dchannel_skb);
198
199void
200recv_Bchannel_skb(struct bchannel *bch, struct sk_buff *skb)
201{
202 if (bch->rcount >= 64) {
203 dev_kfree_skb(skb);
204 return;
205 }
206 bch->rcount++;
207 skb_queue_tail(&bch->rqueue, skb);
208 schedule_event(bch, FLG_RECVQUEUE);
209}
210EXPORT_SYMBOL(recv_Bchannel_skb);
211
212static void
213confirm_Dsend(struct dchannel *dch)
214{
215 struct sk_buff *skb;
216
217 skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(dch->tx_skb),
218 0, NULL, GFP_ATOMIC);
219 if (!skb) {
220 printk(KERN_ERR "%s: no skb id %x\n", __func__,
221 mISDN_HEAD_ID(dch->tx_skb));
222 return;
223 }
224 skb_queue_tail(&dch->rqueue, skb);
225 schedule_event(dch, FLG_RECVQUEUE);
226}
227
228int
229get_next_dframe(struct dchannel *dch)
230{
231 dch->tx_idx = 0;
232 dch->tx_skb = skb_dequeue(&dch->squeue);
233 if (dch->tx_skb) {
234 confirm_Dsend(dch);
235 return 1;
236 }
237 dch->tx_skb = NULL;
238 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
239 return 0;
240}
241EXPORT_SYMBOL(get_next_dframe);
242
243void
244confirm_Bsend(struct bchannel *bch)
245{
246 struct sk_buff *skb;
247
248 if (bch->rcount >= 64)
249 return;
250 skb = _alloc_mISDN_skb(PH_DATA_CNF, mISDN_HEAD_ID(bch->tx_skb),
251 0, NULL, GFP_ATOMIC);
252 if (!skb) {
253 printk(KERN_ERR "%s: no skb id %x\n", __func__,
254 mISDN_HEAD_ID(bch->tx_skb));
255 return;
256 }
257 bch->rcount++;
258 skb_queue_tail(&bch->rqueue, skb);
259 schedule_event(bch, FLG_RECVQUEUE);
260}
261EXPORT_SYMBOL(confirm_Bsend);
262
263int
264get_next_bframe(struct bchannel *bch)
265{
266 bch->tx_idx = 0;
267 if (test_bit(FLG_TX_NEXT, &bch->Flags)) {
268 bch->tx_skb = bch->next_skb;
269 if (bch->tx_skb) {
270 bch->next_skb = NULL;
271 test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
272 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
273 confirm_Bsend(bch); /* not for transparent */
274 return 1;
275 } else {
276 test_and_clear_bit(FLG_TX_NEXT, &bch->Flags);
277 printk(KERN_WARNING "B TX_NEXT without skb\n");
278 }
279 }
280 bch->tx_skb = NULL;
281 test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
282 return 0;
283}
284EXPORT_SYMBOL(get_next_bframe);
285
286void
287queue_ch_frame(struct mISDNchannel *ch, u_int pr, int id, struct sk_buff *skb)
288{
289 struct mISDNhead *hh;
290
291 if (!skb) {
292 _queue_data(ch, pr, id, 0, NULL, GFP_ATOMIC);
293 } else {
294 if (ch->peer) {
295 hh = mISDN_HEAD_P(skb);
296 hh->prim = pr;
297 hh->id = id;
298 if (!ch->recv(ch->peer, skb))
299 return;
300 }
301 dev_kfree_skb(skb);
302 }
303}
304EXPORT_SYMBOL(queue_ch_frame);
305
306int
307dchannel_senddata(struct dchannel *ch, struct sk_buff *skb)
308{
309 /* check oversize */
310 if (skb->len <= 0) {
311 printk(KERN_WARNING "%s: skb too small\n", __func__);
312 return -EINVAL;
313 }
314 if (skb->len > ch->maxlen) {
315 printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
316 __func__, skb->len, ch->maxlen);
317 return -EINVAL;
318 }
319 /* HW lock must be obtained */
320 if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
321 skb_queue_tail(&ch->squeue, skb);
322 return 0;
323 } else {
324 /* write to fifo */
325 ch->tx_skb = skb;
326 ch->tx_idx = 0;
327 return 1;
328 }
329}
330EXPORT_SYMBOL(dchannel_senddata);
331
332int
333bchannel_senddata(struct bchannel *ch, struct sk_buff *skb)
334{
335
336 /* check oversize */
337 if (skb->len <= 0) {
338 printk(KERN_WARNING "%s: skb too small\n", __func__);
339 return -EINVAL;
340 }
341 if (skb->len > ch->maxlen) {
342 printk(KERN_WARNING "%s: skb too large(%d/%d)\n",
343 __func__, skb->len, ch->maxlen);
344 return -EINVAL;
345 }
346 /* HW lock must be obtained */
347 /* check for pending next_skb */
348 if (ch->next_skb) {
349 printk(KERN_WARNING
350 "%s: next_skb exist ERROR (skb->len=%d next_skb->len=%d)\n",
351 __func__, skb->len, ch->next_skb->len);
352 return -EBUSY;
353 }
354 if (test_and_set_bit(FLG_TX_BUSY, &ch->Flags)) {
355 test_and_set_bit(FLG_TX_NEXT, &ch->Flags);
356 ch->next_skb = skb;
357 return 0;
358 } else {
359 /* write to fifo */
360 ch->tx_skb = skb;
361 ch->tx_idx = 0;
362 return 1;
363 }
364}
365EXPORT_SYMBOL(bchannel_senddata);
diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h
new file mode 100644
index 000000000000..a23d575449f6
--- /dev/null
+++ b/drivers/isdn/mISDN/l1oip.h
@@ -0,0 +1,91 @@
1/*
2 * see notice in l1oip.c
3 */
4
5/* debugging */
6#define DEBUG_L1OIP_INIT 0x00010000
7#define DEBUG_L1OIP_SOCKET 0x00020000
8#define DEBUG_L1OIP_MGR 0x00040000
9#define DEBUG_L1OIP_MSG 0x00080000
10
11/* enable to disorder received bchannels by sequence 2143658798... */
12/*
13#define REORDER_DEBUG
14*/
15
16/* frames */
17#define L1OIP_MAX_LEN 2048 /* max packet size form l2 */
18#define L1OIP_MAX_PERFRAME 1400 /* max data size in one frame */
19
20
21/* timers */
22#define L1OIP_KEEPALIVE 15
23#define L1OIP_TIMEOUT 65
24
25
26/* socket */
27#define L1OIP_DEFAULTPORT 931
28
29
30/* channel structure */
31struct l1oip_chan {
32 struct dchannel *dch;
33 struct bchannel *bch;
34 u32 tx_counter; /* counts xmit bytes/packets */
35 u32 rx_counter; /* counts recv bytes/packets */
36 u32 codecstate; /* used by codec to save data */
37#ifdef REORDER_DEBUG
38 int disorder_flag;
39 struct sk_buff *disorder_skb;
40 u32 disorder_cnt;
41#endif
42};
43
44
45/* card structure */
46struct l1oip {
47 struct list_head list;
48
49 /* card */
50 int registered; /* if registered with mISDN */
51 char name[MISDN_MAX_IDLEN];
52 int idx; /* card index */
53 int pri; /* 1=pri, 0=bri */
54 int d_idx; /* current dchannel number */
55 int b_num; /* number of bchannels */
56 u32 id; /* id of connection */
57 int ondemand; /* if transmis. is on demand */
58 int bundle; /* bundle channels in one frm */
59 int codec; /* codec to use for transmis. */
60 int limit; /* limit number of bchannels */
61
62 /* timer */
63 struct timer_list keep_tl;
64 struct timer_list timeout_tl;
65 int timeout_on;
66 struct work_struct workq;
67
68 /* socket */
69 struct socket *socket; /* if set, socket is created */
70 struct completion socket_complete;/* completion of sock thread */
71 struct task_struct *socket_thread;
72 spinlock_t socket_lock; /* access sock outside thread */
73 u32 remoteip; /* if all set, ip is assigned */
74 u16 localport; /* must always be set */
75 u16 remoteport; /* must always be set */
76 struct sockaddr_in sin_local; /* local socket name */
77 struct sockaddr_in sin_remote; /* remote socket name */
78 struct msghdr sendmsg; /* ip message to send */
79 struct iovec sendiov; /* iov for message */
80
81 /* frame */
82 struct l1oip_chan chan[128]; /* channel instances */
83};
84
85extern int l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state);
86extern int l1oip_4bit_to_law(u8 *data, int len, u8 *result);
87extern int l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result);
88extern int l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result);
89extern void l1oip_4bit_free(void);
90extern int l1oip_4bit_alloc(int ulaw);
91
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
new file mode 100644
index 000000000000..a2dc4570ef43
--- /dev/null
+++ b/drivers/isdn/mISDN/l1oip_codec.c
@@ -0,0 +1,374 @@
1/*
2
3 * l1oip_codec.c generic codec using lookup table
4 * -> conversion from a-Law to u-Law
5 * -> conversion from u-Law to a-Law
6 * -> compression by reducing the number of sample resolution to 4
7 *
8 * NOTE: It is not compatible with any standard codec like ADPCM.
9 *
10 * Author Andreas Eversberg (jolly@eversberg.eu)
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 */
27
28/*
29
30How the codec works:
31--------------------
32
33The volume is increased to increase the dynamic range of the audio signal.
34Each sample is converted to a-LAW with only 16 steps of level resolution.
35A pair of two samples are stored in one byte.
36
37The first byte is stored in the upper bits, the second byte is stored in the
38lower bits.
39
40To speed up compression and decompression, two lookup tables are formed:
41
42- 16 bits index for two samples (law encoded) with 8 bit compressed result.
43- 8 bits index for one compressed data with 16 bits decompressed result.
44
45NOTE: The bytes are handled as they are law-encoded.
46
47*/
48
49#include <linux/vmalloc.h>
50#include <linux/mISDNif.h>
51#include "core.h"
52
53/* definitions of codec. don't use calculations, code may run slower. */
54
55static u8 *table_com;
56static u16 *table_dec;
57
58
59/* alaw -> ulaw */
60static u8 alaw_to_ulaw[256] =
61{
62 0xab, 0x2b, 0xe3, 0x63, 0x8b, 0x0b, 0xc9, 0x49,
63 0xba, 0x3a, 0xf6, 0x76, 0x9b, 0x1b, 0xd7, 0x57,
64 0xa3, 0x23, 0xdd, 0x5d, 0x83, 0x03, 0xc1, 0x41,
65 0xb2, 0x32, 0xeb, 0x6b, 0x93, 0x13, 0xcf, 0x4f,
66 0xaf, 0x2f, 0xe7, 0x67, 0x8f, 0x0f, 0xcd, 0x4d,
67 0xbe, 0x3e, 0xfe, 0x7e, 0x9f, 0x1f, 0xdb, 0x5b,
68 0xa7, 0x27, 0xdf, 0x5f, 0x87, 0x07, 0xc5, 0x45,
69 0xb6, 0x36, 0xef, 0x6f, 0x97, 0x17, 0xd3, 0x53,
70 0xa9, 0x29, 0xe1, 0x61, 0x89, 0x09, 0xc7, 0x47,
71 0xb8, 0x38, 0xf2, 0x72, 0x99, 0x19, 0xd5, 0x55,
72 0xa1, 0x21, 0xdc, 0x5c, 0x81, 0x01, 0xbf, 0x3f,
73 0xb0, 0x30, 0xe9, 0x69, 0x91, 0x11, 0xce, 0x4e,
74 0xad, 0x2d, 0xe5, 0x65, 0x8d, 0x0d, 0xcb, 0x4b,
75 0xbc, 0x3c, 0xfa, 0x7a, 0x9d, 0x1d, 0xd9, 0x59,
76 0xa5, 0x25, 0xde, 0x5e, 0x85, 0x05, 0xc3, 0x43,
77 0xb4, 0x34, 0xed, 0x6d, 0x95, 0x15, 0xd1, 0x51,
78 0xac, 0x2c, 0xe4, 0x64, 0x8c, 0x0c, 0xca, 0x4a,
79 0xbb, 0x3b, 0xf8, 0x78, 0x9c, 0x1c, 0xd8, 0x58,
80 0xa4, 0x24, 0xde, 0x5e, 0x84, 0x04, 0xc2, 0x42,
81 0xb3, 0x33, 0xec, 0x6c, 0x94, 0x14, 0xd0, 0x50,
82 0xb0, 0x30, 0xe8, 0x68, 0x90, 0x10, 0xce, 0x4e,
83 0xbf, 0x3f, 0xfe, 0x7e, 0xa0, 0x20, 0xdc, 0x5c,
84 0xa8, 0x28, 0xe0, 0x60, 0x88, 0x08, 0xc6, 0x46,
85 0xb7, 0x37, 0xf0, 0x70, 0x98, 0x18, 0xd4, 0x54,
86 0xaa, 0x2a, 0xe2, 0x62, 0x8a, 0x0a, 0xc8, 0x48,
87 0xb9, 0x39, 0xf4, 0x74, 0x9a, 0x1a, 0xd6, 0x56,
88 0xa2, 0x22, 0xdd, 0x5d, 0x82, 0x02, 0xc0, 0x40,
89 0xb1, 0x31, 0xea, 0x6a, 0x92, 0x12, 0xcf, 0x4f,
90 0xae, 0x2e, 0xe6, 0x66, 0x8e, 0x0e, 0xcc, 0x4c,
91 0xbd, 0x3d, 0xfc, 0x7c, 0x9e, 0x1e, 0xda, 0x5a,
92 0xa6, 0x26, 0xdf, 0x5f, 0x86, 0x06, 0xc4, 0x44,
93 0xb5, 0x35, 0xee, 0x6e, 0x96, 0x16, 0xd2, 0x52
94};
95
96/* ulaw -> alaw */
97static u8 ulaw_to_alaw[256] =
98{
99 0xab, 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35,
100 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25,
101 0xa5, 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d,
102 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d,
103 0xad, 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31,
104 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21,
105 0x59, 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9,
106 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9,
107 0xd7, 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47,
108 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0xdf,
109 0x9f, 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f,
110 0x8f, 0x6f, 0xef, 0x2f, 0x53, 0x13, 0x73, 0x33,
111 0xb3, 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23,
112 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b,
113 0xbb, 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b,
114 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b,
115 0xab, 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34,
116 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24,
117 0xa4, 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c,
118 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c,
119 0xac, 0x50, 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30,
120 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20,
121 0x58, 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8,
122 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8,
123 0xd6, 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46,
124 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde,
125 0x9e, 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e,
126 0x8e, 0x6e, 0xee, 0x2e, 0x52, 0x12, 0x72, 0x32,
127 0xb2, 0x42, 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22,
128 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a,
129 0xba, 0xba, 0x4a, 0x4a, 0xca, 0xca, 0x0a, 0x0a,
130 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
131};
132
133/* alaw -> 4bit compression */
134static u8 alaw_to_4bit[256] = {
135 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
136 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
137 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
138 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
139 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
140 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
141 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
142 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
143 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
144 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
145 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0d, 0x02,
146 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
147 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
148 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
149 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
150 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
151 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
152 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
153 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
154 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
155 0x0e, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
156 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x01, 0x0a, 0x05,
157 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
158 0x0d, 0x02, 0x09, 0x07, 0x0f, 0x00, 0x0b, 0x04,
159 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
160 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
161 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
162 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
163 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
164 0x0d, 0x02, 0x08, 0x07, 0x0f, 0x00, 0x0b, 0x04,
165 0x0e, 0x01, 0x0a, 0x05, 0x0f, 0x00, 0x0c, 0x03,
166 0x0d, 0x02, 0x09, 0x06, 0x0f, 0x00, 0x0b, 0x04,
167};
168
169/* 4bit -> alaw decompression */
170static u8 _4bit_to_alaw[16] = {
171 0x5d, 0x51, 0xd9, 0xd7, 0x5f, 0x53, 0xa3, 0x4b,
172 0x2a, 0x3a, 0x22, 0x2e, 0x26, 0x56, 0x20, 0x2c,
173};
174
175/* ulaw -> 4bit compression */
176static u8 ulaw_to_4bit[256] = {
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
182 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
183 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
184 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
185 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
186 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
187 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
188 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
189 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
190 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
191 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
192 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
193 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
194 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
195 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
196 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
197 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
198 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
199 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
200 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
201 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
202 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
203 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
204 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a,
205 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
206 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
207 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
208 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
209};
210
211/* 4bit -> ulaw decompression */
212static u8 _4bit_to_ulaw[16] = {
213 0x11, 0x21, 0x31, 0x40, 0x4e, 0x5c, 0x68, 0x71,
214 0xfe, 0xef, 0xe7, 0xdb, 0xcd, 0xbf, 0xaf, 0x9f,
215};
216
217
218/*
219 * Compresses data to the result buffer
220 * The result size must be at least half of the input buffer.
221 * The number of samples also must be even!
222 */
223int
224l1oip_law_to_4bit(u8 *data, int len, u8 *result, u32 *state)
225{
226 int ii, i = 0, o = 0;
227
228 if (!len)
229 return 0;
230
231 /* send saved byte and first input byte */
232 if (*state) {
233 *result++ = table_com[(((*state)<<8)&0xff00) | (*data++)];
234 len--;
235 o++;
236 }
237
238 ii = len >> 1;
239
240 while (i < ii) {
241 *result++ = table_com[(data[0]<<8) | (data[1])];
242 data += 2;
243 i++;
244 o++;
245 }
246
247 /* if len has an odd number, we save byte for next call */
248 if (len & 1)
249 *state = 0x100 + *data;
250 else
251 *state = 0;
252
253 return o;
254}
255
256/* Decompress data to the result buffer
257 * The result size must be the number of sample in packet. (2 * input data)
258 * The number of samples in the result are even!
259 */
260int
261l1oip_4bit_to_law(u8 *data, int len, u8 *result)
262{
263 int i = 0;
264 u16 r;
265
266 while (i < len) {
267 r = table_dec[*data++];
268 *result++ = r>>8;
269 *result++ = r;
270 i++;
271 }
272
273 return len << 1;
274}
275
276
277/*
278 * law conversion
279 */
280int
281l1oip_alaw_to_ulaw(u8 *data, int len, u8 *result)
282{
283 int i = 0;
284
285 while (i < len) {
286 *result++ = alaw_to_ulaw[*data++];
287 i++;
288 }
289
290 return len;
291}
292
293int
294l1oip_ulaw_to_alaw(u8 *data, int len, u8 *result)
295{
296 int i = 0;
297
298 while (i < len) {
299 *result++ = ulaw_to_alaw[*data++];
300 i++;
301 }
302
303 return len;
304}
305
306
307/*
308 * generate/free compression and decompression table
309 */
310void
311l1oip_4bit_free(void)
312{
313 if (table_dec)
314 vfree(table_dec);
315 if (table_com)
316 vfree(table_com);
317 table_com = NULL;
318 table_dec = NULL;
319}
320
321int
322l1oip_4bit_alloc(int ulaw)
323{
324 int i1, i2, c, sample;
325
326 /* in case, it is called again */
327 if (table_dec)
328 return 0;
329
330 /* alloc conversion tables */
331 table_com = vmalloc(65536);
332 table_dec = vmalloc(512);
333 if (!table_com | !table_dec) {
334 l1oip_4bit_free();
335 return -ENOMEM;
336 }
337 memset(table_com, 0, 65536);
338 memset(table_dec, 0, 512);
339 /* generate compression table */
340 i1 = 0;
341 while (i1 < 256) {
342 if (ulaw)
343 c = ulaw_to_4bit[i1];
344 else
345 c = alaw_to_4bit[i1];
346 i2 = 0;
347 while (i2 < 256) {
348 table_com[(i1<<8) | i2] |= (c<<4);
349 table_com[(i2<<8) | i1] |= c;
350 i2++;
351 }
352 i1++;
353 }
354
355 /* generate decompression table */
356 i1 = 0;
357 while (i1 < 16) {
358 if (ulaw)
359 sample = _4bit_to_ulaw[i1];
360 else
361 sample = _4bit_to_alaw[i1];
362 i2 = 0;
363 while (i2 < 16) {
364 table_dec[(i1<<4) | i2] |= (sample<<8);
365 table_dec[(i2<<4) | i1] |= sample;
366 i2++;
367 }
368 i1++;
369 }
370
371 return 0;
372}
373
374
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
new file mode 100644
index 000000000000..155b99780c4f
--- /dev/null
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -0,0 +1,1518 @@
1/*
2
3 * l1oip.c low level driver for tunneling layer 1 over IP
4 *
5 * NOTE: It is not compatible with TDMoIP nor "ISDN over IP".
6 *
7 * Author Andreas Eversberg (jolly@eversberg.eu)
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25/* module parameters:
26 * type:
27 Value 1 = BRI
28 Value 2 = PRI
29 Value 3 = BRI (multi channel frame, not supported yet)
30 Value 4 = PRI (multi channel frame, not supported yet)
31 A multi channel frame reduces overhead to a single frame for all
32 b-channels, but increases delay.
33 (NOTE: Multi channel frames are not implemented yet.)
34
35 * codec:
36 Value 0 = transparent (default)
37 Value 1 = transfer ALAW
38 Value 2 = transfer ULAW
39 Value 3 = transfer generic 4 bit compression.
40
41 * ulaw:
42 0 = we use a-Law (default)
43 1 = we use u-Law
44
45 * limit:
46 limitation of B-channels to control bandwidth (1...126)
47 BRI: 1 or 2
48 PRI: 1-30, 31-126 (126, because dchannel ist not counted here)
49 Also limited ressources are used for stack, resulting in less channels.
50 It is possible to have more channels than 30 in PRI mode, this must
51 be supported by the application.
52
53 * ip:
54 byte representation of remote ip address (127.0.0.1 -> 127,0,0,1)
55 If not given or four 0, no remote address is set.
56 For multiple interfaces, concat ip addresses. (127,0,0,1,127,0,0,1)
57
58 * port:
59 port number (local interface)
60 If not given or 0, port 931 is used for fist instance, 932 for next...
61 For multiple interfaces, different ports must be given.
62
63 * remoteport:
64 port number (remote interface)
65 If not given or 0, remote port equals local port
66 For multiple interfaces on equal sites, different ports must be given.
67
68 * ondemand:
69 0 = fixed (always transmit packets, even when remote side timed out)
70 1 = on demand (only transmit packets, when remote side is detected)
71 the default is 0
72 NOTE: ID must also be set for on demand.
73
74 * id:
75 optional value to identify frames. This value must be equal on both
76 peers and should be random. If omitted or 0, no ID is transmitted.
77
78 * debug:
79 NOTE: only one debug value must be given for all cards
80 enable debugging (see l1oip.h for debug options)
81
82
83Special mISDN controls:
84
85 op = MISDN_CTRL_SETPEER*
86 p1 = bytes 0-3 : remote IP address in network order (left element first)
87 p2 = bytes 1-2 : remote port in network order (high byte first)
88 optional:
89 p2 = bytes 3-4 : local port in network order (high byte first)
90
91 op = MISDN_CTRL_UNSETPEER*
92
93 * Use l1oipctrl for comfortable setting or removing ip address.
94 (Layer 1 Over IP CTRL)
95
96
97L1oIP-Protocol
98--------------
99
100Frame Header:
101
102 7 6 5 4 3 2 1 0
103+---------------+
104|Ver|T|I|Coding |
105+---------------+
106| ID byte 3 * |
107+---------------+
108| ID byte 2 * |
109+---------------+
110| ID byte 1 * |
111+---------------+
112| ID byte 0 * |
113+---------------+
114|M| Channel |
115+---------------+
116| Length * |
117+---------------+
118| Time Base MSB |
119+---------------+
120| Time Base LSB |
121+---------------+
122| Data.... |
123
124...
125
126| |
127+---------------+
128|M| Channel |
129+---------------+
130| Length * |
131+---------------+
132| Time Base MSB |
133+---------------+
134| Time Base LSB |
135+---------------+
136| Data.... |
137
138...
139
140
141* Only included in some cases.
142
143- Ver = Version
144If version is missmatch, the frame must be ignored.
145
146- T = Type of interface
147Must be 0 for S0 or 1 for E1.
148
149- I = Id present
150If bit is set, four ID bytes are included in frame.
151
152- ID = Connection ID
153Additional ID to prevent Denial of Service attacs. Also it prevents hijacking
154connections with dynamic IP. The ID should be random and must not be 0.
155
156- Coding = Type of codec
157Must be 0 for no transcoding. Also for D-channel and other HDLC frames.
158 1 and 2 are reserved for explicitly use of a-LAW or u-LAW codec.
159 3 is used for generic table compressor.
160
161- M = More channels to come. If this flag is 1, the following byte contains
162the length of the channel data. After the data block, the next channel will
163be defined. The flag for the last channel block (or if only one channel is
164transmitted), must be 0 and no length is given.
165
166- Channel = Channel number
1670 reserved
1681-3 channel data for S0 (3 is D-channel)
1691-31 channel data for E1 (16 is D-channel)
17032-127 channel data for extended E1 (16 is D-channel)
171
172- The length is used if the M-flag is 1. It is used to find the next channel
173inside frame.
174NOTE: A value of 0 equals 256 bytes of data.
175 -> For larger data blocks, a single frame must be used.
176 -> For larger streams, a single frame or multiple blocks with same channel ID
177 must be used.
178
179- Time Base = Timestamp of first sample in frame
180The "Time Base" is used to rearange packets and to detect packet loss.
181The 16 bits are sent in network order (MSB first) and count 1/8000 th of a
182second. This causes a wrap arround each 8,192 seconds. There is no requirement
183for the initial "Time Base", but 0 should be used for the first packet.
184In case of HDLC data, this timestamp counts the packet or byte number.
185
186
187Two Timers:
188
189After initialisation, a timer of 15 seconds is started. Whenever a packet is
190transmitted, the timer is reset to 15 seconds again. If the timer expires, an
191empty packet is transmitted. This keep the connection alive.
192
193When a valid packet is received, a timer 65 seconds is started. The interface
194become ACTIVE. If the timer expires, the interface becomes INACTIVE.
195
196
197Dynamic IP handling:
198
199To allow dynamic IP, the ID must be non 0. In this case, any packet with the
200correct port number and ID will be accepted. If the remote side changes its IP
201the new IP is used for all transmitted packets until it changes again.
202
203
204On Demand:
205
206If the ondemand parameter is given, the remote IP is set to 0 on timeout.
207This will stop keepalive traffic to remote. If the remote is online again,
208traffic will continue to the remote address. This is usefull for road warriors.
209This feature only works with ID set, otherwhise it is highly unsecure.
210
211
212Socket and Thread
213-----------------
214
215The complete socket opening and closing is done by a thread.
216When the thread opened a socket, the hc->socket descriptor is set. Whenever a
217packet shall be sent to the socket, the hc->socket must be checked wheter not
218NULL. To prevent change in socket descriptor, the hc->socket_lock must be used.
219To change the socket, a recall of l1oip_socket_open() will safely kill the
220socket process and create a new one.
221
222*/
223
224#define L1OIP_VERSION 0 /* 0...3 */
225
226#include <linux/module.h>
227#include <linux/delay.h>
228#include <linux/mISDNif.h>
229#include <linux/mISDNhw.h>
230#include <linux/mISDNdsp.h>
231#include <linux/init.h>
232#include <linux/in.h>
233#include <linux/inet.h>
234#include <linux/workqueue.h>
235#include <linux/kthread.h>
236#include <net/sock.h>
237#include "core.h"
238#include "l1oip.h"
239
240static const char *l1oip_revision = "2.00";
241
242static int l1oip_cnt;
243static spinlock_t l1oip_lock;
244static struct list_head l1oip_ilist;
245
246#define MAX_CARDS 16
247static u_int type[MAX_CARDS];
248static u_int codec[MAX_CARDS];
249static u_int ip[MAX_CARDS*4];
250static u_int port[MAX_CARDS];
251static u_int remoteport[MAX_CARDS];
252static u_int ondemand[MAX_CARDS];
253static u_int limit[MAX_CARDS];
254static u_int id[MAX_CARDS];
255static int debug;
256static int ulaw;
257
258MODULE_AUTHOR("Andreas Eversberg");
259MODULE_LICENSE("GPL");
260module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
261module_param_array(codec, uint, NULL, S_IRUGO | S_IWUSR);
262module_param_array(ip, uint, NULL, S_IRUGO | S_IWUSR);
263module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
264module_param_array(remoteport, uint, NULL, S_IRUGO | S_IWUSR);
265module_param_array(ondemand, uint, NULL, S_IRUGO | S_IWUSR);
266module_param_array(limit, uint, NULL, S_IRUGO | S_IWUSR);
267module_param_array(id, uint, NULL, S_IRUGO | S_IWUSR);
268module_param(ulaw, uint, S_IRUGO | S_IWUSR);
269module_param(debug, uint, S_IRUGO | S_IWUSR);
270
271/*
272 * send a frame via socket, if open and restart timer
273 */
274static int
275l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
276 u16 timebase, u8 *buf, int len)
277{
278 u8 *p;
279 int multi = 0;
280 u8 frame[len+32];
281 struct socket *socket = NULL;
282 mm_segment_t oldfs;
283
284 if (debug & DEBUG_L1OIP_MSG)
285 printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
286 __func__, len);
287
288 p = frame;
289
290 /* restart timer */
291 if ((int)(hc->keep_tl.expires-jiffies) < 5*HZ) {
292 del_timer(&hc->keep_tl);
293 hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ;
294 add_timer(&hc->keep_tl);
295 } else
296 hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE*HZ;
297
298 if (debug & DEBUG_L1OIP_MSG)
299 printk(KERN_DEBUG "%s: resetting timer\n", __func__);
300
301 /* drop if we have no remote ip or port */
302 if (!hc->sin_remote.sin_addr.s_addr || !hc->sin_remote.sin_port) {
303 if (debug & DEBUG_L1OIP_MSG)
304 printk(KERN_DEBUG "%s: dropping frame, because remote "
305 "IP is not set.\n", __func__);
306 return len;
307 }
308
309 /* assemble frame */
310 *p++ = (L1OIP_VERSION<<6) /* version and coding */
311 | (hc->pri?0x20:0x00) /* type */
312 | (hc->id?0x10:0x00) /* id */
313 | localcodec;
314 if (hc->id) {
315 *p++ = hc->id>>24; /* id */
316 *p++ = hc->id>>16;
317 *p++ = hc->id>>8;
318 *p++ = hc->id;
319 }
320 *p++ = (multi == 1)?0x80:0x00 + channel; /* m-flag, channel */
321 if (multi == 1)
322 *p++ = len; /* length */
323 *p++ = timebase>>8; /* time base */
324 *p++ = timebase;
325
326 if (buf && len) { /* add data to frame */
327 if (localcodec == 1 && ulaw)
328 l1oip_ulaw_to_alaw(buf, len, p);
329 else if (localcodec == 2 && !ulaw)
330 l1oip_alaw_to_ulaw(buf, len, p);
331 else if (localcodec == 3)
332 len = l1oip_law_to_4bit(buf, len, p,
333 &hc->chan[channel].codecstate);
334 else
335 memcpy(p, buf, len);
336 }
337 len += p - frame;
338
339 /* check for socket in safe condition */
340 spin_lock(&hc->socket_lock);
341 if (!hc->socket) {
342 spin_unlock(&hc->socket_lock);
343 return 0;
344 }
345 /* seize socket */
346 socket = hc->socket;
347 hc->socket = NULL;
348 spin_unlock(&hc->socket_lock);
349 /* send packet */
350 if (debug & DEBUG_L1OIP_MSG)
351 printk(KERN_DEBUG "%s: sending packet to socket (len "
352 "= %d)\n", __func__, len);
353 hc->sendiov.iov_base = frame;
354 hc->sendiov.iov_len = len;
355 oldfs = get_fs();
356 set_fs(KERNEL_DS);
357 len = sock_sendmsg(socket, &hc->sendmsg, len);
358 set_fs(oldfs);
359 /* give socket back */
360 hc->socket = socket; /* no locking required */
361
362 return len;
363}
364
365
366/*
367 * receive channel data from socket
368 */
369static void
370l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
371 u8 *buf, int len)
372{
373 struct sk_buff *nskb;
374 struct bchannel *bch;
375 struct dchannel *dch;
376 u8 *p;
377 u32 rx_counter;
378
379 if (len == 0) {
380 if (debug & DEBUG_L1OIP_MSG)
381 printk(KERN_DEBUG "%s: received empty keepalive data, "
382 "ignoring\n", __func__);
383 return;
384 }
385
386 if (debug & DEBUG_L1OIP_MSG)
387 printk(KERN_DEBUG "%s: received data, sending to mISDN (%d)\n",
388 __func__, len);
389
390 if (channel < 1 || channel > 127) {
391 printk(KERN_WARNING "%s: packet error - channel %d out of "
392 "range\n", __func__, channel);
393 return;
394 }
395 dch = hc->chan[channel].dch;
396 bch = hc->chan[channel].bch;
397 if (!dch && !bch) {
398 printk(KERN_WARNING "%s: packet error - channel %d not in "
399 "stack\n", __func__, channel);
400 return;
401 }
402
403 /* prepare message */
404 nskb = mI_alloc_skb((remotecodec == 3)?(len<<1):len, GFP_ATOMIC);
405 if (!nskb) {
406 printk(KERN_ERR "%s: No mem for skb.\n", __func__);
407 return;
408 }
409 p = skb_put(nskb, (remotecodec == 3)?(len<<1):len);
410
411 if (remotecodec == 1 && ulaw)
412 l1oip_alaw_to_ulaw(buf, len, p);
413 else if (remotecodec == 2 && !ulaw)
414 l1oip_ulaw_to_alaw(buf, len, p);
415 else if (remotecodec == 3)
416 len = l1oip_4bit_to_law(buf, len, p);
417 else
418 memcpy(p, buf, len);
419
420 /* send message up */
421 if (dch && len >= 2) {
422 dch->rx_skb = nskb;
423 recv_Dchannel(dch);
424 }
425 if (bch) {
426 /* expand 16 bit sequence number to 32 bit sequence number */
427 rx_counter = hc->chan[channel].rx_counter;
428 if (((s16)(timebase - rx_counter)) >= 0) {
429 /* time has changed forward */
430 if (timebase >= (rx_counter & 0xffff))
431 rx_counter =
432 (rx_counter & 0xffff0000) | timebase;
433 else
434 rx_counter = ((rx_counter & 0xffff0000)+0x10000)
435 | timebase;
436 } else {
437 /* time has changed backwards */
438 if (timebase < (rx_counter & 0xffff))
439 rx_counter =
440 (rx_counter & 0xffff0000) | timebase;
441 else
442 rx_counter = ((rx_counter & 0xffff0000)-0x10000)
443 | timebase;
444 }
445 hc->chan[channel].rx_counter = rx_counter;
446
447#ifdef REORDER_DEBUG
448 if (hc->chan[channel].disorder_flag) {
449 struct sk_buff *skb;
450 int cnt;
451 skb = hc->chan[channel].disorder_skb;
452 hc->chan[channel].disorder_skb = nskb;
453 nskb = skb;
454 cnt = hc->chan[channel].disorder_cnt;
455 hc->chan[channel].disorder_cnt = rx_counter;
456 rx_counter = cnt;
457 }
458 hc->chan[channel].disorder_flag ^= 1;
459 if (nskb)
460#endif
461 queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
462 }
463}
464
465
466/*
467 * parse frame and extract channel data
468 */
469static void
470l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
471{
472 u32 id;
473 u8 channel;
474 u8 remotecodec;
475 u16 timebase;
476 int m, mlen;
477 int len_start = len; /* initial frame length */
478 struct dchannel *dch = hc->chan[hc->d_idx].dch;
479
480 if (debug & DEBUG_L1OIP_MSG)
481 printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
482 __func__, len);
483
484 /* check lenght */
485 if (len < 1+1+2) {
486 printk(KERN_WARNING "%s: packet error - length %d below "
487 "4 bytes\n", __func__, len);
488 return;
489 }
490
491 /* check version */
492 if (((*buf)>>6) != L1OIP_VERSION) {
493 printk(KERN_WARNING "%s: packet error - unknown version %d\n",
494 __func__, buf[0]>>6);
495 return;
496 }
497
498 /* check type */
499 if (((*buf)&0x20) && !hc->pri) {
500 printk(KERN_WARNING "%s: packet error - received E1 packet "
501 "on S0 interface\n", __func__);
502 return;
503 }
504 if (!((*buf)&0x20) && hc->pri) {
505 printk(KERN_WARNING "%s: packet error - received S0 packet "
506 "on E1 interface\n", __func__);
507 return;
508 }
509
510 /* get id flag */
511 id = (*buf>>4)&1;
512
513 /* check coding */
514 remotecodec = (*buf) & 0x0f;
515 if (remotecodec > 3) {
516 printk(KERN_WARNING "%s: packet error - remotecodec %d "
517 "unsupported\n", __func__, remotecodec);
518 return;
519 }
520 buf++;
521 len--;
522
523 /* check id */
524 if (id) {
525 if (!hc->id) {
526 printk(KERN_WARNING "%s: packet error - packet has id "
527 "0x%x, but we have not\n", __func__, id);
528 return;
529 }
530 if (len < 4) {
531 printk(KERN_WARNING "%s: packet error - packet too "
532 "short for ID value\n", __func__);
533 return;
534 }
535 id = (*buf++) << 24;
536 id += (*buf++) << 16;
537 id += (*buf++) << 8;
538 id += (*buf++);
539 len -= 4;
540
541 if (id != hc->id) {
542 printk(KERN_WARNING "%s: packet error - ID mismatch, "
543 "got 0x%x, we 0x%x\n",
544 __func__, id, hc->id);
545 return;
546 }
547 } else {
548 if (hc->id) {
549 printk(KERN_WARNING "%s: packet error - packet has no "
550 "ID, but we have\n", __func__);
551 return;
552 }
553 }
554
555multiframe:
556 if (len < 1) {
557 printk(KERN_WARNING "%s: packet error - packet too short, "
558 "channel expected at position %d.\n",
559 __func__, len-len_start+1);
560 return;
561 }
562
563 /* get channel and multiframe flag */
564 channel = *buf&0x7f;
565 m = *buf >> 7;
566 buf++;
567 len--;
568
569 /* check length on multiframe */
570 if (m) {
571 if (len < 1) {
572 printk(KERN_WARNING "%s: packet error - packet too "
573 "short, length expected at position %d.\n",
574 __func__, len_start-len-1);
575 return;
576 }
577
578 mlen = *buf++;
579 len--;
580 if (mlen == 0)
581 mlen = 256;
582 if (len < mlen+3) {
583 printk(KERN_WARNING "%s: packet error - length %d at "
584 "position %d exceeds total length %d.\n",
585 __func__, mlen, len_start-len-1, len_start);
586 return;
587 }
588 if (len == mlen+3) {
589 printk(KERN_WARNING "%s: packet error - length %d at "
590 "position %d will not allow additional "
591 "packet.\n",
592 __func__, mlen, len_start-len+1);
593 return;
594 }
595 } else
596 mlen = len-2; /* single frame, substract timebase */
597
598 if (len < 2) {
599 printk(KERN_WARNING "%s: packet error - packet too short, time "
600 "base expected at position %d.\n",
601 __func__, len-len_start+1);
602 return;
603 }
604
605 /* get time base */
606 timebase = (*buf++) << 8;
607 timebase |= (*buf++);
608 len -= 2;
609
610 /* if inactive, we send up a PH_ACTIVATE and activate */
611 if (!test_bit(FLG_ACTIVE, &dch->Flags)) {
612 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
613 printk(KERN_DEBUG "%s: interface become active due to "
614 "received packet\n", __func__);
615 test_and_set_bit(FLG_ACTIVE, &dch->Flags);
616 _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
617 NULL, GFP_ATOMIC);
618 }
619
620 /* distribute packet */
621 l1oip_socket_recv(hc, remotecodec, channel, timebase, buf, mlen);
622 buf += mlen;
623 len -= mlen;
624
625 /* multiframe */
626 if (m)
627 goto multiframe;
628
629 /* restart timer */
630 if ((int)(hc->timeout_tl.expires-jiffies) < 5*HZ || !hc->timeout_on) {
631 hc->timeout_on = 1;
632 del_timer(&hc->timeout_tl);
633 hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ;
634 add_timer(&hc->timeout_tl);
635 } else /* only adjust timer */
636 hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT*HZ;
637
638 /* if ip or source port changes */
639 if ((hc->sin_remote.sin_addr.s_addr != sin->sin_addr.s_addr)
640 || (hc->sin_remote.sin_port != sin->sin_port)) {
641 if (debug & DEBUG_L1OIP_SOCKET)
642 printk(KERN_DEBUG "%s: remote address changes from "
643 "0x%08x to 0x%08x (port %d to %d)\n", __func__,
644 ntohl(hc->sin_remote.sin_addr.s_addr),
645 ntohl(sin->sin_addr.s_addr),
646 ntohs(hc->sin_remote.sin_port),
647 ntohs(sin->sin_port));
648 hc->sin_remote.sin_addr.s_addr = sin->sin_addr.s_addr;
649 hc->sin_remote.sin_port = sin->sin_port;
650 }
651}
652
653
654/*
655 * socket stuff
656 */
657static int
658l1oip_socket_thread(void *data)
659{
660 struct l1oip *hc = (struct l1oip *)data;
661 int ret = 0;
662 struct msghdr msg;
663 struct iovec iov;
664 mm_segment_t oldfs;
665 struct sockaddr_in sin_rx;
666 unsigned char recvbuf[1500];
667 int recvlen;
668 struct socket *socket = NULL;
669 DECLARE_COMPLETION(wait);
670
671 /* make daemon */
672 allow_signal(SIGTERM);
673
674 /* create socket */
675 if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
676 printk(KERN_ERR "%s: Failed to create socket.\n", __func__);
677 return -EIO;
678 }
679
680 /* set incoming address */
681 hc->sin_local.sin_family = AF_INET;
682 hc->sin_local.sin_addr.s_addr = INADDR_ANY;
683 hc->sin_local.sin_port = htons((unsigned short)hc->localport);
684
685 /* set outgoing address */
686 hc->sin_remote.sin_family = AF_INET;
687 hc->sin_remote.sin_addr.s_addr = htonl(hc->remoteip);
688 hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport);
689
690 /* bind to incomming port */
691 if (socket->ops->bind(socket, (struct sockaddr *)&hc->sin_local,
692 sizeof(hc->sin_local))) {
693 printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",
694 __func__, hc->localport);
695 ret = -EINVAL;
696 goto fail;
697 }
698
699 /* check sk */
700 if (socket->sk == NULL) {
701 printk(KERN_ERR "%s: socket->sk == NULL\n", __func__);
702 ret = -EIO;
703 goto fail;
704 }
705
706 /* build receive message */
707 msg.msg_name = &sin_rx;
708 msg.msg_namelen = sizeof(sin_rx);
709 msg.msg_control = NULL;
710 msg.msg_controllen = 0;
711 msg.msg_iov = &iov;
712 msg.msg_iovlen = 1;
713
714 /* build send message */
715 hc->sendmsg.msg_name = &hc->sin_remote;
716 hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);
717 hc->sendmsg.msg_control = NULL;
718 hc->sendmsg.msg_controllen = 0;
719 hc->sendmsg.msg_iov = &hc->sendiov;
720 hc->sendmsg.msg_iovlen = 1;
721
722 /* give away socket */
723 spin_lock(&hc->socket_lock);
724 hc->socket = socket;
725 spin_unlock(&hc->socket_lock);
726
727 /* read loop */
728 if (debug & DEBUG_L1OIP_SOCKET)
729 printk(KERN_DEBUG "%s: socket created and open\n",
730 __func__);
731 while (!signal_pending(current)) {
732 iov.iov_base = recvbuf;
733 iov.iov_len = sizeof(recvbuf);
734 oldfs = get_fs();
735 set_fs(KERNEL_DS);
736 recvlen = sock_recvmsg(socket, &msg, sizeof(recvbuf), 0);
737 set_fs(oldfs);
738 if (recvlen > 0) {
739 l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
740 } else {
741 if (debug & DEBUG_L1OIP_SOCKET)
742 printk(KERN_WARNING "%s: broken pipe on socket\n",
743 __func__);
744 }
745 }
746
747 /* get socket back, check first if in use, maybe by send function */
748 spin_lock(&hc->socket_lock);
749 /* if hc->socket is NULL, it is in use until it is given back */
750 while (!hc->socket) {
751 spin_unlock(&hc->socket_lock);
752 schedule_timeout(HZ/10);
753 spin_lock(&hc->socket_lock);
754 }
755 hc->socket = NULL;
756 spin_unlock(&hc->socket_lock);
757
758 if (debug & DEBUG_L1OIP_SOCKET)
759 printk(KERN_DEBUG "%s: socket thread terminating\n",
760 __func__);
761
762fail:
763 /* close socket */
764 if (socket)
765 sock_release(socket);
766
767 /* if we got killed, signal completion */
768 complete(&hc->socket_complete);
769 hc->socket_thread = NULL; /* show termination of thread */
770
771 if (debug & DEBUG_L1OIP_SOCKET)
772 printk(KERN_DEBUG "%s: socket thread terminated\n",
773 __func__);
774 return ret;
775}
776
777static void
778l1oip_socket_close(struct l1oip *hc)
779{
780 /* kill thread */
781 if (hc->socket_thread) {
782 if (debug & DEBUG_L1OIP_SOCKET)
783 printk(KERN_DEBUG "%s: socket thread exists, "
784 "killing...\n", __func__);
785 send_sig(SIGTERM, hc->socket_thread, 0);
786 wait_for_completion(&hc->socket_complete);
787 }
788}
789
790static int
791l1oip_socket_open(struct l1oip *hc)
792{
793 /* in case of reopen, we need to close first */
794 l1oip_socket_close(hc);
795
796 init_completion(&hc->socket_complete);
797
798 /* create receive process */
799 hc->socket_thread = kthread_run(l1oip_socket_thread, hc, "l1oip_%s",
800 hc->name);
801 if (IS_ERR(hc->socket_thread)) {
802 int err = PTR_ERR(hc->socket_thread);
803 printk(KERN_ERR "%s: Failed (%d) to create socket process.\n",
804 __func__, err);
805 hc->socket_thread = NULL;
806 sock_release(hc->socket);
807 return err;
808 }
809 if (debug & DEBUG_L1OIP_SOCKET)
810 printk(KERN_DEBUG "%s: socket thread created\n", __func__);
811
812 return 0;
813}
814
815
816static void
817l1oip_send_bh(struct work_struct *work)
818{
819 struct l1oip *hc = container_of(work, struct l1oip, workq);
820
821 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
822 printk(KERN_DEBUG "%s: keepalive timer expired, sending empty "
823 "frame on dchannel\n", __func__);
824
825 /* send an empty l1oip frame at D-channel */
826 l1oip_socket_send(hc, 0, hc->d_idx, 0, 0, NULL, 0);
827}
828
829
830/*
831 * timer stuff
832 */
833static void
834l1oip_keepalive(void *data)
835{
836 struct l1oip *hc = (struct l1oip *)data;
837
838 schedule_work(&hc->workq);
839}
840
841static void
842l1oip_timeout(void *data)
843{
844 struct l1oip *hc = (struct l1oip *)data;
845 struct dchannel *dch = hc->chan[hc->d_idx].dch;
846
847 if (debug & DEBUG_L1OIP_MSG)
848 printk(KERN_DEBUG "%s: timeout timer expired, turn layer one "
849 "down.\n", __func__);
850
851 hc->timeout_on = 0; /* state that timer must be initialized next time */
852
853 /* if timeout, we send up a PH_DEACTIVATE and deactivate */
854 if (test_bit(FLG_ACTIVE, &dch->Flags)) {
855 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
856 printk(KERN_DEBUG "%s: interface become deactivated "
857 "due to timeout\n", __func__);
858 test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
859 _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
860 NULL, GFP_ATOMIC);
861 }
862
863 /* if we have ondemand set, we remove ip address */
864 if (hc->ondemand) {
865 if (debug & DEBUG_L1OIP_MSG)
866 printk(KERN_DEBUG "%s: on demand causes ip address to "
867 "be removed\n", __func__);
868 hc->sin_remote.sin_addr.s_addr = 0;
869 }
870}
871
872
873/*
874 * message handling
875 */
876static int
877handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
878{
879 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
880 struct dchannel *dch = container_of(dev, struct dchannel, dev);
881 struct l1oip *hc = dch->hw;
882 struct mISDNhead *hh = mISDN_HEAD_P(skb);
883 int ret = -EINVAL;
884 int l, ll;
885 unsigned char *p;
886
887 switch (hh->prim) {
888 case PH_DATA_REQ:
889 if (skb->len < 1) {
890 printk(KERN_WARNING "%s: skb too small\n",
891 __func__);
892 break;
893 }
894 if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
895 printk(KERN_WARNING "%s: skb too large\n",
896 __func__);
897 break;
898 }
899 /* send frame */
900 p = skb->data;
901 l = skb->len;
902 while (l) {
903 ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;
904 l1oip_socket_send(hc, 0, dch->slot, 0,
905 hc->chan[dch->slot].tx_counter++, p, ll);
906 p += ll;
907 l -= ll;
908 }
909 skb_trim(skb, 0);
910 queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
911 return 0;
912 case PH_ACTIVATE_REQ:
913 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
914 printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
915 , __func__, dch->slot, hc->b_num+1);
916 skb_trim(skb, 0);
917 if (test_bit(FLG_ACTIVE, &dch->Flags))
918 queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
919 else
920 queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
921 return 0;
922 case PH_DEACTIVATE_REQ:
923 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
924 printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
925 "(1..%d)\n", __func__, dch->slot,
926 hc->b_num+1);
927 skb_trim(skb, 0);
928 if (test_bit(FLG_ACTIVE, &dch->Flags))
929 queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
930 else
931 queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
932 return 0;
933 }
934 if (!ret)
935 dev_kfree_skb(skb);
936 return ret;
937}
938
939static int
940channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
941{
942 int ret = 0;
943 struct l1oip *hc = dch->hw;
944
945 switch (cq->op) {
946 case MISDN_CTRL_GETOP:
947 cq->op = MISDN_CTRL_SETPEER | MISDN_CTRL_UNSETPEER;
948 break;
949 case MISDN_CTRL_SETPEER:
950 hc->remoteip = (u32)cq->p1;
951 hc->remoteport = cq->p2 & 0xffff;
952 hc->localport = cq->p2 >> 16;
953 if (!hc->remoteport)
954 hc->remoteport = hc->localport;
955 if (debug & DEBUG_L1OIP_SOCKET)
956 printk(KERN_DEBUG "%s: got new ip address from user "
957 "space.\n", __func__);
958 l1oip_socket_open(hc);
959 break;
960 case MISDN_CTRL_UNSETPEER:
961 if (debug & DEBUG_L1OIP_SOCKET)
962 printk(KERN_DEBUG "%s: removing ip address.\n",
963 __func__);
964 hc->remoteip = 0;
965 l1oip_socket_open(hc);
966 break;
967 default:
968 printk(KERN_WARNING "%s: unknown Op %x\n",
969 __func__, cq->op);
970 ret = -EINVAL;
971 break;
972 }
973 return ret;
974}
975
976static int
977open_dchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
978{
979 if (debug & DEBUG_HW_OPEN)
980 printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__,
981 dch->dev.id, __builtin_return_address(0));
982 if (rq->protocol == ISDN_P_NONE)
983 return -EINVAL;
984 if ((dch->dev.D.protocol != ISDN_P_NONE) &&
985 (dch->dev.D.protocol != rq->protocol)) {
986 if (debug & DEBUG_HW_OPEN)
987 printk(KERN_WARNING "%s: change protocol %x to %x\n",
988 __func__, dch->dev.D.protocol, rq->protocol);
989 }
990 if (dch->dev.D.protocol != rq->protocol)
991 dch->dev.D.protocol = rq->protocol;
992
993 if (test_bit(FLG_ACTIVE, &dch->Flags)) {
994 _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY,
995 0, NULL, GFP_KERNEL);
996 }
997 rq->ch = &dch->dev.D;
998 if (!try_module_get(THIS_MODULE))
999 printk(KERN_WARNING "%s:cannot get module\n", __func__);
1000 return 0;
1001}
1002
1003static int
1004open_bchannel(struct l1oip *hc, struct dchannel *dch, struct channel_req *rq)
1005{
1006 struct bchannel *bch;
1007 int ch;
1008
1009 if (!test_bit(rq->adr.channel & 0x1f,
1010 &dch->dev.channelmap[rq->adr.channel >> 5]))
1011 return -EINVAL;
1012 if (rq->protocol == ISDN_P_NONE)
1013 return -EINVAL;
1014 ch = rq->adr.channel; /* BRI: 1=B1 2=B2 PRI: 1..15,17.. */
1015 bch = hc->chan[ch].bch;
1016 if (!bch) {
1017 printk(KERN_ERR "%s:internal error ch %d has no bch\n",
1018 __func__, ch);
1019 return -EINVAL;
1020 }
1021 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1022 return -EBUSY; /* b-channel can be only open once */
1023 bch->ch.protocol = rq->protocol;
1024 rq->ch = &bch->ch;
1025 if (!try_module_get(THIS_MODULE))
1026 printk(KERN_WARNING "%s:cannot get module\n", __func__);
1027 return 0;
1028}
1029
1030static int
1031l1oip_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
1032{
1033 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1034 struct dchannel *dch = container_of(dev, struct dchannel, dev);
1035 struct l1oip *hc = dch->hw;
1036 struct channel_req *rq;
1037 int err = 0;
1038
1039 if (dch->debug & DEBUG_HW)
1040 printk(KERN_DEBUG "%s: cmd:%x %p\n",
1041 __func__, cmd, arg);
1042 switch (cmd) {
1043 case OPEN_CHANNEL:
1044 rq = arg;
1045 switch (rq->protocol) {
1046 case ISDN_P_TE_S0:
1047 case ISDN_P_NT_S0:
1048 if (hc->pri) {
1049 err = -EINVAL;
1050 break;
1051 }
1052 err = open_dchannel(hc, dch, rq);
1053 break;
1054 case ISDN_P_TE_E1:
1055 case ISDN_P_NT_E1:
1056 if (!hc->pri) {
1057 err = -EINVAL;
1058 break;
1059 }
1060 err = open_dchannel(hc, dch, rq);
1061 break;
1062 default:
1063 err = open_bchannel(hc, dch, rq);
1064 }
1065 break;
1066 case CLOSE_CHANNEL:
1067 if (debug & DEBUG_HW_OPEN)
1068 printk(KERN_DEBUG "%s: dev(%d) close from %p\n",
1069 __func__, dch->dev.id,
1070 __builtin_return_address(0));
1071 module_put(THIS_MODULE);
1072 break;
1073 case CONTROL_CHANNEL:
1074 err = channel_dctrl(dch, arg);
1075 break;
1076 default:
1077 if (dch->debug & DEBUG_HW)
1078 printk(KERN_DEBUG "%s: unknown command %x\n",
1079 __func__, cmd);
1080 err = -EINVAL;
1081 }
1082 return err;
1083}
1084
1085static int
1086handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
1087{
1088 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1089 struct l1oip *hc = bch->hw;
1090 int ret = -EINVAL;
1091 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1092 int l, ll, i;
1093 unsigned char *p;
1094
1095 switch (hh->prim) {
1096 case PH_DATA_REQ:
1097 if (skb->len <= 0) {
1098 printk(KERN_WARNING "%s: skb too small\n",
1099 __func__);
1100 break;
1101 }
1102 if (skb->len > MAX_DFRAME_LEN_L1 || skb->len > L1OIP_MAX_LEN) {
1103 printk(KERN_WARNING "%s: skb too large\n",
1104 __func__);
1105 break;
1106 }
1107 /* check for AIS / ulaw-silence */
1108 p = skb->data;
1109 l = skb->len;
1110 for (i = 0; i < l; i++) {
1111 if (*p++ != 0xff)
1112 break;
1113 }
1114 if (i == l) {
1115 if (debug & DEBUG_L1OIP_MSG)
1116 printk(KERN_DEBUG "%s: got AIS, not sending, "
1117 "but counting\n", __func__);
1118 hc->chan[bch->slot].tx_counter += l;
1119 skb_trim(skb, 0);
1120 queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
1121 return 0;
1122 }
1123 /* check for silence */
1124 p = skb->data;
1125 l = skb->len;
1126 for (i = 0; i < l; i++) {
1127 if (*p++ != 0x2a)
1128 break;
1129 }
1130 if (i == l) {
1131 if (debug & DEBUG_L1OIP_MSG)
1132 printk(KERN_DEBUG "%s: got silence, not sending"
1133 ", but counting\n", __func__);
1134 hc->chan[bch->slot].tx_counter += l;
1135 skb_trim(skb, 0);
1136 queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
1137 return 0;
1138 }
1139
1140 /* send frame */
1141 p = skb->data;
1142 l = skb->len;
1143 while (l) {
1144 ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;
1145 l1oip_socket_send(hc, hc->codec, bch->slot, 0,
1146 hc->chan[bch->slot].tx_counter, p, ll);
1147 hc->chan[bch->slot].tx_counter += ll;
1148 p += ll;
1149 l -= ll;
1150 }
1151 skb_trim(skb, 0);
1152 queue_ch_frame(ch, PH_DATA_CNF, hh->id, skb);
1153 return 0;
1154 case PH_ACTIVATE_REQ:
1155 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
1156 printk(KERN_DEBUG "%s: PH_ACTIVATE channel %d (1..%d)\n"
1157 , __func__, bch->slot, hc->b_num+1);
1158 hc->chan[bch->slot].codecstate = 0;
1159 test_and_set_bit(FLG_ACTIVE, &bch->Flags);
1160 skb_trim(skb, 0);
1161 queue_ch_frame(ch, PH_ACTIVATE_IND, hh->id, skb);
1162 return 0;
1163 case PH_DEACTIVATE_REQ:
1164 if (debug & (DEBUG_L1OIP_MSG|DEBUG_L1OIP_SOCKET))
1165 printk(KERN_DEBUG "%s: PH_DEACTIVATE channel %d "
1166 "(1..%d)\n", __func__, bch->slot,
1167 hc->b_num+1);
1168 test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
1169 skb_trim(skb, 0);
1170 queue_ch_frame(ch, PH_DEACTIVATE_IND, hh->id, skb);
1171 return 0;
1172 }
1173 if (!ret)
1174 dev_kfree_skb(skb);
1175 return ret;
1176}
1177
1178static int
1179channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1180{
1181 int ret = 0;
1182 struct dsp_features *features =
1183 (struct dsp_features *)(*((u_long *)&cq->p1));
1184
1185 switch (cq->op) {
1186 case MISDN_CTRL_GETOP:
1187 cq->op = MISDN_CTRL_HW_FEATURES_OP;
1188 break;
1189 case MISDN_CTRL_HW_FEATURES: /* fill features structure */
1190 if (debug & DEBUG_L1OIP_MSG)
1191 printk(KERN_DEBUG "%s: HW_FEATURE request\n",
1192 __func__);
1193 /* create confirm */
1194 features->unclocked = 1;
1195 features->unordered = 1;
1196 break;
1197 default:
1198 printk(KERN_WARNING "%s: unknown Op %x\n",
1199 __func__, cq->op);
1200 ret = -EINVAL;
1201 break;
1202 }
1203 return ret;
1204}
1205
1206static int
1207l1oip_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
1208{
1209 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1210 int err = -EINVAL;
1211
1212 if (bch->debug & DEBUG_HW)
1213 printk(KERN_DEBUG "%s: cmd:%x %p\n",
1214 __func__, cmd, arg);
1215 switch (cmd) {
1216 case CLOSE_CHANNEL:
1217 test_and_clear_bit(FLG_OPEN, &bch->Flags);
1218 test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
1219 ch->protocol = ISDN_P_NONE;
1220 ch->peer = NULL;
1221 module_put(THIS_MODULE);
1222 err = 0;
1223 break;
1224 case CONTROL_CHANNEL:
1225 err = channel_bctrl(bch, arg);
1226 break;
1227 default:
1228 printk(KERN_WARNING "%s: unknown prim(%x)\n",
1229 __func__, cmd);
1230 }
1231 return err;
1232}
1233
1234
1235/*
1236 * cleanup module and stack
1237 */
1238static void
1239release_card(struct l1oip *hc)
1240{
1241 int ch;
1242
1243 if (timer_pending(&hc->keep_tl))
1244 del_timer(&hc->keep_tl);
1245
1246 if (timer_pending(&hc->timeout_tl))
1247 del_timer(&hc->timeout_tl);
1248
1249 if (hc->socket_thread)
1250 l1oip_socket_close(hc);
1251
1252 if (hc->registered && hc->chan[hc->d_idx].dch)
1253 mISDN_unregister_device(&hc->chan[hc->d_idx].dch->dev);
1254 for (ch = 0; ch < 128; ch++) {
1255 if (hc->chan[ch].dch) {
1256 mISDN_freedchannel(hc->chan[ch].dch);
1257 kfree(hc->chan[ch].dch);
1258 }
1259 if (hc->chan[ch].bch) {
1260 mISDN_freebchannel(hc->chan[ch].bch);
1261 kfree(hc->chan[ch].bch);
1262#ifdef REORDER_DEBUG
1263 if (hc->chan[ch].disorder_skb)
1264 dev_kfree_skb(hc->chan[ch].disorder_skb);
1265#endif
1266 }
1267 }
1268
1269 spin_lock(&l1oip_lock);
1270 list_del(&hc->list);
1271 spin_unlock(&l1oip_lock);
1272
1273 kfree(hc);
1274}
1275
1276static void
1277l1oip_cleanup(void)
1278{
1279 struct l1oip *hc, *next;
1280
1281 list_for_each_entry_safe(hc, next, &l1oip_ilist, list)
1282 release_card(hc);
1283
1284 l1oip_4bit_free();
1285}
1286
1287
1288/*
1289 * module and stack init
1290 */
1291static int
1292init_card(struct l1oip *hc, int pri, int bundle)
1293{
1294 struct dchannel *dch;
1295 struct bchannel *bch;
1296 int ret;
1297 int i, ch;
1298
1299 spin_lock_init(&hc->socket_lock);
1300 hc->idx = l1oip_cnt;
1301 hc->pri = pri;
1302 hc->d_idx = pri?16:3;
1303 hc->b_num = pri?30:2;
1304 hc->bundle = bundle;
1305 if (hc->pri)
1306 sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);
1307 else
1308 sprintf(hc->name, "l1oip-s0.%d", l1oip_cnt + 1);
1309
1310 switch (codec[l1oip_cnt]) {
1311 case 0: /* as is */
1312 case 1: /* alaw */
1313 case 2: /* ulaw */
1314 case 3: /* 4bit */
1315 break;
1316 default:
1317 printk(KERN_ERR "Codec(%d) not supported.\n",
1318 codec[l1oip_cnt]);
1319 return -EINVAL;
1320 }
1321 hc->codec = codec[l1oip_cnt];
1322 if (debug & DEBUG_L1OIP_INIT)
1323 printk(KERN_DEBUG "%s: using codec %d\n",
1324 __func__, hc->codec);
1325
1326 if (id[l1oip_cnt] == 0) {
1327 printk(KERN_WARNING "Warning: No 'id' value given or "
1328 "0, this is highly unsecure. Please use 32 "
1329 "bit randmom number 0x...\n");
1330 }
1331 hc->id = id[l1oip_cnt];
1332 if (debug & DEBUG_L1OIP_INIT)
1333 printk(KERN_DEBUG "%s: using id 0x%x\n", __func__, hc->id);
1334
1335 hc->ondemand = ondemand[l1oip_cnt];
1336 if (hc->ondemand && !hc->id) {
1337 printk(KERN_ERR "%s: ondemand option only allowed in "
1338 "conjunction with non 0 ID\n", __func__);
1339 return -EINVAL;
1340 }
1341
1342 if (limit[l1oip_cnt])
1343 hc->b_num = limit[l1oip_cnt];
1344 if (!pri && hc->b_num > 2) {
1345 printk(KERN_ERR "Maximum limit for BRI interface is 2 "
1346 "channels.\n");
1347 return -EINVAL;
1348 }
1349 if (pri && hc->b_num > 126) {
1350 printk(KERN_ERR "Maximum limit for PRI interface is 126 "
1351 "channels.\n");
1352 return -EINVAL;
1353 }
1354 if (pri && hc->b_num > 30) {
1355 printk(KERN_WARNING "Maximum limit for BRI interface is 30 "
1356 "channels.\n");
1357 printk(KERN_WARNING "Your selection of %d channels must be "
1358 "supported by application.\n", hc->limit);
1359 }
1360
1361 hc->remoteip = ip[l1oip_cnt<<2] << 24
1362 | ip[(l1oip_cnt<<2)+1] << 16
1363 | ip[(l1oip_cnt<<2)+2] << 8
1364 | ip[(l1oip_cnt<<2)+3];
1365 hc->localport = port[l1oip_cnt]?:(L1OIP_DEFAULTPORT+l1oip_cnt);
1366 if (remoteport[l1oip_cnt])
1367 hc->remoteport = remoteport[l1oip_cnt];
1368 else
1369 hc->remoteport = hc->localport;
1370 if (debug & DEBUG_L1OIP_INIT)
1371 printk(KERN_DEBUG "%s: using local port %d remote ip "
1372 "%d.%d.%d.%d port %d ondemand %d\n", __func__,
1373 hc->localport, hc->remoteip >> 24,
1374 (hc->remoteip >> 16) & 0xff,
1375 (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff,
1376 hc->remoteport, hc->ondemand);
1377
1378 dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
1379 if (!dch)
1380 return -ENOMEM;
1381 dch->debug = debug;
1382 mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, NULL);
1383 dch->hw = hc;
1384 if (pri)
1385 dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
1386 else
1387 dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0);
1388 dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1389 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1390 dch->dev.D.send = handle_dmsg;
1391 dch->dev.D.ctrl = l1oip_dctrl;
1392 dch->dev.nrbchan = hc->b_num;
1393 dch->slot = hc->d_idx;
1394 hc->chan[hc->d_idx].dch = dch;
1395 i = 1;
1396 for (ch = 0; ch < dch->dev.nrbchan; ch++) {
1397 if (ch == 15)
1398 i++;
1399 bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
1400 if (!bch) {
1401 printk(KERN_ERR "%s: no memory for bchannel\n",
1402 __func__);
1403 return -ENOMEM;
1404 }
1405 bch->nr = i + ch;
1406 bch->slot = i + ch;
1407 bch->debug = debug;
1408 mISDN_initbchannel(bch, MAX_DATA_MEM);
1409 bch->hw = hc;
1410 bch->ch.send = handle_bmsg;
1411 bch->ch.ctrl = l1oip_bctrl;
1412 bch->ch.nr = i + ch;
1413 list_add(&bch->ch.list, &dch->dev.bchannels);
1414 hc->chan[i + ch].bch = bch;
1415 test_and_set_bit(bch->nr & 0x1f,
1416 &dch->dev.channelmap[bch->nr >> 5]);
1417 }
1418 ret = mISDN_register_device(&dch->dev, hc->name);
1419 if (ret)
1420 return ret;
1421 hc->registered = 1;
1422
1423 if (debug & DEBUG_L1OIP_INIT)
1424 printk(KERN_DEBUG "%s: Setting up network card(%d)\n",
1425 __func__, l1oip_cnt + 1);
1426 ret = l1oip_socket_open(hc);
1427 if (ret)
1428 return ret;
1429
1430 hc->keep_tl.function = (void *)l1oip_keepalive;
1431 hc->keep_tl.data = (ulong)hc;
1432 init_timer(&hc->keep_tl);
1433 hc->keep_tl.expires = jiffies + 2*HZ; /* two seconds first time */
1434 add_timer(&hc->keep_tl);
1435
1436 hc->timeout_tl.function = (void *)l1oip_timeout;
1437 hc->timeout_tl.data = (ulong)hc;
1438 init_timer(&hc->timeout_tl);
1439 hc->timeout_on = 0; /* state that we have timer off */
1440
1441 return 0;
1442}
1443
1444static int __init
1445l1oip_init(void)
1446{
1447 int pri, bundle;
1448 struct l1oip *hc;
1449 int ret;
1450
1451 printk(KERN_INFO "mISDN: Layer-1-over-IP driver Rev. %s\n",
1452 l1oip_revision);
1453
1454 INIT_LIST_HEAD(&l1oip_ilist);
1455 spin_lock_init(&l1oip_lock);
1456
1457 if (l1oip_4bit_alloc(ulaw))
1458 return -ENOMEM;
1459
1460 l1oip_cnt = 0;
1461 while (type[l1oip_cnt] && l1oip_cnt < MAX_CARDS) {
1462 switch (type[l1oip_cnt] & 0xff) {
1463 case 1:
1464 pri = 0;
1465 bundle = 0;
1466 break;
1467 case 2:
1468 pri = 1;
1469 bundle = 0;
1470 break;
1471 case 3:
1472 pri = 0;
1473 bundle = 1;
1474 break;
1475 case 4:
1476 pri = 1;
1477 bundle = 1;
1478 break;
1479 default:
1480 printk(KERN_ERR "Card type(%d) not supported.\n",
1481 type[l1oip_cnt] & 0xff);
1482 l1oip_cleanup();
1483 return -EINVAL;
1484 }
1485
1486 if (debug & DEBUG_L1OIP_INIT)
1487 printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
1488 __func__, l1oip_cnt, pri?"PRI":"BRI",
1489 bundle?"bundled IP packet for all B-channels"
1490 :"seperate IP packets for every B-channel");
1491
1492 hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
1493 if (!hc) {
1494 printk(KERN_ERR "No kmem for L1-over-IP driver.\n");
1495 l1oip_cleanup();
1496 return -ENOMEM;
1497 }
1498 INIT_WORK(&hc->workq, (void *)l1oip_send_bh);
1499
1500 spin_lock(&l1oip_lock);
1501 list_add_tail(&hc->list, &l1oip_ilist);
1502 spin_unlock(&l1oip_lock);
1503
1504 ret = init_card(hc, pri, bundle);
1505 if (ret) {
1506 l1oip_cleanup();
1507 return ret;
1508 }
1509
1510 l1oip_cnt++;
1511 }
1512 printk(KERN_INFO "%d virtual devices registered\n", l1oip_cnt);
1513 return 0;
1514}
1515
1516module_init(l1oip_init);
1517module_exit(l1oip_cleanup);
1518
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
new file mode 100644
index 000000000000..fced1a2755f8
--- /dev/null
+++ b/drivers/isdn/mISDN/layer1.c
@@ -0,0 +1,403 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18
19#include <linux/module.h>
20#include <linux/mISDNhw.h>
21#include "layer1.h"
22#include "fsm.h"
23
24static int *debug;
25
26struct layer1 {
27 u_long Flags;
28 struct FsmInst l1m;
29 struct FsmTimer timer;
30 int delay;
31 struct dchannel *dch;
32 dchannel_l1callback *dcb;
33};
34
35#define TIMER3_VALUE 7000
36
37static
38struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL};
39
40enum {
41 ST_L1_F2,
42 ST_L1_F3,
43 ST_L1_F4,
44 ST_L1_F5,
45 ST_L1_F6,
46 ST_L1_F7,
47 ST_L1_F8,
48};
49
50#define L1S_STATE_COUNT (ST_L1_F8+1)
51
52static char *strL1SState[] =
53{
54 "ST_L1_F2",
55 "ST_L1_F3",
56 "ST_L1_F4",
57 "ST_L1_F5",
58 "ST_L1_F6",
59 "ST_L1_F7",
60 "ST_L1_F8",
61};
62
63enum {
64 EV_PH_ACTIVATE,
65 EV_PH_DEACTIVATE,
66 EV_RESET_IND,
67 EV_DEACT_CNF,
68 EV_DEACT_IND,
69 EV_POWER_UP,
70 EV_ANYSIG_IND,
71 EV_INFO2_IND,
72 EV_INFO4_IND,
73 EV_TIMER_DEACT,
74 EV_TIMER_ACT,
75 EV_TIMER3,
76};
77
78#define L1_EVENT_COUNT (EV_TIMER3 + 1)
79
80static char *strL1Event[] =
81{
82 "EV_PH_ACTIVATE",
83 "EV_PH_DEACTIVATE",
84 "EV_RESET_IND",
85 "EV_DEACT_CNF",
86 "EV_DEACT_IND",
87 "EV_POWER_UP",
88 "EV_ANYSIG_IND",
89 "EV_INFO2_IND",
90 "EV_INFO4_IND",
91 "EV_TIMER_DEACT",
92 "EV_TIMER_ACT",
93 "EV_TIMER3",
94};
95
96static void
97l1m_debug(struct FsmInst *fi, char *fmt, ...)
98{
99 struct layer1 *l1 = fi->userdata;
100 va_list va;
101
102 va_start(va, fmt);
103 printk(KERN_DEBUG "%s: ", l1->dch->dev.name);
104 vprintk(fmt, va);
105 printk("\n");
106 va_end(va);
107}
108
109static void
110l1_reset(struct FsmInst *fi, int event, void *arg)
111{
112 mISDN_FsmChangeState(fi, ST_L1_F3);
113}
114
115static void
116l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
117{
118 struct layer1 *l1 = fi->userdata;
119
120 mISDN_FsmChangeState(fi, ST_L1_F3);
121 if (test_bit(FLG_L1_ACTIVATING, &l1->Flags))
122 l1->dcb(l1->dch, HW_POWERUP_REQ);
123}
124
125static void
126l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
127{
128 struct layer1 *l1 = fi->userdata;
129
130 mISDN_FsmChangeState(fi, ST_L1_F3);
131 mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2);
132 test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags);
133}
134
135static void
136l1_power_up_s(struct FsmInst *fi, int event, void *arg)
137{
138 struct layer1 *l1 = fi->userdata;
139
140 if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
141 mISDN_FsmChangeState(fi, ST_L1_F4);
142 l1->dcb(l1->dch, INFO3_P8);
143 } else
144 mISDN_FsmChangeState(fi, ST_L1_F3);
145}
146
147static void
148l1_go_F5(struct FsmInst *fi, int event, void *arg)
149{
150 mISDN_FsmChangeState(fi, ST_L1_F5);
151}
152
153static void
154l1_go_F8(struct FsmInst *fi, int event, void *arg)
155{
156 mISDN_FsmChangeState(fi, ST_L1_F8);
157}
158
159static void
160l1_info2_ind(struct FsmInst *fi, int event, void *arg)
161{
162 struct layer1 *l1 = fi->userdata;
163
164 mISDN_FsmChangeState(fi, ST_L1_F6);
165 l1->dcb(l1->dch, INFO3_P8);
166}
167
168static void
169l1_info4_ind(struct FsmInst *fi, int event, void *arg)
170{
171 struct layer1 *l1 = fi->userdata;
172
173 mISDN_FsmChangeState(fi, ST_L1_F7);
174 l1->dcb(l1->dch, INFO3_P8);
175 if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags))
176 mISDN_FsmDelTimer(&l1->timer, 4);
177 if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) {
178 if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags))
179 mISDN_FsmDelTimer(&l1->timer, 3);
180 mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2);
181 test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags);
182 }
183}
184
185static void
186l1_timer3(struct FsmInst *fi, int event, void *arg)
187{
188 struct layer1 *l1 = fi->userdata;
189
190 test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags);
191 if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
192 if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
193 l1->dcb(l1->dch, HW_D_NOBLOCKED);
194 l1->dcb(l1->dch, PH_DEACTIVATE_IND);
195 }
196 if (l1->l1m.state != ST_L1_F6) {
197 mISDN_FsmChangeState(fi, ST_L1_F3);
198 l1->dcb(l1->dch, HW_POWERUP_REQ);
199 }
200}
201
202static void
203l1_timer_act(struct FsmInst *fi, int event, void *arg)
204{
205 struct layer1 *l1 = fi->userdata;
206
207 test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags);
208 test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags);
209 l1->dcb(l1->dch, PH_ACTIVATE_IND);
210}
211
212static void
213l1_timer_deact(struct FsmInst *fi, int event, void *arg)
214{
215 struct layer1 *l1 = fi->userdata;
216
217 test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags);
218 test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags);
219 if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
220 l1->dcb(l1->dch, HW_D_NOBLOCKED);
221 l1->dcb(l1->dch, PH_DEACTIVATE_IND);
222 l1->dcb(l1->dch, HW_DEACT_REQ);
223}
224
225static void
226l1_activate_s(struct FsmInst *fi, int event, void *arg)
227{
228 struct layer1 *l1 = fi->userdata;
229
230 mISDN_FsmRestartTimer(&l1->timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
231 test_and_set_bit(FLG_L1_T3RUN, &l1->Flags);
232 l1->dcb(l1->dch, HW_RESET_REQ);
233}
234
235static void
236l1_activate_no(struct FsmInst *fi, int event, void *arg)
237{
238 struct layer1 *l1 = fi->userdata;
239
240 if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) &&
241 (!test_bit(FLG_L1_T3RUN, &l1->Flags))) {
242 test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags);
243 if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
244 l1->dcb(l1->dch, HW_D_NOBLOCKED);
245 l1->dcb(l1->dch, PH_DEACTIVATE_IND);
246 }
247}
248
249static struct FsmNode L1SFnList[] =
250{
251 {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s},
252 {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no},
253 {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no},
254 {ST_L1_F3, EV_RESET_IND, l1_reset},
255 {ST_L1_F4, EV_RESET_IND, l1_reset},
256 {ST_L1_F5, EV_RESET_IND, l1_reset},
257 {ST_L1_F6, EV_RESET_IND, l1_reset},
258 {ST_L1_F7, EV_RESET_IND, l1_reset},
259 {ST_L1_F8, EV_RESET_IND, l1_reset},
260 {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf},
261 {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf},
262 {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf},
263 {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf},
264 {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf},
265 {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf},
266 {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s},
267 {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s},
268 {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s},
269 {ST_L1_F3, EV_POWER_UP, l1_power_up_s},
270 {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5},
271 {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8},
272 {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8},
273 {ST_L1_F3, EV_INFO2_IND, l1_info2_ind},
274 {ST_L1_F4, EV_INFO2_IND, l1_info2_ind},
275 {ST_L1_F5, EV_INFO2_IND, l1_info2_ind},
276 {ST_L1_F7, EV_INFO2_IND, l1_info2_ind},
277 {ST_L1_F8, EV_INFO2_IND, l1_info2_ind},
278 {ST_L1_F3, EV_INFO4_IND, l1_info4_ind},
279 {ST_L1_F4, EV_INFO4_IND, l1_info4_ind},
280 {ST_L1_F5, EV_INFO4_IND, l1_info4_ind},
281 {ST_L1_F6, EV_INFO4_IND, l1_info4_ind},
282 {ST_L1_F8, EV_INFO4_IND, l1_info4_ind},
283 {ST_L1_F3, EV_TIMER3, l1_timer3},
284 {ST_L1_F4, EV_TIMER3, l1_timer3},
285 {ST_L1_F5, EV_TIMER3, l1_timer3},
286 {ST_L1_F6, EV_TIMER3, l1_timer3},
287 {ST_L1_F8, EV_TIMER3, l1_timer3},
288 {ST_L1_F7, EV_TIMER_ACT, l1_timer_act},
289 {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact},
290 {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact},
291 {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact},
292 {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact},
293 {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact},
294 {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
295};
296
297static void
298release_l1(struct layer1 *l1) {
299 mISDN_FsmDelTimer(&l1->timer, 0);
300 if (l1->dch)
301 l1->dch->l1 = NULL;
302 module_put(THIS_MODULE);
303 kfree(l1);
304}
305
306int
307l1_event(struct layer1 *l1, u_int event)
308{
309 int err = 0;
310
311 if (!l1)
312 return -EINVAL;
313 switch (event) {
314 case HW_RESET_IND:
315 mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
316 break;
317 case HW_DEACT_IND:
318 mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL);
319 break;
320 case HW_POWERUP_IND:
321 mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL);
322 break;
323 case HW_DEACT_CNF:
324 mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
325 break;
326 case ANYSIGNAL:
327 mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
328 break;
329 case LOSTFRAMING:
330 mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
331 break;
332 case INFO2:
333 mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL);
334 break;
335 case INFO4_P8:
336 mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
337 break;
338 case INFO4_P10:
339 mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
340 break;
341 case PH_ACTIVATE_REQ:
342 if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
343 l1->dcb(l1->dch, PH_ACTIVATE_IND);
344 else {
345 test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags);
346 mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL);
347 }
348 break;
349 case CLOSE_CHANNEL:
350 release_l1(l1);
351 break;
352 default:
353 if (*debug & DEBUG_L1)
354 printk(KERN_DEBUG "%s %x unhandled\n",
355 __func__, event);
356 err = -EINVAL;
357 }
358 return err;
359}
360EXPORT_SYMBOL(l1_event);
361
362int
363create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
364 struct layer1 *nl1;
365
366 nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC);
367 if (!nl1) {
368 printk(KERN_ERR "kmalloc struct layer1 failed\n");
369 return -ENOMEM;
370 }
371 nl1->l1m.fsm = &l1fsm_s;
372 nl1->l1m.state = ST_L1_F3;
373 nl1->Flags = 0;
374 nl1->l1m.debug = *debug & DEBUG_L1_FSM;
375 nl1->l1m.userdata = nl1;
376 nl1->l1m.userint = 0;
377 nl1->l1m.printdebug = l1m_debug;
378 nl1->dch = dch;
379 nl1->dcb = dcb;
380 mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer);
381 __module_get(THIS_MODULE);
382 dch->l1 = nl1;
383 return 0;
384}
385EXPORT_SYMBOL(create_l1);
386
387int
388l1_init(u_int *deb)
389{
390 debug = deb;
391 l1fsm_s.state_count = L1S_STATE_COUNT;
392 l1fsm_s.event_count = L1_EVENT_COUNT;
393 l1fsm_s.strEvent = strL1Event;
394 l1fsm_s.strState = strL1SState;
395 mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
396 return 0;
397}
398
399void
400l1_cleanup(void)
401{
402 mISDN_FsmFree(&l1fsm_s);
403}
diff --git a/drivers/isdn/mISDN/layer1.h b/drivers/isdn/mISDN/layer1.h
new file mode 100644
index 000000000000..9c8125fd89af
--- /dev/null
+++ b/drivers/isdn/mISDN/layer1.h
@@ -0,0 +1,26 @@
1/*
2 *
3 * Layer 1 defines
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#define FLG_L1_ACTIVATING 1
19#define FLG_L1_ACTIVATED 2
20#define FLG_L1_DEACTTIMER 3
21#define FLG_L1_ACTTIMER 4
22#define FLG_L1_T3RUN 5
23#define FLG_L1_PULL_REQ 6
24#define FLG_L1_UINT 7
25#define FLG_L1_DBLOCKED 8
26
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
new file mode 100644
index 000000000000..f5ad888ee71e
--- /dev/null
+++ b/drivers/isdn/mISDN/layer2.c
@@ -0,0 +1,2216 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include "fsm.h"
19#include "layer2.h"
20
21static int *debug;
22
23static
24struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL};
25
26static char *strL2State[] =
27{
28 "ST_L2_1",
29 "ST_L2_2",
30 "ST_L2_3",
31 "ST_L2_4",
32 "ST_L2_5",
33 "ST_L2_6",
34 "ST_L2_7",
35 "ST_L2_8",
36};
37
38enum {
39 EV_L2_UI,
40 EV_L2_SABME,
41 EV_L2_DISC,
42 EV_L2_DM,
43 EV_L2_UA,
44 EV_L2_FRMR,
45 EV_L2_SUPER,
46 EV_L2_I,
47 EV_L2_DL_DATA,
48 EV_L2_ACK_PULL,
49 EV_L2_DL_UNITDATA,
50 EV_L2_DL_ESTABLISH_REQ,
51 EV_L2_DL_RELEASE_REQ,
52 EV_L2_MDL_ASSIGN,
53 EV_L2_MDL_REMOVE,
54 EV_L2_MDL_ERROR,
55 EV_L1_DEACTIVATE,
56 EV_L2_T200,
57 EV_L2_T203,
58 EV_L2_SET_OWN_BUSY,
59 EV_L2_CLEAR_OWN_BUSY,
60 EV_L2_FRAME_ERROR,
61};
62
63#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR+1)
64
65static char *strL2Event[] =
66{
67 "EV_L2_UI",
68 "EV_L2_SABME",
69 "EV_L2_DISC",
70 "EV_L2_DM",
71 "EV_L2_UA",
72 "EV_L2_FRMR",
73 "EV_L2_SUPER",
74 "EV_L2_I",
75 "EV_L2_DL_DATA",
76 "EV_L2_ACK_PULL",
77 "EV_L2_DL_UNITDATA",
78 "EV_L2_DL_ESTABLISH_REQ",
79 "EV_L2_DL_RELEASE_REQ",
80 "EV_L2_MDL_ASSIGN",
81 "EV_L2_MDL_REMOVE",
82 "EV_L2_MDL_ERROR",
83 "EV_L1_DEACTIVATE",
84 "EV_L2_T200",
85 "EV_L2_T203",
86 "EV_L2_SET_OWN_BUSY",
87 "EV_L2_CLEAR_OWN_BUSY",
88 "EV_L2_FRAME_ERROR",
89};
90
91static void
92l2m_debug(struct FsmInst *fi, char *fmt, ...)
93{
94 struct layer2 *l2 = fi->userdata;
95 va_list va;
96
97 if (!(*debug & DEBUG_L2_FSM))
98 return;
99 va_start(va, fmt);
100 printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
101 vprintk(fmt, va);
102 printk("\n");
103 va_end(va);
104}
105
106inline u_int
107l2headersize(struct layer2 *l2, int ui)
108{
109 return ((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
110 (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1);
111}
112
113inline u_int
114l2addrsize(struct layer2 *l2)
115{
116 return test_bit(FLG_LAPD, &l2->flag) ? 2 : 1;
117}
118
119static u_int
120l2_newid(struct layer2 *l2)
121{
122 u_int id;
123
124 id = l2->next_id++;
125 if (id == 0x7fff)
126 l2->next_id = 1;
127 id <<= 16;
128 id |= l2->tei << 8;
129 id |= l2->sapi;
130 return id;
131}
132
133static void
134l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb)
135{
136 int err;
137
138 if (!l2->up)
139 return;
140 mISDN_HEAD_PRIM(skb) = prim;
141 mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr;
142 err = l2->up->send(l2->up, skb);
143 if (err) {
144 printk(KERN_WARNING "%s: err=%d\n", __func__, err);
145 dev_kfree_skb(skb);
146 }
147}
148
149static void
150l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)
151{
152 struct sk_buff *skb;
153 struct mISDNhead *hh;
154 int err;
155
156 if (!l2->up)
157 return;
158 skb = mI_alloc_skb(len, GFP_ATOMIC);
159 if (!skb)
160 return;
161 hh = mISDN_HEAD_P(skb);
162 hh->prim = prim;
163 hh->id = (l2->ch.nr << 16) | l2->ch.addr;
164 if (len)
165 memcpy(skb_put(skb, len), arg, len);
166 err = l2->up->send(l2->up, skb);
167 if (err) {
168 printk(KERN_WARNING "%s: err=%d\n", __func__, err);
169 dev_kfree_skb(skb);
170 }
171}
172
173static int
174l2down_skb(struct layer2 *l2, struct sk_buff *skb) {
175 int ret;
176
177 ret = l2->ch.recv(l2->ch.peer, skb);
178 if (ret && (*debug & DEBUG_L2_RECV))
179 printk(KERN_DEBUG "l2down_skb: ret(%d)\n", ret);
180 return ret;
181}
182
183static int
184l2down_raw(struct layer2 *l2, struct sk_buff *skb)
185{
186 struct mISDNhead *hh = mISDN_HEAD_P(skb);
187
188 if (hh->prim == PH_DATA_REQ) {
189 if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
190 skb_queue_tail(&l2->down_queue, skb);
191 return 0;
192 }
193 l2->down_id = mISDN_HEAD_ID(skb);
194 }
195 return l2down_skb(l2, skb);
196}
197
198static int
199l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb)
200{
201 struct mISDNhead *hh = mISDN_HEAD_P(skb);
202
203 hh->prim = prim;
204 hh->id = id;
205 return l2down_raw(l2, skb);
206}
207
208static int
209l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg)
210{
211 struct sk_buff *skb;
212 int err;
213 struct mISDNhead *hh;
214
215 skb = mI_alloc_skb(len, GFP_ATOMIC);
216 if (!skb)
217 return -ENOMEM;
218 hh = mISDN_HEAD_P(skb);
219 hh->prim = prim;
220 hh->id = id;
221 if (len)
222 memcpy(skb_put(skb, len), arg, len);
223 err = l2down_raw(l2, skb);
224 if (err)
225 dev_kfree_skb(skb);
226 return err;
227}
228
229static int
230ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {
231 struct sk_buff *nskb = skb;
232 int ret = -EAGAIN;
233
234 if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {
235 if (hh->id == l2->down_id) {
236 nskb = skb_dequeue(&l2->down_queue);
237 if (nskb) {
238 l2->down_id = mISDN_HEAD_ID(nskb);
239 if (l2down_skb(l2, nskb)) {
240 dev_kfree_skb(nskb);
241 l2->down_id = MISDN_ID_NONE;
242 }
243 } else
244 l2->down_id = MISDN_ID_NONE;
245 if (ret) {
246 dev_kfree_skb(skb);
247 ret = 0;
248 }
249 if (l2->down_id == MISDN_ID_NONE) {
250 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
251 mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
252 }
253 }
254 }
255 if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
256 nskb = skb_dequeue(&l2->down_queue);
257 if (nskb) {
258 l2->down_id = mISDN_HEAD_ID(nskb);
259 if (l2down_skb(l2, nskb)) {
260 dev_kfree_skb(nskb);
261 l2->down_id = MISDN_ID_NONE;
262 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
263 }
264 } else
265 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
266 }
267 return ret;
268}
269
270static int
271l2mgr(struct layer2 *l2, u_int prim, void *arg) {
272 long c = (long)arg;
273
274 printk(KERN_WARNING
275 "l2mgr: addr:%x prim %x %c\n", l2->id, prim, (char)c);
276 if (test_bit(FLG_LAPD, &l2->flag) &&
277 !test_bit(FLG_FIXED_TEI, &l2->flag)) {
278 switch (c) {
279 case 'C':
280 case 'D':
281 case 'G':
282 case 'H':
283 l2_tei(l2, prim, (u_long)arg);
284 break;
285 }
286 }
287 return 0;
288}
289
290static void
291set_peer_busy(struct layer2 *l2) {
292 test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
293 if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))
294 test_and_set_bit(FLG_L2BLOCK, &l2->flag);
295}
296
297static void
298clear_peer_busy(struct layer2 *l2) {
299 if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag))
300 test_and_clear_bit(FLG_L2BLOCK, &l2->flag);
301}
302
303static void
304InitWin(struct layer2 *l2)
305{
306 int i;
307
308 for (i = 0; i < MAX_WINDOW; i++)
309 l2->windowar[i] = NULL;
310}
311
312static int
313freewin(struct layer2 *l2)
314{
315 int i, cnt = 0;
316
317 for (i = 0; i < MAX_WINDOW; i++) {
318 if (l2->windowar[i]) {
319 cnt++;
320 dev_kfree_skb(l2->windowar[i]);
321 l2->windowar[i] = NULL;
322 }
323 }
324 return cnt;
325}
326
327static void
328ReleaseWin(struct layer2 *l2)
329{
330 int cnt = freewin(l2);
331
332 if (cnt)
333 printk(KERN_WARNING
334 "isdnl2 freed %d skbuffs in release\n", cnt);
335}
336
337inline unsigned int
338cansend(struct layer2 *l2)
339{
340 unsigned int p1;
341
342 if (test_bit(FLG_MOD128, &l2->flag))
343 p1 = (l2->vs - l2->va) % 128;
344 else
345 p1 = (l2->vs - l2->va) % 8;
346 return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag);
347}
348
349inline void
350clear_exception(struct layer2 *l2)
351{
352 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
353 test_and_clear_bit(FLG_REJEXC, &l2->flag);
354 test_and_clear_bit(FLG_OWN_BUSY, &l2->flag);
355 clear_peer_busy(l2);
356}
357
358static int
359sethdraddr(struct layer2 *l2, u_char *header, int rsp)
360{
361 u_char *ptr = header;
362 int crbit = rsp;
363
364 if (test_bit(FLG_LAPD, &l2->flag)) {
365 if (test_bit(FLG_LAPD_NET, &l2->flag))
366 crbit = !crbit;
367 *ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0);
368 *ptr++ = (l2->tei << 1) | 1;
369 return 2;
370 } else {
371 if (test_bit(FLG_ORIG, &l2->flag))
372 crbit = !crbit;
373 if (crbit)
374 *ptr++ = l2->addr.B;
375 else
376 *ptr++ = l2->addr.A;
377 return 1;
378 }
379}
380
381static inline void
382enqueue_super(struct layer2 *l2, struct sk_buff *skb)
383{
384 if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
385 dev_kfree_skb(skb);
386}
387
388static inline void
389enqueue_ui(struct layer2 *l2, struct sk_buff *skb)
390{
391 if (l2->tm)
392 l2_tei(l2, MDL_STATUS_UI_IND, 0);
393 if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
394 dev_kfree_skb(skb);
395}
396
397inline int
398IsUI(u_char *data)
399{
400 return (data[0] & 0xef) == UI;
401}
402
403inline int
404IsUA(u_char *data)
405{
406 return (data[0] & 0xef) == UA;
407}
408
409inline int
410IsDM(u_char *data)
411{
412 return (data[0] & 0xef) == DM;
413}
414
415inline int
416IsDISC(u_char *data)
417{
418 return (data[0] & 0xef) == DISC;
419}
420
421inline int
422IsRR(u_char *data, struct layer2 *l2)
423{
424 if (test_bit(FLG_MOD128, &l2->flag))
425 return data[0] == RR;
426 else
427 return (data[0] & 0xf) == 1;
428}
429
430inline int
431IsSFrame(u_char *data, struct layer2 *l2)
432{
433 register u_char d = *data;
434
435 if (!test_bit(FLG_MOD128, &l2->flag))
436 d &= 0xf;
437 return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c);
438}
439
440inline int
441IsSABME(u_char *data, struct layer2 *l2)
442{
443 u_char d = data[0] & ~0x10;
444
445 return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM;
446}
447
448inline int
449IsREJ(u_char *data, struct layer2 *l2)
450{
451 return test_bit(FLG_MOD128, &l2->flag) ?
452 data[0] == REJ : (data[0] & 0xf) == REJ;
453}
454
455inline int
456IsFRMR(u_char *data)
457{
458 return (data[0] & 0xef) == FRMR;
459}
460
461inline int
462IsRNR(u_char *data, struct layer2 *l2)
463{
464 return test_bit(FLG_MOD128, &l2->flag) ?
465 data[0] == RNR : (data[0] & 0xf) == RNR;
466}
467
468int
469iframe_error(struct layer2 *l2, struct sk_buff *skb)
470{
471 u_int i;
472 int rsp = *skb->data & 0x2;
473
474 i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1);
475 if (test_bit(FLG_ORIG, &l2->flag))
476 rsp = !rsp;
477 if (rsp)
478 return 'L';
479 if (skb->len < i)
480 return 'N';
481 if ((skb->len - i) > l2->maxlen)
482 return 'O';
483 return 0;
484}
485
486int
487super_error(struct layer2 *l2, struct sk_buff *skb)
488{
489 if (skb->len != l2addrsize(l2) +
490 (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1))
491 return 'N';
492 return 0;
493}
494
495int
496unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp)
497{
498 int rsp = (*skb->data & 0x2) >> 1;
499 if (test_bit(FLG_ORIG, &l2->flag))
500 rsp = !rsp;
501 if (rsp != wantrsp)
502 return 'L';
503 if (skb->len != l2addrsize(l2) + 1)
504 return 'N';
505 return 0;
506}
507
508int
509UI_error(struct layer2 *l2, struct sk_buff *skb)
510{
511 int rsp = *skb->data & 0x2;
512 if (test_bit(FLG_ORIG, &l2->flag))
513 rsp = !rsp;
514 if (rsp)
515 return 'L';
516 if (skb->len > l2->maxlen + l2addrsize(l2) + 1)
517 return 'O';
518 return 0;
519}
520
521int
522FRMR_error(struct layer2 *l2, struct sk_buff *skb)
523{
524 u_int headers = l2addrsize(l2) + 1;
525 u_char *datap = skb->data + headers;
526 int rsp = *skb->data & 0x2;
527
528 if (test_bit(FLG_ORIG, &l2->flag))
529 rsp = !rsp;
530 if (!rsp)
531 return 'L';
532 if (test_bit(FLG_MOD128, &l2->flag)) {
533 if (skb->len < headers + 5)
534 return 'N';
535 else if (*debug & DEBUG_L2)
536 l2m_debug(&l2->l2m,
537 "FRMR information %2x %2x %2x %2x %2x",
538 datap[0], datap[1], datap[2], datap[3], datap[4]);
539 } else {
540 if (skb->len < headers + 3)
541 return 'N';
542 else if (*debug & DEBUG_L2)
543 l2m_debug(&l2->l2m,
544 "FRMR information %2x %2x %2x",
545 datap[0], datap[1], datap[2]);
546 }
547 return 0;
548}
549
550static unsigned int
551legalnr(struct layer2 *l2, unsigned int nr)
552{
553 if (test_bit(FLG_MOD128, &l2->flag))
554 return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128);
555 else
556 return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8);
557}
558
559static void
560setva(struct layer2 *l2, unsigned int nr)
561{
562 struct sk_buff *skb;
563
564 while (l2->va != nr) {
565 l2->va++;
566 if (test_bit(FLG_MOD128, &l2->flag))
567 l2->va %= 128;
568 else
569 l2->va %= 8;
570 if (l2->windowar[l2->sow]) {
571 skb_trim(l2->windowar[l2->sow], 0);
572 skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);
573 l2->windowar[l2->sow] = NULL;
574 }
575 l2->sow = (l2->sow + 1) % l2->window;
576 }
577 skb = skb_dequeue(&l2->tmp_queue);
578 while (skb) {
579 dev_kfree_skb(skb);
580 skb = skb_dequeue(&l2->tmp_queue);
581 }
582}
583
584static void
585send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
586{
587 u_char tmp[MAX_L2HEADER_LEN];
588 int i;
589
590 i = sethdraddr(l2, tmp, cr);
591 tmp[i++] = cmd;
592 if (skb)
593 skb_trim(skb, 0);
594 else {
595 skb = mI_alloc_skb(i, GFP_ATOMIC);
596 if (!skb) {
597 printk(KERN_WARNING "%s: can't alloc skbuff\n",
598 __func__);
599 return;
600 }
601 }
602 memcpy(skb_put(skb, i), tmp, i);
603 enqueue_super(l2, skb);
604}
605
606
607inline u_char
608get_PollFlag(struct layer2 *l2, struct sk_buff *skb)
609{
610 return skb->data[l2addrsize(l2)] & 0x10;
611}
612
613inline u_char
614get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb)
615{
616 u_char PF;
617
618 PF = get_PollFlag(l2, skb);
619 dev_kfree_skb(skb);
620 return PF;
621}
622
623inline void
624start_t200(struct layer2 *l2, int i)
625{
626 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
627 test_and_set_bit(FLG_T200_RUN, &l2->flag);
628}
629
630inline void
631restart_t200(struct layer2 *l2, int i)
632{
633 mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
634 test_and_set_bit(FLG_T200_RUN, &l2->flag);
635}
636
637inline void
638stop_t200(struct layer2 *l2, int i)
639{
640 if (test_and_clear_bit(FLG_T200_RUN, &l2->flag))
641 mISDN_FsmDelTimer(&l2->t200, i);
642}
643
644inline void
645st5_dl_release_l2l3(struct layer2 *l2)
646{
647 int pr;
648
649 if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
650 pr = DL_RELEASE_CNF;
651 else
652 pr = DL_RELEASE_IND;
653 l2up_create(l2, pr, 0, NULL);
654}
655
656inline void
657lapb_dl_release_l2l3(struct layer2 *l2, int f)
658{
659 if (test_bit(FLG_LAPB, &l2->flag))
660 l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL);
661 l2up_create(l2, f, 0, NULL);
662}
663
664static void
665establishlink(struct FsmInst *fi)
666{
667 struct layer2 *l2 = fi->userdata;
668 u_char cmd;
669
670 clear_exception(l2);
671 l2->rc = 0;
672 cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10;
673 send_uframe(l2, NULL, cmd, CMD);
674 mISDN_FsmDelTimer(&l2->t203, 1);
675 restart_t200(l2, 1);
676 test_and_clear_bit(FLG_PEND_REL, &l2->flag);
677 freewin(l2);
678 mISDN_FsmChangeState(fi, ST_L2_5);
679}
680
681static void
682l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)
683{
684 struct sk_buff *skb = arg;
685 struct layer2 *l2 = fi->userdata;
686
687 if (get_PollFlagFree(l2, skb))
688 l2mgr(l2, MDL_ERROR_IND, (void *) 'C');
689 else
690 l2mgr(l2, MDL_ERROR_IND, (void *) 'D');
691
692}
693
694static void
695l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
696{
697 struct sk_buff *skb = arg;
698 struct layer2 *l2 = fi->userdata;
699
700 if (get_PollFlagFree(l2, skb))
701 l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
702 else {
703 l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
704 establishlink(fi);
705 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
706 }
707}
708
709static void
710l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
711{
712 struct sk_buff *skb = arg;
713 struct layer2 *l2 = fi->userdata;
714
715 if (get_PollFlagFree(l2, skb))
716 l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
717 else
718 l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
719 establishlink(fi);
720 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
721}
722
723static void
724l2_go_st3(struct FsmInst *fi, int event, void *arg)
725{
726 dev_kfree_skb((struct sk_buff *)arg);
727 mISDN_FsmChangeState(fi, ST_L2_3);
728}
729
730static void
731l2_mdl_assign(struct FsmInst *fi, int event, void *arg)
732{
733 struct layer2 *l2 = fi->userdata;
734
735 mISDN_FsmChangeState(fi, ST_L2_3);
736 dev_kfree_skb((struct sk_buff *)arg);
737 l2_tei(l2, MDL_ASSIGN_IND, 0);
738}
739
740static void
741l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg)
742{
743 struct layer2 *l2 = fi->userdata;
744 struct sk_buff *skb = arg;
745
746 skb_queue_tail(&l2->ui_queue, skb);
747 mISDN_FsmChangeState(fi, ST_L2_2);
748 l2_tei(l2, MDL_ASSIGN_IND, 0);
749}
750
751static void
752l2_queue_ui(struct FsmInst *fi, int event, void *arg)
753{
754 struct layer2 *l2 = fi->userdata;
755 struct sk_buff *skb = arg;
756
757 skb_queue_tail(&l2->ui_queue, skb);
758}
759
760static void
761tx_ui(struct layer2 *l2)
762{
763 struct sk_buff *skb;
764 u_char header[MAX_L2HEADER_LEN];
765 int i;
766
767 i = sethdraddr(l2, header, CMD);
768 if (test_bit(FLG_LAPD_NET, &l2->flag))
769 header[1] = 0xff; /* tei 127 */
770 header[i++] = UI;
771 while ((skb = skb_dequeue(&l2->ui_queue))) {
772 memcpy(skb_push(skb, i), header, i);
773 enqueue_ui(l2, skb);
774 }
775}
776
777static void
778l2_send_ui(struct FsmInst *fi, int event, void *arg)
779{
780 struct layer2 *l2 = fi->userdata;
781 struct sk_buff *skb = arg;
782
783 skb_queue_tail(&l2->ui_queue, skb);
784 tx_ui(l2);
785}
786
787static void
788l2_got_ui(struct FsmInst *fi, int event, void *arg)
789{
790 struct layer2 *l2 = fi->userdata;
791 struct sk_buff *skb = arg;
792
793 skb_pull(skb, l2headersize(l2, 1));
794/*
795 * in states 1-3 for broadcast
796 */
797
798 if (l2->tm)
799 l2_tei(l2, MDL_STATUS_UI_IND, 0);
800 l2up(l2, DL_UNITDATA_IND, skb);
801}
802
803static void
804l2_establish(struct FsmInst *fi, int event, void *arg)
805{
806 struct sk_buff *skb = arg;
807 struct layer2 *l2 = fi->userdata;
808
809 establishlink(fi);
810 test_and_set_bit(FLG_L3_INIT, &l2->flag);
811 dev_kfree_skb(skb);
812}
813
814static void
815l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)
816{
817 struct sk_buff *skb = arg;
818 struct layer2 *l2 = fi->userdata;
819
820 skb_queue_purge(&l2->i_queue);
821 test_and_set_bit(FLG_L3_INIT, &l2->flag);
822 test_and_clear_bit(FLG_PEND_REL, &l2->flag);
823 dev_kfree_skb(skb);
824}
825
826static void
827l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)
828{
829 struct sk_buff *skb = arg;
830 struct layer2 *l2 = fi->userdata;
831
832 skb_queue_purge(&l2->i_queue);
833 establishlink(fi);
834 test_and_set_bit(FLG_L3_INIT, &l2->flag);
835 dev_kfree_skb(skb);
836}
837
838static void
839l2_release(struct FsmInst *fi, int event, void *arg)
840{
841 struct layer2 *l2 = fi->userdata;
842 struct sk_buff *skb = arg;
843
844 skb_trim(skb, 0);
845 l2up(l2, DL_RELEASE_CNF, skb);
846}
847
848static void
849l2_pend_rel(struct FsmInst *fi, int event, void *arg)
850{
851 struct sk_buff *skb = arg;
852 struct layer2 *l2 = fi->userdata;
853
854 test_and_set_bit(FLG_PEND_REL, &l2->flag);
855 dev_kfree_skb(skb);
856}
857
858static void
859l2_disconnect(struct FsmInst *fi, int event, void *arg)
860{
861 struct layer2 *l2 = fi->userdata;
862 struct sk_buff *skb = arg;
863
864 skb_queue_purge(&l2->i_queue);
865 freewin(l2);
866 mISDN_FsmChangeState(fi, ST_L2_6);
867 l2->rc = 0;
868 send_uframe(l2, NULL, DISC | 0x10, CMD);
869 mISDN_FsmDelTimer(&l2->t203, 1);
870 restart_t200(l2, 2);
871 if (skb)
872 dev_kfree_skb(skb);
873}
874
875static void
876l2_start_multi(struct FsmInst *fi, int event, void *arg)
877{
878 struct layer2 *l2 = fi->userdata;
879 struct sk_buff *skb = arg;
880
881 l2->vs = 0;
882 l2->va = 0;
883 l2->vr = 0;
884 l2->sow = 0;
885 clear_exception(l2);
886 send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
887 mISDN_FsmChangeState(fi, ST_L2_7);
888 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
889 skb_trim(skb, 0);
890 l2up(l2, DL_ESTABLISH_IND, skb);
891 if (l2->tm)
892 l2_tei(l2, MDL_STATUS_UP_IND, 0);
893}
894
895static void
896l2_send_UA(struct FsmInst *fi, int event, void *arg)
897{
898 struct layer2 *l2 = fi->userdata;
899 struct sk_buff *skb = arg;
900
901 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
902}
903
904static void
905l2_send_DM(struct FsmInst *fi, int event, void *arg)
906{
907 struct layer2 *l2 = fi->userdata;
908 struct sk_buff *skb = arg;
909
910 send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP);
911}
912
913static void
914l2_restart_multi(struct FsmInst *fi, int event, void *arg)
915{
916 struct layer2 *l2 = fi->userdata;
917 struct sk_buff *skb = arg;
918 int est = 0;
919
920 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
921
922 l2mgr(l2, MDL_ERROR_IND, (void *) 'F');
923
924 if (l2->vs != l2->va) {
925 skb_queue_purge(&l2->i_queue);
926 est = 1;
927 }
928
929 clear_exception(l2);
930 l2->vs = 0;
931 l2->va = 0;
932 l2->vr = 0;
933 l2->sow = 0;
934 mISDN_FsmChangeState(fi, ST_L2_7);
935 stop_t200(l2, 3);
936 mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
937
938 if (est)
939 l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);
940/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
941 * MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,
942 * 0, NULL, 0);
943 */
944 if (skb_queue_len(&l2->i_queue) && cansend(l2))
945 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
946}
947
948static void
949l2_stop_multi(struct FsmInst *fi, int event, void *arg)
950{
951 struct layer2 *l2 = fi->userdata;
952 struct sk_buff *skb = arg;
953
954 mISDN_FsmChangeState(fi, ST_L2_4);
955 mISDN_FsmDelTimer(&l2->t203, 3);
956 stop_t200(l2, 4);
957
958 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
959 skb_queue_purge(&l2->i_queue);
960 freewin(l2);
961 lapb_dl_release_l2l3(l2, DL_RELEASE_IND);
962 if (l2->tm)
963 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
964}
965
966static void
967l2_connected(struct FsmInst *fi, int event, void *arg)
968{
969 struct layer2 *l2 = fi->userdata;
970 struct sk_buff *skb = arg;
971 int pr = -1;
972
973 if (!get_PollFlag(l2, skb)) {
974 l2_mdl_error_ua(fi, event, arg);
975 return;
976 }
977 dev_kfree_skb(skb);
978 if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
979 l2_disconnect(fi, event, NULL);
980 if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {
981 pr = DL_ESTABLISH_CNF;
982 } else if (l2->vs != l2->va) {
983 skb_queue_purge(&l2->i_queue);
984 pr = DL_ESTABLISH_IND;
985 }
986 stop_t200(l2, 5);
987 l2->vr = 0;
988 l2->vs = 0;
989 l2->va = 0;
990 l2->sow = 0;
991 mISDN_FsmChangeState(fi, ST_L2_7);
992 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
993 if (pr != -1)
994 l2up_create(l2, pr, 0, NULL);
995
996 if (skb_queue_len(&l2->i_queue) && cansend(l2))
997 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
998
999 if (l2->tm)
1000 l2_tei(l2, MDL_STATUS_UP_IND, 0);
1001}
1002
1003static void
1004l2_released(struct FsmInst *fi, int event, void *arg)
1005{
1006 struct layer2 *l2 = fi->userdata;
1007 struct sk_buff *skb = arg;
1008
1009 if (!get_PollFlag(l2, skb)) {
1010 l2_mdl_error_ua(fi, event, arg);
1011 return;
1012 }
1013 dev_kfree_skb(skb);
1014 stop_t200(l2, 6);
1015 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1016 mISDN_FsmChangeState(fi, ST_L2_4);
1017 if (l2->tm)
1018 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1019}
1020
1021static void
1022l2_reestablish(struct FsmInst *fi, int event, void *arg)
1023{
1024 struct layer2 *l2 = fi->userdata;
1025 struct sk_buff *skb = arg;
1026
1027 if (!get_PollFlagFree(l2, skb)) {
1028 establishlink(fi);
1029 test_and_set_bit(FLG_L3_INIT, &l2->flag);
1030 }
1031}
1032
1033static void
1034l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
1035{
1036 struct layer2 *l2 = fi->userdata;
1037 struct sk_buff *skb = arg;
1038
1039 if (get_PollFlagFree(l2, skb)) {
1040 stop_t200(l2, 7);
1041 if (!test_bit(FLG_L3_INIT, &l2->flag))
1042 skb_queue_purge(&l2->i_queue);
1043 if (test_bit(FLG_LAPB, &l2->flag))
1044 l2down_create(l2, PH_DEACTIVATE_REQ,
1045 l2_newid(l2), 0, NULL);
1046 st5_dl_release_l2l3(l2);
1047 mISDN_FsmChangeState(fi, ST_L2_4);
1048 if (l2->tm)
1049 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1050 }
1051}
1052
1053static void
1054l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
1055{
1056 struct layer2 *l2 = fi->userdata;
1057 struct sk_buff *skb = arg;
1058
1059 if (get_PollFlagFree(l2, skb)) {
1060 stop_t200(l2, 8);
1061 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1062 mISDN_FsmChangeState(fi, ST_L2_4);
1063 if (l2->tm)
1064 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1065 }
1066}
1067
1068void
1069enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
1070{
1071 struct sk_buff *skb;
1072 u_char tmp[MAX_L2HEADER_LEN];
1073 int i;
1074
1075 i = sethdraddr(l2, tmp, cr);
1076 if (test_bit(FLG_MOD128, &l2->flag)) {
1077 tmp[i++] = typ;
1078 tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0);
1079 } else
1080 tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0);
1081 skb = mI_alloc_skb(i, GFP_ATOMIC);
1082 if (!skb) {
1083 printk(KERN_WARNING
1084 "isdnl2 can't alloc sbbuff for enquiry_cr\n");
1085 return;
1086 }
1087 memcpy(skb_put(skb, i), tmp, i);
1088 enqueue_super(l2, skb);
1089}
1090
1091inline void
1092enquiry_response(struct layer2 *l2)
1093{
1094 if (test_bit(FLG_OWN_BUSY, &l2->flag))
1095 enquiry_cr(l2, RNR, RSP, 1);
1096 else
1097 enquiry_cr(l2, RR, RSP, 1);
1098 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1099}
1100
1101inline void
1102transmit_enquiry(struct layer2 *l2)
1103{
1104 if (test_bit(FLG_OWN_BUSY, &l2->flag))
1105 enquiry_cr(l2, RNR, CMD, 1);
1106 else
1107 enquiry_cr(l2, RR, CMD, 1);
1108 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1109 start_t200(l2, 9);
1110}
1111
1112
1113static void
1114nrerrorrecovery(struct FsmInst *fi)
1115{
1116 struct layer2 *l2 = fi->userdata;
1117
1118 l2mgr(l2, MDL_ERROR_IND, (void *) 'J');
1119 establishlink(fi);
1120 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1121}
1122
1123static void
1124invoke_retransmission(struct layer2 *l2, unsigned int nr)
1125{
1126 u_int p1;
1127
1128 if (l2->vs != nr) {
1129 while (l2->vs != nr) {
1130 (l2->vs)--;
1131 if (test_bit(FLG_MOD128, &l2->flag)) {
1132 l2->vs %= 128;
1133 p1 = (l2->vs - l2->va) % 128;
1134 } else {
1135 l2->vs %= 8;
1136 p1 = (l2->vs - l2->va) % 8;
1137 }
1138 p1 = (p1 + l2->sow) % l2->window;
1139 if (l2->windowar[p1])
1140 skb_queue_head(&l2->i_queue, l2->windowar[p1]);
1141 else
1142 printk(KERN_WARNING
1143 "%s: windowar[%d] is NULL\n",
1144 __func__, p1);
1145 l2->windowar[p1] = NULL;
1146 }
1147 mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
1148 }
1149}
1150
1151static void
1152l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
1153{
1154 struct layer2 *l2 = fi->userdata;
1155 struct sk_buff *skb = arg;
1156 int PollFlag, rsp, typ = RR;
1157 unsigned int nr;
1158
1159 rsp = *skb->data & 0x2;
1160 if (test_bit(FLG_ORIG, &l2->flag))
1161 rsp = !rsp;
1162
1163 skb_pull(skb, l2addrsize(l2));
1164 if (IsRNR(skb->data, l2)) {
1165 set_peer_busy(l2);
1166 typ = RNR;
1167 } else
1168 clear_peer_busy(l2);
1169 if (IsREJ(skb->data, l2))
1170 typ = REJ;
1171
1172 if (test_bit(FLG_MOD128, &l2->flag)) {
1173 PollFlag = (skb->data[1] & 0x1) == 0x1;
1174 nr = skb->data[1] >> 1;
1175 } else {
1176 PollFlag = (skb->data[0] & 0x10);
1177 nr = (skb->data[0] >> 5) & 0x7;
1178 }
1179 dev_kfree_skb(skb);
1180
1181 if (PollFlag) {
1182 if (rsp)
1183 l2mgr(l2, MDL_ERROR_IND, (void *) 'A');
1184 else
1185 enquiry_response(l2);
1186 }
1187 if (legalnr(l2, nr)) {
1188 if (typ == REJ) {
1189 setva(l2, nr);
1190 invoke_retransmission(l2, nr);
1191 stop_t200(l2, 10);
1192 if (mISDN_FsmAddTimer(&l2->t203, l2->T203,
1193 EV_L2_T203, NULL, 6))
1194 l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");
1195 } else if ((nr == l2->vs) && (typ == RR)) {
1196 setva(l2, nr);
1197 stop_t200(l2, 11);
1198 mISDN_FsmRestartTimer(&l2->t203, l2->T203,
1199 EV_L2_T203, NULL, 7);
1200 } else if ((l2->va != nr) || (typ == RNR)) {
1201 setva(l2, nr);
1202 if (typ != RR)
1203 mISDN_FsmDelTimer(&l2->t203, 9);
1204 restart_t200(l2, 12);
1205 }
1206 if (skb_queue_len(&l2->i_queue) && (typ == RR))
1207 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1208 } else
1209 nrerrorrecovery(fi);
1210}
1211
1212static void
1213l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
1214{
1215 struct layer2 *l2 = fi->userdata;
1216 struct sk_buff *skb = arg;
1217
1218 if (!test_bit(FLG_L3_INIT, &l2->flag))
1219 skb_queue_tail(&l2->i_queue, skb);
1220 else
1221 dev_kfree_skb(skb);
1222}
1223
1224static void
1225l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)
1226{
1227 struct layer2 *l2 = fi->userdata;
1228 struct sk_buff *skb = arg;
1229
1230 skb_queue_tail(&l2->i_queue, skb);
1231 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1232}
1233
1234static void
1235l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)
1236{
1237 struct layer2 *l2 = fi->userdata;
1238 struct sk_buff *skb = arg;
1239
1240 skb_queue_tail(&l2->i_queue, skb);
1241}
1242
1243static void
1244l2_got_iframe(struct FsmInst *fi, int event, void *arg)
1245{
1246 struct layer2 *l2 = fi->userdata;
1247 struct sk_buff *skb = arg;
1248 int PollFlag, i;
1249 u_int ns, nr;
1250
1251 i = l2addrsize(l2);
1252 if (test_bit(FLG_MOD128, &l2->flag)) {
1253 PollFlag = ((skb->data[i + 1] & 0x1) == 0x1);
1254 ns = skb->data[i] >> 1;
1255 nr = (skb->data[i + 1] >> 1) & 0x7f;
1256 } else {
1257 PollFlag = (skb->data[i] & 0x10);
1258 ns = (skb->data[i] >> 1) & 0x7;
1259 nr = (skb->data[i] >> 5) & 0x7;
1260 }
1261 if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
1262 dev_kfree_skb(skb);
1263 if (PollFlag)
1264 enquiry_response(l2);
1265 } else {
1266 if (l2->vr == ns) {
1267 l2->vr++;
1268 if (test_bit(FLG_MOD128, &l2->flag))
1269 l2->vr %= 128;
1270 else
1271 l2->vr %= 8;
1272 test_and_clear_bit(FLG_REJEXC, &l2->flag);
1273 if (PollFlag)
1274 enquiry_response(l2);
1275 else
1276 test_and_set_bit(FLG_ACK_PEND, &l2->flag);
1277 skb_pull(skb, l2headersize(l2, 0));
1278 l2up(l2, DL_DATA_IND, skb);
1279 } else {
1280 /* n(s)!=v(r) */
1281 dev_kfree_skb(skb);
1282 if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
1283 if (PollFlag)
1284 enquiry_response(l2);
1285 } else {
1286 enquiry_cr(l2, REJ, RSP, PollFlag);
1287 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1288 }
1289 }
1290 }
1291 if (legalnr(l2, nr)) {
1292 if (!test_bit(FLG_PEER_BUSY, &l2->flag) &&
1293 (fi->state == ST_L2_7)) {
1294 if (nr == l2->vs) {
1295 stop_t200(l2, 13);
1296 mISDN_FsmRestartTimer(&l2->t203, l2->T203,
1297 EV_L2_T203, NULL, 7);
1298 } else if (nr != l2->va)
1299 restart_t200(l2, 14);
1300 }
1301 setva(l2, nr);
1302 } else {
1303 nrerrorrecovery(fi);
1304 return;
1305 }
1306 if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7))
1307 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1308 if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag))
1309 enquiry_cr(l2, RR, RSP, 0);
1310}
1311
1312static void
1313l2_got_tei(struct FsmInst *fi, int event, void *arg)
1314{
1315 struct layer2 *l2 = fi->userdata;
1316 u_int info;
1317
1318 l2->tei = (signed char)(long)arg;
1319 set_channel_address(&l2->ch, l2->sapi, l2->tei);
1320 info = DL_INFO_L2_CONNECT;
1321 l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info);
1322 if (fi->state == ST_L2_3) {
1323 establishlink(fi);
1324 test_and_set_bit(FLG_L3_INIT, &l2->flag);
1325 } else
1326 mISDN_FsmChangeState(fi, ST_L2_4);
1327 if (skb_queue_len(&l2->ui_queue))
1328 tx_ui(l2);
1329}
1330
1331static void
1332l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
1333{
1334 struct layer2 *l2 = fi->userdata;
1335
1336 if (test_bit(FLG_LAPD, &l2->flag) &&
1337 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
1338 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1339 } else if (l2->rc == l2->N200) {
1340 mISDN_FsmChangeState(fi, ST_L2_4);
1341 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1342 skb_queue_purge(&l2->i_queue);
1343 l2mgr(l2, MDL_ERROR_IND, (void *) 'G');
1344 if (test_bit(FLG_LAPB, &l2->flag))
1345 l2down_create(l2, PH_DEACTIVATE_REQ,
1346 l2_newid(l2), 0, NULL);
1347 st5_dl_release_l2l3(l2);
1348 if (l2->tm)
1349 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1350 } else {
1351 l2->rc++;
1352 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1353 send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?
1354 SABME : SABM) | 0x10, CMD);
1355 }
1356}
1357
1358static void
1359l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
1360{
1361 struct layer2 *l2 = fi->userdata;
1362
1363 if (test_bit(FLG_LAPD, &l2->flag) &&
1364 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
1365 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1366 } else if (l2->rc == l2->N200) {
1367 mISDN_FsmChangeState(fi, ST_L2_4);
1368 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1369 l2mgr(l2, MDL_ERROR_IND, (void *) 'H');
1370 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1371 if (l2->tm)
1372 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1373 } else {
1374 l2->rc++;
1375 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,
1376 NULL, 9);
1377 send_uframe(l2, NULL, DISC | 0x10, CMD);
1378 }
1379}
1380
1381static void
1382l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
1383{
1384 struct layer2 *l2 = fi->userdata;
1385
1386 if (test_bit(FLG_LAPD, &l2->flag) &&
1387 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
1388 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1389 return;
1390 }
1391 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1392 l2->rc = 0;
1393 mISDN_FsmChangeState(fi, ST_L2_8);
1394 transmit_enquiry(l2);
1395 l2->rc++;
1396}
1397
1398static void
1399l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
1400{
1401 struct layer2 *l2 = fi->userdata;
1402
1403 if (test_bit(FLG_LAPD, &l2->flag) &&
1404 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
1405 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1406 return;
1407 }
1408 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1409 if (l2->rc == l2->N200) {
1410 l2mgr(l2, MDL_ERROR_IND, (void *) 'I');
1411 establishlink(fi);
1412 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1413 } else {
1414 transmit_enquiry(l2);
1415 l2->rc++;
1416 }
1417}
1418
1419static void
1420l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
1421{
1422 struct layer2 *l2 = fi->userdata;
1423
1424 if (test_bit(FLG_LAPD, &l2->flag) &&
1425 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
1426 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);
1427 return;
1428 }
1429 mISDN_FsmChangeState(fi, ST_L2_8);
1430 transmit_enquiry(l2);
1431 l2->rc = 0;
1432}
1433
1434static void
1435l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
1436{
1437 struct layer2 *l2 = fi->userdata;
1438 struct sk_buff *skb, *nskb, *oskb;
1439 u_char header[MAX_L2HEADER_LEN];
1440 u_int i, p1;
1441
1442 if (!cansend(l2))
1443 return;
1444
1445 skb = skb_dequeue(&l2->i_queue);
1446 if (!skb)
1447 return;
1448
1449 if (test_bit(FLG_MOD128, &l2->flag))
1450 p1 = (l2->vs - l2->va) % 128;
1451 else
1452 p1 = (l2->vs - l2->va) % 8;
1453 p1 = (p1 + l2->sow) % l2->window;
1454 if (l2->windowar[p1]) {
1455 printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n",
1456 p1);
1457 dev_kfree_skb(l2->windowar[p1]);
1458 }
1459 l2->windowar[p1] = skb;
1460 i = sethdraddr(l2, header, CMD);
1461 if (test_bit(FLG_MOD128, &l2->flag)) {
1462 header[i++] = l2->vs << 1;
1463 header[i++] = l2->vr << 1;
1464 l2->vs = (l2->vs + 1) % 128;
1465 } else {
1466 header[i++] = (l2->vr << 5) | (l2->vs << 1);
1467 l2->vs = (l2->vs + 1) % 8;
1468 }
1469
1470 nskb = skb_clone(skb, GFP_ATOMIC);
1471 p1 = skb_headroom(nskb);
1472 if (p1 >= i)
1473 memcpy(skb_push(nskb, i), header, i);
1474 else {
1475 printk(KERN_WARNING
1476 "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);
1477 oskb = nskb;
1478 nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC);
1479 if (!nskb) {
1480 dev_kfree_skb(oskb);
1481 printk(KERN_WARNING "%s: no skb mem\n", __func__);
1482 return;
1483 }
1484 memcpy(skb_put(nskb, i), header, i);
1485 memcpy(skb_put(nskb, oskb->len), oskb->data, oskb->len);
1486 dev_kfree_skb(oskb);
1487 }
1488 l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);
1489 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1490 if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {
1491 mISDN_FsmDelTimer(&l2->t203, 13);
1492 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11);
1493 }
1494}
1495
1496static void
1497l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
1498{
1499 struct layer2 *l2 = fi->userdata;
1500 struct sk_buff *skb = arg;
1501 int PollFlag, rsp, rnr = 0;
1502 unsigned int nr;
1503
1504 rsp = *skb->data & 0x2;
1505 if (test_bit(FLG_ORIG, &l2->flag))
1506 rsp = !rsp;
1507
1508 skb_pull(skb, l2addrsize(l2));
1509
1510 if (IsRNR(skb->data, l2)) {
1511 set_peer_busy(l2);
1512 rnr = 1;
1513 } else
1514 clear_peer_busy(l2);
1515
1516 if (test_bit(FLG_MOD128, &l2->flag)) {
1517 PollFlag = (skb->data[1] & 0x1) == 0x1;
1518 nr = skb->data[1] >> 1;
1519 } else {
1520 PollFlag = (skb->data[0] & 0x10);
1521 nr = (skb->data[0] >> 5) & 0x7;
1522 }
1523 dev_kfree_skb(skb);
1524 if (rsp && PollFlag) {
1525 if (legalnr(l2, nr)) {
1526 if (rnr) {
1527 restart_t200(l2, 15);
1528 } else {
1529 stop_t200(l2, 16);
1530 mISDN_FsmAddTimer(&l2->t203, l2->T203,
1531 EV_L2_T203, NULL, 5);
1532 setva(l2, nr);
1533 }
1534 invoke_retransmission(l2, nr);
1535 mISDN_FsmChangeState(fi, ST_L2_7);
1536 if (skb_queue_len(&l2->i_queue) && cansend(l2))
1537 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1538 } else
1539 nrerrorrecovery(fi);
1540 } else {
1541 if (!rsp && PollFlag)
1542 enquiry_response(l2);
1543 if (legalnr(l2, nr))
1544 setva(l2, nr);
1545 else
1546 nrerrorrecovery(fi);
1547 }
1548}
1549
1550static void
1551l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
1552{
1553 struct layer2 *l2 = fi->userdata;
1554 struct sk_buff *skb = arg;
1555
1556 skb_pull(skb, l2addrsize(l2) + 1);
1557
1558 if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */
1559 (IsUA(skb->data) && (fi->state == ST_L2_7))) {
1560 l2mgr(l2, MDL_ERROR_IND, (void *) 'K');
1561 establishlink(fi);
1562 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1563 }
1564 dev_kfree_skb(skb);
1565}
1566
1567static void
1568l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg)
1569{
1570 struct layer2 *l2 = fi->userdata;
1571
1572 skb_queue_purge(&l2->ui_queue);
1573 l2->tei = GROUP_TEI;
1574 mISDN_FsmChangeState(fi, ST_L2_1);
1575}
1576
1577static void
1578l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg)
1579{
1580 struct layer2 *l2 = fi->userdata;
1581
1582 skb_queue_purge(&l2->ui_queue);
1583 l2->tei = GROUP_TEI;
1584 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1585 mISDN_FsmChangeState(fi, ST_L2_1);
1586}
1587
1588static void
1589l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg)
1590{
1591 struct layer2 *l2 = fi->userdata;
1592
1593 skb_queue_purge(&l2->i_queue);
1594 skb_queue_purge(&l2->ui_queue);
1595 freewin(l2);
1596 l2->tei = GROUP_TEI;
1597 stop_t200(l2, 17);
1598 st5_dl_release_l2l3(l2);
1599 mISDN_FsmChangeState(fi, ST_L2_1);
1600}
1601
1602static void
1603l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg)
1604{
1605 struct layer2 *l2 = fi->userdata;
1606
1607 skb_queue_purge(&l2->ui_queue);
1608 l2->tei = GROUP_TEI;
1609 stop_t200(l2, 18);
1610 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1611 mISDN_FsmChangeState(fi, ST_L2_1);
1612}
1613
1614static void
1615l2_tei_remove(struct FsmInst *fi, int event, void *arg)
1616{
1617 struct layer2 *l2 = fi->userdata;
1618
1619 skb_queue_purge(&l2->i_queue);
1620 skb_queue_purge(&l2->ui_queue);
1621 freewin(l2);
1622 l2->tei = GROUP_TEI;
1623 stop_t200(l2, 17);
1624 mISDN_FsmDelTimer(&l2->t203, 19);
1625 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1626/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
1627 * MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED,
1628 * 0, NULL, 0);
1629 */
1630 mISDN_FsmChangeState(fi, ST_L2_1);
1631}
1632
1633static void
1634l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
1635{
1636 struct layer2 *l2 = fi->userdata;
1637 struct sk_buff *skb = arg;
1638
1639 skb_queue_purge(&l2->i_queue);
1640 skb_queue_purge(&l2->ui_queue);
1641 if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
1642 l2up(l2, DL_RELEASE_IND, skb);
1643 else
1644 dev_kfree_skb(skb);
1645}
1646
1647static void
1648l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
1649{
1650 struct layer2 *l2 = fi->userdata;
1651 struct sk_buff *skb = arg;
1652
1653 skb_queue_purge(&l2->i_queue);
1654 skb_queue_purge(&l2->ui_queue);
1655 freewin(l2);
1656 stop_t200(l2, 19);
1657 st5_dl_release_l2l3(l2);
1658 mISDN_FsmChangeState(fi, ST_L2_4);
1659 if (l2->tm)
1660 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1661 dev_kfree_skb(skb);
1662}
1663
1664static void
1665l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
1666{
1667 struct layer2 *l2 = fi->userdata;
1668 struct sk_buff *skb = arg;
1669
1670 skb_queue_purge(&l2->ui_queue);
1671 stop_t200(l2, 20);
1672 l2up(l2, DL_RELEASE_CNF, skb);
1673 mISDN_FsmChangeState(fi, ST_L2_4);
1674 if (l2->tm)
1675 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1676}
1677
1678static void
1679l2_persistant_da(struct FsmInst *fi, int event, void *arg)
1680{
1681 struct layer2 *l2 = fi->userdata;
1682 struct sk_buff *skb = arg;
1683
1684 skb_queue_purge(&l2->i_queue);
1685 skb_queue_purge(&l2->ui_queue);
1686 freewin(l2);
1687 stop_t200(l2, 19);
1688 mISDN_FsmDelTimer(&l2->t203, 19);
1689 l2up(l2, DL_RELEASE_IND, skb);
1690 mISDN_FsmChangeState(fi, ST_L2_4);
1691 if (l2->tm)
1692 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1693}
1694
1695static void
1696l2_set_own_busy(struct FsmInst *fi, int event, void *arg)
1697{
1698 struct layer2 *l2 = fi->userdata;
1699 struct sk_buff *skb = arg;
1700
1701 if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) {
1702 enquiry_cr(l2, RNR, RSP, 0);
1703 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1704 }
1705 if (skb)
1706 dev_kfree_skb(skb);
1707}
1708
1709static void
1710l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)
1711{
1712 struct layer2 *l2 = fi->userdata;
1713 struct sk_buff *skb = arg;
1714
1715 if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) {
1716 enquiry_cr(l2, RR, RSP, 0);
1717 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1718 }
1719 if (skb)
1720 dev_kfree_skb(skb);
1721}
1722
1723static void
1724l2_frame_error(struct FsmInst *fi, int event, void *arg)
1725{
1726 struct layer2 *l2 = fi->userdata;
1727
1728 l2mgr(l2, MDL_ERROR_IND, arg);
1729}
1730
1731static void
1732l2_frame_error_reest(struct FsmInst *fi, int event, void *arg)
1733{
1734 struct layer2 *l2 = fi->userdata;
1735
1736 l2mgr(l2, MDL_ERROR_IND, arg);
1737 establishlink(fi);
1738 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1739}
1740
1741static struct FsmNode L2FnList[] =
1742{
1743 {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign},
1744 {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3},
1745 {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish},
1746 {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3},
1747 {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
1748 {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
1749 {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release},
1750 {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel},
1751 {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect},
1752 {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect},
1753 {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest},
1754 {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull},
1755 {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},
1756 {ST_L2_1, EV_L2_DL_UNITDATA, l2_queue_ui_assign},
1757 {ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui},
1758 {ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui},
1759 {ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui},
1760 {ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui},
1761 {ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui},
1762 {ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui},
1763 {ST_L2_8, EV_L2_DL_UNITDATA, l2_send_ui},
1764 {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei},
1765 {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei},
1766 {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei},
1767 {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove},
1768 {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove},
1769 {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove},
1770 {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove},
1771 {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove},
1772 {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove},
1773 {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove},
1774 {ST_L2_4, EV_L2_SABME, l2_start_multi},
1775 {ST_L2_5, EV_L2_SABME, l2_send_UA},
1776 {ST_L2_6, EV_L2_SABME, l2_send_DM},
1777 {ST_L2_7, EV_L2_SABME, l2_restart_multi},
1778 {ST_L2_8, EV_L2_SABME, l2_restart_multi},
1779 {ST_L2_4, EV_L2_DISC, l2_send_DM},
1780 {ST_L2_5, EV_L2_DISC, l2_send_DM},
1781 {ST_L2_6, EV_L2_DISC, l2_send_UA},
1782 {ST_L2_7, EV_L2_DISC, l2_stop_multi},
1783 {ST_L2_8, EV_L2_DISC, l2_stop_multi},
1784 {ST_L2_4, EV_L2_UA, l2_mdl_error_ua},
1785 {ST_L2_5, EV_L2_UA, l2_connected},
1786 {ST_L2_6, EV_L2_UA, l2_released},
1787 {ST_L2_7, EV_L2_UA, l2_mdl_error_ua},
1788 {ST_L2_8, EV_L2_UA, l2_mdl_error_ua},
1789 {ST_L2_4, EV_L2_DM, l2_reestablish},
1790 {ST_L2_5, EV_L2_DM, l2_st5_dm_release},
1791 {ST_L2_6, EV_L2_DM, l2_st6_dm_release},
1792 {ST_L2_7, EV_L2_DM, l2_mdl_error_dm},
1793 {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm},
1794 {ST_L2_1, EV_L2_UI, l2_got_ui},
1795 {ST_L2_2, EV_L2_UI, l2_got_ui},
1796 {ST_L2_3, EV_L2_UI, l2_got_ui},
1797 {ST_L2_4, EV_L2_UI, l2_got_ui},
1798 {ST_L2_5, EV_L2_UI, l2_got_ui},
1799 {ST_L2_6, EV_L2_UI, l2_got_ui},
1800 {ST_L2_7, EV_L2_UI, l2_got_ui},
1801 {ST_L2_8, EV_L2_UI, l2_got_ui},
1802 {ST_L2_7, EV_L2_FRMR, l2_got_FRMR},
1803 {ST_L2_8, EV_L2_FRMR, l2_got_FRMR},
1804 {ST_L2_7, EV_L2_SUPER, l2_st7_got_super},
1805 {ST_L2_8, EV_L2_SUPER, l2_st8_got_super},
1806 {ST_L2_7, EV_L2_I, l2_got_iframe},
1807 {ST_L2_8, EV_L2_I, l2_got_iframe},
1808 {ST_L2_5, EV_L2_T200, l2_st5_tout_200},
1809 {ST_L2_6, EV_L2_T200, l2_st6_tout_200},
1810 {ST_L2_7, EV_L2_T200, l2_st7_tout_200},
1811 {ST_L2_8, EV_L2_T200, l2_st8_tout_200},
1812 {ST_L2_7, EV_L2_T203, l2_st7_tout_203},
1813 {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},
1814 {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
1815 {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
1816 {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
1817 {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
1818 {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error},
1819 {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error},
1820 {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
1821 {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
1822 {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
1823 {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da},
1824 {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
1825 {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
1826 {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da},
1827 {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da},
1828 {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da},
1829 {ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da},
1830 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
1831};
1832
1833#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
1834
1835static int
1836ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
1837{
1838 u_char *datap = skb->data;
1839 int ret = -EINVAL;
1840 int psapi, ptei;
1841 u_int l;
1842 int c = 0;
1843
1844 l = l2addrsize(l2);
1845 if (skb->len <= l) {
1846 mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
1847 return ret;
1848 }
1849 if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
1850 psapi = *datap++;
1851 ptei = *datap++;
1852 if ((psapi & 1) || !(ptei & 1)) {
1853 printk(KERN_WARNING
1854 "l2 D-channel frame wrong EA0/EA1\n");
1855 return ret;
1856 }
1857 psapi >>= 2;
1858 ptei >>= 1;
1859 if (psapi != l2->sapi) {
1860 /* not our bussiness
1861 * printk(KERN_DEBUG "%s: sapi %d/%d sapi mismatch\n",
1862 * __func__,
1863 * psapi, l2->sapi);
1864 */
1865 dev_kfree_skb(skb);
1866 return 0;
1867 }
1868 if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
1869 /* not our bussiness
1870 * printk(KERN_DEBUG "%s: tei %d/%d sapi %d mismatch\n",
1871 * __func__,
1872 * ptei, l2->tei, psapi);
1873 */
1874 dev_kfree_skb(skb);
1875 return 0;
1876 }
1877 } else
1878 datap += l;
1879 if (!(*datap & 1)) { /* I-Frame */
1880 c = iframe_error(l2, skb);
1881 if (!c)
1882 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb);
1883 } else if (IsSFrame(datap, l2)) { /* S-Frame */
1884 c = super_error(l2, skb);
1885 if (!c)
1886 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb);
1887 } else if (IsUI(datap)) {
1888 c = UI_error(l2, skb);
1889 if (!c)
1890 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
1891 } else if (IsSABME(datap, l2)) {
1892 c = unnum_error(l2, skb, CMD);
1893 if (!c)
1894 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
1895 } else if (IsUA(datap)) {
1896 c = unnum_error(l2, skb, RSP);
1897 if (!c)
1898 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb);
1899 } else if (IsDISC(datap)) {
1900 c = unnum_error(l2, skb, CMD);
1901 if (!c)
1902 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb);
1903 } else if (IsDM(datap)) {
1904 c = unnum_error(l2, skb, RSP);
1905 if (!c)
1906 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb);
1907 } else if (IsFRMR(datap)) {
1908 c = FRMR_error(l2, skb);
1909 if (!c)
1910 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb);
1911 } else
1912 c = 'L';
1913 if (c) {
1914 printk(KERN_WARNING "l2 D-channel frame error %c\n", c);
1915 mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
1916 }
1917 return ret;
1918}
1919
1920static int
1921l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
1922{
1923 struct layer2 *l2 = container_of(ch, struct layer2, ch);
1924 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1925 int ret = -EINVAL;
1926
1927 if (*debug & DEBUG_L2_RECV)
1928 printk(KERN_DEBUG "%s: prim(%x) id(%x) tei(%d)\n",
1929 __func__, hh->prim, hh->id, l2->tei);
1930 switch (hh->prim) {
1931 case PH_DATA_IND:
1932 ret = ph_data_indication(l2, hh, skb);
1933 break;
1934 case PH_DATA_CNF:
1935 ret = ph_data_confirm(l2, hh, skb);
1936 break;
1937 case PH_ACTIVATE_IND:
1938 test_and_set_bit(FLG_L1_ACTIV, &l2->flag);
1939 l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);
1940 if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
1941 ret = mISDN_FsmEvent(&l2->l2m,
1942 EV_L2_DL_ESTABLISH_REQ, skb);
1943 break;
1944 case PH_DEACTIVATE_IND:
1945 test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);
1946 l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL);
1947 ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb);
1948 break;
1949 case MPH_INFORMATION_IND:
1950 if (!l2->up)
1951 break;
1952 ret = l2->up->send(l2->up, skb);
1953 break;
1954 case DL_DATA_REQ:
1955 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);
1956 break;
1957 case DL_UNITDATA_REQ:
1958 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb);
1959 break;
1960 case DL_ESTABLISH_REQ:
1961 if (test_bit(FLG_LAPB, &l2->flag))
1962 test_and_set_bit(FLG_ORIG, &l2->flag);
1963 if (test_bit(FLG_L1_ACTIV, &l2->flag)) {
1964 if (test_bit(FLG_LAPD, &l2->flag) ||
1965 test_bit(FLG_ORIG, &l2->flag))
1966 ret = mISDN_FsmEvent(&l2->l2m,
1967 EV_L2_DL_ESTABLISH_REQ, skb);
1968 } else {
1969 if (test_bit(FLG_LAPD, &l2->flag) ||
1970 test_bit(FLG_ORIG, &l2->flag)) {
1971 test_and_set_bit(FLG_ESTAB_PEND,
1972 &l2->flag);
1973 }
1974 ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),
1975 skb);
1976 }
1977 break;
1978 case DL_RELEASE_REQ:
1979 if (test_bit(FLG_LAPB, &l2->flag))
1980 l2down_create(l2, PH_DEACTIVATE_REQ,
1981 l2_newid(l2), 0, NULL);
1982 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,
1983 skb);
1984 break;
1985 default:
1986 if (*debug & DEBUG_L2)
1987 l2m_debug(&l2->l2m, "l2 unknown pr %04x",
1988 hh->prim);
1989 }
1990 if (ret) {
1991 dev_kfree_skb(skb);
1992 ret = 0;
1993 }
1994 return ret;
1995}
1996
1997int
1998tei_l2(struct layer2 *l2, u_int cmd, u_long arg)
1999{
2000 int ret = -EINVAL;
2001
2002 if (*debug & DEBUG_L2_TEI)
2003 printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd);
2004 switch (cmd) {
2005 case (MDL_ASSIGN_REQ):
2006 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg);
2007 break;
2008 case (MDL_REMOVE_REQ):
2009 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL);
2010 break;
2011 case (MDL_ERROR_IND):
2012 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
2013 break;
2014 case (MDL_ERROR_RSP):
2015 /* ETS 300-125 5.3.2.1 Test: TC13010 */
2016 printk(KERN_NOTICE "MDL_ERROR|REQ (tei_l2)\n");
2017 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
2018 break;
2019 }
2020 return ret;
2021}
2022
2023static void
2024release_l2(struct layer2 *l2)
2025{
2026 mISDN_FsmDelTimer(&l2->t200, 21);
2027 mISDN_FsmDelTimer(&l2->t203, 16);
2028 skb_queue_purge(&l2->i_queue);
2029 skb_queue_purge(&l2->ui_queue);
2030 skb_queue_purge(&l2->down_queue);
2031 ReleaseWin(l2);
2032 if (test_bit(FLG_LAPD, &l2->flag)) {
2033 release_tei(l2);
2034 if (l2->ch.st)
2035 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,
2036 CLOSE_CHANNEL, NULL);
2037 }
2038 kfree(l2);
2039}
2040
2041static int
2042l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
2043{
2044 struct layer2 *l2 = container_of(ch, struct layer2, ch);
2045 u_int info;
2046
2047 if (*debug & DEBUG_L2_CTRL)
2048 printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
2049
2050 switch (cmd) {
2051 case OPEN_CHANNEL:
2052 if (test_bit(FLG_LAPD, &l2->flag)) {
2053 set_channel_address(&l2->ch, l2->sapi, l2->tei);
2054 info = DL_INFO_L2_CONNECT;
2055 l2up_create(l2, DL_INFORMATION_IND,
2056 sizeof(info), &info);
2057 }
2058 break;
2059 case CLOSE_CHANNEL:
2060 if (l2->ch.peer)
2061 l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL);
2062 release_l2(l2);
2063 break;
2064 }
2065 return 0;
2066}
2067
2068struct layer2 *
2069create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
2070{
2071 struct layer2 *l2;
2072 struct channel_req rq;
2073
2074 l2 = kzalloc(sizeof(struct layer2), GFP_KERNEL);
2075 if (!l2) {
2076 printk(KERN_ERR "kzalloc layer2 failed\n");
2077 return NULL;
2078 }
2079 l2->next_id = 1;
2080 l2->down_id = MISDN_ID_NONE;
2081 l2->up = ch;
2082 l2->ch.st = ch->st;
2083 l2->ch.send = l2_send;
2084 l2->ch.ctrl = l2_ctrl;
2085 switch (protocol) {
2086 case ISDN_P_LAPD_NT:
2087 test_and_set_bit(FLG_LAPD, &l2->flag);
2088 test_and_set_bit(FLG_LAPD_NET, &l2->flag);
2089 test_and_set_bit(FLG_MOD128, &l2->flag);
2090 l2->sapi = 0;
2091 l2->maxlen = MAX_DFRAME_LEN;
2092 if (test_bit(OPTION_L2_PMX, &options))
2093 l2->window = 7;
2094 else
2095 l2->window = 1;
2096 if (test_bit(OPTION_L2_PTP, &options))
2097 test_and_set_bit(FLG_PTP, &l2->flag);
2098 if (test_bit(OPTION_L2_FIXEDTEI, &options))
2099 test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
2100 l2->tei = (u_int)arg;
2101 l2->T200 = 1000;
2102 l2->N200 = 3;
2103 l2->T203 = 10000;
2104 if (test_bit(OPTION_L2_PMX, &options))
2105 rq.protocol = ISDN_P_NT_E1;
2106 else
2107 rq.protocol = ISDN_P_NT_S0;
2108 rq.adr.channel = 0;
2109 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
2110 break;
2111 case ISDN_P_LAPD_TE:
2112 test_and_set_bit(FLG_LAPD, &l2->flag);
2113 test_and_set_bit(FLG_MOD128, &l2->flag);
2114 test_and_set_bit(FLG_ORIG, &l2->flag);
2115 l2->sapi = 0;
2116 l2->maxlen = MAX_DFRAME_LEN;
2117 if (test_bit(OPTION_L2_PMX, &options))
2118 l2->window = 7;
2119 else
2120 l2->window = 1;
2121 if (test_bit(OPTION_L2_PTP, &options))
2122 test_and_set_bit(FLG_PTP, &l2->flag);
2123 if (test_bit(OPTION_L2_FIXEDTEI, &options))
2124 test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
2125 l2->tei = (u_int)arg;
2126 l2->T200 = 1000;
2127 l2->N200 = 3;
2128 l2->T203 = 10000;
2129 if (test_bit(OPTION_L2_PMX, &options))
2130 rq.protocol = ISDN_P_TE_E1;
2131 else
2132 rq.protocol = ISDN_P_TE_S0;
2133 rq.adr.channel = 0;
2134 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
2135 break;
2136 case ISDN_P_B_X75SLP:
2137 test_and_set_bit(FLG_LAPB, &l2->flag);
2138 l2->window = 7;
2139 l2->maxlen = MAX_DATA_SIZE;
2140 l2->T200 = 1000;
2141 l2->N200 = 4;
2142 l2->T203 = 5000;
2143 l2->addr.A = 3;
2144 l2->addr.B = 1;
2145 break;
2146 default:
2147 printk(KERN_ERR "layer2 create failed prt %x\n",
2148 protocol);
2149 kfree(l2);
2150 return NULL;
2151 }
2152 skb_queue_head_init(&l2->i_queue);
2153 skb_queue_head_init(&l2->ui_queue);
2154 skb_queue_head_init(&l2->down_queue);
2155 skb_queue_head_init(&l2->tmp_queue);
2156 InitWin(l2);
2157 l2->l2m.fsm = &l2fsm;
2158 if (test_bit(FLG_LAPB, &l2->flag) ||
2159 test_bit(FLG_PTP, &l2->flag) ||
2160 test_bit(FLG_LAPD_NET, &l2->flag))
2161 l2->l2m.state = ST_L2_4;
2162 else
2163 l2->l2m.state = ST_L2_1;
2164 l2->l2m.debug = *debug;
2165 l2->l2m.userdata = l2;
2166 l2->l2m.userint = 0;
2167 l2->l2m.printdebug = l2m_debug;
2168
2169 mISDN_FsmInitTimer(&l2->l2m, &l2->t200);
2170 mISDN_FsmInitTimer(&l2->l2m, &l2->t203);
2171 return l2;
2172}
2173
2174static int
2175x75create(struct channel_req *crq)
2176{
2177 struct layer2 *l2;
2178
2179 if (crq->protocol != ISDN_P_B_X75SLP)
2180 return -EPROTONOSUPPORT;
2181 l2 = create_l2(crq->ch, crq->protocol, 0, 0);
2182 if (!l2)
2183 return -ENOMEM;
2184 crq->ch = &l2->ch;
2185 crq->protocol = ISDN_P_B_HDLC;
2186 return 0;
2187}
2188
2189static struct Bprotocol X75SLP = {
2190 .Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)),
2191 .name = "X75SLP",
2192 .create = x75create
2193};
2194
2195int
2196Isdnl2_Init(u_int *deb)
2197{
2198 debug = deb;
2199 mISDN_register_Bprotocol(&X75SLP);
2200 l2fsm.state_count = L2_STATE_COUNT;
2201 l2fsm.event_count = L2_EVENT_COUNT;
2202 l2fsm.strEvent = strL2Event;
2203 l2fsm.strState = strL2State;
2204 mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
2205 TEIInit(deb);
2206 return 0;
2207}
2208
2209void
2210Isdnl2_cleanup(void)
2211{
2212 mISDN_unregister_Bprotocol(&X75SLP);
2213 TEIFree();
2214 mISDN_FsmFree(&l2fsm);
2215}
2216
diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h
new file mode 100644
index 000000000000..de2dd02056a3
--- /dev/null
+++ b/drivers/isdn/mISDN/layer2.h
@@ -0,0 +1,140 @@
1/*
2 * Layer 2 defines
3 *
4 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/mISDNif.h>
18#include <linux/skbuff.h>
19#include "fsm.h"
20
21#define MAX_WINDOW 8
22
23struct manager {
24 struct mISDNchannel ch;
25 struct mISDNchannel bcast;
26 u_long options;
27 struct list_head layer2;
28 rwlock_t lock;
29 struct FsmInst deact;
30 struct FsmTimer datimer;
31 struct sk_buff_head sendq;
32 struct mISDNchannel *up;
33 u_int nextid;
34 u_int lastid;
35};
36
37struct teimgr {
38 int ri;
39 int rcnt;
40 struct FsmInst tei_m;
41 struct FsmTimer timer;
42 int tval, nval;
43 struct layer2 *l2;
44 struct manager *mgr;
45};
46
47struct laddr {
48 u_char A;
49 u_char B;
50};
51
52struct layer2 {
53 struct list_head list;
54 struct mISDNchannel ch;
55 u_long flag;
56 int id;
57 struct mISDNchannel *up;
58 signed char sapi;
59 signed char tei;
60 struct laddr addr;
61 u_int maxlen;
62 struct teimgr *tm;
63 u_int vs, va, vr;
64 int rc;
65 u_int window;
66 u_int sow;
67 struct FsmInst l2m;
68 struct FsmTimer t200, t203;
69 int T200, N200, T203;
70 u_int next_id;
71 u_int down_id;
72 struct sk_buff *windowar[MAX_WINDOW];
73 struct sk_buff_head i_queue;
74 struct sk_buff_head ui_queue;
75 struct sk_buff_head down_queue;
76 struct sk_buff_head tmp_queue;
77};
78
79enum {
80 ST_L2_1,
81 ST_L2_2,
82 ST_L2_3,
83 ST_L2_4,
84 ST_L2_5,
85 ST_L2_6,
86 ST_L2_7,
87 ST_L2_8,
88};
89
90#define L2_STATE_COUNT (ST_L2_8+1)
91
92extern struct layer2 *create_l2(struct mISDNchannel *, u_int,
93 u_long, u_long);
94extern int tei_l2(struct layer2 *, u_int, u_long arg);
95
96
97/* from tei.c */
98extern int l2_tei(struct layer2 *, u_int, u_long arg);
99extern void release_tei(struct layer2 *);
100extern int TEIInit(u_int *);
101extern void TEIFree(void);
102
103#define MAX_L2HEADER_LEN 4
104
105#define RR 0x01
106#define RNR 0x05
107#define REJ 0x09
108#define SABME 0x6f
109#define SABM 0x2f
110#define DM 0x0f
111#define UI 0x03
112#define DISC 0x43
113#define UA 0x63
114#define FRMR 0x87
115#define XID 0xaf
116
117#define CMD 0
118#define RSP 1
119
120#define LC_FLUSH_WAIT 1
121
122#define FLG_LAPB 0
123#define FLG_LAPD 1
124#define FLG_ORIG 2
125#define FLG_MOD128 3
126#define FLG_PEND_REL 4
127#define FLG_L3_INIT 5
128#define FLG_T200_RUN 6
129#define FLG_ACK_PEND 7
130#define FLG_REJEXC 8
131#define FLG_OWN_BUSY 9
132#define FLG_PEER_BUSY 10
133#define FLG_DCHAN_BUSY 11
134#define FLG_L1_ACTIV 12
135#define FLG_ESTAB_PEND 13
136#define FLG_PTP 14
137#define FLG_FIXED_TEI 15
138#define FLG_L2BLOCK 16
139#define FLG_L1_NOTREADY 17
140#define FLG_LAPD_NET 18
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
new file mode 100644
index 000000000000..4ba4cc364c9e
--- /dev/null
+++ b/drivers/isdn/mISDN/socket.c
@@ -0,0 +1,781 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/mISDNif.h>
19#include "core.h"
20
21static int *debug;
22
23static struct proto mISDN_proto = {
24 .name = "misdn",
25 .owner = THIS_MODULE,
26 .obj_size = sizeof(struct mISDN_sock)
27};
28
29#define _pms(sk) ((struct mISDN_sock *)sk)
30
31static struct mISDN_sock_list data_sockets = {
32 .lock = __RW_LOCK_UNLOCKED(data_sockets.lock)
33};
34
35static struct mISDN_sock_list base_sockets = {
36 .lock = __RW_LOCK_UNLOCKED(base_sockets.lock)
37};
38
39#define L2_HEADER_LEN 4
40
41static inline struct sk_buff *
42_l2_alloc_skb(unsigned int len, gfp_t gfp_mask)
43{
44 struct sk_buff *skb;
45
46 skb = alloc_skb(len + L2_HEADER_LEN, gfp_mask);
47 if (likely(skb))
48 skb_reserve(skb, L2_HEADER_LEN);
49 return skb;
50}
51
52static void
53mISDN_sock_link(struct mISDN_sock_list *l, struct sock *sk)
54{
55 write_lock_bh(&l->lock);
56 sk_add_node(sk, &l->head);
57 write_unlock_bh(&l->lock);
58}
59
60static void mISDN_sock_unlink(struct mISDN_sock_list *l, struct sock *sk)
61{
62 write_lock_bh(&l->lock);
63 sk_del_node_init(sk);
64 write_unlock_bh(&l->lock);
65}
66
67static int
68mISDN_send(struct mISDNchannel *ch, struct sk_buff *skb)
69{
70 struct mISDN_sock *msk;
71 int err;
72
73 msk = container_of(ch, struct mISDN_sock, ch);
74 if (*debug & DEBUG_SOCKET)
75 printk(KERN_DEBUG "%s len %d %p\n", __func__, skb->len, skb);
76 if (msk->sk.sk_state == MISDN_CLOSED)
77 return -EUNATCH;
78 __net_timestamp(skb);
79 err = sock_queue_rcv_skb(&msk->sk, skb);
80 if (err)
81 printk(KERN_WARNING "%s: error %d\n", __func__, err);
82 return err;
83}
84
85static int
86mISDN_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
87{
88 struct mISDN_sock *msk;
89
90 msk = container_of(ch, struct mISDN_sock, ch);
91 if (*debug & DEBUG_SOCKET)
92 printk(KERN_DEBUG "%s(%p, %x, %p)\n", __func__, ch, cmd, arg);
93 switch (cmd) {
94 case CLOSE_CHANNEL:
95 msk->sk.sk_state = MISDN_CLOSED;
96 break;
97 }
98 return 0;
99}
100
101static inline void
102mISDN_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
103{
104 struct timeval tv;
105
106 if (_pms(sk)->cmask & MISDN_TIME_STAMP) {
107 skb_get_timestamp(skb, &tv);
108 put_cmsg(msg, SOL_MISDN, MISDN_TIME_STAMP, sizeof(tv), &tv);
109 }
110}
111
112static int
113mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
114 struct msghdr *msg, size_t len, int flags)
115{
116 struct sk_buff *skb;
117 struct sock *sk = sock->sk;
118 struct sockaddr_mISDN *maddr;
119
120 int copied, err;
121
122 if (*debug & DEBUG_SOCKET)
123 printk(KERN_DEBUG "%s: len %d, flags %x ch.nr %d, proto %x\n",
124 __func__, (int)len, flags, _pms(sk)->ch.nr,
125 sk->sk_protocol);
126 if (flags & (MSG_OOB))
127 return -EOPNOTSUPP;
128
129 if (sk->sk_state == MISDN_CLOSED)
130 return 0;
131
132 skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
133 if (!skb)
134 return err;
135
136 if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
137 msg->msg_namelen = sizeof(struct sockaddr_mISDN);
138 maddr = (struct sockaddr_mISDN *)msg->msg_name;
139 maddr->family = AF_ISDN;
140 maddr->dev = _pms(sk)->dev->id;
141 if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
142 (sk->sk_protocol == ISDN_P_LAPD_NT)) {
143 maddr->channel = (mISDN_HEAD_ID(skb) >> 16) & 0xff;
144 maddr->tei = (mISDN_HEAD_ID(skb) >> 8) & 0xff;
145 maddr->sapi = mISDN_HEAD_ID(skb) & 0xff;
146 } else {
147 maddr->channel = _pms(sk)->ch.nr;
148 maddr->sapi = _pms(sk)->ch.addr & 0xFF;
149 maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
150 }
151 } else {
152 if (msg->msg_namelen)
153 printk(KERN_WARNING "%s: too small namelen %d\n",
154 __func__, msg->msg_namelen);
155 msg->msg_namelen = 0;
156 }
157
158 copied = skb->len + MISDN_HEADER_LEN;
159 if (len < copied) {
160 if (flags & MSG_PEEK)
161 atomic_dec(&skb->users);
162 else
163 skb_queue_head(&sk->sk_receive_queue, skb);
164 return -ENOSPC;
165 }
166 memcpy(skb_push(skb, MISDN_HEADER_LEN), mISDN_HEAD_P(skb),
167 MISDN_HEADER_LEN);
168
169 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
170
171 mISDN_sock_cmsg(sk, msg, skb);
172
173 skb_free_datagram(sk, skb);
174
175 return err ? : copied;
176}
177
178static int
179mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
180 struct msghdr *msg, size_t len)
181{
182 struct sock *sk = sock->sk;
183 struct sk_buff *skb;
184 int err = -ENOMEM;
185 struct sockaddr_mISDN *maddr;
186
187 if (*debug & DEBUG_SOCKET)
188 printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
189 __func__, (int)len, msg->msg_flags, _pms(sk)->ch.nr,
190 sk->sk_protocol);
191
192 if (msg->msg_flags & MSG_OOB)
193 return -EOPNOTSUPP;
194
195 if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
196 return -EINVAL;
197
198 if (len < MISDN_HEADER_LEN)
199 return -EINVAL;
200
201 if (sk->sk_state != MISDN_BOUND)
202 return -EBADFD;
203
204 lock_sock(sk);
205
206 skb = _l2_alloc_skb(len, GFP_KERNEL);
207 if (!skb)
208 goto done;
209
210 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
211 err = -EFAULT;
212 goto drop;
213 }
214
215 memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
216 skb_pull(skb, MISDN_HEADER_LEN);
217
218 if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
219 /* if we have a address, we use it */
220 maddr = (struct sockaddr_mISDN *)msg->msg_name;
221 mISDN_HEAD_ID(skb) = maddr->channel;
222 } else { /* use default for L2 messages */
223 if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
224 (sk->sk_protocol == ISDN_P_LAPD_NT))
225 mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
226 }
227
228 if (*debug & DEBUG_SOCKET)
229 printk(KERN_DEBUG "%s: ID:%x\n",
230 __func__, mISDN_HEAD_ID(skb));
231
232 err = -ENODEV;
233 if (!_pms(sk)->ch.peer ||
234 (err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb)))
235 goto drop;
236
237 err = len;
238
239done:
240 release_sock(sk);
241 return err;
242
243drop:
244 kfree_skb(skb);
245 goto done;
246}
247
248static int
249data_sock_release(struct socket *sock)
250{
251 struct sock *sk = sock->sk;
252
253 if (*debug & DEBUG_SOCKET)
254 printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
255 if (!sk)
256 return 0;
257 switch (sk->sk_protocol) {
258 case ISDN_P_TE_S0:
259 case ISDN_P_NT_S0:
260 case ISDN_P_TE_E1:
261 case ISDN_P_NT_E1:
262 if (sk->sk_state == MISDN_BOUND)
263 delete_channel(&_pms(sk)->ch);
264 else
265 mISDN_sock_unlink(&data_sockets, sk);
266 break;
267 case ISDN_P_LAPD_TE:
268 case ISDN_P_LAPD_NT:
269 case ISDN_P_B_RAW:
270 case ISDN_P_B_HDLC:
271 case ISDN_P_B_X75SLP:
272 case ISDN_P_B_L2DTMF:
273 case ISDN_P_B_L2DSP:
274 case ISDN_P_B_L2DSPHDLC:
275 delete_channel(&_pms(sk)->ch);
276 mISDN_sock_unlink(&data_sockets, sk);
277 break;
278 }
279
280 lock_sock(sk);
281
282 sock_orphan(sk);
283 skb_queue_purge(&sk->sk_receive_queue);
284
285 release_sock(sk);
286 sock_put(sk);
287
288 return 0;
289}
290
291static int
292data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
293{
294 struct mISDN_ctrl_req cq;
295 int err = -EINVAL, val;
296 struct mISDNchannel *bchan, *next;
297
298 lock_sock(sk);
299 if (!_pms(sk)->dev) {
300 err = -ENODEV;
301 goto done;
302 }
303 switch (cmd) {
304 case IMCTRLREQ:
305 if (copy_from_user(&cq, p, sizeof(cq))) {
306 err = -EFAULT;
307 break;
308 }
309 if ((sk->sk_protocol & ~ISDN_P_B_MASK) == ISDN_P_B_START) {
310 list_for_each_entry_safe(bchan, next,
311 &_pms(sk)->dev->bchannels, list) {
312 if (bchan->nr == cq.channel) {
313 err = bchan->ctrl(bchan,
314 CONTROL_CHANNEL, &cq);
315 break;
316 }
317 }
318 } else
319 err = _pms(sk)->dev->D.ctrl(&_pms(sk)->dev->D,
320 CONTROL_CHANNEL, &cq);
321 if (err)
322 break;
323 if (copy_to_user(p, &cq, sizeof(cq)))
324 err = -EFAULT;
325 break;
326 case IMCLEAR_L2:
327 if (sk->sk_protocol != ISDN_P_LAPD_NT) {
328 err = -EINVAL;
329 break;
330 }
331 if (get_user(val, (int __user *)p)) {
332 err = -EFAULT;
333 break;
334 }
335 err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
336 CONTROL_CHANNEL, &val);
337 break;
338 default:
339 err = -EINVAL;
340 break;
341 }
342done:
343 release_sock(sk);
344 return err;
345}
346
347static int
348data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
349{
350 int err = 0, id;
351 struct sock *sk = sock->sk;
352 struct mISDNdevice *dev;
353 struct mISDNversion ver;
354
355 switch (cmd) {
356 case IMGETVERSION:
357 ver.major = MISDN_MAJOR_VERSION;
358 ver.minor = MISDN_MINOR_VERSION;
359 ver.release = MISDN_RELEASE;
360 if (copy_to_user((void __user *)arg, &ver, sizeof(ver)))
361 err = -EFAULT;
362 break;
363 case IMGETCOUNT:
364 id = get_mdevice_count();
365 if (put_user(id, (int __user *)arg))
366 err = -EFAULT;
367 break;
368 case IMGETDEVINFO:
369 if (get_user(id, (int __user *)arg)) {
370 err = -EFAULT;
371 break;
372 }
373 dev = get_mdevice(id);
374 if (dev) {
375 struct mISDN_devinfo di;
376
377 di.id = dev->id;
378 di.Dprotocols = dev->Dprotocols;
379 di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
380 di.protocol = dev->D.protocol;
381 memcpy(di.channelmap, dev->channelmap,
382 MISDN_CHMAP_SIZE * 4);
383 di.nrbchan = dev->nrbchan;
384 strcpy(di.name, dev->name);
385 if (copy_to_user((void __user *)arg, &di, sizeof(di)))
386 err = -EFAULT;
387 } else
388 err = -ENODEV;
389 break;
390 default:
391 if (sk->sk_state == MISDN_BOUND)
392 err = data_sock_ioctl_bound(sk, cmd,
393 (void __user *)arg);
394 else
395 err = -ENOTCONN;
396 }
397 return err;
398}
399
400static int data_sock_setsockopt(struct socket *sock, int level, int optname,
401 char __user *optval, int len)
402{
403 struct sock *sk = sock->sk;
404 int err = 0, opt = 0;
405
406 if (*debug & DEBUG_SOCKET)
407 printk(KERN_DEBUG "%s(%p, %d, %x, %p, %d)\n", __func__, sock,
408 level, optname, optval, len);
409
410 lock_sock(sk);
411
412 switch (optname) {
413 case MISDN_TIME_STAMP:
414 if (get_user(opt, (int __user *)optval)) {
415 err = -EFAULT;
416 break;
417 }
418
419 if (opt)
420 _pms(sk)->cmask |= MISDN_TIME_STAMP;
421 else
422 _pms(sk)->cmask &= ~MISDN_TIME_STAMP;
423 break;
424 default:
425 err = -ENOPROTOOPT;
426 break;
427 }
428 release_sock(sk);
429 return err;
430}
431
432static int data_sock_getsockopt(struct socket *sock, int level, int optname,
433 char __user *optval, int __user *optlen)
434{
435 struct sock *sk = sock->sk;
436 int len, opt;
437
438 if (get_user(len, optlen))
439 return -EFAULT;
440
441 switch (optname) {
442 case MISDN_TIME_STAMP:
443 if (_pms(sk)->cmask & MISDN_TIME_STAMP)
444 opt = 1;
445 else
446 opt = 0;
447
448 if (put_user(opt, optval))
449 return -EFAULT;
450 break;
451 default:
452 return -ENOPROTOOPT;
453 }
454
455 return 0;
456}
457
458static int
459data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
460{
461 struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
462 struct sock *sk = sock->sk;
463 int err = 0;
464
465 if (*debug & DEBUG_SOCKET)
466 printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
467 if (addr_len != sizeof(struct sockaddr_mISDN))
468 return -EINVAL;
469 if (!maddr || maddr->family != AF_ISDN)
470 return -EINVAL;
471
472 lock_sock(sk);
473
474 if (_pms(sk)->dev) {
475 err = -EALREADY;
476 goto done;
477 }
478 _pms(sk)->dev = get_mdevice(maddr->dev);
479 if (!_pms(sk)->dev) {
480 err = -ENODEV;
481 goto done;
482 }
483 _pms(sk)->ch.send = mISDN_send;
484 _pms(sk)->ch.ctrl = mISDN_ctrl;
485
486 switch (sk->sk_protocol) {
487 case ISDN_P_TE_S0:
488 case ISDN_P_NT_S0:
489 case ISDN_P_TE_E1:
490 case ISDN_P_NT_E1:
491 mISDN_sock_unlink(&data_sockets, sk);
492 err = connect_layer1(_pms(sk)->dev, &_pms(sk)->ch,
493 sk->sk_protocol, maddr);
494 if (err)
495 mISDN_sock_link(&data_sockets, sk);
496 break;
497 case ISDN_P_LAPD_TE:
498 case ISDN_P_LAPD_NT:
499 err = create_l2entity(_pms(sk)->dev, &_pms(sk)->ch,
500 sk->sk_protocol, maddr);
501 break;
502 case ISDN_P_B_RAW:
503 case ISDN_P_B_HDLC:
504 case ISDN_P_B_X75SLP:
505 case ISDN_P_B_L2DTMF:
506 case ISDN_P_B_L2DSP:
507 case ISDN_P_B_L2DSPHDLC:
508 err = connect_Bstack(_pms(sk)->dev, &_pms(sk)->ch,
509 sk->sk_protocol, maddr);
510 break;
511 default:
512 err = -EPROTONOSUPPORT;
513 }
514 if (err)
515 goto done;
516 sk->sk_state = MISDN_BOUND;
517 _pms(sk)->ch.protocol = sk->sk_protocol;
518
519done:
520 release_sock(sk);
521 return err;
522}
523
524static int
525data_sock_getname(struct socket *sock, struct sockaddr *addr,
526 int *addr_len, int peer)
527{
528 struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
529 struct sock *sk = sock->sk;
530
531 if (!_pms(sk)->dev)
532 return -EBADFD;
533
534 lock_sock(sk);
535
536 *addr_len = sizeof(*maddr);
537 maddr->dev = _pms(sk)->dev->id;
538 maddr->channel = _pms(sk)->ch.nr;
539 maddr->sapi = _pms(sk)->ch.addr & 0xff;
540 maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xff;
541 release_sock(sk);
542 return 0;
543}
544
545static const struct proto_ops data_sock_ops = {
546 .family = PF_ISDN,
547 .owner = THIS_MODULE,
548 .release = data_sock_release,
549 .ioctl = data_sock_ioctl,
550 .bind = data_sock_bind,
551 .getname = data_sock_getname,
552 .sendmsg = mISDN_sock_sendmsg,
553 .recvmsg = mISDN_sock_recvmsg,
554 .poll = datagram_poll,
555 .listen = sock_no_listen,
556 .shutdown = sock_no_shutdown,
557 .setsockopt = data_sock_setsockopt,
558 .getsockopt = data_sock_getsockopt,
559 .connect = sock_no_connect,
560 .socketpair = sock_no_socketpair,
561 .accept = sock_no_accept,
562 .mmap = sock_no_mmap
563};
564
565static int
566data_sock_create(struct net *net, struct socket *sock, int protocol)
567{
568 struct sock *sk;
569
570 if (sock->type != SOCK_DGRAM)
571 return -ESOCKTNOSUPPORT;
572
573 sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto);
574 if (!sk)
575 return -ENOMEM;
576
577 sock_init_data(sock, sk);
578
579 sock->ops = &data_sock_ops;
580 sock->state = SS_UNCONNECTED;
581 sock_reset_flag(sk, SOCK_ZAPPED);
582
583 sk->sk_protocol = protocol;
584 sk->sk_state = MISDN_OPEN;
585 mISDN_sock_link(&data_sockets, sk);
586
587 return 0;
588}
589
590static int
591base_sock_release(struct socket *sock)
592{
593 struct sock *sk = sock->sk;
594
595 printk(KERN_DEBUG "%s(%p) sk=%p\n", __func__, sock, sk);
596 if (!sk)
597 return 0;
598
599 mISDN_sock_unlink(&base_sockets, sk);
600 sock_orphan(sk);
601 sock_put(sk);
602
603 return 0;
604}
605
606static int
607base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
608{
609 int err = 0, id;
610 struct mISDNdevice *dev;
611 struct mISDNversion ver;
612
613 switch (cmd) {
614 case IMGETVERSION:
615 ver.major = MISDN_MAJOR_VERSION;
616 ver.minor = MISDN_MINOR_VERSION;
617 ver.release = MISDN_RELEASE;
618 if (copy_to_user((void __user *)arg, &ver, sizeof(ver)))
619 err = -EFAULT;
620 break;
621 case IMGETCOUNT:
622 id = get_mdevice_count();
623 if (put_user(id, (int __user *)arg))
624 err = -EFAULT;
625 break;
626 case IMGETDEVINFO:
627 if (get_user(id, (int __user *)arg)) {
628 err = -EFAULT;
629 break;
630 }
631 dev = get_mdevice(id);
632 if (dev) {
633 struct mISDN_devinfo di;
634
635 di.id = dev->id;
636 di.Dprotocols = dev->Dprotocols;
637 di.Bprotocols = dev->Bprotocols | get_all_Bprotocols();
638 di.protocol = dev->D.protocol;
639 memcpy(di.channelmap, dev->channelmap,
640 MISDN_CHMAP_SIZE * 4);
641 di.nrbchan = dev->nrbchan;
642 strcpy(di.name, dev->name);
643 if (copy_to_user((void __user *)arg, &di, sizeof(di)))
644 err = -EFAULT;
645 } else
646 err = -ENODEV;
647 break;
648 default:
649 err = -EINVAL;
650 }
651 return err;
652}
653
654static int
655base_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
656{
657 struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
658 struct sock *sk = sock->sk;
659 int err = 0;
660
661 if (!maddr || maddr->family != AF_ISDN)
662 return -EINVAL;
663
664 lock_sock(sk);
665
666 if (_pms(sk)->dev) {
667 err = -EALREADY;
668 goto done;
669 }
670
671 _pms(sk)->dev = get_mdevice(maddr->dev);
672 if (!_pms(sk)->dev) {
673 err = -ENODEV;
674 goto done;
675 }
676 sk->sk_state = MISDN_BOUND;
677
678done:
679 release_sock(sk);
680 return err;
681}
682
683static const struct proto_ops base_sock_ops = {
684 .family = PF_ISDN,
685 .owner = THIS_MODULE,
686 .release = base_sock_release,
687 .ioctl = base_sock_ioctl,
688 .bind = base_sock_bind,
689 .getname = sock_no_getname,
690 .sendmsg = sock_no_sendmsg,
691 .recvmsg = sock_no_recvmsg,
692 .poll = sock_no_poll,
693 .listen = sock_no_listen,
694 .shutdown = sock_no_shutdown,
695 .setsockopt = sock_no_setsockopt,
696 .getsockopt = sock_no_getsockopt,
697 .connect = sock_no_connect,
698 .socketpair = sock_no_socketpair,
699 .accept = sock_no_accept,
700 .mmap = sock_no_mmap
701};
702
703
704static int
705base_sock_create(struct net *net, struct socket *sock, int protocol)
706{
707 struct sock *sk;
708
709 if (sock->type != SOCK_RAW)
710 return -ESOCKTNOSUPPORT;
711
712 sk = sk_alloc(net, PF_ISDN, GFP_KERNEL, &mISDN_proto);
713 if (!sk)
714 return -ENOMEM;
715
716 sock_init_data(sock, sk);
717 sock->ops = &base_sock_ops;
718 sock->state = SS_UNCONNECTED;
719 sock_reset_flag(sk, SOCK_ZAPPED);
720 sk->sk_protocol = protocol;
721 sk->sk_state = MISDN_OPEN;
722 mISDN_sock_link(&base_sockets, sk);
723
724 return 0;
725}
726
727static int
728mISDN_sock_create(struct net *net, struct socket *sock, int proto)
729{
730 int err = -EPROTONOSUPPORT;
731
732 switch (proto) {
733 case ISDN_P_BASE:
734 err = base_sock_create(net, sock, proto);
735 break;
736 case ISDN_P_TE_S0:
737 case ISDN_P_NT_S0:
738 case ISDN_P_TE_E1:
739 case ISDN_P_NT_E1:
740 case ISDN_P_LAPD_TE:
741 case ISDN_P_LAPD_NT:
742 case ISDN_P_B_RAW:
743 case ISDN_P_B_HDLC:
744 case ISDN_P_B_X75SLP:
745 case ISDN_P_B_L2DTMF:
746 case ISDN_P_B_L2DSP:
747 case ISDN_P_B_L2DSPHDLC:
748 err = data_sock_create(net, sock, proto);
749 break;
750 default:
751 return err;
752 }
753
754 return err;
755}
756
757static struct
758net_proto_family mISDN_sock_family_ops = {
759 .owner = THIS_MODULE,
760 .family = PF_ISDN,
761 .create = mISDN_sock_create,
762};
763
764int
765misdn_sock_init(u_int *deb)
766{
767 int err;
768
769 debug = deb;
770 err = sock_register(&mISDN_sock_family_ops);
771 if (err)
772 printk(KERN_ERR "%s: error(%d)\n", __func__, err);
773 return err;
774}
775
776void
777misdn_sock_cleanup(void)
778{
779 sock_unregister(PF_ISDN);
780}
781
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
new file mode 100644
index 000000000000..54cfddcc4784
--- /dev/null
+++ b/drivers/isdn/mISDN/stack.c
@@ -0,0 +1,674 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/mISDNif.h>
19#include <linux/kthread.h>
20#include "core.h"
21
22static u_int *debug;
23
24static inline void
25_queue_message(struct mISDNstack *st, struct sk_buff *skb)
26{
27 struct mISDNhead *hh = mISDN_HEAD_P(skb);
28
29 if (*debug & DEBUG_QUEUE_FUNC)
30 printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
31 __func__, hh->prim, hh->id, skb);
32 skb_queue_tail(&st->msgq, skb);
33 if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) {
34 test_and_set_bit(mISDN_STACK_WORK, &st->status);
35 wake_up_interruptible(&st->workq);
36 }
37}
38
39int
40mISDN_queue_message(struct mISDNchannel *ch, struct sk_buff *skb)
41{
42 _queue_message(ch->st, skb);
43 return 0;
44}
45
46static struct mISDNchannel *
47get_channel4id(struct mISDNstack *st, u_int id)
48{
49 struct mISDNchannel *ch;
50
51 mutex_lock(&st->lmutex);
52 list_for_each_entry(ch, &st->layer2, list) {
53 if (id == ch->nr)
54 goto unlock;
55 }
56 ch = NULL;
57unlock:
58 mutex_unlock(&st->lmutex);
59 return ch;
60}
61
62static void
63send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
64{
65 struct hlist_node *node;
66 struct sock *sk;
67 struct sk_buff *cskb = NULL;
68
69 read_lock(&sl->lock);
70 sk_for_each(sk, node, &sl->head) {
71 if (sk->sk_state != MISDN_BOUND)
72 continue;
73 if (!cskb)
74 cskb = skb_copy(skb, GFP_KERNEL);
75 if (!cskb) {
76 printk(KERN_WARNING "%s no skb\n", __func__);
77 break;
78 }
79 if (!sock_queue_rcv_skb(sk, cskb))
80 cskb = NULL;
81 }
82 read_unlock(&sl->lock);
83 if (cskb)
84 dev_kfree_skb(cskb);
85}
86
87static void
88send_layer2(struct mISDNstack *st, struct sk_buff *skb)
89{
90 struct sk_buff *cskb;
91 struct mISDNhead *hh = mISDN_HEAD_P(skb);
92 struct mISDNchannel *ch;
93 int ret;
94
95 if (!st)
96 return;
97 mutex_lock(&st->lmutex);
98 if ((hh->id & MISDN_ID_ADDR_MASK) == MISDN_ID_ANY) { /* L2 for all */
99 list_for_each_entry(ch, &st->layer2, list) {
100 if (list_is_last(&ch->list, &st->layer2)) {
101 cskb = skb;
102 skb = NULL;
103 } else {
104 cskb = skb_copy(skb, GFP_KERNEL);
105 }
106 if (cskb) {
107 ret = ch->send(ch, cskb);
108 if (ret) {
109 if (*debug & DEBUG_SEND_ERR)
110 printk(KERN_DEBUG
111 "%s ch%d prim(%x) addr(%x)"
112 " err %d\n",
113 __func__, ch->nr,
114 hh->prim, ch->addr, ret);
115 dev_kfree_skb(cskb);
116 }
117 } else {
118 printk(KERN_WARNING "%s ch%d addr %x no mem\n",
119 __func__, ch->nr, ch->addr);
120 goto out;
121 }
122 }
123 } else {
124 list_for_each_entry(ch, &st->layer2, list) {
125 if ((hh->id & MISDN_ID_ADDR_MASK) == ch->addr) {
126 ret = ch->send(ch, skb);
127 if (!ret)
128 skb = NULL;
129 goto out;
130 }
131 }
132 ret = st->dev->teimgr->ctrl(st->dev->teimgr, CHECK_DATA, skb);
133 if (!ret)
134 skb = NULL;
135 else if (*debug & DEBUG_SEND_ERR)
136 printk(KERN_DEBUG
137 "%s ch%d mgr prim(%x) addr(%x) err %d\n",
138 __func__, ch->nr, hh->prim, ch->addr, ret);
139 }
140out:
141 mutex_unlock(&st->lmutex);
142 if (skb)
143 dev_kfree_skb(skb);
144}
145
146static inline int
147send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
148{
149 struct mISDNhead *hh = mISDN_HEAD_P(skb);
150 struct mISDNchannel *ch;
151 int lm;
152
153 lm = hh->prim & MISDN_LAYERMASK;
154 if (*debug & DEBUG_QUEUE_FUNC)
155 printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
156 __func__, hh->prim, hh->id, skb);
157 if (lm == 0x1) {
158 if (!hlist_empty(&st->l1sock.head)) {
159 __net_timestamp(skb);
160 send_socklist(&st->l1sock, skb);
161 }
162 return st->layer1->send(st->layer1, skb);
163 } else if (lm == 0x2) {
164 if (!hlist_empty(&st->l1sock.head))
165 send_socklist(&st->l1sock, skb);
166 send_layer2(st, skb);
167 return 0;
168 } else if (lm == 0x4) {
169 ch = get_channel4id(st, hh->id);
170 if (ch)
171 return ch->send(ch, skb);
172 else
173 printk(KERN_WARNING
174 "%s: dev(%s) prim(%x) id(%x) no channel\n",
175 __func__, st->dev->name, hh->prim, hh->id);
176 } else if (lm == 0x8) {
177 WARN_ON(lm == 0x8);
178 ch = get_channel4id(st, hh->id);
179 if (ch)
180 return ch->send(ch, skb);
181 else
182 printk(KERN_WARNING
183 "%s: dev(%s) prim(%x) id(%x) no channel\n",
184 __func__, st->dev->name, hh->prim, hh->id);
185 } else {
186 /* broadcast not handled yet */
187 printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n",
188 __func__, st->dev->name, hh->prim);
189 }
190 return -ESRCH;
191}
192
193static void
194do_clear_stack(struct mISDNstack *st)
195{
196}
197
198static int
199mISDNStackd(void *data)
200{
201 struct mISDNstack *st = data;
202 int err = 0;
203
204#ifdef CONFIG_SMP
205 lock_kernel();
206#endif
207 sigfillset(&current->blocked);
208#ifdef CONFIG_SMP
209 unlock_kernel();
210#endif
211 if (*debug & DEBUG_MSG_THREAD)
212 printk(KERN_DEBUG "mISDNStackd %s started\n", st->dev->name);
213
214 if (st->notify != NULL) {
215 complete(st->notify);
216 st->notify = NULL;
217 }
218
219 for (;;) {
220 struct sk_buff *skb;
221
222 if (unlikely(test_bit(mISDN_STACK_STOPPED, &st->status))) {
223 test_and_clear_bit(mISDN_STACK_WORK, &st->status);
224 test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
225 } else
226 test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
227 while (test_bit(mISDN_STACK_WORK, &st->status)) {
228 skb = skb_dequeue(&st->msgq);
229 if (!skb) {
230 test_and_clear_bit(mISDN_STACK_WORK,
231 &st->status);
232 /* test if a race happens */
233 skb = skb_dequeue(&st->msgq);
234 if (!skb)
235 continue;
236 test_and_set_bit(mISDN_STACK_WORK,
237 &st->status);
238 }
239#ifdef MISDN_MSG_STATS
240 st->msg_cnt++;
241#endif
242 err = send_msg_to_layer(st, skb);
243 if (unlikely(err)) {
244 if (*debug & DEBUG_SEND_ERR)
245 printk(KERN_DEBUG
246 "%s: %s prim(%x) id(%x) "
247 "send call(%d)\n",
248 __func__, st->dev->name,
249 mISDN_HEAD_PRIM(skb),
250 mISDN_HEAD_ID(skb), err);
251 dev_kfree_skb(skb);
252 continue;
253 }
254 if (unlikely(test_bit(mISDN_STACK_STOPPED,
255 &st->status))) {
256 test_and_clear_bit(mISDN_STACK_WORK,
257 &st->status);
258 test_and_clear_bit(mISDN_STACK_RUNNING,
259 &st->status);
260 break;
261 }
262 }
263 if (test_bit(mISDN_STACK_CLEARING, &st->status)) {
264 test_and_set_bit(mISDN_STACK_STOPPED, &st->status);
265 test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
266 do_clear_stack(st);
267 test_and_clear_bit(mISDN_STACK_CLEARING, &st->status);
268 test_and_set_bit(mISDN_STACK_RESTART, &st->status);
269 }
270 if (test_and_clear_bit(mISDN_STACK_RESTART, &st->status)) {
271 test_and_clear_bit(mISDN_STACK_STOPPED, &st->status);
272 test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
273 if (!skb_queue_empty(&st->msgq))
274 test_and_set_bit(mISDN_STACK_WORK,
275 &st->status);
276 }
277 if (test_bit(mISDN_STACK_ABORT, &st->status))
278 break;
279 if (st->notify != NULL) {
280 complete(st->notify);
281 st->notify = NULL;
282 }
283#ifdef MISDN_MSG_STATS
284 st->sleep_cnt++;
285#endif
286 test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
287 wait_event_interruptible(st->workq, (st->status &
288 mISDN_STACK_ACTION_MASK));
289 if (*debug & DEBUG_MSG_THREAD)
290 printk(KERN_DEBUG "%s: %s wake status %08lx\n",
291 __func__, st->dev->name, st->status);
292 test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
293
294 test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status);
295
296 if (test_bit(mISDN_STACK_STOPPED, &st->status)) {
297 test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
298#ifdef MISDN_MSG_STATS
299 st->stopped_cnt++;
300#endif
301 }
302 }
303#ifdef MISDN_MSG_STATS
304 printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d "
305 "msg %d sleep %d stopped\n",
306 st->dev->name, st->msg_cnt, st->sleep_cnt, st->stopped_cnt);
307 printk(KERN_DEBUG
308 "mISDNStackd daemon for %s utime(%ld) stime(%ld)\n",
309 st->dev->name, st->thread->utime, st->thread->stime);
310 printk(KERN_DEBUG
311 "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
312 st->dev->name, st->thread->nvcsw, st->thread->nivcsw);
313 printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n",
314 st->dev->name);
315#endif
316 test_and_set_bit(mISDN_STACK_KILLED, &st->status);
317 test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
318 test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
319 test_and_clear_bit(mISDN_STACK_ABORT, &st->status);
320 skb_queue_purge(&st->msgq);
321 st->thread = NULL;
322 if (st->notify != NULL) {
323 complete(st->notify);
324 st->notify = NULL;
325 }
326 return 0;
327}
328
329static int
330l1_receive(struct mISDNchannel *ch, struct sk_buff *skb)
331{
332 if (!ch->st)
333 return -ENODEV;
334 __net_timestamp(skb);
335 _queue_message(ch->st, skb);
336 return 0;
337}
338
339void
340set_channel_address(struct mISDNchannel *ch, u_int sapi, u_int tei)
341{
342 ch->addr = sapi | (tei << 8);
343}
344
345void
346__add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
347{
348 list_add_tail(&ch->list, &st->layer2);
349}
350
351void
352add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
353{
354 mutex_lock(&st->lmutex);
355 __add_layer2(ch, st);
356 mutex_unlock(&st->lmutex);
357}
358
359static int
360st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
361{
362 if (!ch->st || ch->st->layer1)
363 return -EINVAL;
364 return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
365}
366
367int
368create_stack(struct mISDNdevice *dev)
369{
370 struct mISDNstack *newst;
371 int err;
372 DECLARE_COMPLETION_ONSTACK(done);
373
374 newst = kzalloc(sizeof(struct mISDNstack), GFP_KERNEL);
375 if (!newst) {
376 printk(KERN_ERR "kmalloc mISDN_stack failed\n");
377 return -ENOMEM;
378 }
379 newst->dev = dev;
380 INIT_LIST_HEAD(&newst->layer2);
381 INIT_HLIST_HEAD(&newst->l1sock.head);
382 rwlock_init(&newst->l1sock.lock);
383 init_waitqueue_head(&newst->workq);
384 skb_queue_head_init(&newst->msgq);
385 mutex_init(&newst->lmutex);
386 dev->D.st = newst;
387 err = create_teimanager(dev);
388 if (err) {
389 printk(KERN_ERR "kmalloc teimanager failed\n");
390 kfree(newst);
391 return err;
392 }
393 dev->teimgr->peer = &newst->own;
394 dev->teimgr->recv = mISDN_queue_message;
395 dev->teimgr->st = newst;
396 newst->layer1 = &dev->D;
397 dev->D.recv = l1_receive;
398 dev->D.peer = &newst->own;
399 newst->own.st = newst;
400 newst->own.ctrl = st_own_ctrl;
401 newst->own.send = mISDN_queue_message;
402 newst->own.recv = mISDN_queue_message;
403 if (*debug & DEBUG_CORE_FUNC)
404 printk(KERN_DEBUG "%s: st(%s)\n", __func__, newst->dev->name);
405 newst->notify = &done;
406 newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s",
407 newst->dev->name);
408 if (IS_ERR(newst->thread)) {
409 err = PTR_ERR(newst->thread);
410 printk(KERN_ERR
411 "mISDN:cannot create kernel thread for %s (%d)\n",
412 newst->dev->name, err);
413 delete_teimanager(dev->teimgr);
414 kfree(newst);
415 } else
416 wait_for_completion(&done);
417 return err;
418}
419
420int
421connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
422 u_int protocol, struct sockaddr_mISDN *adr)
423{
424 struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
425 struct channel_req rq;
426 int err;
427
428
429 if (*debug & DEBUG_CORE_FUNC)
430 printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
431 __func__, dev->name, protocol, adr->dev, adr->channel,
432 adr->sapi, adr->tei);
433 switch (protocol) {
434 case ISDN_P_NT_S0:
435 case ISDN_P_NT_E1:
436 case ISDN_P_TE_S0:
437 case ISDN_P_TE_E1:
438#ifdef PROTOCOL_CHECK
439 /* this should be enhanced */
440 if (!list_empty(&dev->D.st->layer2)
441 && dev->D.protocol != protocol)
442 return -EBUSY;
443 if (!hlist_empty(&dev->D.st->l1sock.head)
444 && dev->D.protocol != protocol)
445 return -EBUSY;
446#endif
447 ch->recv = mISDN_queue_message;
448 ch->peer = &dev->D.st->own;
449 ch->st = dev->D.st;
450 rq.protocol = protocol;
451 rq.adr.channel = 0;
452 err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
453 printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err);
454 if (err)
455 return err;
456 write_lock_bh(&dev->D.st->l1sock.lock);
457 sk_add_node(&msk->sk, &dev->D.st->l1sock.head);
458 write_unlock_bh(&dev->D.st->l1sock.lock);
459 break;
460 default:
461 return -ENOPROTOOPT;
462 }
463 return 0;
464}
465
466int
467connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
468 u_int protocol, struct sockaddr_mISDN *adr)
469{
470 struct channel_req rq, rq2;
471 int pmask, err;
472 struct Bprotocol *bp;
473
474 if (*debug & DEBUG_CORE_FUNC)
475 printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
476 __func__, dev->name, protocol,
477 adr->dev, adr->channel, adr->sapi,
478 adr->tei);
479 ch->st = dev->D.st;
480 pmask = 1 << (protocol & ISDN_P_B_MASK);
481 if (pmask & dev->Bprotocols) {
482 rq.protocol = protocol;
483 rq.adr = *adr;
484 err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
485 if (err)
486 return err;
487 ch->recv = rq.ch->send;
488 ch->peer = rq.ch;
489 rq.ch->recv = ch->send;
490 rq.ch->peer = ch;
491 rq.ch->st = dev->D.st;
492 } else {
493 bp = get_Bprotocol4mask(pmask);
494 if (!bp)
495 return -ENOPROTOOPT;
496 rq2.protocol = protocol;
497 rq2.adr = *adr;
498 rq2.ch = ch;
499 err = bp->create(&rq2);
500 if (err)
501 return err;
502 ch->recv = rq2.ch->send;
503 ch->peer = rq2.ch;
504 rq2.ch->st = dev->D.st;
505 rq.protocol = rq2.protocol;
506 rq.adr = *adr;
507 err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
508 if (err) {
509 rq2.ch->ctrl(rq2.ch, CLOSE_CHANNEL, NULL);
510 return err;
511 }
512 rq2.ch->recv = rq.ch->send;
513 rq2.ch->peer = rq.ch;
514 rq.ch->recv = rq2.ch->send;
515 rq.ch->peer = rq2.ch;
516 rq.ch->st = dev->D.st;
517 }
518 ch->protocol = protocol;
519 ch->nr = rq.ch->nr;
520 return 0;
521}
522
523int
524create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
525 u_int protocol, struct sockaddr_mISDN *adr)
526{
527 struct channel_req rq;
528 int err;
529
530 if (*debug & DEBUG_CORE_FUNC)
531 printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
532 __func__, dev->name, protocol,
533 adr->dev, adr->channel, adr->sapi,
534 adr->tei);
535 rq.protocol = ISDN_P_TE_S0;
536 if (dev->Dprotocols & (1 << ISDN_P_TE_E1))
537 rq.protocol = ISDN_P_TE_E1;
538 switch (protocol) {
539 case ISDN_P_LAPD_NT:
540 rq.protocol = ISDN_P_NT_S0;
541 if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
542 rq.protocol = ISDN_P_NT_E1;
543 case ISDN_P_LAPD_TE:
544#ifdef PROTOCOL_CHECK
545 /* this should be enhanced */
546 if (!list_empty(&dev->D.st->layer2)
547 && dev->D.protocol != protocol)
548 return -EBUSY;
549 if (!hlist_empty(&dev->D.st->l1sock.head)
550 && dev->D.protocol != protocol)
551 return -EBUSY;
552#endif
553 ch->recv = mISDN_queue_message;
554 ch->peer = &dev->D.st->own;
555 ch->st = dev->D.st;
556 rq.adr.channel = 0;
557 err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
558 printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err);
559 if (err)
560 break;
561 rq.protocol = protocol;
562 rq.adr = *adr;
563 rq.ch = ch;
564 err = dev->teimgr->ctrl(dev->teimgr, OPEN_CHANNEL, &rq);
565 printk(KERN_DEBUG "%s: ret 2 %d\n", __func__, err);
566 if (!err) {
567 if ((protocol == ISDN_P_LAPD_NT) && !rq.ch)
568 break;
569 add_layer2(rq.ch, dev->D.st);
570 rq.ch->recv = mISDN_queue_message;
571 rq.ch->peer = &dev->D.st->own;
572 rq.ch->ctrl(rq.ch, OPEN_CHANNEL, NULL); /* can't fail */
573 }
574 break;
575 default:
576 err = -EPROTONOSUPPORT;
577 }
578 return err;
579}
580
581void
582delete_channel(struct mISDNchannel *ch)
583{
584 struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
585 struct mISDNchannel *pch;
586
587 if (!ch->st) {
588 printk(KERN_WARNING "%s: no stack\n", __func__);
589 return;
590 }
591 if (*debug & DEBUG_CORE_FUNC)
592 printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__,
593 ch->st->dev->name, ch->protocol);
594 if (ch->protocol >= ISDN_P_B_START) {
595 if (ch->peer) {
596 ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL);
597 ch->peer = NULL;
598 }
599 return;
600 }
601 switch (ch->protocol) {
602 case ISDN_P_NT_S0:
603 case ISDN_P_TE_S0:
604 case ISDN_P_NT_E1:
605 case ISDN_P_TE_E1:
606 write_lock_bh(&ch->st->l1sock.lock);
607 sk_del_node_init(&msk->sk);
608 write_unlock_bh(&ch->st->l1sock.lock);
609 ch->st->dev->D.ctrl(&ch->st->dev->D, CLOSE_CHANNEL, NULL);
610 break;
611 case ISDN_P_LAPD_TE:
612 pch = get_channel4id(ch->st, ch->nr);
613 if (pch) {
614 mutex_lock(&ch->st->lmutex);
615 list_del(&pch->list);
616 mutex_unlock(&ch->st->lmutex);
617 pch->ctrl(pch, CLOSE_CHANNEL, NULL);
618 pch = ch->st->dev->teimgr;
619 pch->ctrl(pch, CLOSE_CHANNEL, NULL);
620 } else
621 printk(KERN_WARNING "%s: no l2 channel\n",
622 __func__);
623 break;
624 case ISDN_P_LAPD_NT:
625 pch = ch->st->dev->teimgr;
626 if (pch) {
627 pch->ctrl(pch, CLOSE_CHANNEL, NULL);
628 } else
629 printk(KERN_WARNING "%s: no l2 channel\n",
630 __func__);
631 break;
632 default:
633 break;
634 }
635 return;
636}
637
638void
639delete_stack(struct mISDNdevice *dev)
640{
641 struct mISDNstack *st = dev->D.st;
642 DECLARE_COMPLETION_ONSTACK(done);
643
644 if (*debug & DEBUG_CORE_FUNC)
645 printk(KERN_DEBUG "%s: st(%s)\n", __func__,
646 st->dev->name);
647 if (dev->teimgr)
648 delete_teimanager(dev->teimgr);
649 if (st->thread) {
650 if (st->notify) {
651 printk(KERN_WARNING "%s: notifier in use\n",
652 __func__);
653 complete(st->notify);
654 }
655 st->notify = &done;
656 test_and_set_bit(mISDN_STACK_ABORT, &st->status);
657 test_and_set_bit(mISDN_STACK_WAKEUP, &st->status);
658 wake_up_interruptible(&st->workq);
659 wait_for_completion(&done);
660 }
661 if (!list_empty(&st->layer2))
662 printk(KERN_WARNING "%s: layer2 list not empty\n",
663 __func__);
664 if (!hlist_empty(&st->l1sock.head))
665 printk(KERN_WARNING "%s: layer1 list not empty\n",
666 __func__);
667 kfree(st);
668}
669
670void
671mISDN_initstack(u_int *dp)
672{
673 debug = dp;
674}
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
new file mode 100644
index 000000000000..56a76a0ffddd
--- /dev/null
+++ b/drivers/isdn/mISDN/tei.c
@@ -0,0 +1,1340 @@
1/*
2 *
3 * Author Karsten Keil <kkeil@novell.com>
4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17#include "layer2.h"
18#include <linux/random.h>
19#include "core.h"
20
21#define ID_REQUEST 1
22#define ID_ASSIGNED 2
23#define ID_DENIED 3
24#define ID_CHK_REQ 4
25#define ID_CHK_RES 5
26#define ID_REMOVE 6
27#define ID_VERIFY 7
28
29#define TEI_ENTITY_ID 0xf
30
31#define MGR_PH_ACTIVE 16
32#define MGR_PH_NOTREADY 17
33
34#define DATIMER_VAL 10000
35
36static u_int *debug;
37
38static struct Fsm deactfsm = {NULL, 0, 0, NULL, NULL};
39static struct Fsm teifsmu = {NULL, 0, 0, NULL, NULL};
40static struct Fsm teifsmn = {NULL, 0, 0, NULL, NULL};
41
42enum {
43 ST_L1_DEACT,
44 ST_L1_DEACT_PENDING,
45 ST_L1_ACTIV,
46};
47#define DEACT_STATE_COUNT (ST_L1_ACTIV+1)
48
49static char *strDeactState[] =
50{
51 "ST_L1_DEACT",
52 "ST_L1_DEACT_PENDING",
53 "ST_L1_ACTIV",
54};
55
56enum {
57 EV_ACTIVATE,
58 EV_ACTIVATE_IND,
59 EV_DEACTIVATE,
60 EV_DEACTIVATE_IND,
61 EV_UI,
62 EV_DATIMER,
63};
64
65#define DEACT_EVENT_COUNT (EV_DATIMER+1)
66
67static char *strDeactEvent[] =
68{
69 "EV_ACTIVATE",
70 "EV_ACTIVATE_IND",
71 "EV_DEACTIVATE",
72 "EV_DEACTIVATE_IND",
73 "EV_UI",
74 "EV_DATIMER",
75};
76
77static void
78da_debug(struct FsmInst *fi, char *fmt, ...)
79{
80 struct manager *mgr = fi->userdata;
81 va_list va;
82
83 if (!(*debug & DEBUG_L2_TEIFSM))
84 return;
85 va_start(va, fmt);
86 printk(KERN_DEBUG "mgr(%d): ", mgr->ch.st->dev->id);
87 vprintk(fmt, va);
88 printk("\n");
89 va_end(va);
90}
91
92static void
93da_activate(struct FsmInst *fi, int event, void *arg)
94{
95 struct manager *mgr = fi->userdata;
96
97 if (fi->state == ST_L1_DEACT_PENDING)
98 mISDN_FsmDelTimer(&mgr->datimer, 1);
99 mISDN_FsmChangeState(fi, ST_L1_ACTIV);
100}
101
102static void
103da_deactivate_ind(struct FsmInst *fi, int event, void *arg)
104{
105 mISDN_FsmChangeState(fi, ST_L1_DEACT);
106}
107
108static void
109da_deactivate(struct FsmInst *fi, int event, void *arg)
110{
111 struct manager *mgr = fi->userdata;
112 struct layer2 *l2;
113 u_long flags;
114
115 read_lock_irqsave(&mgr->lock, flags);
116 list_for_each_entry(l2, &mgr->layer2, list) {
117 if (l2->l2m.state > ST_L2_4) {
118 /* have still activ TEI */
119 read_unlock_irqrestore(&mgr->lock, flags);
120 return;
121 }
122 }
123 read_unlock_irqrestore(&mgr->lock, flags);
124 /* All TEI are inactiv */
125 mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1);
126 mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
127}
128
129static void
130da_ui(struct FsmInst *fi, int event, void *arg)
131{
132 struct manager *mgr = fi->userdata;
133
134 /* restart da timer */
135 mISDN_FsmDelTimer(&mgr->datimer, 2);
136 mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2);
137
138}
139
140static void
141da_timer(struct FsmInst *fi, int event, void *arg)
142{
143 struct manager *mgr = fi->userdata;
144 struct layer2 *l2;
145 u_long flags;
146
147 /* check again */
148 read_lock_irqsave(&mgr->lock, flags);
149 list_for_each_entry(l2, &mgr->layer2, list) {
150 if (l2->l2m.state > ST_L2_4) {
151 /* have still activ TEI */
152 read_unlock_irqrestore(&mgr->lock, flags);
153 mISDN_FsmChangeState(fi, ST_L1_ACTIV);
154 return;
155 }
156 }
157 read_unlock_irqrestore(&mgr->lock, flags);
158 /* All TEI are inactiv */
159 mISDN_FsmChangeState(fi, ST_L1_DEACT);
160 _queue_data(&mgr->ch, PH_DEACTIVATE_REQ, MISDN_ID_ANY, 0, NULL,
161 GFP_ATOMIC);
162}
163
164static struct FsmNode DeactFnList[] =
165{
166 {ST_L1_DEACT, EV_ACTIVATE_IND, da_activate},
167 {ST_L1_ACTIV, EV_DEACTIVATE_IND, da_deactivate_ind},
168 {ST_L1_ACTIV, EV_DEACTIVATE, da_deactivate},
169 {ST_L1_DEACT_PENDING, EV_ACTIVATE, da_activate},
170 {ST_L1_DEACT_PENDING, EV_UI, da_ui},
171 {ST_L1_DEACT_PENDING, EV_DATIMER, da_timer},
172};
173
174enum {
175 ST_TEI_NOP,
176 ST_TEI_IDREQ,
177 ST_TEI_IDVERIFY,
178};
179
180#define TEI_STATE_COUNT (ST_TEI_IDVERIFY+1)
181
182static char *strTeiState[] =
183{
184 "ST_TEI_NOP",
185 "ST_TEI_IDREQ",
186 "ST_TEI_IDVERIFY",
187};
188
189enum {
190 EV_IDREQ,
191 EV_ASSIGN,
192 EV_ASSIGN_REQ,
193 EV_DENIED,
194 EV_CHKREQ,
195 EV_CHKRESP,
196 EV_REMOVE,
197 EV_VERIFY,
198 EV_TIMER,
199};
200
201#define TEI_EVENT_COUNT (EV_TIMER+1)
202
203static char *strTeiEvent[] =
204{
205 "EV_IDREQ",
206 "EV_ASSIGN",
207 "EV_ASSIGN_REQ",
208 "EV_DENIED",
209 "EV_CHKREQ",
210 "EV_CHKRESP",
211 "EV_REMOVE",
212 "EV_VERIFY",
213 "EV_TIMER",
214};
215
216static void
217tei_debug(struct FsmInst *fi, char *fmt, ...)
218{
219 struct teimgr *tm = fi->userdata;
220 va_list va;
221
222 if (!(*debug & DEBUG_L2_TEIFSM))
223 return;
224 va_start(va, fmt);
225 printk(KERN_DEBUG "tei(%d): ", tm->l2->tei);
226 vprintk(fmt, va);
227 printk("\n");
228 va_end(va);
229}
230
231
232
233static int
234get_free_id(struct manager *mgr)
235{
236 u64 ids = 0;
237 int i;
238 struct layer2 *l2;
239
240 list_for_each_entry(l2, &mgr->layer2, list) {
241 if (l2->ch.nr > 63) {
242 printk(KERN_WARNING
243 "%s: more as 63 layer2 for one device\n",
244 __func__);
245 return -EBUSY;
246 }
247 test_and_set_bit(l2->ch.nr, (u_long *)&ids);
248 }
249 for (i = 1; i < 64; i++)
250 if (!test_bit(i, (u_long *)&ids))
251 return i;
252 printk(KERN_WARNING "%s: more as 63 layer2 for one device\n",
253 __func__);
254 return -EBUSY;
255}
256
257static int
258get_free_tei(struct manager *mgr)
259{
260 u64 ids = 0;
261 int i;
262 struct layer2 *l2;
263
264 list_for_each_entry(l2, &mgr->layer2, list) {
265 if (l2->ch.nr == 0)
266 continue;
267 if ((l2->ch.addr & 0xff) != 0)
268 continue;
269 i = l2->ch.addr >> 8;
270 if (i < 64)
271 continue;
272 i -= 64;
273
274 test_and_set_bit(i, (u_long *)&ids);
275 }
276 for (i = 0; i < 64; i++)
277 if (!test_bit(i, (u_long *)&ids))
278 return i + 64;
279 printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n",
280 __func__);
281 return -1;
282}
283
284static void
285teiup_create(struct manager *mgr, u_int prim, int len, void *arg)
286{
287 struct sk_buff *skb;
288 struct mISDNhead *hh;
289 int err;
290
291 skb = mI_alloc_skb(len, GFP_ATOMIC);
292 if (!skb)
293 return;
294 hh = mISDN_HEAD_P(skb);
295 hh->prim = prim;
296 hh->id = (mgr->ch.nr << 16) | mgr->ch.addr;
297 if (len)
298 memcpy(skb_put(skb, len), arg, len);
299 err = mgr->up->send(mgr->up, skb);
300 if (err) {
301 printk(KERN_WARNING "%s: err=%d\n", __func__, err);
302 dev_kfree_skb(skb);
303 }
304}
305
306static u_int
307new_id(struct manager *mgr)
308{
309 u_int id;
310
311 id = mgr->nextid++;
312 if (id == 0x7fff)
313 mgr->nextid = 1;
314 id <<= 16;
315 id |= GROUP_TEI << 8;
316 id |= TEI_SAPI;
317 return id;
318}
319
320static void
321do_send(struct manager *mgr)
322{
323 if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
324 return;
325
326 if (!test_and_set_bit(MGR_PH_NOTREADY, &mgr->options)) {
327 struct sk_buff *skb = skb_dequeue(&mgr->sendq);
328
329 if (!skb) {
330 test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
331 return;
332 }
333 mgr->lastid = mISDN_HEAD_ID(skb);
334 mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
335 if (mgr->ch.recv(mgr->ch.peer, skb)) {
336 dev_kfree_skb(skb);
337 test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
338 mgr->lastid = MISDN_ID_NONE;
339 }
340 }
341}
342
343static void
344do_ack(struct manager *mgr, u_int id)
345{
346 if (test_bit(MGR_PH_NOTREADY, &mgr->options)) {
347 if (id == mgr->lastid) {
348 if (test_bit(MGR_PH_ACTIVE, &mgr->options)) {
349 struct sk_buff *skb;
350
351 skb = skb_dequeue(&mgr->sendq);
352 if (skb) {
353 mgr->lastid = mISDN_HEAD_ID(skb);
354 if (!mgr->ch.recv(mgr->ch.peer, skb))
355 return;
356 dev_kfree_skb(skb);
357 }
358 }
359 mgr->lastid = MISDN_ID_NONE;
360 test_and_clear_bit(MGR_PH_NOTREADY, &mgr->options);
361 }
362 }
363}
364
365static void
366mgr_send_down(struct manager *mgr, struct sk_buff *skb)
367{
368 skb_queue_tail(&mgr->sendq, skb);
369 if (!test_bit(MGR_PH_ACTIVE, &mgr->options)) {
370 _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
371 NULL, GFP_KERNEL);
372 } else {
373 do_send(mgr);
374 }
375}
376
377static int
378dl_unit_data(struct manager *mgr, struct sk_buff *skb)
379{
380 if (!test_bit(MGR_OPT_NETWORK, &mgr->options)) /* only net send UI */
381 return -EINVAL;
382 if (!test_bit(MGR_PH_ACTIVE, &mgr->options))
383 _queue_data(&mgr->ch, PH_ACTIVATE_REQ, MISDN_ID_ANY, 0,
384 NULL, GFP_KERNEL);
385 skb_push(skb, 3);
386 skb->data[0] = 0x02; /* SAPI 0 C/R = 1 */
387 skb->data[1] = 0xff; /* TEI 127 */
388 skb->data[2] = UI; /* UI frame */
389 mISDN_HEAD_PRIM(skb) = PH_DATA_REQ;
390 mISDN_HEAD_ID(skb) = new_id(mgr);
391 skb_queue_tail(&mgr->sendq, skb);
392 do_send(mgr);
393 return 0;
394}
395
396unsigned int
397random_ri(void)
398{
399 u16 x;
400
401 get_random_bytes(&x, sizeof(x));
402 return x;
403}
404
405static struct layer2 *
406findtei(struct manager *mgr, int tei)
407{
408 struct layer2 *l2;
409 u_long flags;
410
411 read_lock_irqsave(&mgr->lock, flags);
412 list_for_each_entry(l2, &mgr->layer2, list) {
413 if ((l2->sapi == 0) && (l2->tei > 0) &&
414 (l2->tei != GROUP_TEI) && (l2->tei == tei))
415 goto done;
416 }
417 l2 = NULL;
418done:
419 read_unlock_irqrestore(&mgr->lock, flags);
420 return l2;
421}
422
423static void
424put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
425{
426 struct sk_buff *skb;
427 u_char bp[8];
428
429 bp[0] = (TEI_SAPI << 2);
430 if (test_bit(MGR_OPT_NETWORK, &mgr->options))
431 bp[0] |= 2; /* CR:=1 for net command */
432 bp[1] = (GROUP_TEI << 1) | 0x1;
433 bp[2] = UI;
434 bp[3] = TEI_ENTITY_ID;
435 bp[4] = ri >> 8;
436 bp[5] = ri & 0xff;
437 bp[6] = m_id;
438 bp[7] = (tei << 1) | 1;
439 skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr),
440 8, bp, GFP_ATOMIC);
441 if (!skb) {
442 printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
443 return;
444 }
445 mgr_send_down(mgr, skb);
446}
447
448static void
449tei_id_request(struct FsmInst *fi, int event, void *arg)
450{
451 struct teimgr *tm = fi->userdata;
452
453 if (tm->l2->tei != GROUP_TEI) {
454 tm->tei_m.printdebug(&tm->tei_m,
455 "assign request for allready assigned tei %d",
456 tm->l2->tei);
457 return;
458 }
459 tm->ri = random_ri();
460 if (*debug & DEBUG_L2_TEI)
461 tm->tei_m.printdebug(&tm->tei_m,
462 "assign request ri %d", tm->ri);
463 put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
464 mISDN_FsmChangeState(fi, ST_TEI_IDREQ);
465 mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 1);
466 tm->nval = 3;
467}
468
469static void
470tei_id_assign(struct FsmInst *fi, int event, void *arg)
471{
472 struct teimgr *tm = fi->userdata;
473 struct layer2 *l2;
474 u_char *dp = arg;
475 int ri, tei;
476
477 ri = ((unsigned int) *dp++ << 8);
478 ri += *dp++;
479 dp++;
480 tei = *dp >> 1;
481 if (*debug & DEBUG_L2_TEI)
482 tm->tei_m.printdebug(fi, "identity assign ri %d tei %d",
483 ri, tei);
484 l2 = findtei(tm->mgr, tei);
485 if (l2) { /* same tei is in use */
486 if (ri != l2->tm->ri) {
487 tm->tei_m.printdebug(fi,
488 "possible duplicate assignment tei %d", tei);
489 tei_l2(l2, MDL_ERROR_RSP, 0);
490 }
491 } else if (ri == tm->ri) {
492 mISDN_FsmDelTimer(&tm->timer, 1);
493 mISDN_FsmChangeState(fi, ST_TEI_NOP);
494 tei_l2(tm->l2, MDL_ASSIGN_REQ, tei);
495 }
496}
497
498static void
499tei_id_test_dup(struct FsmInst *fi, int event, void *arg)
500{
501 struct teimgr *tm = fi->userdata;
502 struct layer2 *l2;
503 u_char *dp = arg;
504 int tei, ri;
505
506 ri = ((unsigned int) *dp++ << 8);
507 ri += *dp++;
508 dp++;
509 tei = *dp >> 1;
510 if (*debug & DEBUG_L2_TEI)
511 tm->tei_m.printdebug(fi, "foreign identity assign ri %d tei %d",
512 ri, tei);
513 l2 = findtei(tm->mgr, tei);
514 if (l2) { /* same tei is in use */
515 if (ri != l2->tm->ri) { /* and it wasn't our request */
516 tm->tei_m.printdebug(fi,
517 "possible duplicate assignment tei %d", tei);
518 mISDN_FsmEvent(&l2->tm->tei_m, EV_VERIFY, NULL);
519 }
520 }
521}
522
523static void
524tei_id_denied(struct FsmInst *fi, int event, void *arg)
525{
526 struct teimgr *tm = fi->userdata;
527 u_char *dp = arg;
528 int ri, tei;
529
530 ri = ((unsigned int) *dp++ << 8);
531 ri += *dp++;
532 dp++;
533 tei = *dp >> 1;
534 if (*debug & DEBUG_L2_TEI)
535 tm->tei_m.printdebug(fi, "identity denied ri %d tei %d",
536 ri, tei);
537}
538
539static void
540tei_id_chk_req(struct FsmInst *fi, int event, void *arg)
541{
542 struct teimgr *tm = fi->userdata;
543 u_char *dp = arg;
544 int tei;
545
546 tei = *(dp+3) >> 1;
547 if (*debug & DEBUG_L2_TEI)
548 tm->tei_m.printdebug(fi, "identity check req tei %d", tei);
549 if ((tm->l2->tei != GROUP_TEI) && ((tei == GROUP_TEI) ||
550 (tei == tm->l2->tei))) {
551 mISDN_FsmDelTimer(&tm->timer, 4);
552 mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
553 put_tei_msg(tm->mgr, ID_CHK_RES, random_ri(), tm->l2->tei);
554 }
555}
556
557static void
558tei_id_remove(struct FsmInst *fi, int event, void *arg)
559{
560 struct teimgr *tm = fi->userdata;
561 u_char *dp = arg;
562 int tei;
563
564 tei = *(dp+3) >> 1;
565 if (*debug & DEBUG_L2_TEI)
566 tm->tei_m.printdebug(fi, "identity remove tei %d", tei);
567 if ((tm->l2->tei != GROUP_TEI) &&
568 ((tei == GROUP_TEI) || (tei == tm->l2->tei))) {
569 mISDN_FsmDelTimer(&tm->timer, 5);
570 mISDN_FsmChangeState(&tm->tei_m, ST_TEI_NOP);
571 tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
572 }
573}
574
575static void
576tei_id_verify(struct FsmInst *fi, int event, void *arg)
577{
578 struct teimgr *tm = fi->userdata;
579
580 if (*debug & DEBUG_L2_TEI)
581 tm->tei_m.printdebug(fi, "id verify request for tei %d",
582 tm->l2->tei);
583 put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
584 mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
585 mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
586 tm->nval = 2;
587}
588
589static void
590tei_id_req_tout(struct FsmInst *fi, int event, void *arg)
591{
592 struct teimgr *tm = fi->userdata;
593
594 if (--tm->nval) {
595 tm->ri = random_ri();
596 if (*debug & DEBUG_L2_TEI)
597 tm->tei_m.printdebug(fi, "assign req(%d) ri %d",
598 4 - tm->nval, tm->ri);
599 put_tei_msg(tm->mgr, ID_REQUEST, tm->ri, GROUP_TEI);
600 mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 3);
601 } else {
602 tm->tei_m.printdebug(fi, "assign req failed");
603 tei_l2(tm->l2, MDL_ERROR_RSP, 0);
604 mISDN_FsmChangeState(fi, ST_TEI_NOP);
605 }
606}
607
608static void
609tei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
610{
611 struct teimgr *tm = fi->userdata;
612
613 if (--tm->nval) {
614 if (*debug & DEBUG_L2_TEI)
615 tm->tei_m.printdebug(fi,
616 "id verify req(%d) for tei %d",
617 3 - tm->nval, tm->l2->tei);
618 put_tei_msg(tm->mgr, ID_VERIFY, 0, tm->l2->tei);
619 mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
620 } else {
621 tm->tei_m.printdebug(fi, "verify req for tei %d failed",
622 tm->l2->tei);
623 tei_l2(tm->l2, MDL_REMOVE_REQ, 0);
624 mISDN_FsmChangeState(fi, ST_TEI_NOP);
625 }
626}
627
628static struct FsmNode TeiFnListUser[] =
629{
630 {ST_TEI_NOP, EV_IDREQ, tei_id_request},
631 {ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup},
632 {ST_TEI_NOP, EV_VERIFY, tei_id_verify},
633 {ST_TEI_NOP, EV_REMOVE, tei_id_remove},
634 {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
635 {ST_TEI_IDREQ, EV_TIMER, tei_id_req_tout},
636 {ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
637 {ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
638 {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout},
639 {ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
640 {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
641};
642
643static void
644tei_l2remove(struct layer2 *l2)
645{
646 put_tei_msg(l2->tm->mgr, ID_REMOVE, 0, l2->tei);
647 tei_l2(l2, MDL_REMOVE_REQ, 0);
648 list_del(&l2->ch.list);
649 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
650}
651
652static void
653tei_assign_req(struct FsmInst *fi, int event, void *arg)
654{
655 struct teimgr *tm = fi->userdata;
656 u_char *dp = arg;
657
658 if (tm->l2->tei == GROUP_TEI) {
659 tm->tei_m.printdebug(&tm->tei_m,
660 "net tei assign request without tei");
661 return;
662 }
663 tm->ri = ((unsigned int) *dp++ << 8);
664 tm->ri += *dp++;
665 if (*debug & DEBUG_L2_TEI)
666 tm->tei_m.printdebug(&tm->tei_m,
667 "net assign request ri %d teim %d", tm->ri, *dp);
668 put_tei_msg(tm->mgr, ID_ASSIGNED, tm->ri, tm->l2->tei);
669 mISDN_FsmChangeState(fi, ST_TEI_NOP);
670}
671
672static void
673tei_id_chk_req_net(struct FsmInst *fi, int event, void *arg)
674{
675 struct teimgr *tm = fi->userdata;
676
677 if (*debug & DEBUG_L2_TEI)
678 tm->tei_m.printdebug(fi, "id check request for tei %d",
679 tm->l2->tei);
680 tm->rcnt = 0;
681 put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
682 mISDN_FsmChangeState(&tm->tei_m, ST_TEI_IDVERIFY);
683 mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 2);
684 tm->nval = 2;
685}
686
687static void
688tei_id_chk_resp(struct FsmInst *fi, int event, void *arg)
689{
690 struct teimgr *tm = fi->userdata;
691 u_char *dp = arg;
692 int tei;
693
694 tei = dp[3] >> 1;
695 if (*debug & DEBUG_L2_TEI)
696 tm->tei_m.printdebug(fi, "identity check resp tei %d", tei);
697 if (tei == tm->l2->tei)
698 tm->rcnt++;
699}
700
701static void
702tei_id_verify_net(struct FsmInst *fi, int event, void *arg)
703{
704 struct teimgr *tm = fi->userdata;
705 u_char *dp = arg;
706 int tei;
707
708 tei = dp[3] >> 1;
709 if (*debug & DEBUG_L2_TEI)
710 tm->tei_m.printdebug(fi, "identity verify req tei %d/%d",
711 tei, tm->l2->tei);
712 if (tei == tm->l2->tei)
713 tei_id_chk_req_net(fi, event, arg);
714}
715
716static void
717tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
718{
719 struct teimgr *tm = fi->userdata;
720
721 if (tm->rcnt == 1) {
722 if (*debug & DEBUG_L2_TEI)
723 tm->tei_m.printdebug(fi,
724 "check req for tei %d sucessful\n", tm->l2->tei);
725 mISDN_FsmChangeState(fi, ST_TEI_NOP);
726 } else if (tm->rcnt > 1) {
727 /* duplicate assignment; remove */
728 tei_l2remove(tm->l2);
729 } else if (--tm->nval) {
730 if (*debug & DEBUG_L2_TEI)
731 tm->tei_m.printdebug(fi,
732 "id check req(%d) for tei %d",
733 3 - tm->nval, tm->l2->tei);
734 put_tei_msg(tm->mgr, ID_CHK_REQ, 0, tm->l2->tei);
735 mISDN_FsmAddTimer(&tm->timer, tm->tval, EV_TIMER, NULL, 4);
736 } else {
737 tm->tei_m.printdebug(fi, "check req for tei %d failed",
738 tm->l2->tei);
739 mISDN_FsmChangeState(fi, ST_TEI_NOP);
740 tei_l2remove(tm->l2);
741 }
742}
743
744static struct FsmNode TeiFnListNet[] =
745{
746 {ST_TEI_NOP, EV_ASSIGN_REQ, tei_assign_req},
747 {ST_TEI_NOP, EV_VERIFY, tei_id_verify_net},
748 {ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req_net},
749 {ST_TEI_IDVERIFY, EV_TIMER, tei_id_ver_tout_net},
750 {ST_TEI_IDVERIFY, EV_CHKRESP, tei_id_chk_resp},
751};
752
753static void
754tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
755{
756 if (test_bit(FLG_FIXED_TEI, &tm->l2->flag))
757 return;
758 if (*debug & DEBUG_L2_TEI)
759 tm->tei_m.printdebug(&tm->tei_m, "tei handler mt %x", mt);
760 if (mt == ID_ASSIGNED)
761 mISDN_FsmEvent(&tm->tei_m, EV_ASSIGN, dp);
762 else if (mt == ID_DENIED)
763 mISDN_FsmEvent(&tm->tei_m, EV_DENIED, dp);
764 else if (mt == ID_CHK_REQ)
765 mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, dp);
766 else if (mt == ID_REMOVE)
767 mISDN_FsmEvent(&tm->tei_m, EV_REMOVE, dp);
768 else if (mt == ID_VERIFY)
769 mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, dp);
770 else if (mt == ID_CHK_RES)
771 mISDN_FsmEvent(&tm->tei_m, EV_CHKRESP, dp);
772}
773
774static struct layer2 *
775create_new_tei(struct manager *mgr, int tei)
776{
777 u_long opt = 0;
778 u_long flags;
779 int id;
780 struct layer2 *l2;
781
782 if (!mgr->up)
783 return NULL;
784 if (tei < 64)
785 test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
786 if (mgr->ch.st->dev->Dprotocols
787 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
788 test_and_set_bit(OPTION_L2_PMX, &opt);
789 l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei);
790 if (!l2) {
791 printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
792 return NULL;
793 }
794 l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
795 if (!l2->tm) {
796 kfree(l2);
797 printk(KERN_WARNING "%s:no memory for teimgr\n", __func__);
798 return NULL;
799 }
800 l2->tm->mgr = mgr;
801 l2->tm->l2 = l2;
802 l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
803 l2->tm->tei_m.userdata = l2->tm;
804 l2->tm->tei_m.printdebug = tei_debug;
805 l2->tm->tei_m.fsm = &teifsmn;
806 l2->tm->tei_m.state = ST_TEI_NOP;
807 l2->tm->tval = 2000; /* T202 2 sec */
808 mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
809 write_lock_irqsave(&mgr->lock, flags);
810 id = get_free_id(mgr);
811 list_add_tail(&l2->list, &mgr->layer2);
812 write_unlock_irqrestore(&mgr->lock, flags);
813 if (id < 0) {
814 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
815 printk(KERN_WARNING "%s:no free id\n", __func__);
816 return NULL;
817 } else {
818 l2->ch.nr = id;
819 __add_layer2(&l2->ch, mgr->ch.st);
820 l2->ch.recv = mgr->ch.recv;
821 l2->ch.peer = mgr->ch.peer;
822 l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
823 }
824 return l2;
825}
826
827static void
828new_tei_req(struct manager *mgr, u_char *dp)
829{
830 int tei, ri;
831 struct layer2 *l2;
832
833 ri = dp[0] << 8;
834 ri += dp[1];
835 if (!mgr->up)
836 goto denied;
837 tei = get_free_tei(mgr);
838 if (tei < 0) {
839 printk(KERN_WARNING "%s:No free tei\n", __func__);
840 goto denied;
841 }
842 l2 = create_new_tei(mgr, tei);
843 if (!l2)
844 goto denied;
845 else
846 mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
847 return;
848denied:
849 put_tei_msg(mgr, ID_DENIED, ri, GROUP_TEI);
850}
851
852static int
853ph_data_ind(struct manager *mgr, struct sk_buff *skb)
854{
855 int ret = -EINVAL;
856 struct layer2 *l2;
857 u_long flags;
858 u_char mt;
859
860 if (skb->len < 8) {
861 if (*debug & DEBUG_L2_TEI)
862 printk(KERN_DEBUG "%s: short mgr frame %d/8\n",
863 __func__, skb->len);
864 goto done;
865 }
866 if (*debug & DEBUG_L2_TEI)
867
868 if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
869 goto done;
870 if (skb->data[0] & 1) /* EA0 formal error */
871 goto done;
872 if (!(skb->data[1] & 1)) /* EA1 formal error */
873 goto done;
874 if ((skb->data[1] >> 1) != GROUP_TEI) /* not for us */
875 goto done;
876 if ((skb->data[2] & 0xef) != UI) /* not UI */
877 goto done;
878 if (skb->data[3] != TEI_ENTITY_ID) /* not tei entity */
879 goto done;
880 mt = skb->data[6];
881 switch (mt) {
882 case ID_REQUEST:
883 case ID_CHK_RES:
884 case ID_VERIFY:
885 if (!test_bit(MGR_OPT_NETWORK, &mgr->options))
886 goto done;
887 break;
888 case ID_ASSIGNED:
889 case ID_DENIED:
890 case ID_CHK_REQ:
891 case ID_REMOVE:
892 if (test_bit(MGR_OPT_NETWORK, &mgr->options))
893 goto done;
894 break;
895 default:
896 goto done;
897 }
898 ret = 0;
899 if (mt == ID_REQUEST) {
900 new_tei_req(mgr, &skb->data[4]);
901 goto done;
902 }
903 read_lock_irqsave(&mgr->lock, flags);
904 list_for_each_entry(l2, &mgr->layer2, list) {
905 tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
906 }
907 read_unlock_irqrestore(&mgr->lock, flags);
908done:
909 return ret;
910}
911
912int
913l2_tei(struct layer2 *l2, u_int cmd, u_long arg)
914{
915 struct teimgr *tm = l2->tm;
916
917 if (test_bit(FLG_FIXED_TEI, &l2->flag))
918 return 0;
919 if (*debug & DEBUG_L2_TEI)
920 printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd);
921 switch (cmd) {
922 case MDL_ASSIGN_IND:
923 mISDN_FsmEvent(&tm->tei_m, EV_IDREQ, NULL);
924 break;
925 case MDL_ERROR_IND:
926 if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
927 mISDN_FsmEvent(&tm->tei_m, EV_CHKREQ, &l2->tei);
928 if (test_bit(MGR_OPT_USER, &tm->mgr->options))
929 mISDN_FsmEvent(&tm->tei_m, EV_VERIFY, NULL);
930 break;
931 case MDL_STATUS_UP_IND:
932 if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
933 mISDN_FsmEvent(&tm->mgr->deact, EV_ACTIVATE, NULL);
934 break;
935 case MDL_STATUS_DOWN_IND:
936 if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
937 mISDN_FsmEvent(&tm->mgr->deact, EV_DEACTIVATE, NULL);
938 break;
939 case MDL_STATUS_UI_IND:
940 if (test_bit(MGR_OPT_NETWORK, &tm->mgr->options))
941 mISDN_FsmEvent(&tm->mgr->deact, EV_UI, NULL);
942 break;
943 }
944 return 0;
945}
946
947void
948release_tei(struct layer2 *l2)
949{
950 struct teimgr *tm = l2->tm;
951 u_long flags;
952
953 mISDN_FsmDelTimer(&tm->timer, 1);
954 write_lock_irqsave(&tm->mgr->lock, flags);
955 list_del(&l2->list);
956 write_unlock_irqrestore(&tm->mgr->lock, flags);
957 l2->tm = NULL;
958 kfree(tm);
959}
960
961static int
962create_teimgr(struct manager *mgr, struct channel_req *crq)
963{
964 struct layer2 *l2;
965 u_long opt = 0;
966 u_long flags;
967 int id;
968
969 if (*debug & DEBUG_L2_TEI)
970 printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
971 __func__, mgr->ch.st->dev->name, crq->protocol,
972 crq->adr.dev, crq->adr.channel, crq->adr.sapi,
973 crq->adr.tei);
974 if (crq->adr.sapi != 0) /* not supported yet */
975 return -EINVAL;
976 if (crq->adr.tei > GROUP_TEI)
977 return -EINVAL;
978 if (crq->adr.tei < 64)
979 test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
980 if (crq->adr.tei == 0)
981 test_and_set_bit(OPTION_L2_PTP, &opt);
982 if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
983 if (crq->protocol == ISDN_P_LAPD_TE)
984 return -EPROTONOSUPPORT;
985 if ((crq->adr.tei != 0) && (crq->adr.tei != 127))
986 return -EINVAL;
987 if (mgr->up) {
988 printk(KERN_WARNING
989 "%s: only one network manager is allowed\n",
990 __func__);
991 return -EBUSY;
992 }
993 } else if (test_bit(MGR_OPT_USER, &mgr->options)) {
994 if (crq->protocol == ISDN_P_LAPD_NT)
995 return -EPROTONOSUPPORT;
996 if ((crq->adr.tei >= 64) && (crq->adr.tei < GROUP_TEI))
997 return -EINVAL; /* dyn tei */
998 } else {
999 if (crq->protocol == ISDN_P_LAPD_NT)
1000 test_and_set_bit(MGR_OPT_NETWORK, &mgr->options);
1001 if (crq->protocol == ISDN_P_LAPD_TE)
1002 test_and_set_bit(MGR_OPT_USER, &mgr->options);
1003 }
1004 if (mgr->ch.st->dev->Dprotocols
1005 & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
1006 test_and_set_bit(OPTION_L2_PMX, &opt);
1007 if ((crq->protocol == ISDN_P_LAPD_NT) && (crq->adr.tei == 127)) {
1008 mgr->up = crq->ch;
1009 id = DL_INFO_L2_CONNECT;
1010 teiup_create(mgr, DL_INFORMATION_IND, sizeof(id), &id);
1011 crq->ch = NULL;
1012 if (!list_empty(&mgr->layer2)) {
1013 read_lock_irqsave(&mgr->lock, flags);
1014 list_for_each_entry(l2, &mgr->layer2, list) {
1015 l2->up = mgr->up;
1016 l2->ch.ctrl(&l2->ch, OPEN_CHANNEL, NULL);
1017 }
1018 read_unlock_irqrestore(&mgr->lock, flags);
1019 }
1020 return 0;
1021 }
1022 l2 = create_l2(crq->ch, crq->protocol, (u_int)opt,
1023 (u_long)crq->adr.tei);
1024 if (!l2)
1025 return -ENOMEM;
1026 l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
1027 if (!l2->tm) {
1028 kfree(l2);
1029 printk(KERN_ERR "kmalloc teimgr failed\n");
1030 return -ENOMEM;
1031 }
1032 l2->tm->mgr = mgr;
1033 l2->tm->l2 = l2;
1034 l2->tm->tei_m.debug = *debug & DEBUG_L2_TEIFSM;
1035 l2->tm->tei_m.userdata = l2->tm;
1036 l2->tm->tei_m.printdebug = tei_debug;
1037 if (crq->protocol == ISDN_P_LAPD_TE) {
1038 l2->tm->tei_m.fsm = &teifsmu;
1039 l2->tm->tei_m.state = ST_TEI_NOP;
1040 l2->tm->tval = 1000; /* T201 1 sec */
1041 } else {
1042 l2->tm->tei_m.fsm = &teifsmn;
1043 l2->tm->tei_m.state = ST_TEI_NOP;
1044 l2->tm->tval = 2000; /* T202 2 sec */
1045 }
1046 mISDN_FsmInitTimer(&l2->tm->tei_m, &l2->tm->timer);
1047 write_lock_irqsave(&mgr->lock, flags);
1048 id = get_free_id(mgr);
1049 list_add_tail(&l2->list, &mgr->layer2);
1050 write_unlock_irqrestore(&mgr->lock, flags);
1051 if (id < 0) {
1052 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
1053 } else {
1054 l2->ch.nr = id;
1055 l2->up->nr = id;
1056 crq->ch = &l2->ch;
1057 id = 0;
1058 }
1059 return id;
1060}
1061
1062static int
1063mgr_send(struct mISDNchannel *ch, struct sk_buff *skb)
1064{
1065 struct manager *mgr;
1066 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1067 int ret = -EINVAL;
1068
1069 mgr = container_of(ch, struct manager, ch);
1070 if (*debug & DEBUG_L2_RECV)
1071 printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
1072 __func__, hh->prim, hh->id);
1073 switch (hh->prim) {
1074 case PH_DATA_IND:
1075 mISDN_FsmEvent(&mgr->deact, EV_UI, NULL);
1076 ret = ph_data_ind(mgr, skb);
1077 break;
1078 case PH_DATA_CNF:
1079 do_ack(mgr, hh->id);
1080 ret = 0;
1081 break;
1082 case PH_ACTIVATE_IND:
1083 test_and_set_bit(MGR_PH_ACTIVE, &mgr->options);
1084 mISDN_FsmEvent(&mgr->deact, EV_ACTIVATE_IND, NULL);
1085 do_send(mgr);
1086 ret = 0;
1087 break;
1088 case PH_DEACTIVATE_IND:
1089 test_and_clear_bit(MGR_PH_ACTIVE, &mgr->options);
1090 mISDN_FsmEvent(&mgr->deact, EV_DEACTIVATE_IND, NULL);
1091 ret = 0;
1092 break;
1093 case DL_UNITDATA_REQ:
1094 return dl_unit_data(mgr, skb);
1095 }
1096 if (!ret)
1097 dev_kfree_skb(skb);
1098 return ret;
1099}
1100
1101static int
1102free_teimanager(struct manager *mgr)
1103{
1104 struct layer2 *l2, *nl2;
1105
1106 if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
1107 /* not locked lock is taken in release tei */
1108 mgr->up = NULL;
1109 if (test_bit(OPTION_L2_CLEANUP, &mgr->options)) {
1110 list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
1111 put_tei_msg(mgr, ID_REMOVE, 0, l2->tei);
1112 mutex_lock(&mgr->ch.st->lmutex);
1113 list_del(&l2->ch.list);
1114 mutex_unlock(&mgr->ch.st->lmutex);
1115 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
1116 }
1117 test_and_clear_bit(MGR_OPT_NETWORK, &mgr->options);
1118 } else {
1119 list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
1120 l2->up = NULL;
1121 }
1122 }
1123 }
1124 if (test_bit(MGR_OPT_USER, &mgr->options)) {
1125 if (list_empty(&mgr->layer2))
1126 test_and_clear_bit(MGR_OPT_USER, &mgr->options);
1127 }
1128 mgr->ch.st->dev->D.ctrl(&mgr->ch.st->dev->D, CLOSE_CHANNEL, NULL);
1129 return 0;
1130}
1131
1132static int
1133ctrl_teimanager(struct manager *mgr, void *arg)
1134{
1135 /* currently we only have one option */
1136 int clean = *((int *)arg);
1137
1138 if (clean)
1139 test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
1140 else
1141 test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
1142 return 0;
1143}
1144
1145/* This function does create a L2 for fixed TEI in NT Mode */
1146static int
1147check_data(struct manager *mgr, struct sk_buff *skb)
1148{
1149 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1150 int ret, tei;
1151 struct layer2 *l2;
1152
1153 if (*debug & DEBUG_L2_CTRL)
1154 printk(KERN_DEBUG "%s: prim(%x) id(%x)\n",
1155 __func__, hh->prim, hh->id);
1156 if (test_bit(MGR_OPT_USER, &mgr->options))
1157 return -ENOTCONN;
1158 if (hh->prim != PH_DATA_IND)
1159 return -ENOTCONN;
1160 if (skb->len != 3)
1161 return -ENOTCONN;
1162 if (skb->data[0] != 0)
1163 /* only SAPI 0 command */
1164 return -ENOTCONN;
1165 if (!(skb->data[1] & 1)) /* invalid EA1 */
1166 return -EINVAL;
1167 tei = skb->data[1] >> 0;
1168 if (tei > 63) /* not a fixed tei */
1169 return -ENOTCONN;
1170 if ((skb->data[2] & ~0x10) != SABME)
1171 return -ENOTCONN;
1172 /* We got a SABME for a fixed TEI */
1173 l2 = create_new_tei(mgr, tei);
1174 if (!l2)
1175 return -ENOMEM;
1176 ret = l2->ch.send(&l2->ch, skb);
1177 return ret;
1178}
1179
1180void
1181delete_teimanager(struct mISDNchannel *ch)
1182{
1183 struct manager *mgr;
1184 struct layer2 *l2, *nl2;
1185
1186 mgr = container_of(ch, struct manager, ch);
1187 /* not locked lock is taken in release tei */
1188 list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
1189 mutex_lock(&mgr->ch.st->lmutex);
1190 list_del(&l2->ch.list);
1191 mutex_unlock(&mgr->ch.st->lmutex);
1192 l2->ch.ctrl(&l2->ch, CLOSE_CHANNEL, NULL);
1193 }
1194 list_del(&mgr->ch.list);
1195 list_del(&mgr->bcast.list);
1196 skb_queue_purge(&mgr->sendq);
1197 kfree(mgr);
1198}
1199
1200static int
1201mgr_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
1202{
1203 struct manager *mgr;
1204 int ret = -EINVAL;
1205
1206 mgr = container_of(ch, struct manager, ch);
1207 if (*debug & DEBUG_L2_CTRL)
1208 printk(KERN_DEBUG "%s(%x, %p)\n", __func__, cmd, arg);
1209 switch (cmd) {
1210 case OPEN_CHANNEL:
1211 ret = create_teimgr(mgr, arg);
1212 break;
1213 case CLOSE_CHANNEL:
1214 ret = free_teimanager(mgr);
1215 break;
1216 case CONTROL_CHANNEL:
1217 ret = ctrl_teimanager(mgr, arg);
1218 break;
1219 case CHECK_DATA:
1220 ret = check_data(mgr, arg);
1221 break;
1222 }
1223 return ret;
1224}
1225
1226static int
1227mgr_bcast(struct mISDNchannel *ch, struct sk_buff *skb)
1228{
1229 struct manager *mgr = container_of(ch, struct manager, bcast);
1230 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1231 struct sk_buff *cskb = NULL;
1232 struct layer2 *l2;
1233 u_long flags;
1234 int ret;
1235
1236 read_lock_irqsave(&mgr->lock, flags);
1237 list_for_each_entry(l2, &mgr->layer2, list) {
1238 if ((hh->id & MISDN_ID_SAPI_MASK) ==
1239 (l2->ch.addr & MISDN_ID_SAPI_MASK)) {
1240 if (list_is_last(&l2->list, &mgr->layer2)) {
1241 cskb = skb;
1242 skb = NULL;
1243 } else {
1244 if (!cskb)
1245 cskb = skb_copy(skb, GFP_KERNEL);
1246 }
1247 if (cskb) {
1248 ret = l2->ch.send(&l2->ch, cskb);
1249 if (ret) {
1250 if (*debug & DEBUG_SEND_ERR)
1251 printk(KERN_DEBUG
1252 "%s ch%d prim(%x) addr(%x)"
1253 " err %d\n",
1254 __func__, l2->ch.nr,
1255 hh->prim, l2->ch.addr, ret);
1256 } else
1257 cskb = NULL;
1258 } else {
1259 printk(KERN_WARNING "%s ch%d addr %x no mem\n",
1260 __func__, ch->nr, ch->addr);
1261 goto out;
1262 }
1263 }
1264 }
1265out:
1266 read_unlock_irqrestore(&mgr->lock, flags);
1267 if (cskb)
1268 dev_kfree_skb(cskb);
1269 if (skb)
1270 dev_kfree_skb(skb);
1271 return 0;
1272}
1273
1274static int
1275mgr_bcast_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
1276{
1277
1278 return -EINVAL;
1279}
1280
1281int
1282create_teimanager(struct mISDNdevice *dev)
1283{
1284 struct manager *mgr;
1285
1286 mgr = kzalloc(sizeof(struct manager), GFP_KERNEL);
1287 if (!mgr)
1288 return -ENOMEM;
1289 INIT_LIST_HEAD(&mgr->layer2);
1290 mgr->lock = __RW_LOCK_UNLOCKED(mgr->lock);
1291 skb_queue_head_init(&mgr->sendq);
1292 mgr->nextid = 1;
1293 mgr->lastid = MISDN_ID_NONE;
1294 mgr->ch.send = mgr_send;
1295 mgr->ch.ctrl = mgr_ctrl;
1296 mgr->ch.st = dev->D.st;
1297 set_channel_address(&mgr->ch, TEI_SAPI, GROUP_TEI);
1298 add_layer2(&mgr->ch, dev->D.st);
1299 mgr->bcast.send = mgr_bcast;
1300 mgr->bcast.ctrl = mgr_bcast_ctrl;
1301 mgr->bcast.st = dev->D.st;
1302 set_channel_address(&mgr->bcast, 0, GROUP_TEI);
1303 add_layer2(&mgr->bcast, dev->D.st);
1304 mgr->deact.debug = *debug & DEBUG_MANAGER;
1305 mgr->deact.userdata = mgr;
1306 mgr->deact.printdebug = da_debug;
1307 mgr->deact.fsm = &deactfsm;
1308 mgr->deact.state = ST_L1_DEACT;
1309 mISDN_FsmInitTimer(&mgr->deact, &mgr->datimer);
1310 dev->teimgr = &mgr->ch;
1311 return 0;
1312}
1313
1314int TEIInit(u_int *deb)
1315{
1316 debug = deb;
1317 teifsmu.state_count = TEI_STATE_COUNT;
1318 teifsmu.event_count = TEI_EVENT_COUNT;
1319 teifsmu.strEvent = strTeiEvent;
1320 teifsmu.strState = strTeiState;
1321 mISDN_FsmNew(&teifsmu, TeiFnListUser, ARRAY_SIZE(TeiFnListUser));
1322 teifsmn.state_count = TEI_STATE_COUNT;
1323 teifsmn.event_count = TEI_EVENT_COUNT;
1324 teifsmn.strEvent = strTeiEvent;
1325 teifsmn.strState = strTeiState;
1326 mISDN_FsmNew(&teifsmn, TeiFnListNet, ARRAY_SIZE(TeiFnListNet));
1327 deactfsm.state_count = DEACT_STATE_COUNT;
1328 deactfsm.event_count = DEACT_EVENT_COUNT;
1329 deactfsm.strEvent = strDeactEvent;
1330 deactfsm.strState = strDeactState;
1331 mISDN_FsmNew(&deactfsm, DeactFnList, ARRAY_SIZE(DeactFnList));
1332 return 0;
1333}
1334
1335void TEIFree(void)
1336{
1337 mISDN_FsmFree(&teifsmu);
1338 mISDN_FsmFree(&teifsmn);
1339 mISDN_FsmFree(&deactfsm);
1340}
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
new file mode 100644
index 000000000000..b5fabc7019d8
--- /dev/null
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -0,0 +1,301 @@
1/*
2 *
3 * general timer device for using in ISDN stacks
4 *
5 * Author Karsten Keil <kkeil@novell.com>
6 *
7 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 */
19
20#include <linux/poll.h>
21#include <linux/vmalloc.h>
22#include <linux/timer.h>
23#include <linux/miscdevice.h>
24#include <linux/module.h>
25#include <linux/mISDNif.h>
26
27static int *debug;
28
29
30struct mISDNtimerdev {
31 int next_id;
32 struct list_head pending;
33 struct list_head expired;
34 wait_queue_head_t wait;
35 u_int work;
36 spinlock_t lock; /* protect lists */
37};
38
39struct mISDNtimer {
40 struct list_head list;
41 struct mISDNtimerdev *dev;
42 struct timer_list tl;
43 int id;
44};
45
46static int
47mISDN_open(struct inode *ino, struct file *filep)
48{
49 struct mISDNtimerdev *dev;
50
51 if (*debug & DEBUG_TIMER)
52 printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
53 dev = kmalloc(sizeof(struct mISDNtimerdev) , GFP_KERNEL);
54 if (!dev)
55 return -ENOMEM;
56 dev->next_id = 1;
57 INIT_LIST_HEAD(&dev->pending);
58 INIT_LIST_HEAD(&dev->expired);
59 spin_lock_init(&dev->lock);
60 dev->work = 0;
61 init_waitqueue_head(&dev->wait);
62 filep->private_data = dev;
63 __module_get(THIS_MODULE);
64 return 0;
65}
66
67static int
68mISDN_close(struct inode *ino, struct file *filep)
69{
70 struct mISDNtimerdev *dev = filep->private_data;
71 struct mISDNtimer *timer, *next;
72
73 if (*debug & DEBUG_TIMER)
74 printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
75 list_for_each_entry_safe(timer, next, &dev->pending, list) {
76 del_timer(&timer->tl);
77 kfree(timer);
78 }
79 list_for_each_entry_safe(timer, next, &dev->expired, list) {
80 kfree(timer);
81 }
82 kfree(dev);
83 module_put(THIS_MODULE);
84 return 0;
85}
86
87static ssize_t
88mISDN_read(struct file *filep, char *buf, size_t count, loff_t *off)
89{
90 struct mISDNtimerdev *dev = filep->private_data;
91 struct mISDNtimer *timer;
92 u_long flags;
93 int ret = 0;
94
95 if (*debug & DEBUG_TIMER)
96 printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__,
97 filep, buf, (int)count, off);
98 if (*off != filep->f_pos)
99 return -ESPIPE;
100
101 if (list_empty(&dev->expired) && (dev->work == 0)) {
102 if (filep->f_flags & O_NONBLOCK)
103 return -EAGAIN;
104 wait_event_interruptible(dev->wait, (dev->work ||
105 !list_empty(&dev->expired)));
106 if (signal_pending(current))
107 return -ERESTARTSYS;
108 }
109 if (count < sizeof(int))
110 return -ENOSPC;
111 if (dev->work)
112 dev->work = 0;
113 if (!list_empty(&dev->expired)) {
114 spin_lock_irqsave(&dev->lock, flags);
115 timer = (struct mISDNtimer *)dev->expired.next;
116 list_del(&timer->list);
117 spin_unlock_irqrestore(&dev->lock, flags);
118 if (put_user(timer->id, (int *)buf))
119 ret = -EFAULT;
120 else
121 ret = sizeof(int);
122 kfree(timer);
123 }
124 return ret;
125}
126
127static loff_t
128mISDN_llseek(struct file *filep, loff_t offset, int orig)
129{
130 return -ESPIPE;
131}
132
133static ssize_t
134mISDN_write(struct file *filep, const char *buf, size_t count, loff_t *off)
135{
136 return -EOPNOTSUPP;
137}
138
139static unsigned int
140mISDN_poll(struct file *filep, poll_table *wait)
141{
142 struct mISDNtimerdev *dev = filep->private_data;
143 unsigned int mask = POLLERR;
144
145 if (*debug & DEBUG_TIMER)
146 printk(KERN_DEBUG "%s(%p, %p)\n", __func__, filep, wait);
147 if (dev) {
148 poll_wait(filep, &dev->wait, wait);
149 mask = 0;
150 if (dev->work || !list_empty(&dev->expired))
151 mask |= (POLLIN | POLLRDNORM);
152 if (*debug & DEBUG_TIMER)
153 printk(KERN_DEBUG "%s work(%d) empty(%d)\n", __func__,
154 dev->work, list_empty(&dev->expired));
155 }
156 return mask;
157}
158
159static void
160dev_expire_timer(struct mISDNtimer *timer)
161{
162 u_long flags;
163
164 spin_lock_irqsave(&timer->dev->lock, flags);
165 list_del(&timer->list);
166 list_add_tail(&timer->list, &timer->dev->expired);
167 spin_unlock_irqrestore(&timer->dev->lock, flags);
168 wake_up_interruptible(&timer->dev->wait);
169}
170
171static int
172misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
173{
174 int id;
175 u_long flags;
176 struct mISDNtimer *timer;
177
178 if (!timeout) {
179 dev->work = 1;
180 wake_up_interruptible(&dev->wait);
181 id = 0;
182 } else {
183 timer = kzalloc(sizeof(struct mISDNtimer), GFP_KERNEL);
184 if (!timer)
185 return -ENOMEM;
186 spin_lock_irqsave(&dev->lock, flags);
187 timer->id = dev->next_id++;
188 if (dev->next_id < 0)
189 dev->next_id = 1;
190 list_add_tail(&timer->list, &dev->pending);
191 spin_unlock_irqrestore(&dev->lock, flags);
192 timer->dev = dev;
193 timer->tl.data = (long)timer;
194 timer->tl.function = (void *) dev_expire_timer;
195 init_timer(&timer->tl);
196 timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000);
197 add_timer(&timer->tl);
198 id = timer->id;
199 }
200 return id;
201}
202
203static int
204misdn_del_timer(struct mISDNtimerdev *dev, int id)
205{
206 u_long flags;
207 struct mISDNtimer *timer;
208 int ret = 0;
209
210 spin_lock_irqsave(&dev->lock, flags);
211 list_for_each_entry(timer, &dev->pending, list) {
212 if (timer->id == id) {
213 list_del_init(&timer->list);
214 del_timer(&timer->tl);
215 ret = timer->id;
216 kfree(timer);
217 goto unlock;
218 }
219 }
220unlock:
221 spin_unlock_irqrestore(&dev->lock, flags);
222 return ret;
223}
224
225static int
226mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
227 unsigned long arg)
228{
229 struct mISDNtimerdev *dev = filep->private_data;
230 int id, tout, ret = 0;
231
232
233 if (*debug & DEBUG_TIMER)
234 printk(KERN_DEBUG "%s(%p, %x, %lx)\n", __func__,
235 filep, cmd, arg);
236 switch (cmd) {
237 case IMADDTIMER:
238 if (get_user(tout, (int __user *)arg)) {
239 ret = -EFAULT;
240 break;
241 }
242 id = misdn_add_timer(dev, tout);
243 if (*debug & DEBUG_TIMER)
244 printk(KERN_DEBUG "%s add %d id %d\n", __func__,
245 tout, id);
246 if (id < 0) {
247 ret = id;
248 break;
249 }
250 if (put_user(id, (int __user *)arg))
251 ret = -EFAULT;
252 break;
253 case IMDELTIMER:
254 if (get_user(id, (int __user *)arg)) {
255 ret = -EFAULT;
256 break;
257 }
258 if (*debug & DEBUG_TIMER)
259 printk(KERN_DEBUG "%s del id %d\n", __func__, id);
260 id = misdn_del_timer(dev, id);
261 if (put_user(id, (int __user *)arg))
262 ret = -EFAULT;
263 break;
264 default:
265 ret = -EINVAL;
266 }
267 return ret;
268}
269
270static struct file_operations mISDN_fops = {
271 .llseek = mISDN_llseek,
272 .read = mISDN_read,
273 .write = mISDN_write,
274 .poll = mISDN_poll,
275 .ioctl = mISDN_ioctl,
276 .open = mISDN_open,
277 .release = mISDN_close,
278};
279
280static struct miscdevice mISDNtimer = {
281 .minor = MISC_DYNAMIC_MINOR,
282 .name = "mISDNtimer",
283 .fops = &mISDN_fops,
284};
285
286int
287mISDN_inittimer(int *deb)
288{
289 int err;
290
291 debug = deb;
292 err = misc_register(&mISDNtimer);
293 if (err)
294 printk(KERN_WARNING "mISDN: Could not register timer device\n");
295 return err;
296}
297
298void mISDN_timer_cleanup(void)
299{
300 misc_deregister(&mISDNtimer);
301}