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