aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorKarsten Keil <kkeil@suse.de>2008-07-26 19:54:58 -0400
committerKarsten Keil <kkeil@suse.de>2008-07-26 19:54:58 -0400
commit1b2b03f8e514e4f68e293846ba511a948b80243c (patch)
tree5ffb07d532afca95170ea0615bb74af78b0d0483 /drivers/isdn
parent04578dd330f1ec6bc9c4233833bee0d0ca73ff09 (diff)
Add mISDN core files
Add mISDN core files Signed-off-by: Karsten Keil <kkeil@suse.de>
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/mISDN/Kconfig9
-rw-r--r--drivers/isdn/mISDN/Makefile9
-rw-r--r--drivers/isdn/mISDN/core.c244
-rw-r--r--drivers/isdn/mISDN/core.h77
-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/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
15 files changed, 6835 insertions, 0 deletions
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
new file mode 100644
index 000000000000..231bd0d08316
--- /dev/null
+++ b/drivers/isdn/mISDN/Kconfig
@@ -0,0 +1,9 @@
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
diff --git a/drivers/isdn/mISDN/Makefile b/drivers/isdn/mISDN/Makefile
new file mode 100644
index 000000000000..87c563d33612
--- /dev/null
+++ b/drivers/isdn/mISDN/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for the modular ISDN driver
3#
4
5obj-$(CONFIG_MISDN) += mISDN_core.o
6
7# multi objects
8
9mISDN_core-objs := core.o fsm.o socket.o hwchannel.o stack.o layer1.o layer2.o tei.o timerdev.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/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/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}