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