blob: 949cabb88f1c113c9606d26ff72627f6cf9db108 [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
Karsten Keilf45ebf32012-05-04 04:15:35 +0000113 printk(KERN_DEBUG "%s l2 (sapi %d tei %d): %pV\n",
114 mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei, &vaf);
Joe Perches020f01e2010-11-09 14:35:16 +0000115
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) {
Karsten Keilf45ebf32012-05-04 04:15:35 +0000157 printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
158 mISDNDevName4ch(&l2->ch), err);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200159 dev_kfree_skb(skb);
160 }
161}
162
163static void
164l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)
165{
166 struct sk_buff *skb;
167 struct mISDNhead *hh;
168 int err;
169
170 if (!l2->up)
171 return;
172 skb = mI_alloc_skb(len, GFP_ATOMIC);
173 if (!skb)
174 return;
175 hh = mISDN_HEAD_P(skb);
176 hh->prim = prim;
177 hh->id = (l2->ch.nr << 16) | l2->ch.addr;
178 if (len)
179 memcpy(skb_put(skb, len), arg, len);
180 err = l2->up->send(l2->up, skb);
181 if (err) {
Karsten Keilf45ebf32012-05-04 04:15:35 +0000182 printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,
183 mISDNDevName4ch(&l2->ch), err);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200184 dev_kfree_skb(skb);
185 }
186}
187
188static int
189l2down_skb(struct layer2 *l2, struct sk_buff *skb) {
190 int ret;
191
192 ret = l2->ch.recv(l2->ch.peer, skb);
193 if (ret && (*debug & DEBUG_L2_RECV))
Karsten Keilf45ebf32012-05-04 04:15:35 +0000194 printk(KERN_DEBUG "l2down_skb: dev %s ret(%d)\n",
195 mISDNDevName4ch(&l2->ch), ret);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200196 return ret;
197}
198
199static int
200l2down_raw(struct layer2 *l2, struct sk_buff *skb)
201{
202 struct mISDNhead *hh = mISDN_HEAD_P(skb);
203
204 if (hh->prim == PH_DATA_REQ) {
205 if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
206 skb_queue_tail(&l2->down_queue, skb);
207 return 0;
208 }
209 l2->down_id = mISDN_HEAD_ID(skb);
210 }
211 return l2down_skb(l2, skb);
212}
213
214static int
215l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb)
216{
217 struct mISDNhead *hh = mISDN_HEAD_P(skb);
218
219 hh->prim = prim;
220 hh->id = id;
221 return l2down_raw(l2, skb);
222}
223
224static int
225l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg)
226{
227 struct sk_buff *skb;
228 int err;
229 struct mISDNhead *hh;
230
231 skb = mI_alloc_skb(len, GFP_ATOMIC);
232 if (!skb)
233 return -ENOMEM;
234 hh = mISDN_HEAD_P(skb);
235 hh->prim = prim;
236 hh->id = id;
237 if (len)
238 memcpy(skb_put(skb, len), arg, len);
239 err = l2down_raw(l2, skb);
240 if (err)
241 dev_kfree_skb(skb);
242 return err;
243}
244
245static int
246ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {
247 struct sk_buff *nskb = skb;
248 int ret = -EAGAIN;
249
250 if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {
251 if (hh->id == l2->down_id) {
252 nskb = skb_dequeue(&l2->down_queue);
253 if (nskb) {
254 l2->down_id = mISDN_HEAD_ID(nskb);
255 if (l2down_skb(l2, nskb)) {
256 dev_kfree_skb(nskb);
257 l2->down_id = MISDN_ID_NONE;
258 }
259 } else
260 l2->down_id = MISDN_ID_NONE;
261 if (ret) {
262 dev_kfree_skb(skb);
263 ret = 0;
264 }
265 if (l2->down_id == MISDN_ID_NONE) {
266 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
267 mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
268 }
269 }
270 }
271 if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {
272 nskb = skb_dequeue(&l2->down_queue);
273 if (nskb) {
274 l2->down_id = mISDN_HEAD_ID(nskb);
275 if (l2down_skb(l2, nskb)) {
276 dev_kfree_skb(nskb);
277 l2->down_id = MISDN_ID_NONE;
278 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
279 }
280 } else
281 test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);
282 }
283 return ret;
284}
285
Karsten Keil8423e6b2012-05-04 04:15:32 +0000286static void
287l2_timeout(struct FsmInst *fi, int event, void *arg)
288{
289 struct layer2 *l2 = fi->userdata;
290 struct sk_buff *skb;
291 struct mISDNhead *hh;
292
293 skb = mI_alloc_skb(0, GFP_ATOMIC);
294 if (!skb) {
Karsten Keilf45ebf32012-05-04 04:15:35 +0000295 printk(KERN_WARNING "%s: L2(%d,%d) nr:%x timer %s no skb\n",
296 mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,
297 l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");
Karsten Keil8423e6b2012-05-04 04:15:32 +0000298 return;
299 }
300 hh = mISDN_HEAD_P(skb);
301 hh->prim = event == EV_L2_T200 ? DL_TIMER200_IND : DL_TIMER203_IND;
302 hh->id = l2->ch.nr;
303 if (*debug & DEBUG_TIMER)
Karsten Keilf45ebf32012-05-04 04:15:35 +0000304 printk(KERN_DEBUG "%s: L2(%d,%d) nr:%x timer %s expired\n",
305 mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,
306 l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");
Karsten Keil8423e6b2012-05-04 04:15:32 +0000307 if (l2->ch.st)
308 l2->ch.st->own.recv(&l2->ch.st->own, skb);
309}
310
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200311static int
312l2mgr(struct layer2 *l2, u_int prim, void *arg) {
313 long c = (long)arg;
314
Karsten Keilf45ebf32012-05-04 04:15:35 +0000315 printk(KERN_WARNING "l2mgr: dev %s addr:%x prim %x %c\n",
316 mISDNDevName4ch(&l2->ch), l2->id, prim, (char)c);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200317 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -0800318 !test_bit(FLG_FIXED_TEI, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200319 switch (c) {
320 case 'C':
321 case 'D':
322 case 'G':
323 case 'H':
324 l2_tei(l2, prim, (u_long)arg);
325 break;
326 }
327 }
328 return 0;
329}
330
331static void
332set_peer_busy(struct layer2 *l2) {
333 test_and_set_bit(FLG_PEER_BUSY, &l2->flag);
334 if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))
335 test_and_set_bit(FLG_L2BLOCK, &l2->flag);
336}
337
338static void
339clear_peer_busy(struct layer2 *l2) {
340 if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag))
341 test_and_clear_bit(FLG_L2BLOCK, &l2->flag);
342}
343
344static void
345InitWin(struct layer2 *l2)
346{
347 int i;
348
349 for (i = 0; i < MAX_WINDOW; i++)
350 l2->windowar[i] = NULL;
351}
352
353static int
354freewin(struct layer2 *l2)
355{
356 int i, cnt = 0;
357
358 for (i = 0; i < MAX_WINDOW; i++) {
359 if (l2->windowar[i]) {
360 cnt++;
361 dev_kfree_skb(l2->windowar[i]);
362 l2->windowar[i] = NULL;
363 }
364 }
365 return cnt;
366}
367
368static void
369ReleaseWin(struct layer2 *l2)
370{
371 int cnt = freewin(l2);
372
373 if (cnt)
374 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -0800375 "isdnl2 freed %d skbuffs in release\n", cnt);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200376}
377
378inline unsigned int
379cansend(struct layer2 *l2)
380{
381 unsigned int p1;
382
383 if (test_bit(FLG_MOD128, &l2->flag))
384 p1 = (l2->vs - l2->va) % 128;
385 else
386 p1 = (l2->vs - l2->va) % 8;
387 return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag);
388}
389
390inline void
391clear_exception(struct layer2 *l2)
392{
393 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
394 test_and_clear_bit(FLG_REJEXC, &l2->flag);
395 test_and_clear_bit(FLG_OWN_BUSY, &l2->flag);
396 clear_peer_busy(l2);
397}
398
399static int
400sethdraddr(struct layer2 *l2, u_char *header, int rsp)
401{
402 u_char *ptr = header;
403 int crbit = rsp;
404
405 if (test_bit(FLG_LAPD, &l2->flag)) {
406 if (test_bit(FLG_LAPD_NET, &l2->flag))
407 crbit = !crbit;
408 *ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0);
409 *ptr++ = (l2->tei << 1) | 1;
410 return 2;
411 } else {
412 if (test_bit(FLG_ORIG, &l2->flag))
413 crbit = !crbit;
414 if (crbit)
415 *ptr++ = l2->addr.B;
416 else
417 *ptr++ = l2->addr.A;
418 return 1;
419 }
420}
421
422static inline void
423enqueue_super(struct layer2 *l2, struct sk_buff *skb)
424{
425 if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
426 dev_kfree_skb(skb);
427}
428
429static inline void
430enqueue_ui(struct layer2 *l2, struct sk_buff *skb)
431{
432 if (l2->tm)
433 l2_tei(l2, MDL_STATUS_UI_IND, 0);
434 if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))
435 dev_kfree_skb(skb);
436}
437
438inline int
439IsUI(u_char *data)
440{
441 return (data[0] & 0xef) == UI;
442}
443
444inline int
445IsUA(u_char *data)
446{
447 return (data[0] & 0xef) == UA;
448}
449
450inline int
451IsDM(u_char *data)
452{
453 return (data[0] & 0xef) == DM;
454}
455
456inline int
457IsDISC(u_char *data)
458{
459 return (data[0] & 0xef) == DISC;
460}
461
462inline int
463IsRR(u_char *data, struct layer2 *l2)
464{
465 if (test_bit(FLG_MOD128, &l2->flag))
466 return data[0] == RR;
467 else
468 return (data[0] & 0xf) == 1;
469}
470
471inline int
472IsSFrame(u_char *data, struct layer2 *l2)
473{
474 register u_char d = *data;
475
476 if (!test_bit(FLG_MOD128, &l2->flag))
477 d &= 0xf;
478 return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c);
479}
480
481inline int
482IsSABME(u_char *data, struct layer2 *l2)
483{
484 u_char d = data[0] & ~0x10;
485
486 return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM;
487}
488
489inline int
490IsREJ(u_char *data, struct layer2 *l2)
491{
492 return test_bit(FLG_MOD128, &l2->flag) ?
493 data[0] == REJ : (data[0] & 0xf) == REJ;
494}
495
496inline int
497IsFRMR(u_char *data)
498{
499 return (data[0] & 0xef) == FRMR;
500}
501
502inline int
503IsRNR(u_char *data, struct layer2 *l2)
504{
505 return test_bit(FLG_MOD128, &l2->flag) ?
Joe Perches475be4d2012-02-19 19:52:38 -0800506 data[0] == RNR : (data[0] & 0xf) == RNR;
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200507}
508
Hannes Eder5b834352008-12-12 21:15:17 -0800509static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200510iframe_error(struct layer2 *l2, struct sk_buff *skb)
511{
512 u_int i;
513 int rsp = *skb->data & 0x2;
514
515 i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1);
516 if (test_bit(FLG_ORIG, &l2->flag))
517 rsp = !rsp;
518 if (rsp)
519 return 'L';
520 if (skb->len < i)
521 return 'N';
522 if ((skb->len - i) > l2->maxlen)
523 return 'O';
524 return 0;
525}
526
Hannes Eder5b834352008-12-12 21:15:17 -0800527static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200528super_error(struct layer2 *l2, struct sk_buff *skb)
529{
530 if (skb->len != l2addrsize(l2) +
531 (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1))
532 return 'N';
533 return 0;
534}
535
Hannes Eder5b834352008-12-12 21:15:17 -0800536static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200537unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp)
538{
539 int rsp = (*skb->data & 0x2) >> 1;
540 if (test_bit(FLG_ORIG, &l2->flag))
541 rsp = !rsp;
542 if (rsp != wantrsp)
543 return 'L';
544 if (skb->len != l2addrsize(l2) + 1)
545 return 'N';
546 return 0;
547}
548
Hannes Eder5b834352008-12-12 21:15:17 -0800549static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200550UI_error(struct layer2 *l2, struct sk_buff *skb)
551{
552 int rsp = *skb->data & 0x2;
553 if (test_bit(FLG_ORIG, &l2->flag))
554 rsp = !rsp;
555 if (rsp)
556 return 'L';
557 if (skb->len > l2->maxlen + l2addrsize(l2) + 1)
558 return 'O';
559 return 0;
560}
561
Hannes Eder5b834352008-12-12 21:15:17 -0800562static int
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200563FRMR_error(struct layer2 *l2, struct sk_buff *skb)
564{
565 u_int headers = l2addrsize(l2) + 1;
566 u_char *datap = skb->data + headers;
567 int rsp = *skb->data & 0x2;
568
569 if (test_bit(FLG_ORIG, &l2->flag))
570 rsp = !rsp;
571 if (!rsp)
572 return 'L';
573 if (test_bit(FLG_MOD128, &l2->flag)) {
574 if (skb->len < headers + 5)
575 return 'N';
576 else if (*debug & DEBUG_L2)
577 l2m_debug(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -0800578 "FRMR information %2x %2x %2x %2x %2x",
579 datap[0], datap[1], datap[2], datap[3], datap[4]);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200580 } else {
581 if (skb->len < headers + 3)
582 return 'N';
583 else if (*debug & DEBUG_L2)
584 l2m_debug(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -0800585 "FRMR information %2x %2x %2x",
586 datap[0], datap[1], datap[2]);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200587 }
588 return 0;
589}
590
591static unsigned int
592legalnr(struct layer2 *l2, unsigned int nr)
593{
594 if (test_bit(FLG_MOD128, &l2->flag))
595 return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128);
596 else
597 return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8);
598}
599
600static void
601setva(struct layer2 *l2, unsigned int nr)
602{
603 struct sk_buff *skb;
604
605 while (l2->va != nr) {
606 l2->va++;
607 if (test_bit(FLG_MOD128, &l2->flag))
608 l2->va %= 128;
609 else
610 l2->va %= 8;
611 if (l2->windowar[l2->sow]) {
612 skb_trim(l2->windowar[l2->sow], 0);
613 skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);
614 l2->windowar[l2->sow] = NULL;
615 }
616 l2->sow = (l2->sow + 1) % l2->window;
617 }
618 skb = skb_dequeue(&l2->tmp_queue);
619 while (skb) {
620 dev_kfree_skb(skb);
621 skb = skb_dequeue(&l2->tmp_queue);
622 }
623}
624
625static void
626send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)
627{
628 u_char tmp[MAX_L2HEADER_LEN];
629 int i;
630
631 i = sethdraddr(l2, tmp, cr);
632 tmp[i++] = cmd;
633 if (skb)
634 skb_trim(skb, 0);
635 else {
636 skb = mI_alloc_skb(i, GFP_ATOMIC);
637 if (!skb) {
Karsten Keilf45ebf32012-05-04 04:15:35 +0000638 printk(KERN_WARNING "%s: can't alloc skbuff in %s\n",
639 mISDNDevName4ch(&l2->ch), __func__);
Karsten Keil1b2b03f2008-07-27 01:54:58 +0200640 return;
641 }
642 }
643 memcpy(skb_put(skb, i), tmp, i);
644 enqueue_super(l2, skb);
645}
646
647
648inline u_char
649get_PollFlag(struct layer2 *l2, struct sk_buff *skb)
650{
651 return skb->data[l2addrsize(l2)] & 0x10;
652}
653
654inline u_char
655get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb)
656{
657 u_char PF;
658
659 PF = get_PollFlag(l2, skb);
660 dev_kfree_skb(skb);
661 return PF;
662}
663
664inline void
665start_t200(struct layer2 *l2, int i)
666{
667 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
668 test_and_set_bit(FLG_T200_RUN, &l2->flag);
669}
670
671inline void
672restart_t200(struct layer2 *l2, int i)
673{
674 mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);
675 test_and_set_bit(FLG_T200_RUN, &l2->flag);
676}
677
678inline void
679stop_t200(struct layer2 *l2, int i)
680{
681 if (test_and_clear_bit(FLG_T200_RUN, &l2->flag))
682 mISDN_FsmDelTimer(&l2->t200, i);
683}
684
685inline void
686st5_dl_release_l2l3(struct layer2 *l2)
687{
688 int pr;
689
690 if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
691 pr = DL_RELEASE_CNF;
692 else
693 pr = DL_RELEASE_IND;
694 l2up_create(l2, pr, 0, NULL);
695}
696
697inline void
698lapb_dl_release_l2l3(struct layer2 *l2, int f)
699{
700 if (test_bit(FLG_LAPB, &l2->flag))
701 l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL);
702 l2up_create(l2, f, 0, NULL);
703}
704
705static void
706establishlink(struct FsmInst *fi)
707{
708 struct layer2 *l2 = fi->userdata;
709 u_char cmd;
710
711 clear_exception(l2);
712 l2->rc = 0;
713 cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10;
714 send_uframe(l2, NULL, cmd, CMD);
715 mISDN_FsmDelTimer(&l2->t203, 1);
716 restart_t200(l2, 1);
717 test_and_clear_bit(FLG_PEND_REL, &l2->flag);
718 freewin(l2);
719 mISDN_FsmChangeState(fi, ST_L2_5);
720}
721
722static void
723l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)
724{
725 struct sk_buff *skb = arg;
726 struct layer2 *l2 = fi->userdata;
727
728 if (get_PollFlagFree(l2, skb))
729 l2mgr(l2, MDL_ERROR_IND, (void *) 'C');
730 else
731 l2mgr(l2, MDL_ERROR_IND, (void *) 'D');
732
733}
734
735static void
736l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
737{
738 struct sk_buff *skb = arg;
739 struct layer2 *l2 = fi->userdata;
740
741 if (get_PollFlagFree(l2, skb))
742 l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
743 else {
744 l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
745 establishlink(fi);
746 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
747 }
748}
749
750static void
751l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)
752{
753 struct sk_buff *skb = arg;
754 struct layer2 *l2 = fi->userdata;
755
756 if (get_PollFlagFree(l2, skb))
757 l2mgr(l2, MDL_ERROR_IND, (void *) 'B');
758 else
759 l2mgr(l2, MDL_ERROR_IND, (void *) 'E');
760 establishlink(fi);
761 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
762}
763
764static void
765l2_go_st3(struct FsmInst *fi, int event, void *arg)
766{
767 dev_kfree_skb((struct sk_buff *)arg);
768 mISDN_FsmChangeState(fi, ST_L2_3);
769}
770
771static void
772l2_mdl_assign(struct FsmInst *fi, int event, void *arg)
773{
774 struct layer2 *l2 = fi->userdata;
775
776 mISDN_FsmChangeState(fi, ST_L2_3);
777 dev_kfree_skb((struct sk_buff *)arg);
778 l2_tei(l2, MDL_ASSIGN_IND, 0);
779}
780
781static void
782l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg)
783{
784 struct layer2 *l2 = fi->userdata;
785 struct sk_buff *skb = arg;
786
787 skb_queue_tail(&l2->ui_queue, skb);
788 mISDN_FsmChangeState(fi, ST_L2_2);
789 l2_tei(l2, MDL_ASSIGN_IND, 0);
790}
791
792static void
793l2_queue_ui(struct FsmInst *fi, int event, void *arg)
794{
795 struct layer2 *l2 = fi->userdata;
796 struct sk_buff *skb = arg;
797
798 skb_queue_tail(&l2->ui_queue, skb);
799}
800
801static void
802tx_ui(struct layer2 *l2)
803{
804 struct sk_buff *skb;
805 u_char header[MAX_L2HEADER_LEN];
806 int i;
807
808 i = sethdraddr(l2, header, CMD);
809 if (test_bit(FLG_LAPD_NET, &l2->flag))
810 header[1] = 0xff; /* tei 127 */
811 header[i++] = UI;
812 while ((skb = skb_dequeue(&l2->ui_queue))) {
813 memcpy(skb_push(skb, i), header, i);
814 enqueue_ui(l2, skb);
815 }
816}
817
818static void
819l2_send_ui(struct FsmInst *fi, int event, void *arg)
820{
821 struct layer2 *l2 = fi->userdata;
822 struct sk_buff *skb = arg;
823
824 skb_queue_tail(&l2->ui_queue, skb);
825 tx_ui(l2);
826}
827
828static void
829l2_got_ui(struct FsmInst *fi, int event, void *arg)
830{
831 struct layer2 *l2 = fi->userdata;
832 struct sk_buff *skb = arg;
833
834 skb_pull(skb, l2headersize(l2, 1));
835/*
836 * in states 1-3 for broadcast
837 */
838
839 if (l2->tm)
840 l2_tei(l2, MDL_STATUS_UI_IND, 0);
841 l2up(l2, DL_UNITDATA_IND, skb);
842}
843
844static void
845l2_establish(struct FsmInst *fi, int event, void *arg)
846{
847 struct sk_buff *skb = arg;
848 struct layer2 *l2 = fi->userdata;
849
850 establishlink(fi);
851 test_and_set_bit(FLG_L3_INIT, &l2->flag);
852 dev_kfree_skb(skb);
853}
854
855static void
856l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)
857{
858 struct sk_buff *skb = arg;
859 struct layer2 *l2 = fi->userdata;
860
861 skb_queue_purge(&l2->i_queue);
862 test_and_set_bit(FLG_L3_INIT, &l2->flag);
863 test_and_clear_bit(FLG_PEND_REL, &l2->flag);
864 dev_kfree_skb(skb);
865}
866
867static void
868l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)
869{
870 struct sk_buff *skb = arg;
871 struct layer2 *l2 = fi->userdata;
872
873 skb_queue_purge(&l2->i_queue);
874 establishlink(fi);
875 test_and_set_bit(FLG_L3_INIT, &l2->flag);
876 dev_kfree_skb(skb);
877}
878
879static void
880l2_release(struct FsmInst *fi, int event, void *arg)
881{
882 struct layer2 *l2 = fi->userdata;
883 struct sk_buff *skb = arg;
884
885 skb_trim(skb, 0);
886 l2up(l2, DL_RELEASE_CNF, skb);
887}
888
889static void
890l2_pend_rel(struct FsmInst *fi, int event, void *arg)
891{
892 struct sk_buff *skb = arg;
893 struct layer2 *l2 = fi->userdata;
894
895 test_and_set_bit(FLG_PEND_REL, &l2->flag);
896 dev_kfree_skb(skb);
897}
898
899static void
900l2_disconnect(struct FsmInst *fi, int event, void *arg)
901{
902 struct layer2 *l2 = fi->userdata;
903 struct sk_buff *skb = arg;
904
905 skb_queue_purge(&l2->i_queue);
906 freewin(l2);
907 mISDN_FsmChangeState(fi, ST_L2_6);
908 l2->rc = 0;
909 send_uframe(l2, NULL, DISC | 0x10, CMD);
910 mISDN_FsmDelTimer(&l2->t203, 1);
911 restart_t200(l2, 2);
912 if (skb)
913 dev_kfree_skb(skb);
914}
915
916static void
917l2_start_multi(struct FsmInst *fi, int event, void *arg)
918{
919 struct layer2 *l2 = fi->userdata;
920 struct sk_buff *skb = arg;
921
922 l2->vs = 0;
923 l2->va = 0;
924 l2->vr = 0;
925 l2->sow = 0;
926 clear_exception(l2);
927 send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
928 mISDN_FsmChangeState(fi, ST_L2_7);
929 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
930 skb_trim(skb, 0);
931 l2up(l2, DL_ESTABLISH_IND, skb);
932 if (l2->tm)
933 l2_tei(l2, MDL_STATUS_UP_IND, 0);
934}
935
936static void
937l2_send_UA(struct FsmInst *fi, int event, void *arg)
938{
939 struct layer2 *l2 = fi->userdata;
940 struct sk_buff *skb = arg;
941
942 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
943}
944
945static void
946l2_send_DM(struct FsmInst *fi, int event, void *arg)
947{
948 struct layer2 *l2 = fi->userdata;
949 struct sk_buff *skb = arg;
950
951 send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP);
952}
953
954static void
955l2_restart_multi(struct FsmInst *fi, int event, void *arg)
956{
957 struct layer2 *l2 = fi->userdata;
958 struct sk_buff *skb = arg;
959 int est = 0;
960
961 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
962
963 l2mgr(l2, MDL_ERROR_IND, (void *) 'F');
964
965 if (l2->vs != l2->va) {
966 skb_queue_purge(&l2->i_queue);
967 est = 1;
968 }
969
970 clear_exception(l2);
971 l2->vs = 0;
972 l2->va = 0;
973 l2->vr = 0;
974 l2->sow = 0;
975 mISDN_FsmChangeState(fi, ST_L2_7);
976 stop_t200(l2, 3);
977 mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
978
979 if (est)
980 l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);
981/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
982 * MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,
983 * 0, NULL, 0);
984 */
985 if (skb_queue_len(&l2->i_queue) && cansend(l2))
986 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
987}
988
989static void
990l2_stop_multi(struct FsmInst *fi, int event, void *arg)
991{
992 struct layer2 *l2 = fi->userdata;
993 struct sk_buff *skb = arg;
994
995 mISDN_FsmChangeState(fi, ST_L2_4);
996 mISDN_FsmDelTimer(&l2->t203, 3);
997 stop_t200(l2, 4);
998
999 send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
1000 skb_queue_purge(&l2->i_queue);
1001 freewin(l2);
1002 lapb_dl_release_l2l3(l2, DL_RELEASE_IND);
1003 if (l2->tm)
1004 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1005}
1006
1007static void
1008l2_connected(struct FsmInst *fi, int event, void *arg)
1009{
1010 struct layer2 *l2 = fi->userdata;
1011 struct sk_buff *skb = arg;
1012 int pr = -1;
1013
1014 if (!get_PollFlag(l2, skb)) {
1015 l2_mdl_error_ua(fi, event, arg);
1016 return;
1017 }
1018 dev_kfree_skb(skb);
1019 if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))
1020 l2_disconnect(fi, event, NULL);
1021 if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {
1022 pr = DL_ESTABLISH_CNF;
1023 } else if (l2->vs != l2->va) {
1024 skb_queue_purge(&l2->i_queue);
1025 pr = DL_ESTABLISH_IND;
1026 }
1027 stop_t200(l2, 5);
1028 l2->vr = 0;
1029 l2->vs = 0;
1030 l2->va = 0;
1031 l2->sow = 0;
1032 mISDN_FsmChangeState(fi, ST_L2_7);
1033 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);
1034 if (pr != -1)
1035 l2up_create(l2, pr, 0, NULL);
1036
1037 if (skb_queue_len(&l2->i_queue) && cansend(l2))
1038 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1039
1040 if (l2->tm)
1041 l2_tei(l2, MDL_STATUS_UP_IND, 0);
1042}
1043
1044static void
1045l2_released(struct FsmInst *fi, int event, void *arg)
1046{
1047 struct layer2 *l2 = fi->userdata;
1048 struct sk_buff *skb = arg;
1049
1050 if (!get_PollFlag(l2, skb)) {
1051 l2_mdl_error_ua(fi, event, arg);
1052 return;
1053 }
1054 dev_kfree_skb(skb);
1055 stop_t200(l2, 6);
1056 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1057 mISDN_FsmChangeState(fi, ST_L2_4);
1058 if (l2->tm)
1059 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1060}
1061
1062static void
1063l2_reestablish(struct FsmInst *fi, int event, void *arg)
1064{
1065 struct layer2 *l2 = fi->userdata;
1066 struct sk_buff *skb = arg;
1067
1068 if (!get_PollFlagFree(l2, skb)) {
1069 establishlink(fi);
1070 test_and_set_bit(FLG_L3_INIT, &l2->flag);
1071 }
1072}
1073
1074static void
1075l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)
1076{
1077 struct layer2 *l2 = fi->userdata;
1078 struct sk_buff *skb = arg;
1079
1080 if (get_PollFlagFree(l2, skb)) {
1081 stop_t200(l2, 7);
1082 if (!test_bit(FLG_L3_INIT, &l2->flag))
1083 skb_queue_purge(&l2->i_queue);
1084 if (test_bit(FLG_LAPB, &l2->flag))
1085 l2down_create(l2, PH_DEACTIVATE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08001086 l2_newid(l2), 0, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001087 st5_dl_release_l2l3(l2);
1088 mISDN_FsmChangeState(fi, ST_L2_4);
1089 if (l2->tm)
1090 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1091 }
1092}
1093
1094static void
1095l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)
1096{
1097 struct layer2 *l2 = fi->userdata;
1098 struct sk_buff *skb = arg;
1099
1100 if (get_PollFlagFree(l2, skb)) {
1101 stop_t200(l2, 8);
1102 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1103 mISDN_FsmChangeState(fi, ST_L2_4);
1104 if (l2->tm)
1105 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1106 }
1107}
1108
Hannes Eder5b834352008-12-12 21:15:17 -08001109static void
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001110enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)
1111{
1112 struct sk_buff *skb;
1113 u_char tmp[MAX_L2HEADER_LEN];
1114 int i;
1115
1116 i = sethdraddr(l2, tmp, cr);
1117 if (test_bit(FLG_MOD128, &l2->flag)) {
1118 tmp[i++] = typ;
1119 tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0);
1120 } else
1121 tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0);
1122 skb = mI_alloc_skb(i, GFP_ATOMIC);
1123 if (!skb) {
Karsten Keilf45ebf32012-05-04 04:15:35 +00001124 printk(KERN_WARNING "%s: isdnl2 can't alloc sbbuff in %s\n",
1125 mISDNDevName4ch(&l2->ch), __func__);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001126 return;
1127 }
1128 memcpy(skb_put(skb, i), tmp, i);
1129 enqueue_super(l2, skb);
1130}
1131
1132inline void
1133enquiry_response(struct layer2 *l2)
1134{
1135 if (test_bit(FLG_OWN_BUSY, &l2->flag))
1136 enquiry_cr(l2, RNR, RSP, 1);
1137 else
1138 enquiry_cr(l2, RR, RSP, 1);
1139 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1140}
1141
1142inline void
1143transmit_enquiry(struct layer2 *l2)
1144{
1145 if (test_bit(FLG_OWN_BUSY, &l2->flag))
1146 enquiry_cr(l2, RNR, CMD, 1);
1147 else
1148 enquiry_cr(l2, RR, CMD, 1);
1149 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1150 start_t200(l2, 9);
1151}
1152
1153
1154static void
1155nrerrorrecovery(struct FsmInst *fi)
1156{
1157 struct layer2 *l2 = fi->userdata;
1158
1159 l2mgr(l2, MDL_ERROR_IND, (void *) 'J');
1160 establishlink(fi);
1161 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1162}
1163
1164static void
1165invoke_retransmission(struct layer2 *l2, unsigned int nr)
1166{
1167 u_int p1;
1168
1169 if (l2->vs != nr) {
1170 while (l2->vs != nr) {
1171 (l2->vs)--;
1172 if (test_bit(FLG_MOD128, &l2->flag)) {
1173 l2->vs %= 128;
1174 p1 = (l2->vs - l2->va) % 128;
1175 } else {
1176 l2->vs %= 8;
1177 p1 = (l2->vs - l2->va) % 8;
1178 }
1179 p1 = (p1 + l2->sow) % l2->window;
1180 if (l2->windowar[p1])
1181 skb_queue_head(&l2->i_queue, l2->windowar[p1]);
1182 else
1183 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08001184 "%s: windowar[%d] is NULL\n",
Karsten Keilf45ebf32012-05-04 04:15:35 +00001185 mISDNDevName4ch(&l2->ch), p1);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001186 l2->windowar[p1] = NULL;
1187 }
1188 mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);
1189 }
1190}
1191
1192static void
1193l2_st7_got_super(struct FsmInst *fi, int event, void *arg)
1194{
1195 struct layer2 *l2 = fi->userdata;
1196 struct sk_buff *skb = arg;
1197 int PollFlag, rsp, typ = RR;
1198 unsigned int nr;
1199
1200 rsp = *skb->data & 0x2;
1201 if (test_bit(FLG_ORIG, &l2->flag))
1202 rsp = !rsp;
1203
1204 skb_pull(skb, l2addrsize(l2));
1205 if (IsRNR(skb->data, l2)) {
1206 set_peer_busy(l2);
1207 typ = RNR;
1208 } else
1209 clear_peer_busy(l2);
1210 if (IsREJ(skb->data, l2))
1211 typ = REJ;
1212
1213 if (test_bit(FLG_MOD128, &l2->flag)) {
1214 PollFlag = (skb->data[1] & 0x1) == 0x1;
1215 nr = skb->data[1] >> 1;
1216 } else {
1217 PollFlag = (skb->data[0] & 0x10);
1218 nr = (skb->data[0] >> 5) & 0x7;
1219 }
1220 dev_kfree_skb(skb);
1221
1222 if (PollFlag) {
1223 if (rsp)
1224 l2mgr(l2, MDL_ERROR_IND, (void *) 'A');
1225 else
1226 enquiry_response(l2);
1227 }
1228 if (legalnr(l2, nr)) {
1229 if (typ == REJ) {
1230 setva(l2, nr);
1231 invoke_retransmission(l2, nr);
1232 stop_t200(l2, 10);
1233 if (mISDN_FsmAddTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001234 EV_L2_T203, NULL, 6))
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001235 l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");
1236 } else if ((nr == l2->vs) && (typ == RR)) {
1237 setva(l2, nr);
1238 stop_t200(l2, 11);
1239 mISDN_FsmRestartTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001240 EV_L2_T203, NULL, 7);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001241 } else if ((l2->va != nr) || (typ == RNR)) {
1242 setva(l2, nr);
1243 if (typ != RR)
1244 mISDN_FsmDelTimer(&l2->t203, 9);
1245 restart_t200(l2, 12);
1246 }
1247 if (skb_queue_len(&l2->i_queue) && (typ == RR))
1248 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1249 } else
1250 nrerrorrecovery(fi);
1251}
1252
1253static void
1254l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)
1255{
1256 struct layer2 *l2 = fi->userdata;
1257 struct sk_buff *skb = arg;
1258
1259 if (!test_bit(FLG_L3_INIT, &l2->flag))
1260 skb_queue_tail(&l2->i_queue, skb);
1261 else
1262 dev_kfree_skb(skb);
1263}
1264
1265static void
1266l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)
1267{
1268 struct layer2 *l2 = fi->userdata;
1269 struct sk_buff *skb = arg;
1270
1271 skb_queue_tail(&l2->i_queue, skb);
1272 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1273}
1274
1275static void
1276l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)
1277{
1278 struct layer2 *l2 = fi->userdata;
1279 struct sk_buff *skb = arg;
1280
1281 skb_queue_tail(&l2->i_queue, skb);
1282}
1283
1284static void
1285l2_got_iframe(struct FsmInst *fi, int event, void *arg)
1286{
1287 struct layer2 *l2 = fi->userdata;
1288 struct sk_buff *skb = arg;
1289 int PollFlag, i;
1290 u_int ns, nr;
1291
1292 i = l2addrsize(l2);
1293 if (test_bit(FLG_MOD128, &l2->flag)) {
1294 PollFlag = ((skb->data[i + 1] & 0x1) == 0x1);
1295 ns = skb->data[i] >> 1;
1296 nr = (skb->data[i + 1] >> 1) & 0x7f;
1297 } else {
1298 PollFlag = (skb->data[i] & 0x10);
1299 ns = (skb->data[i] >> 1) & 0x7;
1300 nr = (skb->data[i] >> 5) & 0x7;
1301 }
1302 if (test_bit(FLG_OWN_BUSY, &l2->flag)) {
1303 dev_kfree_skb(skb);
1304 if (PollFlag)
1305 enquiry_response(l2);
1306 } else {
1307 if (l2->vr == ns) {
1308 l2->vr++;
1309 if (test_bit(FLG_MOD128, &l2->flag))
1310 l2->vr %= 128;
1311 else
1312 l2->vr %= 8;
1313 test_and_clear_bit(FLG_REJEXC, &l2->flag);
1314 if (PollFlag)
1315 enquiry_response(l2);
1316 else
1317 test_and_set_bit(FLG_ACK_PEND, &l2->flag);
1318 skb_pull(skb, l2headersize(l2, 0));
1319 l2up(l2, DL_DATA_IND, skb);
1320 } else {
1321 /* n(s)!=v(r) */
1322 dev_kfree_skb(skb);
1323 if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {
1324 if (PollFlag)
1325 enquiry_response(l2);
1326 } else {
1327 enquiry_cr(l2, REJ, RSP, PollFlag);
1328 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1329 }
1330 }
1331 }
1332 if (legalnr(l2, nr)) {
1333 if (!test_bit(FLG_PEER_BUSY, &l2->flag) &&
1334 (fi->state == ST_L2_7)) {
1335 if (nr == l2->vs) {
1336 stop_t200(l2, 13);
1337 mISDN_FsmRestartTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001338 EV_L2_T203, NULL, 7);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001339 } else if (nr != l2->va)
1340 restart_t200(l2, 14);
1341 }
1342 setva(l2, nr);
1343 } else {
1344 nrerrorrecovery(fi);
1345 return;
1346 }
1347 if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7))
1348 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1349 if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag))
1350 enquiry_cr(l2, RR, RSP, 0);
1351}
1352
1353static void
1354l2_got_tei(struct FsmInst *fi, int event, void *arg)
1355{
1356 struct layer2 *l2 = fi->userdata;
1357 u_int info;
1358
1359 l2->tei = (signed char)(long)arg;
1360 set_channel_address(&l2->ch, l2->sapi, l2->tei);
1361 info = DL_INFO_L2_CONNECT;
1362 l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info);
1363 if (fi->state == ST_L2_3) {
1364 establishlink(fi);
1365 test_and_set_bit(FLG_L3_INIT, &l2->flag);
1366 } else
1367 mISDN_FsmChangeState(fi, ST_L2_4);
1368 if (skb_queue_len(&l2->ui_queue))
1369 tx_ui(l2);
1370}
1371
1372static void
1373l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)
1374{
1375 struct layer2 *l2 = fi->userdata;
1376
1377 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001378 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001379 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1380 } else if (l2->rc == l2->N200) {
1381 mISDN_FsmChangeState(fi, ST_L2_4);
1382 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1383 skb_queue_purge(&l2->i_queue);
1384 l2mgr(l2, MDL_ERROR_IND, (void *) 'G');
1385 if (test_bit(FLG_LAPB, &l2->flag))
1386 l2down_create(l2, PH_DEACTIVATE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08001387 l2_newid(l2), 0, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001388 st5_dl_release_l2l3(l2);
1389 if (l2->tm)
1390 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1391 } else {
1392 l2->rc++;
1393 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1394 send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?
Joe Perches475be4d2012-02-19 19:52:38 -08001395 SABME : SABM) | 0x10, CMD);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001396 }
1397}
1398
1399static void
1400l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)
1401{
1402 struct layer2 *l2 = fi->userdata;
1403
1404 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001405 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001406 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1407 } else if (l2->rc == l2->N200) {
1408 mISDN_FsmChangeState(fi, ST_L2_4);
1409 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1410 l2mgr(l2, MDL_ERROR_IND, (void *) 'H');
1411 lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);
1412 if (l2->tm)
1413 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1414 } else {
1415 l2->rc++;
1416 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,
Joe Perches475be4d2012-02-19 19:52:38 -08001417 NULL, 9);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001418 send_uframe(l2, NULL, DISC | 0x10, CMD);
1419 }
1420}
1421
1422static void
1423l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)
1424{
1425 struct layer2 *l2 = fi->userdata;
1426
1427 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001428 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001429 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1430 return;
1431 }
1432 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1433 l2->rc = 0;
1434 mISDN_FsmChangeState(fi, ST_L2_8);
1435 transmit_enquiry(l2);
1436 l2->rc++;
1437}
1438
1439static void
1440l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)
1441{
1442 struct layer2 *l2 = fi->userdata;
1443
1444 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001445 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001446 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);
1447 return;
1448 }
1449 test_and_clear_bit(FLG_T200_RUN, &l2->flag);
1450 if (l2->rc == l2->N200) {
1451 l2mgr(l2, MDL_ERROR_IND, (void *) 'I');
1452 establishlink(fi);
1453 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1454 } else {
1455 transmit_enquiry(l2);
1456 l2->rc++;
1457 }
1458}
1459
1460static void
1461l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)
1462{
1463 struct layer2 *l2 = fi->userdata;
1464
1465 if (test_bit(FLG_LAPD, &l2->flag) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001466 test_bit(FLG_DCHAN_BUSY, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001467 mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);
1468 return;
1469 }
1470 mISDN_FsmChangeState(fi, ST_L2_8);
1471 transmit_enquiry(l2);
1472 l2->rc = 0;
1473}
1474
1475static void
1476l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)
1477{
1478 struct layer2 *l2 = fi->userdata;
1479 struct sk_buff *skb, *nskb, *oskb;
1480 u_char header[MAX_L2HEADER_LEN];
1481 u_int i, p1;
1482
1483 if (!cansend(l2))
1484 return;
1485
1486 skb = skb_dequeue(&l2->i_queue);
1487 if (!skb)
1488 return;
1489
1490 if (test_bit(FLG_MOD128, &l2->flag))
1491 p1 = (l2->vs - l2->va) % 128;
1492 else
1493 p1 = (l2->vs - l2->va) % 8;
1494 p1 = (p1 + l2->sow) % l2->window;
1495 if (l2->windowar[p1]) {
Karsten Keilf45ebf32012-05-04 04:15:35 +00001496 printk(KERN_WARNING "%s: l2 try overwrite ack queue entry %d\n",
1497 mISDNDevName4ch(&l2->ch), p1);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001498 dev_kfree_skb(l2->windowar[p1]);
1499 }
1500 l2->windowar[p1] = skb;
1501 i = sethdraddr(l2, header, CMD);
1502 if (test_bit(FLG_MOD128, &l2->flag)) {
1503 header[i++] = l2->vs << 1;
1504 header[i++] = l2->vr << 1;
1505 l2->vs = (l2->vs + 1) % 128;
1506 } else {
1507 header[i++] = (l2->vr << 5) | (l2->vs << 1);
1508 l2->vs = (l2->vs + 1) % 8;
1509 }
1510
1511 nskb = skb_clone(skb, GFP_ATOMIC);
1512 p1 = skb_headroom(nskb);
1513 if (p1 >= i)
1514 memcpy(skb_push(nskb, i), header, i);
1515 else {
1516 printk(KERN_WARNING
Karsten Keilf45ebf32012-05-04 04:15:35 +00001517 "%s: L2 pull_iqueue skb header(%d/%d) too short\n",
1518 mISDNDevName4ch(&l2->ch), i, p1);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001519 oskb = nskb;
1520 nskb = mI_alloc_skb(oskb->len + i, GFP_ATOMIC);
1521 if (!nskb) {
1522 dev_kfree_skb(oskb);
Karsten Keilf45ebf32012-05-04 04:15:35 +00001523 printk(KERN_WARNING "%s: no skb mem in %s\n",
1524 mISDNDevName4ch(&l2->ch), __func__);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001525 return;
1526 }
1527 memcpy(skb_put(nskb, i), header, i);
1528 memcpy(skb_put(nskb, oskb->len), oskb->data, oskb->len);
1529 dev_kfree_skb(oskb);
1530 }
1531 l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);
1532 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1533 if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {
1534 mISDN_FsmDelTimer(&l2->t203, 13);
1535 mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11);
1536 }
1537}
1538
1539static void
1540l2_st8_got_super(struct FsmInst *fi, int event, void *arg)
1541{
1542 struct layer2 *l2 = fi->userdata;
1543 struct sk_buff *skb = arg;
1544 int PollFlag, rsp, rnr = 0;
1545 unsigned int nr;
1546
1547 rsp = *skb->data & 0x2;
1548 if (test_bit(FLG_ORIG, &l2->flag))
1549 rsp = !rsp;
1550
1551 skb_pull(skb, l2addrsize(l2));
1552
1553 if (IsRNR(skb->data, l2)) {
1554 set_peer_busy(l2);
1555 rnr = 1;
1556 } else
1557 clear_peer_busy(l2);
1558
1559 if (test_bit(FLG_MOD128, &l2->flag)) {
1560 PollFlag = (skb->data[1] & 0x1) == 0x1;
1561 nr = skb->data[1] >> 1;
1562 } else {
1563 PollFlag = (skb->data[0] & 0x10);
1564 nr = (skb->data[0] >> 5) & 0x7;
1565 }
1566 dev_kfree_skb(skb);
1567 if (rsp && PollFlag) {
1568 if (legalnr(l2, nr)) {
1569 if (rnr) {
1570 restart_t200(l2, 15);
1571 } else {
1572 stop_t200(l2, 16);
1573 mISDN_FsmAddTimer(&l2->t203, l2->T203,
Joe Perches475be4d2012-02-19 19:52:38 -08001574 EV_L2_T203, NULL, 5);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001575 setva(l2, nr);
1576 }
1577 invoke_retransmission(l2, nr);
1578 mISDN_FsmChangeState(fi, ST_L2_7);
1579 if (skb_queue_len(&l2->i_queue) && cansend(l2))
1580 mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);
1581 } else
1582 nrerrorrecovery(fi);
1583 } else {
1584 if (!rsp && PollFlag)
1585 enquiry_response(l2);
1586 if (legalnr(l2, nr))
1587 setva(l2, nr);
1588 else
1589 nrerrorrecovery(fi);
1590 }
1591}
1592
1593static void
1594l2_got_FRMR(struct FsmInst *fi, int event, void *arg)
1595{
1596 struct layer2 *l2 = fi->userdata;
1597 struct sk_buff *skb = arg;
1598
1599 skb_pull(skb, l2addrsize(l2) + 1);
1600
1601 if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */
1602 (IsUA(skb->data) && (fi->state == ST_L2_7))) {
1603 l2mgr(l2, MDL_ERROR_IND, (void *) 'K');
1604 establishlink(fi);
1605 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1606 }
1607 dev_kfree_skb(skb);
1608}
1609
1610static void
1611l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg)
1612{
1613 struct layer2 *l2 = fi->userdata;
1614
1615 skb_queue_purge(&l2->ui_queue);
1616 l2->tei = GROUP_TEI;
1617 mISDN_FsmChangeState(fi, ST_L2_1);
1618}
1619
1620static void
1621l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg)
1622{
1623 struct layer2 *l2 = fi->userdata;
1624
1625 skb_queue_purge(&l2->ui_queue);
1626 l2->tei = GROUP_TEI;
1627 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1628 mISDN_FsmChangeState(fi, ST_L2_1);
1629}
1630
1631static void
1632l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg)
1633{
1634 struct layer2 *l2 = fi->userdata;
1635
1636 skb_queue_purge(&l2->i_queue);
1637 skb_queue_purge(&l2->ui_queue);
1638 freewin(l2);
1639 l2->tei = GROUP_TEI;
1640 stop_t200(l2, 17);
1641 st5_dl_release_l2l3(l2);
1642 mISDN_FsmChangeState(fi, ST_L2_1);
1643}
1644
1645static void
1646l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg)
1647{
1648 struct layer2 *l2 = fi->userdata;
1649
1650 skb_queue_purge(&l2->ui_queue);
1651 l2->tei = GROUP_TEI;
1652 stop_t200(l2, 18);
1653 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1654 mISDN_FsmChangeState(fi, ST_L2_1);
1655}
1656
1657static void
1658l2_tei_remove(struct FsmInst *fi, int event, void *arg)
1659{
1660 struct layer2 *l2 = fi->userdata;
1661
1662 skb_queue_purge(&l2->i_queue);
1663 skb_queue_purge(&l2->ui_queue);
1664 freewin(l2);
1665 l2->tei = GROUP_TEI;
1666 stop_t200(l2, 17);
1667 mISDN_FsmDelTimer(&l2->t203, 19);
1668 l2up_create(l2, DL_RELEASE_IND, 0, NULL);
1669/* mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,
1670 * MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED,
1671 * 0, NULL, 0);
1672 */
1673 mISDN_FsmChangeState(fi, ST_L2_1);
1674}
1675
1676static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001677l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001678{
1679 struct layer2 *l2 = fi->userdata;
1680 struct sk_buff *skb = arg;
1681
1682 skb_queue_purge(&l2->i_queue);
1683 skb_queue_purge(&l2->ui_queue);
1684 if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
1685 l2up(l2, DL_RELEASE_IND, skb);
1686 else
1687 dev_kfree_skb(skb);
1688}
1689
1690static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001691l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001692{
1693 struct layer2 *l2 = fi->userdata;
1694 struct sk_buff *skb = arg;
1695
1696 skb_queue_purge(&l2->i_queue);
1697 skb_queue_purge(&l2->ui_queue);
1698 freewin(l2);
1699 stop_t200(l2, 19);
1700 st5_dl_release_l2l3(l2);
1701 mISDN_FsmChangeState(fi, ST_L2_4);
1702 if (l2->tm)
1703 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1704 dev_kfree_skb(skb);
1705}
1706
1707static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001708l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001709{
1710 struct layer2 *l2 = fi->userdata;
1711 struct sk_buff *skb = arg;
1712
1713 skb_queue_purge(&l2->ui_queue);
1714 stop_t200(l2, 20);
1715 l2up(l2, DL_RELEASE_CNF, skb);
1716 mISDN_FsmChangeState(fi, ST_L2_4);
1717 if (l2->tm)
1718 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1719}
1720
1721static void
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001722l2_persistent_da(struct FsmInst *fi, int event, void *arg)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001723{
1724 struct layer2 *l2 = fi->userdata;
1725 struct sk_buff *skb = arg;
1726
1727 skb_queue_purge(&l2->i_queue);
1728 skb_queue_purge(&l2->ui_queue);
1729 freewin(l2);
1730 stop_t200(l2, 19);
1731 mISDN_FsmDelTimer(&l2->t203, 19);
1732 l2up(l2, DL_RELEASE_IND, skb);
1733 mISDN_FsmChangeState(fi, ST_L2_4);
1734 if (l2->tm)
1735 l2_tei(l2, MDL_STATUS_DOWN_IND, 0);
1736}
1737
1738static void
1739l2_set_own_busy(struct FsmInst *fi, int event, void *arg)
1740{
1741 struct layer2 *l2 = fi->userdata;
1742 struct sk_buff *skb = arg;
1743
1744 if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) {
1745 enquiry_cr(l2, RNR, RSP, 0);
1746 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1747 }
1748 if (skb)
1749 dev_kfree_skb(skb);
1750}
1751
1752static void
1753l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)
1754{
1755 struct layer2 *l2 = fi->userdata;
1756 struct sk_buff *skb = arg;
1757
1758 if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) {
1759 enquiry_cr(l2, RR, RSP, 0);
1760 test_and_clear_bit(FLG_ACK_PEND, &l2->flag);
1761 }
1762 if (skb)
1763 dev_kfree_skb(skb);
1764}
1765
1766static void
1767l2_frame_error(struct FsmInst *fi, int event, void *arg)
1768{
1769 struct layer2 *l2 = fi->userdata;
1770
1771 l2mgr(l2, MDL_ERROR_IND, arg);
1772}
1773
1774static void
1775l2_frame_error_reest(struct FsmInst *fi, int event, void *arg)
1776{
1777 struct layer2 *l2 = fi->userdata;
1778
1779 l2mgr(l2, MDL_ERROR_IND, arg);
1780 establishlink(fi);
1781 test_and_clear_bit(FLG_L3_INIT, &l2->flag);
1782}
1783
1784static struct FsmNode L2FnList[] =
1785{
1786 {ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign},
1787 {ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3},
1788 {ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish},
1789 {ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3},
1790 {ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
1791 {ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},
1792 {ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release},
1793 {ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel},
1794 {ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect},
1795 {ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect},
1796 {ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest},
1797 {ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull},
1798 {ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},
1799 {ST_L2_1, EV_L2_DL_UNITDATA, l2_queue_ui_assign},
1800 {ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui},
1801 {ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui},
1802 {ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui},
1803 {ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui},
1804 {ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui},
1805 {ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui},
1806 {ST_L2_8, EV_L2_DL_UNITDATA, l2_send_ui},
1807 {ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei},
1808 {ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei},
1809 {ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei},
1810 {ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove},
1811 {ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove},
1812 {ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove},
1813 {ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove},
1814 {ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove},
1815 {ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove},
1816 {ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove},
1817 {ST_L2_4, EV_L2_SABME, l2_start_multi},
1818 {ST_L2_5, EV_L2_SABME, l2_send_UA},
1819 {ST_L2_6, EV_L2_SABME, l2_send_DM},
1820 {ST_L2_7, EV_L2_SABME, l2_restart_multi},
1821 {ST_L2_8, EV_L2_SABME, l2_restart_multi},
1822 {ST_L2_4, EV_L2_DISC, l2_send_DM},
1823 {ST_L2_5, EV_L2_DISC, l2_send_DM},
1824 {ST_L2_6, EV_L2_DISC, l2_send_UA},
1825 {ST_L2_7, EV_L2_DISC, l2_stop_multi},
1826 {ST_L2_8, EV_L2_DISC, l2_stop_multi},
1827 {ST_L2_4, EV_L2_UA, l2_mdl_error_ua},
1828 {ST_L2_5, EV_L2_UA, l2_connected},
1829 {ST_L2_6, EV_L2_UA, l2_released},
1830 {ST_L2_7, EV_L2_UA, l2_mdl_error_ua},
1831 {ST_L2_8, EV_L2_UA, l2_mdl_error_ua},
1832 {ST_L2_4, EV_L2_DM, l2_reestablish},
1833 {ST_L2_5, EV_L2_DM, l2_st5_dm_release},
1834 {ST_L2_6, EV_L2_DM, l2_st6_dm_release},
1835 {ST_L2_7, EV_L2_DM, l2_mdl_error_dm},
1836 {ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm},
1837 {ST_L2_1, EV_L2_UI, l2_got_ui},
1838 {ST_L2_2, EV_L2_UI, l2_got_ui},
1839 {ST_L2_3, EV_L2_UI, l2_got_ui},
1840 {ST_L2_4, EV_L2_UI, l2_got_ui},
1841 {ST_L2_5, EV_L2_UI, l2_got_ui},
1842 {ST_L2_6, EV_L2_UI, l2_got_ui},
1843 {ST_L2_7, EV_L2_UI, l2_got_ui},
1844 {ST_L2_8, EV_L2_UI, l2_got_ui},
1845 {ST_L2_7, EV_L2_FRMR, l2_got_FRMR},
1846 {ST_L2_8, EV_L2_FRMR, l2_got_FRMR},
1847 {ST_L2_7, EV_L2_SUPER, l2_st7_got_super},
1848 {ST_L2_8, EV_L2_SUPER, l2_st8_got_super},
1849 {ST_L2_7, EV_L2_I, l2_got_iframe},
1850 {ST_L2_8, EV_L2_I, l2_got_iframe},
Karsten Keil8423e6b2012-05-04 04:15:32 +00001851 {ST_L2_5, EV_L2_T200, l2_timeout},
1852 {ST_L2_6, EV_L2_T200, l2_timeout},
1853 {ST_L2_7, EV_L2_T200, l2_timeout},
1854 {ST_L2_8, EV_L2_T200, l2_timeout},
1855 {ST_L2_7, EV_L2_T203, l2_timeout},
1856 {ST_L2_5, EV_L2_T200I, l2_st5_tout_200},
1857 {ST_L2_6, EV_L2_T200I, l2_st6_tout_200},
1858 {ST_L2_7, EV_L2_T200I, l2_st7_tout_200},
1859 {ST_L2_8, EV_L2_T200I, l2_st8_tout_200},
1860 {ST_L2_7, EV_L2_T203I, l2_st7_tout_203},
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001861 {ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},
1862 {ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
1863 {ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy},
1864 {ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
1865 {ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},
1866 {ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error},
1867 {ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error},
1868 {ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
1869 {ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
1870 {ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001871 {ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001872 {ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
1873 {ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
Jan Engelhardt95b8fba2011-04-03 13:31:06 +00001874 {ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
1875 {ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
1876 {ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
1877 {ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
1878 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001879};
1880
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001881static int
1882ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
1883{
1884 u_char *datap = skb->data;
1885 int ret = -EINVAL;
1886 int psapi, ptei;
1887 u_int l;
1888 int c = 0;
1889
1890 l = l2addrsize(l2);
1891 if (skb->len <= l) {
1892 mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
1893 return ret;
1894 }
1895 if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
1896 psapi = *datap++;
1897 ptei = *datap++;
1898 if ((psapi & 1) || !(ptei & 1)) {
1899 printk(KERN_WARNING
Karsten Keilf45ebf32012-05-04 04:15:35 +00001900 "%s l2 D-channel frame wrong EA0/EA1\n",
1901 mISDNDevName4ch(&l2->ch));
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001902 return ret;
1903 }
1904 psapi >>= 2;
1905 ptei >>= 1;
1906 if (psapi != l2->sapi) {
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001907 /* not our business */
Andreas Eversbergd7965092009-05-22 11:04:51 +00001908 if (*debug & DEBUG_L2)
1909 printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
Karsten Keilf45ebf32012-05-04 04:15:35 +00001910 mISDNDevName4ch(&l2->ch), psapi,
1911 l2->sapi);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001912 dev_kfree_skb(skb);
1913 return 0;
1914 }
1915 if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001916 /* not our business */
Andreas Eversbergd7965092009-05-22 11:04:51 +00001917 if (*debug & DEBUG_L2)
1918 printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
Karsten Keilf45ebf32012-05-04 04:15:35 +00001919 mISDNDevName4ch(&l2->ch), ptei, l2->tei);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001920 dev_kfree_skb(skb);
1921 return 0;
1922 }
1923 } else
1924 datap += l;
1925 if (!(*datap & 1)) { /* I-Frame */
1926 c = iframe_error(l2, skb);
1927 if (!c)
1928 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb);
1929 } else if (IsSFrame(datap, l2)) { /* S-Frame */
1930 c = super_error(l2, skb);
1931 if (!c)
1932 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb);
1933 } else if (IsUI(datap)) {
1934 c = UI_error(l2, skb);
1935 if (!c)
1936 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
1937 } else if (IsSABME(datap, l2)) {
1938 c = unnum_error(l2, skb, CMD);
1939 if (!c)
1940 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
1941 } else if (IsUA(datap)) {
1942 c = unnum_error(l2, skb, RSP);
1943 if (!c)
1944 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb);
1945 } else if (IsDISC(datap)) {
1946 c = unnum_error(l2, skb, CMD);
1947 if (!c)
1948 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb);
1949 } else if (IsDM(datap)) {
1950 c = unnum_error(l2, skb, RSP);
1951 if (!c)
1952 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb);
1953 } else if (IsFRMR(datap)) {
1954 c = FRMR_error(l2, skb);
1955 if (!c)
1956 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb);
1957 } else
1958 c = 'L';
1959 if (c) {
Karsten Keilf45ebf32012-05-04 04:15:35 +00001960 printk(KERN_WARNING "%s:l2 D-channel frame error %c\n",
1961 mISDNDevName4ch(&l2->ch), c);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001962 mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c);
1963 }
1964 return ret;
1965}
1966
1967static int
1968l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
1969{
1970 struct layer2 *l2 = container_of(ch, struct layer2, ch);
1971 struct mISDNhead *hh = mISDN_HEAD_P(skb);
Joe Perches475be4d2012-02-19 19:52:38 -08001972 int ret = -EINVAL;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001973
1974 if (*debug & DEBUG_L2_RECV)
Karsten Keilf45ebf32012-05-04 04:15:35 +00001975 printk(KERN_DEBUG "%s: %s prim(%x) id(%x) sapi(%d) tei(%d)\n",
1976 __func__, mISDNDevName4ch(&l2->ch), hh->prim, hh->id,
1977 l2->sapi, l2->tei);
Karsten Keil8423e6b2012-05-04 04:15:32 +00001978 if (hh->prim == DL_INTERN_MSG) {
1979 struct mISDNhead *chh = hh + 1; /* saved copy */
1980
1981 *hh = *chh;
1982 if (*debug & DEBUG_L2_RECV)
1983 printk(KERN_DEBUG "%s: prim(%x) id(%x) internal msg\n",
Karsten Keilf45ebf32012-05-04 04:15:35 +00001984 mISDNDevName4ch(&l2->ch), hh->prim, hh->id);
Karsten Keil8423e6b2012-05-04 04:15:32 +00001985 }
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001986 switch (hh->prim) {
1987 case PH_DATA_IND:
1988 ret = ph_data_indication(l2, hh, skb);
1989 break;
1990 case PH_DATA_CNF:
1991 ret = ph_data_confirm(l2, hh, skb);
1992 break;
1993 case PH_ACTIVATE_IND:
1994 test_and_set_bit(FLG_L1_ACTIV, &l2->flag);
1995 l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);
1996 if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))
1997 ret = mISDN_FsmEvent(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -08001998 EV_L2_DL_ESTABLISH_REQ, skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02001999 break;
2000 case PH_DEACTIVATE_IND:
2001 test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);
2002 l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL);
2003 ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb);
2004 break;
2005 case MPH_INFORMATION_IND:
2006 if (!l2->up)
2007 break;
2008 ret = l2->up->send(l2->up, skb);
2009 break;
2010 case DL_DATA_REQ:
2011 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);
2012 break;
2013 case DL_UNITDATA_REQ:
2014 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb);
2015 break;
2016 case DL_ESTABLISH_REQ:
2017 if (test_bit(FLG_LAPB, &l2->flag))
2018 test_and_set_bit(FLG_ORIG, &l2->flag);
2019 if (test_bit(FLG_L1_ACTIV, &l2->flag)) {
2020 if (test_bit(FLG_LAPD, &l2->flag) ||
Joe Perches475be4d2012-02-19 19:52:38 -08002021 test_bit(FLG_ORIG, &l2->flag))
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002022 ret = mISDN_FsmEvent(&l2->l2m,
Joe Perches475be4d2012-02-19 19:52:38 -08002023 EV_L2_DL_ESTABLISH_REQ, skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002024 } else {
2025 if (test_bit(FLG_LAPD, &l2->flag) ||
Joe Perches475be4d2012-02-19 19:52:38 -08002026 test_bit(FLG_ORIG, &l2->flag)) {
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002027 test_and_set_bit(FLG_ESTAB_PEND,
Joe Perches475be4d2012-02-19 19:52:38 -08002028 &l2->flag);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002029 }
2030 ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),
Joe Perches475be4d2012-02-19 19:52:38 -08002031 skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002032 }
2033 break;
2034 case DL_RELEASE_REQ:
2035 if (test_bit(FLG_LAPB, &l2->flag))
2036 l2down_create(l2, PH_DEACTIVATE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08002037 l2_newid(l2), 0, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002038 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,
Joe Perches475be4d2012-02-19 19:52:38 -08002039 skb);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002040 break;
Karsten Keil8423e6b2012-05-04 04:15:32 +00002041 case DL_TIMER200_IND:
2042 mISDN_FsmEvent(&l2->l2m, EV_L2_T200I, NULL);
2043 break;
2044 case DL_TIMER203_IND:
2045 mISDN_FsmEvent(&l2->l2m, EV_L2_T203I, NULL);
2046 break;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002047 default:
2048 if (*debug & DEBUG_L2)
2049 l2m_debug(&l2->l2m, "l2 unknown pr %04x",
Joe Perches475be4d2012-02-19 19:52:38 -08002050 hh->prim);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002051 }
2052 if (ret) {
2053 dev_kfree_skb(skb);
2054 ret = 0;
2055 }
2056 return ret;
2057}
2058
2059int
2060tei_l2(struct layer2 *l2, u_int cmd, u_long arg)
2061{
2062 int ret = -EINVAL;
2063
2064 if (*debug & DEBUG_L2_TEI)
Karsten Keilf45ebf32012-05-04 04:15:35 +00002065 printk(KERN_DEBUG "%s: cmd(%x) in %s\n",
2066 mISDNDevName4ch(&l2->ch), cmd, __func__);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002067 switch (cmd) {
2068 case (MDL_ASSIGN_REQ):
2069 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg);
2070 break;
2071 case (MDL_REMOVE_REQ):
2072 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL);
2073 break;
2074 case (MDL_ERROR_IND):
2075 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
2076 break;
2077 case (MDL_ERROR_RSP):
2078 /* ETS 300-125 5.3.2.1 Test: TC13010 */
Karsten Keilf45ebf32012-05-04 04:15:35 +00002079 printk(KERN_NOTICE "%s: MDL_ERROR|REQ (tei_l2)\n",
2080 mISDNDevName4ch(&l2->ch));
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002081 ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);
2082 break;
2083 }
2084 return ret;
2085}
2086
2087static void
2088release_l2(struct layer2 *l2)
2089{
2090 mISDN_FsmDelTimer(&l2->t200, 21);
2091 mISDN_FsmDelTimer(&l2->t203, 16);
2092 skb_queue_purge(&l2->i_queue);
2093 skb_queue_purge(&l2->ui_queue);
2094 skb_queue_purge(&l2->down_queue);
2095 ReleaseWin(l2);
2096 if (test_bit(FLG_LAPD, &l2->flag)) {
Karsten Keilc5b61d52008-07-27 18:32:50 +02002097 TEIrelease(l2);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002098 if (l2->ch.st)
2099 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,
Joe Perches475be4d2012-02-19 19:52:38 -08002100 CLOSE_CHANNEL, NULL);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002101 }
2102 kfree(l2);
2103}
2104
2105static int
2106l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
2107{
2108 struct layer2 *l2 = container_of(ch, struct layer2, ch);
2109 u_int info;
2110
2111 if (*debug & DEBUG_L2_CTRL)
Karsten Keilf45ebf32012-05-04 04:15:35 +00002112 printk(KERN_DEBUG "%s: %s cmd(%x)\n",
2113 mISDNDevName4ch(ch), __func__, cmd);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002114
2115 switch (cmd) {
2116 case OPEN_CHANNEL:
2117 if (test_bit(FLG_LAPD, &l2->flag)) {
2118 set_channel_address(&l2->ch, l2->sapi, l2->tei);
2119 info = DL_INFO_L2_CONNECT;
2120 l2up_create(l2, DL_INFORMATION_IND,
Joe Perches475be4d2012-02-19 19:52:38 -08002121 sizeof(info), &info);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002122 }
2123 break;
2124 case CLOSE_CHANNEL:
2125 if (l2->ch.peer)
2126 l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL);
2127 release_l2(l2);
2128 break;
2129 }
2130 return 0;
2131}
2132
2133struct layer2 *
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002134create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
Joe Perches475be4d2012-02-19 19:52:38 -08002135 int sapi)
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002136{
2137 struct layer2 *l2;
2138 struct channel_req rq;
2139
2140 l2 = kzalloc(sizeof(struct layer2), GFP_KERNEL);
2141 if (!l2) {
2142 printk(KERN_ERR "kzalloc layer2 failed\n");
2143 return NULL;
2144 }
2145 l2->next_id = 1;
2146 l2->down_id = MISDN_ID_NONE;
2147 l2->up = ch;
2148 l2->ch.st = ch->st;
2149 l2->ch.send = l2_send;
2150 l2->ch.ctrl = l2_ctrl;
2151 switch (protocol) {
2152 case ISDN_P_LAPD_NT:
2153 test_and_set_bit(FLG_LAPD, &l2->flag);
2154 test_and_set_bit(FLG_LAPD_NET, &l2->flag);
2155 test_and_set_bit(FLG_MOD128, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002156 l2->sapi = sapi;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002157 l2->maxlen = MAX_DFRAME_LEN;
2158 if (test_bit(OPTION_L2_PMX, &options))
2159 l2->window = 7;
2160 else
2161 l2->window = 1;
2162 if (test_bit(OPTION_L2_PTP, &options))
2163 test_and_set_bit(FLG_PTP, &l2->flag);
2164 if (test_bit(OPTION_L2_FIXEDTEI, &options))
2165 test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002166 l2->tei = tei;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002167 l2->T200 = 1000;
2168 l2->N200 = 3;
2169 l2->T203 = 10000;
2170 if (test_bit(OPTION_L2_PMX, &options))
2171 rq.protocol = ISDN_P_NT_E1;
2172 else
2173 rq.protocol = ISDN_P_NT_S0;
2174 rq.adr.channel = 0;
2175 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
2176 break;
2177 case ISDN_P_LAPD_TE:
2178 test_and_set_bit(FLG_LAPD, &l2->flag);
2179 test_and_set_bit(FLG_MOD128, &l2->flag);
2180 test_and_set_bit(FLG_ORIG, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002181 l2->sapi = sapi;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002182 l2->maxlen = MAX_DFRAME_LEN;
2183 if (test_bit(OPTION_L2_PMX, &options))
2184 l2->window = 7;
2185 else
2186 l2->window = 1;
2187 if (test_bit(OPTION_L2_PTP, &options))
2188 test_and_set_bit(FLG_PTP, &l2->flag);
2189 if (test_bit(OPTION_L2_FIXEDTEI, &options))
2190 test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002191 l2->tei = tei;
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002192 l2->T200 = 1000;
2193 l2->N200 = 3;
2194 l2->T203 = 10000;
2195 if (test_bit(OPTION_L2_PMX, &options))
2196 rq.protocol = ISDN_P_TE_E1;
2197 else
2198 rq.protocol = ISDN_P_TE_S0;
2199 rq.adr.channel = 0;
2200 l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);
2201 break;
2202 case ISDN_P_B_X75SLP:
2203 test_and_set_bit(FLG_LAPB, &l2->flag);
2204 l2->window = 7;
2205 l2->maxlen = MAX_DATA_SIZE;
2206 l2->T200 = 1000;
2207 l2->N200 = 4;
2208 l2->T203 = 5000;
2209 l2->addr.A = 3;
2210 l2->addr.B = 1;
2211 break;
2212 default:
2213 printk(KERN_ERR "layer2 create failed prt %x\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002214 protocol);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002215 kfree(l2);
2216 return NULL;
2217 }
2218 skb_queue_head_init(&l2->i_queue);
2219 skb_queue_head_init(&l2->ui_queue);
2220 skb_queue_head_init(&l2->down_queue);
2221 skb_queue_head_init(&l2->tmp_queue);
2222 InitWin(l2);
2223 l2->l2m.fsm = &l2fsm;
2224 if (test_bit(FLG_LAPB, &l2->flag) ||
Karsten Keil25099332012-08-04 00:14:25 +00002225 test_bit(FLG_FIXED_TEI, &l2->flag) ||
Joe Perches475be4d2012-02-19 19:52:38 -08002226 test_bit(FLG_LAPD_NET, &l2->flag))
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002227 l2->l2m.state = ST_L2_4;
2228 else
2229 l2->l2m.state = ST_L2_1;
2230 l2->l2m.debug = *debug;
2231 l2->l2m.userdata = l2;
2232 l2->l2m.userint = 0;
2233 l2->l2m.printdebug = l2m_debug;
2234
2235 mISDN_FsmInitTimer(&l2->l2m, &l2->t200);
2236 mISDN_FsmInitTimer(&l2->l2m, &l2->t203);
2237 return l2;
2238}
2239
2240static int
2241x75create(struct channel_req *crq)
2242{
2243 struct layer2 *l2;
2244
2245 if (crq->protocol != ISDN_P_B_X75SLP)
2246 return -EPROTONOSUPPORT;
Andreas Eversberg5b277b82009-05-25 00:50:02 -07002247 l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);
Karsten Keil1b2b03f2008-07-27 01:54:58 +02002248 if (!l2)
2249 return -ENOMEM;
2250 crq->ch = &l2->ch;
2251 crq->protocol = ISDN_P_B_HDLC;
2252 return 0;
2253}
2254
2255static struct Bprotocol X75SLP = {
2256 .Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)),
2257 .name = "X75SLP",
2258 .create = x75create
2259};
2260
2261int
2262Isdnl2_Init(u_int *deb)
2263{
2264 debug = deb;
2265 mISDN_register_Bprotocol(&X75SLP);
2266 l2fsm.state_count = L2_STATE_COUNT;
2267 l2fsm.event_count = L2_EVENT_COUNT;
2268 l2fsm.strEvent = strL2Event;
2269 l2fsm.strState = strL2State;
2270 mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
2271 TEIInit(deb);
2272 return 0;
2273}
2274
2275void
2276Isdnl2_cleanup(void)
2277{
2278 mISDN_unregister_Bprotocol(&X75SLP);
2279 TEIFree();
2280 mISDN_FsmFree(&l2fsm);
2281}