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