blob: b6fbaec1d61247434c096c9a0d14e472b537aef1 [file] [log] [blame]
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001/*
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
Hannes Eder5b834352008-12-12 21:15:17 -080018#include <linux/mISDNif.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090019#include <linux/slab.h>
Hannes Eder5b834352008-12-12 21:15:17 -080020#include "core.h"
Karsten Keil1b2b03f2008-07-27 01:54:58 +020021#include "fsm.h"
22#include "layer2.h"
23
Hannes Ederdfa96ec2008-12-12 21:13:45 -080024static u_int *debug;
Karsten Keil1b2b03f2008-07-27 01:54:58 +020025
26static
27struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL};
28
29static char *strL2State[] =
30{
31 "ST_L2_1",
32 "ST_L2_2",
33 "ST_L2_3",
34 "ST_L2_4",
35 "ST_L2_5",
36 "ST_L2_6",
37 "ST_L2_7",
38 "ST_L2_8",
39};
40
41enum {
42 EV_L2_UI,
43 EV_L2_SABME,
44 EV_L2_DISC,
45 EV_L2_DM,
46 EV_L2_UA,
47 EV_L2_FRMR,
48 EV_L2_SUPER,
49 EV_L2_I,
50 EV_L2_DL_DATA,
51 EV_L2_ACK_PULL,
52 EV_L2_DL_UNITDATA,
53 EV_L2_DL_ESTABLISH_REQ,
54 EV_L2_DL_RELEASE_REQ,
55 EV_L2_MDL_ASSIGN,
56 EV_L2_MDL_REMOVE,
57 EV_L2_MDL_ERROR,
58 EV_L1_DEACTIVATE,
59 EV_L2_T200,
60 EV_L2_T203,
Karsten Keil8423e6b2012-05-04 04:15:32 +000061 EV_L2_T200I,
62 EV_L2_T203I,
Karsten Keil1b2b03f2008-07-27 01:54:58 +020063 EV_L2_SET_OWN_BUSY,
64 EV_L2_CLEAR_OWN_BUSY,
65 EV_L2_FRAME_ERROR,
66};
67
Joe Perches475be4d2012-02-19 19:52:38 -080068#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1)
Karsten Keil1b2b03f2008-07-27 01:54:58 +020069
70static char *strL2Event[] =
71{
72 "EV_L2_UI",
73 "EV_L2_SABME",
74 "EV_L2_DISC",
75 "EV_L2_DM",
76 "EV_L2_UA",
77 "EV_L2_FRMR",
78 "EV_L2_SUPER",
79 "EV_L2_I",
80 "EV_L2_DL_DATA",
81 "EV_L2_ACK_PULL",
82 "EV_L2_DL_UNITDATA",
83 "EV_L2_DL_ESTABLISH_REQ",
84 "EV_L2_DL_RELEASE_REQ",
85 "EV_L2_MDL_ASSIGN",
86 "EV_L2_MDL_REMOVE",
87 "EV_L2_MDL_ERROR",
88 "EV_L1_DEACTIVATE",
89 "EV_L2_T200",
90 "EV_L2_T203",
Karsten Keil8423e6b2012-05-04 04:15:32 +000091 "EV_L2_T200I",
92 "EV_L2_T203I",
Karsten Keil1b2b03f2008-07-27 01:54:58 +020093 "EV_L2_SET_OWN_BUSY",
94 "EV_L2_CLEAR_OWN_BUSY",
95 "EV_L2_FRAME_ERROR",
96};
97
98static void
99l2m_debug(struct FsmInst *fi, char *fmt, ...)
100{
101 struct layer2 *l2 = fi->userdata;
Joe Perches020f01e2010-11-09 14:35:16 +0000102 struct va_format vaf;
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200103 va_list va;
104
105 if (!(*debug & DEBUG_L2_FSM))
106 return;
Joe Perches020f01e2010-11-09 14:35:16 +0000107
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200108 va_start(va, fmt);
Joe Perches020f01e2010-11-09 14:35:16 +0000109
110 vaf.fmt = fmt;
111 vaf.va = &va;
112
113 printk(KERN_DEBUG "l2 (sapi %d tei %d): %pV\n",
114 l2->sapi, l2->tei, &vaf);
115
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200116 va_end(va);
117}
118
119inline u_int
120l2headersize(struct layer2 *l2, int ui)
121{
122 return ((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +
123 (test_bit(FLG_LAPD, &l2->flag) ? 2 : 1);
124}
125
126inline u_int
127l2addrsize(struct layer2 *l2)
128{
129 return test_bit(FLG_LAPD, &l2->flag) ? 2 : 1;
130}
131
132static u_int
133l2_newid(struct layer2 *l2)
134{
135 u_int id;
136
137 id = l2->next_id++;
138 if (id == 0x7fff)
139 l2->next_id = 1;
140 id <<= 16;
141 id |= l2->tei << 8;
142 id |= l2->sapi;
143 return id;
144}
145
146static void
147l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb)
148{
149 int err;
150
151 if (!l2->up)
152 return;
153 mISDN_HEAD_PRIM(skb) = prim;
154 mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr;
155 err = l2->up->send(l2->up, skb);
156 if (err) {
157 printk(KERN_WARNING "%s: err=%d\n", __func__, err);
158 dev_kfree_skb(skb);
159 }
160}
161
162static void
163l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)
164{
165 struct sk_buff *skb;
166 struct mISDNhead *hh;
167 int err;
168
169 if (!l2->up)
170 return;
171 skb = mI_alloc_skb(len, GFP_ATOMIC);
172 if (!skb)
173 return;
174 hh = mISDN_HEAD_P(skb);
175 hh->prim = prim;
176 hh->id = (l2->ch.nr << 16) | l2->ch.addr;
177 if (len)
178 memcpy(skb_put(skb, len), arg, len);
179 err = l2->up->send(l2->up, skb);
180 if (err) {
181 printk(KERN_WARNING "%s: err=%d\n", __func__, err);
182 dev_kfree_skb(skb);
183 }
184}
185
186static int
187l2down_skb(struct layer2 *l2, struct sk_buff *skb) {
188 int ret;
189
190 ret = l2->ch.recv(l2->ch.peer, skb);
191 if (ret && (*debug & DEBUG_L2_RECV))
192 printk(KERN_DEBUG "l2down_skb: ret(%d)\n", ret);
193 return ret;
194}
195
196static int
197l2down_raw(struct layer2 *l2, struct sk_buff *skb)
198{
199 struct mISDNhead *hh = mISDN_HEAD_P(skb);
200
201 if (hh->prim == PH_DATA_REQ) {
202 if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
203 skb_queue_tail(&l2->down_queue, skb);
204 return 0;
205 }
206 l2->down_id = mISDN_HEAD_ID(skb);
207 }
208 return l2down_skb(l2, skb);
209}
210
211static int
212l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb)
213{
214 struct mISDNhead *hh = mISDN_HEAD_P(skb);
215
216 hh->prim = prim;
217 hh->id = id;
218 return l2down_raw(l2, skb);
219}
220
221static int
222l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg)
223{
224 struct sk_buff *skb;
225 int err;
226 struct mISDNhead *hh;
227
228 skb = mI_alloc_skb(len, GFP_ATOMIC);
229 if (!skb)
230 return -ENOMEM;
231 hh = mISDN_HEAD_P(skb);
232 hh->prim = prim;
233 hh->id = id;
234 if (len)
235 memcpy(skb_put(skb, len), arg, len);
236 err = l2down_raw(l2, skb);
237 if (err)
238 dev_kfree_skb(skb);
239 return err;
240}
241
242static int
243ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {
244 struct sk_buff *nskb = skb;
245 int ret = -EAGAIN;
246
247 if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {
248 if (hh->id == l2->down_id) {
249 nskb = skb_dequeue(&l2->down_queue);
250 if (nskb) {
251 l2->down_id = mISDN_HEAD_ID(nskb);
252 if (l2down_skb(l2, nskb)) {
253 dev_kfree_skb(nskb);
254 l2->down_id = MISDN_ID_NONE;
255 }
256 } else
257 l2->down_id = MISDN_ID_NONE;
258 if (ret) {
259 dev_kfree_skb(skb);
260 ret = 0;
261 }
262 if (l2->down_id == MISDN_ID_NONE) {
263 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
264 mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
265 }
266 }
267 }
268 if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
269 nskb = skb_dequeue(&l2->down_queue);
270 if (nskb) {
271 l2->down_id = mISDN_HEAD_ID(nskb);
272 if (l2down_skb(l2, nskb)) {
273 dev_kfree_skb(nskb);
274 l2->down_id = MISDN_ID_NONE;
275 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
276 }
277 } else
278 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
279 }
280 return ret;
281}
282
Karsten Keil8423e6b2012-05-04 04:15:32 +0000283static void
284l2_timeout(struct FsmInst *fi, int event, void *arg)
285{
286 struct layer2 *l2 = fi->userdata;
287 struct sk_buff *skb;
288 struct mISDNhead *hh;
289
290 skb = mI_alloc_skb(0, GFP_ATOMIC);
291 if (!skb) {
292 printk(KERN_WARNING "L2(%d,%d) nr:%x timer %s lost - no skb\n",
293 l2->sapi, l2->tei, l2->ch.nr, event == EV_L2_T200 ?
294 "T200" : "T203");
295 return;
296 }
297 hh = mISDN_HEAD_P(skb);
298 hh->prim = event == EV_L2_T200 ? DL_TIMER200_IND : DL_TIMER203_IND;
299 hh->id = l2->ch.nr;
300 if (*debug & DEBUG_TIMER)
301 printk(KERN_DEBUG "L2(%d,%d) nr:%x timer %s expired\n",
302 l2->sapi, l2->tei, l2->ch.nr, event == EV_L2_T200 ?
303 "T200" : "T203");
304 if (l2->ch.st)
305 l2->ch.st->own.recv(&l2->ch.st->own, skb);
306}
307
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200308static int
309l2mgr(struct layer2 *l2, u_int prim, void *arg) {
310 long c = (long)arg;
311
312 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -0800313 "l2mgr: addr:%x prim %x %c\n", l2->id, prim, (char)c);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200314 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -0800315 !test_bit(FLG_FIXED_TEI, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200316 switch (c) {
317 case 'C':
318 case 'D':
319 case 'G':
320 case 'H':
321 l2_tei(l2, prim, (u_long)arg);
322 break;
323 }
324 }
325 return 0;
326}
327
328static void
329set_peer_busy(struct layer2 *l2) {
330 test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
331 if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))
332 test_and_set_bit(FLG_L2BLOCK, &l2->flag);
333}
334
335static void
336clear_peer_busy(struct layer2 *l2) {
337 if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag))
338 test_and_clear_bit(FLG_L2BLOCK, &l2->flag);
339}
340
341static void
342InitWin(struct layer2 *l2)
343{
344 int i;
345
346 for (i = 0; i < MAX_WINDOW; i++)
347 l2->windowar[i] = NULL;
348}
349
350static int
351freewin(struct layer2 *l2)
352{
353 int i, cnt = 0;
354
355 for (i = 0; i < MAX_WINDOW; i++) {
356 if (l2->windowar[i]) {
357 cnt++;
358 dev_kfree_skb(l2->windowar[i]);
359 l2->windowar[i] = NULL;
360 }
361 }
362 return cnt;
363}
364
365static void
366ReleaseWin(struct layer2 *l2)
367{
368 int cnt = freewin(l2);
369
370 if (cnt)
371 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -0800372 "isdnl2 freed %d skbuffs in release\n", cnt);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200373}
374
375inline unsigned int
376cansend(struct layer2 *l2)
377{
378 unsigned int p1;
379
380 if (test_bit(FLG_MOD128, &l2->flag))
381 p1 = (l2->vs - l2->va) % 128;
382 else
383 p1 = (l2->vs - l2->va) % 8;
384 return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag);
385}
386
387inline void
388clear_exception(struct layer2 *l2)
389{
390 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
391 test_and_clear_bit(FLG_REJEXC, &l2->flag);
392 test_and_clear_bit(FLG_OWN_BUSY, &l2->flag);
393 clear_peer_busy(l2);
394}
395
396static int
397sethdraddr(struct layer2 *l2, u_char *header, int rsp)
398{
399 u_char *ptr = header;
400 int crbit = rsp;
401
402 if (test_bit(FLG_LAPD, &l2->flag)) {
403 if (test_bit(FLG_LAPD_NET, &l2->flag))
404 crbit = !crbit;
405 *ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0);
406 *ptr++ = (l2->tei << 1) | 1;
407 return 2;
408 } else {
409 if (test_bit(FLG_ORIG, &l2->flag))
410 crbit = !crbit;
411 if (crbit)
412 *ptr++ = l2->addr.B;
413 else
414 *ptr++ = l2->addr.A;
415 return 1;
416 }
417}
418
419static inline void
420enqueue_super(struct layer2 *l2, struct sk_buff *skb)
421{
422 if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
423 dev_kfree_skb(skb);
424}
425
426static inline void
427enqueue_ui(struct layer2 *l2, struct sk_buff *skb)
428{
429 if (l2->tm)
430 l2_tei(l2, MDL_STATUS_UI_IND, 0);
431 if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
432 dev_kfree_skb(skb);
433}
434
435inline int
436IsUI(u_char *data)
437{
438 return (data[0] & 0xef) == UI;
439}
440
441inline int
442IsUA(u_char *data)
443{
444 return (data[0] & 0xef) == UA;
445}
446
447inline int
448IsDM(u_char *data)
449{
450 return (data[0] & 0xef) == DM;
451}
452
453inline int
454IsDISC(u_char *data)
455{
456 return (data[0] & 0xef) == DISC;
457}
458
459inline int
460IsRR(u_char *data, struct layer2 *l2)
461{
462 if (test_bit(FLG_MOD128, &l2->flag))
463 return data[0] == RR;
464 else
465 return (data[0] & 0xf) == 1;
466}
467
468inline int
469IsSFrame(u_char *data, struct layer2 *l2)
470{
471 register u_char d = *data;
472
473 if (!test_bit(FLG_MOD128, &l2->flag))
474 d &= 0xf;
475 return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c);
476}
477
478inline int
479IsSABME(u_char *data, struct layer2 *l2)
480{
481 u_char d = data[0] & ~0x10;
482
483 return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM;
484}
485
486inline int
487IsREJ(u_char *data, struct layer2 *l2)
488{
489 return test_bit(FLG_MOD128, &l2->flag) ?
490 data[0] == REJ : (data[0] & 0xf) == REJ;
491}
492
493inline int
494IsFRMR(u_char *data)
495{
496 return (data[0] & 0xef) == FRMR;
497}
498
499inline int
500IsRNR(u_char *data, struct layer2 *l2)
501{
502 return test_bit(FLG_MOD128, &l2->flag) ?
Joe Perches475be4d2012-02-19 19:52:38 -0800503 data[0] == RNR : (data[0] & 0xf) == RNR;
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200504}
505
Hannes Eder5b834352008-12-12 21:15:17 -0800506static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200507iframe_error(struct layer2 *l2, struct sk_buff *skb)
508{
509 u_int i;
510 int rsp = *skb->data & 0x2;
511
512 i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1);
513 if (test_bit(FLG_ORIG, &l2->flag))
514 rsp = !rsp;
515 if (rsp)
516 return 'L';
517 if (skb->len < i)
518 return 'N';
519 if ((skb->len - i) > l2->maxlen)
520 return 'O';
521 return 0;
522}
523
Hannes Eder5b834352008-12-12 21:15:17 -0800524static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200525super_error(struct layer2 *l2, struct sk_buff *skb)
526{
527 if (skb->len != l2addrsize(l2) +
528 (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1))
529 return 'N';
530 return 0;
531}
532
Hannes Eder5b834352008-12-12 21:15:17 -0800533static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200534unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp)
535{
536 int rsp = (*skb->data & 0x2) >> 1;
537 if (test_bit(FLG_ORIG, &l2->flag))
538 rsp = !rsp;
539 if (rsp != wantrsp)
540 return 'L';
541 if (skb->len != l2addrsize(l2) + 1)
542 return 'N';
543 return 0;
544}
545
Hannes Eder5b834352008-12-12 21:15:17 -0800546static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200547UI_error(struct layer2 *l2, struct sk_buff *skb)
548{
549 int rsp = *skb->data & 0x2;
550 if (test_bit(FLG_ORIG, &l2->flag))
551 rsp = !rsp;
552 if (rsp)
553 return 'L';
554 if (skb->len > l2->maxlen + l2addrsize(l2) + 1)
555 return 'O';
556 return 0;
557}
558
Hannes Eder5b834352008-12-12 21:15:17 -0800559static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200560FRMR_error(struct layer2 *l2, struct sk_buff *skb)
561{
562 u_int headers = l2addrsize(l2) + 1;
563 u_char *datap = skb->data + headers;
564 int rsp = *skb->data & 0x2;
565
566 if (test_bit(FLG_ORIG, &l2->flag))
567 rsp = !rsp;
568 if (!rsp)
569 return 'L';
570 if (test_bit(FLG_MOD128, &l2->flag)) {
571 if (skb->len < headers + 5)
572 return 'N';
573 else if (*debug & DEBUG_L2)
574 l2m_debug(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -0800575 "FRMR information %2x %2x %2x %2x %2x",
576 datap[0], datap[1], datap[2], datap[3], datap[4]);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200577 } else {
578 if (skb->len < headers + 3)
579 return 'N';
580 else if (*debug & DEBUG_L2)
581 l2m_debug(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -0800582 "FRMR information %2x %2x %2x",
583 datap[0], datap[1], datap[2]);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200584 }
585 return 0;
586}
587
588static unsigned int
589legalnr(struct layer2 *l2, unsigned int nr)
590{
591 if (test_bit(FLG_MOD128, &l2->flag))
592 return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128);
593 else
594 return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8);
595}
596
597static void
598setva(struct layer2 *l2, unsigned int nr)
599{
600 struct sk_buff *skb;
601
602 while (l2->va != nr) {
603 l2->va++;
604 if (test_bit(FLG_MOD128, &l2->flag))
605 l2->va %= 128;
606 else
607 l2->va %= 8;
608 if (l2->windowar[l2->sow]) {
609 skb_trim(l2->windowar[l2->sow], 0);
610 skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);
611 l2->windowar[l2->sow] = NULL;
612 }
613 l2->sow = (l2->sow + 1) % l2->window;
614 }
615 skb = skb_dequeue(&l2->tmp_queue);
616 while (skb) {
617 dev_kfree_skb(skb);
618 skb = skb_dequeue(&l2->tmp_queue);
619 }
620}
621
622static void
623send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
624{
625 u_char tmp[MAX_L2HEADER_LEN];
626 int i;
627
628 i = sethdraddr(l2, tmp, cr);
629 tmp[i++] = cmd;
630 if (skb)
631 skb_trim(skb, 0);
632 else {
633 skb = mI_alloc_skb(i, GFP_ATOMIC);
634 if (!skb) {
635 printk(KERN_WARNING "%s: can't alloc skbuff\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800636 __func__);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200637 return;
638 }
639 }
640 memcpy(skb_put(skb, i), tmp, i);
641 enqueue_super(l2, skb);
642}
643
644
645inline u_char
646get_PollFlag(struct layer2 *l2, struct sk_buff *skb)
647{
648 return skb->data[l2addrsize(l2)] & 0x10;
649}
650
651inline u_char
652get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb)
653{
654 u_char PF;
655
656 PF = get_PollFlag(l2, skb);
657 dev_kfree_skb(skb);
658 return PF;
659}
660
661inline void
662start_t200(struct layer2 *l2, int i)
663{
664 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
665 test_and_set_bit(FLG_T200_RUN, &l2->flag);
666}
667
668inline void
669restart_t200(struct layer2 *l2, int i)
670{
671 mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
672 test_and_set_bit(FLG_T200_RUN, &l2->flag);
673}
674
675inline void
676stop_t200(struct layer2 *l2, int i)
677{
678 if (test_and_clear_bit(FLG_T200_RUN, &l2->flag))
679 mISDN_FsmDelTimer(&l2->t200, i);
680}
681
682inline void
683st5_dl_release_l2l3(struct layer2 *l2)
684{
685 int pr;
686
687 if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
688 pr = DL_RELEASE_CNF;
689 else
690 pr = DL_RELEASE_IND;
691 l2up_create(l2, pr, 0, NULL);
692}
693
694inline void
695lapb_dl_release_l2l3(struct layer2 *l2, int f)
696{
697 if (test_bit(FLG_LAPB, &l2->flag))
698 l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL);
699 l2up_create(l2, f, 0, NULL);
700}
701
702static void
703establishlink(struct FsmInst *fi)
704{
705 struct layer2 *l2 = fi->userdata;
706 u_char cmd;
707
708 clear_exception(l2);
709 l2->rc = 0;
710 cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10;
711 send_uframe(l2, NULL, cmd, CMD);
712 mISDN_FsmDelTimer(&l2->t203, 1);
713 restart_t200(l2, 1);
714 test_and_clear_bit(FLG_PEND_REL, &l2->flag);
715 freewin(l2);
716 mISDN_FsmChangeState(fi, ST_L2_5);
717}
718
719static void
720l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)
721{
722 struct sk_buff *skb = arg;
723 struct layer2 *l2 = fi->userdata;
724
725 if (get_PollFlagFree(l2, skb))
726 l2mgr(l2, MDL_ERROR_IND, (void *) 'C');
727 else
728 l2mgr(l2, MDL_ERROR_IND, (void *) 'D');
729
730}
731
732static void
733l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
734{
735 struct sk_buff *skb = arg;
736 struct layer2 *l2 = fi->userdata;
737
738 if (get_PollFlagFree(l2, skb))
739 l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
740 else {
741 l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
742 establishlink(fi);
743 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
744 }
745}
746
747static void
748l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
749{
750 struct sk_buff *skb = arg;
751 struct layer2 *l2 = fi->userdata;
752
753 if (get_PollFlagFree(l2, skb))
754 l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
755 else
756 l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
757 establishlink(fi);
758 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
759}
760
761static void
762l2_go_st3(struct FsmInst *fi, int event, void *arg)
763{
764 dev_kfree_skb((struct sk_buff *)arg);
765 mISDN_FsmChangeState(fi, ST_L2_3);
766}
767
768static void
769l2_mdl_assign(struct FsmInst *fi, int event, void *arg)
770{
771 struct layer2 *l2 = fi->userdata;
772
773 mISDN_FsmChangeState(fi, ST_L2_3);
774 dev_kfree_skb((struct sk_buff *)arg);
775 l2_tei(l2, MDL_ASSIGN_IND, 0);
776}
777
778static void
779l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg)
780{
781 struct layer2 *l2 = fi->userdata;
782 struct sk_buff *skb = arg;
783
784 skb_queue_tail(&l2->ui_queue, skb);
785 mISDN_FsmChangeState(fi, ST_L2_2);
786 l2_tei(l2, MDL_ASSIGN_IND, 0);
787}
788
789static void
790l2_queue_ui(struct FsmInst *fi, int event, void *arg)
791{
792 struct layer2 *l2 = fi->userdata;
793 struct sk_buff *skb = arg;
794
795 skb_queue_tail(&l2->ui_queue, skb);
796}
797
798static void
799tx_ui(struct layer2 *l2)
800{
801 struct sk_buff *skb;
802 u_char header[MAX_L2HEADER_LEN];
803 int i;
804
805 i = sethdraddr(l2, header, CMD);
806 if (test_bit(FLG_LAPD_NET, &l2->flag))
807 header[1] = 0xff; /* tei 127 */
808 header[i++] = UI;
809 while ((skb = skb_dequeue(&l2->ui_queue))) {
810 memcpy(skb_push(skb, i), header, i);
811 enqueue_ui(l2, skb);
812 }
813}
814
815static void
816l2_send_ui(struct FsmInst *fi, int event, void *arg)
817{
818 struct layer2 *l2 = fi->userdata;
819 struct sk_buff *skb = arg;
820
821 skb_queue_tail(&l2->ui_queue, skb);
822 tx_ui(l2);
823}
824
825static void
826l2_got_ui(struct FsmInst *fi, int event, void *arg)
827{
828 struct layer2 *l2 = fi->userdata;
829 struct sk_buff *skb = arg;
830
831 skb_pull(skb, l2headersize(l2, 1));
832/*
833 * in states 1-3 for broadcast
834 */
835
836 if (l2->tm)
837 l2_tei(l2, MDL_STATUS_UI_IND, 0);
838 l2up(l2, DL_UNITDATA_IND, skb);
839}
840
841static void
842l2_establish(struct FsmInst *fi, int event, void *arg)
843{
844 struct sk_buff *skb = arg;
845 struct layer2 *l2 = fi->userdata;
846
847 establishlink(fi);
848 test_and_set_bit(FLG_L3_INIT, &l2->flag);
849 dev_kfree_skb(skb);
850}
851
852static void
853l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)
854{
855 struct sk_buff *skb = arg;
856 struct layer2 *l2 = fi->userdata;
857
858 skb_queue_purge(&l2->i_queue);
859 test_and_set_bit(FLG_L3_INIT, &l2->flag);
860 test_and_clear_bit(FLG_PEND_REL, &l2->flag);
861 dev_kfree_skb(skb);
862}
863
864static void
865l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)
866{
867 struct sk_buff *skb = arg;
868 struct layer2 *l2 = fi->userdata;
869
870 skb_queue_purge(&l2->i_queue);
871 establishlink(fi);
872 test_and_set_bit(FLG_L3_INIT, &l2->flag);
873 dev_kfree_skb(skb);
874}
875
876static void
877l2_release(struct FsmInst *fi, int event, void *arg)
878{
879 struct layer2 *l2 = fi->userdata;
880 struct sk_buff *skb = arg;
881
882 skb_trim(skb, 0);
883 l2up(l2, DL_RELEASE_CNF, skb);
884}
885
886static void
887l2_pend_rel(struct FsmInst *fi, int event, void *arg)
888{
889 struct sk_buff *skb = arg;
890 struct layer2 *l2 = fi->userdata;
891
892 test_and_set_bit(FLG_PEND_REL, &l2->flag);
893 dev_kfree_skb(skb);
894}
895
896static void
897l2_disconnect(struct FsmInst *fi, int event, void *arg)
898{
899 struct layer2 *l2 = fi->userdata;
900 struct sk_buff *skb = arg;
901
902 skb_queue_purge(&l2->i_queue);
903 freewin(l2);
904 mISDN_FsmChangeState(fi, ST_L2_6);
905 l2->rc = 0;
906 send_uframe(l2, NULL, DISC | 0x10, CMD);
907 mISDN_FsmDelTimer(&l2->t203, 1);
908 restart_t200(l2, 2);
909 if (skb)
910 dev_kfree_skb(skb);
911}
912
913static void
914l2_start_multi(struct FsmInst *fi, int event, void *arg)
915{
916 struct layer2 *l2 = fi->userdata;
917 struct sk_buff *skb = arg;
918
919 l2->vs = 0;
920 l2->va = 0;
921 l2->vr = 0;
922 l2->sow = 0;
923 clear_exception(l2);
924 send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
925 mISDN_FsmChangeState(fi, ST_L2_7);
926 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
927 skb_trim(skb, 0);
928 l2up(l2, DL_ESTABLISH_IND, skb);
929 if (l2->tm)
930 l2_tei(l2, MDL_STATUS_UP_IND, 0);
931}
932
933static void
934l2_send_UA(struct FsmInst *fi, int event, void *arg)
935{
936 struct layer2 *l2 = fi->userdata;
937 struct sk_buff *skb = arg;
938
939 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
940}
941
942static void
943l2_send_DM(struct FsmInst *fi, int event, void *arg)
944{
945 struct layer2 *l2 = fi->userdata;
946 struct sk_buff *skb = arg;
947
948 send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP);
949}
950
951static void
952l2_restart_multi(struct FsmInst *fi, int event, void *arg)
953{
954 struct layer2 *l2 = fi->userdata;
955 struct sk_buff *skb = arg;
956 int est = 0;
957
958 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
959
960 l2mgr(l2, MDL_ERROR_IND, (void *) 'F');
961
962 if (l2->vs != l2->va) {
963 skb_queue_purge(&l2->i_queue);
964 est = 1;
965 }
966
967 clear_exception(l2);
968 l2->vs = 0;
969 l2->va = 0;
970 l2->vr = 0;
971 l2->sow = 0;
972 mISDN_FsmChangeState(fi, ST_L2_7);
973 stop_t200(l2, 3);
974 mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
975
976 if (est)
977 l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);
978/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
979 * MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,
980 * 0, NULL, 0);
981 */
982 if (skb_queue_len(&l2->i_queue) && cansend(l2))
983 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
984}
985
986static void
987l2_stop_multi(struct FsmInst *fi, int event, void *arg)
988{
989 struct layer2 *l2 = fi->userdata;
990 struct sk_buff *skb = arg;
991
992 mISDN_FsmChangeState(fi, ST_L2_4);
993 mISDN_FsmDelTimer(&l2->t203, 3);
994 stop_t200(l2, 4);
995
996 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
997 skb_queue_purge(&l2->i_queue);
998 freewin(l2);
999 lapb_dl_release_l2l3(l2, DL_RELEASE_IND);
1000 if (l2->tm)
1001 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1002}
1003
1004static void
1005l2_connected(struct FsmInst *fi, int event, void *arg)
1006{
1007 struct layer2 *l2 = fi->userdata;
1008 struct sk_buff *skb = arg;
1009 int pr = -1;
1010
1011 if (!get_PollFlag(l2, skb)) {
1012 l2_mdl_error_ua(fi, event, arg);
1013 return;
1014 }
1015 dev_kfree_skb(skb);
1016 if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
1017 l2_disconnect(fi, event, NULL);
1018 if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {
1019 pr = DL_ESTABLISH_CNF;
1020 } else if (l2->vs != l2->va) {
1021 skb_queue_purge(&l2->i_queue);
1022 pr = DL_ESTABLISH_IND;
1023 }
1024 stop_t200(l2, 5);
1025 l2->vr = 0;
1026 l2->vs = 0;
1027 l2->va = 0;
1028 l2->sow = 0;
1029 mISDN_FsmChangeState(fi, ST_L2_7);
1030 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
1031 if (pr != -1)
1032 l2up_create(l2, pr, 0, NULL);
1033
1034 if (skb_queue_len(&l2->i_queue) && cansend(l2))
1035 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1036
1037 if (l2->tm)
1038 l2_tei(l2, MDL_STATUS_UP_IND, 0);
1039}
1040
1041static void
1042l2_released(struct FsmInst *fi, int event, void *arg)
1043{
1044 struct layer2 *l2 = fi->userdata;
1045 struct sk_buff *skb = arg;
1046
1047 if (!get_PollFlag(l2, skb)) {
1048 l2_mdl_error_ua(fi, event, arg);
1049 return;
1050 }
1051 dev_kfree_skb(skb);
1052 stop_t200(l2, 6);
1053 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1054 mISDN_FsmChangeState(fi, ST_L2_4);
1055 if (l2->tm)
1056 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1057}
1058
1059static void
1060l2_reestablish(struct FsmInst *fi, int event, void *arg)
1061{
1062 struct layer2 *l2 = fi->userdata;
1063 struct sk_buff *skb = arg;
1064
1065 if (!get_PollFlagFree(l2, skb)) {
1066 establishlink(fi);
1067 test_and_set_bit(FLG_L3_INIT, &l2->flag);
1068 }
1069}
1070
1071static void
1072l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
1073{
1074 struct layer2 *l2 = fi->userdata;
1075 struct sk_buff *skb = arg;
1076
1077 if (get_PollFlagFree(l2, skb)) {
1078 stop_t200(l2, 7);
1079 if (!test_bit(FLG_L3_INIT, &l2->flag))
1080 skb_queue_purge(&l2->i_queue);
1081 if (test_bit(FLG_LAPB, &l2->flag))
1082 l2down_create(l2, PH_DEACTIVATE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08001083 l2_newid(l2), 0, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001084 st5_dl_release_l2l3(l2);
1085 mISDN_FsmChangeState(fi, ST_L2_4);
1086 if (l2->tm)
1087 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1088 }
1089}
1090
1091static void
1092l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
1093{
1094 struct layer2 *l2 = fi->userdata;
1095 struct sk_buff *skb = arg;
1096
1097 if (get_PollFlagFree(l2, skb)) {
1098 stop_t200(l2, 8);
1099 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1100 mISDN_FsmChangeState(fi, ST_L2_4);
1101 if (l2->tm)
1102 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1103 }
1104}
1105
Hannes Eder5b834352008-12-12 21:15:17 -08001106static void
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001107enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
1108{
1109 struct sk_buff *skb;
1110 u_char tmp[MAX_L2HEADER_LEN];
1111 int i;
1112
1113 i = sethdraddr(l2, tmp, cr);
1114 if (test_bit(FLG_MOD128, &l2->flag)) {
1115 tmp[i++] = typ;
1116 tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0);
1117 } else
1118 tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0);
1119 skb = mI_alloc_skb(i, GFP_ATOMIC);
1120 if (!skb) {
1121 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001122 "isdnl2 can't alloc sbbuff for enquiry_cr\n");
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001123 return;
1124 }
1125 memcpy(skb_put(skb, i), tmp, i);
1126 enqueue_super(l2, skb);
1127}
1128
1129inline void
1130enquiry_response(struct layer2 *l2)
1131{
1132 if (test_bit(FLG_OWN_BUSY, &l2->flag))
1133 enquiry_cr(l2, RNR, RSP, 1);
1134 else
1135 enquiry_cr(l2, RR, RSP, 1);
1136 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1137}
1138
1139inline void
1140transmit_enquiry(struct layer2 *l2)
1141{
1142 if (test_bit(FLG_OWN_BUSY, &l2->flag))
1143 enquiry_cr(l2, RNR, CMD, 1);
1144 else
1145 enquiry_cr(l2, RR, CMD, 1);
1146 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1147 start_t200(l2, 9);
1148}
1149
1150
1151static void
1152nrerrorrecovery(struct FsmInst *fi)
1153{
1154 struct layer2 *l2 = fi->userdata;
1155
1156 l2mgr(l2, MDL_ERROR_IND, (void *) 'J');
1157 establishlink(fi);
1158 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1159}
1160
1161static void
1162invoke_retransmission(struct layer2 *l2, unsigned int nr)
1163{
1164 u_int p1;
1165
1166 if (l2->vs != nr) {
1167 while (l2->vs != nr) {
1168 (l2->vs)--;
1169 if (test_bit(FLG_MOD128, &l2->flag)) {
1170 l2->vs %= 128;
1171 p1 = (l2->vs - l2->va) % 128;
1172 } else {
1173 l2->vs %= 8;
1174 p1 = (l2->vs - l2->va) % 8;
1175 }
1176 p1 = (p1 + l2->sow) % l2->window;
1177 if (l2->windowar[p1])
1178 skb_queue_head(&l2->i_queue, l2->windowar[p1]);
1179 else
1180 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001181 "%s: windowar[%d] is NULL\n",
1182 __func__, p1);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001183 l2->windowar[p1] = NULL;
1184 }
1185 mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
1186 }
1187}
1188
1189static void
1190l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
1191{
1192 struct layer2 *l2 = fi->userdata;
1193 struct sk_buff *skb = arg;
1194 int PollFlag, rsp, typ = RR;
1195 unsigned int nr;
1196
1197 rsp = *skb->data & 0x2;
1198 if (test_bit(FLG_ORIG, &l2->flag))
1199 rsp = !rsp;
1200
1201 skb_pull(skb, l2addrsize(l2));
1202 if (IsRNR(skb->data, l2)) {
1203 set_peer_busy(l2);
1204 typ = RNR;
1205 } else
1206 clear_peer_busy(l2);
1207 if (IsREJ(skb->data, l2))
1208 typ = REJ;
1209
1210 if (test_bit(FLG_MOD128, &l2->flag)) {
1211 PollFlag = (skb->data[1] & 0x1) == 0x1;
1212 nr = skb->data[1] >> 1;
1213 } else {
1214 PollFlag = (skb->data[0] & 0x10);
1215 nr = (skb->data[0] >> 5) & 0x7;
1216 }
1217 dev_kfree_skb(skb);
1218
1219 if (PollFlag) {
1220 if (rsp)
1221 l2mgr(l2, MDL_ERROR_IND, (void *) 'A');
1222 else
1223 enquiry_response(l2);
1224 }
1225 if (legalnr(l2, nr)) {
1226 if (typ == REJ) {
1227 setva(l2, nr);
1228 invoke_retransmission(l2, nr);
1229 stop_t200(l2, 10);
1230 if (mISDN_FsmAddTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001231 EV_L2_T203, NULL, 6))
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001232 l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");
1233 } else if ((nr == l2->vs) && (typ == RR)) {
1234 setva(l2, nr);
1235 stop_t200(l2, 11);
1236 mISDN_FsmRestartTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001237 EV_L2_T203, NULL, 7);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001238 } else if ((l2->va != nr) || (typ == RNR)) {
1239 setva(l2, nr);
1240 if (typ != RR)
1241 mISDN_FsmDelTimer(&l2->t203, 9);
1242 restart_t200(l2, 12);
1243 }
1244 if (skb_queue_len(&l2->i_queue) && (typ == RR))
1245 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1246 } else
1247 nrerrorrecovery(fi);
1248}
1249
1250static void
1251l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
1252{
1253 struct layer2 *l2 = fi->userdata;
1254 struct sk_buff *skb = arg;
1255
1256 if (!test_bit(FLG_L3_INIT, &l2->flag))
1257 skb_queue_tail(&l2->i_queue, skb);
1258 else
1259 dev_kfree_skb(skb);
1260}
1261
1262static void
1263l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)
1264{
1265 struct layer2 *l2 = fi->userdata;
1266 struct sk_buff *skb = arg;
1267
1268 skb_queue_tail(&l2->i_queue, skb);
1269 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1270}
1271
1272static void
1273l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)
1274{
1275 struct layer2 *l2 = fi->userdata;
1276 struct sk_buff *skb = arg;
1277
1278 skb_queue_tail(&l2->i_queue, skb);
1279}
1280
1281static void
1282l2_got_iframe(struct FsmInst *fi, int event, void *arg)
1283{
1284 struct layer2 *l2 = fi->userdata;
1285 struct sk_buff *skb = arg;
1286 int PollFlag, i;
1287 u_int ns, nr;
1288
1289 i = l2addrsize(l2);
1290 if (test_bit(FLG_MOD128, &l2->flag)) {
1291 PollFlag = ((skb->data[i + 1] & 0x1) == 0x1);
1292 ns = skb->data[i] >> 1;
1293 nr = (skb->data[i + 1] >> 1) & 0x7f;
1294 } else {
1295 PollFlag = (skb->data[i] & 0x10);
1296 ns = (skb->data[i] >> 1) & 0x7;
1297 nr = (skb->data[i] >> 5) & 0x7;
1298 }
1299 if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
1300 dev_kfree_skb(skb);
1301 if (PollFlag)
1302 enquiry_response(l2);
1303 } else {
1304 if (l2->vr == ns) {
1305 l2->vr++;
1306 if (test_bit(FLG_MOD128, &l2->flag))
1307 l2->vr %= 128;
1308 else
1309 l2->vr %= 8;
1310 test_and_clear_bit(FLG_REJEXC, &l2->flag);
1311 if (PollFlag)
1312 enquiry_response(l2);
1313 else
1314 test_and_set_bit(FLG_ACK_PEND, &l2->flag);
1315 skb_pull(skb, l2headersize(l2, 0));
1316 l2up(l2, DL_DATA_IND, skb);
1317 } else {
1318 /* n(s)!=v(r) */
1319 dev_kfree_skb(skb);
1320 if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
1321 if (PollFlag)
1322 enquiry_response(l2);
1323 } else {
1324 enquiry_cr(l2, REJ, RSP, PollFlag);
1325 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1326 }
1327 }
1328 }
1329 if (legalnr(l2, nr)) {
1330 if (!test_bit(FLG_PEER_BUSY, &l2->flag) &&
1331 (fi->state == ST_L2_7)) {
1332 if (nr == l2->vs) {
1333 stop_t200(l2, 13);
1334 mISDN_FsmRestartTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001335 EV_L2_T203, NULL, 7);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001336 } else if (nr != l2->va)
1337 restart_t200(l2, 14);
1338 }
1339 setva(l2, nr);
1340 } else {
1341 nrerrorrecovery(fi);
1342 return;
1343 }
1344 if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7))
1345 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1346 if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag))
1347 enquiry_cr(l2, RR, RSP, 0);
1348}
1349
1350static void
1351l2_got_tei(struct FsmInst *fi, int event, void *arg)
1352{
1353 struct layer2 *l2 = fi->userdata;
1354 u_int info;
1355
1356 l2->tei = (signed char)(long)arg;
1357 set_channel_address(&l2->ch, l2->sapi, l2->tei);
1358 info = DL_INFO_L2_CONNECT;
1359 l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info);
1360 if (fi->state == ST_L2_3) {
1361 establishlink(fi);
1362 test_and_set_bit(FLG_L3_INIT, &l2->flag);
1363 } else
1364 mISDN_FsmChangeState(fi, ST_L2_4);
1365 if (skb_queue_len(&l2->ui_queue))
1366 tx_ui(l2);
1367}
1368
1369static void
1370l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
1371{
1372 struct layer2 *l2 = fi->userdata;
1373
1374 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001375 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001376 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1377 } else if (l2->rc == l2->N200) {
1378 mISDN_FsmChangeState(fi, ST_L2_4);
1379 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1380 skb_queue_purge(&l2->i_queue);
1381 l2mgr(l2, MDL_ERROR_IND, (void *) 'G');
1382 if (test_bit(FLG_LAPB, &l2->flag))
1383 l2down_create(l2, PH_DEACTIVATE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08001384 l2_newid(l2), 0, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001385 st5_dl_release_l2l3(l2);
1386 if (l2->tm)
1387 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1388 } else {
1389 l2->rc++;
1390 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1391 send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?
Joe Perches475be4d2012-02-19 19:52:38 -08001392 SABME : SABM) | 0x10, CMD);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001393 }
1394}
1395
1396static void
1397l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
1398{
1399 struct layer2 *l2 = fi->userdata;
1400
1401 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001402 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001403 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1404 } else if (l2->rc == l2->N200) {
1405 mISDN_FsmChangeState(fi, ST_L2_4);
1406 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1407 l2mgr(l2, MDL_ERROR_IND, (void *) 'H');
1408 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1409 if (l2->tm)
1410 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1411 } else {
1412 l2->rc++;
1413 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,
Joe Perches475be4d2012-02-19 19:52:38 -08001414 NULL, 9);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001415 send_uframe(l2, NULL, DISC | 0x10, CMD);
1416 }
1417}
1418
1419static void
1420l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
1421{
1422 struct layer2 *l2 = fi->userdata;
1423
1424 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001425 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001426 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1427 return;
1428 }
1429 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1430 l2->rc = 0;
1431 mISDN_FsmChangeState(fi, ST_L2_8);
1432 transmit_enquiry(l2);
1433 l2->rc++;
1434}
1435
1436static void
1437l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
1438{
1439 struct layer2 *l2 = fi->userdata;
1440
1441 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001442 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001443 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1444 return;
1445 }
1446 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1447 if (l2->rc == l2->N200) {
1448 l2mgr(l2, MDL_ERROR_IND, (void *) 'I');
1449 establishlink(fi);
1450 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1451 } else {
1452 transmit_enquiry(l2);
1453 l2->rc++;
1454 }
1455}
1456
1457static void
1458l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
1459{
1460 struct layer2 *l2 = fi->userdata;
1461
1462 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001463 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001464 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);
1465 return;
1466 }
1467 mISDN_FsmChangeState(fi, ST_L2_8);
1468 transmit_enquiry(l2);
1469 l2->rc = 0;
1470}
1471
1472static void
1473l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
1474{
1475 struct layer2 *l2 = fi->userdata;
1476 struct sk_buff *skb, *nskb, *oskb;
1477 u_char header[MAX_L2HEADER_LEN];
1478 u_int i, p1;
1479
1480 if (!cansend(l2))
1481 return;
1482
1483 skb = skb_dequeue(&l2->i_queue);
1484 if (!skb)
1485 return;
1486
1487 if (test_bit(FLG_MOD128, &l2->flag))
1488 p1 = (l2->vs - l2->va) % 128;
1489 else
1490 p1 = (l2->vs - l2->va) % 8;
1491 p1 = (p1 + l2->sow) % l2->window;
1492 if (l2->windowar[p1]) {
1493 printk(KERN_WARNING "isdnl2 try overwrite ack queue entry %d\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001494 p1);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001495 dev_kfree_skb(l2->windowar[p1]);
1496 }
1497 l2->windowar[p1] = skb;
1498 i = sethdraddr(l2, header, CMD);
1499 if (test_bit(FLG_MOD128, &l2->flag)) {
1500 header[i++] = l2->vs << 1;
1501 header[i++] = l2->vr << 1;
1502 l2->vs = (l2->vs + 1) % 128;
1503 } else {
1504 header[i++] = (l2->vr << 5) | (l2->vs << 1);
1505 l2->vs = (l2->vs + 1) % 8;
1506 }
1507
1508 nskb = skb_clone(skb, GFP_ATOMIC);
1509 p1 = skb_headroom(nskb);
1510 if (p1 >= i)
1511 memcpy(skb_push(nskb, i), header, i);
1512 else {
1513 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001514 "isdnl2 pull_iqueue skb header(%d/%d) too short\n", i, p1);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001515 oskb = nskb;
1516 nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC);
1517 if (!nskb) {
1518 dev_kfree_skb(oskb);
1519 printk(KERN_WARNING "%s: no skb mem\n", __func__);
1520 return;
1521 }
1522 memcpy(skb_put(nskb, i), header, i);
1523 memcpy(skb_put(nskb, oskb->len), oskb->data, oskb->len);
1524 dev_kfree_skb(oskb);
1525 }
1526 l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);
1527 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1528 if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {
1529 mISDN_FsmDelTimer(&l2->t203, 13);
1530 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11);
1531 }
1532}
1533
1534static void
1535l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
1536{
1537 struct layer2 *l2 = fi->userdata;
1538 struct sk_buff *skb = arg;
1539 int PollFlag, rsp, rnr = 0;
1540 unsigned int nr;
1541
1542 rsp = *skb->data & 0x2;
1543 if (test_bit(FLG_ORIG, &l2->flag))
1544 rsp = !rsp;
1545
1546 skb_pull(skb, l2addrsize(l2));
1547
1548 if (IsRNR(skb->data, l2)) {
1549 set_peer_busy(l2);
1550 rnr = 1;
1551 } else
1552 clear_peer_busy(l2);
1553
1554 if (test_bit(FLG_MOD128, &l2->flag)) {
1555 PollFlag = (skb->data[1] & 0x1) == 0x1;
1556 nr = skb->data[1] >> 1;
1557 } else {
1558 PollFlag = (skb->data[0] & 0x10);
1559 nr = (skb->data[0] >> 5) & 0x7;
1560 }
1561 dev_kfree_skb(skb);
1562 if (rsp && PollFlag) {
1563 if (legalnr(l2, nr)) {
1564 if (rnr) {
1565 restart_t200(l2, 15);
1566 } else {
1567 stop_t200(l2, 16);
1568 mISDN_FsmAddTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001569 EV_L2_T203, NULL, 5);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001570 setva(l2, nr);
1571 }
1572 invoke_retransmission(l2, nr);
1573 mISDN_FsmChangeState(fi, ST_L2_7);
1574 if (skb_queue_len(&l2->i_queue) && cansend(l2))
1575 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1576 } else
1577 nrerrorrecovery(fi);
1578 } else {
1579 if (!rsp && PollFlag)
1580 enquiry_response(l2);
1581 if (legalnr(l2, nr))
1582 setva(l2, nr);
1583 else
1584 nrerrorrecovery(fi);
1585 }
1586}
1587
1588static void
1589l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
1590{
1591 struct layer2 *l2 = fi->userdata;
1592 struct sk_buff *skb = arg;
1593
1594 skb_pull(skb, l2addrsize(l2) + 1);
1595
1596 if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */
1597 (IsUA(skb->data) && (fi->state == ST_L2_7))) {
1598 l2mgr(l2, MDL_ERROR_IND, (void *) 'K');
1599 establishlink(fi);
1600 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1601 }
1602 dev_kfree_skb(skb);
1603}
1604
1605static void
1606l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg)
1607{
1608 struct layer2 *l2 = fi->userdata;
1609
1610 skb_queue_purge(&l2->ui_queue);
1611 l2->tei = GROUP_TEI;
1612 mISDN_FsmChangeState(fi, ST_L2_1);
1613}
1614
1615static void
1616l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg)
1617{
1618 struct layer2 *l2 = fi->userdata;
1619
1620 skb_queue_purge(&l2->ui_queue);
1621 l2->tei = GROUP_TEI;
1622 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1623 mISDN_FsmChangeState(fi, ST_L2_1);
1624}
1625
1626static void
1627l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg)
1628{
1629 struct layer2 *l2 = fi->userdata;
1630
1631 skb_queue_purge(&l2->i_queue);
1632 skb_queue_purge(&l2->ui_queue);
1633 freewin(l2);
1634 l2->tei = GROUP_TEI;
1635 stop_t200(l2, 17);
1636 st5_dl_release_l2l3(l2);
1637 mISDN_FsmChangeState(fi, ST_L2_1);
1638}
1639
1640static void
1641l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg)
1642{
1643 struct layer2 *l2 = fi->userdata;
1644
1645 skb_queue_purge(&l2->ui_queue);
1646 l2->tei = GROUP_TEI;
1647 stop_t200(l2, 18);
1648 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1649 mISDN_FsmChangeState(fi, ST_L2_1);
1650}
1651
1652static void
1653l2_tei_remove(struct FsmInst *fi, int event, void *arg)
1654{
1655 struct layer2 *l2 = fi->userdata;
1656
1657 skb_queue_purge(&l2->i_queue);
1658 skb_queue_purge(&l2->ui_queue);
1659 freewin(l2);
1660 l2->tei = GROUP_TEI;
1661 stop_t200(l2, 17);
1662 mISDN_FsmDelTimer(&l2->t203, 19);
1663 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1664/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
1665 * MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED,
1666 * 0, NULL, 0);
1667 */
1668 mISDN_FsmChangeState(fi, ST_L2_1);
1669}
1670
1671static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001672l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001673{
1674 struct layer2 *l2 = fi->userdata;
1675 struct sk_buff *skb = arg;
1676
1677 skb_queue_purge(&l2->i_queue);
1678 skb_queue_purge(&l2->ui_queue);
1679 if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
1680 l2up(l2, DL_RELEASE_IND, skb);
1681 else
1682 dev_kfree_skb(skb);
1683}
1684
1685static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001686l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001687{
1688 struct layer2 *l2 = fi->userdata;
1689 struct sk_buff *skb = arg;
1690
1691 skb_queue_purge(&l2->i_queue);
1692 skb_queue_purge(&l2->ui_queue);
1693 freewin(l2);
1694 stop_t200(l2, 19);
1695 st5_dl_release_l2l3(l2);
1696 mISDN_FsmChangeState(fi, ST_L2_4);
1697 if (l2->tm)
1698 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1699 dev_kfree_skb(skb);
1700}
1701
1702static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001703l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001704{
1705 struct layer2 *l2 = fi->userdata;
1706 struct sk_buff *skb = arg;
1707
1708 skb_queue_purge(&l2->ui_queue);
1709 stop_t200(l2, 20);
1710 l2up(l2, DL_RELEASE_CNF, skb);
1711 mISDN_FsmChangeState(fi, ST_L2_4);
1712 if (l2->tm)
1713 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1714}
1715
1716static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001717l2_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001718{
1719 struct layer2 *l2 = fi->userdata;
1720 struct sk_buff *skb = arg;
1721
1722 skb_queue_purge(&l2->i_queue);
1723 skb_queue_purge(&l2->ui_queue);
1724 freewin(l2);
1725 stop_t200(l2, 19);
1726 mISDN_FsmDelTimer(&l2->t203, 19);
1727 l2up(l2, DL_RELEASE_IND, skb);
1728 mISDN_FsmChangeState(fi, ST_L2_4);
1729 if (l2->tm)
1730 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1731}
1732
1733static void
1734l2_set_own_busy(struct FsmInst *fi, int event, void *arg)
1735{
1736 struct layer2 *l2 = fi->userdata;
1737 struct sk_buff *skb = arg;
1738
1739 if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) {
1740 enquiry_cr(l2, RNR, RSP, 0);
1741 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1742 }
1743 if (skb)
1744 dev_kfree_skb(skb);
1745}
1746
1747static void
1748l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)
1749{
1750 struct layer2 *l2 = fi->userdata;
1751 struct sk_buff *skb = arg;
1752
1753 if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) {
1754 enquiry_cr(l2, RR, RSP, 0);
1755 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1756 }
1757 if (skb)
1758 dev_kfree_skb(skb);
1759}
1760
1761static void
1762l2_frame_error(struct FsmInst *fi, int event, void *arg)
1763{
1764 struct layer2 *l2 = fi->userdata;
1765
1766 l2mgr(l2, MDL_ERROR_IND, arg);
1767}
1768
1769static void
1770l2_frame_error_reest(struct FsmInst *fi, int event, void *arg)
1771{
1772 struct layer2 *l2 = fi->userdata;
1773
1774 l2mgr(l2, MDL_ERROR_IND, arg);
1775 establishlink(fi);
1776 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1777}
1778
1779static struct FsmNode L2FnList[] =
1780{
1781 {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign},
1782 {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3},
1783 {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish},
1784 {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3},
1785 {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
1786 {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
1787 {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release},
1788 {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel},
1789 {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect},
1790 {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect},
1791 {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest},
1792 {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull},
1793 {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},
1794 {ST_L2_1, EV_L2_DL_UNITDATA, l2_queue_ui_assign},
1795 {ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui},
1796 {ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui},
1797 {ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui},
1798 {ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui},
1799 {ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui},
1800 {ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui},
1801 {ST_L2_8, EV_L2_DL_UNITDATA, l2_send_ui},
1802 {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei},
1803 {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei},
1804 {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei},
1805 {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove},
1806 {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove},
1807 {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove},
1808 {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove},
1809 {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove},
1810 {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove},
1811 {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove},
1812 {ST_L2_4, EV_L2_SABME, l2_start_multi},
1813 {ST_L2_5, EV_L2_SABME, l2_send_UA},
1814 {ST_L2_6, EV_L2_SABME, l2_send_DM},
1815 {ST_L2_7, EV_L2_SABME, l2_restart_multi},
1816 {ST_L2_8, EV_L2_SABME, l2_restart_multi},
1817 {ST_L2_4, EV_L2_DISC, l2_send_DM},
1818 {ST_L2_5, EV_L2_DISC, l2_send_DM},
1819 {ST_L2_6, EV_L2_DISC, l2_send_UA},
1820 {ST_L2_7, EV_L2_DISC, l2_stop_multi},
1821 {ST_L2_8, EV_L2_DISC, l2_stop_multi},
1822 {ST_L2_4, EV_L2_UA, l2_mdl_error_ua},
1823 {ST_L2_5, EV_L2_UA, l2_connected},
1824 {ST_L2_6, EV_L2_UA, l2_released},
1825 {ST_L2_7, EV_L2_UA, l2_mdl_error_ua},
1826 {ST_L2_8, EV_L2_UA, l2_mdl_error_ua},
1827 {ST_L2_4, EV_L2_DM, l2_reestablish},
1828 {ST_L2_5, EV_L2_DM, l2_st5_dm_release},
1829 {ST_L2_6, EV_L2_DM, l2_st6_dm_release},
1830 {ST_L2_7, EV_L2_DM, l2_mdl_error_dm},
1831 {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm},
1832 {ST_L2_1, EV_L2_UI, l2_got_ui},
1833 {ST_L2_2, EV_L2_UI, l2_got_ui},
1834 {ST_L2_3, EV_L2_UI, l2_got_ui},
1835 {ST_L2_4, EV_L2_UI, l2_got_ui},
1836 {ST_L2_5, EV_L2_UI, l2_got_ui},
1837 {ST_L2_6, EV_L2_UI, l2_got_ui},
1838 {ST_L2_7, EV_L2_UI, l2_got_ui},
1839 {ST_L2_8, EV_L2_UI, l2_got_ui},
1840 {ST_L2_7, EV_L2_FRMR, l2_got_FRMR},
1841 {ST_L2_8, EV_L2_FRMR, l2_got_FRMR},
1842 {ST_L2_7, EV_L2_SUPER, l2_st7_got_super},
1843 {ST_L2_8, EV_L2_SUPER, l2_st8_got_super},
1844 {ST_L2_7, EV_L2_I, l2_got_iframe},
1845 {ST_L2_8, EV_L2_I, l2_got_iframe},
Karsten Keil8423e6b2012-05-04 04:15:32 +00001846 {ST_L2_5, EV_L2_T200, l2_timeout},
1847 {ST_L2_6, EV_L2_T200, l2_timeout},
1848 {ST_L2_7, EV_L2_T200, l2_timeout},
1849 {ST_L2_8, EV_L2_T200, l2_timeout},
1850 {ST_L2_7, EV_L2_T203, l2_timeout},
1851 {ST_L2_5, EV_L2_T200I, l2_st5_tout_200},
1852 {ST_L2_6, EV_L2_T200I, l2_st6_tout_200},
1853 {ST_L2_7, EV_L2_T200I, l2_st7_tout_200},
1854 {ST_L2_8, EV_L2_T200I, l2_st8_tout_200},
1855 {ST_L2_7, EV_L2_T203I, l2_st7_tout_203},
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001856 {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},
1857 {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
1858 {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
1859 {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
1860 {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
1861 {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error},
1862 {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error},
1863 {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
1864 {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
1865 {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001866 {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001867 {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
1868 {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001869 {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
1870 {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
1871 {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
1872 {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
1873 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001874};
1875
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001876static int
1877ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
1878{
1879 u_char *datap = skb->data;
1880 int ret = -EINVAL;
1881 int psapi, ptei;
1882 u_int l;
1883 int c = 0;
1884
1885 l = l2addrsize(l2);
1886 if (skb->len <= l) {
1887 mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
1888 return ret;
1889 }
1890 if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
1891 psapi = *datap++;
1892 ptei = *datap++;
1893 if ((psapi & 1) || !(ptei & 1)) {
1894 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001895 "l2 D-channel frame wrong EA0/EA1\n");
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001896 return ret;
1897 }
1898 psapi >>= 2;
1899 ptei >>= 1;
1900 if (psapi != l2->sapi) {
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001901 /* not our business */
Andreas Eversbergd7965092009-05-22 11:04:51 +00001902 if (*debug & DEBUG_L2)
1903 printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001904 __func__, psapi, l2->sapi);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001905 dev_kfree_skb(skb);
1906 return 0;
1907 }
1908 if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001909 /* not our business */
Andreas Eversbergd7965092009-05-22 11:04:51 +00001910 if (*debug & DEBUG_L2)
1911 printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001912 __func__, ptei, l2->tei);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001913 dev_kfree_skb(skb);
1914 return 0;
1915 }
1916 } else
1917 datap += l;
1918 if (!(*datap & 1)) { /* I-Frame */
1919 c = iframe_error(l2, skb);
1920 if (!c)
1921 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb);
1922 } else if (IsSFrame(datap, l2)) { /* S-Frame */
1923 c = super_error(l2, skb);
1924 if (!c)
1925 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb);
1926 } else if (IsUI(datap)) {
1927 c = UI_error(l2, skb);
1928 if (!c)
1929 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
1930 } else if (IsSABME(datap, l2)) {
1931 c = unnum_error(l2, skb, CMD);
1932 if (!c)
1933 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
1934 } else if (IsUA(datap)) {
1935 c = unnum_error(l2, skb, RSP);
1936 if (!c)
1937 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb);
1938 } else if (IsDISC(datap)) {
1939 c = unnum_error(l2, skb, CMD);
1940 if (!c)
1941 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb);
1942 } else if (IsDM(datap)) {
1943 c = unnum_error(l2, skb, RSP);
1944 if (!c)
1945 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb);
1946 } else if (IsFRMR(datap)) {
1947 c = FRMR_error(l2, skb);
1948 if (!c)
1949 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb);
1950 } else
1951 c = 'L';
1952 if (c) {
1953 printk(KERN_WARNING "l2 D-channel frame error %c\n", c);
1954 mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
1955 }
1956 return ret;
1957}
1958
1959static int
1960l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
1961{
1962 struct layer2 *l2 = container_of(ch, struct layer2, ch);
1963 struct mISDNhead *hh = mISDN_HEAD_P(skb);
Joe Perches475be4d2012-02-19 19:52:38 -08001964 int ret = -EINVAL;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001965
1966 if (*debug & DEBUG_L2_RECV)
Andreas Eversbergd7965092009-05-22 11:04:51 +00001967 printk(KERN_DEBUG "%s: prim(%x) id(%x) sapi(%d) tei(%d)\n",
Joe Perches475be4d2012-02-19 19:52:38 -08001968 __func__, hh->prim, hh->id, l2->sapi, l2->tei);
Karsten Keil8423e6b2012-05-04 04:15:32 +00001969 if (hh->prim == DL_INTERN_MSG) {
1970 struct mISDNhead *chh = hh + 1; /* saved copy */
1971
1972 *hh = *chh;
1973 if (*debug & DEBUG_L2_RECV)
1974 printk(KERN_DEBUG "%s: prim(%x) id(%x) internal msg\n",
1975 __func__, hh->prim, hh->id);
1976 }
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001977 switch (hh->prim) {
1978 case PH_DATA_IND:
1979 ret = ph_data_indication(l2, hh, skb);
1980 break;
1981 case PH_DATA_CNF:
1982 ret = ph_data_confirm(l2, hh, skb);
1983 break;
1984 case PH_ACTIVATE_IND:
1985 test_and_set_bit(FLG_L1_ACTIV, &l2->flag);
1986 l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);
1987 if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
1988 ret = mISDN_FsmEvent(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -08001989 EV_L2_DL_ESTABLISH_REQ, skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001990 break;
1991 case PH_DEACTIVATE_IND:
1992 test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);
1993 l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL);
1994 ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb);
1995 break;
1996 case MPH_INFORMATION_IND:
1997 if (!l2->up)
1998 break;
1999 ret = l2->up->send(l2->up, skb);
2000 break;
2001 case DL_DATA_REQ:
2002 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);
2003 break;
2004 case DL_UNITDATA_REQ:
2005 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb);
2006 break;
2007 case DL_ESTABLISH_REQ:
2008 if (test_bit(FLG_LAPB, &l2->flag))
2009 test_and_set_bit(FLG_ORIG, &l2->flag);
2010 if (test_bit(FLG_L1_ACTIV, &l2->flag)) {
2011 if (test_bit(FLG_LAPD, &l2->flag) ||
Joe Perches475be4d2012-02-19 19:52:38 -08002012 test_bit(FLG_ORIG, &l2->flag))
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002013 ret = mISDN_FsmEvent(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -08002014 EV_L2_DL_ESTABLISH_REQ, skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002015 } else {
2016 if (test_bit(FLG_LAPD, &l2->flag) ||
Joe Perches475be4d2012-02-19 19:52:38 -08002017 test_bit(FLG_ORIG, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002018 test_and_set_bit(FLG_ESTAB_PEND,
Joe Perches475be4d2012-02-19 19:52:38 -08002019 &l2->flag);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002020 }
2021 ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),
Joe Perches475be4d2012-02-19 19:52:38 -08002022 skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002023 }
2024 break;
2025 case DL_RELEASE_REQ:
2026 if (test_bit(FLG_LAPB, &l2->flag))
2027 l2down_create(l2, PH_DEACTIVATE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08002028 l2_newid(l2), 0, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002029 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08002030 skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002031 break;
Karsten Keil8423e6b2012-05-04 04:15:32 +00002032 case DL_TIMER200_IND:
2033 mISDN_FsmEvent(&l2->l2m, EV_L2_T200I, NULL);
2034 break;
2035 case DL_TIMER203_IND:
2036 mISDN_FsmEvent(&l2->l2m, EV_L2_T203I, NULL);
2037 break;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002038 default:
2039 if (*debug & DEBUG_L2)
2040 l2m_debug(&l2->l2m, "l2 unknown pr %04x",
Joe Perches475be4d2012-02-19 19:52:38 -08002041 hh->prim);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002042 }
2043 if (ret) {
2044 dev_kfree_skb(skb);
2045 ret = 0;
2046 }
2047 return ret;
2048}
2049
2050int
2051tei_l2(struct layer2 *l2, u_int cmd, u_long arg)
2052{
2053 int ret = -EINVAL;
2054
2055 if (*debug & DEBUG_L2_TEI)
2056 printk(KERN_DEBUG "%s: cmd(%x)\n", __func__, cmd);
2057 switch (cmd) {
2058 case (MDL_ASSIGN_REQ):
2059 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg);
2060 break;
2061 case (MDL_REMOVE_REQ):
2062 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL);
2063 break;
2064 case (MDL_ERROR_IND):
2065 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
2066 break;
2067 case (MDL_ERROR_RSP):
2068 /* ETS 300-125 5.3.2.1 Test: TC13010 */
2069 printk(KERN_NOTICE "MDL_ERROR|REQ (tei_l2)\n");
2070 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
2071 break;
2072 }
2073 return ret;
2074}
2075
2076static void
2077release_l2(struct layer2 *l2)
2078{
2079 mISDN_FsmDelTimer(&l2->t200, 21);
2080 mISDN_FsmDelTimer(&l2->t203, 16);
2081 skb_queue_purge(&l2->i_queue);
2082 skb_queue_purge(&l2->ui_queue);
2083 skb_queue_purge(&l2->down_queue);
2084 ReleaseWin(l2);
2085 if (test_bit(FLG_LAPD, &l2->flag)) {
Karsten Keilc5b61d52008-07-27 18:32:50 +02002086 TEIrelease(l2);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002087 if (l2->ch.st)
2088 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,
Joe Perches475be4d2012-02-19 19:52:38 -08002089 CLOSE_CHANNEL, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002090 }
2091 kfree(l2);
2092}
2093
2094static int
2095l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
2096{
2097 struct layer2 *l2 = container_of(ch, struct layer2, ch);
2098 u_int info;
2099
2100 if (*debug & DEBUG_L2_CTRL)
2101 printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
2102
2103 switch (cmd) {
2104 case OPEN_CHANNEL:
2105 if (test_bit(FLG_LAPD, &l2->flag)) {
2106 set_channel_address(&l2->ch, l2->sapi, l2->tei);
2107 info = DL_INFO_L2_CONNECT;
2108 l2up_create(l2, DL_INFORMATION_IND,
Joe Perches475be4d2012-02-19 19:52:38 -08002109 sizeof(info), &info);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002110 }
2111 break;
2112 case CLOSE_CHANNEL:
2113 if (l2->ch.peer)
2114 l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL);
2115 release_l2(l2);
2116 break;
2117 }
2118 return 0;
2119}
2120
2121struct layer2 *
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002122create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
Joe Perches475be4d2012-02-19 19:52:38 -08002123 int sapi)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002124{
2125 struct layer2 *l2;
2126 struct channel_req rq;
2127
2128 l2 = kzalloc(sizeof(struct layer2), GFP_KERNEL);
2129 if (!l2) {
2130 printk(KERN_ERR "kzalloc layer2 failed\n");
2131 return NULL;
2132 }
2133 l2->next_id = 1;
2134 l2->down_id = MISDN_ID_NONE;
2135 l2->up = ch;
2136 l2->ch.st = ch->st;
2137 l2->ch.send = l2_send;
2138 l2->ch.ctrl = l2_ctrl;
2139 switch (protocol) {
2140 case ISDN_P_LAPD_NT:
2141 test_and_set_bit(FLG_LAPD, &l2->flag);
2142 test_and_set_bit(FLG_LAPD_NET, &l2->flag);
2143 test_and_set_bit(FLG_MOD128, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002144 l2->sapi = sapi;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002145 l2->maxlen = MAX_DFRAME_LEN;
2146 if (test_bit(OPTION_L2_PMX, &options))
2147 l2->window = 7;
2148 else
2149 l2->window = 1;
2150 if (test_bit(OPTION_L2_PTP, &options))
2151 test_and_set_bit(FLG_PTP, &l2->flag);
2152 if (test_bit(OPTION_L2_FIXEDTEI, &options))
2153 test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002154 l2->tei = tei;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002155 l2->T200 = 1000;
2156 l2->N200 = 3;
2157 l2->T203 = 10000;
2158 if (test_bit(OPTION_L2_PMX, &options))
2159 rq.protocol = ISDN_P_NT_E1;
2160 else
2161 rq.protocol = ISDN_P_NT_S0;
2162 rq.adr.channel = 0;
2163 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
2164 break;
2165 case ISDN_P_LAPD_TE:
2166 test_and_set_bit(FLG_LAPD, &l2->flag);
2167 test_and_set_bit(FLG_MOD128, &l2->flag);
2168 test_and_set_bit(FLG_ORIG, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002169 l2->sapi = sapi;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002170 l2->maxlen = MAX_DFRAME_LEN;
2171 if (test_bit(OPTION_L2_PMX, &options))
2172 l2->window = 7;
2173 else
2174 l2->window = 1;
2175 if (test_bit(OPTION_L2_PTP, &options))
2176 test_and_set_bit(FLG_PTP, &l2->flag);
2177 if (test_bit(OPTION_L2_FIXEDTEI, &options))
2178 test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002179 l2->tei = tei;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002180 l2->T200 = 1000;
2181 l2->N200 = 3;
2182 l2->T203 = 10000;
2183 if (test_bit(OPTION_L2_PMX, &options))
2184 rq.protocol = ISDN_P_TE_E1;
2185 else
2186 rq.protocol = ISDN_P_TE_S0;
2187 rq.adr.channel = 0;
2188 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
2189 break;
2190 case ISDN_P_B_X75SLP:
2191 test_and_set_bit(FLG_LAPB, &l2->flag);
2192 l2->window = 7;
2193 l2->maxlen = MAX_DATA_SIZE;
2194 l2->T200 = 1000;
2195 l2->N200 = 4;
2196 l2->T203 = 5000;
2197 l2->addr.A = 3;
2198 l2->addr.B = 1;
2199 break;
2200 default:
2201 printk(KERN_ERR "layer2 create failed prt %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002202 protocol);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002203 kfree(l2);
2204 return NULL;
2205 }
2206 skb_queue_head_init(&l2->i_queue);
2207 skb_queue_head_init(&l2->ui_queue);
2208 skb_queue_head_init(&l2->down_queue);
2209 skb_queue_head_init(&l2->tmp_queue);
2210 InitWin(l2);
2211 l2->l2m.fsm = &l2fsm;
2212 if (test_bit(FLG_LAPB, &l2->flag) ||
Joe Perches475be4d2012-02-19 19:52:38 -08002213 test_bit(FLG_PTP, &l2->flag) ||
2214 test_bit(FLG_LAPD_NET, &l2->flag))
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002215 l2->l2m.state = ST_L2_4;
2216 else
2217 l2->l2m.state = ST_L2_1;
2218 l2->l2m.debug = *debug;
2219 l2->l2m.userdata = l2;
2220 l2->l2m.userint = 0;
2221 l2->l2m.printdebug = l2m_debug;
2222
2223 mISDN_FsmInitTimer(&l2->l2m, &l2->t200);
2224 mISDN_FsmInitTimer(&l2->l2m, &l2->t203);
2225 return l2;
2226}
2227
2228static int
2229x75create(struct channel_req *crq)
2230{
2231 struct layer2 *l2;
2232
2233 if (crq->protocol != ISDN_P_B_X75SLP)
2234 return -EPROTONOSUPPORT;
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002235 l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002236 if (!l2)
2237 return -ENOMEM;
2238 crq->ch = &l2->ch;
2239 crq->protocol = ISDN_P_B_HDLC;
2240 return 0;
2241}
2242
2243static struct Bprotocol X75SLP = {
2244 .Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)),
2245 .name = "X75SLP",
2246 .create = x75create
2247};
2248
2249int
2250Isdnl2_Init(u_int *deb)
2251{
2252 debug = deb;
2253 mISDN_register_Bprotocol(&X75SLP);
2254 l2fsm.state_count = L2_STATE_COUNT;
2255 l2fsm.event_count = L2_EVENT_COUNT;
2256 l2fsm.strEvent = strL2Event;
2257 l2fsm.strState = strL2State;
2258 mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
2259 TEIInit(deb);
2260 return 0;
2261}
2262
2263void
2264Isdnl2_cleanup(void)
2265{
2266 mISDN_unregister_Bprotocol(&X75SLP);
2267 TEIFree();
2268 mISDN_FsmFree(&l2fsm);
2269}