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