isdnl3.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. /* $Id: isdnl3.c,v 2.22.2.3 2004/01/13 14:31:25 keil Exp $
  2. *
  3. * Author Karsten Keil
  4. * based on the teles driver from Jan den Ouden
  5. * Copyright by Karsten Keil <keil@isdn4linux.de>
  6. *
  7. * This software may be used and distributed according to the terms
  8. * of the GNU General Public License, incorporated herein by reference.
  9. *
  10. * For changes and modifications please read
  11. * Documentation/isdn/HiSax.cert
  12. *
  13. * Thanks to Jan den Ouden
  14. * Fritz Elfert
  15. *
  16. */
  17. #include <linux/init.h>
  18. #include "hisax.h"
  19. #include "isdnl3.h"
  20. const char *l3_revision = "$Revision: 2.22.2.3 $";
  21. static struct Fsm l3fsm;
  22. enum {
  23. ST_L3_LC_REL,
  24. ST_L3_LC_ESTAB_WAIT,
  25. ST_L3_LC_REL_DELAY,
  26. ST_L3_LC_REL_WAIT,
  27. ST_L3_LC_ESTAB,
  28. };
  29. #define L3_STATE_COUNT (ST_L3_LC_ESTAB+1)
  30. static char *strL3State[] =
  31. {
  32. "ST_L3_LC_REL",
  33. "ST_L3_LC_ESTAB_WAIT",
  34. "ST_L3_LC_REL_DELAY",
  35. "ST_L3_LC_REL_WAIT",
  36. "ST_L3_LC_ESTAB",
  37. };
  38. enum {
  39. EV_ESTABLISH_REQ,
  40. EV_ESTABLISH_IND,
  41. EV_ESTABLISH_CNF,
  42. EV_RELEASE_REQ,
  43. EV_RELEASE_CNF,
  44. EV_RELEASE_IND,
  45. EV_TIMEOUT,
  46. };
  47. #define L3_EVENT_COUNT (EV_TIMEOUT+1)
  48. static char *strL3Event[] =
  49. {
  50. "EV_ESTABLISH_REQ",
  51. "EV_ESTABLISH_IND",
  52. "EV_ESTABLISH_CNF",
  53. "EV_RELEASE_REQ",
  54. "EV_RELEASE_CNF",
  55. "EV_RELEASE_IND",
  56. "EV_TIMEOUT",
  57. };
  58. static void
  59. l3m_debug(struct FsmInst *fi, char *fmt, ...)
  60. {
  61. va_list args;
  62. struct PStack *st = fi->userdata;
  63. va_start(args, fmt);
  64. VHiSax_putstatus(st->l1.hardware, st->l3.debug_id, fmt, args);
  65. va_end(args);
  66. }
  67. u_char *
  68. findie(u_char * p, int size, u_char ie, int wanted_set)
  69. {
  70. int l, codeset, maincodeset;
  71. u_char *pend = p + size;
  72. /* skip protocol discriminator, callref and message type */
  73. p++;
  74. l = (*p++) & 0xf;
  75. p += l;
  76. p++;
  77. codeset = 0;
  78. maincodeset = 0;
  79. /* while there are bytes left... */
  80. while (p < pend) {
  81. if ((*p & 0xf0) == 0x90) {
  82. codeset = *p & 0x07;
  83. if (!(*p & 0x08))
  84. maincodeset = codeset;
  85. }
  86. if (*p & 0x80)
  87. p++;
  88. else {
  89. if (codeset == wanted_set) {
  90. if (*p == ie)
  91. { /* improved length check (Werner Cornelius) */
  92. if ((pend - p) < 2)
  93. return(NULL);
  94. if (*(p+1) > (pend - (p+2)))
  95. return(NULL);
  96. return (p);
  97. }
  98. if (*p > ie)
  99. return (NULL);
  100. }
  101. p++;
  102. l = *p++;
  103. p += l;
  104. codeset = maincodeset;
  105. }
  106. }
  107. return (NULL);
  108. }
  109. int
  110. getcallref(u_char * p)
  111. {
  112. int l, cr = 0;
  113. p++; /* prot discr */
  114. if (*p & 0xfe) /* wrong callref BRI only 1 octet*/
  115. return(-2);
  116. l = 0xf & *p++; /* callref length */
  117. if (!l) /* dummy CallRef */
  118. return(-1);
  119. cr = *p++;
  120. return (cr);
  121. }
  122. static int OrigCallRef = 0;
  123. int
  124. newcallref(void)
  125. {
  126. if (OrigCallRef == 127)
  127. OrigCallRef = 1;
  128. else
  129. OrigCallRef++;
  130. return (OrigCallRef);
  131. }
  132. void
  133. newl3state(struct l3_process *pc, int state)
  134. {
  135. if (pc->debug & L3_DEB_STATE)
  136. l3_debug(pc->st, "newstate cr %d %d --> %d",
  137. pc->callref & 0x7F,
  138. pc->state, state);
  139. pc->state = state;
  140. }
  141. static void
  142. L3ExpireTimer(struct L3Timer *t)
  143. {
  144. t->pc->st->lli.l4l3(t->pc->st, t->event, t->pc);
  145. }
  146. void
  147. L3InitTimer(struct l3_process *pc, struct L3Timer *t)
  148. {
  149. t->pc = pc;
  150. t->tl.function = (void *) L3ExpireTimer;
  151. t->tl.data = (long) t;
  152. init_timer(&t->tl);
  153. }
  154. void
  155. L3DelTimer(struct L3Timer *t)
  156. {
  157. del_timer(&t->tl);
  158. }
  159. int
  160. L3AddTimer(struct L3Timer *t,
  161. int millisec, int event)
  162. {
  163. if (timer_pending(&t->tl)) {
  164. printk(KERN_WARNING "L3AddTimer: timer already active!\n");
  165. return -1;
  166. }
  167. init_timer(&t->tl);
  168. t->event = event;
  169. t->tl.expires = jiffies + (millisec * HZ) / 1000;
  170. add_timer(&t->tl);
  171. return 0;
  172. }
  173. void
  174. StopAllL3Timer(struct l3_process *pc)
  175. {
  176. L3DelTimer(&pc->timer);
  177. }
  178. struct sk_buff *
  179. l3_alloc_skb(int len)
  180. {
  181. struct sk_buff *skb;
  182. if (!(skb = alloc_skb(len + MAX_HEADER_LEN, GFP_ATOMIC))) {
  183. printk(KERN_WARNING "HiSax: No skb for D-channel\n");
  184. return (NULL);
  185. }
  186. skb_reserve(skb, MAX_HEADER_LEN);
  187. return (skb);
  188. }
  189. static void
  190. no_l3_proto(struct PStack *st, int pr, void *arg)
  191. {
  192. struct sk_buff *skb = arg;
  193. HiSax_putstatus(st->l1.hardware, "L3", "no D protocol");
  194. if (skb) {
  195. dev_kfree_skb(skb);
  196. }
  197. }
  198. static int
  199. no_l3_proto_spec(struct PStack *st, isdn_ctrl *ic)
  200. {
  201. printk(KERN_WARNING "HiSax: no specific protocol handler for proto %lu\n",ic->arg & 0xFF);
  202. return(-1);
  203. }
  204. #ifdef CONFIG_HISAX_EURO
  205. extern void setstack_dss1(struct PStack *st);
  206. #endif
  207. #ifdef CONFIG_HISAX_NI1
  208. extern void setstack_ni1(struct PStack *st);
  209. #endif
  210. #ifdef CONFIG_HISAX_1TR6
  211. extern void setstack_1tr6(struct PStack *st);
  212. #endif
  213. struct l3_process
  214. *getl3proc(struct PStack *st, int cr)
  215. {
  216. struct l3_process *p = st->l3.proc;
  217. while (p)
  218. if (p->callref == cr)
  219. return (p);
  220. else
  221. p = p->next;
  222. return (NULL);
  223. }
  224. struct l3_process
  225. *new_l3_process(struct PStack *st, int cr)
  226. {
  227. struct l3_process *p, *np;
  228. if (!(p = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
  229. printk(KERN_ERR "HiSax can't get memory for cr %d\n", cr);
  230. return (NULL);
  231. }
  232. if (!st->l3.proc)
  233. st->l3.proc = p;
  234. else {
  235. np = st->l3.proc;
  236. while (np->next)
  237. np = np->next;
  238. np->next = p;
  239. }
  240. p->next = NULL;
  241. p->debug = st->l3.debug;
  242. p->callref = cr;
  243. p->state = 0;
  244. p->chan = NULL;
  245. p->st = st;
  246. p->N303 = st->l3.N303;
  247. L3InitTimer(p, &p->timer);
  248. return (p);
  249. };
  250. void
  251. release_l3_process(struct l3_process *p)
  252. {
  253. struct l3_process *np, *pp = NULL;
  254. if (!p)
  255. return;
  256. np = p->st->l3.proc;
  257. while (np) {
  258. if (np == p) {
  259. StopAllL3Timer(p);
  260. if (pp)
  261. pp->next = np->next;
  262. else if (!(p->st->l3.proc = np->next) &&
  263. !test_bit(FLG_PTP, &p->st->l2.flag)) {
  264. if (p->debug)
  265. l3_debug(p->st, "release_l3_process: last process");
  266. if (skb_queue_empty(&p->st->l3.squeue)) {
  267. if (p->debug)
  268. l3_debug(p->st, "release_l3_process: release link");
  269. if (p->st->protocol != ISDN_PTYPE_NI1)
  270. FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL);
  271. else
  272. FsmEvent(&p->st->l3.l3m, EV_RELEASE_IND, NULL);
  273. } else {
  274. if (p->debug)
  275. l3_debug(p->st, "release_l3_process: not release link");
  276. }
  277. }
  278. kfree(p);
  279. return;
  280. }
  281. pp = np;
  282. np = np->next;
  283. }
  284. printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref);
  285. l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref);
  286. };
  287. static void
  288. l3ml3p(struct PStack *st, int pr)
  289. {
  290. struct l3_process *p = st->l3.proc;
  291. struct l3_process *np;
  292. while (p) {
  293. /* p might be kfreed under us, so we need to save where we want to go on */
  294. np = p->next;
  295. st->l3.l3ml3(st, pr, p);
  296. p = np;
  297. }
  298. }
  299. void
  300. setstack_l3dc(struct PStack *st, struct Channel *chanp)
  301. {
  302. char tmp[64];
  303. st->l3.proc = NULL;
  304. st->l3.global = NULL;
  305. skb_queue_head_init(&st->l3.squeue);
  306. st->l3.l3m.fsm = &l3fsm;
  307. st->l3.l3m.state = ST_L3_LC_REL;
  308. st->l3.l3m.debug = 1;
  309. st->l3.l3m.userdata = st;
  310. st->l3.l3m.userint = 0;
  311. st->l3.l3m.printdebug = l3m_debug;
  312. FsmInitTimer(&st->l3.l3m, &st->l3.l3m_timer);
  313. strcpy(st->l3.debug_id, "L3DC ");
  314. st->lli.l4l3_proto = no_l3_proto_spec;
  315. #ifdef CONFIG_HISAX_EURO
  316. if (st->protocol == ISDN_PTYPE_EURO) {
  317. setstack_dss1(st);
  318. } else
  319. #endif
  320. #ifdef CONFIG_HISAX_NI1
  321. if (st->protocol == ISDN_PTYPE_NI1) {
  322. setstack_ni1(st);
  323. } else
  324. #endif
  325. #ifdef CONFIG_HISAX_1TR6
  326. if (st->protocol == ISDN_PTYPE_1TR6) {
  327. setstack_1tr6(st);
  328. } else
  329. #endif
  330. if (st->protocol == ISDN_PTYPE_LEASED) {
  331. st->lli.l4l3 = no_l3_proto;
  332. st->l2.l2l3 = no_l3_proto;
  333. st->l3.l3ml3 = no_l3_proto;
  334. printk(KERN_INFO "HiSax: Leased line mode\n");
  335. } else {
  336. st->lli.l4l3 = no_l3_proto;
  337. st->l2.l2l3 = no_l3_proto;
  338. st->l3.l3ml3 = no_l3_proto;
  339. sprintf(tmp, "protocol %s not supported",
  340. (st->protocol == ISDN_PTYPE_1TR6) ? "1tr6" :
  341. (st->protocol == ISDN_PTYPE_EURO) ? "euro" :
  342. (st->protocol == ISDN_PTYPE_NI1) ? "ni1" :
  343. "unknown");
  344. printk(KERN_WARNING "HiSax: %s\n", tmp);
  345. st->protocol = -1;
  346. }
  347. }
  348. static void
  349. isdnl3_trans(struct PStack *st, int pr, void *arg) {
  350. st->l3.l3l2(st, pr, arg);
  351. }
  352. void
  353. releasestack_isdnl3(struct PStack *st)
  354. {
  355. while (st->l3.proc)
  356. release_l3_process(st->l3.proc);
  357. if (st->l3.global) {
  358. StopAllL3Timer(st->l3.global);
  359. kfree(st->l3.global);
  360. st->l3.global = NULL;
  361. }
  362. FsmDelTimer(&st->l3.l3m_timer, 54);
  363. skb_queue_purge(&st->l3.squeue);
  364. }
  365. void
  366. setstack_l3bc(struct PStack *st, struct Channel *chanp)
  367. {
  368. st->l3.proc = NULL;
  369. st->l3.global = NULL;
  370. skb_queue_head_init(&st->l3.squeue);
  371. st->l3.l3m.fsm = &l3fsm;
  372. st->l3.l3m.state = ST_L3_LC_REL;
  373. st->l3.l3m.debug = 1;
  374. st->l3.l3m.userdata = st;
  375. st->l3.l3m.userint = 0;
  376. st->l3.l3m.printdebug = l3m_debug;
  377. strcpy(st->l3.debug_id, "L3BC ");
  378. st->lli.l4l3 = isdnl3_trans;
  379. }
  380. #define DREL_TIMER_VALUE 40000
  381. static void
  382. lc_activate(struct FsmInst *fi, int event, void *arg)
  383. {
  384. struct PStack *st = fi->userdata;
  385. FsmChangeState(fi, ST_L3_LC_ESTAB_WAIT);
  386. st->l3.l3l2(st, DL_ESTABLISH | REQUEST, NULL);
  387. }
  388. static void
  389. lc_connect(struct FsmInst *fi, int event, void *arg)
  390. {
  391. struct PStack *st = fi->userdata;
  392. struct sk_buff *skb = arg;
  393. int dequeued = 0;
  394. FsmChangeState(fi, ST_L3_LC_ESTAB);
  395. while ((skb = skb_dequeue(&st->l3.squeue))) {
  396. st->l3.l3l2(st, DL_DATA | REQUEST, skb);
  397. dequeued++;
  398. }
  399. if ((!st->l3.proc) && dequeued) {
  400. if (st->l3.debug)
  401. l3_debug(st, "lc_connect: release link");
  402. FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL);
  403. } else
  404. l3ml3p(st, DL_ESTABLISH | INDICATION);
  405. }
  406. static void
  407. lc_connected(struct FsmInst *fi, int event, void *arg)
  408. {
  409. struct PStack *st = fi->userdata;
  410. struct sk_buff *skb = arg;
  411. int dequeued = 0;
  412. FsmDelTimer(&st->l3.l3m_timer, 51);
  413. FsmChangeState(fi, ST_L3_LC_ESTAB);
  414. while ((skb = skb_dequeue(&st->l3.squeue))) {
  415. st->l3.l3l2(st, DL_DATA | REQUEST, skb);
  416. dequeued++;
  417. }
  418. if ((!st->l3.proc) && dequeued) {
  419. if (st->l3.debug)
  420. l3_debug(st, "lc_connected: release link");
  421. FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL);
  422. } else
  423. l3ml3p(st, DL_ESTABLISH | CONFIRM);
  424. }
  425. static void
  426. lc_start_delay(struct FsmInst *fi, int event, void *arg)
  427. {
  428. struct PStack *st = fi->userdata;
  429. FsmChangeState(fi, ST_L3_LC_REL_DELAY);
  430. FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
  431. }
  432. static void
  433. lc_start_delay_check(struct FsmInst *fi, int event, void *arg)
  434. /* 20/09/00 - GE timer not user for NI-1 as layer 2 should stay up */
  435. {
  436. struct PStack *st = fi->userdata;
  437. FsmChangeState(fi, ST_L3_LC_REL_DELAY);
  438. /* 19/09/00 - GE timer not user for NI-1 */
  439. if (st->protocol != ISDN_PTYPE_NI1)
  440. FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
  441. }
  442. static void
  443. lc_release_req(struct FsmInst *fi, int event, void *arg)
  444. {
  445. struct PStack *st = fi->userdata;
  446. if (test_bit(FLG_L2BLOCK, &st->l2.flag)) {
  447. if (st->l3.debug)
  448. l3_debug(st, "lc_release_req: l2 blocked");
  449. /* restart release timer */
  450. FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 51);
  451. } else {
  452. FsmChangeState(fi, ST_L3_LC_REL_WAIT);
  453. st->l3.l3l2(st, DL_RELEASE | REQUEST, NULL);
  454. }
  455. }
  456. static void
  457. lc_release_ind(struct FsmInst *fi, int event, void *arg)
  458. {
  459. struct PStack *st = fi->userdata;
  460. FsmDelTimer(&st->l3.l3m_timer, 52);
  461. FsmChangeState(fi, ST_L3_LC_REL);
  462. skb_queue_purge(&st->l3.squeue);
  463. l3ml3p(st, DL_RELEASE | INDICATION);
  464. }
  465. static void
  466. lc_release_cnf(struct FsmInst *fi, int event, void *arg)
  467. {
  468. struct PStack *st = fi->userdata;
  469. FsmChangeState(fi, ST_L3_LC_REL);
  470. skb_queue_purge(&st->l3.squeue);
  471. l3ml3p(st, DL_RELEASE | CONFIRM);
  472. }
  473. /* *INDENT-OFF* */
  474. static struct FsmNode L3FnList[] __initdata =
  475. {
  476. {ST_L3_LC_REL, EV_ESTABLISH_REQ, lc_activate},
  477. {ST_L3_LC_REL, EV_ESTABLISH_IND, lc_connect},
  478. {ST_L3_LC_REL, EV_ESTABLISH_CNF, lc_connect},
  479. {ST_L3_LC_ESTAB_WAIT, EV_ESTABLISH_CNF, lc_connected},
  480. {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_REQ, lc_start_delay},
  481. {ST_L3_LC_ESTAB_WAIT, EV_RELEASE_IND, lc_release_ind},
  482. {ST_L3_LC_ESTAB, EV_RELEASE_IND, lc_release_ind},
  483. {ST_L3_LC_ESTAB, EV_RELEASE_REQ, lc_start_delay_check},
  484. {ST_L3_LC_REL_DELAY, EV_RELEASE_IND, lc_release_ind},
  485. {ST_L3_LC_REL_DELAY, EV_ESTABLISH_REQ, lc_connected},
  486. {ST_L3_LC_REL_DELAY, EV_TIMEOUT, lc_release_req},
  487. {ST_L3_LC_REL_WAIT, EV_RELEASE_CNF, lc_release_cnf},
  488. {ST_L3_LC_REL_WAIT, EV_ESTABLISH_REQ, lc_activate},
  489. };
  490. /* *INDENT-ON* */
  491. #define L3_FN_COUNT (sizeof(L3FnList)/sizeof(struct FsmNode))
  492. void
  493. l3_msg(struct PStack *st, int pr, void *arg)
  494. {
  495. switch (pr) {
  496. case (DL_DATA | REQUEST):
  497. if (st->l3.l3m.state == ST_L3_LC_ESTAB) {
  498. st->l3.l3l2(st, pr, arg);
  499. } else {
  500. struct sk_buff *skb = arg;
  501. skb_queue_tail(&st->l3.squeue, skb);
  502. FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL);
  503. }
  504. break;
  505. case (DL_ESTABLISH | REQUEST):
  506. FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL);
  507. break;
  508. case (DL_ESTABLISH | CONFIRM):
  509. FsmEvent(&st->l3.l3m, EV_ESTABLISH_CNF, NULL);
  510. break;
  511. case (DL_ESTABLISH | INDICATION):
  512. FsmEvent(&st->l3.l3m, EV_ESTABLISH_IND, NULL);
  513. break;
  514. case (DL_RELEASE | INDICATION):
  515. FsmEvent(&st->l3.l3m, EV_RELEASE_IND, NULL);
  516. break;
  517. case (DL_RELEASE | CONFIRM):
  518. FsmEvent(&st->l3.l3m, EV_RELEASE_CNF, NULL);
  519. break;
  520. case (DL_RELEASE | REQUEST):
  521. FsmEvent(&st->l3.l3m, EV_RELEASE_REQ, NULL);
  522. break;
  523. }
  524. }
  525. int __init
  526. Isdnl3New(void)
  527. {
  528. l3fsm.state_count = L3_STATE_COUNT;
  529. l3fsm.event_count = L3_EVENT_COUNT;
  530. l3fsm.strEvent = strL3Event;
  531. l3fsm.strState = strL3State;
  532. return FsmNew(&l3fsm, L3FnList, L3_FN_COUNT);
  533. }
  534. void
  535. Isdnl3Free(void)
  536. {
  537. FsmFree(&l3fsm);
  538. }