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