PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/isdn/hisax/isdnl3.c

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