18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Author Karsten Keil <kkeil@novell.com> 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright 2008 by Karsten Keil <kkeil@novell.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/slab.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/mISDNhw.h> 138c2ecf20Sopenharmony_ci#include "core.h" 148c2ecf20Sopenharmony_ci#include "layer1.h" 158c2ecf20Sopenharmony_ci#include "fsm.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_cistatic u_int *debug; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistruct layer1 { 208c2ecf20Sopenharmony_ci u_long Flags; 218c2ecf20Sopenharmony_ci struct FsmInst l1m; 228c2ecf20Sopenharmony_ci struct FsmTimer timer3; 238c2ecf20Sopenharmony_ci struct FsmTimer timerX; 248c2ecf20Sopenharmony_ci int delay; 258c2ecf20Sopenharmony_ci int t3_value; 268c2ecf20Sopenharmony_ci struct dchannel *dch; 278c2ecf20Sopenharmony_ci dchannel_l1callback *dcb; 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define TIMER3_DEFAULT_VALUE 7000 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic 338c2ecf20Sopenharmony_cistruct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cienum { 368c2ecf20Sopenharmony_ci ST_L1_F2, 378c2ecf20Sopenharmony_ci ST_L1_F3, 388c2ecf20Sopenharmony_ci ST_L1_F4, 398c2ecf20Sopenharmony_ci ST_L1_F5, 408c2ecf20Sopenharmony_ci ST_L1_F6, 418c2ecf20Sopenharmony_ci ST_L1_F7, 428c2ecf20Sopenharmony_ci ST_L1_F8, 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define L1S_STATE_COUNT (ST_L1_F8 + 1) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cistatic char *strL1SState[] = 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci "ST_L1_F2", 508c2ecf20Sopenharmony_ci "ST_L1_F3", 518c2ecf20Sopenharmony_ci "ST_L1_F4", 528c2ecf20Sopenharmony_ci "ST_L1_F5", 538c2ecf20Sopenharmony_ci "ST_L1_F6", 548c2ecf20Sopenharmony_ci "ST_L1_F7", 558c2ecf20Sopenharmony_ci "ST_L1_F8", 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cienum { 598c2ecf20Sopenharmony_ci EV_PH_ACTIVATE, 608c2ecf20Sopenharmony_ci EV_PH_DEACTIVATE, 618c2ecf20Sopenharmony_ci EV_RESET_IND, 628c2ecf20Sopenharmony_ci EV_DEACT_CNF, 638c2ecf20Sopenharmony_ci EV_DEACT_IND, 648c2ecf20Sopenharmony_ci EV_POWER_UP, 658c2ecf20Sopenharmony_ci EV_ANYSIG_IND, 668c2ecf20Sopenharmony_ci EV_INFO2_IND, 678c2ecf20Sopenharmony_ci EV_INFO4_IND, 688c2ecf20Sopenharmony_ci EV_TIMER_DEACT, 698c2ecf20Sopenharmony_ci EV_TIMER_ACT, 708c2ecf20Sopenharmony_ci EV_TIMER3, 718c2ecf20Sopenharmony_ci}; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#define L1_EVENT_COUNT (EV_TIMER3 + 1) 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic char *strL1Event[] = 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci "EV_PH_ACTIVATE", 788c2ecf20Sopenharmony_ci "EV_PH_DEACTIVATE", 798c2ecf20Sopenharmony_ci "EV_RESET_IND", 808c2ecf20Sopenharmony_ci "EV_DEACT_CNF", 818c2ecf20Sopenharmony_ci "EV_DEACT_IND", 828c2ecf20Sopenharmony_ci "EV_POWER_UP", 838c2ecf20Sopenharmony_ci "EV_ANYSIG_IND", 848c2ecf20Sopenharmony_ci "EV_INFO2_IND", 858c2ecf20Sopenharmony_ci "EV_INFO4_IND", 868c2ecf20Sopenharmony_ci "EV_TIMER_DEACT", 878c2ecf20Sopenharmony_ci "EV_TIMER_ACT", 888c2ecf20Sopenharmony_ci "EV_TIMER3", 898c2ecf20Sopenharmony_ci}; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_cistatic void 928c2ecf20Sopenharmony_cil1m_debug(struct FsmInst *fi, char *fmt, ...) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 958c2ecf20Sopenharmony_ci struct va_format vaf; 968c2ecf20Sopenharmony_ci va_list va; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci va_start(va, fmt); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci vaf.fmt = fmt; 1018c2ecf20Sopenharmony_ci vaf.va = &va; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci va_end(va); 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic void 1098c2ecf20Sopenharmony_cil1_reset(struct FsmInst *fi, int event, void *arg) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic void 1158c2ecf20Sopenharmony_cil1_deact_cnf(struct FsmInst *fi, int event, void *arg) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 1208c2ecf20Sopenharmony_ci if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) 1218c2ecf20Sopenharmony_ci l1->dcb(l1->dch, HW_POWERUP_REQ); 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic void 1258c2ecf20Sopenharmony_cil1_deact_req_s(struct FsmInst *fi, int event, void *arg) 1268c2ecf20Sopenharmony_ci{ 1278c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 1308c2ecf20Sopenharmony_ci mISDN_FsmRestartTimer(&l1->timerX, 550, EV_TIMER_DEACT, NULL, 2); 1318c2ecf20Sopenharmony_ci test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic void 1358c2ecf20Sopenharmony_cil1_power_up_s(struct FsmInst *fi, int event, void *arg) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1408c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F4); 1418c2ecf20Sopenharmony_ci l1->dcb(l1->dch, INFO3_P8); 1428c2ecf20Sopenharmony_ci } else 1438c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic void 1478c2ecf20Sopenharmony_cil1_go_F5(struct FsmInst *fi, int event, void *arg) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F5); 1508c2ecf20Sopenharmony_ci} 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cistatic void 1538c2ecf20Sopenharmony_cil1_go_F8(struct FsmInst *fi, int event, void *arg) 1548c2ecf20Sopenharmony_ci{ 1558c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F8); 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic void 1598c2ecf20Sopenharmony_cil1_info2_ind(struct FsmInst *fi, int event, void *arg) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F6); 1648c2ecf20Sopenharmony_ci l1->dcb(l1->dch, INFO3_P8); 1658c2ecf20Sopenharmony_ci} 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic void 1688c2ecf20Sopenharmony_cil1_info4_ind(struct FsmInst *fi, int event, void *arg) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F7); 1738c2ecf20Sopenharmony_ci l1->dcb(l1->dch, INFO3_P8); 1748c2ecf20Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 1758c2ecf20Sopenharmony_ci mISDN_FsmDelTimer(&l1->timerX, 4); 1768c2ecf20Sopenharmony_ci if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 1778c2ecf20Sopenharmony_ci if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 1788c2ecf20Sopenharmony_ci mISDN_FsmDelTimer(&l1->timer3, 3); 1798c2ecf20Sopenharmony_ci mISDN_FsmRestartTimer(&l1->timerX, 110, EV_TIMER_ACT, NULL, 2); 1808c2ecf20Sopenharmony_ci test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic void 1858c2ecf20Sopenharmony_cil1_timer3(struct FsmInst *fi, int event, void *arg) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); 1908c2ecf20Sopenharmony_ci if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1918c2ecf20Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 1928c2ecf20Sopenharmony_ci l1->dcb(l1->dch, HW_D_NOBLOCKED); 1938c2ecf20Sopenharmony_ci l1->dcb(l1->dch, PH_DEACTIVATE_IND); 1948c2ecf20Sopenharmony_ci } 1958c2ecf20Sopenharmony_ci if (l1->l1m.state != ST_L1_F6) { 1968c2ecf20Sopenharmony_ci mISDN_FsmChangeState(fi, ST_L1_F3); 1978c2ecf20Sopenharmony_ci /* do not force anything here, we need send INFO 0 */ 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic void 2028c2ecf20Sopenharmony_cil1_timer_act(struct FsmInst *fi, int event, void *arg) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); 2078c2ecf20Sopenharmony_ci test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); 2088c2ecf20Sopenharmony_ci l1->dcb(l1->dch, PH_ACTIVATE_IND); 2098c2ecf20Sopenharmony_ci} 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_cistatic void 2128c2ecf20Sopenharmony_cil1_timer_deact(struct FsmInst *fi, int event, void *arg) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); 2178c2ecf20Sopenharmony_ci test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); 2188c2ecf20Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2198c2ecf20Sopenharmony_ci l1->dcb(l1->dch, HW_D_NOBLOCKED); 2208c2ecf20Sopenharmony_ci l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2218c2ecf20Sopenharmony_ci l1->dcb(l1->dch, HW_DEACT_REQ); 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic void 2258c2ecf20Sopenharmony_cil1_activate_s(struct FsmInst *fi, int event, void *arg) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci mISDN_FsmRestartTimer(&l1->timer3, l1->t3_value, EV_TIMER3, NULL, 2); 2308c2ecf20Sopenharmony_ci test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); 2318c2ecf20Sopenharmony_ci /* Tell HW to send INFO 1 */ 2328c2ecf20Sopenharmony_ci l1->dcb(l1->dch, HW_RESET_REQ); 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic void 2368c2ecf20Sopenharmony_cil1_activate_no(struct FsmInst *fi, int event, void *arg) 2378c2ecf20Sopenharmony_ci{ 2388c2ecf20Sopenharmony_ci struct layer1 *l1 = fi->userdata; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && 2418c2ecf20Sopenharmony_ci (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { 2428c2ecf20Sopenharmony_ci test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); 2438c2ecf20Sopenharmony_ci if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2448c2ecf20Sopenharmony_ci l1->dcb(l1->dch, HW_D_NOBLOCKED); 2458c2ecf20Sopenharmony_ci l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci} 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_cistatic struct FsmNode L1SFnList[] = 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, 2528c2ecf20Sopenharmony_ci {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, 2538c2ecf20Sopenharmony_ci {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, 2548c2ecf20Sopenharmony_ci {ST_L1_F3, EV_RESET_IND, l1_reset}, 2558c2ecf20Sopenharmony_ci {ST_L1_F4, EV_RESET_IND, l1_reset}, 2568c2ecf20Sopenharmony_ci {ST_L1_F5, EV_RESET_IND, l1_reset}, 2578c2ecf20Sopenharmony_ci {ST_L1_F6, EV_RESET_IND, l1_reset}, 2588c2ecf20Sopenharmony_ci {ST_L1_F7, EV_RESET_IND, l1_reset}, 2598c2ecf20Sopenharmony_ci {ST_L1_F8, EV_RESET_IND, l1_reset}, 2608c2ecf20Sopenharmony_ci {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, 2618c2ecf20Sopenharmony_ci {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, 2628c2ecf20Sopenharmony_ci {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, 2638c2ecf20Sopenharmony_ci {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, 2648c2ecf20Sopenharmony_ci {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, 2658c2ecf20Sopenharmony_ci {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, 2668c2ecf20Sopenharmony_ci {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, 2678c2ecf20Sopenharmony_ci {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, 2688c2ecf20Sopenharmony_ci {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, 2698c2ecf20Sopenharmony_ci {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, 2708c2ecf20Sopenharmony_ci {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, 2718c2ecf20Sopenharmony_ci {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, 2728c2ecf20Sopenharmony_ci {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, 2738c2ecf20Sopenharmony_ci {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, 2748c2ecf20Sopenharmony_ci {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, 2758c2ecf20Sopenharmony_ci {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, 2768c2ecf20Sopenharmony_ci {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, 2778c2ecf20Sopenharmony_ci {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, 2788c2ecf20Sopenharmony_ci {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, 2798c2ecf20Sopenharmony_ci {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, 2808c2ecf20Sopenharmony_ci {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, 2818c2ecf20Sopenharmony_ci {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, 2828c2ecf20Sopenharmony_ci {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, 2838c2ecf20Sopenharmony_ci {ST_L1_F3, EV_TIMER3, l1_timer3}, 2848c2ecf20Sopenharmony_ci {ST_L1_F4, EV_TIMER3, l1_timer3}, 2858c2ecf20Sopenharmony_ci {ST_L1_F5, EV_TIMER3, l1_timer3}, 2868c2ecf20Sopenharmony_ci {ST_L1_F6, EV_TIMER3, l1_timer3}, 2878c2ecf20Sopenharmony_ci {ST_L1_F8, EV_TIMER3, l1_timer3}, 2888c2ecf20Sopenharmony_ci {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, 2898c2ecf20Sopenharmony_ci {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, 2908c2ecf20Sopenharmony_ci {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, 2918c2ecf20Sopenharmony_ci {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, 2928c2ecf20Sopenharmony_ci {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, 2938c2ecf20Sopenharmony_ci {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, 2948c2ecf20Sopenharmony_ci {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 2958c2ecf20Sopenharmony_ci}; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistatic void 2988c2ecf20Sopenharmony_cirelease_l1(struct layer1 *l1) { 2998c2ecf20Sopenharmony_ci mISDN_FsmDelTimer(&l1->timerX, 0); 3008c2ecf20Sopenharmony_ci mISDN_FsmDelTimer(&l1->timer3, 0); 3018c2ecf20Sopenharmony_ci if (l1->dch) 3028c2ecf20Sopenharmony_ci l1->dch->l1 = NULL; 3038c2ecf20Sopenharmony_ci module_put(THIS_MODULE); 3048c2ecf20Sopenharmony_ci kfree(l1); 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ciint 3088c2ecf20Sopenharmony_cil1_event(struct layer1 *l1, u_int event) 3098c2ecf20Sopenharmony_ci{ 3108c2ecf20Sopenharmony_ci int err = 0; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci if (!l1) 3138c2ecf20Sopenharmony_ci return -EINVAL; 3148c2ecf20Sopenharmony_ci switch (event) { 3158c2ecf20Sopenharmony_ci case HW_RESET_IND: 3168c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); 3178c2ecf20Sopenharmony_ci break; 3188c2ecf20Sopenharmony_ci case HW_DEACT_IND: 3198c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); 3208c2ecf20Sopenharmony_ci break; 3218c2ecf20Sopenharmony_ci case HW_POWERUP_IND: 3228c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); 3238c2ecf20Sopenharmony_ci break; 3248c2ecf20Sopenharmony_ci case HW_DEACT_CNF: 3258c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); 3268c2ecf20Sopenharmony_ci break; 3278c2ecf20Sopenharmony_ci case ANYSIGNAL: 3288c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3298c2ecf20Sopenharmony_ci break; 3308c2ecf20Sopenharmony_ci case LOSTFRAMING: 3318c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3328c2ecf20Sopenharmony_ci break; 3338c2ecf20Sopenharmony_ci case INFO2: 3348c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); 3358c2ecf20Sopenharmony_ci break; 3368c2ecf20Sopenharmony_ci case INFO4_P8: 3378c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3388c2ecf20Sopenharmony_ci break; 3398c2ecf20Sopenharmony_ci case INFO4_P10: 3408c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3418c2ecf20Sopenharmony_ci break; 3428c2ecf20Sopenharmony_ci case PH_ACTIVATE_REQ: 3438c2ecf20Sopenharmony_ci if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) 3448c2ecf20Sopenharmony_ci l1->dcb(l1->dch, PH_ACTIVATE_IND); 3458c2ecf20Sopenharmony_ci else { 3468c2ecf20Sopenharmony_ci test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); 3478c2ecf20Sopenharmony_ci mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci break; 3508c2ecf20Sopenharmony_ci case CLOSE_CHANNEL: 3518c2ecf20Sopenharmony_ci release_l1(l1); 3528c2ecf20Sopenharmony_ci break; 3538c2ecf20Sopenharmony_ci default: 3548c2ecf20Sopenharmony_ci if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { 3558c2ecf20Sopenharmony_ci int val = event & HW_TIMER3_VMASK; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci if (val < 5) 3588c2ecf20Sopenharmony_ci val = 5; 3598c2ecf20Sopenharmony_ci if (val > 30) 3608c2ecf20Sopenharmony_ci val = 30; 3618c2ecf20Sopenharmony_ci l1->t3_value = val; 3628c2ecf20Sopenharmony_ci break; 3638c2ecf20Sopenharmony_ci } 3648c2ecf20Sopenharmony_ci if (*debug & DEBUG_L1) 3658c2ecf20Sopenharmony_ci printk(KERN_DEBUG "%s %x unhandled\n", 3668c2ecf20Sopenharmony_ci __func__, event); 3678c2ecf20Sopenharmony_ci err = -EINVAL; 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci return err; 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ciEXPORT_SYMBOL(l1_event); 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ciint 3748c2ecf20Sopenharmony_cicreate_l1(struct dchannel *dch, dchannel_l1callback *dcb) { 3758c2ecf20Sopenharmony_ci struct layer1 *nl1; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); 3788c2ecf20Sopenharmony_ci if (!nl1) { 3798c2ecf20Sopenharmony_ci printk(KERN_ERR "kmalloc struct layer1 failed\n"); 3808c2ecf20Sopenharmony_ci return -ENOMEM; 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci nl1->l1m.fsm = &l1fsm_s; 3838c2ecf20Sopenharmony_ci nl1->l1m.state = ST_L1_F3; 3848c2ecf20Sopenharmony_ci nl1->Flags = 0; 3858c2ecf20Sopenharmony_ci nl1->t3_value = TIMER3_DEFAULT_VALUE; 3868c2ecf20Sopenharmony_ci nl1->l1m.debug = *debug & DEBUG_L1_FSM; 3878c2ecf20Sopenharmony_ci nl1->l1m.userdata = nl1; 3888c2ecf20Sopenharmony_ci nl1->l1m.userint = 0; 3898c2ecf20Sopenharmony_ci nl1->l1m.printdebug = l1m_debug; 3908c2ecf20Sopenharmony_ci nl1->dch = dch; 3918c2ecf20Sopenharmony_ci nl1->dcb = dcb; 3928c2ecf20Sopenharmony_ci mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer3); 3938c2ecf20Sopenharmony_ci mISDN_FsmInitTimer(&nl1->l1m, &nl1->timerX); 3948c2ecf20Sopenharmony_ci __module_get(THIS_MODULE); 3958c2ecf20Sopenharmony_ci dch->l1 = nl1; 3968c2ecf20Sopenharmony_ci return 0; 3978c2ecf20Sopenharmony_ci} 3988c2ecf20Sopenharmony_ciEXPORT_SYMBOL(create_l1); 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ciint 4018c2ecf20Sopenharmony_ciIsdnl1_Init(u_int *deb) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci debug = deb; 4048c2ecf20Sopenharmony_ci l1fsm_s.state_count = L1S_STATE_COUNT; 4058c2ecf20Sopenharmony_ci l1fsm_s.event_count = L1_EVENT_COUNT; 4068c2ecf20Sopenharmony_ci l1fsm_s.strEvent = strL1Event; 4078c2ecf20Sopenharmony_ci l1fsm_s.strState = strL1SState; 4088c2ecf20Sopenharmony_ci return mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); 4098c2ecf20Sopenharmony_ci} 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_civoid 4128c2ecf20Sopenharmony_ciIsdnl1_cleanup(void) 4138c2ecf20Sopenharmony_ci{ 4148c2ecf20Sopenharmony_ci mISDN_FsmFree(&l1fsm_s); 4158c2ecf20Sopenharmony_ci} 416