root/drivers/isdn/teles/isdnl2.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ph_r1
  2. ph_r2
  3. ph_r3
  4. ph_r4
  5. cansend
  6. discard_i_queue
  7. discard_window
  8. l2headersize
  9. l2addrsize
  10. sethdraddr
  11. enqueue_ui
  12. enqueue_super
  13. legalnr
  14. setva
  15. l2s1
  16. l2s2
  17. l2s3
  18. establishlink
  19. l2s11
  20. l2s13
  21. l2s12
  22. l2s14
  23. l2s5
  24. l2s15
  25. l2s6
  26. l2s7
  27. l2s8
  28. l2s17
  29. enquiry_response
  30. invoke_retransmission
  31. l2s16
  32. l2s19
  33. l2s20
  34. l2s21
  35. l2s22
  36. transmit_enquiry
  37. l2s23
  38. l2s24
  39. l2s25
  40. l2s26
  41. l2s27
  42. l2s28
  43. IsUI
  44. IsUA
  45. IsDISC
  46. IsRR
  47. IsI
  48. IsSABMX
  49. IsREJ
  50. IsFRMR
  51. IsRNR
  52. isdnl2_l1l2
  53. isdnl2_l3l2
  54. isdnl2_manl2
  55. isdnl2_teil2
  56. releasestack_isdnl2
  57. l2m_debug
  58. setstack_isdnl2
  59. trans_acceptph
  60. transdown
  61. setstack_transl2
  62. releasestack_transl2
  63. Isdnl2New
  64. Isdnl2Free

   1 /* $Id: isdnl2.c,v 1.1 1996/04/13 10:24:16 fritz Exp $
   2  *
   3  * $Log: isdnl2.c,v $
   4  * Revision 1.1  1996/04/13 10:24:16  fritz
   5  * Initial revision
   6  *
   7  *
   8  */
   9 #define __NO_VERSION__
  10 #include "teles.h"
  11 
  12 #define TIMER_1 2000
  13 
  14 static void     l2m_debug(struct FsmInst *fi, char *s);
  15 
  16 struct Fsm      l2fsm =
  17 {NULL, 0, 0};
  18 
  19 #if 0
  20 
  21 
  22 enum {
  23         ST_PH_NULL,
  24         ST_PH_ACTIVATED,
  25         ST_PH_ACTIVE,
  26 };
  27 
  28 #define PH_STATE_COUNT (ST_PH_ACTIVE+1)
  29 
  30 static char    *strPhState[] =
  31 {
  32         "ST_PH_NULL",
  33         "ST_PH_ACTIVATED",
  34         "ST_PH_ACTIVE",
  35 };
  36 
  37 enum {
  38         EV_PH_ACTIVATE_REQ,
  39         EV_PH_ACTIVATE,
  40         EV_PH_DEACTIVATE_REQ,
  41         EV_PH_DEACTIVATE,
  42 };
  43 
  44 #define PH_EVENT_COUNT (EV_PH_DEACTIVATE+1)
  45 
  46 static char    *strPhEvent[] =
  47 {
  48         "EV_PH_ACTIVATE_REQ",
  49         "EV_PH_ACTIVATE",
  50         "EV_PH_DEACTIVATE_REQ",
  51         "EV_PH_DEACTIVATE",
  52 };
  53 
  54 #endif
  55 
  56 enum {
  57         ST_L2_1,
  58         ST_L2_3,
  59         ST_L2_4,
  60         ST_L2_5,
  61         ST_L2_6,
  62         ST_L2_7,
  63         ST_L2_8,
  64 };
  65 
  66 #define L2_STATE_COUNT (ST_L2_8+1)
  67 
  68 static char    *strL2State[] =
  69 {
  70         "ST_L2_1",
  71         "ST_L2_3",
  72         "ST_L2_4",
  73         "ST_L2_5",
  74         "ST_L2_6",
  75         "ST_L2_7",
  76         "ST_L2_8",
  77 };
  78 
  79 enum {
  80         EV_L2_UI,
  81         EV_L2_SABMX,
  82         EV_L2_UA,
  83         EV_L2_DISC,
  84         EV_L2_I,
  85         EV_L2_RR,
  86         EV_L2_REJ,
  87         EV_L2_FRMR,
  88         EV_L2_DL_DATA,
  89         EV_L2_DL_ESTABLISH,
  90         EV_L2_MDL_ASSIGN,
  91         EV_L2_DL_UNIT_DATA,
  92         EV_L2_DL_RELEASE,
  93         EV_L2_MDL_NOTEIPROC,
  94         EV_L2_T200,
  95         EV_L2_ACK_PULL,
  96         EV_L2_T203,
  97         EV_L2_RNR,
  98 };
  99 
 100 #define L2_EVENT_COUNT (EV_L2_RNR+1)
 101 
 102 static char    *strL2Event[] =
 103 {
 104         "EV_L2_UI",
 105         "EV_L2_SABMX",
 106         "EV_L2_UA",
 107         "EV_L2_DISC",
 108         "EV_L2_I",
 109         "EV_L2_RR",
 110         "EV_L2_REJ",
 111         "EV_L2_FRMR",
 112         "EV_L2_DL_DATA",
 113         "EV_L2_DL_ESTABLISH",
 114         "EV_L2_MDL_ASSIGN",
 115         "EV_L2_DL_UNIT_DATA",
 116         "EV_L2_DL_RELEASE",
 117         "EV_L2_MDL_NOTEIPROC",
 118         "EV_L2_T200",
 119         "EV_L2_ACK_PULL",
 120         "EV_L2_T203",
 121         "EV_L2_RNR",
 122 };
 123 
 124 #if 0
 125 static void
 126 ph_r1(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 127 {
 128         struct PStack  *st = fi->userdata;
 129 
 130         FsmChangeState(fi, ST_PH_ACTIVATED);
 131         st->l1.service_down(st, PH_ACTIVATE, NULL);
 132 }
 133 
 134 static void
 135 ph_r2(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         struct PStack  *st = fi->userdata;
 138 
 139         FsmChangeState(fi, ST_PH_ACTIVE);
 140         st->l3.service_up(st, DL_ACTIVATE_CNF, NULL);
 141 }
 142 
 143 static void
 144 ph_r3(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 145 {
 146         struct PStack  *st = fi->userdata;
 147 
 148         FsmChangeState(fi, ST_PH_NULL);
 149         st->l1.service_down(st, PH_DEACTIVATE, NULL);
 150 }
 151 
 152 static void
 153 ph_r4(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155         struct PStack  *st = fi->userdata;
 156 
 157         FsmChangeState(fi, ST_PH_NULL);
 158         st->l3.service_up(st, DL_DEACTIVATE_IND, NULL);
 159 }
 160 
 161 static struct FsmNode PhFnList[] =
 162 {
 163         {ST_PH_NULL, EV_PH_ACTIVATE_REQ, ph_r1},
 164         {ST_PH_ACTIVATED, EV_PH_ACTIVATE, ph_r2},
 165         {ST_PH_ACTIVATED, EV_PH_DEACTIVATE, ph_r4},
 166         {ST_PH_ACTIVE, EV_PH_DEACTIVATE_REQ, ph_r3},
 167 };
 168 
 169 #define PH_FN_COUNT (sizeof(PhFnList)/sizeof(struct FsmNode))
 170 #endif
 171 
 172 int             errcount = 0;
 173 
 174 static int      l2addrsize(struct Layer2 *tsp);
 175 
 176 static int
 177 cansend(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         int             p1;
 180 
 181         p1 = (st->l2.va + st->l2.window) % (st->l2.extended ? 128 : 8);
 182         return (st->l2.vs != p1);
 183 }
 184 
 185 static void
 186 discard_i_queue(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         struct BufHeader *ibh;
 189 
 190         while (!BufQueueUnlink(&ibh, &st->l2.i_queue))
 191                 BufPoolRelease(ibh);
 192 }
 193 
 194 #ifdef DEFINED_BUT_NOT_USED
 195 static void
 196 discard_window(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         struct BufHeader *ibh;
 199         struct Layer2  *l2;
 200         int             i, p1, p2;
 201 
 202         l2 = &st->l2;
 203         p1 = l2->vs - l2->va;
 204         if (p1 < 0)
 205                 p1 += l2->extended ? 128 : 8;
 206 
 207         for (i = 0; i < p1; i++) {
 208                 p2 = (i + l2->sow) % l2->window;
 209                 ibh = l2->windowar[p2];
 210                 BufPoolRelease(ibh);
 211         }
 212 }
 213 #endif
 214 
 215 int
 216 l2headersize(struct Layer2 *tsp, int UI)
     /* [previous][next][first][last][top][bottom][index][help] */
 217 {
 218         return ((tsp->extended && (!UI) ? 2 : 1) + (tsp->laptype == LAPD ? 2 : 1));
 219 }
 220 
 221 int
 222 l2addrsize(struct Layer2 *tsp)
     /* [previous][next][first][last][top][bottom][index][help] */
 223 {
 224         return (tsp->laptype == LAPD ? 2 : 1);
 225 }
 226 
 227 static int
 228 sethdraddr(struct Layer2 *tsp,
     /* [previous][next][first][last][top][bottom][index][help] */
 229            struct BufHeader *ibh, int rsp)
 230 {
 231         byte           *ptr = DATAPTR(ibh);
 232         int             crbit;
 233 
 234         if (tsp->laptype == LAPD) {
 235                 crbit = rsp;
 236                 if (!tsp->orig)
 237                         crbit = !crbit;
 238                 *ptr++ = (tsp->sap << 2) | (crbit ? 2 : 0);
 239                 *ptr++ = (tsp->tei << 1) | 1;
 240                 return (2);
 241         } else {
 242                 crbit = rsp;
 243                 if (tsp->orig)
 244                         crbit = !crbit;
 245                 if (crbit)
 246                         *ptr++ = 1;
 247                 else
 248                         *ptr++ = 3;
 249                 return (1);
 250         }
 251 }
 252 
 253 static void
 254 enqueue_ui(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
 255            struct BufHeader *ibh)
 256 {
 257 #ifdef FRITZDEBUG
 258         static char     tmp[100];
 259 
 260         sprintf(tmp, "enqueue_ui: %d bytes\n", ibh->datasize);
 261         teles_putstatus(tmp);
 262 #endif
 263         st->l2.l2l1(st, PH_DATA, ibh);
 264 }
 265 
 266 static void
 267 enqueue_super(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
 268               struct BufHeader *ibh)
 269 {
 270 #ifdef FRITZDEBUG
 271         static char     tmp[100];
 272 
 273         sprintf(tmp, "enqueue_super: %d bytes\n", ibh->datasize);
 274         teles_putstatus(tmp);
 275 #endif
 276         st->l2.l2l1(st, PH_DATA, ibh);
 277 }
 278 
 279 static int
 280 legalnr(struct PStack *st, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282         struct Layer2  *l2 = &st->l2;
 283         int             lnr, lvs;
 284 
 285         lvs = (l2->vs >= l2->va) ? l2->vs : (l2->vs + l2->extended ? 128 : 8);
 286         lnr = (nr >= l2->va) ? nr : (nr + l2->extended ? 128 : 8);
 287         return (lnr <= lvs);
 288 }
 289 
 290 static void
 291 setva(struct PStack *st, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 292 {
 293         struct Layer2  *l2 = &st->l2;
 294 
 295         if (l2->va != nr) {
 296                 while (l2->va != nr) {
 297                         l2->va = (l2->va + 1) % (l2->extended ? 128 : 8);
 298                         BufPoolRelease(l2->windowar[l2->sow]);
 299                         l2->sow = (l2->sow + 1) % l2->window;
 300                 }
 301                 if (st->l4.l2writewakeup)
 302                         st->l4.l2writewakeup(st);
 303         }
 304 }
 305 
 306 static void
 307 l2s1(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 308 {
 309         struct PStack  *st = fi->userdata;
 310 
 311         st->l2.l2tei(st, MDL_ASSIGN, (void *)st->l2.ces);
 312         FsmChangeState(fi, ST_L2_3);
 313 }
 314 
 315 static void
 316 l2s2(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 317 {
 318         struct PStack  *st = fi->userdata;
 319         struct BufHeader *ibh = arg;
 320 
 321         byte           *ptr;
 322         int             i;
 323 
 324         i = sethdraddr(&(st->l2), ibh, 0);
 325         ptr = DATAPTR(ibh);
 326         ptr += i;
 327         *ptr = 0x3;
 328 
 329         enqueue_ui(st, ibh);
 330 }
 331 
 332 static void
 333 l2s3(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 334 {
 335         struct PStack  *st = fi->userdata;
 336         struct BufHeader *ibh = arg;
 337 
 338         st->l2.l2l3(st, DL_UNIT_DATA, ibh);
 339 }
 340 
 341 static void
 342 establishlink(struct FsmInst *fi)
     /* [previous][next][first][last][top][bottom][index][help] */
 343 {
 344         struct PStack  *st = fi->userdata;
 345         struct BufHeader *ibh;
 346         int             i;
 347         byte           *ptr;
 348 
 349         FsmChangeState(fi, ST_L2_5);
 350         st->l2.rc = 0;
 351 
 352         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 1))
 353                 if (st->l2.l2m.debug)
 354                         l2m_debug(&st->l2.l2m, "FAT 1");
 355 
 356 
 357         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
 358                 return;
 359         i = sethdraddr(&st->l2, ibh, 0);
 360         ptr = DATAPTR(ibh);
 361         ptr += i;
 362         if (st->l2.extended)
 363                 *ptr = 0x7f;
 364         else
 365                 *ptr = 0x3f;
 366         ibh->datasize = i + 1;
 367 
 368         enqueue_super(st, ibh);
 369 }
 370 
 371 static void
 372 l2s11(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 373 {
 374         establishlink(fi);
 375 }
 376 
 377 static void
 378 l2s13(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 379 {
 380         struct PStack  *st = fi->userdata;
 381         struct Channel *chanp = st->l4.userdata;
 382         byte           *ptr;
 383         struct BufHeader *ibh;
 384         int             i;
 385 
 386         FsmChangeState(fi, ST_L2_6);
 387 
 388         FsmDelTimer(&st->l2.t203_timer, 1);
 389         if (st->l2.t200_running) {
 390                 FsmDelTimer(&st->l2.t200_timer, 2);
 391                 st->l2.t200_running = 0;
 392         }
 393         st->l2.rc = 0;
 394         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 2))
 395                 if (st->l2.l2m.debug)
 396                         l2m_debug(&st->l2.l2m, "FAT 2");
 397 
 398 
 399         if ((chanp->impair == 2) && (st->l2.laptype == LAPB))
 400                 goto nodisc;
 401 
 402         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 9))
 403                 return;
 404         i = sethdraddr(&(st->l2), ibh, 0);
 405         ptr = DATAPTR(ibh);
 406         ptr += i;
 407         *ptr = 0x53;
 408         ibh->datasize = i + 1;
 409         enqueue_super(st, ibh);
 410 
 411       nodisc:
 412         discard_i_queue(st);
 413 }
 414 
 415 static void
 416 l2s12(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 417 {
 418         struct PStack  *st = fi->userdata;
 419         struct BufHeader *ibh = arg;
 420         byte           *ptr;
 421         int             i;
 422 
 423         BufPoolRelease(ibh);
 424         st->l2.vs = 0;
 425         st->l2.va = 0;
 426         st->l2.vr = 0;
 427         st->l2.sow = 0;
 428         FsmChangeState(fi, ST_L2_7);
 429         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 3))
 430                 if (st->l2.l2m.debug)
 431                         l2m_debug(&st->l2.l2m, "FAT 3");
 432 
 433         st->l2.l2man(st, DL_ESTABLISH, NULL);
 434 
 435         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 10))
 436                 return;
 437         i = sethdraddr(&(st->l2), ibh, 0);
 438         ptr = DATAPTR(ibh);
 439         ptr += i;
 440         *ptr = 0x73;
 441         ibh->datasize = i + 1;
 442         enqueue_super(st, ibh);
 443 
 444 }
 445 
 446 static void
 447 l2s14(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 448 {
 449         struct PStack  *st = fi->userdata;
 450         struct BufHeader *ibh = arg;
 451         struct Channel *chanp = st->l4.userdata;
 452         byte           *ptr;
 453         int             i, p;
 454 
 455         ptr = DATAPTR(ibh);
 456         ptr += l2addrsize(&(st->l2));
 457         p = (*ptr) & 0x10;
 458         BufPoolRelease(ibh);
 459 
 460         FsmChangeState(fi, ST_L2_4);
 461 
 462         FsmDelTimer(&st->l2.t203_timer, 3);
 463         if (st->l2.t200_running) {
 464                 FsmDelTimer(&st->l2.t200_timer, 4);
 465                 st->l2.t200_running = 0;
 466         }
 467         if ((chanp->impair == 1) && (st->l2.laptype == LAPB))
 468                 goto noresponse;
 469 
 470         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 11))
 471                 return;
 472         i = sethdraddr(&(st->l2), ibh, 0);
 473         ptr = DATAPTR(ibh);
 474         ptr += i;
 475         *ptr = 0x63 | (p ? 0x10 : 0x0);
 476         ibh->datasize = i + 1;
 477         enqueue_super(st, ibh);
 478 
 479       noresponse:
 480         st->l2.l2man(st, DL_RELEASE, NULL);
 481 
 482 }
 483 
 484 static void
 485 l2s5(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 486 {
 487         struct PStack  *st = fi->userdata;
 488         struct BufHeader *ibh = arg;
 489         int             f;
 490         byte           *data;
 491 
 492         data = DATAPTR(ibh);
 493         data += l2addrsize(&(st->l2));
 494 
 495         f = *data & 0x10;
 496         BufPoolRelease(ibh);
 497 
 498         if (f) {
 499                 st->l2.vs = 0;
 500                 st->l2.va = 0;
 501                 st->l2.vr = 0;
 502                 st->l2.sow = 0;
 503                 FsmChangeState(fi, ST_L2_7);
 504 
 505                 FsmDelTimer(&st->l2.t200_timer, 5);
 506                 if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 4))
 507                         if (st->l2.l2m.debug)
 508                                 l2m_debug(&st->l2.l2m, "FAT 4");
 509 
 510 
 511                 st->l2.l2man(st, DL_ESTABLISH, NULL);
 512         }
 513 }
 514 
 515 static void
 516 l2s15(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518         struct PStack  *st = fi->userdata;
 519         struct BufHeader *ibh = arg;
 520         int             f;
 521         byte           *data;
 522 
 523         data = DATAPTR(ibh);
 524         data += l2addrsize(&st->l2);
 525 
 526         f = *data & 0x10;
 527         BufPoolRelease(ibh);
 528 
 529         if (f) {
 530                 FsmDelTimer(&st->l2.t200_timer, 6);
 531                 FsmChangeState(fi, ST_L2_4);
 532                 st->l2.l2man(st, DL_RELEASE, NULL);
 533         }
 534 }
 535 
 536 static void
 537 l2s6(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539         struct PStack  *st = fi->userdata;
 540         struct Channel *chanp = st->l4.userdata;
 541         struct BufHeader *ibh = arg;
 542         int             p, i, seq, rsp;
 543         byte           *ptr;
 544         struct Layer2  *l2;
 545 
 546         l2 = &st->l2;
 547         ptr = DATAPTR(ibh);
 548 
 549         if (l2->laptype == LAPD) {
 550                 rsp = ptr[0] & 0x2;
 551                 if (l2->orig)
 552                         rsp = !rsp;
 553         } else {
 554                 rsp = ptr[0] == 0x3;
 555                 if (l2->orig)
 556                         rsp = !rsp;
 557         }
 558 
 559         ptr += l2addrsize(l2);
 560 
 561         if (l2->extended) {
 562                 p = (ptr[1] & 0x1) == 0x1;
 563                 seq = ptr[1] >> 1;
 564         } else {
 565                 p = (ptr[0] & 0x10);
 566                 seq = (ptr[0] >> 5) & 0x7;
 567         }
 568         BufPoolRelease(ibh);
 569 
 570         if ((chanp->impair == 4) && (st->l2.laptype == LAPB))
 571                 goto noresp;
 572 
 573         if ((!rsp) && p) {
 574                 if (!BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 12)) {
 575                         i = sethdraddr(l2, ibh, !0);
 576                         ptr = DATAPTR(ibh);
 577                         ptr += i;
 578 
 579                         if (l2->extended) {
 580                                 *ptr++ = 0x1;
 581                                 *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
 582                                 i += 2;
 583                         } else {
 584                                 *ptr++ = (l2->vr << 5) | 0x1 | (p ? 0x10 : 0x0);
 585                                 i += 1;
 586                         }
 587                         ibh->datasize = i;
 588                         enqueue_super(st, ibh);
 589                 }
 590         }
 591       noresp:
 592         if (legalnr(st, seq))
 593                 if (seq == st->l2.vs) {
 594                         setva(st, seq);
 595                         FsmDelTimer(&st->l2.t200_timer, 7);
 596                         st->l2.t200_running = 0;
 597                         FsmDelTimer(&st->l2.t203_timer, 8);
 598                         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 5))
 599                                 if (st->l2.l2m.debug)
 600                                         l2m_debug(&st->l2.l2m, "FAT 5");
 601 
 602                         if (st->l2.i_queue.head)
 603                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 604                 } else if (st->l2.va != seq) {
 605                         setva(st, seq);
 606                         FsmDelTimer(&st->l2.t200_timer, 9);
 607                         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 6))
 608                                 if (st->l2.l2m.debug)
 609                                         l2m_debug(&st->l2.l2m, "FAT 6");
 610 
 611                         if (st->l2.i_queue.head)
 612                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 613                 }
 614 }
 615 
 616 static void
 617 l2s7(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 618 {
 619         struct PStack  *st = fi->userdata;
 620         struct BufHeader *ibh = arg;
 621         int             i;
 622         byte           *ptr;
 623         struct IsdnCardState *sp = st->l1.hardware;
 624         char            str[64];
 625 
 626         i = sethdraddr(&st->l2, ibh, 0);
 627         ptr = DATAPTR(ibh);
 628 
 629         if (st->l2.laptype == LAPD)
 630                 if (sp->dlogflag) {
 631                         sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
 632                         dlogframe(sp, ptr + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
 633                                   str);
 634                 }
 635         BufQueueLink(&st->l2.i_queue, ibh);
 636 
 637         st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 638 }
 639 
 640 static void
 641 l2s8(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643         struct PStack  *st = fi->userdata;
 644         struct Channel *chanp = st->l4.userdata;
 645         struct BufHeader *ibh = arg;
 646         byte           *ptr;
 647         struct BufHeader *ibh2;
 648         struct IsdnCardState *sp = st->l1.hardware;
 649         struct Layer2  *l2 = &(st->l2);
 650         int             i, p, seq, nr, wasok;
 651         char            str[64];
 652 
 653         ptr = DATAPTR(ibh);
 654         ptr += l2addrsize(l2);
 655         if (l2->extended) {
 656                 p = (ptr[1] & 0x1) == 0x1;
 657                 seq = ptr[0] >> 1;
 658                 nr = (ptr[1] >> 1) & 0x7f;
 659         } else {
 660                 p = (ptr[0] & 0x10);
 661                 seq = (ptr[0] >> 1) & 0x7;
 662                 nr = (ptr[0] >> 5) & 0x7;
 663         }
 664 
 665         if (l2->vr == seq) {
 666                 wasok = !0;
 667 
 668                 l2->vr = (l2->vr + 1) % (l2->extended ? 128 : 8);
 669                 l2->rejexp = 0;
 670 
 671                 ptr = DATAPTR(ibh);
 672                 if (st->l2.laptype == LAPD)
 673                         if (sp->dlogflag) {
 674                                 sprintf(str, "Q.931 frame network->user tei %d", st->l2.tei);
 675                                 dlogframe(st->l1.hardware, ptr + l2->ihsize,
 676                                         ibh->datasize - l2->ihsize, str);
 677                         }
 678               label8_1:
 679                 if ((chanp->impair == 3) && (st->l2.laptype == LAPB))
 680                         goto noRR;
 681 
 682                 if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 13)) {
 683                         i = sethdraddr(&(st->l2), ibh2, p);
 684                         ptr = DATAPTR(ibh2);
 685                         ptr += i;
 686 
 687                         if (l2->extended) {
 688                                 *ptr++ = 0x1;
 689                                 *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
 690                                 i += 2;
 691                         } else {
 692                                 *ptr++ = (l2->vr << 5) | 0x1 | (p ? 0x10 : 0x0);
 693                                 i += 1;
 694                         }
 695                         ibh2->datasize = i;
 696                         enqueue_super(st, ibh2);
 697                       noRR:
 698                 }
 699         } else {
 700                 /* n(s)!=v(r) */
 701                 wasok = 0;
 702                 BufPoolRelease(ibh);
 703                 if (st->l2.rejexp) {
 704                         if (p)
 705                                 goto label8_1;
 706                 } else {
 707                         st->l2.rejexp = !0;
 708                         if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 14)) {
 709                                 i = sethdraddr(&(st->l2), ibh2, p);
 710                                 ptr = DATAPTR(ibh2);
 711                                 ptr += i;
 712 
 713                                 if (l2->extended) {
 714                                         *ptr++ = 0x9;
 715                                         *ptr++ = (l2->vr << 1) | (p ? 1 : 0);
 716                                         i += 2;
 717                                 } else {
 718                                         *ptr++ = (l2->vr << 5) | 0x9 | (p ? 0x10 : 0x0);
 719                                         i += 1;
 720                                 }
 721                                 ibh2->datasize = i;
 722                                 enqueue_super(st, ibh2);
 723                         }
 724                 }
 725         }
 726 
 727         if (legalnr(st, nr))
 728                 if (nr == st->l2.vs) {
 729                         setva(st, nr);
 730                         FsmDelTimer(&st->l2.t200_timer, 10);
 731                         st->l2.t200_running = 0;
 732                         FsmDelTimer(&st->l2.t203_timer, 11);
 733                         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 7))
 734                                 if (st->l2.l2m.debug)
 735                                         l2m_debug(&st->l2.l2m, "FAT 5");
 736 
 737                         if (st->l2.i_queue.head)
 738                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 739                 } else if (nr != st->l2.va) {
 740                         setva(st, nr);
 741                         FsmDelTimer(&st->l2.t200_timer, 12);
 742                         if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 8))
 743                                 if (st->l2.l2m.debug)
 744                                         l2m_debug(&st->l2.l2m, "FAT 6");
 745 
 746                         if (st->l2.i_queue.head)
 747                                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 748                 }
 749         if (wasok)
 750                 st->l2.l2l3(st, DL_DATA, ibh);
 751 
 752 }
 753 
 754 static void
 755 l2s17(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 756 {
 757         struct PStack  *st = fi->userdata;
 758 
 759         st->l2.tei = (int) arg;
 760         establishlink(fi);
 761 }
 762 
 763 static void
 764 enquiry_response(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 765 {
 766         struct BufHeader *ibh2;
 767         int             i;
 768         byte           *ptr;
 769         struct Layer2  *l2;
 770 
 771         l2 = &st->l2;
 772         if (!BufPoolGet(&ibh2, st->l1.smallpool, GFP_ATOMIC, (void *) st, 16)) {
 773                 i = sethdraddr(&(st->l2), ibh2, !0);
 774                 ptr = DATAPTR(ibh2);
 775                 ptr += i;
 776 
 777                 if (l2->extended) {
 778                         *ptr++ = 0x1;
 779                         *ptr++ = (l2->vr << 1) | 0x1;
 780                         i += 2;
 781                 } else {
 782                         *ptr++ = (l2->vr << 5) | 0x1 | 0x10;
 783                         i += 1;
 784                 }
 785                 ibh2->datasize = i;
 786                 enqueue_super(st, ibh2);
 787         }
 788 }
 789 
 790 static void
 791 invoke_retransmission(struct PStack *st, int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 792 {
 793         struct Layer2  *l2 = &st->l2;
 794         int             p1;
 795 
 796         if (l2->vs != nr) {
 797                 while (l2->vs != nr) {
 798 
 799                         l2->vs = l2->vs - 1;
 800                         if (l2->vs < 0)
 801                                 l2->vs += l2->extended ? 128 : 8;
 802 
 803                         p1 = l2->vs - l2->va;
 804                         if (p1 < 0)
 805                                 p1 += l2->extended ? 128 : 8;
 806                         p1 = (p1 + l2->sow) % l2->window;
 807 
 808                         BufQueueLinkFront(&l2->i_queue, l2->windowar[p1]);
 809                 }
 810                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 811         }
 812 }
 813 
 814 static void
 815 l2s16(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 816 {
 817         struct PStack  *st = fi->userdata;
 818         struct BufHeader *ibh = arg;
 819         int             p, seq, rsp;
 820         byte           *ptr;
 821         struct Layer2  *l2;
 822 
 823         l2 = &(st->l2);
 824         ptr = DATAPTR(ibh);
 825 
 826         if (l2->laptype == LAPD) {
 827                 rsp = ptr[0] & 0x2;
 828                 if (l2->orig)
 829                         rsp = !rsp;
 830         } else {
 831                 rsp = ptr[0] == 0x3;
 832                 if (l2->orig)
 833                         rsp = !rsp;
 834         }
 835 
 836 
 837         ptr += l2addrsize(l2);
 838 
 839         if (l2->extended) {
 840                 p = (ptr[1] & 0x1) == 0x1;
 841                 seq = ptr[1] >> 1;
 842         } else {
 843                 p = (ptr[0] & 0x10);
 844                 seq = (ptr[0] >> 5) & 0x7;
 845         }
 846         BufPoolRelease(ibh);
 847 
 848         if ((!rsp) && p)
 849                 enquiry_response(st);
 850 
 851         if (!legalnr(st, seq))
 852                 return;
 853 
 854         setva(st, seq);
 855         invoke_retransmission(st, seq);
 856 
 857 }
 858 
 859 static void
 860 l2s19(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 861 {
 862         FsmChangeState(fi, ST_L2_4);
 863 }
 864 
 865 static void
 866 l2s20(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 867 {
 868         struct PStack  *st = fi->userdata;
 869         int             i;
 870         struct BufHeader *ibh;
 871         byte           *ptr;
 872 
 873         if (st->l2.rc == st->l2.n200) {
 874                 FsmChangeState(fi, ST_L2_4);
 875                 st->l2.l2man(st, DL_RELEASE, NULL);
 876         } else {
 877                 st->l2.rc++;
 878 
 879                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 9))
 880                         if (st->l2.l2m.debug)
 881                                 l2m_debug(&st->l2.l2m, "FAT 7");
 882 
 883                 if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
 884                         return;
 885 
 886                 i = sethdraddr(&st->l2, ibh, 0);
 887                 ptr = DATAPTR(ibh);
 888                 ptr += i;
 889                 if (st->l2.extended)
 890                         *ptr = 0x7f;
 891                 else
 892                         *ptr = 0x3f;
 893                 ibh->datasize = i + 1;
 894                 enqueue_super(st, ibh);
 895         }
 896 }
 897 
 898 static void
 899 l2s21(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 900 {
 901         struct PStack  *st = fi->userdata;
 902         struct Channel *chanp = st->l4.userdata;
 903         int             i;
 904         struct BufHeader *ibh;
 905         byte           *ptr;
 906 
 907         if (st->l2.rc == st->l2.n200) {
 908                 FsmChangeState(fi, ST_L2_4);
 909                 st->l2.l2man(st, DL_RELEASE, NULL);
 910         } else {
 911                 st->l2.rc++;
 912 
 913                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 10))
 914                         if (st->l2.l2m.debug)
 915                                 l2m_debug(&st->l2.l2m, "FAT 8");
 916 
 917 
 918                 if ((chanp->impair == 2) && (st->l2.laptype == LAPB))
 919                         goto nodisc;
 920 
 921                 if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 15))
 922                         return;
 923 
 924                 i = sethdraddr(&st->l2, ibh, 0);
 925                 ptr = DATAPTR(ibh);
 926                 ptr += i;
 927                 *ptr = 0x53;
 928                 ibh->datasize = i + 1;
 929                 enqueue_super(st, ibh);
 930               nodisc:
 931 
 932         }
 933 }
 934 
 935 static void
 936 l2s22(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 937 {
 938         struct PStack  *st = fi->userdata;
 939         struct BufHeader *ibh;
 940         struct Layer2  *l2 = &st->l2;
 941         byte           *ptr;
 942         int             p1;
 943 
 944         if (!cansend(st))
 945                 return;
 946 
 947         if (BufQueueUnlink(&ibh, &l2->i_queue))
 948                 return;
 949 
 950 
 951         p1 = l2->vs - l2->va;
 952         if (p1 < 0)
 953                 p1 += l2->extended ? 128 : 8;
 954         p1 = (p1 + l2->sow) % l2->window;
 955         l2->windowar[p1] = ibh;
 956 
 957         ptr = DATAPTR(ibh);
 958         ptr += l2addrsize(l2);
 959 
 960         if (l2->extended) {
 961                 *ptr++ = l2->vs << 1;
 962                 *ptr++ = (l2->vr << 1) | 0x1;
 963                 l2->vs = (l2->vs + 1) % 128;
 964         } else {
 965                 *ptr++ = (l2->vr << 5) | (l2->vs << 1) | 0x10;
 966                 l2->vs = (l2->vs + 1) % 8;
 967         }
 968 
 969         st->l2.l2l1(st, PH_DATA_PULLED, ibh);
 970 
 971         if (!st->l2.t200_running) {
 972                 FsmDelTimer(&st->l2.t203_timer, 13);
 973                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 11))
 974                         if (st->l2.l2m.debug)
 975                                 l2m_debug(&st->l2.l2m, "FAT 9");
 976 
 977                 st->l2.t200_running = !0;
 978         }
 979         if (l2->i_queue.head && cansend(st))
 980                 st->l2.l2l1(st, PH_REQUEST_PULL, NULL);
 981 
 982 }
 983 
 984 static void
 985 transmit_enquiry(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 986 {
 987         struct BufHeader *ibh;
 988         byte           *ptr;
 989 
 990         if (!BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 12)) {
 991                 ptr = DATAPTR(ibh);
 992                 ptr += sethdraddr(&st->l2, ibh, 0);
 993 
 994                 if (st->l2.extended) {
 995                         *ptr++ = 0x1;
 996                         *ptr++ = (st->l2.vr << 1) | 1;
 997                 } else {
 998                         *ptr++ = (st->l2.vr << 5) | 0x11;
 999                 }
1000                 ibh->datasize = ptr - DATAPTR(ibh);
1001                 enqueue_super(st, ibh);
1002                 if (FsmAddTimer(&st->l2.t200_timer, st->l2.t200, EV_L2_T200, NULL, 12))
1003                         if (st->l2.l2m.debug)
1004                                 l2m_debug(&st->l2.l2m, "FAT 10");
1005 
1006                 st->l2.t200_running = !0;
1007         }
1008 }
1009 
1010 static void
1011 l2s23(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1012 {
1013         struct PStack  *st = fi->userdata;
1014 
1015         st->l2.t200_running = 0;
1016 
1017         st->l2.rc = 1;
1018         FsmChangeState(fi, ST_L2_8);
1019         transmit_enquiry(st);
1020 }
1021 
1022 static void
1023 l2s24(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1024 {
1025         struct PStack  *st = fi->userdata;
1026         struct BufHeader *ibh = arg;
1027         int             p, seq, rsp;
1028         byte           *ptr;
1029         struct Layer2  *l2;
1030 
1031         l2 = &st->l2;
1032         ptr = DATAPTR(ibh);
1033 
1034         if (l2->laptype == LAPD) {
1035                 rsp = ptr[0] & 0x2;
1036                 if (l2->orig)
1037                         rsp = !rsp;
1038         } else {
1039                 rsp = ptr[0] == 0x3;
1040                 if (l2->orig)
1041                         rsp = !rsp;
1042         }
1043 
1044 
1045         ptr += l2addrsize(l2);
1046 
1047         if (l2->extended) {
1048                 p = (ptr[1] & 0x1) == 0x1;
1049                 seq = ptr[1] >> 1;
1050         } else {
1051                 p = (ptr[0] & 0x10);
1052                 seq = (ptr[0] >> 5) & 0x7;
1053         }
1054         BufPoolRelease(ibh);
1055 
1056         if (rsp && p) {
1057                 if (legalnr(st, seq)) {
1058                         FsmChangeState(fi, ST_L2_7);
1059                         setva(st, seq);
1060                         if (st->l2.t200_running) {
1061                                 FsmDelTimer(&st->l2.t200_timer, 14);
1062                                 st->l2.t200_running = 0;
1063                         }
1064                         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 13))
1065                                 if (st->l2.l2m.debug)
1066                                         l2m_debug(&st->l2.l2m, "FAT 11");
1067 
1068                         invoke_retransmission(st, seq);
1069                 }
1070         } else {
1071                 if (!rsp && p)
1072                         enquiry_response(st);
1073                 if (legalnr(st, seq)) {
1074                         setva(st, seq);
1075                 }
1076         }
1077 }
1078 
1079 static void
1080 l2s25(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1081 {
1082         struct PStack  *st = fi->userdata;
1083 
1084         st->l2.rc = 0;
1085         FsmChangeState(fi, ST_L2_8);
1086         transmit_enquiry(st);
1087 }
1088 
1089 static void
1090 l2s26(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1091 {
1092         struct PStack  *st = fi->userdata;
1093 
1094         if (st->l2.rc == st->l2.n200) {
1095                 l2s13(fi, event, NULL);
1096         } else {
1097                 st->l2.rc++;
1098                 transmit_enquiry(st);
1099         }
1100 }
1101 
1102 static void
1103 l2s27(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1104 {
1105         struct PStack  *st = fi->userdata;
1106         struct BufHeader *ibh = arg;
1107         byte           *ptr;
1108         int             i, p, est;
1109 
1110         ptr = DATAPTR(ibh);
1111         ptr += l2addrsize(&st->l2);
1112 
1113         if (st->l2.extended)
1114                 p = ptr[1] & 0x1;
1115         else
1116                 p = ptr[0] & 0x10;
1117 
1118         BufPoolRelease(ibh);
1119 
1120         if (BufPoolGet(&ibh, st->l1.smallpool, GFP_ATOMIC, (void *) st, 10))
1121                 return;
1122         i = sethdraddr(&st->l2, ibh, 0);
1123         ptr = DATAPTR(ibh);
1124         ptr += i;
1125         *ptr = 0x63 | p;
1126         ibh->datasize = i + 1;
1127         enqueue_super(st, ibh);
1128 
1129         if (st->l2.vs != st->l2.va) {
1130                 discard_i_queue(st);
1131                 est = !0;
1132         } else
1133                 est = 0;
1134 
1135         FsmDelTimer(&st->l2.t200_timer, 15);
1136         st->l2.t200_running = 0;
1137 
1138         if (FsmAddTimer(&st->l2.t203_timer, st->l2.t203, EV_L2_T203, NULL, 3))
1139                 if (st->l2.l2m.debug)
1140                         l2m_debug(&st->l2.l2m, "FAT 12");
1141 
1142         st->l2.vs = 0;
1143         st->l2.va = 0;
1144         st->l2.vr = 0;
1145         st->l2.sow = 0;
1146 
1147 
1148         if (est)
1149                 st->l2.l2man(st, DL_ESTABLISH, NULL);
1150 
1151 }
1152 
1153 static void
1154 l2s28(struct FsmInst *fi, int event, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1155 {
1156         struct PStack  *st = fi->userdata;
1157         struct BufHeader *ibh = arg;
1158         byte           *ptr;
1159         char            tmp[64];
1160 
1161         ptr = DATAPTR(ibh);
1162         ptr += l2addrsize(&st->l2);
1163         ptr++;
1164 
1165         if (st->l2.l2m.debug) {
1166                 if (st->l2.extended)
1167                         sprintf(tmp, "FRMR information %2x %2x %2x %2x %2x",
1168                                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4]);
1169                 else
1170                         sprintf(tmp, "FRMR information %2x %2x %2x",
1171                                 ptr[0], ptr[1], ptr[2]);
1172 
1173                 l2m_debug(&st->l2.l2m, tmp);
1174         }
1175         BufPoolRelease(ibh);
1176 }
1177 
1178 static int
1179 IsUI(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1180 {
1181         return ((data[0] & 0xef) == 0x3);
1182 }
1183 
1184 static int
1185 IsUA(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1186 {
1187         return ((data[0] & 0xef) == 0x63);
1188 }
1189 
1190 static int
1191 IsDISC(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1192 {
1193         return ((data[0] & 0xef) == 0x43);
1194 }
1195 
1196 static int
1197 IsRR(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1198 {
1199         if (ext)
1200                 return (data[0] == 0x1);
1201         else
1202                 return ((data[0] & 0xf) == 1);
1203 }
1204 
1205 static int
1206 IsI(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1207 {
1208         return ((data[0] & 0x1) == 0x0);
1209 }
1210 
1211 static int
1212 IsSABMX(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1213 {
1214         return (ext ? data[0] == 0x7f : data[0] == 0x3f);
1215 }
1216 
1217 static int
1218 IsREJ(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1219 {
1220         return (ext ? data[0] == 0x9 : (data[0] & 0xf) == 0x9);
1221 }
1222 
1223 static int
1224 IsFRMR(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1225 {
1226         return ((data[0] & 0xef) == 0x87);
1227 }
1228 
1229 static int
1230 IsRNR(byte * data, int ext)
     /* [previous][next][first][last][top][bottom][index][help] */
1231 {
1232         if (ext)
1233                 return (data[0] == 0x5);
1234         else
1235                 return ((data[0] & 0xf) == 5);
1236 }
1237 
1238 static struct FsmNode L2FnList[] =
1239 {
1240         {ST_L2_1, EV_L2_DL_ESTABLISH, l2s1},
1241         {ST_L2_1, EV_L2_MDL_NOTEIPROC, l2s19},
1242         {ST_L2_3, EV_L2_MDL_ASSIGN, l2s17},
1243         {ST_L2_4, EV_L2_DL_UNIT_DATA, l2s2},
1244         {ST_L2_4, EV_L2_DL_ESTABLISH, l2s11},
1245         {ST_L2_7, EV_L2_DL_UNIT_DATA, l2s2},
1246         {ST_L2_7, EV_L2_DL_DATA, l2s7},
1247         {ST_L2_7, EV_L2_DL_RELEASE, l2s13},
1248         {ST_L2_7, EV_L2_ACK_PULL, l2s22},
1249         {ST_L2_8, EV_L2_DL_RELEASE, l2s13},
1250 
1251         {ST_L2_1, EV_L2_UI, l2s3},
1252         {ST_L2_4, EV_L2_UI, l2s3},
1253         {ST_L2_4, EV_L2_SABMX, l2s12},
1254         {ST_L2_5, EV_L2_UA, l2s5},
1255         {ST_L2_6, EV_L2_UA, l2s15},
1256         {ST_L2_7, EV_L2_UI, l2s3},
1257         {ST_L2_7, EV_L2_DISC, l2s14},
1258         {ST_L2_7, EV_L2_I, l2s8},
1259         {ST_L2_7, EV_L2_RR, l2s6},
1260         {ST_L2_7, EV_L2_REJ, l2s16},
1261         {ST_L2_7, EV_L2_SABMX, l2s27},
1262         {ST_L2_7, EV_L2_FRMR, l2s28},
1263         {ST_L2_8, EV_L2_RR, l2s24},
1264         {ST_L2_8, EV_L2_DISC, l2s14},
1265         {ST_L2_8, EV_L2_FRMR, l2s28},
1266 
1267         {ST_L2_5, EV_L2_T200, l2s20},
1268         {ST_L2_6, EV_L2_T200, l2s21},
1269         {ST_L2_7, EV_L2_T200, l2s23},
1270         {ST_L2_7, EV_L2_T203, l2s25},
1271         {ST_L2_8, EV_L2_T200, l2s26},
1272 };
1273 
1274 #define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
1275 
1276 static void
1277 isdnl2_l1l2(struct PStack *st, int pr, struct BufHeader *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1278 {
1279         struct BufHeader *ibh;
1280         byte           *datap;
1281         int             ret = !0;
1282 
1283         switch (pr) {
1284           case (PH_DATA):
1285 
1286                   ibh = arg;
1287                   datap = DATAPTR(ibh);
1288                   datap += l2addrsize(&st->l2);
1289 
1290                   if (IsI(datap, st->l2.extended))
1291                           ret = FsmEvent(&st->l2.l2m, EV_L2_I, ibh);
1292                   else if (IsRR(datap, st->l2.extended))
1293                           ret = FsmEvent(&st->l2.l2m, EV_L2_RR, ibh);
1294                   else if (IsUI(datap, st->l2.extended))
1295                           ret = FsmEvent(&st->l2.l2m, EV_L2_UI, ibh);
1296                   else if (IsSABMX(datap, st->l2.extended))
1297                           ret = FsmEvent(&st->l2.l2m, EV_L2_SABMX, ibh);
1298                   else if (IsUA(datap, st->l2.extended))
1299                           ret = FsmEvent(&st->l2.l2m, EV_L2_UA, ibh);
1300                   else if (IsDISC(datap, st->l2.extended))
1301                           ret = FsmEvent(&st->l2.l2m, EV_L2_DISC, ibh);
1302                   else if (IsREJ(datap, st->l2.extended))
1303                           ret = FsmEvent(&st->l2.l2m, EV_L2_REJ, ibh);
1304                   else if (IsFRMR(datap, st->l2.extended))
1305                           ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, ibh);
1306                   else if (IsRNR(datap, st->l2.extended))
1307                           ret = FsmEvent(&st->l2.l2m, EV_L2_RNR, ibh);
1308 
1309                   if (ret)
1310                           BufPoolRelease(ibh);
1311 
1312                   break;
1313           case (PH_PULL_ACK):
1314                   FsmEvent(&st->l2.l2m, EV_L2_ACK_PULL, arg);
1315                   break;
1316         }
1317 }
1318 
1319 static void
1320 isdnl2_l3l2(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1321             void *arg)
1322 {
1323         switch (pr) {
1324           case (DL_DATA):
1325                   if (FsmEvent(&st->l2.l2m, EV_L2_DL_DATA, arg))
1326                           BufPoolRelease((struct BufHeader *) arg);
1327                   break;
1328           case (DL_UNIT_DATA):
1329                   if (FsmEvent(&st->l2.l2m, EV_L2_DL_UNIT_DATA, arg))
1330                           BufPoolRelease((struct BufHeader *) arg);
1331                   break;
1332         }
1333 }
1334 
1335 static void
1336 isdnl2_manl2(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1337              void *arg)
1338 {
1339         switch (pr) {
1340           case (DL_ESTABLISH):
1341                   FsmEvent(&st->l2.l2m, EV_L2_DL_ESTABLISH, arg);
1342                   break;
1343           case (DL_RELEASE):
1344                   FsmEvent(&st->l2.l2m, EV_L2_DL_RELEASE, arg);
1345                   break;
1346           case (MDL_NOTEIPROC):
1347                   FsmEvent(&st->l2.l2m, EV_L2_MDL_NOTEIPROC, NULL);
1348                   break;
1349         }
1350 }
1351 
1352 static void
1353 isdnl2_teil2(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1354              void *arg)
1355 {
1356         switch (pr) {
1357           case (MDL_ASSIGN):
1358                   FsmEvent(&st->l2.l2m, EV_L2_MDL_ASSIGN, arg);
1359                   break;
1360         }
1361 }
1362 
1363 void
1364 releasestack_isdnl2(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1365 {
1366         FsmDelTimer(&st->l2.t200_timer, 15);
1367         FsmDelTimer(&st->l2.t203_timer, 16);
1368 }
1369 
1370 static void
1371 l2m_debug(struct FsmInst *fi, char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
1372 {
1373         struct PStack  *st = fi->userdata;
1374         char            tm[32], str[256];
1375 
1376         jiftime(tm, jiffies);
1377         sprintf(str, "%s %s %s\n", tm, st->l2.debug_id, s);
1378         teles_putstatus(str);
1379 }
1380 
1381 
1382 void
1383 setstack_isdnl2(struct PStack *st, char *debug_id)
     /* [previous][next][first][last][top][bottom][index][help] */
1384 {
1385         st->l1.l1l2 = isdnl2_l1l2;
1386         st->l3.l3l2 = isdnl2_l3l2;
1387         st->ma.manl2 = isdnl2_manl2;
1388         st->ma.teil2 = isdnl2_teil2;
1389 
1390         st->l2.uihsize = l2headersize(&st->l2, !0);
1391         st->l2.ihsize = l2headersize(&st->l2, 0);
1392         BufQueueInit(&(st->l2.i_queue));
1393         st->l2.rejexp = 0;
1394         st->l2.debug = 1;
1395 
1396         st->l2.l2m.fsm = &l2fsm;
1397         st->l2.l2m.state = ST_L2_1;
1398         st->l2.l2m.debug = 0;
1399         st->l2.l2m.userdata = st;
1400         st->l2.l2m.printdebug = l2m_debug;
1401         strcpy(st->l2.debug_id, debug_id);
1402 
1403         FsmInitTimer(&st->l2.l2m, &st->l2.t200_timer);
1404         FsmInitTimer(&st->l2.l2m, &st->l2.t203_timer);
1405         st->l2.t200_running = 0;
1406 }
1407 
1408 #ifdef DEFINED_BUT_NOT_USED
1409 static void
1410 trans_acceptph(struct PStack *st, struct BufHeader *ibh)
     /* [previous][next][first][last][top][bottom][index][help] */
1411 {
1412 #if 0
1413         st->l3.service_up(st, DL_DATA, ibh);
1414 #endif
1415 }
1416 
1417 
1418 static void
1419 transdown(struct PStack *st, int pr,
     /* [previous][next][first][last][top][bottom][index][help] */
1420           struct BufHeader *ibh)
1421 {
1422         if (pr == DL_DATA) {
1423                 ibh->primitive = !0;
1424                 st->l2.l2l1(st, PH_DATA, ibh);
1425         }
1426 }
1427 #endif
1428 
1429 void
1430 setstack_transl2(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1431 {
1432 #if 0
1433         st->l2.phdata_up = trans_acceptph;
1434         st->l2.service_down = (void *) transdown;
1435         st->l2.ihsize = 0;
1436         st->l2.debug = 0;
1437 #endif
1438 }
1439 
1440 void
1441 releasestack_transl2(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
1442 {
1443 }
1444 
1445 void
1446 Isdnl2New(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1447 {
1448         l2fsm.state_count = L2_STATE_COUNT;
1449         l2fsm.event_count = L2_EVENT_COUNT;
1450         l2fsm.strEvent = strL2Event;
1451         l2fsm.strState = strL2State;
1452         FsmNew(&l2fsm, L2FnList, L2_FN_COUNT);
1453 }
1454 
1455 void
1456 Isdnl2Free(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1457 {
1458         FsmFree(&l2fsm);
1459 }

/* [previous][next][first][last][top][bottom][index][help] */