1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Author Karsten Keil <kkeil@novell.com>
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright 2008 by Karsten Keil <kkeil@novell.com>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/mISDNhw.h>
13*4882a593Smuzhiyun #include "core.h"
14*4882a593Smuzhiyun #include "layer1.h"
15*4882a593Smuzhiyun #include "fsm.h"
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun static u_int *debug;
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun struct layer1 {
20*4882a593Smuzhiyun u_long Flags;
21*4882a593Smuzhiyun struct FsmInst l1m;
22*4882a593Smuzhiyun struct FsmTimer timer3;
23*4882a593Smuzhiyun struct FsmTimer timerX;
24*4882a593Smuzhiyun int delay;
25*4882a593Smuzhiyun int t3_value;
26*4882a593Smuzhiyun struct dchannel *dch;
27*4882a593Smuzhiyun dchannel_l1callback *dcb;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define TIMER3_DEFAULT_VALUE 7000
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun static
33*4882a593Smuzhiyun struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL};
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun enum {
36*4882a593Smuzhiyun ST_L1_F2,
37*4882a593Smuzhiyun ST_L1_F3,
38*4882a593Smuzhiyun ST_L1_F4,
39*4882a593Smuzhiyun ST_L1_F5,
40*4882a593Smuzhiyun ST_L1_F6,
41*4882a593Smuzhiyun ST_L1_F7,
42*4882a593Smuzhiyun ST_L1_F8,
43*4882a593Smuzhiyun };
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #define L1S_STATE_COUNT (ST_L1_F8 + 1)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun static char *strL1SState[] =
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun "ST_L1_F2",
50*4882a593Smuzhiyun "ST_L1_F3",
51*4882a593Smuzhiyun "ST_L1_F4",
52*4882a593Smuzhiyun "ST_L1_F5",
53*4882a593Smuzhiyun "ST_L1_F6",
54*4882a593Smuzhiyun "ST_L1_F7",
55*4882a593Smuzhiyun "ST_L1_F8",
56*4882a593Smuzhiyun };
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun enum {
59*4882a593Smuzhiyun EV_PH_ACTIVATE,
60*4882a593Smuzhiyun EV_PH_DEACTIVATE,
61*4882a593Smuzhiyun EV_RESET_IND,
62*4882a593Smuzhiyun EV_DEACT_CNF,
63*4882a593Smuzhiyun EV_DEACT_IND,
64*4882a593Smuzhiyun EV_POWER_UP,
65*4882a593Smuzhiyun EV_ANYSIG_IND,
66*4882a593Smuzhiyun EV_INFO2_IND,
67*4882a593Smuzhiyun EV_INFO4_IND,
68*4882a593Smuzhiyun EV_TIMER_DEACT,
69*4882a593Smuzhiyun EV_TIMER_ACT,
70*4882a593Smuzhiyun EV_TIMER3,
71*4882a593Smuzhiyun };
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun #define L1_EVENT_COUNT (EV_TIMER3 + 1)
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun static char *strL1Event[] =
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun "EV_PH_ACTIVATE",
78*4882a593Smuzhiyun "EV_PH_DEACTIVATE",
79*4882a593Smuzhiyun "EV_RESET_IND",
80*4882a593Smuzhiyun "EV_DEACT_CNF",
81*4882a593Smuzhiyun "EV_DEACT_IND",
82*4882a593Smuzhiyun "EV_POWER_UP",
83*4882a593Smuzhiyun "EV_ANYSIG_IND",
84*4882a593Smuzhiyun "EV_INFO2_IND",
85*4882a593Smuzhiyun "EV_INFO4_IND",
86*4882a593Smuzhiyun "EV_TIMER_DEACT",
87*4882a593Smuzhiyun "EV_TIMER_ACT",
88*4882a593Smuzhiyun "EV_TIMER3",
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun static void
l1m_debug(struct FsmInst * fi,char * fmt,...)92*4882a593Smuzhiyun l1m_debug(struct FsmInst *fi, char *fmt, ...)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
95*4882a593Smuzhiyun struct va_format vaf;
96*4882a593Smuzhiyun va_list va;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun va_start(va, fmt);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun vaf.fmt = fmt;
101*4882a593Smuzhiyun vaf.va = &va;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun va_end(va);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun static void
l1_reset(struct FsmInst * fi,int event,void * arg)109*4882a593Smuzhiyun l1_reset(struct FsmInst *fi, int event, void *arg)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F3);
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun static void
l1_deact_cnf(struct FsmInst * fi,int event,void * arg)115*4882a593Smuzhiyun l1_deact_cnf(struct FsmInst *fi, int event, void *arg)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F3);
120*4882a593Smuzhiyun if (test_bit(FLG_L1_ACTIVATING, &l1->Flags))
121*4882a593Smuzhiyun l1->dcb(l1->dch, HW_POWERUP_REQ);
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun static void
l1_deact_req_s(struct FsmInst * fi,int event,void * arg)125*4882a593Smuzhiyun l1_deact_req_s(struct FsmInst *fi, int event, void *arg)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F3);
130*4882a593Smuzhiyun mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2);
131*4882a593Smuzhiyun test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun static void
l1_power_up_s(struct FsmInst * fi,int event,void * arg)135*4882a593Smuzhiyun l1_power_up_s(struct FsmInst *fi, int event, void *arg)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
140*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F4);
141*4882a593Smuzhiyun l1->dcb(l1->dch, INFO3_P8);
142*4882a593Smuzhiyun } else
143*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F3);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun static void
l1_go_F5(struct FsmInst * fi,int event,void * arg)147*4882a593Smuzhiyun l1_go_F5(struct FsmInst *fi, int event, void *arg)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F5);
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun static void
l1_go_F8(struct FsmInst * fi,int event,void * arg)153*4882a593Smuzhiyun l1_go_F8(struct FsmInst *fi, int event, void *arg)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F8);
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun static void
l1_info2_ind(struct FsmInst * fi,int event,void * arg)159*4882a593Smuzhiyun l1_info2_ind(struct FsmInst *fi, int event, void *arg)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F6);
164*4882a593Smuzhiyun l1->dcb(l1->dch, INFO3_P8);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun static void
l1_info4_ind(struct FsmInst * fi,int event,void * arg)168*4882a593Smuzhiyun l1_info4_ind(struct FsmInst *fi, int event, void *arg)
169*4882a593Smuzhiyun {
170*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F7);
173*4882a593Smuzhiyun l1->dcb(l1->dch, INFO3_P8);
174*4882a593Smuzhiyun if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags))
175*4882a593Smuzhiyun mISDN_FsmDelTimer(&l1->timerX, 4);
176*4882a593Smuzhiyun if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) {
177*4882a593Smuzhiyun if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags))
178*4882a593Smuzhiyun mISDN_FsmDelTimer(&l1->timer3, 3);
179*4882a593Smuzhiyun mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2);
180*4882a593Smuzhiyun test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun static void
l1_timer3(struct FsmInst * fi,int event,void * arg)185*4882a593Smuzhiyun l1_timer3(struct FsmInst *fi, int event, void *arg)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags);
190*4882a593Smuzhiyun if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) {
191*4882a593Smuzhiyun if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
192*4882a593Smuzhiyun l1->dcb(l1->dch, HW_D_NOBLOCKED);
193*4882a593Smuzhiyun l1->dcb(l1->dch, PH_DEACTIVATE_IND);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun if (l1->l1m.state != ST_L1_F6) {
196*4882a593Smuzhiyun mISDN_FsmChangeState(fi, ST_L1_F3);
197*4882a593Smuzhiyun /* do not force anything here, we need send INFO 0 */
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun static void
l1_timer_act(struct FsmInst * fi,int event,void * arg)202*4882a593Smuzhiyun l1_timer_act(struct FsmInst *fi, int event, void *arg)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags);
207*4882a593Smuzhiyun test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags);
208*4882a593Smuzhiyun l1->dcb(l1->dch, PH_ACTIVATE_IND);
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun static void
l1_timer_deact(struct FsmInst * fi,int event,void * arg)212*4882a593Smuzhiyun l1_timer_deact(struct FsmInst *fi, int event, void *arg)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags);
217*4882a593Smuzhiyun test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags);
218*4882a593Smuzhiyun if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
219*4882a593Smuzhiyun l1->dcb(l1->dch, HW_D_NOBLOCKED);
220*4882a593Smuzhiyun l1->dcb(l1->dch, PH_DEACTIVATE_IND);
221*4882a593Smuzhiyun l1->dcb(l1->dch, HW_DEACT_REQ);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun static void
l1_activate_s(struct FsmInst * fi,int event,void * arg)225*4882a593Smuzhiyun l1_activate_s(struct FsmInst *fi, int event, void *arg)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
228*4882a593Smuzhiyun
229*4882a593Smuzhiyun mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2);
230*4882a593Smuzhiyun test_and_set_bit(FLG_L1_T3RUN, &l1->Flags);
231*4882a593Smuzhiyun /* Tell HW to send INFO 1 */
232*4882a593Smuzhiyun l1->dcb(l1->dch, HW_RESET_REQ);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun static void
l1_activate_no(struct FsmInst * fi,int event,void * arg)236*4882a593Smuzhiyun l1_activate_no(struct FsmInst *fi, int event, void *arg)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun struct layer1 *l1 = fi->userdata;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) &&
241*4882a593Smuzhiyun (!test_bit(FLG_L1_T3RUN, &l1->Flags))) {
242*4882a593Smuzhiyun test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags);
243*4882a593Smuzhiyun if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags))
244*4882a593Smuzhiyun l1->dcb(l1->dch, HW_D_NOBLOCKED);
245*4882a593Smuzhiyun l1->dcb(l1->dch, PH_DEACTIVATE_IND);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun static struct FsmNode L1SFnList[] =
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s},
252*4882a593Smuzhiyun {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no},
253*4882a593Smuzhiyun {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no},
254*4882a593Smuzhiyun {ST_L1_F3, EV_RESET_IND, l1_reset},
255*4882a593Smuzhiyun {ST_L1_F4, EV_RESET_IND, l1_reset},
256*4882a593Smuzhiyun {ST_L1_F5, EV_RESET_IND, l1_reset},
257*4882a593Smuzhiyun {ST_L1_F6, EV_RESET_IND, l1_reset},
258*4882a593Smuzhiyun {ST_L1_F7, EV_RESET_IND, l1_reset},
259*4882a593Smuzhiyun {ST_L1_F8, EV_RESET_IND, l1_reset},
260*4882a593Smuzhiyun {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf},
261*4882a593Smuzhiyun {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf},
262*4882a593Smuzhiyun {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf},
263*4882a593Smuzhiyun {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf},
264*4882a593Smuzhiyun {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf},
265*4882a593Smuzhiyun {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf},
266*4882a593Smuzhiyun {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s},
267*4882a593Smuzhiyun {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s},
268*4882a593Smuzhiyun {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s},
269*4882a593Smuzhiyun {ST_L1_F3, EV_POWER_UP, l1_power_up_s},
270*4882a593Smuzhiyun {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5},
271*4882a593Smuzhiyun {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8},
272*4882a593Smuzhiyun {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8},
273*4882a593Smuzhiyun {ST_L1_F3, EV_INFO2_IND, l1_info2_ind},
274*4882a593Smuzhiyun {ST_L1_F4, EV_INFO2_IND, l1_info2_ind},
275*4882a593Smuzhiyun {ST_L1_F5, EV_INFO2_IND, l1_info2_ind},
276*4882a593Smuzhiyun {ST_L1_F7, EV_INFO2_IND, l1_info2_ind},
277*4882a593Smuzhiyun {ST_L1_F8, EV_INFO2_IND, l1_info2_ind},
278*4882a593Smuzhiyun {ST_L1_F3, EV_INFO4_IND, l1_info4_ind},
279*4882a593Smuzhiyun {ST_L1_F4, EV_INFO4_IND, l1_info4_ind},
280*4882a593Smuzhiyun {ST_L1_F5, EV_INFO4_IND, l1_info4_ind},
281*4882a593Smuzhiyun {ST_L1_F6, EV_INFO4_IND, l1_info4_ind},
282*4882a593Smuzhiyun {ST_L1_F8, EV_INFO4_IND, l1_info4_ind},
283*4882a593Smuzhiyun {ST_L1_F3, EV_TIMER3, l1_timer3},
284*4882a593Smuzhiyun {ST_L1_F4, EV_TIMER3, l1_timer3},
285*4882a593Smuzhiyun {ST_L1_F5, EV_TIMER3, l1_timer3},
286*4882a593Smuzhiyun {ST_L1_F6, EV_TIMER3, l1_timer3},
287*4882a593Smuzhiyun {ST_L1_F8, EV_TIMER3, l1_timer3},
288*4882a593Smuzhiyun {ST_L1_F7, EV_TIMER_ACT, l1_timer_act},
289*4882a593Smuzhiyun {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact},
290*4882a593Smuzhiyun {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact},
291*4882a593Smuzhiyun {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact},
292*4882a593Smuzhiyun {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact},
293*4882a593Smuzhiyun {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact},
294*4882a593Smuzhiyun {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
295*4882a593Smuzhiyun };
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun static void
release_l1(struct layer1 * l1)298*4882a593Smuzhiyun release_l1(struct layer1 *l1) {
299*4882a593Smuzhiyun mISDN_FsmDelTimer(&l1->timerX, 0);
300*4882a593Smuzhiyun mISDN_FsmDelTimer(&l1->timer3, 0);
301*4882a593Smuzhiyun if (l1->dch)
302*4882a593Smuzhiyun l1->dch->l1 = NULL;
303*4882a593Smuzhiyun module_put(THIS_MODULE);
304*4882a593Smuzhiyun kfree(l1);
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun int
l1_event(struct layer1 * l1,u_int event)308*4882a593Smuzhiyun l1_event(struct layer1 *l1, u_int event)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun int err = 0;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun if (!l1)
313*4882a593Smuzhiyun return -EINVAL;
314*4882a593Smuzhiyun switch (event) {
315*4882a593Smuzhiyun case HW_RESET_IND:
316*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL);
317*4882a593Smuzhiyun break;
318*4882a593Smuzhiyun case HW_DEACT_IND:
319*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL);
320*4882a593Smuzhiyun break;
321*4882a593Smuzhiyun case HW_POWERUP_IND:
322*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL);
323*4882a593Smuzhiyun break;
324*4882a593Smuzhiyun case HW_DEACT_CNF:
325*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL);
326*4882a593Smuzhiyun break;
327*4882a593Smuzhiyun case ANYSIGNAL:
328*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
329*4882a593Smuzhiyun break;
330*4882a593Smuzhiyun case LOSTFRAMING:
331*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL);
332*4882a593Smuzhiyun break;
333*4882a593Smuzhiyun case INFO2:
334*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL);
335*4882a593Smuzhiyun break;
336*4882a593Smuzhiyun case INFO4_P8:
337*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
338*4882a593Smuzhiyun break;
339*4882a593Smuzhiyun case INFO4_P10:
340*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL);
341*4882a593Smuzhiyun break;
342*4882a593Smuzhiyun case PH_ACTIVATE_REQ:
343*4882a593Smuzhiyun if (test_bit(FLG_L1_ACTIVATED, &l1->Flags))
344*4882a593Smuzhiyun l1->dcb(l1->dch, PH_ACTIVATE_IND);
345*4882a593Smuzhiyun else {
346*4882a593Smuzhiyun test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags);
347*4882a593Smuzhiyun mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL);
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun break;
350*4882a593Smuzhiyun case CLOSE_CHANNEL:
351*4882a593Smuzhiyun release_l1(l1);
352*4882a593Smuzhiyun break;
353*4882a593Smuzhiyun default:
354*4882a593Smuzhiyun if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) {
355*4882a593Smuzhiyun int val = event & HW_TIMER3_VMASK;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (val < 5)
358*4882a593Smuzhiyun val = 5;
359*4882a593Smuzhiyun if (val > 30)
360*4882a593Smuzhiyun val = 30;
361*4882a593Smuzhiyun l1->t3_value = val;
362*4882a593Smuzhiyun break;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun if (*debug & DEBUG_L1)
365*4882a593Smuzhiyun printk(KERN_DEBUG "%s %x unhandled\n",
366*4882a593Smuzhiyun __func__, event);
367*4882a593Smuzhiyun err = -EINVAL;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun return err;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun EXPORT_SYMBOL(l1_event);
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun int
create_l1(struct dchannel * dch,dchannel_l1callback * dcb)374*4882a593Smuzhiyun create_l1(struct dchannel *dch, dchannel_l1callback *dcb) {
375*4882a593Smuzhiyun struct layer1 *nl1;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC);
378*4882a593Smuzhiyun if (!nl1) {
379*4882a593Smuzhiyun printk(KERN_ERR "kmalloc struct layer1 failed\n");
380*4882a593Smuzhiyun return -ENOMEM;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun nl1->l1m.fsm = &l1fsm_s;
383*4882a593Smuzhiyun nl1->l1m.state = ST_L1_F3;
384*4882a593Smuzhiyun nl1->Flags = 0;
385*4882a593Smuzhiyun nl1->t3_value = TIMER3_DEFAULT_VALUE;
386*4882a593Smuzhiyun nl1->l1m.debug = *debug & DEBUG_L1_FSM;
387*4882a593Smuzhiyun nl1->l1m.userdata = nl1;
388*4882a593Smuzhiyun nl1->l1m.userint = 0;
389*4882a593Smuzhiyun nl1->l1m.printdebug = l1m_debug;
390*4882a593Smuzhiyun nl1->dch = dch;
391*4882a593Smuzhiyun nl1->dcb = dcb;
392*4882a593Smuzhiyun mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3);
393*4882a593Smuzhiyun mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX);
394*4882a593Smuzhiyun __module_get(THIS_MODULE);
395*4882a593Smuzhiyun dch->l1 = nl1;
396*4882a593Smuzhiyun return 0;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun EXPORT_SYMBOL(create_l1);
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun int
Isdnl1_Init(u_int * deb)401*4882a593Smuzhiyun Isdnl1_Init(u_int *deb)
402*4882a593Smuzhiyun {
403*4882a593Smuzhiyun debug = deb;
404*4882a593Smuzhiyun l1fsm_s.state_count = L1S_STATE_COUNT;
405*4882a593Smuzhiyun l1fsm_s.event_count = L1_EVENT_COUNT;
406*4882a593Smuzhiyun l1fsm_s.strEvent = strL1Event;
407*4882a593Smuzhiyun l1fsm_s.strState = strL1SState;
408*4882a593Smuzhiyun return mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun void
Isdnl1_cleanup(void)412*4882a593Smuzhiyun Isdnl1_cleanup(void)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun mISDN_FsmFree(&l1fsm_s);
415*4882a593Smuzhiyun }
416