]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/i4b/layer1/isic/i4b_l1fsm.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / i4b / layer1 / isic / i4b_l1fsm.c
1 /*-
2  * Copyright (c) 1997, 2001 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_l1fsm.c - isdn4bsd layer 1 I.430 state machine
29  *      --------------------------------------------------
30  *      last edit-date: [Wed Jan 24 09:12:18 2001]
31  *
32  *---------------------------------------------------------------------------*/
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/systm.h>
40 #include <sys/socket.h>
41
42 #include <net/if.h>
43
44 #include <i4b/include/i4b_debug.h>
45 #include <i4b/include/i4b_ioctl.h>
46 #include <i4b/include/i4b_trace.h>
47
48 #include <i4b/layer1/isic/i4b_isic.h>
49
50 #include <i4b/layer1/i4b_l1.h>
51
52 #include <i4b/include/i4b_global.h>
53
54 #include <i4b/include/i4b_mbuf.h>
55
56 #if DO_I4B_DEBUG
57 static char *state_text[N_STATES] = {
58         "F3 Deactivated",
59         "F4 Awaiting Signal",
60         "F5 Identifying Input",
61         "F6 Synchronized",
62         "F7 Activated",
63         "F8 Lost Framing",
64         "Illegal State" 
65 };
66
67 static char *event_text[N_EVENTS] = {
68         "EV_PHAR PH_ACT_REQ",
69         "EV_T3 Timer 3 expired",
70         "EV_INFO0 INFO0 received",
71         "EV_RSY Level Detected",
72         "EV_INFO2 INFO2 received",
73         "EV_INFO48 INFO4 received",
74         "EV_INFO410 INFO4 received",
75         "EV_DR Deactivate Req",
76         "EV_PU Power UP",
77         "EV_DIS Disconnected",
78         "EV_EI Error Ind",
79         "Illegal Event"
80 };
81 #endif
82
83 /* Function prototypes */
84
85 static void timer3_expired (struct l1_softc *sc);
86 static void T3_start (struct l1_softc *sc);
87 static void T3_stop (struct l1_softc *sc);
88 static void F_T3ex (struct l1_softc *sc);
89 static void timer4_expired (struct l1_softc *sc);
90 static void T4_start (struct l1_softc *sc);
91 static void T4_stop (struct l1_softc *sc);
92 static void F_AI8 (struct l1_softc *sc);
93 static void F_AI10 (struct l1_softc *sc);
94 static void F_I01 (struct l1_softc *sc);
95 static void F_I02 (struct l1_softc *sc);
96 static void F_I03 (struct l1_softc *sc);
97 static void F_I2 (struct l1_softc *sc);
98 static void F_ill (struct l1_softc *sc);
99 static void F_NULL (struct l1_softc *sc);
100
101 /*---------------------------------------------------------------------------*
102  *      I.430 Timer T3 expire function
103  *---------------------------------------------------------------------------*/ 
104 static void
105 timer3_expired(struct l1_softc *sc)
106 {
107         if(sc->sc_I430T3)
108         {
109                 NDBGL1(L1_T_ERR, "state = %s", isic_printstate(sc));
110                 sc->sc_I430T3 = 0;
111
112                 /* XXX try some recovery here XXX */
113
114                 isic_recover(sc);
115
116                 sc->sc_init_tries++;    /* increment retry count */
117
118 /*XXX*/         if(sc->sc_init_tries > 4)
119                 {
120                         int s = SPLI4B();
121
122                         sc->sc_init_tries = 0;
123                         
124                         if(sc->sc_obuf2 != NULL)
125                         {
126                                 i4b_Dfreembuf(sc->sc_obuf2);
127                                 sc->sc_obuf2 = NULL;
128                         }
129                         if(sc->sc_obuf != NULL)
130                         {
131                                 i4b_Dfreembuf(sc->sc_obuf);
132                                 sc->sc_obuf = NULL;
133                                 sc->sc_freeflag = 0;
134                                 sc->sc_op = NULL;
135                                 sc->sc_ol = 0;
136                         }
137
138                         splx(s);
139
140                         i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
141                 }
142                 
143                 isic_next_state(sc, EV_T3);             
144         }
145         else
146         {
147                 NDBGL1(L1_T_ERR, "expired without starting it ....");
148         }
149 }
150
151 /*---------------------------------------------------------------------------*
152  *      I.430 Timer T3 start
153  *---------------------------------------------------------------------------*/ 
154 static void
155 T3_start(struct l1_softc *sc)
156 {
157         NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
158         sc->sc_I430T3 = 1;
159         sc->sc_T3_callout = timeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, 2*hz);
160 }
161
162 /*---------------------------------------------------------------------------*
163  *      I.430 Timer T3 stop
164  *---------------------------------------------------------------------------*/ 
165 static void
166 T3_stop(struct l1_softc *sc)
167 {
168         NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
169
170         sc->sc_init_tries = 0;  /* init connect retry count */
171         
172         if(sc->sc_I430T3)
173         {
174                 sc->sc_I430T3 = 0;
175                 untimeout((TIMEOUT_FUNC_T)timer3_expired,(struct l1_softc *)sc, sc->sc_T3_callout);
176         }
177 }
178
179 /*---------------------------------------------------------------------------*
180  *      I.430 Timer T3 expiry
181  *---------------------------------------------------------------------------*/ 
182 static void
183 F_T3ex(struct l1_softc *sc)
184 {
185         NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
186         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
187                 i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit));
188 }
189
190 /*---------------------------------------------------------------------------*
191  *      Timer T4 expire function
192  *---------------------------------------------------------------------------*/ 
193 static void
194 timer4_expired(struct l1_softc *sc)
195 {
196         if(sc->sc_I430T4)
197         {
198                 NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
199                 sc->sc_I430T4 = 0;
200                 i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
201         }
202         else
203         {
204                 NDBGL1(L1_T_ERR, "expired without starting it ....");
205         }
206 }
207
208 /*---------------------------------------------------------------------------*
209  *      Timer T4 start
210  *---------------------------------------------------------------------------*/ 
211 static void
212 T4_start(struct l1_softc *sc)
213 {
214         NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
215         sc->sc_I430T4 = 1;
216         sc->sc_T4_callout = timeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, hz);
217 }
218
219 /*---------------------------------------------------------------------------*
220  *      Timer T4 stop
221  *---------------------------------------------------------------------------*/ 
222 static void
223 T4_stop(struct l1_softc *sc)
224 {
225         NDBGL1(L1_T_MSG, "state = %s", isic_printstate(sc));
226
227         if(sc->sc_I430T4)
228         {
229                 sc->sc_I430T4 = 0;
230                 untimeout((TIMEOUT_FUNC_T)timer4_expired,(struct l1_softc *)sc, sc->sc_T4_callout);
231         }
232 }
233
234 /*---------------------------------------------------------------------------*
235  *      FSM function: received AI8
236  *---------------------------------------------------------------------------*/ 
237 static void
238 F_AI8(struct l1_softc *sc)
239 {
240         T4_stop(sc);
241
242         NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
243
244         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
245                 i4b_l1_ph_activate_ind(L0ISICUNIT(sc->sc_unit));
246
247         T3_stop(sc);
248
249         if(sc->sc_trace & TRACE_I)
250         {
251                 i4b_trace_hdr_t hdr;
252                 char info = INFO4_8;
253                 
254                 hdr.unit = L0ISICUNIT(sc->sc_unit);
255                 hdr.type = TRC_CH_I;
256                 hdr.dir = FROM_NT;
257                 hdr.count = 0;
258                 MICROTIME(hdr.time);
259                 i4b_l1_trace_ind(&hdr, 1, &info);
260         }
261 }
262
263 /*---------------------------------------------------------------------------*
264  *      FSM function: received AI10
265  *---------------------------------------------------------------------------*/ 
266 static void
267 F_AI10(struct l1_softc *sc)
268 {
269         T4_stop(sc);
270         
271         NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
272
273         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
274                 i4b_l1_ph_activate_ind(L0ISICUNIT(sc->sc_unit));
275
276         T3_stop(sc);
277
278         if(sc->sc_trace & TRACE_I)
279         {
280                 i4b_trace_hdr_t hdr;
281                 char info = INFO4_10;
282                 
283                 hdr.unit = L0ISICUNIT(sc->sc_unit);
284                 hdr.type = TRC_CH_I;
285                 hdr.dir = FROM_NT;
286                 hdr.count = 0;
287                 MICROTIME(hdr.time);
288                 i4b_l1_trace_ind(&hdr, 1, &info);
289         }
290 }
291
292 /*---------------------------------------------------------------------------*
293  *      FSM function: received INFO 0 in states F3 .. F5
294  *---------------------------------------------------------------------------*/ 
295 static void
296 F_I01(struct l1_softc *sc)
297 {
298         NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
299
300         if(sc->sc_trace & TRACE_I)
301         {
302                 i4b_trace_hdr_t hdr;
303                 char info = INFO0;
304                 
305                 hdr.unit = L0ISICUNIT(sc->sc_unit);
306                 hdr.type = TRC_CH_I;
307                 hdr.dir = FROM_NT;
308                 hdr.count = 0;
309                 MICROTIME(hdr.time);
310                 i4b_l1_trace_ind(&hdr, 1, &info);
311         }
312 }
313
314 /*---------------------------------------------------------------------------*
315  *      FSM function: received INFO 0 in state F6
316  *---------------------------------------------------------------------------*/ 
317 static void
318 F_I02(struct l1_softc *sc)
319 {
320         NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
321
322         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
323                 i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit));
324
325         if(sc->sc_trace & TRACE_I)
326         {
327                 i4b_trace_hdr_t hdr;
328                 char info = INFO0;
329                 
330                 hdr.unit = L0ISICUNIT(sc->sc_unit);
331                 hdr.type = TRC_CH_I;
332                 hdr.dir = FROM_NT;
333                 hdr.count = 0;
334                 MICROTIME(hdr.time);
335                 i4b_l1_trace_ind(&hdr, 1, &info);
336         }
337 }
338
339 /*---------------------------------------------------------------------------*
340  *      FSM function: received INFO 0 in state F7 or F8
341  *---------------------------------------------------------------------------*/ 
342 static void
343 F_I03(struct l1_softc *sc)
344 {
345         NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
346
347         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
348                 i4b_l1_ph_deactivate_ind(L0ISICUNIT(sc->sc_unit));
349
350         T4_start(sc);
351         
352         if(sc->sc_trace & TRACE_I)
353         {
354                 i4b_trace_hdr_t hdr;
355                 char info = INFO0;
356                 
357                 hdr.unit = L0ISICUNIT(sc->sc_unit);
358                 hdr.type = TRC_CH_I;
359                 hdr.dir = FROM_NT;
360                 hdr.count = 0;
361                 MICROTIME(hdr.time);
362                 i4b_l1_trace_ind(&hdr, 1, &info);
363         }
364 }
365
366 /*---------------------------------------------------------------------------*
367  *      FSM function: activate request
368  *---------------------------------------------------------------------------*/ 
369 static void
370 F_AR(struct l1_softc *sc)
371 {
372         NDBGL1(L1_F_MSG, "FSM function F_AR executing");
373
374         if(sc->sc_trace & TRACE_I)
375         {
376                 i4b_trace_hdr_t hdr;
377                 char info = INFO1_8;
378                 
379                 hdr.unit = L0ISICUNIT(sc->sc_unit);
380                 hdr.type = TRC_CH_I;
381                 hdr.dir = FROM_TE;
382                 hdr.count = 0;
383                 MICROTIME(hdr.time);
384                 i4b_l1_trace_ind(&hdr, 1, &info);
385         }
386
387         isic_isac_l1_cmd(sc, CMD_AR8);
388
389         T3_start(sc);
390 }
391
392 /*---------------------------------------------------------------------------*
393  *      FSM function: received INFO2
394  *---------------------------------------------------------------------------*/ 
395 static void
396 F_I2(struct l1_softc *sc)
397 {
398         NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
399
400         if(sc->sc_trace & TRACE_I)
401         {
402                 i4b_trace_hdr_t hdr;
403                 char info = INFO2;
404                 
405                 hdr.unit = L0ISICUNIT(sc->sc_unit);
406                 hdr.type = TRC_CH_I;
407                 hdr.dir = FROM_NT;
408                 hdr.count = 0;
409                 MICROTIME(hdr.time);
410                 i4b_l1_trace_ind(&hdr, 1, &info);
411         }               
412
413 }
414
415 /*---------------------------------------------------------------------------*
416  *      illegal state default action
417  *---------------------------------------------------------------------------*/ 
418 static void
419 F_ill(struct l1_softc *sc)
420 {
421         NDBGL1(L1_F_ERR, "FSM function F_ill executing");
422 }
423
424 /*---------------------------------------------------------------------------*
425  *      No action
426  *---------------------------------------------------------------------------*/ 
427 static void
428 F_NULL(struct l1_softc *sc)
429 {
430         NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
431 }
432
433
434 /*---------------------------------------------------------------------------*
435  *      layer 1 state transition table
436  *---------------------------------------------------------------------------*/ 
437 struct isic_state_tab {
438         void (*func) (struct l1_softc *sc);     /* function to execute */
439         int newstate;                           /* next state */
440 } isic_state_tab[N_EVENTS][N_STATES] = {
441
442 /* STATE:       F3                      F4                      F5                      F6                      F7                      F8                      ILLEGAL STATE     */
443 /* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
444 /* EV_PHAR x*/  {{F_AR,   ST_F4},       {F_NULL, ST_F4},        {F_NULL, ST_F5},        {F_NULL, ST_F6},        {F_ill,  ST_ILL},       {F_NULL, ST_F8},        {F_ill, ST_ILL}},
445 /* EV_T3   x*/  {{F_NULL, ST_F3},       {F_T3ex, ST_F3},        {F_T3ex, ST_F3},        {F_T3ex, ST_F3},        {F_NULL, ST_F7},        {F_NULL, ST_F8},        {F_ill, ST_ILL}},
446 /* EV_INFO0 */  {{F_I01,  ST_F3},       {F_I01,  ST_F4},        {F_I01,  ST_F5},        {F_I02,  ST_F3},        {F_I03,  ST_F3},        {F_I03,  ST_F3},        {F_ill, ST_ILL}},
447 /* EV_RSY  x*/  {{F_NULL, ST_F3},       {F_NULL, ST_F5},        {F_NULL, ST_F5},        {F_NULL, ST_F8},        {F_NULL, ST_F8},        {F_NULL, ST_F8},        {F_ill, ST_ILL}},
448 /* EV_INFO2 */  {{F_I2,   ST_F6},       {F_I2,   ST_F6},        {F_I2,   ST_F6},        {F_I2,   ST_F6},        {F_I2,   ST_F6},        {F_I2,   ST_F6},        {F_ill, ST_ILL}},
449 /* EV_INFO48*/  {{F_AI8,  ST_F7},       {F_AI8,  ST_F7},        {F_AI8,  ST_F7},        {F_AI8,  ST_F7},        {F_NULL, ST_F7},        {F_AI8,  ST_F7},        {F_ill, ST_ILL}},
450 /* EV_INFO41*/  {{F_AI10, ST_F7},       {F_AI10, ST_F7},        {F_AI10, ST_F7},        {F_AI10, ST_F7},        {F_NULL, ST_F7},        {F_AI10, ST_F7},        {F_ill, ST_ILL}},
451 /* EV_DR    */  {{F_NULL, ST_F3},       {F_NULL, ST_F4},        {F_NULL, ST_F5},        {F_NULL, ST_F6},        {F_NULL, ST_F7},        {F_NULL, ST_F8},        {F_ill, ST_ILL}},
452 /* EV_PU    */  {{F_NULL, ST_F3},       {F_NULL, ST_F4},        {F_NULL, ST_F5},        {F_NULL, ST_F6},        {F_NULL, ST_F7},        {F_NULL, ST_F8},        {F_ill, ST_ILL}},
453 /* EV_DIS   */  {{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}},
454 /* EV_EI    */  {{F_NULL, ST_F3},       {F_NULL, ST_F3},        {F_NULL, ST_F3},        {F_NULL, ST_F3},        {F_NULL, ST_F3},        {F_NULL, ST_F3},        {F_ill, ST_ILL}},
455 /* 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}}
456 };
457
458 /*---------------------------------------------------------------------------*
459  *      event handler
460  *---------------------------------------------------------------------------*/ 
461 void
462 isic_next_state(struct l1_softc *sc, int event)
463 {
464         int currstate, newstate;
465
466         if(event >= N_EVENTS)
467                 panic("i4b_l1fsm.c: event >= N_EVENTS\n");
468
469         currstate = sc->sc_I430state;
470
471         if(currstate >= N_STATES)
472                 panic("i4b_l1fsm.c: currstate >= N_STATES\n");  
473
474         newstate = isic_state_tab[event][currstate].newstate;
475
476         if(newstate >= N_STATES)
477                 panic("i4b_l1fsm.c: newstate >= N_STATES\n");   
478         
479         NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
480                                            state_text[currstate],
481                                            state_text[newstate]);
482
483         (*isic_state_tab[event][currstate].func)(sc);
484
485         if(newstate == ST_ILL)
486         {
487                 newstate = ST_F3;
488                 NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
489                                         state_text[currstate],
490                                         state_text[newstate],
491                                         event_text[event]);
492         }
493
494         sc->sc_I430state = newstate;
495 }
496
497 #if DO_I4B_DEBUG
498 /*---------------------------------------------------------------------------*
499  *      return pointer to current state description
500  *---------------------------------------------------------------------------*/ 
501 char *
502 isic_printstate(struct l1_softc *sc)
503 {
504         return((char *) state_text[sc->sc_I430state]);
505 }
506 #endif