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