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