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