File: /usr/src/linux/drivers/isdn/hisax/isdnl1.c
1 /* $Id: isdnl1.c,v 2.41.6.4 2001/08/23 19:44:23 kai Exp $
2 *
3 * isdnl1.c common low level stuff for Siemens Chipsetbased isdn cards
4 * based on the teles driver from Jan den Ouden
5 *
6 * Author Karsten Keil (keil@isdn4linux.de)
7 *
8 * This file is (c) under GNU General Public License
9 * For changes and modifications please read
10 * ../../../Documentation/isdn/HiSax.cert
11 *
12 * Thanks to Jan den Ouden
13 * Fritz Elfert
14 * Beat Doebeli
15 *
16 */
17
18 const char *l1_revision = "$Revision: 2.41.6.4 $";
19
20 #define __NO_VERSION__
21 #include <linux/init.h>
22 #include "hisax.h"
23 #include "isdnl1.h"
24
25 #define TIMER3_VALUE 7000
26
27 static struct Fsm l1fsm_b;
28 static struct Fsm l1fsm_s;
29
30 enum {
31 ST_L1_F2,
32 ST_L1_F3,
33 ST_L1_F4,
34 ST_L1_F5,
35 ST_L1_F6,
36 ST_L1_F7,
37 ST_L1_F8,
38 };
39
40 #define L1S_STATE_COUNT (ST_L1_F8+1)
41
42 static char *strL1SState[] =
43 {
44 "ST_L1_F2",
45 "ST_L1_F3",
46 "ST_L1_F4",
47 "ST_L1_F5",
48 "ST_L1_F6",
49 "ST_L1_F7",
50 "ST_L1_F8",
51 };
52
53 #ifdef HISAX_UINTERFACE
54 static
55 struct Fsm l1fsm_u =
56 {NULL, 0, 0, NULL, NULL};
57
58 enum {
59 ST_L1_RESET,
60 ST_L1_DEACT,
61 ST_L1_SYNC2,
62 ST_L1_TRANS,
63 };
64
65 #define L1U_STATE_COUNT (ST_L1_TRANS+1)
66
67 static char *strL1UState[] =
68 {
69 "ST_L1_RESET",
70 "ST_L1_DEACT",
71 "ST_L1_SYNC2",
72 "ST_L1_TRANS",
73 };
74 #endif
75
76 enum {
77 ST_L1_NULL,
78 ST_L1_WAIT_ACT,
79 ST_L1_WAIT_DEACT,
80 ST_L1_ACTIV,
81 };
82
83 #define L1B_STATE_COUNT (ST_L1_ACTIV+1)
84
85 static char *strL1BState[] =
86 {
87 "ST_L1_NULL",
88 "ST_L1_WAIT_ACT",
89 "ST_L1_WAIT_DEACT",
90 "ST_L1_ACTIV",
91 };
92
93 enum {
94 EV_PH_ACTIVATE,
95 EV_PH_DEACTIVATE,
96 EV_RESET_IND,
97 EV_DEACT_CNF,
98 EV_DEACT_IND,
99 EV_POWER_UP,
100 EV_RSYNC_IND,
101 EV_INFO2_IND,
102 EV_INFO4_IND,
103 EV_TIMER_DEACT,
104 EV_TIMER_ACT,
105 EV_TIMER3,
106 };
107
108 #define L1_EVENT_COUNT (EV_TIMER3 + 1)
109
110 static char *strL1Event[] =
111 {
112 "EV_PH_ACTIVATE",
113 "EV_PH_DEACTIVATE",
114 "EV_RESET_IND",
115 "EV_DEACT_CNF",
116 "EV_DEACT_IND",
117 "EV_POWER_UP",
118 "EV_RSYNC_IND",
119 "EV_INFO2_IND",
120 "EV_INFO4_IND",
121 "EV_TIMER_DEACT",
122 "EV_TIMER_ACT",
123 "EV_TIMER3",
124 };
125
126 void
127 debugl1(struct IsdnCardState *cs, char *fmt, ...)
128 {
129 va_list args;
130 char tmp[8];
131
132 va_start(args, fmt);
133 sprintf(tmp, "Card%d ", cs->cardnr + 1);
134 VHiSax_putstatus(cs, tmp, fmt, args);
135 va_end(args);
136 }
137
138 static void
139 l1m_debug(struct FsmInst *fi, char *fmt, ...)
140 {
141 va_list args;
142 struct PStack *st = fi->userdata;
143 struct IsdnCardState *cs = st->l1.hardware;
144 char tmp[8];
145
146 va_start(args, fmt);
147 sprintf(tmp, "Card%d ", cs->cardnr + 1);
148 VHiSax_putstatus(cs, tmp, fmt, args);
149 va_end(args);
150 }
151
152 void
153 L1activated(struct IsdnCardState *cs)
154 {
155 struct PStack *st;
156
157 st = cs->stlist;
158 while (st) {
159 if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
160 st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
161 else
162 st->l1.l1l2(st, PH_ACTIVATE | INDICATION, NULL);
163 st = st->next;
164 }
165 }
166
167 void
168 L1deactivated(struct IsdnCardState *cs)
169 {
170 struct PStack *st;
171
172 st = cs->stlist;
173 while (st) {
174 if (test_bit(FLG_L1_DBUSY, &cs->HW_Flags))
175 st->l1.l1l2(st, PH_PAUSE | CONFIRM, NULL);
176 st->l1.l1l2(st, PH_DEACTIVATE | INDICATION, NULL);
177 st = st->next;
178 }
179 test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags);
180 }
181
182 void
183 DChannel_proc_xmt(struct IsdnCardState *cs)
184 {
185 struct PStack *stptr;
186
187 if (cs->tx_skb)
188 return;
189
190 stptr = cs->stlist;
191 while (stptr != NULL)
192 if (test_and_clear_bit(FLG_L1_PULL_REQ, &stptr->l1.Flags)) {
193 stptr->l1.l1l2(stptr, PH_PULL | CONFIRM, NULL);
194 break;
195 } else
196 stptr = stptr->next;
197 }
198
199 void
200 DChannel_proc_rcv(struct IsdnCardState *cs)
201 {
202 struct sk_buff *skb, *nskb;
203 struct PStack *stptr = cs->stlist;
204 int found, tei, sapi;
205
206 if (stptr)
207 if (test_bit(FLG_L1_ACTTIMER, &stptr->l1.Flags))
208 FsmEvent(&stptr->l1.l1m, EV_TIMER_ACT, NULL);
209 while ((skb = skb_dequeue(&cs->rq))) {
210 #ifdef L2FRAME_DEBUG /* psa */
211 if (cs->debug & L1_DEB_LAPD)
212 Logl2Frame(cs, skb, "PH_DATA", 1);
213 #endif
214 stptr = cs->stlist;
215 if (skb->len<3) {
216 debugl1(cs, "D-channel frame too short(%d)",skb->len);
217 dev_kfree_skb(skb);
218 return;
219 }
220 if ((skb->data[0] & 1) || !(skb->data[1] &1)) {
221 debugl1(cs, "D-channel frame wrong EA0/EA1");
222 dev_kfree_skb(skb);
223 return;
224 }
225 sapi = skb->data[0] >> 2;
226 tei = skb->data[1] >> 1;
227 if (cs->debug & DEB_DLOG_HEX)
228 LogFrame(cs, skb->data, skb->len);
229 if (cs->debug & DEB_DLOG_VERBOSE)
230 dlogframe(cs, skb, 1);
231 if (tei == GROUP_TEI) {
232 if (sapi == CTRL_SAPI) { /* sapi 0 */
233 while (stptr != NULL) {
234 if ((nskb = skb_clone(skb, GFP_ATOMIC)))
235 stptr->l1.l1l2(stptr, PH_DATA | INDICATION, nskb);
236 else
237 printk(KERN_WARNING "HiSax: isdn broadcast buffer shortage\n");
238 stptr = stptr->next;
239 }
240 } else if (sapi == TEI_SAPI) {
241 while (stptr != NULL) {
242 if ((nskb = skb_clone(skb, GFP_ATOMIC)))
243 stptr->l1.l1tei(stptr, PH_DATA | INDICATION, nskb);
244 else
245 printk(KERN_WARNING "HiSax: tei broadcast buffer shortage\n");
246 stptr = stptr->next;
247 }
248 }
249 dev_kfree_skb(skb);
250 } else if (sapi == CTRL_SAPI) { /* sapi 0 */
251 found = 0;
252 while (stptr != NULL)
253 if (tei == stptr->l2.tei) {
254 stptr->l1.l1l2(stptr, PH_DATA | INDICATION, skb);
255 found = !0;
256 break;
257 } else
258 stptr = stptr->next;
259 if (!found)
260 dev_kfree_skb(skb);
261 } else
262 dev_kfree_skb(skb);
263 }
264 }
265
266 static void
267 BChannel_proc_xmt(struct BCState *bcs)
268 {
269 struct PStack *st = bcs->st;
270
271 if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
272 debugl1(bcs->cs, "BC_BUSY Error");
273 return;
274 }
275
276 if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags))
277 st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
278 if (!test_bit(BC_FLG_ACTIV, &bcs->Flag)) {
279 if (!test_bit(BC_FLG_BUSY, &bcs->Flag) && (!skb_queue_len(&bcs->squeue))) {
280 st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL);
281 }
282 }
283 }
284
285 static void
286 BChannel_proc_rcv(struct BCState *bcs)
287 {
288 struct sk_buff *skb;
289
290 if (bcs->st->l1.l1m.state == ST_L1_WAIT_ACT) {
291 FsmDelTimer(&bcs->st->l1.timer, 4);
292 FsmEvent(&bcs->st->l1.l1m, EV_TIMER_ACT, NULL);
293 }
294 while ((skb = skb_dequeue(&bcs->rqueue))) {
295 bcs->st->l1.l1l2(bcs->st, PH_DATA | INDICATION, skb);
296 }
297 }
298
299 void
300 BChannel_bh(struct BCState *bcs)
301 {
302 if (!bcs)
303 return;
304 if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event))
305 BChannel_proc_rcv(bcs);
306 if (test_and_clear_bit(B_XMTBUFREADY, &bcs->event))
307 BChannel_proc_xmt(bcs);
308 }
309
310 void
311 HiSax_addlist(struct IsdnCardState *cs,
312 struct PStack *st)
313 {
314 st->next = cs->stlist;
315 cs->stlist = st;
316 }
317
318 void
319 HiSax_rmlist(struct IsdnCardState *cs,
320 struct PStack *st)
321 {
322 struct PStack *p;
323
324 FsmDelTimer(&st->l1.timer, 0);
325 if (cs->stlist == st)
326 cs->stlist = st->next;
327 else {
328 p = cs->stlist;
329 while (p)
330 if (p->next == st) {
331 p->next = st->next;
332 return;
333 } else
334 p = p->next;
335 }
336 }
337
338 void
339 init_bcstate(struct IsdnCardState *cs,
340 int bc)
341 {
342 struct BCState *bcs = cs->bcs + bc;
343
344 bcs->cs = cs;
345 bcs->channel = bc;
346 bcs->tqueue.sync = 0;
347 bcs->tqueue.routine = (void *) (void *) BChannel_bh;
348 bcs->tqueue.data = bcs;
349 bcs->BC_SetStack = NULL;
350 bcs->BC_Close = NULL;
351 bcs->Flag = 0;
352 }
353
354 #ifdef L2FRAME_DEBUG /* psa */
355
356 char *
357 l2cmd(u_char cmd)
358 {
359 switch (cmd & ~0x10) {
360 case 1:
361 return "RR";
362 case 5:
363 return "RNR";
364 case 9:
365 return "REJ";
366 case 0x6f:
367 return "SABME";
368 case 0x0f:
369 return "DM";
370 case 3:
371 return "UI";
372 case 0x43:
373 return "DISC";
374 case 0x63:
375 return "UA";
376 case 0x87:
377 return "FRMR";
378 case 0xaf:
379 return "XID";
380 default:
381 if (!(cmd & 1))
382 return "I";
383 else
384 return "invalid command";
385 }
386 }
387
388 static char tmpdeb[32];
389
390 char *
391 l2frames(u_char * ptr)
392 {
393 switch (ptr[2] & ~0x10) {
394 case 1:
395 case 5:
396 case 9:
397 sprintf(tmpdeb, "%s[%d](nr %d)", l2cmd(ptr[2]), ptr[3] & 1, ptr[3] >> 1);
398 break;
399 case 0x6f:
400 case 0x0f:
401 case 3:
402 case 0x43:
403 case 0x63:
404 case 0x87:
405 case 0xaf:
406 sprintf(tmpdeb, "%s[%d]", l2cmd(ptr[2]), (ptr[2] & 0x10) >> 4);
407 break;
408 default:
409 if (!(ptr[2] & 1)) {
410 sprintf(tmpdeb, "I[%d](ns %d, nr %d)", ptr[3] & 1, ptr[2] >> 1, ptr[3] >> 1);
411 break;
412 } else
413 return "invalid command";
414 }
415
416
417 return tmpdeb;
418 }
419
420 void
421 Logl2Frame(struct IsdnCardState *cs, struct sk_buff *skb, char *buf, int dir)
422 {
423 u_char *ptr;
424
425 ptr = skb->data;
426
427 if (ptr[0] & 1 || !(ptr[1] & 1))
428 debugl1(cs, "Address not LAPD");
429 else
430 debugl1(cs, "%s %s: %s%c (sapi %d, tei %d)",
431 (dir ? "<-" : "->"), buf, l2frames(ptr),
432 ((ptr[0] & 2) >> 1) == dir ? 'C' : 'R', ptr[0] >> 2, ptr[1] >> 1);
433 }
434 #endif
435
436 static void
437 l1_reset(struct FsmInst *fi, int event, void *arg)
438 {
439 FsmChangeState(fi, ST_L1_F3);
440 }
441
442 static void
443 l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
444 {
445 struct PStack *st = fi->userdata;
446
447 FsmChangeState(fi, ST_L1_F3);
448 if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
449 st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
450 }
451
452 static void
453 l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
454 {
455 struct PStack *st = fi->userdata;
456
457 FsmChangeState(fi, ST_L1_F3);
458 FsmRestartTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2);
459 test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
460 }
461
462 static void
463 l1_power_up_s(struct FsmInst *fi, int event, void *arg)
464 {
465 struct PStack *st = fi->userdata;
466
467 if (test_bit(FLG_L1_ACTIVATING, &st->l1.Flags)) {
468 FsmChangeState(fi, ST_L1_F4);
469 st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
470 FsmRestartTimer(&st->l1.timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
471 test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags);
472 } else
473 FsmChangeState(fi, ST_L1_F3);
474 }
475
476 static void
477 l1_go_F5(struct FsmInst *fi, int event, void *arg)
478 {
479 FsmChangeState(fi, ST_L1_F5);
480 }
481
482 static void
483 l1_go_F8(struct FsmInst *fi, int event, void *arg)
484 {
485 FsmChangeState(fi, ST_L1_F8);
486 }
487
488 static void
489 l1_info2_ind(struct FsmInst *fi, int event, void *arg)
490 {
491 struct PStack *st = fi->userdata;
492
493 #ifdef HISAX_UINTERFACE
494 if (test_bit(FLG_L1_UINT, &st->l1.Flags))
495 FsmChangeState(fi, ST_L1_SYNC2);
496 else
497 #endif
498 FsmChangeState(fi, ST_L1_F6);
499 st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
500 }
501
502 static void
503 l1_info4_ind(struct FsmInst *fi, int event, void *arg)
504 {
505 struct PStack *st = fi->userdata;
506
507 #ifdef HISAX_UINTERFACE
508 if (test_bit(FLG_L1_UINT, &st->l1.Flags))
509 FsmChangeState(fi, ST_L1_TRANS);
510 else
511 #endif
512 FsmChangeState(fi, ST_L1_F7);
513 st->l1.l1hw(st, HW_INFO3 | REQUEST, NULL);
514 if (test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags))
515 FsmDelTimer(&st->l1.timer, 4);
516 if (!test_bit(FLG_L1_ACTIVATED, &st->l1.Flags)) {
517 if (test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags))
518 FsmDelTimer(&st->l1.timer, 3);
519 FsmRestartTimer(&st->l1.timer, 110, EV_TIMER_ACT, NULL, 2);
520 test_and_set_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
521 }
522 }
523
524 static void
525 l1_timer3(struct FsmInst *fi, int event, void *arg)
526 {
527 struct PStack *st = fi->userdata;
528
529 test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags);
530 if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
531 L1deactivated(st->l1.hardware);
532
533 #ifdef HISAX_UINTERFACE
534 if (!test_bit(FLG_L1_UINT, &st->l1.Flags))
535 #endif
536 if (st->l1.l1m.state != ST_L1_F6) {
537 FsmChangeState(fi, ST_L1_F3);
538 st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
539 }
540 }
541
542 static void
543 l1_timer_act(struct FsmInst *fi, int event, void *arg)
544 {
545 struct PStack *st = fi->userdata;
546
547 test_and_clear_bit(FLG_L1_ACTTIMER, &st->l1.Flags);
548 test_and_set_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
549 L1activated(st->l1.hardware);
550 }
551
552 static void
553 l1_timer_deact(struct FsmInst *fi, int event, void *arg)
554 {
555 struct PStack *st = fi->userdata;
556
557 test_and_clear_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
558 test_and_clear_bit(FLG_L1_ACTIVATED, &st->l1.Flags);
559 L1deactivated(st->l1.hardware);
560 st->l1.l1hw(st, HW_DEACTIVATE | RESPONSE, NULL);
561 }
562
563 static void
564 l1_activate_s(struct FsmInst *fi, int event, void *arg)
565 {
566 struct PStack *st = fi->userdata;
567
568 st->l1.l1hw(st, HW_RESET | REQUEST, NULL);
569 }
570
571 static void
572 l1_activate_no(struct FsmInst *fi, int event, void *arg)
573 {
574 struct PStack *st = fi->userdata;
575
576 if ((!test_bit(FLG_L1_DEACTTIMER, &st->l1.Flags)) && (!test_bit(FLG_L1_T3RUN, &st->l1.Flags))) {
577 test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
578 L1deactivated(st->l1.hardware);
579 }
580 }
581
582 static struct FsmNode L1SFnList[] __initdata =
583 {
584 {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s},
585 {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no},
586 {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no},
587 {ST_L1_F3, EV_RESET_IND, l1_reset},
588 {ST_L1_F4, EV_RESET_IND, l1_reset},
589 {ST_L1_F5, EV_RESET_IND, l1_reset},
590 {ST_L1_F6, EV_RESET_IND, l1_reset},
591 {ST_L1_F7, EV_RESET_IND, l1_reset},
592 {ST_L1_F8, EV_RESET_IND, l1_reset},
593 {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf},
594 {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf},
595 {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf},
596 {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf},
597 {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf},
598 {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf},
599 {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s},
600 {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s},
601 {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s},
602 {ST_L1_F3, EV_POWER_UP, l1_power_up_s},
603 {ST_L1_F4, EV_RSYNC_IND, l1_go_F5},
604 {ST_L1_F6, EV_RSYNC_IND, l1_go_F8},
605 {ST_L1_F7, EV_RSYNC_IND, l1_go_F8},
606 {ST_L1_F3, EV_INFO2_IND, l1_info2_ind},
607 {ST_L1_F4, EV_INFO2_IND, l1_info2_ind},
608 {ST_L1_F5, EV_INFO2_IND, l1_info2_ind},
609 {ST_L1_F7, EV_INFO2_IND, l1_info2_ind},
610 {ST_L1_F8, EV_INFO2_IND, l1_info2_ind},
611 {ST_L1_F3, EV_INFO4_IND, l1_info4_ind},
612 {ST_L1_F4, EV_INFO4_IND, l1_info4_ind},
613 {ST_L1_F5, EV_INFO4_IND, l1_info4_ind},
614 {ST_L1_F6, EV_INFO4_IND, l1_info4_ind},
615 {ST_L1_F8, EV_INFO4_IND, l1_info4_ind},
616 {ST_L1_F3, EV_TIMER3, l1_timer3},
617 {ST_L1_F4, EV_TIMER3, l1_timer3},
618 {ST_L1_F5, EV_TIMER3, l1_timer3},
619 {ST_L1_F6, EV_TIMER3, l1_timer3},
620 {ST_L1_F8, EV_TIMER3, l1_timer3},
621 {ST_L1_F7, EV_TIMER_ACT, l1_timer_act},
622 {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact},
623 {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact},
624 {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact},
625 {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact},
626 {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact},
627 {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
628 };
629
630 #define L1S_FN_COUNT (sizeof(L1SFnList)/sizeof(struct FsmNode))
631
632 #ifdef HISAX_UINTERFACE
633 static void
634 l1_deact_req_u(struct FsmInst *fi, int event, void *arg)
635 {
636 struct PStack *st = fi->userdata;
637
638 FsmChangeState(fi, ST_L1_RESET);
639 FsmRestartTimer(&st->l1.timer, 550, EV_TIMER_DEACT, NULL, 2);
640 test_and_set_bit(FLG_L1_DEACTTIMER, &st->l1.Flags);
641 st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
642 }
643
644 static void
645 l1_power_up_u(struct FsmInst *fi, int event, void *arg)
646 {
647 struct PStack *st = fi->userdata;
648
649 FsmRestartTimer(&st->l1.timer, TIMER3_VALUE, EV_TIMER3, NULL, 2);
650 test_and_set_bit(FLG_L1_T3RUN, &st->l1.Flags);
651 }
652
653 static void
654 l1_info0_ind(struct FsmInst *fi, int event, void *arg)
655 {
656 FsmChangeState(fi, ST_L1_DEACT);
657 }
658
659 static void
660 l1_activate_u(struct FsmInst *fi, int event, void *arg)
661 {
662 struct PStack *st = fi->userdata;
663
664 st->l1.l1hw(st, HW_INFO1 | REQUEST, NULL);
665 }
666
667 static struct FsmNode L1UFnList[] __initdata =
668 {
669 {ST_L1_RESET, EV_DEACT_IND, l1_deact_req_u},
670 {ST_L1_DEACT, EV_DEACT_IND, l1_deact_req_u},
671 {ST_L1_SYNC2, EV_DEACT_IND, l1_deact_req_u},
672 {ST_L1_TRANS, EV_DEACT_IND, l1_deact_req_u},
673 {ST_L1_DEACT, EV_PH_ACTIVATE, l1_activate_u},
674 {ST_L1_DEACT, EV_POWER_UP, l1_power_up_u},
675 {ST_L1_DEACT, EV_INFO2_IND, l1_info2_ind},
676 {ST_L1_TRANS, EV_INFO2_IND, l1_info2_ind},
677 {ST_L1_RESET, EV_DEACT_CNF, l1_info0_ind},
678 {ST_L1_DEACT, EV_INFO4_IND, l1_info4_ind},
679 {ST_L1_SYNC2, EV_INFO4_IND, l1_info4_ind},
680 {ST_L1_RESET, EV_INFO4_IND, l1_info4_ind},
681 {ST_L1_DEACT, EV_TIMER3, l1_timer3},
682 {ST_L1_SYNC2, EV_TIMER3, l1_timer3},
683 {ST_L1_TRANS, EV_TIMER_ACT, l1_timer_act},
684 {ST_L1_DEACT, EV_TIMER_DEACT, l1_timer_deact},
685 {ST_L1_SYNC2, EV_TIMER_DEACT, l1_timer_deact},
686 {ST_L1_RESET, EV_TIMER_DEACT, l1_timer_deact},
687 };
688
689 #define L1U_FN_COUNT (sizeof(L1UFnList)/sizeof(struct FsmNode))
690
691 #endif
692
693 static void
694 l1b_activate(struct FsmInst *fi, int event, void *arg)
695 {
696 struct PStack *st = fi->userdata;
697
698 FsmChangeState(fi, ST_L1_WAIT_ACT);
699 FsmRestartTimer(&st->l1.timer, st->l1.delay, EV_TIMER_ACT, NULL, 2);
700 }
701
702 static void
703 l1b_deactivate(struct FsmInst *fi, int event, void *arg)
704 {
705 struct PStack *st = fi->userdata;
706
707 FsmChangeState(fi, ST_L1_WAIT_DEACT);
708 FsmRestartTimer(&st->l1.timer, 10, EV_TIMER_DEACT, NULL, 2);
709 }
710
711 static void
712 l1b_timer_act(struct FsmInst *fi, int event, void *arg)
713 {
714 struct PStack *st = fi->userdata;
715
716 FsmChangeState(fi, ST_L1_ACTIV);
717 st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
718 }
719
720 static void
721 l1b_timer_deact(struct FsmInst *fi, int event, void *arg)
722 {
723 struct PStack *st = fi->userdata;
724
725 FsmChangeState(fi, ST_L1_NULL);
726 st->l2.l2l1(st, PH_DEACTIVATE | CONFIRM, NULL);
727 }
728
729 static struct FsmNode L1BFnList[] __initdata =
730 {
731 {ST_L1_NULL, EV_PH_ACTIVATE, l1b_activate},
732 {ST_L1_WAIT_ACT, EV_TIMER_ACT, l1b_timer_act},
733 {ST_L1_ACTIV, EV_PH_DEACTIVATE, l1b_deactivate},
734 {ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact},
735 };
736
737 #define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
738
739 int __init
740 Isdnl1New(void)
741 {
742 int retval;
743
744 l1fsm_s.state_count = L1S_STATE_COUNT;
745 l1fsm_s.event_count = L1_EVENT_COUNT;
746 l1fsm_s.strEvent = strL1Event;
747 l1fsm_s.strState = strL1SState;
748 retval = FsmNew(&l1fsm_s, L1SFnList, L1S_FN_COUNT);
749 if (retval)
750 return retval;
751
752 l1fsm_b.state_count = L1B_STATE_COUNT;
753 l1fsm_b.event_count = L1_EVENT_COUNT;
754 l1fsm_b.strEvent = strL1Event;
755 l1fsm_b.strState = strL1BState;
756 retval = FsmNew(&l1fsm_b, L1BFnList, L1B_FN_COUNT);
757 if (retval) {
758 FsmFree(&l1fsm_s);
759 return retval;
760 }
761 #ifdef HISAX_UINTERFACE
762 l1fsm_u.state_count = L1U_STATE_COUNT;
763 l1fsm_u.event_count = L1_EVENT_COUNT;
764 l1fsm_u.strEvent = strL1Event;
765 l1fsm_u.strState = strL1UState;
766 retval = FsmNew(&l1fsm_u, L1UFnList, L1U_FN_COUNT);
767 if (retval) {
768 FsmFree(&l1fsm_s);
769 FsmFree(&l1fsm_b);
770 return retval;
771 }
772 #endif
773 return 0;
774 }
775
776 void Isdnl1Free(void)
777 {
778 #ifdef HISAX_UINTERFACE
779 FsmFree(&l1fsm_u);
780 #endif
781 FsmFree(&l1fsm_s);
782 FsmFree(&l1fsm_b);
783 }
784
785 static void
786 dch_l2l1(struct PStack *st, int pr, void *arg)
787 {
788 struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
789
790 switch (pr) {
791 case (PH_DATA | REQUEST):
792 case (PH_PULL | REQUEST):
793 case (PH_PULL |INDICATION):
794 st->l1.l1hw(st, pr, arg);
795 break;
796 case (PH_ACTIVATE | REQUEST):
797 if (cs->debug)
798 debugl1(cs, "PH_ACTIVATE_REQ %s",
799 st->l1.l1m.fsm->strState[st->l1.l1m.state]);
800 if (test_bit(FLG_L1_ACTIVATED, &st->l1.Flags))
801 st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
802 else {
803 test_and_set_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
804 FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, arg);
805 }
806 break;
807 case (PH_TESTLOOP | REQUEST):
808 if (1 & (long) arg)
809 debugl1(cs, "PH_TEST_LOOP B1");
810 if (2 & (long) arg)
811 debugl1(cs, "PH_TEST_LOOP B2");
812 if (!(3 & (long) arg))
813 debugl1(cs, "PH_TEST_LOOP DISABLED");
814 st->l1.l1hw(st, HW_TESTLOOP | REQUEST, arg);
815 break;
816 default:
817 if (cs->debug)
818 debugl1(cs, "dch_l2l1 msg %04X unhandled", pr);
819 break;
820 }
821 }
822
823 void
824 l1_msg(struct IsdnCardState *cs, int pr, void *arg) {
825 struct PStack *st;
826
827 st = cs->stlist;
828
829 while (st) {
830 switch(pr) {
831 case (HW_RESET | INDICATION):
832 FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
833 break;
834 case (HW_DEACTIVATE | CONFIRM):
835 FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
836 break;
837 case (HW_DEACTIVATE | INDICATION):
838 FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
839 break;
840 case (HW_POWERUP | CONFIRM):
841 FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
842 break;
843 case (HW_RSYNC | INDICATION):
844 FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
845 break;
846 case (HW_INFO2 | INDICATION):
847 FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
848 break;
849 case (HW_INFO4_P8 | INDICATION):
850 case (HW_INFO4_P10 | INDICATION):
851 FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
852 break;
853 default:
854 if (cs->debug)
855 debugl1(cs, "l1msg %04X unhandled", pr);
856 break;
857 }
858 st = st->next;
859 }
860 }
861
862 void
863 l1_msg_b(struct PStack *st, int pr, void *arg) {
864 switch(pr) {
865 case (PH_ACTIVATE | REQUEST):
866 FsmEvent(&st->l1.l1m, EV_PH_ACTIVATE, NULL);
867 break;
868 case (PH_DEACTIVATE | REQUEST):
869 FsmEvent(&st->l1.l1m, EV_PH_DEACTIVATE, NULL);
870 break;
871 }
872 }
873
874 void
875 setstack_HiSax(struct PStack *st, struct IsdnCardState *cs)
876 {
877 st->l1.hardware = cs;
878 st->protocol = cs->protocol;
879 st->l1.l1m.fsm = &l1fsm_s;
880 st->l1.l1m.state = ST_L1_F3;
881 st->l1.Flags = 0;
882 #ifdef HISAX_UINTERFACE
883 if (test_bit(FLG_HW_L1_UINT, &cs->HW_Flags)) {
884 st->l1.l1m.fsm = &l1fsm_u;
885 st->l1.l1m.state = ST_L1_RESET;
886 st->l1.Flags = FLG_L1_UINT;
887 }
888 #endif
889 st->l1.l1m.debug = cs->debug;
890 st->l1.l1m.userdata = st;
891 st->l1.l1m.userint = 0;
892 st->l1.l1m.printdebug = l1m_debug;
893 FsmInitTimer(&st->l1.l1m, &st->l1.timer);
894 setstack_tei(st);
895 setstack_manager(st);
896 st->l1.stlistp = &(cs->stlist);
897 st->l2.l2l1 = dch_l2l1;
898 if (cs->setstack_d)
899 cs->setstack_d(st, cs);
900 }
901
902 void
903 setstack_l1_B(struct PStack *st)
904 {
905 struct IsdnCardState *cs = st->l1.hardware;
906
907 st->l1.l1m.fsm = &l1fsm_b;
908 st->l1.l1m.state = ST_L1_NULL;
909 st->l1.l1m.debug = cs->debug;
910 st->l1.l1m.userdata = st;
911 st->l1.l1m.userint = 0;
912 st->l1.l1m.printdebug = l1m_debug;
913 st->l1.Flags = 0;
914 FsmInitTimer(&st->l1.l1m, &st->l1.timer);
915 }
916