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