brintos

brintos / linux-shallow public Read only

0
0
Text · 51.3 KiB · 5bf7fcb Raw
2267 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 *4 * Author	Karsten Keil <kkeil@novell.com>5 *6 * Copyright 2008  by Karsten Keil <kkeil@novell.com>7 */8 9#include <linux/mISDNif.h>10#include <linux/slab.h>11#include "core.h"12#include "fsm.h"13#include "layer2.h"14 15static u_int *debug;16 17static18struct Fsm l2fsm = {NULL, 0, 0, NULL, NULL};19 20static char *strL2State[] =21{22	"ST_L2_1",23	"ST_L2_2",24	"ST_L2_3",25	"ST_L2_4",26	"ST_L2_5",27	"ST_L2_6",28	"ST_L2_7",29	"ST_L2_8",30};31 32enum {33	EV_L2_UI,34	EV_L2_SABME,35	EV_L2_DISC,36	EV_L2_DM,37	EV_L2_UA,38	EV_L2_FRMR,39	EV_L2_SUPER,40	EV_L2_I,41	EV_L2_DL_DATA,42	EV_L2_ACK_PULL,43	EV_L2_DL_UNITDATA,44	EV_L2_DL_ESTABLISH_REQ,45	EV_L2_DL_RELEASE_REQ,46	EV_L2_MDL_ASSIGN,47	EV_L2_MDL_REMOVE,48	EV_L2_MDL_ERROR,49	EV_L1_DEACTIVATE,50	EV_L2_T200,51	EV_L2_T203,52	EV_L2_T200I,53	EV_L2_T203I,54	EV_L2_SET_OWN_BUSY,55	EV_L2_CLEAR_OWN_BUSY,56	EV_L2_FRAME_ERROR,57};58 59#define L2_EVENT_COUNT (EV_L2_FRAME_ERROR + 1)60 61static char *strL2Event[] =62{63	"EV_L2_UI",64	"EV_L2_SABME",65	"EV_L2_DISC",66	"EV_L2_DM",67	"EV_L2_UA",68	"EV_L2_FRMR",69	"EV_L2_SUPER",70	"EV_L2_I",71	"EV_L2_DL_DATA",72	"EV_L2_ACK_PULL",73	"EV_L2_DL_UNITDATA",74	"EV_L2_DL_ESTABLISH_REQ",75	"EV_L2_DL_RELEASE_REQ",76	"EV_L2_MDL_ASSIGN",77	"EV_L2_MDL_REMOVE",78	"EV_L2_MDL_ERROR",79	"EV_L1_DEACTIVATE",80	"EV_L2_T200",81	"EV_L2_T203",82	"EV_L2_T200I",83	"EV_L2_T203I",84	"EV_L2_SET_OWN_BUSY",85	"EV_L2_CLEAR_OWN_BUSY",86	"EV_L2_FRAME_ERROR",87};88 89static void90l2m_debug(struct FsmInst *fi, char *fmt, ...)91{92	struct layer2 *l2 = fi->userdata;93	struct va_format vaf;94	va_list va;95 96	if (!(*debug & DEBUG_L2_FSM))97		return;98 99	va_start(va, fmt);100 101	vaf.fmt = fmt;102	vaf.va = &va;103 104	printk(KERN_DEBUG "%s l2 (sapi %d tei %d): %pV\n",105	       mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei, &vaf);106 107	va_end(va);108}109 110inline u_int111l2headersize(struct layer2 *l2, int ui)112{113	return ((test_bit(FLG_MOD128, &l2->flag) && (!ui)) ? 2 : 1) +114		(test_bit(FLG_LAPD, &l2->flag) ? 2 : 1);115}116 117inline u_int118l2addrsize(struct layer2 *l2)119{120	return test_bit(FLG_LAPD, &l2->flag) ? 2 : 1;121}122 123static u_int124l2_newid(struct layer2 *l2)125{126	u_int	id;127 128	id = l2->next_id++;129	if (id == 0x7fff)130		l2->next_id = 1;131	id <<= 16;132	id |= l2->tei << 8;133	id |= l2->sapi;134	return id;135}136 137static void138l2up(struct layer2 *l2, u_int prim, struct sk_buff *skb)139{140	int	err;141 142	if (!l2->up)143		return;144	mISDN_HEAD_PRIM(skb) = prim;145	mISDN_HEAD_ID(skb) = (l2->ch.nr << 16) | l2->ch.addr;146	err = l2->up->send(l2->up, skb);147	if (err) {148		printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,149		       mISDNDevName4ch(&l2->ch), err);150		dev_kfree_skb(skb);151	}152}153 154static void155l2up_create(struct layer2 *l2, u_int prim, int len, void *arg)156{157	struct sk_buff	*skb;158	struct mISDNhead *hh;159	int		err;160 161	if (!l2->up)162		return;163	skb = mI_alloc_skb(len, GFP_ATOMIC);164	if (!skb)165		return;166	hh = mISDN_HEAD_P(skb);167	hh->prim = prim;168	hh->id = (l2->ch.nr << 16) | l2->ch.addr;169	if (len)170		skb_put_data(skb, arg, len);171	err = l2->up->send(l2->up, skb);172	if (err) {173		printk(KERN_WARNING "%s: dev %s err=%d\n", __func__,174		       mISDNDevName4ch(&l2->ch), err);175		dev_kfree_skb(skb);176	}177}178 179static int180l2down_skb(struct layer2 *l2, struct sk_buff *skb) {181	int ret;182 183	ret = l2->ch.recv(l2->ch.peer, skb);184	if (ret && (*debug & DEBUG_L2_RECV))185		printk(KERN_DEBUG "l2down_skb: dev %s ret(%d)\n",186		       mISDNDevName4ch(&l2->ch), ret);187	return ret;188}189 190static int191l2down_raw(struct layer2 *l2, struct sk_buff *skb)192{193	struct mISDNhead *hh = mISDN_HEAD_P(skb);194 195	if (hh->prim == PH_DATA_REQ) {196		if (test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {197			skb_queue_tail(&l2->down_queue, skb);198			return 0;199		}200		l2->down_id = mISDN_HEAD_ID(skb);201	}202	return l2down_skb(l2, skb);203}204 205static int206l2down(struct layer2 *l2, u_int prim, u_int id, struct sk_buff *skb)207{208	struct mISDNhead *hh = mISDN_HEAD_P(skb);209 210	hh->prim = prim;211	hh->id = id;212	return l2down_raw(l2, skb);213}214 215static int216l2down_create(struct layer2 *l2, u_int prim, u_int id, int len, void *arg)217{218	struct sk_buff	*skb;219	int		err;220	struct mISDNhead *hh;221 222	skb = mI_alloc_skb(len, GFP_ATOMIC);223	if (!skb)224		return -ENOMEM;225	hh = mISDN_HEAD_P(skb);226	hh->prim = prim;227	hh->id = id;228	if (len)229		skb_put_data(skb, arg, len);230	err = l2down_raw(l2, skb);231	if (err)232		dev_kfree_skb(skb);233	return err;234}235 236static int237ph_data_confirm(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) {238	struct sk_buff *nskb = skb;239	int ret = -EAGAIN;240 241	if (test_bit(FLG_L1_NOTREADY, &l2->flag)) {242		if (hh->id == l2->down_id) {243			nskb = skb_dequeue(&l2->down_queue);244			if (nskb) {245				l2->down_id = mISDN_HEAD_ID(nskb);246				if (l2down_skb(l2, nskb)) {247					dev_kfree_skb(nskb);248					l2->down_id = MISDN_ID_NONE;249				}250			} else251				l2->down_id = MISDN_ID_NONE;252			if (ret) {253				dev_kfree_skb(skb);254				ret = 0;255			}256			if (l2->down_id == MISDN_ID_NONE) {257				test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);258				mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);259			}260		}261	}262	if (!test_and_set_bit(FLG_L1_NOTREADY, &l2->flag)) {263		nskb = skb_dequeue(&l2->down_queue);264		if (nskb) {265			l2->down_id = mISDN_HEAD_ID(nskb);266			if (l2down_skb(l2, nskb)) {267				dev_kfree_skb(nskb);268				l2->down_id = MISDN_ID_NONE;269				test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);270			}271		} else272			test_and_clear_bit(FLG_L1_NOTREADY, &l2->flag);273	}274	return ret;275}276 277static void278l2_timeout(struct FsmInst *fi, int event, void *arg)279{280	struct layer2 *l2 = fi->userdata;281	struct sk_buff *skb;282	struct mISDNhead *hh;283 284	skb = mI_alloc_skb(0, GFP_ATOMIC);285	if (!skb) {286		printk(KERN_WARNING "%s: L2(%d,%d) nr:%x timer %s no skb\n",287		       mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,288		       l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");289		return;290	}291	hh = mISDN_HEAD_P(skb);292	hh->prim = event == EV_L2_T200 ? DL_TIMER200_IND : DL_TIMER203_IND;293	hh->id = l2->ch.nr;294	if (*debug & DEBUG_TIMER)295		printk(KERN_DEBUG "%s: L2(%d,%d) nr:%x timer %s expired\n",296		       mISDNDevName4ch(&l2->ch), l2->sapi, l2->tei,297		       l2->ch.nr, event == EV_L2_T200 ? "T200" : "T203");298	if (l2->ch.st)299		l2->ch.st->own.recv(&l2->ch.st->own, skb);300}301 302static int303l2mgr(struct layer2 *l2, u_int prim, void *arg) {304	long c = (long)arg;305 306	printk(KERN_WARNING "l2mgr: dev %s addr:%x prim %x %c\n",307	       mISDNDevName4ch(&l2->ch), l2->id, prim, (char)c);308	if (test_bit(FLG_LAPD, &l2->flag) &&309	    !test_bit(FLG_FIXED_TEI, &l2->flag)) {310		switch (c) {311		case 'C':312		case 'D':313		case 'G':314		case 'H':315			l2_tei(l2, prim, (u_long)arg);316			break;317		}318	}319	return 0;320}321 322static void323set_peer_busy(struct layer2 *l2) {324	test_and_set_bit(FLG_PEER_BUSY, &l2->flag);325	if (skb_queue_len(&l2->i_queue) || skb_queue_len(&l2->ui_queue))326		test_and_set_bit(FLG_L2BLOCK, &l2->flag);327}328 329static void330clear_peer_busy(struct layer2 *l2) {331	if (test_and_clear_bit(FLG_PEER_BUSY, &l2->flag))332		test_and_clear_bit(FLG_L2BLOCK, &l2->flag);333}334 335static void336InitWin(struct layer2 *l2)337{338	int i;339 340	for (i = 0; i < MAX_WINDOW; i++)341		l2->windowar[i] = NULL;342}343 344static int345freewin(struct layer2 *l2)346{347	int i, cnt = 0;348 349	for (i = 0; i < MAX_WINDOW; i++) {350		if (l2->windowar[i]) {351			cnt++;352			dev_kfree_skb(l2->windowar[i]);353			l2->windowar[i] = NULL;354		}355	}356	return cnt;357}358 359static void360ReleaseWin(struct layer2 *l2)361{362	int cnt = freewin(l2);363 364	if (cnt)365		printk(KERN_WARNING366		       "isdnl2 freed %d skbuffs in release\n", cnt);367}368 369inline unsigned int370cansend(struct layer2 *l2)371{372	unsigned int p1;373 374	if (test_bit(FLG_MOD128, &l2->flag))375		p1 = (l2->vs - l2->va) % 128;376	else377		p1 = (l2->vs - l2->va) % 8;378	return (p1 < l2->window) && !test_bit(FLG_PEER_BUSY, &l2->flag);379}380 381inline void382clear_exception(struct layer2 *l2)383{384	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);385	test_and_clear_bit(FLG_REJEXC, &l2->flag);386	test_and_clear_bit(FLG_OWN_BUSY, &l2->flag);387	clear_peer_busy(l2);388}389 390static int391sethdraddr(struct layer2 *l2, u_char *header, int rsp)392{393	u_char *ptr = header;394	int crbit = rsp;395 396	if (test_bit(FLG_LAPD, &l2->flag)) {397		if (test_bit(FLG_LAPD_NET, &l2->flag))398			crbit = !crbit;399		*ptr++ = (l2->sapi << 2) | (crbit ? 2 : 0);400		*ptr++ = (l2->tei << 1) | 1;401		return 2;402	} else {403		if (test_bit(FLG_ORIG, &l2->flag))404			crbit = !crbit;405		if (crbit)406			*ptr++ = l2->addr.B;407		else408			*ptr++ = l2->addr.A;409		return 1;410	}411}412 413static inline void414enqueue_super(struct layer2 *l2, struct sk_buff *skb)415{416	if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))417		dev_kfree_skb(skb);418}419 420static inline void421enqueue_ui(struct layer2 *l2, struct sk_buff *skb)422{423	if (l2->tm)424		l2_tei(l2, MDL_STATUS_UI_IND, 0);425	if (l2down(l2, PH_DATA_REQ, l2_newid(l2), skb))426		dev_kfree_skb(skb);427}428 429inline int430IsUI(u_char *data)431{432	return (data[0] & 0xef) == UI;433}434 435inline int436IsUA(u_char *data)437{438	return (data[0] & 0xef) == UA;439}440 441inline int442IsDM(u_char *data)443{444	return (data[0] & 0xef) == DM;445}446 447inline int448IsDISC(u_char *data)449{450	return (data[0] & 0xef) == DISC;451}452 453inline int454IsRR(u_char *data, struct layer2 *l2)455{456	if (test_bit(FLG_MOD128, &l2->flag))457		return data[0] == RR;458	else459		return (data[0] & 0xf) == 1;460}461 462inline int463IsSFrame(u_char *data, struct layer2 *l2)464{465	register u_char d = *data;466 467	if (!test_bit(FLG_MOD128, &l2->flag))468		d &= 0xf;469	return ((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c);470}471 472inline int473IsSABME(u_char *data, struct layer2 *l2)474{475	u_char d = data[0] & ~0x10;476 477	return test_bit(FLG_MOD128, &l2->flag) ? d == SABME : d == SABM;478}479 480inline int481IsREJ(u_char *data, struct layer2 *l2)482{483	return test_bit(FLG_MOD128, &l2->flag) ?484		data[0] == REJ : (data[0] & 0xf) == REJ;485}486 487inline int488IsFRMR(u_char *data)489{490	return (data[0] & 0xef) == FRMR;491}492 493inline int494IsRNR(u_char *data, struct layer2 *l2)495{496	return test_bit(FLG_MOD128, &l2->flag) ?497		data[0] == RNR : (data[0] & 0xf) == RNR;498}499 500static int501iframe_error(struct layer2 *l2, struct sk_buff *skb)502{503	u_int	i;504	int	rsp = *skb->data & 0x2;505 506	i = l2addrsize(l2) + (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1);507	if (test_bit(FLG_ORIG, &l2->flag))508		rsp = !rsp;509	if (rsp)510		return 'L';511	if (skb->len < i)512		return 'N';513	if ((skb->len - i) > l2->maxlen)514		return 'O';515	return 0;516}517 518static int519super_error(struct layer2 *l2, struct sk_buff *skb)520{521	if (skb->len != l2addrsize(l2) +522	    (test_bit(FLG_MOD128, &l2->flag) ? 2 : 1))523		return 'N';524	return 0;525}526 527static int528unnum_error(struct layer2 *l2, struct sk_buff *skb, int wantrsp)529{530	int rsp = (*skb->data & 0x2) >> 1;531	if (test_bit(FLG_ORIG, &l2->flag))532		rsp = !rsp;533	if (rsp != wantrsp)534		return 'L';535	if (skb->len != l2addrsize(l2) + 1)536		return 'N';537	return 0;538}539 540static int541UI_error(struct layer2 *l2, struct sk_buff *skb)542{543	int rsp = *skb->data & 0x2;544	if (test_bit(FLG_ORIG, &l2->flag))545		rsp = !rsp;546	if (rsp)547		return 'L';548	if (skb->len > l2->maxlen + l2addrsize(l2) + 1)549		return 'O';550	return 0;551}552 553static int554FRMR_error(struct layer2 *l2, struct sk_buff *skb)555{556	u_int	headers = l2addrsize(l2) + 1;557	u_char	*datap = skb->data + headers;558	int	rsp = *skb->data & 0x2;559 560	if (test_bit(FLG_ORIG, &l2->flag))561		rsp = !rsp;562	if (!rsp)563		return 'L';564	if (test_bit(FLG_MOD128, &l2->flag)) {565		if (skb->len < headers + 5)566			return 'N';567		else if (*debug & DEBUG_L2)568			l2m_debug(&l2->l2m,569				  "FRMR information %2x %2x %2x %2x %2x",570				  datap[0], datap[1], datap[2], datap[3], datap[4]);571	} else {572		if (skb->len < headers + 3)573			return 'N';574		else if (*debug & DEBUG_L2)575			l2m_debug(&l2->l2m,576				  "FRMR information %2x %2x %2x",577				  datap[0], datap[1], datap[2]);578	}579	return 0;580}581 582static unsigned int583legalnr(struct layer2 *l2, unsigned int nr)584{585	if (test_bit(FLG_MOD128, &l2->flag))586		return ((nr - l2->va) % 128) <= ((l2->vs - l2->va) % 128);587	else588		return ((nr - l2->va) % 8) <= ((l2->vs - l2->va) % 8);589}590 591static void592setva(struct layer2 *l2, unsigned int nr)593{594	struct sk_buff	*skb;595 596	while (l2->va != nr) {597		l2->va++;598		if (test_bit(FLG_MOD128, &l2->flag))599			l2->va %= 128;600		else601			l2->va %= 8;602		if (l2->windowar[l2->sow]) {603			skb_trim(l2->windowar[l2->sow], 0);604			skb_queue_tail(&l2->tmp_queue, l2->windowar[l2->sow]);605			l2->windowar[l2->sow] = NULL;606		}607		l2->sow = (l2->sow + 1) % l2->window;608	}609	skb = skb_dequeue(&l2->tmp_queue);610	while (skb) {611		dev_kfree_skb(skb);612		skb = skb_dequeue(&l2->tmp_queue);613	}614}615 616static void617send_uframe(struct layer2 *l2, struct sk_buff *skb, u_char cmd, u_char cr)618{619	u_char tmp[MAX_L2HEADER_LEN];620	int i;621 622	i = sethdraddr(l2, tmp, cr);623	tmp[i++] = cmd;624	if (skb)625		skb_trim(skb, 0);626	else {627		skb = mI_alloc_skb(i, GFP_ATOMIC);628		if (!skb) {629			printk(KERN_WARNING "%s: can't alloc skbuff in %s\n",630			       mISDNDevName4ch(&l2->ch), __func__);631			return;632		}633	}634	skb_put_data(skb, tmp, i);635	enqueue_super(l2, skb);636}637 638 639inline u_char640get_PollFlag(struct layer2 *l2, struct sk_buff *skb)641{642	return skb->data[l2addrsize(l2)] & 0x10;643}644 645inline u_char646get_PollFlagFree(struct layer2 *l2, struct sk_buff *skb)647{648	u_char PF;649 650	PF = get_PollFlag(l2, skb);651	dev_kfree_skb(skb);652	return PF;653}654 655inline void656start_t200(struct layer2 *l2, int i)657{658	mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);659	test_and_set_bit(FLG_T200_RUN, &l2->flag);660}661 662inline void663restart_t200(struct layer2 *l2, int i)664{665	mISDN_FsmRestartTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, i);666	test_and_set_bit(FLG_T200_RUN, &l2->flag);667}668 669inline void670stop_t200(struct layer2 *l2, int i)671{672	if (test_and_clear_bit(FLG_T200_RUN, &l2->flag))673		mISDN_FsmDelTimer(&l2->t200, i);674}675 676inline void677st5_dl_release_l2l3(struct layer2 *l2)678{679	int pr;680 681	if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))682		pr = DL_RELEASE_CNF;683	else684		pr = DL_RELEASE_IND;685	l2up_create(l2, pr, 0, NULL);686}687 688inline void689lapb_dl_release_l2l3(struct layer2 *l2, int f)690{691	if (test_bit(FLG_LAPB, &l2->flag))692		l2down_create(l2, PH_DEACTIVATE_REQ, l2_newid(l2), 0, NULL);693	l2up_create(l2, f, 0, NULL);694}695 696static void697establishlink(struct FsmInst *fi)698{699	struct layer2 *l2 = fi->userdata;700	u_char cmd;701 702	clear_exception(l2);703	l2->rc = 0;704	cmd = (test_bit(FLG_MOD128, &l2->flag) ? SABME : SABM) | 0x10;705	send_uframe(l2, NULL, cmd, CMD);706	mISDN_FsmDelTimer(&l2->t203, 1);707	restart_t200(l2, 1);708	test_and_clear_bit(FLG_PEND_REL, &l2->flag);709	freewin(l2);710	mISDN_FsmChangeState(fi, ST_L2_5);711}712 713static void714l2_mdl_error_ua(struct FsmInst *fi, int event, void *arg)715{716	struct sk_buff *skb = arg;717	struct layer2 *l2 = fi->userdata;718 719	if (get_PollFlagFree(l2, skb))720		l2mgr(l2, MDL_ERROR_IND, (void *) 'C');721	else722		l2mgr(l2, MDL_ERROR_IND, (void *) 'D');723 724}725 726static void727l2_mdl_error_dm(struct FsmInst *fi, int event, void *arg)728{729	struct sk_buff *skb = arg;730	struct layer2 *l2 = fi->userdata;731 732	if (get_PollFlagFree(l2, skb))733		l2mgr(l2, MDL_ERROR_IND, (void *) 'B');734	else {735		l2mgr(l2, MDL_ERROR_IND, (void *) 'E');736		establishlink(fi);737		test_and_clear_bit(FLG_L3_INIT, &l2->flag);738	}739}740 741static void742l2_st8_mdl_error_dm(struct FsmInst *fi, int event, void *arg)743{744	struct sk_buff *skb = arg;745	struct layer2 *l2 = fi->userdata;746 747	if (get_PollFlagFree(l2, skb))748		l2mgr(l2, MDL_ERROR_IND, (void *) 'B');749	else750		l2mgr(l2, MDL_ERROR_IND, (void *) 'E');751	establishlink(fi);752	test_and_clear_bit(FLG_L3_INIT, &l2->flag);753}754 755static void756l2_go_st3(struct FsmInst *fi, int event, void *arg)757{758	dev_kfree_skb((struct sk_buff *)arg);759	mISDN_FsmChangeState(fi, ST_L2_3);760}761 762static void763l2_mdl_assign(struct FsmInst *fi, int event, void *arg)764{765	struct layer2	*l2 = fi->userdata;766 767	mISDN_FsmChangeState(fi, ST_L2_3);768	dev_kfree_skb((struct sk_buff *)arg);769	l2_tei(l2, MDL_ASSIGN_IND, 0);770}771 772static void773l2_queue_ui_assign(struct FsmInst *fi, int event, void *arg)774{775	struct layer2 *l2 = fi->userdata;776	struct sk_buff *skb = arg;777 778	skb_queue_tail(&l2->ui_queue, skb);779	mISDN_FsmChangeState(fi, ST_L2_2);780	l2_tei(l2, MDL_ASSIGN_IND, 0);781}782 783static void784l2_queue_ui(struct FsmInst *fi, int event, void *arg)785{786	struct layer2 *l2 = fi->userdata;787	struct sk_buff *skb = arg;788 789	skb_queue_tail(&l2->ui_queue, skb);790}791 792static void793tx_ui(struct layer2 *l2)794{795	struct sk_buff *skb;796	u_char header[MAX_L2HEADER_LEN];797	int i;798 799	i = sethdraddr(l2, header, CMD);800	if (test_bit(FLG_LAPD_NET, &l2->flag))801		header[1] = 0xff; /* tei 127 */802	header[i++] = UI;803	while ((skb = skb_dequeue(&l2->ui_queue))) {804		memcpy(skb_push(skb, i), header, i);805		enqueue_ui(l2, skb);806	}807}808 809static void810l2_send_ui(struct FsmInst *fi, int event, void *arg)811{812	struct layer2 *l2 = fi->userdata;813	struct sk_buff *skb = arg;814 815	skb_queue_tail(&l2->ui_queue, skb);816	tx_ui(l2);817}818 819static void820l2_got_ui(struct FsmInst *fi, int event, void *arg)821{822	struct layer2 *l2 = fi->userdata;823	struct sk_buff *skb = arg;824 825	skb_pull(skb, l2headersize(l2, 1));826/*827 *		in states 1-3 for broadcast828 */829 830	if (l2->tm)831		l2_tei(l2, MDL_STATUS_UI_IND, 0);832	l2up(l2, DL_UNITDATA_IND, skb);833}834 835static void836l2_establish(struct FsmInst *fi, int event, void *arg)837{838	struct sk_buff *skb = arg;839	struct layer2 *l2 = fi->userdata;840 841	establishlink(fi);842	test_and_set_bit(FLG_L3_INIT, &l2->flag);843	dev_kfree_skb(skb);844}845 846static void847l2_discard_i_setl3(struct FsmInst *fi, int event, void *arg)848{849	struct sk_buff *skb = arg;850	struct layer2 *l2 = fi->userdata;851 852	skb_queue_purge(&l2->i_queue);853	test_and_set_bit(FLG_L3_INIT, &l2->flag);854	test_and_clear_bit(FLG_PEND_REL, &l2->flag);855	dev_kfree_skb(skb);856}857 858static void859l2_l3_reestablish(struct FsmInst *fi, int event, void *arg)860{861	struct sk_buff *skb = arg;862	struct layer2 *l2 = fi->userdata;863 864	skb_queue_purge(&l2->i_queue);865	establishlink(fi);866	test_and_set_bit(FLG_L3_INIT, &l2->flag);867	dev_kfree_skb(skb);868}869 870static void871l2_release(struct FsmInst *fi, int event, void *arg)872{873	struct layer2 *l2 = fi->userdata;874	struct sk_buff *skb = arg;875 876	skb_trim(skb, 0);877	l2up(l2, DL_RELEASE_CNF, skb);878}879 880static void881l2_pend_rel(struct FsmInst *fi, int event, void *arg)882{883	struct sk_buff *skb = arg;884	struct layer2 *l2 = fi->userdata;885 886	test_and_set_bit(FLG_PEND_REL, &l2->flag);887	dev_kfree_skb(skb);888}889 890static void891l2_disconnect(struct FsmInst *fi, int event, void *arg)892{893	struct layer2 *l2 = fi->userdata;894	struct sk_buff *skb = arg;895 896	skb_queue_purge(&l2->i_queue);897	freewin(l2);898	mISDN_FsmChangeState(fi, ST_L2_6);899	l2->rc = 0;900	send_uframe(l2, NULL, DISC | 0x10, CMD);901	mISDN_FsmDelTimer(&l2->t203, 1);902	restart_t200(l2, 2);903	dev_kfree_skb(skb);904}905 906static void907l2_start_multi(struct FsmInst *fi, int event, void *arg)908{909	struct layer2	*l2 = fi->userdata;910	struct sk_buff	*skb = arg;911 912	l2->vs = 0;913	l2->va = 0;914	l2->vr = 0;915	l2->sow = 0;916	clear_exception(l2);917	send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);918	mISDN_FsmChangeState(fi, ST_L2_7);919	mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);920	skb_trim(skb, 0);921	l2up(l2, DL_ESTABLISH_IND, skb);922	if (l2->tm)923		l2_tei(l2, MDL_STATUS_UP_IND, 0);924}925 926static void927l2_send_UA(struct FsmInst *fi, int event, void *arg)928{929	struct layer2 *l2 = fi->userdata;930	struct sk_buff *skb = arg;931 932	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);933}934 935static void936l2_send_DM(struct FsmInst *fi, int event, void *arg)937{938	struct layer2 *l2 = fi->userdata;939	struct sk_buff *skb = arg;940 941	send_uframe(l2, skb, DM | get_PollFlag(l2, skb), RSP);942}943 944static void945l2_restart_multi(struct FsmInst *fi, int event, void *arg)946{947	struct layer2	*l2 = fi->userdata;948	struct sk_buff	*skb = arg;949	int		est = 0;950 951	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);952 953	l2mgr(l2, MDL_ERROR_IND, (void *) 'F');954 955	if (l2->vs != l2->va) {956		skb_queue_purge(&l2->i_queue);957		est = 1;958	}959 960	clear_exception(l2);961	l2->vs = 0;962	l2->va = 0;963	l2->vr = 0;964	l2->sow = 0;965	mISDN_FsmChangeState(fi, ST_L2_7);966	stop_t200(l2, 3);967	mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);968 969	if (est)970		l2up_create(l2, DL_ESTABLISH_IND, 0, NULL);971/*		mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,972 *		    MGR_SHORTSTATUS | INDICATION, SSTATUS_L2_ESTABLISHED,973 *		    0, NULL, 0);974 */975	if (skb_queue_len(&l2->i_queue) && cansend(l2))976		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);977}978 979static void980l2_stop_multi(struct FsmInst *fi, int event, void *arg)981{982	struct layer2	*l2 = fi->userdata;983	struct sk_buff	*skb = arg;984 985	mISDN_FsmChangeState(fi, ST_L2_4);986	mISDN_FsmDelTimer(&l2->t203, 3);987	stop_t200(l2, 4);988 989	send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);990	skb_queue_purge(&l2->i_queue);991	freewin(l2);992	lapb_dl_release_l2l3(l2, DL_RELEASE_IND);993	if (l2->tm)994		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);995}996 997static void998l2_connected(struct FsmInst *fi, int event, void *arg)999{1000	struct layer2	*l2 = fi->userdata;1001	struct sk_buff	*skb = arg;1002	int pr = -1;1003 1004	if (!get_PollFlag(l2, skb)) {1005		l2_mdl_error_ua(fi, event, arg);1006		return;1007	}1008	dev_kfree_skb(skb);1009	if (test_and_clear_bit(FLG_PEND_REL, &l2->flag))1010		l2_disconnect(fi, event, NULL);1011	if (test_and_clear_bit(FLG_L3_INIT, &l2->flag)) {1012		pr = DL_ESTABLISH_CNF;1013	} else if (l2->vs != l2->va) {1014		skb_queue_purge(&l2->i_queue);1015		pr = DL_ESTABLISH_IND;1016	}1017	stop_t200(l2, 5);1018	l2->vr = 0;1019	l2->vs = 0;1020	l2->va = 0;1021	l2->sow = 0;1022	mISDN_FsmChangeState(fi, ST_L2_7);1023	mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 4);1024	if (pr != -1)1025		l2up_create(l2, pr, 0, NULL);1026 1027	if (skb_queue_len(&l2->i_queue) && cansend(l2))1028		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);1029 1030	if (l2->tm)1031		l2_tei(l2, MDL_STATUS_UP_IND, 0);1032}1033 1034static void1035l2_released(struct FsmInst *fi, int event, void *arg)1036{1037	struct layer2 *l2 = fi->userdata;1038	struct sk_buff *skb = arg;1039 1040	if (!get_PollFlag(l2, skb)) {1041		l2_mdl_error_ua(fi, event, arg);1042		return;1043	}1044	dev_kfree_skb(skb);1045	stop_t200(l2, 6);1046	lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);1047	mISDN_FsmChangeState(fi, ST_L2_4);1048	if (l2->tm)1049		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1050}1051 1052static void1053l2_reestablish(struct FsmInst *fi, int event, void *arg)1054{1055	struct layer2 *l2 = fi->userdata;1056	struct sk_buff *skb = arg;1057 1058	if (!get_PollFlagFree(l2, skb)) {1059		establishlink(fi);1060		test_and_set_bit(FLG_L3_INIT, &l2->flag);1061	}1062}1063 1064static void1065l2_st5_dm_release(struct FsmInst *fi, int event, void *arg)1066{1067	struct layer2 *l2 = fi->userdata;1068	struct sk_buff *skb = arg;1069 1070	if (get_PollFlagFree(l2, skb)) {1071		stop_t200(l2, 7);1072		if (!test_bit(FLG_L3_INIT, &l2->flag))1073			skb_queue_purge(&l2->i_queue);1074		if (test_bit(FLG_LAPB, &l2->flag))1075			l2down_create(l2, PH_DEACTIVATE_REQ,1076				      l2_newid(l2), 0, NULL);1077		st5_dl_release_l2l3(l2);1078		mISDN_FsmChangeState(fi, ST_L2_4);1079		if (l2->tm)1080			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1081	}1082}1083 1084static void1085l2_st6_dm_release(struct FsmInst *fi, int event, void *arg)1086{1087	struct layer2 *l2 = fi->userdata;1088	struct sk_buff *skb = arg;1089 1090	if (get_PollFlagFree(l2, skb)) {1091		stop_t200(l2, 8);1092		lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);1093		mISDN_FsmChangeState(fi, ST_L2_4);1094		if (l2->tm)1095			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1096	}1097}1098 1099static void1100enquiry_cr(struct layer2 *l2, u_char typ, u_char cr, u_char pf)1101{1102	struct sk_buff *skb;1103	u_char tmp[MAX_L2HEADER_LEN];1104	int i;1105 1106	i = sethdraddr(l2, tmp, cr);1107	if (test_bit(FLG_MOD128, &l2->flag)) {1108		tmp[i++] = typ;1109		tmp[i++] = (l2->vr << 1) | (pf ? 1 : 0);1110	} else1111		tmp[i++] = (l2->vr << 5) | typ | (pf ? 0x10 : 0);1112	skb = mI_alloc_skb(i, GFP_ATOMIC);1113	if (!skb) {1114		printk(KERN_WARNING "%s: isdnl2 can't alloc sbbuff in %s\n",1115		       mISDNDevName4ch(&l2->ch), __func__);1116		return;1117	}1118	skb_put_data(skb, tmp, i);1119	enqueue_super(l2, skb);1120}1121 1122inline void1123enquiry_response(struct layer2 *l2)1124{1125	if (test_bit(FLG_OWN_BUSY, &l2->flag))1126		enquiry_cr(l2, RNR, RSP, 1);1127	else1128		enquiry_cr(l2, RR, RSP, 1);1129	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);1130}1131 1132inline void1133transmit_enquiry(struct layer2 *l2)1134{1135	if (test_bit(FLG_OWN_BUSY, &l2->flag))1136		enquiry_cr(l2, RNR, CMD, 1);1137	else1138		enquiry_cr(l2, RR, CMD, 1);1139	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);1140	start_t200(l2, 9);1141}1142 1143 1144static void1145nrerrorrecovery(struct FsmInst *fi)1146{1147	struct layer2 *l2 = fi->userdata;1148 1149	l2mgr(l2, MDL_ERROR_IND, (void *) 'J');1150	establishlink(fi);1151	test_and_clear_bit(FLG_L3_INIT, &l2->flag);1152}1153 1154static void1155invoke_retransmission(struct layer2 *l2, unsigned int nr)1156{1157	u_int	p1;1158 1159	if (l2->vs != nr) {1160		while (l2->vs != nr) {1161			(l2->vs)--;1162			if (test_bit(FLG_MOD128, &l2->flag)) {1163				l2->vs %= 128;1164				p1 = (l2->vs - l2->va) % 128;1165			} else {1166				l2->vs %= 8;1167				p1 = (l2->vs - l2->va) % 8;1168			}1169			p1 = (p1 + l2->sow) % l2->window;1170			if (l2->windowar[p1])1171				skb_queue_head(&l2->i_queue, l2->windowar[p1]);1172			else1173				printk(KERN_WARNING1174				       "%s: windowar[%d] is NULL\n",1175				       mISDNDevName4ch(&l2->ch), p1);1176			l2->windowar[p1] = NULL;1177		}1178		mISDN_FsmEvent(&l2->l2m, EV_L2_ACK_PULL, NULL);1179	}1180}1181 1182static void1183l2_st7_got_super(struct FsmInst *fi, int event, void *arg)1184{1185	struct layer2 *l2 = fi->userdata;1186	struct sk_buff *skb = arg;1187	int PollFlag, rsp, typ = RR;1188	unsigned int nr;1189 1190	rsp = *skb->data & 0x2;1191	if (test_bit(FLG_ORIG, &l2->flag))1192		rsp = !rsp;1193 1194	skb_pull(skb, l2addrsize(l2));1195	if (IsRNR(skb->data, l2)) {1196		set_peer_busy(l2);1197		typ = RNR;1198	} else1199		clear_peer_busy(l2);1200	if (IsREJ(skb->data, l2))1201		typ = REJ;1202 1203	if (test_bit(FLG_MOD128, &l2->flag)) {1204		PollFlag = (skb->data[1] & 0x1) == 0x1;1205		nr = skb->data[1] >> 1;1206	} else {1207		PollFlag = (skb->data[0] & 0x10);1208		nr = (skb->data[0] >> 5) & 0x7;1209	}1210	dev_kfree_skb(skb);1211 1212	if (PollFlag) {1213		if (rsp)1214			l2mgr(l2, MDL_ERROR_IND, (void *) 'A');1215		else1216			enquiry_response(l2);1217	}1218	if (legalnr(l2, nr)) {1219		if (typ == REJ) {1220			setva(l2, nr);1221			invoke_retransmission(l2, nr);1222			stop_t200(l2, 10);1223			if (mISDN_FsmAddTimer(&l2->t203, l2->T203,1224					      EV_L2_T203, NULL, 6))1225				l2m_debug(&l2->l2m, "Restart T203 ST7 REJ");1226		} else if ((nr == l2->vs) && (typ == RR)) {1227			setva(l2, nr);1228			stop_t200(l2, 11);1229			mISDN_FsmRestartTimer(&l2->t203, l2->T203,1230					      EV_L2_T203, NULL, 7);1231		} else if ((l2->va != nr) || (typ == RNR)) {1232			setva(l2, nr);1233			if (typ != RR)1234				mISDN_FsmDelTimer(&l2->t203, 9);1235			restart_t200(l2, 12);1236		}1237		if (skb_queue_len(&l2->i_queue) && (typ == RR))1238			mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);1239	} else1240		nrerrorrecovery(fi);1241}1242 1243static void1244l2_feed_i_if_reest(struct FsmInst *fi, int event, void *arg)1245{1246	struct layer2 *l2 = fi->userdata;1247	struct sk_buff *skb = arg;1248 1249	if (!test_bit(FLG_L3_INIT, &l2->flag))1250		skb_queue_tail(&l2->i_queue, skb);1251	else1252		dev_kfree_skb(skb);1253}1254 1255static void1256l2_feed_i_pull(struct FsmInst *fi, int event, void *arg)1257{1258	struct layer2 *l2 = fi->userdata;1259	struct sk_buff *skb = arg;1260 1261	skb_queue_tail(&l2->i_queue, skb);1262	mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);1263}1264 1265static void1266l2_feed_iqueue(struct FsmInst *fi, int event, void *arg)1267{1268	struct layer2 *l2 = fi->userdata;1269	struct sk_buff *skb = arg;1270 1271	skb_queue_tail(&l2->i_queue, skb);1272}1273 1274static void1275l2_got_iframe(struct FsmInst *fi, int event, void *arg)1276{1277	struct layer2	*l2 = fi->userdata;1278	struct sk_buff	*skb = arg;1279	int		PollFlag, i;1280	u_int		ns, nr;1281 1282	i = l2addrsize(l2);1283	if (test_bit(FLG_MOD128, &l2->flag)) {1284		PollFlag = ((skb->data[i + 1] & 0x1) == 0x1);1285		ns = skb->data[i] >> 1;1286		nr = (skb->data[i + 1] >> 1) & 0x7f;1287	} else {1288		PollFlag = (skb->data[i] & 0x10);1289		ns = (skb->data[i] >> 1) & 0x7;1290		nr = (skb->data[i] >> 5) & 0x7;1291	}1292	if (test_bit(FLG_OWN_BUSY, &l2->flag)) {1293		dev_kfree_skb(skb);1294		if (PollFlag)1295			enquiry_response(l2);1296	} else {1297		if (l2->vr == ns) {1298			l2->vr++;1299			if (test_bit(FLG_MOD128, &l2->flag))1300				l2->vr %= 128;1301			else1302				l2->vr %= 8;1303			test_and_clear_bit(FLG_REJEXC, &l2->flag);1304			if (PollFlag)1305				enquiry_response(l2);1306			else1307				test_and_set_bit(FLG_ACK_PEND, &l2->flag);1308			skb_pull(skb, l2headersize(l2, 0));1309			l2up(l2, DL_DATA_IND, skb);1310		} else {1311			/* n(s)!=v(r) */1312			dev_kfree_skb(skb);1313			if (test_and_set_bit(FLG_REJEXC, &l2->flag)) {1314				if (PollFlag)1315					enquiry_response(l2);1316			} else {1317				enquiry_cr(l2, REJ, RSP, PollFlag);1318				test_and_clear_bit(FLG_ACK_PEND, &l2->flag);1319			}1320		}1321	}1322	if (legalnr(l2, nr)) {1323		if (!test_bit(FLG_PEER_BUSY, &l2->flag) &&1324		    (fi->state == ST_L2_7)) {1325			if (nr == l2->vs) {1326				stop_t200(l2, 13);1327				mISDN_FsmRestartTimer(&l2->t203, l2->T203,1328						      EV_L2_T203, NULL, 7);1329			} else if (nr != l2->va)1330				restart_t200(l2, 14);1331		}1332		setva(l2, nr);1333	} else {1334		nrerrorrecovery(fi);1335		return;1336	}1337	if (skb_queue_len(&l2->i_queue) && (fi->state == ST_L2_7))1338		mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);1339	if (test_and_clear_bit(FLG_ACK_PEND, &l2->flag))1340		enquiry_cr(l2, RR, RSP, 0);1341}1342 1343static void1344l2_got_tei(struct FsmInst *fi, int event, void *arg)1345{1346	struct layer2	*l2 = fi->userdata;1347	u_int		info;1348 1349	l2->tei = (signed char)(long)arg;1350	set_channel_address(&l2->ch, l2->sapi, l2->tei);1351	info = DL_INFO_L2_CONNECT;1352	l2up_create(l2, DL_INFORMATION_IND, sizeof(info), &info);1353	if (fi->state == ST_L2_3) {1354		establishlink(fi);1355		test_and_set_bit(FLG_L3_INIT, &l2->flag);1356	} else1357		mISDN_FsmChangeState(fi, ST_L2_4);1358	if (skb_queue_len(&l2->ui_queue))1359		tx_ui(l2);1360}1361 1362static void1363l2_st5_tout_200(struct FsmInst *fi, int event, void *arg)1364{1365	struct layer2 *l2 = fi->userdata;1366 1367	if (test_bit(FLG_LAPD, &l2->flag) &&1368	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {1369		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);1370	} else if (l2->rc == l2->N200) {1371		mISDN_FsmChangeState(fi, ST_L2_4);1372		test_and_clear_bit(FLG_T200_RUN, &l2->flag);1373		skb_queue_purge(&l2->i_queue);1374		l2mgr(l2, MDL_ERROR_IND, (void *) 'G');1375		if (test_bit(FLG_LAPB, &l2->flag))1376			l2down_create(l2, PH_DEACTIVATE_REQ,1377				      l2_newid(l2), 0, NULL);1378		st5_dl_release_l2l3(l2);1379		if (l2->tm)1380			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1381	} else {1382		l2->rc++;1383		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);1384		send_uframe(l2, NULL, (test_bit(FLG_MOD128, &l2->flag) ?1385				       SABME : SABM) | 0x10, CMD);1386	}1387}1388 1389static void1390l2_st6_tout_200(struct FsmInst *fi, int event, void *arg)1391{1392	struct layer2 *l2 = fi->userdata;1393 1394	if (test_bit(FLG_LAPD, &l2->flag) &&1395	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {1396		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);1397	} else if (l2->rc == l2->N200) {1398		mISDN_FsmChangeState(fi, ST_L2_4);1399		test_and_clear_bit(FLG_T200_RUN, &l2->flag);1400		l2mgr(l2, MDL_ERROR_IND, (void *) 'H');1401		lapb_dl_release_l2l3(l2, DL_RELEASE_CNF);1402		if (l2->tm)1403			l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1404	} else {1405		l2->rc++;1406		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200,1407				  NULL, 9);1408		send_uframe(l2, NULL, DISC | 0x10, CMD);1409	}1410}1411 1412static void1413l2_st7_tout_200(struct FsmInst *fi, int event, void *arg)1414{1415	struct layer2 *l2 = fi->userdata;1416 1417	if (test_bit(FLG_LAPD, &l2->flag) &&1418	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {1419		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);1420		return;1421	}1422	test_and_clear_bit(FLG_T200_RUN, &l2->flag);1423	l2->rc = 0;1424	mISDN_FsmChangeState(fi, ST_L2_8);1425	transmit_enquiry(l2);1426	l2->rc++;1427}1428 1429static void1430l2_st8_tout_200(struct FsmInst *fi, int event, void *arg)1431{1432	struct layer2 *l2 = fi->userdata;1433 1434	if (test_bit(FLG_LAPD, &l2->flag) &&1435	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {1436		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 9);1437		return;1438	}1439	test_and_clear_bit(FLG_T200_RUN, &l2->flag);1440	if (l2->rc == l2->N200) {1441		l2mgr(l2, MDL_ERROR_IND, (void *) 'I');1442		establishlink(fi);1443		test_and_clear_bit(FLG_L3_INIT, &l2->flag);1444	} else {1445		transmit_enquiry(l2);1446		l2->rc++;1447	}1448}1449 1450static void1451l2_st7_tout_203(struct FsmInst *fi, int event, void *arg)1452{1453	struct layer2 *l2 = fi->userdata;1454 1455	if (test_bit(FLG_LAPD, &l2->flag) &&1456	    test_bit(FLG_DCHAN_BUSY, &l2->flag)) {1457		mISDN_FsmAddTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 9);1458		return;1459	}1460	mISDN_FsmChangeState(fi, ST_L2_8);1461	transmit_enquiry(l2);1462	l2->rc = 0;1463}1464 1465static void1466l2_pull_iqueue(struct FsmInst *fi, int event, void *arg)1467{1468	struct layer2	*l2 = fi->userdata;1469	struct sk_buff	*skb, *nskb;1470	u_char		header[MAX_L2HEADER_LEN];1471	u_int		i, p1;1472 1473	if (!cansend(l2))1474		return;1475 1476	skb = skb_dequeue(&l2->i_queue);1477	if (!skb)1478		return;1479	i = sethdraddr(l2, header, CMD);1480	if (test_bit(FLG_MOD128, &l2->flag)) {1481		header[i++] = l2->vs << 1;1482		header[i++] = l2->vr << 1;1483	} else1484		header[i++] = (l2->vr << 5) | (l2->vs << 1);1485	nskb = skb_realloc_headroom(skb, i);1486	if (!nskb) {1487		printk(KERN_WARNING "%s: no headroom(%d) copy for IFrame\n",1488		       mISDNDevName4ch(&l2->ch), i);1489		skb_queue_head(&l2->i_queue, skb);1490		return;1491	}1492	if (test_bit(FLG_MOD128, &l2->flag)) {1493		p1 = (l2->vs - l2->va) % 128;1494		l2->vs = (l2->vs + 1) % 128;1495	} else {1496		p1 = (l2->vs - l2->va) % 8;1497		l2->vs = (l2->vs + 1) % 8;1498	}1499	p1 = (p1 + l2->sow) % l2->window;1500	if (l2->windowar[p1]) {1501		printk(KERN_WARNING "%s: l2 try overwrite ack queue entry %d\n",1502		       mISDNDevName4ch(&l2->ch), p1);1503		dev_kfree_skb(l2->windowar[p1]);1504	}1505	l2->windowar[p1] = skb;1506	memcpy(skb_push(nskb, i), header, i);1507	l2down(l2, PH_DATA_REQ, l2_newid(l2), nskb);1508	test_and_clear_bit(FLG_ACK_PEND, &l2->flag);1509	if (!test_and_set_bit(FLG_T200_RUN, &l2->flag)) {1510		mISDN_FsmDelTimer(&l2->t203, 13);1511		mISDN_FsmAddTimer(&l2->t200, l2->T200, EV_L2_T200, NULL, 11);1512	}1513}1514 1515static void1516l2_st8_got_super(struct FsmInst *fi, int event, void *arg)1517{1518	struct layer2 *l2 = fi->userdata;1519	struct sk_buff *skb = arg;1520	int PollFlag, rsp, rnr = 0;1521	unsigned int nr;1522 1523	rsp = *skb->data & 0x2;1524	if (test_bit(FLG_ORIG, &l2->flag))1525		rsp = !rsp;1526 1527	skb_pull(skb, l2addrsize(l2));1528 1529	if (IsRNR(skb->data, l2)) {1530		set_peer_busy(l2);1531		rnr = 1;1532	} else1533		clear_peer_busy(l2);1534 1535	if (test_bit(FLG_MOD128, &l2->flag)) {1536		PollFlag = (skb->data[1] & 0x1) == 0x1;1537		nr = skb->data[1] >> 1;1538	} else {1539		PollFlag = (skb->data[0] & 0x10);1540		nr = (skb->data[0] >> 5) & 0x7;1541	}1542	dev_kfree_skb(skb);1543	if (rsp && PollFlag) {1544		if (legalnr(l2, nr)) {1545			if (rnr) {1546				restart_t200(l2, 15);1547			} else {1548				stop_t200(l2, 16);1549				mISDN_FsmAddTimer(&l2->t203, l2->T203,1550						  EV_L2_T203, NULL, 5);1551				setva(l2, nr);1552			}1553			invoke_retransmission(l2, nr);1554			mISDN_FsmChangeState(fi, ST_L2_7);1555			if (skb_queue_len(&l2->i_queue) && cansend(l2))1556				mISDN_FsmEvent(fi, EV_L2_ACK_PULL, NULL);1557		} else1558			nrerrorrecovery(fi);1559	} else {1560		if (!rsp && PollFlag)1561			enquiry_response(l2);1562		if (legalnr(l2, nr))1563			setva(l2, nr);1564		else1565			nrerrorrecovery(fi);1566	}1567}1568 1569static void1570l2_got_FRMR(struct FsmInst *fi, int event, void *arg)1571{1572	struct layer2 *l2 = fi->userdata;1573	struct sk_buff *skb = arg;1574 1575	skb_pull(skb, l2addrsize(l2) + 1);1576 1577	if (!(skb->data[0] & 1) || ((skb->data[0] & 3) == 1) || /* I or S */1578	    (IsUA(skb->data) && (fi->state == ST_L2_7))) {1579		l2mgr(l2, MDL_ERROR_IND, (void *) 'K');1580		establishlink(fi);1581		test_and_clear_bit(FLG_L3_INIT, &l2->flag);1582	}1583	dev_kfree_skb(skb);1584}1585 1586static void1587l2_st24_tei_remove(struct FsmInst *fi, int event, void *arg)1588{1589	struct layer2 *l2 = fi->userdata;1590 1591	skb_queue_purge(&l2->ui_queue);1592	l2->tei = GROUP_TEI;1593	mISDN_FsmChangeState(fi, ST_L2_1);1594}1595 1596static void1597l2_st3_tei_remove(struct FsmInst *fi, int event, void *arg)1598{1599	struct layer2 *l2 = fi->userdata;1600 1601	skb_queue_purge(&l2->ui_queue);1602	l2->tei = GROUP_TEI;1603	l2up_create(l2, DL_RELEASE_IND, 0, NULL);1604	mISDN_FsmChangeState(fi, ST_L2_1);1605}1606 1607static void1608l2_st5_tei_remove(struct FsmInst *fi, int event, void *arg)1609{1610	struct layer2 *l2 = fi->userdata;1611 1612	skb_queue_purge(&l2->i_queue);1613	skb_queue_purge(&l2->ui_queue);1614	freewin(l2);1615	l2->tei = GROUP_TEI;1616	stop_t200(l2, 17);1617	st5_dl_release_l2l3(l2);1618	mISDN_FsmChangeState(fi, ST_L2_1);1619}1620 1621static void1622l2_st6_tei_remove(struct FsmInst *fi, int event, void *arg)1623{1624	struct layer2 *l2 = fi->userdata;1625 1626	skb_queue_purge(&l2->ui_queue);1627	l2->tei = GROUP_TEI;1628	stop_t200(l2, 18);1629	l2up_create(l2, DL_RELEASE_IND, 0, NULL);1630	mISDN_FsmChangeState(fi, ST_L2_1);1631}1632 1633static void1634l2_tei_remove(struct FsmInst *fi, int event, void *arg)1635{1636	struct layer2 *l2 = fi->userdata;1637 1638	skb_queue_purge(&l2->i_queue);1639	skb_queue_purge(&l2->ui_queue);1640	freewin(l2);1641	l2->tei = GROUP_TEI;1642	stop_t200(l2, 17);1643	mISDN_FsmDelTimer(&l2->t203, 19);1644	l2up_create(l2, DL_RELEASE_IND, 0, NULL);1645/*	mISDN_queue_data(&l2->inst, l2->inst.id | MSG_BROADCAST,1646 *		MGR_SHORTSTATUS_IND, SSTATUS_L2_RELEASED,1647 *		0, NULL, 0);1648 */1649	mISDN_FsmChangeState(fi, ST_L2_1);1650}1651 1652static void1653l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)1654{1655	struct layer2 *l2 = fi->userdata;1656	struct sk_buff *skb = arg;1657 1658	skb_queue_purge(&l2->i_queue);1659	skb_queue_purge(&l2->ui_queue);1660	if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))1661		l2up(l2, DL_RELEASE_IND, skb);1662	else1663		dev_kfree_skb(skb);1664}1665 1666static void1667l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)1668{1669	struct layer2 *l2 = fi->userdata;1670	struct sk_buff *skb = arg;1671 1672	skb_queue_purge(&l2->i_queue);1673	skb_queue_purge(&l2->ui_queue);1674	freewin(l2);1675	stop_t200(l2, 19);1676	st5_dl_release_l2l3(l2);1677	mISDN_FsmChangeState(fi, ST_L2_4);1678	if (l2->tm)1679		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1680	dev_kfree_skb(skb);1681}1682 1683static void1684l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)1685{1686	struct layer2 *l2 = fi->userdata;1687	struct sk_buff *skb = arg;1688 1689	skb_queue_purge(&l2->ui_queue);1690	stop_t200(l2, 20);1691	l2up(l2, DL_RELEASE_CNF, skb);1692	mISDN_FsmChangeState(fi, ST_L2_4);1693	if (l2->tm)1694		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1695}1696 1697static void1698l2_persistent_da(struct FsmInst *fi, int event, void *arg)1699{1700	struct layer2 *l2 = fi->userdata;1701	struct sk_buff *skb = arg;1702 1703	skb_queue_purge(&l2->i_queue);1704	skb_queue_purge(&l2->ui_queue);1705	freewin(l2);1706	stop_t200(l2, 19);1707	mISDN_FsmDelTimer(&l2->t203, 19);1708	l2up(l2, DL_RELEASE_IND, skb);1709	mISDN_FsmChangeState(fi, ST_L2_4);1710	if (l2->tm)1711		l2_tei(l2, MDL_STATUS_DOWN_IND, 0);1712}1713 1714static void1715l2_set_own_busy(struct FsmInst *fi, int event, void *arg)1716{1717	struct layer2 *l2 = fi->userdata;1718	struct sk_buff *skb = arg;1719 1720	if (!test_and_set_bit(FLG_OWN_BUSY, &l2->flag)) {1721		enquiry_cr(l2, RNR, RSP, 0);1722		test_and_clear_bit(FLG_ACK_PEND, &l2->flag);1723	}1724	dev_kfree_skb(skb);1725}1726 1727static void1728l2_clear_own_busy(struct FsmInst *fi, int event, void *arg)1729{1730	struct layer2 *l2 = fi->userdata;1731	struct sk_buff *skb = arg;1732 1733	if (!test_and_clear_bit(FLG_OWN_BUSY, &l2->flag)) {1734		enquiry_cr(l2, RR, RSP, 0);1735		test_and_clear_bit(FLG_ACK_PEND, &l2->flag);1736	}1737	dev_kfree_skb(skb);1738}1739 1740static void1741l2_frame_error(struct FsmInst *fi, int event, void *arg)1742{1743	struct layer2 *l2 = fi->userdata;1744 1745	l2mgr(l2, MDL_ERROR_IND, arg);1746}1747 1748static void1749l2_frame_error_reest(struct FsmInst *fi, int event, void *arg)1750{1751	struct layer2 *l2 = fi->userdata;1752 1753	l2mgr(l2, MDL_ERROR_IND, arg);1754	establishlink(fi);1755	test_and_clear_bit(FLG_L3_INIT, &l2->flag);1756}1757 1758static struct FsmNode L2FnList[] =1759{1760	{ST_L2_1, EV_L2_DL_ESTABLISH_REQ, l2_mdl_assign},1761	{ST_L2_2, EV_L2_DL_ESTABLISH_REQ, l2_go_st3},1762	{ST_L2_4, EV_L2_DL_ESTABLISH_REQ, l2_establish},1763	{ST_L2_5, EV_L2_DL_ESTABLISH_REQ, l2_discard_i_setl3},1764	{ST_L2_7, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},1765	{ST_L2_8, EV_L2_DL_ESTABLISH_REQ, l2_l3_reestablish},1766	{ST_L2_4, EV_L2_DL_RELEASE_REQ, l2_release},1767	{ST_L2_5, EV_L2_DL_RELEASE_REQ, l2_pend_rel},1768	{ST_L2_7, EV_L2_DL_RELEASE_REQ, l2_disconnect},1769	{ST_L2_8, EV_L2_DL_RELEASE_REQ, l2_disconnect},1770	{ST_L2_5, EV_L2_DL_DATA, l2_feed_i_if_reest},1771	{ST_L2_7, EV_L2_DL_DATA, l2_feed_i_pull},1772	{ST_L2_8, EV_L2_DL_DATA, l2_feed_iqueue},1773	{ST_L2_1, EV_L2_DL_UNITDATA, l2_queue_ui_assign},1774	{ST_L2_2, EV_L2_DL_UNITDATA, l2_queue_ui},1775	{ST_L2_3, EV_L2_DL_UNITDATA, l2_queue_ui},1776	{ST_L2_4, EV_L2_DL_UNITDATA, l2_send_ui},1777	{ST_L2_5, EV_L2_DL_UNITDATA, l2_send_ui},1778	{ST_L2_6, EV_L2_DL_UNITDATA, l2_send_ui},1779	{ST_L2_7, EV_L2_DL_UNITDATA, l2_send_ui},1780	{ST_L2_8, EV_L2_DL_UNITDATA, l2_send_ui},1781	{ST_L2_1, EV_L2_MDL_ASSIGN, l2_got_tei},1782	{ST_L2_2, EV_L2_MDL_ASSIGN, l2_got_tei},1783	{ST_L2_3, EV_L2_MDL_ASSIGN, l2_got_tei},1784	{ST_L2_2, EV_L2_MDL_ERROR, l2_st24_tei_remove},1785	{ST_L2_3, EV_L2_MDL_ERROR, l2_st3_tei_remove},1786	{ST_L2_4, EV_L2_MDL_REMOVE, l2_st24_tei_remove},1787	{ST_L2_5, EV_L2_MDL_REMOVE, l2_st5_tei_remove},1788	{ST_L2_6, EV_L2_MDL_REMOVE, l2_st6_tei_remove},1789	{ST_L2_7, EV_L2_MDL_REMOVE, l2_tei_remove},1790	{ST_L2_8, EV_L2_MDL_REMOVE, l2_tei_remove},1791	{ST_L2_4, EV_L2_SABME, l2_start_multi},1792	{ST_L2_5, EV_L2_SABME, l2_send_UA},1793	{ST_L2_6, EV_L2_SABME, l2_send_DM},1794	{ST_L2_7, EV_L2_SABME, l2_restart_multi},1795	{ST_L2_8, EV_L2_SABME, l2_restart_multi},1796	{ST_L2_4, EV_L2_DISC, l2_send_DM},1797	{ST_L2_5, EV_L2_DISC, l2_send_DM},1798	{ST_L2_6, EV_L2_DISC, l2_send_UA},1799	{ST_L2_7, EV_L2_DISC, l2_stop_multi},1800	{ST_L2_8, EV_L2_DISC, l2_stop_multi},1801	{ST_L2_4, EV_L2_UA, l2_mdl_error_ua},1802	{ST_L2_5, EV_L2_UA, l2_connected},1803	{ST_L2_6, EV_L2_UA, l2_released},1804	{ST_L2_7, EV_L2_UA, l2_mdl_error_ua},1805	{ST_L2_8, EV_L2_UA, l2_mdl_error_ua},1806	{ST_L2_4, EV_L2_DM, l2_reestablish},1807	{ST_L2_5, EV_L2_DM, l2_st5_dm_release},1808	{ST_L2_6, EV_L2_DM, l2_st6_dm_release},1809	{ST_L2_7, EV_L2_DM, l2_mdl_error_dm},1810	{ST_L2_8, EV_L2_DM, l2_st8_mdl_error_dm},1811	{ST_L2_1, EV_L2_UI, l2_got_ui},1812	{ST_L2_2, EV_L2_UI, l2_got_ui},1813	{ST_L2_3, EV_L2_UI, l2_got_ui},1814	{ST_L2_4, EV_L2_UI, l2_got_ui},1815	{ST_L2_5, EV_L2_UI, l2_got_ui},1816	{ST_L2_6, EV_L2_UI, l2_got_ui},1817	{ST_L2_7, EV_L2_UI, l2_got_ui},1818	{ST_L2_8, EV_L2_UI, l2_got_ui},1819	{ST_L2_7, EV_L2_FRMR, l2_got_FRMR},1820	{ST_L2_8, EV_L2_FRMR, l2_got_FRMR},1821	{ST_L2_7, EV_L2_SUPER, l2_st7_got_super},1822	{ST_L2_8, EV_L2_SUPER, l2_st8_got_super},1823	{ST_L2_7, EV_L2_I, l2_got_iframe},1824	{ST_L2_8, EV_L2_I, l2_got_iframe},1825	{ST_L2_5, EV_L2_T200, l2_timeout},1826	{ST_L2_6, EV_L2_T200, l2_timeout},1827	{ST_L2_7, EV_L2_T200, l2_timeout},1828	{ST_L2_8, EV_L2_T200, l2_timeout},1829	{ST_L2_7, EV_L2_T203, l2_timeout},1830	{ST_L2_5, EV_L2_T200I, l2_st5_tout_200},1831	{ST_L2_6, EV_L2_T200I, l2_st6_tout_200},1832	{ST_L2_7, EV_L2_T200I, l2_st7_tout_200},1833	{ST_L2_8, EV_L2_T200I, l2_st8_tout_200},1834	{ST_L2_7, EV_L2_T203I, l2_st7_tout_203},1835	{ST_L2_7, EV_L2_ACK_PULL, l2_pull_iqueue},1836	{ST_L2_7, EV_L2_SET_OWN_BUSY, l2_set_own_busy},1837	{ST_L2_8, EV_L2_SET_OWN_BUSY, l2_set_own_busy},1838	{ST_L2_7, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},1839	{ST_L2_8, EV_L2_CLEAR_OWN_BUSY, l2_clear_own_busy},1840	{ST_L2_4, EV_L2_FRAME_ERROR, l2_frame_error},1841	{ST_L2_5, EV_L2_FRAME_ERROR, l2_frame_error},1842	{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},1843	{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},1844	{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},1845	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},1846	{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},1847	{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},1848	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},1849	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},1850	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},1851	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},1852	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},1853};1854 1855static int1856ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)1857{1858	u_char	*datap = skb->data;1859	int	ret = -EINVAL;1860	int	psapi, ptei;1861	u_int	l;1862	int	c = 0;1863 1864	l = l2addrsize(l2);1865	if (skb->len <= l) {1866		mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');1867		return ret;1868	}1869	if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */1870		psapi = *datap++;1871		ptei = *datap++;1872		if ((psapi & 1) || !(ptei & 1)) {1873			printk(KERN_WARNING1874			       "%s l2 D-channel frame wrong EA0/EA1\n",1875			       mISDNDevName4ch(&l2->ch));1876			return ret;1877		}1878		psapi >>= 2;1879		ptei >>= 1;1880		if (psapi != l2->sapi) {1881			/* not our business */1882			if (*debug & DEBUG_L2)1883				printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",1884				       mISDNDevName4ch(&l2->ch), psapi,1885				       l2->sapi);1886			dev_kfree_skb(skb);1887			return 0;1888		}1889		if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {1890			/* not our business */1891			if (*debug & DEBUG_L2)1892				printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",1893				       mISDNDevName4ch(&l2->ch), ptei, l2->tei);1894			dev_kfree_skb(skb);1895			return 0;1896		}1897	} else1898		datap += l;1899	if (!(*datap & 1)) {	/* I-Frame */1900		c = iframe_error(l2, skb);1901		if (!c)1902			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_I, skb);1903	} else if (IsSFrame(datap, l2)) {	/* S-Frame */1904		c = super_error(l2, skb);1905		if (!c)1906			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SUPER, skb);1907	} else if (IsUI(datap)) {1908		c = UI_error(l2, skb);1909		if (!c)1910			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);1911	} else if (IsSABME(datap, l2)) {1912		c = unnum_error(l2, skb, CMD);1913		if (!c)1914			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);1915	} else if (IsUA(datap)) {1916		c = unnum_error(l2, skb, RSP);1917		if (!c)1918			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UA, skb);1919	} else if (IsDISC(datap)) {1920		c = unnum_error(l2, skb, CMD);1921		if (!c)1922			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DISC, skb);1923	} else if (IsDM(datap)) {1924		c = unnum_error(l2, skb, RSP);1925		if (!c)1926			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DM, skb);1927	} else if (IsFRMR(datap)) {1928		c = FRMR_error(l2, skb);1929		if (!c)1930			ret = mISDN_FsmEvent(&l2->l2m, EV_L2_FRMR, skb);1931	} else1932		c = 'L';1933	if (c) {1934		printk(KERN_WARNING "%s:l2 D-channel frame error %c\n",1935		       mISDNDevName4ch(&l2->ch), c);1936		mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *)(long)c);1937	}1938	return ret;1939}1940 1941static int1942l2_send(struct mISDNchannel *ch, struct sk_buff *skb)1943{1944	struct layer2		*l2 = container_of(ch, struct layer2, ch);1945	struct mISDNhead	*hh =  mISDN_HEAD_P(skb);1946	int			ret = -EINVAL;1947 1948	if (*debug & DEBUG_L2_RECV)1949		printk(KERN_DEBUG "%s: %s prim(%x) id(%x) sapi(%d) tei(%d)\n",1950		       __func__, mISDNDevName4ch(&l2->ch), hh->prim, hh->id,1951		       l2->sapi, l2->tei);1952	if (hh->prim == DL_INTERN_MSG) {1953		struct mISDNhead *chh = hh + 1; /* saved copy */1954 1955		*hh = *chh;1956		if (*debug & DEBUG_L2_RECV)1957			printk(KERN_DEBUG "%s: prim(%x) id(%x) internal msg\n",1958				mISDNDevName4ch(&l2->ch), hh->prim, hh->id);1959	}1960	switch (hh->prim) {1961	case PH_DATA_IND:1962		ret = ph_data_indication(l2, hh, skb);1963		break;1964	case PH_DATA_CNF:1965		ret = ph_data_confirm(l2, hh, skb);1966		break;1967	case PH_ACTIVATE_IND:1968		test_and_set_bit(FLG_L1_ACTIV, &l2->flag);1969		l2up_create(l2, MPH_ACTIVATE_IND, 0, NULL);1970		if (test_and_clear_bit(FLG_ESTAB_PEND, &l2->flag))1971			ret = mISDN_FsmEvent(&l2->l2m,1972					     EV_L2_DL_ESTABLISH_REQ, skb);1973		break;1974	case PH_DEACTIVATE_IND:1975		test_and_clear_bit(FLG_L1_ACTIV, &l2->flag);1976		l2up_create(l2, MPH_DEACTIVATE_IND, 0, NULL);1977		ret = mISDN_FsmEvent(&l2->l2m, EV_L1_DEACTIVATE, skb);1978		break;1979	case MPH_INFORMATION_IND:1980		if (!l2->up)1981			break;1982		ret = l2->up->send(l2->up, skb);1983		break;1984	case DL_DATA_REQ:1985		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_DATA, skb);1986		break;1987	case DL_UNITDATA_REQ:1988		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_UNITDATA, skb);1989		break;1990	case DL_ESTABLISH_REQ:1991		if (test_bit(FLG_LAPB, &l2->flag))1992			test_and_set_bit(FLG_ORIG, &l2->flag);1993		if (test_bit(FLG_L1_ACTIV, &l2->flag)) {1994			if (test_bit(FLG_LAPD, &l2->flag) ||1995			    test_bit(FLG_ORIG, &l2->flag))1996				ret = mISDN_FsmEvent(&l2->l2m,1997						     EV_L2_DL_ESTABLISH_REQ, skb);1998		} else {1999			if (test_bit(FLG_LAPD, &l2->flag) ||2000			    test_bit(FLG_ORIG, &l2->flag)) {2001				test_and_set_bit(FLG_ESTAB_PEND,2002						 &l2->flag);2003			}2004			ret = l2down(l2, PH_ACTIVATE_REQ, l2_newid(l2),2005				     skb);2006		}2007		break;2008	case DL_RELEASE_REQ:2009		if (test_bit(FLG_LAPB, &l2->flag))2010			l2down_create(l2, PH_DEACTIVATE_REQ,2011				      l2_newid(l2), 0, NULL);2012		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_DL_RELEASE_REQ,2013				     skb);2014		break;2015	case DL_TIMER200_IND:2016		mISDN_FsmEvent(&l2->l2m, EV_L2_T200I, NULL);2017		break;2018	case DL_TIMER203_IND:2019		mISDN_FsmEvent(&l2->l2m, EV_L2_T203I, NULL);2020		break;2021	default:2022		if (*debug & DEBUG_L2)2023			l2m_debug(&l2->l2m, "l2 unknown pr %04x",2024				  hh->prim);2025	}2026	if (ret) {2027		dev_kfree_skb(skb);2028		ret = 0;2029	}2030	return ret;2031}2032 2033int2034tei_l2(struct layer2 *l2, u_int cmd, u_long arg)2035{2036	int		ret = -EINVAL;2037 2038	if (*debug & DEBUG_L2_TEI)2039		printk(KERN_DEBUG "%s: cmd(%x) in %s\n",2040		       mISDNDevName4ch(&l2->ch), cmd, __func__);2041	switch (cmd) {2042	case (MDL_ASSIGN_REQ):2043		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ASSIGN, (void *)arg);2044		break;2045	case (MDL_REMOVE_REQ):2046		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_REMOVE, NULL);2047		break;2048	case (MDL_ERROR_IND):2049		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);2050		break;2051	case (MDL_ERROR_RSP):2052		/* ETS 300-125 5.3.2.1 Test: TC13010 */2053		printk(KERN_NOTICE "%s: MDL_ERROR|REQ (tei_l2)\n",2054		       mISDNDevName4ch(&l2->ch));2055		ret = mISDN_FsmEvent(&l2->l2m, EV_L2_MDL_ERROR, NULL);2056		break;2057	}2058	return ret;2059}2060 2061static void2062release_l2(struct layer2 *l2)2063{2064	mISDN_FsmDelTimer(&l2->t200, 21);2065	mISDN_FsmDelTimer(&l2->t203, 16);2066	skb_queue_purge(&l2->i_queue);2067	skb_queue_purge(&l2->ui_queue);2068	skb_queue_purge(&l2->down_queue);2069	ReleaseWin(l2);2070	if (test_bit(FLG_LAPD, &l2->flag)) {2071		TEIrelease(l2);2072		if (l2->ch.st)2073			l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D,2074					       CLOSE_CHANNEL, NULL);2075	}2076	kfree(l2);2077}2078 2079static int2080l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)2081{2082	struct layer2		*l2 = container_of(ch, struct layer2, ch);2083	u_int			info;2084 2085	if (*debug & DEBUG_L2_CTRL)2086		printk(KERN_DEBUG "%s: %s cmd(%x)\n",2087		       mISDNDevName4ch(ch), __func__, cmd);2088 2089	switch (cmd) {2090	case OPEN_CHANNEL:2091		if (test_bit(FLG_LAPD, &l2->flag)) {2092			set_channel_address(&l2->ch, l2->sapi, l2->tei);2093			info = DL_INFO_L2_CONNECT;2094			l2up_create(l2, DL_INFORMATION_IND,2095				    sizeof(info), &info);2096		}2097		break;2098	case CLOSE_CHANNEL:2099		if (l2->ch.peer)2100			l2->ch.peer->ctrl(l2->ch.peer, CLOSE_CHANNEL, NULL);2101		release_l2(l2);2102		break;2103	}2104	return 0;2105}2106 2107struct layer2 *2108create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,2109	  int sapi)2110{2111	struct layer2		*l2;2112	struct channel_req	rq;2113 2114	l2 = kzalloc(sizeof(struct layer2), GFP_KERNEL);2115	if (!l2) {2116		printk(KERN_ERR "kzalloc layer2 failed\n");2117		return NULL;2118	}2119	l2->next_id = 1;2120	l2->down_id = MISDN_ID_NONE;2121	l2->up = ch;2122	l2->ch.st = ch->st;2123	l2->ch.send = l2_send;2124	l2->ch.ctrl = l2_ctrl;2125	switch (protocol) {2126	case ISDN_P_LAPD_NT:2127		test_and_set_bit(FLG_LAPD, &l2->flag);2128		test_and_set_bit(FLG_LAPD_NET, &l2->flag);2129		test_and_set_bit(FLG_MOD128, &l2->flag);2130		l2->sapi = sapi;2131		l2->maxlen = MAX_DFRAME_LEN;2132		if (test_bit(OPTION_L2_PMX, &options))2133			l2->window = 7;2134		else2135			l2->window = 1;2136		if (test_bit(OPTION_L2_PTP, &options))2137			test_and_set_bit(FLG_PTP, &l2->flag);2138		if (test_bit(OPTION_L2_FIXEDTEI, &options))2139			test_and_set_bit(FLG_FIXED_TEI, &l2->flag);2140		l2->tei = tei;2141		l2->T200 = 1000;2142		l2->N200 = 3;2143		l2->T203 = 10000;2144		if (test_bit(OPTION_L2_PMX, &options))2145			rq.protocol = ISDN_P_NT_E1;2146		else2147			rq.protocol = ISDN_P_NT_S0;2148		rq.adr.channel = 0;2149		l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);2150		break;2151	case ISDN_P_LAPD_TE:2152		test_and_set_bit(FLG_LAPD, &l2->flag);2153		test_and_set_bit(FLG_MOD128, &l2->flag);2154		test_and_set_bit(FLG_ORIG, &l2->flag);2155		l2->sapi = sapi;2156		l2->maxlen = MAX_DFRAME_LEN;2157		if (test_bit(OPTION_L2_PMX, &options))2158			l2->window = 7;2159		else2160			l2->window = 1;2161		if (test_bit(OPTION_L2_PTP, &options))2162			test_and_set_bit(FLG_PTP, &l2->flag);2163		if (test_bit(OPTION_L2_FIXEDTEI, &options))2164			test_and_set_bit(FLG_FIXED_TEI, &l2->flag);2165		l2->tei = tei;2166		l2->T200 = 1000;2167		l2->N200 = 3;2168		l2->T203 = 10000;2169		if (test_bit(OPTION_L2_PMX, &options))2170			rq.protocol = ISDN_P_TE_E1;2171		else2172			rq.protocol = ISDN_P_TE_S0;2173		rq.adr.channel = 0;2174		l2->ch.st->dev->D.ctrl(&l2->ch.st->dev->D, OPEN_CHANNEL, &rq);2175		break;2176	case ISDN_P_B_X75SLP:2177		test_and_set_bit(FLG_LAPB, &l2->flag);2178		l2->window = 7;2179		l2->maxlen = MAX_DATA_SIZE;2180		l2->T200 = 1000;2181		l2->N200 = 4;2182		l2->T203 = 5000;2183		l2->addr.A = 3;2184		l2->addr.B = 1;2185		break;2186	default:2187		printk(KERN_ERR "layer2 create failed prt %x\n",2188		       protocol);2189		kfree(l2);2190		return NULL;2191	}2192	skb_queue_head_init(&l2->i_queue);2193	skb_queue_head_init(&l2->ui_queue);2194	skb_queue_head_init(&l2->down_queue);2195	skb_queue_head_init(&l2->tmp_queue);2196	InitWin(l2);2197	l2->l2m.fsm = &l2fsm;2198	if (test_bit(FLG_LAPB, &l2->flag) ||2199	    test_bit(FLG_FIXED_TEI, &l2->flag) ||2200	    test_bit(FLG_LAPD_NET, &l2->flag))2201		l2->l2m.state = ST_L2_4;2202	else2203		l2->l2m.state = ST_L2_1;2204	l2->l2m.debug = *debug;2205	l2->l2m.userdata = l2;2206	l2->l2m.userint = 0;2207	l2->l2m.printdebug = l2m_debug;2208 2209	mISDN_FsmInitTimer(&l2->l2m, &l2->t200);2210	mISDN_FsmInitTimer(&l2->l2m, &l2->t203);2211	return l2;2212}2213 2214static int2215x75create(struct channel_req *crq)2216{2217	struct layer2	*l2;2218 2219	if (crq->protocol != ISDN_P_B_X75SLP)2220		return -EPROTONOSUPPORT;2221	l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);2222	if (!l2)2223		return -ENOMEM;2224	crq->ch = &l2->ch;2225	crq->protocol = ISDN_P_B_HDLC;2226	return 0;2227}2228 2229static struct Bprotocol X75SLP = {2230	.Bprotocols = (1 << (ISDN_P_B_X75SLP & ISDN_P_B_MASK)),2231	.name = "X75SLP",2232	.create = x75create2233};2234 2235int2236Isdnl2_Init(u_int *deb)2237{2238	int res;2239	debug = deb;2240	mISDN_register_Bprotocol(&X75SLP);2241	l2fsm.state_count = L2_STATE_COUNT;2242	l2fsm.event_count = L2_EVENT_COUNT;2243	l2fsm.strEvent = strL2Event;2244	l2fsm.strState = strL2State;2245	res = mISDN_FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));2246	if (res)2247		goto error;2248	res = TEIInit(deb);2249	if (res)2250		goto error_fsm;2251	return 0;2252 2253error_fsm:2254	mISDN_FsmFree(&l2fsm);2255error:2256	mISDN_unregister_Bprotocol(&X75SLP);2257	return res;2258}2259 2260void2261Isdnl2_cleanup(void)2262{2263	mISDN_unregister_Bprotocol(&X75SLP);2264	TEIFree();2265	mISDN_FsmFree(&l2fsm);2266}2267