162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Author Karsten Keil <kkeil@novell.com> 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright 2008 by Karsten Keil <kkeil@novell.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/slab.h> 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/mISDNhw.h> 1362306a36Sopenharmony_ci#include "core.h" 1462306a36Sopenharmony_ci#include "layer1.h" 1562306a36Sopenharmony_ci#include "fsm.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistatic u_int *debug; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct layer1 { 2062306a36Sopenharmony_ci u_long Flags; 2162306a36Sopenharmony_ci struct FsmInst l1m; 2262306a36Sopenharmony_ci struct FsmTimer timer3; 2362306a36Sopenharmony_ci struct FsmTimer timerX; 2462306a36Sopenharmony_ci int delay; 2562306a36Sopenharmony_ci int t3_value; 2662306a36Sopenharmony_ci struct dchannel *dch; 2762306a36Sopenharmony_ci dchannel_l1callback *dcb; 2862306a36Sopenharmony_ci}; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#define TIMER3_DEFAULT_VALUE 7000 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic 3362306a36Sopenharmony_cistruct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cienum { 3662306a36Sopenharmony_ci ST_L1_F2, 3762306a36Sopenharmony_ci ST_L1_F3, 3862306a36Sopenharmony_ci ST_L1_F4, 3962306a36Sopenharmony_ci ST_L1_F5, 4062306a36Sopenharmony_ci ST_L1_F6, 4162306a36Sopenharmony_ci ST_L1_F7, 4262306a36Sopenharmony_ci ST_L1_F8, 4362306a36Sopenharmony_ci}; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define L1S_STATE_COUNT (ST_L1_F8 + 1) 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic char *strL1SState[] = 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci "ST_L1_F2", 5062306a36Sopenharmony_ci "ST_L1_F3", 5162306a36Sopenharmony_ci "ST_L1_F4", 5262306a36Sopenharmony_ci "ST_L1_F5", 5362306a36Sopenharmony_ci "ST_L1_F6", 5462306a36Sopenharmony_ci "ST_L1_F7", 5562306a36Sopenharmony_ci "ST_L1_F8", 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cienum { 5962306a36Sopenharmony_ci EV_PH_ACTIVATE, 6062306a36Sopenharmony_ci EV_PH_DEACTIVATE, 6162306a36Sopenharmony_ci EV_RESET_IND, 6262306a36Sopenharmony_ci EV_DEACT_CNF, 6362306a36Sopenharmony_ci EV_DEACT_IND, 6462306a36Sopenharmony_ci EV_POWER_UP, 6562306a36Sopenharmony_ci EV_ANYSIG_IND, 6662306a36Sopenharmony_ci EV_INFO2_IND, 6762306a36Sopenharmony_ci EV_INFO4_IND, 6862306a36Sopenharmony_ci EV_TIMER_DEACT, 6962306a36Sopenharmony_ci EV_TIMER_ACT, 7062306a36Sopenharmony_ci EV_TIMER3, 7162306a36Sopenharmony_ci}; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define L1_EVENT_COUNT (EV_TIMER3 + 1) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic char *strL1Event[] = 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci "EV_PH_ACTIVATE", 7862306a36Sopenharmony_ci "EV_PH_DEACTIVATE", 7962306a36Sopenharmony_ci "EV_RESET_IND", 8062306a36Sopenharmony_ci "EV_DEACT_CNF", 8162306a36Sopenharmony_ci "EV_DEACT_IND", 8262306a36Sopenharmony_ci "EV_POWER_UP", 8362306a36Sopenharmony_ci "EV_ANYSIG_IND", 8462306a36Sopenharmony_ci "EV_INFO2_IND", 8562306a36Sopenharmony_ci "EV_INFO4_IND", 8662306a36Sopenharmony_ci "EV_TIMER_DEACT", 8762306a36Sopenharmony_ci "EV_TIMER_ACT", 8862306a36Sopenharmony_ci "EV_TIMER3", 8962306a36Sopenharmony_ci}; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic void 9262306a36Sopenharmony_cil1m_debug(struct FsmInst *fi, char *fmt, ...) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 9562306a36Sopenharmony_ci struct va_format vaf; 9662306a36Sopenharmony_ci va_list va; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci va_start(va, fmt); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci vaf.fmt = fmt; 10162306a36Sopenharmony_ci vaf.va = &va; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci va_end(va); 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic void 10962306a36Sopenharmony_cil1_reset(struct FsmInst *fi, int event, void *arg) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic void 11562306a36Sopenharmony_cil1_deact_cnf(struct FsmInst *fi, int event, void *arg) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 12062306a36Sopenharmony_ci if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) 12162306a36Sopenharmony_ci l1->dcb(l1->dch, HW_POWERUP_REQ); 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic void 12562306a36Sopenharmony_cil1_deact_req_s(struct FsmInst *fi, int event, void *arg) 12662306a36Sopenharmony_ci{ 12762306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 13062306a36Sopenharmony_ci mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2); 13162306a36Sopenharmony_ci test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic void 13562306a36Sopenharmony_cil1_power_up_s(struct FsmInst *fi, int event, void *arg) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 14062306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F4); 14162306a36Sopenharmony_ci l1->dcb(l1->dch, INFO3_P8); 14262306a36Sopenharmony_ci } else 14362306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 14462306a36Sopenharmony_ci} 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistatic void 14762306a36Sopenharmony_cil1_go_F5(struct FsmInst *fi, int event, void *arg) 14862306a36Sopenharmony_ci{ 14962306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F5); 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic void 15362306a36Sopenharmony_cil1_go_F8(struct FsmInst *fi, int event, void *arg) 15462306a36Sopenharmony_ci{ 15562306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F8); 15662306a36Sopenharmony_ci} 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_cistatic void 15962306a36Sopenharmony_cil1_info2_ind(struct FsmInst *fi, int event, void *arg) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F6); 16462306a36Sopenharmony_ci l1->dcb(l1->dch, INFO3_P8); 16562306a36Sopenharmony_ci} 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic void 16862306a36Sopenharmony_cil1_info4_ind(struct FsmInst *fi, int event, void *arg) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F7); 17362306a36Sopenharmony_ci l1->dcb(l1->dch, INFO3_P8); 17462306a36Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 17562306a36Sopenharmony_ci mISDN_FsmDelTimer(&l1->timerX, 4); 17662306a36Sopenharmony_ci if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 17762306a36Sopenharmony_ci if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 17862306a36Sopenharmony_ci mISDN_FsmDelTimer(&l1->timer3, 3); 17962306a36Sopenharmony_ci mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2); 18062306a36Sopenharmony_ci test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic void 18562306a36Sopenharmony_cil1_timer3(struct FsmInst *fi, int event, void *arg) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); 19062306a36Sopenharmony_ci if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 19162306a36Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 19262306a36Sopenharmony_ci l1->dcb(l1->dch, HW_D_NOBLOCKED); 19362306a36Sopenharmony_ci l1->dcb(l1->dch, PH_DEACTIVATE_IND); 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci if (l1->l1m.state != ST_L1_F6) { 19662306a36Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 19762306a36Sopenharmony_ci /* do not force anything here, we need send INFO 0 */ 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic void 20262306a36Sopenharmony_cil1_timer_act(struct FsmInst *fi, int event, void *arg) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); 20762306a36Sopenharmony_ci test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); 20862306a36Sopenharmony_ci l1->dcb(l1->dch, PH_ACTIVATE_IND); 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic void 21262306a36Sopenharmony_cil1_timer_deact(struct FsmInst *fi, int event, void *arg) 21362306a36Sopenharmony_ci{ 21462306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); 21762306a36Sopenharmony_ci test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); 21862306a36Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 21962306a36Sopenharmony_ci l1->dcb(l1->dch, HW_D_NOBLOCKED); 22062306a36Sopenharmony_ci l1->dcb(l1->dch, PH_DEACTIVATE_IND); 22162306a36Sopenharmony_ci l1->dcb(l1->dch, HW_DEACT_REQ); 22262306a36Sopenharmony_ci} 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic void 22562306a36Sopenharmony_cil1_activate_s(struct FsmInst *fi, int event, void *arg) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2); 23062306a36Sopenharmony_ci test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); 23162306a36Sopenharmony_ci /* Tell HW to send INFO 1 */ 23262306a36Sopenharmony_ci l1->dcb(l1->dch, HW_RESET_REQ); 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_cistatic void 23662306a36Sopenharmony_cil1_activate_no(struct FsmInst *fi, int event, void *arg) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci struct layer1 *l1 = fi->userdata; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && 24162306a36Sopenharmony_ci (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { 24262306a36Sopenharmony_ci test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); 24362306a36Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 24462306a36Sopenharmony_ci l1->dcb(l1->dch, HW_D_NOBLOCKED); 24562306a36Sopenharmony_ci l1->dcb(l1->dch, PH_DEACTIVATE_IND); 24662306a36Sopenharmony_ci } 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic struct FsmNode L1SFnList[] = 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, 25262306a36Sopenharmony_ci {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, 25362306a36Sopenharmony_ci {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, 25462306a36Sopenharmony_ci {ST_L1_F3, EV_RESET_IND, l1_reset}, 25562306a36Sopenharmony_ci {ST_L1_F4, EV_RESET_IND, l1_reset}, 25662306a36Sopenharmony_ci {ST_L1_F5, EV_RESET_IND, l1_reset}, 25762306a36Sopenharmony_ci {ST_L1_F6, EV_RESET_IND, l1_reset}, 25862306a36Sopenharmony_ci {ST_L1_F7, EV_RESET_IND, l1_reset}, 25962306a36Sopenharmony_ci {ST_L1_F8, EV_RESET_IND, l1_reset}, 26062306a36Sopenharmony_ci {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, 26162306a36Sopenharmony_ci {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, 26262306a36Sopenharmony_ci {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, 26362306a36Sopenharmony_ci {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, 26462306a36Sopenharmony_ci {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, 26562306a36Sopenharmony_ci {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, 26662306a36Sopenharmony_ci {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, 26762306a36Sopenharmony_ci {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, 26862306a36Sopenharmony_ci {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, 26962306a36Sopenharmony_ci {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, 27062306a36Sopenharmony_ci {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, 27162306a36Sopenharmony_ci {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, 27262306a36Sopenharmony_ci {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, 27362306a36Sopenharmony_ci {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, 27462306a36Sopenharmony_ci {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, 27562306a36Sopenharmony_ci {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, 27662306a36Sopenharmony_ci {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, 27762306a36Sopenharmony_ci {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, 27862306a36Sopenharmony_ci {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, 27962306a36Sopenharmony_ci {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, 28062306a36Sopenharmony_ci {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, 28162306a36Sopenharmony_ci {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, 28262306a36Sopenharmony_ci {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, 28362306a36Sopenharmony_ci {ST_L1_F3, EV_TIMER3, l1_timer3}, 28462306a36Sopenharmony_ci {ST_L1_F4, EV_TIMER3, l1_timer3}, 28562306a36Sopenharmony_ci {ST_L1_F5, EV_TIMER3, l1_timer3}, 28662306a36Sopenharmony_ci {ST_L1_F6, EV_TIMER3, l1_timer3}, 28762306a36Sopenharmony_ci {ST_L1_F8, EV_TIMER3, l1_timer3}, 28862306a36Sopenharmony_ci {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, 28962306a36Sopenharmony_ci {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, 29062306a36Sopenharmony_ci {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, 29162306a36Sopenharmony_ci {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, 29262306a36Sopenharmony_ci {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, 29362306a36Sopenharmony_ci {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, 29462306a36Sopenharmony_ci {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 29562306a36Sopenharmony_ci}; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic void 29862306a36Sopenharmony_cirelease_l1(struct layer1 *l1) { 29962306a36Sopenharmony_ci mISDN_FsmDelTimer(&l1->timerX, 0); 30062306a36Sopenharmony_ci mISDN_FsmDelTimer(&l1->timer3, 0); 30162306a36Sopenharmony_ci if (l1->dch) 30262306a36Sopenharmony_ci l1->dch->l1 = NULL; 30362306a36Sopenharmony_ci module_put(THIS_MODULE); 30462306a36Sopenharmony_ci kfree(l1); 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ciint 30862306a36Sopenharmony_cil1_event(struct layer1 *l1, u_int event) 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci int err = 0; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci if (!l1) 31362306a36Sopenharmony_ci return -EINVAL; 31462306a36Sopenharmony_ci switch (event) { 31562306a36Sopenharmony_ci case HW_RESET_IND: 31662306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); 31762306a36Sopenharmony_ci break; 31862306a36Sopenharmony_ci case HW_DEACT_IND: 31962306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); 32062306a36Sopenharmony_ci break; 32162306a36Sopenharmony_ci case HW_POWERUP_IND: 32262306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); 32362306a36Sopenharmony_ci break; 32462306a36Sopenharmony_ci case HW_DEACT_CNF: 32562306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); 32662306a36Sopenharmony_ci break; 32762306a36Sopenharmony_ci case ANYSIGNAL: 32862306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 32962306a36Sopenharmony_ci break; 33062306a36Sopenharmony_ci case LOSTFRAMING: 33162306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 33262306a36Sopenharmony_ci break; 33362306a36Sopenharmony_ci case INFO2: 33462306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); 33562306a36Sopenharmony_ci break; 33662306a36Sopenharmony_ci case INFO4_P8: 33762306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 33862306a36Sopenharmony_ci break; 33962306a36Sopenharmony_ci case INFO4_P10: 34062306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 34162306a36Sopenharmony_ci break; 34262306a36Sopenharmony_ci case PH_ACTIVATE_REQ: 34362306a36Sopenharmony_ci if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) 34462306a36Sopenharmony_ci l1->dcb(l1->dch, PH_ACTIVATE_IND); 34562306a36Sopenharmony_ci else { 34662306a36Sopenharmony_ci test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); 34762306a36Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci break; 35062306a36Sopenharmony_ci case CLOSE_CHANNEL: 35162306a36Sopenharmony_ci release_l1(l1); 35262306a36Sopenharmony_ci break; 35362306a36Sopenharmony_ci default: 35462306a36Sopenharmony_ci if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { 35562306a36Sopenharmony_ci int val = event & HW_TIMER3_VMASK; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci if (val < 5) 35862306a36Sopenharmony_ci val = 5; 35962306a36Sopenharmony_ci if (val > 30) 36062306a36Sopenharmony_ci val = 30; 36162306a36Sopenharmony_ci l1->t3_value = val; 36262306a36Sopenharmony_ci break; 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci if (*debug & DEBUG_L1) 36562306a36Sopenharmony_ci printk(KERN_DEBUG "%s %x unhandled\n", 36662306a36Sopenharmony_ci __func__, event); 36762306a36Sopenharmony_ci err = -EINVAL; 36862306a36Sopenharmony_ci } 36962306a36Sopenharmony_ci return err; 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ciEXPORT_SYMBOL(l1_event); 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ciint 37462306a36Sopenharmony_cicreate_l1(struct dchannel *dch, dchannel_l1callback *dcb) { 37562306a36Sopenharmony_ci struct layer1 *nl1; 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); 37862306a36Sopenharmony_ci if (!nl1) { 37962306a36Sopenharmony_ci printk(KERN_ERR "kmalloc struct layer1 failed\n"); 38062306a36Sopenharmony_ci return -ENOMEM; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci nl1->l1m.fsm = &l1fsm_s; 38362306a36Sopenharmony_ci nl1->l1m.state = ST_L1_F3; 38462306a36Sopenharmony_ci nl1->Flags = 0; 38562306a36Sopenharmony_ci nl1->t3_value = TIMER3_DEFAULT_VALUE; 38662306a36Sopenharmony_ci nl1->l1m.debug = *debug & DEBUG_L1_FSM; 38762306a36Sopenharmony_ci nl1->l1m.userdata = nl1; 38862306a36Sopenharmony_ci nl1->l1m.userint = 0; 38962306a36Sopenharmony_ci nl1->l1m.printdebug = l1m_debug; 39062306a36Sopenharmony_ci nl1->dch = dch; 39162306a36Sopenharmony_ci nl1->dcb = dcb; 39262306a36Sopenharmony_ci mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3); 39362306a36Sopenharmony_ci mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX); 39462306a36Sopenharmony_ci __module_get(THIS_MODULE); 39562306a36Sopenharmony_ci dch->l1 = nl1; 39662306a36Sopenharmony_ci return 0; 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ciEXPORT_SYMBOL(create_l1); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ciint 40162306a36Sopenharmony_ciIsdnl1_Init(u_int *deb) 40262306a36Sopenharmony_ci{ 40362306a36Sopenharmony_ci debug = deb; 40462306a36Sopenharmony_ci l1fsm_s.state_count = L1S_STATE_COUNT; 40562306a36Sopenharmony_ci l1fsm_s.event_count = L1_EVENT_COUNT; 40662306a36Sopenharmony_ci l1fsm_s.strEvent = strL1Event; 40762306a36Sopenharmony_ci l1fsm_s.strState = strL1SState; 40862306a36Sopenharmony_ci return mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); 40962306a36Sopenharmony_ci} 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_civoid 41262306a36Sopenharmony_ciIsdnl1_cleanup(void) 41362306a36Sopenharmony_ci{ 41462306a36Sopenharmony_ci mISDN_FsmFree(&l1fsm_s); 41562306a36Sopenharmony_ci} 416