Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / net / i4b / layer2 / i4b_l2fsm.c
1 /*
2  * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  *---------------------------------------------------------------------------
26  *
27  *      i4b_l2fsm.c - layer 2 FSM
28  *      -------------------------
29  *
30  *      $Id: i4b_l2fsm.c,v 1.22 2000/08/24 11:48:58 hm Exp $ 
31  *
32  * $FreeBSD: src/sys/i4b/layer2/i4b_l2fsm.c,v 1.6.2.1 2001/08/10 14:08:41 obrien Exp $
33  *
34  *      last edit-date: [Tue May 30 15:48:20 2000]
35  *
36  *---------------------------------------------------------------------------*/
37
38 #ifdef __FreeBSD__
39 #include "i4bq921.h"
40 #else
41 #define NI4BQ921        1
42 #endif
43 #if NI4BQ921 > 0
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/socket.h>
48 #include <net/if.h>
49
50 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
51 #include <sys/callout.h>
52 #endif
53
54 #ifdef __FreeBSD__
55 #include <machine/i4b_debug.h>
56 #include <machine/i4b_ioctl.h>
57 #else
58 #include <i4b/i4b_debug.h>
59 #include <i4b/i4b_ioctl.h>
60 #endif
61
62 #include <i4b/include/i4b_global.h>
63 #include <i4b/include/i4b_l2l3.h>
64 #include <i4b/include/i4b_mbuf.h>
65
66 #include <i4b/layer2/i4b_l2.h>
67 #include <i4b/layer2/i4b_l2fsm.h>
68
69 l2_softc_t l2_softc[MAXL1UNITS];
70
71 #if DO_I4B_DEBUG
72 static char *l2state_text[N_STATES] = {
73         "ST_TEI_UNAS",
74         "ST_ASG_AW_TEI",
75         "ST_EST_AW_TEI",
76         "ST_TEI_ASGD",
77
78         "ST_AW_EST",
79         "ST_AW_REL",
80         "ST_MULTIFR",
81         "ST_TIMREC",
82
83         "ST_SUBSET",
84         "Illegal State"
85 };
86
87 static char *l2event_text[N_EVENTS] = {
88         "EV_DLESTRQ",
89         "EV_DLUDTRQ",
90         "EV_MDASGRQ",
91         "EV_MDERRRS",
92         "EV_PSDEACT",
93         "EV_MDREMRQ",
94         "EV_RXSABME",
95         "EV_RXDISC",
96         "EV_RXUA",
97         "EV_RXDM",
98         "EV_T200EXP",
99         "EV_DLDATRQ",
100         "EV_DLRELRQ",
101         "EV_T203EXP",
102         "EV_OWNBUSY",
103         "EV_OWNRDY", 
104         "EV_RXRR",
105         "EV_RXREJ",
106         "EV_RXRNR",
107         "EV_RXFRMR",
108         "Illegal Event"
109 };
110 #endif
111
112 static void F_TU01 __P((l2_softc_t *));
113 static void F_TU03 __P((l2_softc_t *));
114
115 static void F_TA03 __P((l2_softc_t *));
116 static void F_TA04 __P((l2_softc_t *));
117 static void F_TA05 __P((l2_softc_t *));
118
119 static void F_TE03 __P((l2_softc_t *));
120 static void F_TE04 __P((l2_softc_t *));
121 static void F_TE05 __P((l2_softc_t *));
122
123 static void F_T01 __P((l2_softc_t *));
124 static void F_T05 __P((l2_softc_t *));
125 static void F_T06 __P((l2_softc_t *));
126 static void F_T07 __P((l2_softc_t *));
127 static void F_T08 __P((l2_softc_t *));
128 static void F_T09 __P((l2_softc_t *));
129 static void F_T10 __P((l2_softc_t *));
130 static void F_T13 __P((l2_softc_t *));
131
132 static void F_AE01 __P((l2_softc_t *));
133 static void F_AE05 __P((l2_softc_t *));
134 static void F_AE06 __P((l2_softc_t *));
135 static void F_AE07 __P((l2_softc_t *));
136 static void F_AE08 __P((l2_softc_t *));
137 static void F_AE09 __P((l2_softc_t *));
138 static void F_AE10 __P((l2_softc_t *));
139 static void F_AE11 __P((l2_softc_t *));
140 static void F_AE12 __P((l2_softc_t *));
141
142 static void F_AR05 __P((l2_softc_t *));
143 static void F_AR06 __P((l2_softc_t *));
144 static void F_AR07 __P((l2_softc_t *));
145 static void F_AR08 __P((l2_softc_t *));
146 static void F_AR09 __P((l2_softc_t *));
147 static void F_AR10 __P((l2_softc_t *));
148 static void F_AR11 __P((l2_softc_t *));
149
150 static void F_MF01 __P((l2_softc_t *));
151 static void F_MF05 __P((l2_softc_t *));
152 static void F_MF06 __P((l2_softc_t *));
153 static void F_MF07 __P((l2_softc_t *));
154 static void F_MF08 __P((l2_softc_t *));
155 static void F_MF09 __P((l2_softc_t *));
156 static void F_MF10 __P((l2_softc_t *));
157 static void F_MF11 __P((l2_softc_t *));
158 static void F_MF12 __P((l2_softc_t *));
159 static void F_MF13 __P((l2_softc_t *));
160 static void F_MF14 __P((l2_softc_t *));
161 static void F_MF15 __P((l2_softc_t *));
162 static void F_MF16 __P((l2_softc_t *));
163 static void F_MF17 __P((l2_softc_t *));
164 static void F_MF18 __P((l2_softc_t *));
165 static void F_MF19 __P((l2_softc_t *));
166 static void F_MF20 __P((l2_softc_t *));
167
168 static void F_TR01 __P((l2_softc_t *));
169 static void F_TR05 __P((l2_softc_t *));
170 static void F_TR06 __P((l2_softc_t *));
171 static void F_TR07 __P((l2_softc_t *));
172 static void F_TR08 __P((l2_softc_t *));
173 static void F_TR09 __P((l2_softc_t *));
174 static void F_TR10 __P((l2_softc_t *));
175 static void F_TR11 __P((l2_softc_t *));
176 static void F_TR12 __P((l2_softc_t *));
177 static void F_TR13 __P((l2_softc_t *));
178 static void F_TR15 __P((l2_softc_t *));
179 static void F_TR16 __P((l2_softc_t *));
180 static void F_TR17 __P((l2_softc_t *));
181 static void F_TR18 __P((l2_softc_t *));
182 static void F_TR19 __P((l2_softc_t *));
183 static void F_TR20 __P((l2_softc_t *));
184 static void F_ILL __P((l2_softc_t *));
185 static void F_NCNA __P((l2_softc_t *));
186
187 /*---------------------------------------------------------------------------*
188  *      FSM illegal state default action
189  *---------------------------------------------------------------------------*/ 
190 static void
191 F_ILL(l2_softc_t *l2sc)
192 {
193         NDBGL2(L2_F_ERR, "FSM function F_ILL executing");
194 }
195
196 /*---------------------------------------------------------------------------*
197  *      FSM No change, No action
198  *---------------------------------------------------------------------------*/ 
199 static void
200 F_NCNA(l2_softc_t *l2sc)
201 {
202         NDBGL2(L2_F_MSG, "FSM function F_NCNA executing");
203 }
204
205 /*---------------------------------------------------------------------------*
206  *      layer 2 state transition table
207  *---------------------------------------------------------------------------*/ 
208 struct l2state_tab {
209         void (*func) __P((l2_softc_t *));       /* function to execute */
210         int newstate;                           /* next state */
211 } l2state_tab[N_EVENTS][N_STATES] = {
212
213 /* STATE:       ST_TEI_UNAS,                    ST_ASG_AW_TEI,                  ST_EST_AW_TEI,                  ST_TEI_ASGD,            ST_AW_EST,              ST_AW_REL,              ST_MULTIFR,             ST_TIMREC,              ST_SUBSET,              ILLEGAL STATE   */
214 /* -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
215 /*EV_DLESTRQ*/{ {F_TU01, ST_EST_AW_TEI},        {F_NCNA, ST_EST_AW_TEI},        {F_ILL, ST_ILL},                {F_T01, ST_AW_EST},     {F_AE01, ST_AW_EST},    {F_ILL, ST_ILL},        {F_MF01, ST_AW_EST},    {F_TR01, ST_AW_EST},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
216 /*EV_DLUDTRQ*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
217 /*EV_MDASGRQ*/{ {F_TU03, ST_TEI_ASGD},          {F_TA03, ST_TEI_ASGD},          {F_TE03, ST_AW_EST},            {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
218 /*EV_MDERRRS*/{ {F_ILL, ST_ILL},                {F_TA04, ST_TEI_UNAS},          {F_TE04, ST_TEI_UNAS},          {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
219 /*EV_PSDEACT*/{ {F_ILL, ST_ILL},                {F_TA05, ST_TEI_UNAS},          {F_TE05, ST_TEI_UNAS},          {F_T05, ST_TEI_ASGD},   {F_AE05, ST_TEI_ASGD},  {F_AR05, ST_TEI_ASGD},  {F_MF05, ST_TEI_ASGD},  {F_TR05, ST_TEI_ASGD},  {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
220 /*EV_MDREMRQ*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_T06, ST_TEI_UNAS},   {F_AE06, ST_TEI_UNAS},  {F_AR06, ST_TEI_UNAS},  {F_MF06, ST_TEI_UNAS},  {F_TR06, ST_TEI_UNAS},  {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
221 /*EV_RXSABME*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_T07, ST_SUBSET},     {F_AE07, ST_AW_EST},    {F_AR07, ST_AW_REL},    {F_MF07, ST_MULTIFR},   {F_TR07, ST_MULTIFR},   {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
222 /*EV_RXDISC */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_T08, ST_TEI_ASGD},   {F_AE08, ST_AW_EST},    {F_AR08, ST_AW_REL},    {F_MF08, ST_TEI_ASGD},  {F_TR08, ST_TEI_ASGD},  {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
223 /*EV_RXUA   */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_T09, ST_TEI_ASGD},   {F_AE09, ST_SUBSET},    {F_AR09, ST_SUBSET},    {F_MF09, ST_MULTIFR},   {F_TR09, ST_TIMREC},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
224 /*EV_RXDM   */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_T10, ST_SUBSET},     {F_AE10, ST_SUBSET},    {F_AR10, ST_SUBSET},    {F_MF10, ST_SUBSET},    {F_TR10, ST_AW_EST},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
225 /*EV_T200EXP*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_AE11, ST_SUBSET},    {F_AR11, ST_SUBSET},    {F_MF11, ST_TIMREC},    {F_TR11, ST_SUBSET},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
226 /*EV_DLDATRQ*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_AE12, ST_AW_EST},    {F_ILL, ST_ILL},        {F_MF12, ST_MULTIFR},   {F_TR12, ST_TIMREC},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
227 /*EV_DLRELRQ*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_T13, ST_TEI_ASGD},   {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF13, ST_AW_REL},    {F_TR13, ST_AW_REL},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
228 /*EV_T203EXP*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF14, ST_TIMREC},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
229 /*EV_OWNBUSY*/{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF15, ST_MULTIFR},   {F_TR15, ST_TIMREC},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
230 /*EV_OWNRDY */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF16, ST_MULTIFR},   {F_TR16, ST_TIMREC},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
231 /*EV_RXRR   */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF17, ST_SUBSET},    {F_TR17, ST_SUBSET},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
232 /*EV_RXREJ  */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF18, ST_SUBSET},    {F_TR18, ST_SUBSET},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
233 /*EV_RXRNR  */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF19, ST_SUBSET},    {F_TR19, ST_SUBSET},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
234 /*EV_RXFRMR */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_MF20, ST_AW_EST},    {F_TR20, ST_AW_EST},    {F_ILL, ST_ILL},        {F_ILL, ST_ILL} },
235 /*EV_ILL    */{ {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},                {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL},        {F_ILL, ST_ILL} }
236 };
237
238 /*---------------------------------------------------------------------------*
239  *      event handler, executes function and sets new state
240  *---------------------------------------------------------------------------*/ 
241 void i4b_next_l2state(l2_softc_t *l2sc, int event)
242 {
243         int currstate, newstate;
244         int (*savpostfsmfunc)(int) = NULL;
245
246         /* check event number */
247         if(event > N_EVENTS)
248                 panic("i4b_l2fsm.c: event > N_EVENTS\n");
249
250         /* get current state and check it */
251         if((currstate = l2sc->Q921_state) > N_STATES)   /* failsafe */
252                 panic("i4b_l2fsm.c: currstate > N_STATES\n");   
253
254         /* get new state and check it */
255         if((newstate = l2state_tab[event][currstate].newstate) > N_STATES)
256                 panic("i4b_l2fsm.c: newstate > N_STATES\n");    
257         
258         
259         if(newstate != ST_SUBSET)
260         {       /* state function does NOT set new state */
261                 NDBGL2(L2_F_MSG, "FSM event [%s]: [%s/%d => %s/%d]",
262                                 l2event_text[event],
263                                 l2state_text[currstate], currstate,
264                                 l2state_text[newstate], newstate);
265         }
266
267         /* execute state transition function */
268         (*l2state_tab[event][currstate].func)(l2sc);
269
270         if(newstate == ST_SUBSET)
271         {       /* state function DOES set new state */
272                 NDBGL2(L2_F_MSG, "FSM S-event [%s]: [%s => %s]", l2event_text[event],
273                                            l2state_text[currstate],
274                                            l2state_text[l2sc->Q921_state]);
275         }
276         
277         /* check for illegal new state */
278
279         if(newstate == ST_ILL)
280         {
281                 newstate = currstate;
282                 NDBGL2(L2_F_ERR, "FSM illegal state, state = %s, event = %s!",
283                                 l2state_text[currstate],
284                                 l2event_text[event]);
285         }
286
287         /* check if state machine function has to set new state */
288
289         if(newstate != ST_SUBSET)
290                 l2sc->Q921_state = newstate;        /* no, we set new state */
291
292         if(l2sc->postfsmfunc != NULL)
293         {
294                 NDBGL2(L2_F_MSG, "FSM executing postfsmfunc!");
295                 /* try to avoid an endless loop */
296                 savpostfsmfunc = l2sc->postfsmfunc;
297                 l2sc->postfsmfunc = NULL;
298                 (*savpostfsmfunc)(l2sc->postfsmarg);
299         }
300 }
301
302 #if DO_I4B_DEBUG
303 /*---------------------------------------------------------------------------*
304  *      return pointer to current state description
305  *---------------------------------------------------------------------------*/ 
306 char *i4b_print_l2state(l2_softc_t *l2sc)
307 {
308         return((char *) l2state_text[l2sc->Q921_state]);
309 }
310 #endif
311
312 /*---------------------------------------------------------------------------*
313  *      FSM state ST_TEI_UNAS event dl establish request
314  *---------------------------------------------------------------------------*/ 
315 static void
316 F_TU01(l2_softc_t *l2sc)
317 {
318         NDBGL2(L2_F_MSG, "FSM function F_TU01 executing");
319         i4b_mdl_assign_ind(l2sc);
320 }
321
322 /*---------------------------------------------------------------------------*
323  *      FSM state ST_TEI_UNAS event mdl assign request
324  *---------------------------------------------------------------------------*/ 
325 static void
326 F_TU03(l2_softc_t *l2sc)
327 {
328         NDBGL2(L2_F_MSG, "FSM function F_TU03 executing");
329 }
330
331 /*---------------------------------------------------------------------------*
332  *      FSM state ST_ASG_AW_TEI event mdl assign request
333  *---------------------------------------------------------------------------*/ 
334 static void
335 F_TA03(l2_softc_t *l2sc)
336 {
337         NDBGL2(L2_F_MSG, "FSM function F_TA03 executing");
338 }
339
340 /*---------------------------------------------------------------------------*
341  *      FSM state ST_ASG_AW_TEI event mdl error response
342  *---------------------------------------------------------------------------*/ 
343 static void
344 F_TA04(l2_softc_t *l2sc)
345 {
346         NDBGL2(L2_F_MSG, "FSM function F_TA04 executing");
347 }
348
349 /*---------------------------------------------------------------------------*
350  *      FSM state ST_ASG_AW_TEI event persistent deactivation
351  *---------------------------------------------------------------------------*/ 
352 static void
353 F_TA05(l2_softc_t *l2sc)
354 {
355         NDBGL2(L2_F_MSG, "FSM function F_TA05 executing");
356 }
357
358 /*---------------------------------------------------------------------------*
359  *      FSM state ST_EST_AW_TEI event mdl assign request
360  *---------------------------------------------------------------------------*/ 
361 static void
362 F_TE03(l2_softc_t *l2sc)
363 {
364         NDBGL2(L2_F_MSG, "FSM function F_TE03 executing");
365         i4b_establish_data_link(l2sc);
366         l2sc->l3initiated = 1;
367 }
368
369 /*---------------------------------------------------------------------------*
370  *      FSM state ST_EST_AW_TEI event mdl error response
371  *---------------------------------------------------------------------------*/ 
372 static void
373 F_TE04(l2_softc_t *l2sc)
374 {
375         NDBGL2(L2_F_MSG, "FSM function F_TE04 executing");
376         l2sc->postfsmarg = l2sc->unit;
377         l2sc->postfsmfunc = DL_Rel_Ind_A;
378 }
379
380 /*---------------------------------------------------------------------------*
381  *      FSM state ST_EST_AW_TEI event persistent deactivation
382  *---------------------------------------------------------------------------*/ 
383 static void
384 F_TE05(l2_softc_t *l2sc)
385 {
386         NDBGL2(L2_F_MSG, "FSM function F_TE05 executing");
387         l2sc->postfsmarg = l2sc->unit;
388         l2sc->postfsmfunc = DL_Rel_Ind_A;
389 }
390
391 /*---------------------------------------------------------------------------*
392  *      FSM state ST_TEI_ASGD event dl establish request
393  *---------------------------------------------------------------------------*/ 
394 static void
395 F_T01(l2_softc_t *l2sc)
396 {
397         NDBGL2(L2_F_MSG, "FSM function F_T01 executing");
398         i4b_establish_data_link(l2sc);
399         l2sc->l3initiated = 1;
400 }
401
402 /*---------------------------------------------------------------------------*
403  *      FSM state ST_TEI_ASGD event persistent deactivation
404  *---------------------------------------------------------------------------*/ 
405 static void
406 F_T05(l2_softc_t *l2sc)
407 {
408         NDBGL2(L2_F_MSG, "FSM function F_T05 executing");
409 }
410
411 /*---------------------------------------------------------------------------*
412  *      FSM state ST_TEI_ASGD event mdl remove request
413  *---------------------------------------------------------------------------*/ 
414 static void
415 F_T06(l2_softc_t *l2sc)
416 {
417         NDBGL2(L2_F_MSG, "FSM function F_T06 executing");
418 /*XXX*/ i4b_mdl_assign_ind(l2sc);
419 }
420
421 /*---------------------------------------------------------------------------*
422  *      FSM state ST_TEI_ASGD event rx'd SABME
423  *---------------------------------------------------------------------------*/ 
424 static void
425 F_T07(l2_softc_t *l2sc)
426 {
427         NDBGL2(L2_F_MSG, "FSM function F_T07 executing");
428
429 /* XXX */
430 #ifdef NOTDEF
431         if(NOT able to establish)
432         {
433                 i4b_tx_dm(l2sc, l2sc->rxd_PF);
434                 l2sc->Q921_state = ST_TEI_ASGD;
435                 return;
436         }
437 #endif
438
439         i4b_clear_exception_conditions(l2sc);
440
441         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_ACTIVE);
442         
443         i4b_tx_ua(l2sc, l2sc->rxd_PF);
444
445         l2sc->vs = 0;
446         l2sc->va = 0;
447         l2sc->vr = 0;   
448
449         l2sc->postfsmarg = l2sc->unit;
450         l2sc->postfsmfunc = DL_Est_Ind_A;
451
452         i4b_T203_start(l2sc);   
453
454         l2sc->Q921_state = ST_MULTIFR;
455 }
456
457 /*---------------------------------------------------------------------------*
458  *      FSM state ST_TEI_ASGD event rx'd DISC
459  *---------------------------------------------------------------------------*/ 
460 static void
461 F_T08(l2_softc_t *l2sc)
462 {
463         NDBGL2(L2_F_MSG, "FSM function F_T08 executing");
464         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_IDLE);
465         i4b_tx_ua(l2sc, l2sc->rxd_PF);
466 }
467
468 /*---------------------------------------------------------------------------*
469  *      FSM state ST_TEI_ASGD event rx'd UA
470  *---------------------------------------------------------------------------*/ 
471 static void
472 F_T09(l2_softc_t *l2sc)
473 {
474         NDBGL2(L2_F_MSG, "FSM function F_T09 executing");
475         i4b_mdl_error_ind(l2sc, "F_T09", MDL_ERR_C);
476         i4b_mdl_error_ind(l2sc, "F_T09", MDL_ERR_D);    
477 }
478
479 /*---------------------------------------------------------------------------*
480  *      FSM state ST_TEI_ASGD event rx'd DM
481  *---------------------------------------------------------------------------*/ 
482 static void
483 F_T10(l2_softc_t *l2sc)
484 {
485         NDBGL2(L2_F_MSG, "FSM function F_T10 executing");
486
487         if(l2sc->rxd_PF)
488         {
489                 l2sc->Q921_state = ST_TEI_ASGD;
490         }
491         else
492         {
493 #ifdef NOTDEF
494                 if(NOT able_to_etablish)
495                 {
496                         l2sc->Q921_state = ST_TEI_ASGD;
497                         return;
498                 }
499 #endif
500                 i4b_establish_data_link(l2sc);
501
502                 l2sc->l3initiated = 1;
503
504                 l2sc->Q921_state = ST_AW_EST;
505         }
506 }
507
508 /*---------------------------------------------------------------------------*
509  *      FSM state ST_TEI_ASGD event dl release request
510  *---------------------------------------------------------------------------*/ 
511 static void
512 F_T13(l2_softc_t *l2sc)
513 {
514         NDBGL2(L2_F_MSG, "FSM function F_T13 executing");
515         l2sc->postfsmarg = l2sc->unit;
516         l2sc->postfsmfunc = DL_Rel_Cnf_A;
517 }
518
519 /*---------------------------------------------------------------------------*
520  *      FSM state ST_AW_EST event dl establish request
521  *---------------------------------------------------------------------------*/ 
522 static void
523 F_AE01(l2_softc_t *l2sc)
524 {
525         NDBGL2(L2_F_MSG, "FSM function F_AE01 executing");
526
527         i4b_Dcleanifq(&l2sc->i_queue);
528         
529         l2sc->l3initiated = 1;
530 }
531
532 /*---------------------------------------------------------------------------*
533  *      FSM state ST_AW_EST event persistent deactivation
534  *---------------------------------------------------------------------------*/ 
535 static void
536 F_AE05(l2_softc_t *l2sc)
537 {
538         NDBGL2(L2_F_MSG, "FSM function F_AE05 executing");
539
540         i4b_Dcleanifq(&l2sc->i_queue);  
541
542         l2sc->postfsmarg = l2sc->unit;
543         l2sc->postfsmfunc = DL_Rel_Ind_A;
544
545         i4b_T200_stop(l2sc);
546 }
547
548 /*---------------------------------------------------------------------------*
549  *      FSM state ST_AW_EST event mdl remove request
550  *---------------------------------------------------------------------------*/ 
551 static void
552 F_AE06(l2_softc_t *l2sc)
553 {
554         NDBGL2(L2_F_MSG, "FSM function F_AE06 executing");
555
556         i4b_Dcleanifq(&l2sc->i_queue);  
557
558         l2sc->postfsmarg = l2sc->unit;
559         l2sc->postfsmfunc = DL_Rel_Ind_A;
560
561         i4b_T200_stop(l2sc);
562
563 /*XXX*/ i4b_mdl_assign_ind(l2sc);
564 }
565
566 /*---------------------------------------------------------------------------*
567  *      FSM state ST_AW_EST event rx'd SABME
568  *---------------------------------------------------------------------------*/ 
569 static void
570 F_AE07(l2_softc_t *l2sc)
571 {
572         NDBGL2(L2_F_MSG, "FSM function F_AE07 executing");
573         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_ACTIVE);
574         i4b_tx_ua(l2sc, l2sc->rxd_PF);
575 }
576
577 /*---------------------------------------------------------------------------*
578  *      FSM state ST_AW_EST event rx'd DISC
579  *---------------------------------------------------------------------------*/ 
580 static void
581 F_AE08(l2_softc_t *l2sc)
582 {
583         NDBGL2(L2_F_MSG, "FSM function F_AE08 executing");
584         i4b_tx_dm(l2sc, l2sc->rxd_PF);
585 }
586
587 /*---------------------------------------------------------------------------*
588  *      FSM state ST_AW_EST event rx'd UA
589  *---------------------------------------------------------------------------*/ 
590 static void
591 F_AE09(l2_softc_t *l2sc)
592 {
593         NDBGL2(L2_F_MSG, "FSM function F_AE09 executing");
594
595         if(l2sc->rxd_PF == 0)
596         {
597                 i4b_mdl_error_ind(l2sc, "F_AE09", MDL_ERR_D);
598                 l2sc->Q921_state = ST_AW_EST;
599         }
600         else
601         {
602                 if(l2sc->l3initiated)
603                 {
604                         l2sc->l3initiated = 0;
605                         l2sc->vr = 0;
606                         l2sc->postfsmarg = l2sc->unit;
607                         l2sc->postfsmfunc = DL_Est_Cnf_A;
608                 }
609                 else
610                 {
611                         if(l2sc->vs != l2sc->va)
612                         {
613                                 i4b_Dcleanifq(&l2sc->i_queue);
614                                 l2sc->postfsmarg = l2sc->unit;
615                                 l2sc->postfsmfunc = DL_Est_Ind_A;
616                         }
617                 }
618
619                 MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_ACTIVE);
620                 
621                 i4b_T200_stop(l2sc);
622                 i4b_T203_start(l2sc);
623
624                 l2sc->vs = 0;
625                 l2sc->va = 0;
626
627                 l2sc->Q921_state = ST_MULTIFR;
628         }
629 }
630
631 /*---------------------------------------------------------------------------*
632  *      FSM state ST_AW_EST event rx'd DM
633  *---------------------------------------------------------------------------*/ 
634 static void
635 F_AE10(l2_softc_t *l2sc)
636 {
637         NDBGL2(L2_F_MSG, "FSM function F_AE10 executing");
638
639         if(l2sc->rxd_PF == 0)
640         {
641                 l2sc->Q921_state = ST_AW_EST;
642         }
643         else
644         {
645                 i4b_Dcleanifq(&l2sc->i_queue);
646
647                 l2sc->postfsmarg = l2sc->unit;
648                 l2sc->postfsmfunc = DL_Rel_Ind_A;
649
650                 i4b_T200_stop(l2sc);
651
652                 l2sc->Q921_state = ST_TEI_ASGD;         
653         }
654 }
655
656 /*---------------------------------------------------------------------------*
657  *      FSM state ST_AW_EST event T200 expiry
658  *---------------------------------------------------------------------------*/ 
659 static void
660 F_AE11(l2_softc_t *l2sc)
661 {
662         NDBGL2(L2_F_MSG, "FSM function F_AE11 executing");
663
664         if(l2sc->RC >= N200)
665         {
666                 i4b_Dcleanifq(&l2sc->i_queue);
667
668                 i4b_mdl_error_ind(l2sc, "F_AE11", MDL_ERR_G);
669
670                 l2sc->postfsmarg = l2sc->unit;
671                 l2sc->postfsmfunc = DL_Rel_Ind_A;
672
673                 l2sc->Q921_state = ST_TEI_ASGD;
674         }
675         else
676         {
677                 l2sc->RC++;
678
679                 i4b_tx_sabme(l2sc, P1);
680
681                 i4b_T200_start(l2sc);
682
683                 l2sc->Q921_state = ST_AW_EST;
684         }
685 }
686
687 /*---------------------------------------------------------------------------*
688  *      FSM state ST_AW_EST event dl data request
689  *---------------------------------------------------------------------------*/ 
690 static void
691 F_AE12(l2_softc_t *l2sc)
692 {
693         NDBGL2(L2_F_MSG, "FSM function F_AE12 executing");
694
695         if(l2sc->l3initiated == 0)
696         {
697                 i4b_i_frame_queued_up(l2sc);
698         }
699 }
700
701 /*---------------------------------------------------------------------------*
702  *      FSM state ST_AW_REL event persistent deactivation
703  *---------------------------------------------------------------------------*/ 
704 static void
705 F_AR05(l2_softc_t *l2sc)
706 {
707         NDBGL2(L2_F_MSG, "FSM function F_AR05 executing");
708
709         l2sc->postfsmarg = l2sc->unit;
710         l2sc->postfsmfunc = DL_Rel_Cnf_A;
711
712         i4b_T200_stop(l2sc);
713 }
714
715 /*---------------------------------------------------------------------------*
716  *      FSM state ST_AW_REL event mdl remove request
717  *---------------------------------------------------------------------------*/ 
718 static void
719 F_AR06(l2_softc_t *l2sc)
720 {
721         NDBGL2(L2_F_MSG, "FSM function F_AR06 executing");
722
723         l2sc->postfsmarg = l2sc->unit;
724         l2sc->postfsmfunc = DL_Rel_Cnf_A;
725
726         i4b_T200_stop(l2sc);
727
728 /*XXX*/ i4b_mdl_assign_ind(l2sc);       
729 }
730
731 /*---------------------------------------------------------------------------*
732  *      FSM state ST_AW_REL event rx'd SABME
733  *---------------------------------------------------------------------------*/ 
734 static void
735 F_AR07(l2_softc_t *l2sc)
736 {
737         NDBGL2(L2_F_MSG, "FSM function F_AR07 executing");      
738         i4b_tx_dm(l2sc, l2sc->rxd_PF);
739 }
740
741 /*---------------------------------------------------------------------------*
742  *      FSM state ST_AW_REL event rx'd DISC
743  *---------------------------------------------------------------------------*/ 
744 static void
745 F_AR08(l2_softc_t *l2sc)
746 {
747         NDBGL2(L2_F_MSG, "FSM function F_AR08 executing");
748         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_IDLE);
749         i4b_tx_ua(l2sc, l2sc->rxd_PF);  
750 }
751
752 /*---------------------------------------------------------------------------*
753  *      FSM state ST_AW_REL event rx'd UA
754  *---------------------------------------------------------------------------*/ 
755 static void
756 F_AR09(l2_softc_t *l2sc)
757 {
758         NDBGL2(L2_F_MSG, "FSM function F_AR09 executing");
759
760         if(l2sc->rxd_PF)
761         {
762                 l2sc->postfsmarg = l2sc->unit;
763                 l2sc->postfsmfunc = DL_Rel_Cnf_A;
764
765                 i4b_T200_stop(l2sc);
766
767                 l2sc->Q921_state = ST_TEI_ASGD;
768         }
769         else
770         {
771                 i4b_mdl_error_ind(l2sc, "F_AR09", MDL_ERR_D);
772                 
773                 l2sc->Q921_state = ST_AW_REL;
774         }
775 }
776
777 /*---------------------------------------------------------------------------*
778  *      FSM state ST_AW_REL event rx'd DM
779  *---------------------------------------------------------------------------*/ 
780 static void
781 F_AR10(l2_softc_t *l2sc)
782 {
783         NDBGL2(L2_F_MSG, "FSM function F_AR10 executing");
784
785         if(l2sc->rxd_PF)
786         {
787                 l2sc->postfsmarg = l2sc->unit;
788                 l2sc->postfsmfunc = DL_Rel_Cnf_A;
789
790                 i4b_T200_stop(l2sc);
791
792                 l2sc->Q921_state = ST_TEI_ASGD;
793         }
794         else
795         {
796                 l2sc->Q921_state = ST_AW_REL;
797         }
798 }
799
800 /*---------------------------------------------------------------------------*
801  *      FSM state ST_AW_REL event T200 expiry
802  *---------------------------------------------------------------------------*/ 
803 static void
804 F_AR11(l2_softc_t *l2sc)
805 {
806         NDBGL2(L2_F_MSG, "FSM function F_AR11 executing");
807
808         if(l2sc->RC >= N200)
809         {
810                 i4b_mdl_error_ind(l2sc, "F_AR11", MDL_ERR_H);
811
812                 l2sc->postfsmarg = l2sc->unit;
813                 l2sc->postfsmfunc = DL_Rel_Cnf_A;
814
815                 l2sc->Q921_state = ST_TEI_ASGD;
816         }
817         else
818         {
819                 l2sc->RC++;
820
821                 i4b_tx_disc(l2sc, P1);
822
823                 i4b_T200_start(l2sc);
824
825                 l2sc->Q921_state = ST_AW_REL;
826         }
827 }
828
829 /*---------------------------------------------------------------------------*
830  *      FSM state ST_MULTIFR event dl establish request
831  *---------------------------------------------------------------------------*/ 
832 static void
833 F_MF01(l2_softc_t *l2sc)
834 {
835         NDBGL2(L2_F_MSG, "FSM function F_MF01 executing");
836
837         i4b_Dcleanifq(&l2sc->i_queue);
838
839         i4b_establish_data_link(l2sc);
840         
841         l2sc->l3initiated = 1;
842 }
843
844 /*---------------------------------------------------------------------------*
845  *      FSM state ST_MULTIFR event persistent deactivation
846  *---------------------------------------------------------------------------*/ 
847 static void
848 F_MF05(l2_softc_t *l2sc)
849 {
850         NDBGL2(L2_F_MSG, "FSM function F_MF05 executing");
851
852         i4b_Dcleanifq(&l2sc->i_queue);
853         
854         l2sc->postfsmarg = l2sc->unit;
855         l2sc->postfsmfunc = DL_Rel_Ind_A;
856         
857         i4b_T200_stop(l2sc);
858         i4b_T203_stop(l2sc);
859 }
860
861 /*---------------------------------------------------------------------------*
862  *      FSM state ST_MULTIFR event mdl remove request
863  *---------------------------------------------------------------------------*/ 
864 static void
865 F_MF06(l2_softc_t *l2sc)
866 {
867         NDBGL2(L2_F_MSG, "FSM function F_MF06 executing");
868
869         i4b_Dcleanifq(&l2sc->i_queue);
870         
871         l2sc->postfsmarg = l2sc->unit;
872         l2sc->postfsmfunc = DL_Rel_Ind_A;
873         
874         i4b_T200_stop(l2sc);
875         i4b_T203_stop(l2sc);
876
877 /*XXX*/ i4b_mdl_assign_ind(l2sc);       
878 }
879
880 /*---------------------------------------------------------------------------*
881  *      FSM state ST_MULTIFR event rx'd SABME
882  *---------------------------------------------------------------------------*/ 
883 static void
884 F_MF07(l2_softc_t *l2sc)
885 {
886         NDBGL2(L2_F_MSG, "FSM function F_MF07 executing");
887
888         i4b_clear_exception_conditions(l2sc);
889
890         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_ACTIVE);   
891
892         i4b_tx_ua(l2sc, l2sc->rxd_PF);
893
894         i4b_mdl_error_ind(l2sc, "F_MF07", MDL_ERR_F);
895
896         if(l2sc->vs != l2sc->va)
897         {
898                 i4b_Dcleanifq(&l2sc->i_queue);
899         
900                 l2sc->postfsmarg = l2sc->unit;
901                 l2sc->postfsmfunc = DL_Est_Ind_A;
902         }
903
904         i4b_T200_stop(l2sc);
905         i4b_T203_start(l2sc);
906
907         l2sc->vs = 0;
908         l2sc->va = 0;
909         l2sc->vr = 0;   
910 }
911
912 /*---------------------------------------------------------------------------*
913  *      FSM state ST_MULTIFR event rx'd DISC
914  *---------------------------------------------------------------------------*/ 
915 static void
916 F_MF08(l2_softc_t *l2sc)
917 {
918         NDBGL2(L2_F_MSG, "FSM function F_MF08 executing");
919
920         i4b_Dcleanifq(&l2sc->i_queue);
921         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_IDLE);
922         i4b_tx_ua(l2sc, l2sc->rxd_PF);
923         
924         l2sc->postfsmarg = l2sc->unit;
925         l2sc->postfsmfunc = DL_Rel_Ind_A;
926
927         i4b_T200_stop(l2sc);
928         i4b_T203_stop(l2sc);
929 }
930
931 /*---------------------------------------------------------------------------*
932  *      FSM state ST_MULTIFR event rx'd UA
933  *---------------------------------------------------------------------------*/ 
934 static void
935 F_MF09(l2_softc_t *l2sc)
936 {
937         NDBGL2(L2_F_MSG, "FSM function F_MF09 executing");
938         if(l2sc->rxd_PF)
939                 i4b_mdl_error_ind(l2sc, "F_MF09", MDL_ERR_C);
940         else
941                 i4b_mdl_error_ind(l2sc, "F_MF09", MDL_ERR_D);
942 }
943
944 /*---------------------------------------------------------------------------*
945  *      FSM state ST_MULTIFR event rx'd DM
946  *---------------------------------------------------------------------------*/ 
947 static void
948 F_MF10(l2_softc_t *l2sc)
949 {
950         NDBGL2(L2_F_MSG, "FSM function F_MF10 executing");
951
952         if(l2sc->rxd_PF)
953         {
954                 i4b_mdl_error_ind(l2sc, "F_MF10", MDL_ERR_B);
955                 
956                 l2sc->Q921_state = ST_MULTIFR;
957         }
958         else
959         {
960                 i4b_mdl_error_ind(l2sc, "F_MF10", MDL_ERR_E);
961                 
962                 i4b_establish_data_link(l2sc);
963
964                 l2sc->l3initiated = 0;
965                 
966                 l2sc->Q921_state = ST_AW_EST;
967         }
968 }
969
970 /*---------------------------------------------------------------------------*
971  *      FSM state ST_MULTIFR event T200 expiry
972  *---------------------------------------------------------------------------*/ 
973 static void
974 F_MF11(l2_softc_t *l2sc)
975 {
976         NDBGL2(L2_F_MSG, "FSM function F_MF11 executing");
977
978         l2sc->RC = 0;
979
980         i4b_transmit_enquire(l2sc);
981
982         l2sc->RC++;
983 }
984
985 /*---------------------------------------------------------------------------*
986  *      FSM state ST_MULTIFR event dl data request
987  *---------------------------------------------------------------------------*/ 
988 static void
989 F_MF12(l2_softc_t *l2sc)
990 {
991         NDBGL2(L2_F_MSG, "FSM function F_MF12 executing");
992
993         i4b_i_frame_queued_up(l2sc);
994 }
995
996 /*---------------------------------------------------------------------------*
997  *      FSM state ST_MULTIFR event dl release request
998  *---------------------------------------------------------------------------*/ 
999 static void
1000 F_MF13(l2_softc_t *l2sc)
1001 {
1002         NDBGL2(L2_F_MSG, "FSM function F_MF13 executing");
1003
1004         i4b_Dcleanifq(&l2sc->i_queue);
1005
1006         l2sc->RC = 0;
1007
1008         i4b_tx_disc(l2sc, P1);
1009         
1010         i4b_T203_stop(l2sc);
1011         i4b_T200_restart(l2sc); 
1012 }
1013
1014 /*---------------------------------------------------------------------------*
1015  *      FSM state ST_MULTIFR event T203 expiry
1016  *---------------------------------------------------------------------------*/ 
1017 static void
1018 F_MF14(l2_softc_t *l2sc)
1019 {
1020         NDBGL2(L2_F_MSG, "FSM function F_MF14 executing");
1021
1022         i4b_transmit_enquire(l2sc);
1023
1024         l2sc->RC = 0;
1025 }
1026
1027 /*---------------------------------------------------------------------------*
1028  *      FSM state ST_MULTIFR event set own rx busy
1029  *---------------------------------------------------------------------------*/ 
1030 static void
1031 F_MF15(l2_softc_t *l2sc)
1032 {
1033         NDBGL2(L2_F_MSG, "FSM function F_MF15 executing");
1034
1035         if(l2sc->own_busy == 0)
1036         {
1037                 l2sc->own_busy = 1;
1038
1039                 i4b_tx_rnr_response(l2sc, F0); /* wrong in Q.921 03/93 p 64 */
1040
1041                 l2sc->ack_pend = 0;
1042         }
1043 }
1044
1045 /*---------------------------------------------------------------------------*
1046  *      FSM state ST_MULTIFR event clear own rx busy
1047  *---------------------------------------------------------------------------*/ 
1048 static void
1049 F_MF16(l2_softc_t *l2sc)
1050 {
1051         NDBGL2(L2_F_MSG, "FSM function F_MF16 executing");
1052
1053         if(l2sc->own_busy != 0)
1054         {
1055                 l2sc->own_busy = 0;
1056
1057                 i4b_tx_rr_response(l2sc, F0); /* wrong in Q.921 03/93 p 64 */
1058
1059                 l2sc->ack_pend = 0;
1060         }
1061 }
1062
1063 /*---------------------------------------------------------------------------*
1064  *      FSM state ST_MULTIFR event rx'd RR
1065  *---------------------------------------------------------------------------*/ 
1066 static void
1067 F_MF17(l2_softc_t *l2sc)
1068 {
1069         NDBGL2(L2_F_MSG, "FSM function F_MF17 executing");
1070
1071         l2sc->peer_busy = 0;
1072
1073         if(l2sc->rxd_CR == CR_CMD_FROM_NT)
1074         {
1075                 if(l2sc->rxd_PF == 1)
1076                 {
1077                         i4b_enquiry_response(l2sc);
1078                 }
1079         }
1080         else
1081         {
1082                 if(l2sc->rxd_PF == 1)
1083                 {
1084                         i4b_mdl_error_ind(l2sc, "F_MF17", MDL_ERR_A);
1085                 }
1086         }
1087
1088         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1089         {
1090                 if(l2sc->rxd_NR == l2sc->vs)
1091                 {
1092                         l2sc->va = l2sc->rxd_NR;
1093                         i4b_T200_stop(l2sc);
1094                         i4b_T203_restart(l2sc);
1095                 }
1096                 else if(l2sc->rxd_NR != l2sc->va)
1097                 {
1098                         l2sc->va = l2sc->rxd_NR;
1099                         i4b_T200_restart(l2sc);
1100                 }
1101                 l2sc->Q921_state = ST_MULTIFR;
1102         }
1103         else
1104         {
1105                 i4b_nr_error_recovery(l2sc);
1106                 l2sc->Q921_state = ST_AW_EST;
1107         }
1108 }
1109
1110 /*---------------------------------------------------------------------------*
1111  *      FSM state ST_MULTIFR event rx'd REJ
1112  *---------------------------------------------------------------------------*/ 
1113 static void
1114 F_MF18(l2_softc_t *l2sc)
1115 {
1116         NDBGL2(L2_F_MSG, "FSM function F_MF18 executing");
1117
1118         l2sc->peer_busy = 0;
1119
1120         if(l2sc->rxd_CR == CR_CMD_FROM_NT)
1121         {
1122                 if(l2sc->rxd_PF == 1)
1123                 {
1124                         i4b_enquiry_response(l2sc);
1125                 }
1126         }
1127         else
1128         {
1129                 if(l2sc->rxd_PF == 1)
1130                 {
1131                         i4b_mdl_error_ind(l2sc, "F_MF18", MDL_ERR_A);
1132                 }
1133         }
1134
1135         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1136         {
1137                 l2sc->va = l2sc->rxd_NR;
1138                 i4b_T200_stop(l2sc);
1139                 i4b_T203_start(l2sc);
1140                 i4b_invoke_retransmission(l2sc, l2sc->rxd_NR);
1141                 l2sc->Q921_state = ST_MULTIFR;
1142         }
1143         else
1144         {
1145                 i4b_nr_error_recovery(l2sc);
1146                 l2sc->Q921_state = ST_AW_EST;           
1147         }
1148 }
1149
1150 /*---------------------------------------------------------------------------*
1151  *      FSM state ST_MULTIFR event rx'd RNR
1152  *---------------------------------------------------------------------------*/ 
1153 static void
1154 F_MF19(l2_softc_t *l2sc)
1155 {
1156         NDBGL2(L2_F_MSG, "FSM function F_MF19 executing");
1157
1158         l2sc->peer_busy = 1;
1159
1160         if(l2sc->rxd_CR == CR_CMD_FROM_NT)
1161         {
1162                 if(l2sc->rxd_PF == 1)
1163                 {
1164                         i4b_enquiry_response(l2sc);
1165                 }
1166         }
1167         else
1168         {
1169                 if(l2sc->rxd_PF == 1)
1170                 {
1171                         i4b_mdl_error_ind(l2sc, "F_MF19", MDL_ERR_A);
1172                 }
1173         }
1174
1175         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1176         {
1177                 l2sc->va = l2sc->rxd_NR;
1178                 i4b_T203_stop(l2sc);
1179                 i4b_T200_restart(l2sc);
1180                 l2sc->Q921_state = ST_MULTIFR;
1181         }
1182         else
1183         {
1184                 i4b_nr_error_recovery(l2sc);
1185                 l2sc->Q921_state = ST_AW_EST;                
1186         }
1187 }
1188
1189 /*---------------------------------------------------------------------------*
1190  *      FSM state ST_MULTIFR event rx'd FRMR
1191  *---------------------------------------------------------------------------*/ 
1192 static void
1193 F_MF20(l2_softc_t *l2sc)
1194 {
1195         NDBGL2(L2_F_MSG, "FSM function F_MF20 executing");
1196
1197         i4b_mdl_error_ind(l2sc, "F_MF20", MDL_ERR_K);
1198
1199         i4b_establish_data_link(l2sc);
1200
1201         l2sc->l3initiated = 0;
1202 }
1203
1204 /*---------------------------------------------------------------------------*
1205  *      FSM state ST_TIMREC event dl establish request
1206  *---------------------------------------------------------------------------*/ 
1207 static void
1208 F_TR01(l2_softc_t *l2sc)
1209 {
1210         NDBGL2(L2_F_MSG, "FSM function F_TR01 executing");
1211
1212         i4b_Dcleanifq(&l2sc->i_queue);
1213
1214         i4b_establish_data_link(l2sc);
1215
1216         l2sc->l3initiated = 1;
1217 }
1218
1219 /*---------------------------------------------------------------------------*
1220  *      FSM state ST_TIMREC event persistent deactivation
1221  *---------------------------------------------------------------------------*/ 
1222 static void
1223 F_TR05(l2_softc_t *l2sc)
1224 {
1225         NDBGL2(L2_F_MSG, "FSM function F_TR05 executing");
1226
1227         i4b_Dcleanifq(&l2sc->i_queue);  
1228
1229         l2sc->postfsmarg = l2sc->unit;
1230         l2sc->postfsmfunc = DL_Rel_Ind_A;
1231
1232         i4b_T200_stop(l2sc);
1233 }
1234
1235 /*---------------------------------------------------------------------------*
1236  *      FSM state ST_TIMREC event mdl remove request
1237  *---------------------------------------------------------------------------*/ 
1238 static void
1239 F_TR06(l2_softc_t *l2sc)
1240 {
1241         NDBGL2(L2_F_MSG, "FSM function F_TR06 executing");
1242
1243         i4b_Dcleanifq(&l2sc->i_queue);
1244
1245         l2sc->postfsmarg = l2sc->unit;
1246         l2sc->postfsmfunc = DL_Rel_Ind_A;
1247
1248         i4b_T200_stop(l2sc);
1249
1250 /*XXX*/ i4b_mdl_assign_ind(l2sc);       
1251 }
1252
1253 /*---------------------------------------------------------------------------*
1254  *      FSM state ST_TIMREC event rx'd SABME
1255  *---------------------------------------------------------------------------*/ 
1256 static void
1257 F_TR07(l2_softc_t *l2sc)
1258 {
1259         NDBGL2(L2_F_MSG, "FSM function F_TR07 executing");
1260
1261         i4b_clear_exception_conditions(l2sc);
1262
1263         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_ACTIVE);
1264         
1265         i4b_tx_ua(l2sc, l2sc->rxd_PF);
1266
1267         i4b_mdl_error_ind(l2sc, "F_TR07", MDL_ERR_F);
1268
1269         if(l2sc->vs != l2sc->va)
1270         {
1271                 i4b_Dcleanifq(&l2sc->i_queue);          
1272
1273                 l2sc->postfsmarg = l2sc->unit;
1274                 l2sc->postfsmfunc = DL_Est_Ind_A;
1275         }
1276
1277         i4b_T200_stop(l2sc);
1278         i4b_T203_start(l2sc);
1279         
1280         l2sc->vs = 0;
1281         l2sc->va = 0;
1282         l2sc->vr = 0;
1283 }
1284
1285 /*---------------------------------------------------------------------------*
1286  *      FSM state ST_TIMREC event rx'd DISC
1287  *---------------------------------------------------------------------------*/ 
1288 static void
1289 F_TR08(l2_softc_t *l2sc)
1290 {
1291         NDBGL2(L2_F_MSG, "FSM function F_TR08 executing");
1292
1293         i4b_Dcleanifq(&l2sc->i_queue);          
1294         MDL_Status_Ind(l2sc->unit, STI_L2STAT, LAYER_IDLE);
1295         i4b_tx_ua(l2sc, l2sc->rxd_PF);
1296
1297         l2sc->postfsmarg = l2sc->unit;
1298         l2sc->postfsmfunc = DL_Rel_Ind_A;
1299
1300         i4b_T200_stop(l2sc);
1301 }
1302
1303 /*---------------------------------------------------------------------------*
1304  *      FSM state ST_TIMREC event rx'd UA
1305  *---------------------------------------------------------------------------*/ 
1306 static void
1307 F_TR09(l2_softc_t *l2sc)
1308 {
1309         NDBGL2(L2_F_MSG, "FSM function F_TR09 executing");
1310         if(l2sc->rxd_PF)
1311                 i4b_mdl_error_ind(l2sc, "F_TR09", MDL_ERR_C);
1312         else
1313                 i4b_mdl_error_ind(l2sc, "F_TR09", MDL_ERR_D);   
1314 }
1315
1316 /*---------------------------------------------------------------------------*
1317  *      FSM state ST_TIMREC event rx'd DM
1318  *---------------------------------------------------------------------------*/ 
1319 static void
1320 F_TR10(l2_softc_t *l2sc)
1321 {
1322         NDBGL2(L2_F_MSG, "FSM function F_TR10 executing");
1323
1324         if(l2sc->rxd_PF)
1325         {
1326                 i4b_mdl_error_ind(l2sc, "F_TR10", MDL_ERR_B);
1327         }
1328         else
1329         {
1330                 i4b_mdl_error_ind(l2sc, "F_TR10", MDL_ERR_E);
1331         }
1332
1333         i4b_establish_data_link(l2sc);
1334
1335         l2sc->l3initiated = 0;
1336 }
1337
1338 /*---------------------------------------------------------------------------*
1339  *      FSM state ST_TIMREC event T200 expiry
1340  *---------------------------------------------------------------------------*/ 
1341 static void
1342 F_TR11(l2_softc_t *l2sc)
1343 {
1344         NDBGL2(L2_F_MSG, "FSM function F_TR11 executing");
1345
1346         if(l2sc->RC >= N200)
1347         {
1348                 i4b_mdl_error_ind(l2sc, "F_TR11", MDL_ERR_I);
1349
1350                 i4b_establish_data_link(l2sc);
1351
1352                 l2sc->l3initiated = 0;
1353
1354                 l2sc->Q921_state = ST_AW_EST;
1355         }
1356         else
1357         {
1358                 i4b_transmit_enquire(l2sc);
1359
1360                 l2sc->RC++;
1361
1362                 l2sc->Q921_state = ST_TIMREC;
1363         }
1364 }
1365
1366 /*---------------------------------------------------------------------------*
1367  *      FSM state ST_TIMREC event dl data request
1368  *---------------------------------------------------------------------------*/ 
1369 static void
1370 F_TR12(l2_softc_t *l2sc)
1371 {
1372         NDBGL2(L2_F_MSG, "FSM function F_TR12 executing");
1373
1374         i4b_i_frame_queued_up(l2sc);
1375 }
1376
1377 /*---------------------------------------------------------------------------*
1378  *      FSM state ST_TIMREC event dl release request
1379  *---------------------------------------------------------------------------*/ 
1380 static void
1381 F_TR13(l2_softc_t *l2sc)
1382 {
1383         NDBGL2(L2_F_MSG, "FSM function F_TR13 executing");
1384
1385         i4b_Dcleanifq(&l2sc->i_queue);                  
1386
1387         l2sc->RC = 0;
1388
1389         i4b_tx_disc(l2sc, P1);
1390
1391         i4b_T200_restart(l2sc);
1392 }
1393
1394 /*---------------------------------------------------------------------------*
1395  *      FSM state ST_TIMREC event set own rx busy
1396  *---------------------------------------------------------------------------*/ 
1397 static void
1398 F_TR15(l2_softc_t *l2sc)
1399 {
1400         NDBGL2(L2_F_MSG, "FSM function F_TR15 executing");
1401
1402         if(l2sc->own_busy == 0)
1403         {
1404                 l2sc->own_busy = 1;
1405
1406                 i4b_tx_rnr_response(l2sc, F0);
1407
1408                 l2sc->ack_pend = 0;
1409         }
1410 }
1411
1412 /*---------------------------------------------------------------------------*
1413  *      FSM state ST_TIMREC event clear own rx busy
1414  *---------------------------------------------------------------------------*/ 
1415 static void
1416 F_TR16(l2_softc_t *l2sc)
1417 {
1418         NDBGL2(L2_F_MSG, "FSM function F_TR16 executing");
1419
1420         if(l2sc->own_busy != 0)
1421         {
1422                 l2sc->own_busy = 0;
1423
1424                 i4b_tx_rr_response(l2sc, F0);   /* this is wrong         */
1425                                                 /* in Q.921 03/93 p 74 ! */
1426                 l2sc->ack_pend = 0;
1427         }
1428 }
1429
1430 /*---------------------------------------------------------------------------*
1431  *      FSM state ST_TIMREC event rx'd RR
1432  *---------------------------------------------------------------------------*/ 
1433 static void
1434 F_TR17(l2_softc_t *l2sc)
1435 {
1436         NDBGL2(L2_F_MSG, "FSM function F_TR17 executing");
1437
1438         l2sc->peer_busy = 0;
1439
1440         if(l2sc->rxd_CR == CR_CMD_FROM_NT)
1441         {
1442                 if(l2sc->rxd_PF == 1)
1443                 {
1444                         i4b_enquiry_response(l2sc);
1445                 }
1446         }
1447         else
1448         {
1449                 if(l2sc->rxd_PF == 1)
1450                 {
1451                         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1452                         {
1453                                 l2sc->va = l2sc->rxd_NR;
1454                                 i4b_T200_stop(l2sc);
1455                                 i4b_T203_start(l2sc);
1456                                 i4b_invoke_retransmission(l2sc, l2sc->rxd_NR);
1457                                 l2sc->Q921_state = ST_MULTIFR;
1458                                 return;
1459                         }
1460                         else
1461                         {
1462                                 i4b_nr_error_recovery(l2sc);
1463                                 l2sc->Q921_state = ST_AW_EST;
1464                                 return;
1465                         }
1466                 }
1467         }
1468
1469         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1470         {
1471                 l2sc->va = l2sc->rxd_NR;
1472                 l2sc->Q921_state = ST_TIMREC;
1473         }
1474         else
1475         {
1476                 i4b_nr_error_recovery(l2sc);
1477                 l2sc->Q921_state = ST_AW_EST;
1478         }
1479 }
1480
1481 /*---------------------------------------------------------------------------*
1482  *      FSM state ST_TIMREC event 
1483  *---------------------------------------------------------------------------*/ 
1484 static void
1485 F_TR18(l2_softc_t *l2sc)
1486 {
1487         NDBGL2(L2_F_MSG, "FSM function F_TR18 executing");
1488
1489         l2sc->peer_busy = 0;
1490
1491         if(l2sc->rxd_CR == CR_CMD_FROM_NT)
1492         {
1493                 if(l2sc->rxd_PF == 1)
1494                 {
1495                         i4b_enquiry_response(l2sc);
1496                 }
1497         }
1498         else
1499         {
1500                 if(l2sc->rxd_PF == 1)
1501                 {
1502                         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1503                         {
1504                                 l2sc->va = l2sc->rxd_NR;
1505                                 i4b_T200_stop(l2sc);
1506                                 i4b_T203_start(l2sc);
1507                                 i4b_invoke_retransmission(l2sc, l2sc->rxd_NR);
1508                                 l2sc->Q921_state = ST_MULTIFR;
1509                                 return;
1510                         }
1511                         else
1512                         {
1513                                 i4b_nr_error_recovery(l2sc);
1514                                 l2sc->Q921_state = ST_AW_EST;
1515                                 return;
1516                         }
1517                 }
1518         }
1519
1520         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1521         {
1522                 l2sc->va = l2sc->rxd_NR;
1523                 l2sc->Q921_state = ST_TIMREC;
1524         }
1525         else
1526         {
1527                 i4b_nr_error_recovery(l2sc);
1528                 l2sc->Q921_state = ST_AW_EST;
1529         }
1530 }
1531
1532 /*---------------------------------------------------------------------------*
1533  *      FSM state ST_TIMREC event rx'd RNR
1534  *---------------------------------------------------------------------------*/ 
1535 static void
1536 F_TR19(l2_softc_t *l2sc)
1537 {
1538         NDBGL2(L2_F_MSG, "FSM function F_TR19 executing");
1539
1540         l2sc->peer_busy = 0;
1541
1542         if(l2sc->rxd_CR == CR_CMD_FROM_NT)
1543         {
1544                 if(l2sc->rxd_PF == 1)
1545                 {
1546                         i4b_enquiry_response(l2sc);
1547                 }
1548         }
1549         else
1550         {
1551                 if(l2sc->rxd_PF == 1)
1552                 {
1553                         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1554                         {
1555                                 l2sc->va = l2sc->rxd_NR;
1556                                 i4b_T200_restart(l2sc);
1557                                 i4b_invoke_retransmission(l2sc, l2sc->rxd_NR);
1558                                 l2sc->Q921_state = ST_MULTIFR;
1559                                 return;
1560                         }
1561                         else
1562                         {
1563                                 i4b_nr_error_recovery(l2sc);
1564                                 l2sc->Q921_state = ST_AW_EST;
1565                                 return;
1566                         }
1567                 }
1568         }
1569
1570         if(i4b_l2_nr_ok(l2sc->rxd_NR, l2sc->va, l2sc->vs))
1571         {
1572                 l2sc->va = l2sc->rxd_NR;
1573                 l2sc->Q921_state = ST_TIMREC;
1574         }
1575         else
1576         {
1577                 i4b_nr_error_recovery(l2sc);
1578                 l2sc->Q921_state = ST_AW_EST;
1579         }
1580 }
1581
1582 /*---------------------------------------------------------------------------*
1583  *      FSM state ST_TIMREC event rx'd FRMR
1584  *---------------------------------------------------------------------------*/ 
1585 static void
1586 F_TR20(l2_softc_t *l2sc)
1587 {
1588         NDBGL2(L2_F_MSG, "FSM function F_TR20 executing");
1589
1590         i4b_mdl_error_ind(l2sc, "F_TR20", MDL_ERR_K);
1591
1592         i4b_establish_data_link(l2sc);
1593
1594         l2sc->l3initiated = 0;
1595 }
1596         
1597 #endif /* NI4BQ921 > 0 */