binutils/ld: Don't add /usr/lib to the library search path twice.
[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.5 2005/06/03 16:50:02 dillon Exp $
34  *
35  *      last edit-date: [Mon May 29 15:23:15 2000]
36  *
37  *---------------------------------------------------------------------------*/
38
39 #include "use_ifpi2.h"
40 #include "use_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 #include <sys/thread2.h>
49
50 #include <net/if.h>
51
52 #include <net/i4b/include/machine/i4b_debug.h>
53 #include <net/i4b/include/machine/i4b_ioctl.h>
54 #include <net/i4b/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_ifpi2_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", ifpi2_printstate(sc));
117                 sc->sc_I430T3 = 0;
118
119                 /* XXX try some recovery here XXX */
120
121                 ifpi2_recover(sc);
122
123                 sc->sc_init_tries++;    /* increment retry count */
124
125 /*XXX*/         if(sc->sc_init_tries > 4)
126                 {
127                         crit_enter();
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                         crit_exit();
146
147                         i4b_l1_mph_status_ind(L0IFPI2UNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
148                 }
149                 
150                 ifpi2_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", ifpi2_printstate(sc));
165         sc->sc_I430T3 = 1;
166         callout_reset(&sc->sc_T3_timeout, 2 * hz,
167                         (TIMEOUT_FUNC_T)timer3_expired, (struct l1_softc *)sc);
168 }
169
170 /*---------------------------------------------------------------------------*
171  *      I.430 Timer T3 stop
172  *---------------------------------------------------------------------------*/ 
173 static void
174 T3_stop(struct l1_softc *sc)
175 {
176         NDBGL1(L1_T_MSG, "state = %s", ifpi2_printstate(sc));
177
178         sc->sc_init_tries = 0;  /* init connect retry count */
179         
180         if(sc->sc_I430T3)
181         {
182                 sc->sc_I430T3 = 0;
183                 callout_stop(&sc->sc_T3_timeout);
184         }
185 }
186
187 /*---------------------------------------------------------------------------*
188  *      I.430 Timer T3 expiry
189  *---------------------------------------------------------------------------*/ 
190 static void
191 F_T3ex(struct l1_softc *sc)
192 {
193         NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
194         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
195                 i4b_l1_ph_deactivate_ind(L0IFPI2UNIT(sc->sc_unit));
196 }
197
198 /*---------------------------------------------------------------------------*
199  *      Timer T4 expire function
200  *---------------------------------------------------------------------------*/ 
201 static void
202 timer4_expired(struct l1_softc *sc)
203 {
204         if(sc->sc_I430T4)
205         {
206                 NDBGL1(L1_T_MSG, "state = %s", ifpi2_printstate(sc));
207                 sc->sc_I430T4 = 0;
208                 i4b_l1_mph_status_ind(L0IFPI2UNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
209         }
210         else
211         {
212                 NDBGL1(L1_T_ERR, "expired without starting it ....");
213         }
214 }
215
216 /*---------------------------------------------------------------------------*
217  *      Timer T4 start
218  *---------------------------------------------------------------------------*/ 
219 static void
220 T4_start(struct l1_softc *sc)
221 {
222         NDBGL1(L1_T_MSG, "state = %s", ifpi2_printstate(sc));
223         sc->sc_I430T4 = 1;
224         callout_reset(&sc->sc_T4_timeout, hz,
225                         (TIMEOUT_FUNC_T)timer4_expired, (struct l1_softc *)sc);
226 }
227
228 /*---------------------------------------------------------------------------*
229  *      Timer T4 stop
230  *---------------------------------------------------------------------------*/ 
231 static void
232 T4_stop(struct l1_softc *sc)
233 {
234         NDBGL1(L1_T_MSG, "state = %s", ifpi2_printstate(sc));
235
236         if(sc->sc_I430T4)
237         {
238                 sc->sc_I430T4 = 0;
239                 callout_stop(&sc->sc_T4_timeout);
240         }
241 }
242
243 /*---------------------------------------------------------------------------*
244  *      FSM function: received AI8
245  *---------------------------------------------------------------------------*/ 
246 static void
247 F_AI8(struct l1_softc *sc)
248 {
249         T4_stop(sc);
250
251         NDBGL1(L1_F_MSG, "FSM function F_AI8 executing");
252
253         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
254                 i4b_l1_ph_activate_ind(L0IFPI2UNIT(sc->sc_unit));
255
256         T3_stop(sc);
257
258         if(sc->sc_trace & TRACE_I)
259         {
260                 i4b_trace_hdr_t hdr;
261                 char info = INFO4_8;
262                 
263                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
264                 hdr.type = TRC_CH_I;
265                 hdr.dir = FROM_NT;
266                 hdr.count = 0;
267                 MICROTIME(hdr.time);
268                 i4b_l1_trace_ind(&hdr, 1, &info);
269         }
270 }
271
272 /*---------------------------------------------------------------------------*
273  *      FSM function: received AI10
274  *---------------------------------------------------------------------------*/ 
275 static void
276 F_AI10(struct l1_softc *sc)
277 {
278         T4_stop(sc);
279         
280         NDBGL1(L1_F_MSG, "FSM function F_AI10 executing");
281
282         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
283                 i4b_l1_ph_activate_ind(L0IFPI2UNIT(sc->sc_unit));
284
285         T3_stop(sc);
286
287         if(sc->sc_trace & TRACE_I)
288         {
289                 i4b_trace_hdr_t hdr;
290                 char info = INFO4_10;
291                 
292                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
293                 hdr.type = TRC_CH_I;
294                 hdr.dir = FROM_NT;
295                 hdr.count = 0;
296                 MICROTIME(hdr.time);
297                 i4b_l1_trace_ind(&hdr, 1, &info);
298         }
299 }
300
301 /*---------------------------------------------------------------------------*
302  *      FSM function: received INFO 0 in states F3 .. F5
303  *---------------------------------------------------------------------------*/ 
304 static void
305 F_I01(struct l1_softc *sc)
306 {
307         NDBGL1(L1_F_MSG, "FSM function F_I01 executing");
308
309         if(sc->sc_trace & TRACE_I)
310         {
311                 i4b_trace_hdr_t hdr;
312                 char info = INFO0;
313                 
314                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
315                 hdr.type = TRC_CH_I;
316                 hdr.dir = FROM_NT;
317                 hdr.count = 0;
318                 MICROTIME(hdr.time);
319                 i4b_l1_trace_ind(&hdr, 1, &info);
320         }
321 }
322
323 /*---------------------------------------------------------------------------*
324  *      FSM function: received INFO 0 in state F6
325  *---------------------------------------------------------------------------*/ 
326 static void
327 F_I02(struct l1_softc *sc)
328 {
329         NDBGL1(L1_F_MSG, "FSM function F_I02 executing");
330
331         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
332                 i4b_l1_ph_deactivate_ind(L0IFPI2UNIT(sc->sc_unit));
333
334         if(sc->sc_trace & TRACE_I)
335         {
336                 i4b_trace_hdr_t hdr;
337                 char info = INFO0;
338                 
339                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
340                 hdr.type = TRC_CH_I;
341                 hdr.dir = FROM_NT;
342                 hdr.count = 0;
343                 MICROTIME(hdr.time);
344                 i4b_l1_trace_ind(&hdr, 1, &info);
345         }
346 }
347
348 /*---------------------------------------------------------------------------*
349  *      FSM function: received INFO 0 in state F7 or F8
350  *---------------------------------------------------------------------------*/ 
351 static void
352 F_I03(struct l1_softc *sc)
353 {
354         NDBGL1(L1_F_MSG, "FSM function F_I03 executing");
355
356         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
357                 i4b_l1_ph_deactivate_ind(L0IFPI2UNIT(sc->sc_unit));
358
359         T4_start(sc);
360         
361         if(sc->sc_trace & TRACE_I)
362         {
363                 i4b_trace_hdr_t hdr;
364                 char info = INFO0;
365                 
366                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
367                 hdr.type = TRC_CH_I;
368                 hdr.dir = FROM_NT;
369                 hdr.count = 0;
370                 MICROTIME(hdr.time);
371                 i4b_l1_trace_ind(&hdr, 1, &info);
372         }
373 }
374
375 /*---------------------------------------------------------------------------*
376  *      FSM function: activate request
377  *---------------------------------------------------------------------------*/ 
378 static void
379 F_AR(struct l1_softc *sc)
380 {
381         NDBGL1(L1_F_MSG, "FSM function F_AR executing");
382
383         if(sc->sc_trace & TRACE_I)
384         {
385                 i4b_trace_hdr_t hdr;
386                 char info = INFO1_8;
387                 
388                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
389                 hdr.type = TRC_CH_I;
390                 hdr.dir = FROM_TE;
391                 hdr.count = 0;
392                 MICROTIME(hdr.time);
393                 i4b_l1_trace_ind(&hdr, 1, &info);
394         }
395
396         ifpi2_isacsx_l1_cmd(sc, CMD_AR8);
397
398         T3_start(sc);
399 }
400
401 /*---------------------------------------------------------------------------*
402  *      FSM function: received INFO2
403  *---------------------------------------------------------------------------*/ 
404 static void
405 F_I2(struct l1_softc *sc)
406 {
407         NDBGL1(L1_F_MSG, "FSM function F_I2 executing");
408
409         if(sc->sc_trace & TRACE_I)
410         {
411                 i4b_trace_hdr_t hdr;
412                 char info = INFO2;
413                 
414                 hdr.unit = L0IFPI2UNIT(sc->sc_unit);
415                 hdr.type = TRC_CH_I;
416                 hdr.dir = FROM_NT;
417                 hdr.count = 0;
418                 MICROTIME(hdr.time);
419                 i4b_l1_trace_ind(&hdr, 1, &info);
420         }               
421
422 }
423
424 /*---------------------------------------------------------------------------*
425  *      illegal state default action
426  *---------------------------------------------------------------------------*/ 
427 static void
428 F_ill(struct l1_softc *sc)
429 {
430         NDBGL1(L1_F_ERR, "FSM function F_ill executing");
431 }
432
433 /*---------------------------------------------------------------------------*
434  *      No action
435  *---------------------------------------------------------------------------*/ 
436 static void
437 F_NULL(struct l1_softc *sc)
438 {
439         NDBGL1(L1_F_MSG, "FSM function F_NULL executing");
440 }
441
442
443 /*---------------------------------------------------------------------------*
444  *      layer 1 state transition table
445  *---------------------------------------------------------------------------*/ 
446 struct ifpi2_state_tab {
447         void (*func) (struct l1_softc *sc);     /* function to execute */
448         int newstate;                           /* next state */
449 } ifpi2_state_tab[N_EVENTS][N_STATES] = {
450
451 /* STATE:       F3                      F4                      F5                      F6                      F7                      F8                      ILLEGAL STATE     */
452 /* -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
453 /* 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}},
454 /* 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}},
455 /* 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}},
456 /* 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}},
457 /* 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}},
458 /* 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}},
459 /* 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}},
460 /* 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}},
461 /* 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}},
462 /* 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}},
463 /* 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}},
464 /* 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}}
465 };
466
467 /*---------------------------------------------------------------------------*
468  *      event handler
469  *---------------------------------------------------------------------------*/ 
470 void
471 ifpi2_next_state(struct l1_softc *sc, int event)
472 {
473         int currstate, newstate;
474
475         if(event >= N_EVENTS)
476                 panic("i4b_l1fsm.c: event >= N_EVENTS\n");
477
478         currstate = sc->sc_I430state;
479
480         if(currstate >= N_STATES)
481                 panic("i4b_l1fsm.c: currstate >= N_STATES\n");  
482
483         newstate = ifpi2_state_tab[event][currstate].newstate;
484
485         if(newstate >= N_STATES)
486                 panic("i4b_l1fsm.c: newstate >= N_STATES\n");   
487         
488         NDBGL1(L1_F_MSG, "FSM event [%s]: [%s => %s]", event_text[event],
489                                            state_text[currstate],
490                                            state_text[newstate]);
491
492         (*ifpi2_state_tab[event][currstate].func)(sc);
493
494         if(newstate == ST_ILL)
495         {
496                 newstate = ST_F3;
497                 NDBGL1(L1_F_ERR, "FSM Illegal State ERROR, oldstate = %s, newstate = %s, event = %s!",
498                                         state_text[currstate],
499                                         state_text[newstate],
500                                         event_text[event]);
501         }
502
503         sc->sc_I430state = newstate;
504 }
505
506 #if DO_I4B_DEBUG
507 /*---------------------------------------------------------------------------*
508  *      return pointer to current state description
509  *---------------------------------------------------------------------------*/ 
510 char *
511 ifpi2_printstate(struct l1_softc *sc)
512 {
513         return((char *) state_text[sc->sc_I430state]);
514 }
515 #endif
516         
517 #endif /* NIFPI2 > 0 */