11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: tei.c,v 2.20.2.3 2004/01/13 14:31:26 keil Exp $
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author       Karsten Keil
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              based on the teles driver from Jan den Ouden
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright    by Karsten Keil      <keil@isdn4linux.de>
6475be4d85a274d0961593db41cf85689db1d583cJoe Perches *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For changes and modifications please read
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Documentation/isdn/HiSax.cert
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Thanks to    Jan den Ouden
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *              Fritz Elfert
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hisax.h"
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isdnl2.h"
205a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h>
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/random.h>
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconst char *tei_revision = "$Revision: 2.20.2.3 $";
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_REQUEST	1
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_ASSIGNED	2
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_DENIED	3
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_CHK_REQ	4
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_CHK_RES	5
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_REMOVE	6
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ID_VERIFY	7
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEI_ENTITY_ID	0xf
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct Fsm teifsm;
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid tei_handler(struct PStack *st, u_char pr, struct sk_buff *skb);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum {
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ST_TEI_NOP,
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ST_TEI_IDREQ,
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ST_TEI_IDVERIFY,
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
46475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define TEI_STATE_COUNT (ST_TEI_IDVERIFY + 1)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strTeiState[] =
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"ST_TEI_NOP",
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"ST_TEI_IDREQ",
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"ST_TEI_IDVERIFY",
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum {
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_IDREQ,
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_ASSIGN,
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_DENIED,
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_CHKREQ,
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_REMOVE,
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_VERIFY,
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	EV_T202,
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
65475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define TEI_EVENT_COUNT (EV_T202 + 1)
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *strTeiEvent[] =
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_IDREQ",
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_ASSIGN",
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_DENIED",
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_CHKREQ",
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_REMOVE",
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_VERIFY",
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	"EV_T202",
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
78672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic unsigned int
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrandom_ri(void)
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int x;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	get_random_bytes(&x, sizeof(x));
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (x & 0xffff);
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct PStack *
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfindtei(struct PStack *st, int tei)
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *ptr = *(st->l1.stlistp);
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (tei == 127)
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (NULL);
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (ptr)
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ptr->l2.tei == tei)
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return (ptr);
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ptr = ptr->next;
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (NULL);
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsput_tei_msg(struct PStack *st, u_char m_id, unsigned int ri, u_char tei)
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb;
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_char *bp;
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!(skb = alloc_skb(8, GFP_ATOMIC))) {
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING "HiSax: No skb for TEI manager\n");
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = skb_put(skb, 3);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[0] = (TEI_SAPI << 2);
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[1] = (GROUP_TEI << 1) | 0x1;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[2] = UI;
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp = skb_put(skb, 5);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[0] = TEI_ENTITY_ID;
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[1] = ri >> 8;
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[2] = ri & 0xff;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[3] = m_id;
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	bp[4] = (tei << 1) | 1;
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->l2.l2l1(st, PH_DATA | REQUEST, skb);
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_request(struct FsmInst *fi, int event, void *arg)
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->l2.tei != -1) {
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
133475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"assign request for already assigned tei %d",
134475be4d85a274d0961593db41cf85689db1d583cJoe Perches					st->l2.tei);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.ri = random_ri();
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
140475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"assign request ri %d", st->ma.ri);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	FsmChangeState(&st->ma.tei_m, ST_TEI_IDREQ);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 1);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.N202 = 3;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_assign(struct FsmInst *fi, int event, void *arg)
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *ost, *st = fi->userdata;
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb = arg;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs;
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ri, tei;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tei = skb->data[4] >> 1;
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
159475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"identity assign ri %d tei %d", ri, tei);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((ost = findtei(st, tei))) {	/* same tei is in use */
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ri != ost->ma.ri) {
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
163475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"possible duplicate assignment tei %d", tei);
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ost->l2.l2tei(ost, MDL_ERROR | RESPONSE, NULL);
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else if (ri == st->ma.ri) {
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmDelTimer(&st->ma.t202, 1);
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) tei);
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs = (struct IsdnCardState *) st->l1.hardware;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_test_dup(struct FsmInst *fi, int event, void *arg)
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *ost, *st = fi->userdata;
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb = arg;
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tei, ri;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tei = skb->data[4] >> 1;
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
186475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"foreign identity assign ri %d tei %d", ri, tei);
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((ost = findtei(st, tei))) {	/* same tei is in use */
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (ri != ost->ma.ri) {	/* and it wasn't our request */
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
190475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"possible duplicate assignment tei %d", tei);
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			FsmEvent(&ost->ma.tei_m, EV_VERIFY, NULL);
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
193475be4d85a274d0961593db41cf85689db1d583cJoe Perches	}
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_denied(struct FsmInst *fi, int event, void *arg)
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb = arg;
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ri, tei;
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ri = ((unsigned int) skb->data[1] << 8) + skb->data[2];
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tei = skb->data[4] >> 1;
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
207475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"identity denied ri %d tei %d", ri, tei);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_chk_req(struct FsmInst *fi, int event, void *arg)
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb = arg;
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tei;
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tei = skb->data[4] >> 1;
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
220475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"identity check req tei %d", tei);
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmDelTimer(&st->ma.t202, 4);
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_tei_msg(st, ID_CHK_RES, random_ri(), st->l2.tei);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_remove(struct FsmInst *fi, int event, void *arg)
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb = arg;
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int tei;
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tei = skb->data[4] >> 1;
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
239475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"identity remove tei %d", tei);
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((st->l2.tei != -1) && ((tei == GROUP_TEI) || (tei == st->l2.tei))) {
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmDelTimer(&st->ma.t202, 5);
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmChangeState(&st->ma.tei_m, ST_TEI_NOP);
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs = (struct IsdnCardState *) st->l1.hardware;
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_verify(struct FsmInst *fi, int event, void *arg)
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (st->ma.debug)
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
256475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"id verify request for tei %d", st->l2.tei);
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	FsmChangeState(&st->ma.tei_m, ST_TEI_IDVERIFY);
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 2);
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.N202 = 2;
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_req_tout(struct FsmInst *fi, int event, void *arg)
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs;
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (--st->ma.N202) {
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.ri = random_ri();
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (st->ma.debug)
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
273475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"assign req(%d) ri %d", 4 - st->ma.N202,
274475be4d85a274d0961593db41cf85689db1d583cJoe Perches						st->ma.ri);
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_tei_msg(st, ID_REQUEST, st->ma.ri, 127);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 3);
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m, "assign req failed");
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->l3.l3l2(st, MDL_ERROR | RESPONSE, NULL);
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs = (struct IsdnCardState *) st->l1.hardware;
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmChangeState(fi, ST_TEI_NOP);
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_id_ver_tout(struct FsmInst *fi, int event, void *arg)
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs;
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (--st->ma.N202) {
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (st->ma.debug)
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
295475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"id verify req(%d) for tei %d",
296475be4d85a274d0961593db41cf85689db1d583cJoe Perches						3 - st->ma.N202, st->l2.tei);
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		put_tei_msg(st, ID_VERIFY, 0, st->l2.tei);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmAddTimer(&st->ma.t202, st->ma.T202, EV_T202, NULL, 4);
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
301475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"verify req for tei %d failed", st->l2.tei);
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->l3.l3l2(st, MDL_REMOVE | REQUEST, NULL);
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs = (struct IsdnCardState *) st->l1.hardware;
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cs->cardmsg(cs, MDL_REMOVE | REQUEST, NULL);
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmChangeState(fi, ST_TEI_NOP);
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_l1l2(struct PStack *st, int pr, void *arg)
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct sk_buff *skb = arg;
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int mt;
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev_kfree_skb(skb);
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (pr == (PH_DATA | INDICATION)) {
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (skb->len < 3) {
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
323475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"short mgr frame %ld/3", skb->len);
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if ((skb->data[0] != ((TEI_SAPI << 2) | 2)) ||
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   (skb->data[1] != ((GROUP_TEI << 1) | 1))) {
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
327475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"wrong mgr sapi/tei %x/%x",
328475be4d85a274d0961593db41cf85689db1d583cJoe Perches						skb->data[0], skb->data[1]);
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else if ((skb->data[2] & 0xef) != UI) {
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->ma.tei_m.printdebug(&st->ma.tei_m,
331475be4d85a274d0961593db41cf85689db1d583cJoe Perches						"mgr frame is not ui %x", skb->data[2]);
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			skb_pull(skb, 3);
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (skb->len < 5) {
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				st->ma.tei_m.printdebug(&st->ma.tei_m,
336475be4d85a274d0961593db41cf85689db1d583cJoe Perches							"short mgr frame %ld/5", skb->len);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else if (skb->data[0] != TEI_ENTITY_ID) {
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* wrong management entity identifier, ignore */
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				st->ma.tei_m.printdebug(&st->ma.tei_m,
340475be4d85a274d0961593db41cf85689db1d583cJoe Perches							"tei handler wrong entity id %x",
341475be4d85a274d0961593db41cf85689db1d583cJoe Perches							skb->data[0]);
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			} else {
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				mt = skb->data[3];
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				if (mt == ID_ASSIGNED)
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					FsmEvent(&st->ma.tei_m, EV_ASSIGN, skb);
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else if (mt == ID_DENIED)
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					FsmEvent(&st->ma.tei_m, EV_DENIED, skb);
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else if (mt == ID_CHK_REQ)
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					FsmEvent(&st->ma.tei_m, EV_CHKREQ, skb);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else if (mt == ID_REMOVE)
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					FsmEvent(&st->ma.tei_m, EV_REMOVE, skb);
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				else {
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					st->ma.tei_m.printdebug(&st->ma.tei_m,
354475be4d85a274d0961593db41cf85689db1d583cJoe Perches								"tei handler wrong mt %x\n", mt);
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				}
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st->ma.tei_m.printdebug(&st->ma.tei_m,
360475be4d85a274d0961593db41cf85689db1d583cJoe Perches					"tei handler wrong pr %x\n", pr);
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev_kfree_skb(skb);
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_l2tei(struct PStack *st, int pr, void *arg)
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs;
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (pr == (MDL_ASSIGN | INDICATION)) {
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (st->ma.debug)
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				st->ma.tei_m.printdebug(&st->ma.tei_m,
374475be4d85a274d0961593db41cf85689db1d583cJoe Perches							"fixed assign tei %d", st->l2.tei);
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			st->l3.l3l2(st, MDL_ASSIGN | REQUEST, (void *) (long) st->l2.tei);
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cs = (struct IsdnCardState *) st->l1.hardware;
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			cs->cardmsg(cs, MDL_ASSIGN | REQUEST, NULL);
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (pr) {
382475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case (MDL_ASSIGN | INDICATION):
383475be4d85a274d0961593db41cf85689db1d583cJoe Perches		FsmEvent(&st->ma.tei_m, EV_IDREQ, arg);
384475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
385475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case (MDL_ERROR | REQUEST):
386475be4d85a274d0961593db41cf85689db1d583cJoe Perches		FsmEvent(&st->ma.tei_m, EV_VERIFY, arg);
387475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
388475be4d85a274d0961593db41cf85689db1d583cJoe Perches	default:
389475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstei_debug(struct FsmInst *fi, char *fmt, ...)
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_list args;
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = fi->userdata;
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_start(args, fmt);
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	VHiSax_putstatus(st->l1.hardware, "tei ", fmt, args);
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	va_end(args);
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssetstack_tei(struct PStack *st)
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->l2.l2tei = tei_l2tei;
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.T202 = 2000;	/* T202  2000 milliseconds */
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->l1.l1tei = tei_l1l2;
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.debug = 1;
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.tei_m.fsm = &teifsm;
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.tei_m.state = ST_TEI_NOP;
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.tei_m.debug = 1;
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.tei_m.userdata = st;
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.tei_m.userint = 0;
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	st->ma.tei_m.printdebug = tei_debug;
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	FsmInitTimer(&st->ma.tei_m, &st->ma.t202);
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsinit_tei(struct IsdnCardState *cs, int protocol)
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrelease_tei(struct IsdnCardState *cs)
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct PStack *st = cs->stlist;
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	while (st) {
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		FsmDelTimer(&st->ma.t202, 1);
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		st = st->next;
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct FsmNode TeiFnList[] __initdata =
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_NOP, EV_IDREQ, tei_id_request},
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_NOP, EV_ASSIGN, tei_id_test_dup},
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_NOP, EV_VERIFY, tei_id_verify},
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_NOP, EV_REMOVE, tei_id_remove},
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_NOP, EV_CHKREQ, tei_id_chk_req},
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_IDREQ, EV_T202, tei_id_req_tout},
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_IDREQ, EV_ASSIGN, tei_id_assign},
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_IDREQ, EV_DENIED, tei_id_denied},
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_IDVERIFY, EV_T202, tei_id_ver_tout},
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_IDVERIFY, EV_REMOVE, tei_id_remove},
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsTeiNew(void)
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	teifsm.state_count = TEI_STATE_COUNT;
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	teifsm.event_count = TEI_EVENT_COUNT;
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	teifsm.strEvent = strTeiEvent;
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	teifsm.strState = strTeiState;
458ba2d6ccb1df6ebb2c1b2322518ce7be25c1e3469Karsten Keil	return FsmNew(&teifsm, TeiFnList, ARRAY_SIZE(TeiFnList));
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsTeiFree(void)
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	FsmFree(&teifsm);
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
466