binutils/ld: Don't add /usr/lib to the library search path twice.
[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.6 2005/06/03 16:50:00 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 #include <sys/thread2.h>
49
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 "../i4b_l1.h"
59 #include "../../include/i4b_global.h"
60 #include "../../include/i4b_mbuf.h"
61
62 #include "i4b_ifpi_ext.h"
63
64 #if DO_I4B_DEBUG
65 static char *state_text[N_STATES] = {
66         "F3 Deactivated",
67         "F4 Awaiting Signal",
68         "F5 Identifying Input",
69         "F6 Synchronized",
70         "F7 Activated",
71         "F8 Lost Framing",
72         "Illegal State" 
73 };
74
75 static char *event_text[N_EVENTS] = {
76         "EV_PHAR PH_ACT_REQ",
77         "EV_T3 Timer 3 expired",
78         "EV_INFO0 INFO0 received",
79         "EV_RSY Level Detected",
80         "EV_INFO2 INFO2 received",
81         "EV_INFO48 INFO4 received",
82         "EV_INFO410 INFO4 received",
83         "EV_DR Deactivate Req",
84         "EV_PU Power UP",
85         "EV_DIS Disconnected",
86         "EV_EI Error Ind",
87         "Illegal Event"
88 };
89 #endif
90
91 /* Function prototypes */
92
93 static void timer3_expired (struct l1_softc *sc);
94 static void T3_start (struct l1_softc *sc);
95 static void T3_stop (struct l1_softc *sc);
96 static void F_T3ex (struct l1_softc *sc);
97 static void timer4_expired (struct l1_softc *sc);
98 static void T4_start (struct l1_softc *sc);
99 static void T4_stop (struct l1_softc *sc);
100 static void F_AI8 (struct l1_softc *sc);
101 static void F_AI10 (struct l1_softc *sc);
102 static void F_I01 (struct l1_softc *sc);
103 static void F_I02 (struct l1_softc *sc);
104 static void F_I03 (struct l1_softc *sc);
105 static void F_I2 (struct l1_softc *sc);
106 static void F_ill (struct l1_softc *sc);
107 static void F_NULL (struct l1_softc *sc);
108
109 /*---------------------------------------------------------------------------*
110  *      I.430 Timer T3 expire function
111  *---------------------------------------------------------------------------*/ 
112 static void
113 timer3_expired(struct l1_softc *sc)
114 {
115         if(sc->sc_I430T3)
116         {
117                 NDBGL1(L1_T_ERR, "state = %s", ifpi_printstate(sc));
118                 sc->sc_I430T3 = 0;
119
120                 /* XXX try some recovery here XXX */
121
122                 ifpi_recover(sc);
123
124                 sc->sc_init_tries++;    /* increment retry count */
125
126 /*XXX*/         if(sc->sc_init_tries > 4)
127                 {
128                         crit_enter();
129
130                         sc->sc_init_tries = 0;
131                         
132                         if(sc->sc_obuf2 != NULL)
133                         {
134                                 i4b_Dfreembuf(sc->sc_obuf2);
135                                 sc->sc_obuf2 = NULL;
136                         }
137                         if(sc->sc_obuf != NULL)
138                         {
139                                 i4b_Dfreembuf(sc->sc_obuf);
140                                 sc->sc_obuf = NULL;
141                                 sc->sc_freeflag = 0;
142                                 sc->sc_op = NULL;
143                                 sc->sc_ol = 0;
144                         }
145
146                         crit_exit();
147
148                         i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_NOL1ACC, 0, NULL);
149                 }
150                 
151                 ifpi_next_state(sc, EV_T3);             
152         }
153         else
154         {
155                 NDBGL1(L1_T_ERR, "expired without starting it ....");
156         }
157 }
158
159 /*---------------------------------------------------------------------------*
160  *      I.430 Timer T3 start
161  *---------------------------------------------------------------------------*/ 
162 static void
163 T3_start(struct l1_softc *sc)
164 {
165         NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
166         sc->sc_I430T3 = 1;
167         callout_reset(&sc->sc_T3_timeout, 2 * hz,
168                         (TIMEOUT_FUNC_T)timer3_expired, (struct l1_softc *)sc);
169 }
170
171 /*---------------------------------------------------------------------------*
172  *      I.430 Timer T3 stop
173  *---------------------------------------------------------------------------*/ 
174 static void
175 T3_stop(struct l1_softc *sc)
176 {
177         NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
178
179         sc->sc_init_tries = 0;  /* init connect retry count */
180         
181         if(sc->sc_I430T3)
182         {
183                 sc->sc_I430T3 = 0;
184                 callout_stop(&sc->sc_T3_timeout);
185         }
186 }
187
188 /*---------------------------------------------------------------------------*
189  *      I.430 Timer T3 expiry
190  *---------------------------------------------------------------------------*/ 
191 static void
192 F_T3ex(struct l1_softc *sc)
193 {
194         NDBGL1(L1_F_MSG, "FSM function F_T3ex executing");
195         if(ctrl_desc[sc->sc_unit].protocol != PROTOCOL_D64S)
196                 i4b_l1_ph_deactivate_ind(L0IFPIUNIT(sc->sc_unit));
197 }
198
199 /*---------------------------------------------------------------------------*
200  *      Timer T4 expire function
201  *---------------------------------------------------------------------------*/ 
202 static void
203 timer4_expired(struct l1_softc *sc)
204 {
205         if(sc->sc_I430T4)
206         {
207                 NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
208                 sc->sc_I430T4 = 0;
209                 i4b_l1_mph_status_ind(L0IFPIUNIT(sc->sc_unit), STI_PDEACT, 0, NULL);
210         }
211         else
212         {
213                 NDBGL1(L1_T_ERR, "expired without starting it ....");
214         }
215 }
216
217 /*---------------------------------------------------------------------------*
218  *      Timer T4 start
219  *---------------------------------------------------------------------------*/ 
220 static void
221 T4_start(struct l1_softc *sc)
222 {
223         NDBGL1(L1_T_MSG, "state = %s", ifpi_printstate(sc));
224         sc->sc_I430T4 = 1;
225         callout_reset(&sc->sc_T4_timeout, hz,
226                         (TIMEOUT_FUNC_T)timer4_expired, (struct l1_softc *)sc);
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", ifpi_printstate(sc));
236
237         if(sc->sc_I430T4)
238         {
239                 sc->sc_I430T4 = 0;
240                 callout_stop(&sc->sc_T4_timeout);
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(L0IFPIUNIT(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 = L0IFPIUNIT(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(L0IFPIUNIT(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 = L0IFPIUNIT(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 = L0IFPIUNIT(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(L0IFPIUNIT(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 = L0IFPIUNIT(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(L0IFPIUNIT(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 = L0IFPIUNIT(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 = L0IFPIUNIT(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         ifpi_isac_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 = L0IFPIUNIT(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 ifpi_state_tab {
448         void (*func) (struct l1_softc *sc);     /* function to execute */
449         int newstate;                           /* next state */
450 } ifpi_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 ifpi_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 = ifpi_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         (*ifpi_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 ifpi_printstate(struct l1_softc *sc)
513 {
514         return((char *) state_text[sc->sc_I430state]);
515 }
516 #endif
517         
518 #endif /* NIFPI > 0 */