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