11b2b03f8SKarsten Keil /* 21b2b03f8SKarsten Keil * 31b2b03f8SKarsten Keil * Author Karsten Keil <kkeil@novell.com> 41b2b03f8SKarsten Keil * 51b2b03f8SKarsten Keil * Copyright 2008 by Karsten Keil <kkeil@novell.com> 61b2b03f8SKarsten Keil * 71b2b03f8SKarsten Keil * This program is free software; you can redistribute it and/or modify 81b2b03f8SKarsten Keil * it under the terms of the GNU General Public License version 2 as 91b2b03f8SKarsten Keil * published by the Free Software Foundation. 101b2b03f8SKarsten Keil * 111b2b03f8SKarsten Keil * This program is distributed in the hope that it will be useful, 121b2b03f8SKarsten Keil * but WITHOUT ANY WARRANTY; without even the implied warranty of 131b2b03f8SKarsten Keil * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141b2b03f8SKarsten Keil * GNU General Public License for more details. 151b2b03f8SKarsten Keil * 161b2b03f8SKarsten Keil */ 171b2b03f8SKarsten Keil 181b2b03f8SKarsten Keil 195a0e3ad6STejun Heo #include <linux/slab.h> 201b2b03f8SKarsten Keil #include <linux/module.h> 211b2b03f8SKarsten Keil #include <linux/mISDNhw.h> 225b834354SHannes Eder #include "core.h" 231b2b03f8SKarsten Keil #include "layer1.h" 241b2b03f8SKarsten Keil #include "fsm.h" 251b2b03f8SKarsten Keil 26dfa96ec1SHannes Eder static u_int *debug; 271b2b03f8SKarsten Keil 281b2b03f8SKarsten Keil struct layer1 { 291b2b03f8SKarsten Keil u_long Flags; 301b2b03f8SKarsten Keil struct FsmInst l1m; 311b2b03f8SKarsten Keil struct FsmTimer timer; 321b2b03f8SKarsten Keil int delay; 33c626c127SKarsten Keil int t3_value; 341b2b03f8SKarsten Keil struct dchannel *dch; 351b2b03f8SKarsten Keil dchannel_l1callback *dcb; 361b2b03f8SKarsten Keil }; 371b2b03f8SKarsten Keil 38c626c127SKarsten Keil #define TIMER3_DEFAULT_VALUE 7000 391b2b03f8SKarsten Keil 401b2b03f8SKarsten Keil static 411b2b03f8SKarsten Keil struct Fsm l1fsm_s = {NULL, 0, 0, NULL, NULL}; 421b2b03f8SKarsten Keil 431b2b03f8SKarsten Keil enum { 441b2b03f8SKarsten Keil ST_L1_F2, 451b2b03f8SKarsten Keil ST_L1_F3, 461b2b03f8SKarsten Keil ST_L1_F4, 471b2b03f8SKarsten Keil ST_L1_F5, 481b2b03f8SKarsten Keil ST_L1_F6, 491b2b03f8SKarsten Keil ST_L1_F7, 501b2b03f8SKarsten Keil ST_L1_F8, 511b2b03f8SKarsten Keil }; 521b2b03f8SKarsten Keil 531b2b03f8SKarsten Keil #define L1S_STATE_COUNT (ST_L1_F8 + 1) 541b2b03f8SKarsten Keil 551b2b03f8SKarsten Keil static char *strL1SState[] = 561b2b03f8SKarsten Keil { 571b2b03f8SKarsten Keil "ST_L1_F2", 581b2b03f8SKarsten Keil "ST_L1_F3", 591b2b03f8SKarsten Keil "ST_L1_F4", 601b2b03f8SKarsten Keil "ST_L1_F5", 611b2b03f8SKarsten Keil "ST_L1_F6", 621b2b03f8SKarsten Keil "ST_L1_F7", 631b2b03f8SKarsten Keil "ST_L1_F8", 641b2b03f8SKarsten Keil }; 651b2b03f8SKarsten Keil 661b2b03f8SKarsten Keil enum { 671b2b03f8SKarsten Keil EV_PH_ACTIVATE, 681b2b03f8SKarsten Keil EV_PH_DEACTIVATE, 691b2b03f8SKarsten Keil EV_RESET_IND, 701b2b03f8SKarsten Keil EV_DEACT_CNF, 711b2b03f8SKarsten Keil EV_DEACT_IND, 721b2b03f8SKarsten Keil EV_POWER_UP, 731b2b03f8SKarsten Keil EV_ANYSIG_IND, 741b2b03f8SKarsten Keil EV_INFO2_IND, 751b2b03f8SKarsten Keil EV_INFO4_IND, 761b2b03f8SKarsten Keil EV_TIMER_DEACT, 771b2b03f8SKarsten Keil EV_TIMER_ACT, 781b2b03f8SKarsten Keil EV_TIMER3, 791b2b03f8SKarsten Keil }; 801b2b03f8SKarsten Keil 811b2b03f8SKarsten Keil #define L1_EVENT_COUNT (EV_TIMER3 + 1) 821b2b03f8SKarsten Keil 831b2b03f8SKarsten Keil static char *strL1Event[] = 841b2b03f8SKarsten Keil { 851b2b03f8SKarsten Keil "EV_PH_ACTIVATE", 861b2b03f8SKarsten Keil "EV_PH_DEACTIVATE", 871b2b03f8SKarsten Keil "EV_RESET_IND", 881b2b03f8SKarsten Keil "EV_DEACT_CNF", 891b2b03f8SKarsten Keil "EV_DEACT_IND", 901b2b03f8SKarsten Keil "EV_POWER_UP", 911b2b03f8SKarsten Keil "EV_ANYSIG_IND", 921b2b03f8SKarsten Keil "EV_INFO2_IND", 931b2b03f8SKarsten Keil "EV_INFO4_IND", 941b2b03f8SKarsten Keil "EV_TIMER_DEACT", 951b2b03f8SKarsten Keil "EV_TIMER_ACT", 961b2b03f8SKarsten Keil "EV_TIMER3", 971b2b03f8SKarsten Keil }; 981b2b03f8SKarsten Keil 991b2b03f8SKarsten Keil static void 1001b2b03f8SKarsten Keil l1m_debug(struct FsmInst *fi, char *fmt, ...) 1011b2b03f8SKarsten Keil { 1021b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 103020f01ebSJoe Perches struct va_format vaf; 1041b2b03f8SKarsten Keil va_list va; 1051b2b03f8SKarsten Keil 1061b2b03f8SKarsten Keil va_start(va, fmt); 107020f01ebSJoe Perches 108020f01ebSJoe Perches vaf.fmt = fmt; 109020f01ebSJoe Perches vaf.va = &va; 110020f01ebSJoe Perches 111020f01ebSJoe Perches printk(KERN_DEBUG "%s: %pV\n", dev_name(&l1->dch->dev.dev), &vaf); 112020f01ebSJoe Perches 1131b2b03f8SKarsten Keil va_end(va); 1141b2b03f8SKarsten Keil } 1151b2b03f8SKarsten Keil 1161b2b03f8SKarsten Keil static void 1171b2b03f8SKarsten Keil l1_reset(struct FsmInst *fi, int event, void *arg) 1181b2b03f8SKarsten Keil { 1191b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1201b2b03f8SKarsten Keil } 1211b2b03f8SKarsten Keil 1221b2b03f8SKarsten Keil static void 1231b2b03f8SKarsten Keil l1_deact_cnf(struct FsmInst *fi, int event, void *arg) 1241b2b03f8SKarsten Keil { 1251b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1261b2b03f8SKarsten Keil 1271b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1281b2b03f8SKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) 1291b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 1301b2b03f8SKarsten Keil } 1311b2b03f8SKarsten Keil 1321b2b03f8SKarsten Keil static void 1331b2b03f8SKarsten Keil l1_deact_req_s(struct FsmInst *fi, int event, void *arg) 1341b2b03f8SKarsten Keil { 1351b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1361b2b03f8SKarsten Keil 1371b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1381b2b03f8SKarsten Keil mISDN_FsmRestartTimer(&l1->timer, 550, EV_TIMER_DEACT, NULL, 2); 1391b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_DEACTTIMER, &l1->Flags); 1401b2b03f8SKarsten Keil } 1411b2b03f8SKarsten Keil 1421b2b03f8SKarsten Keil static void 1431b2b03f8SKarsten Keil l1_power_up_s(struct FsmInst *fi, int event, void *arg) 1441b2b03f8SKarsten Keil { 1451b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1461b2b03f8SKarsten Keil 1471b2b03f8SKarsten Keil if (test_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1481b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F4); 1491b2b03f8SKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1501b2b03f8SKarsten Keil } else 1511b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 1521b2b03f8SKarsten Keil } 1531b2b03f8SKarsten Keil 1541b2b03f8SKarsten Keil static void 1551b2b03f8SKarsten Keil l1_go_F5(struct FsmInst *fi, int event, void *arg) 1561b2b03f8SKarsten Keil { 1571b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F5); 1581b2b03f8SKarsten Keil } 1591b2b03f8SKarsten Keil 1601b2b03f8SKarsten Keil static void 1611b2b03f8SKarsten Keil l1_go_F8(struct FsmInst *fi, int event, void *arg) 1621b2b03f8SKarsten Keil { 1631b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F8); 1641b2b03f8SKarsten Keil } 1651b2b03f8SKarsten Keil 1661b2b03f8SKarsten Keil static void 1671b2b03f8SKarsten Keil l1_info2_ind(struct FsmInst *fi, int event, void *arg) 1681b2b03f8SKarsten Keil { 1691b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1701b2b03f8SKarsten Keil 1711b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F6); 1721b2b03f8SKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1731b2b03f8SKarsten Keil } 1741b2b03f8SKarsten Keil 1751b2b03f8SKarsten Keil static void 1761b2b03f8SKarsten Keil l1_info4_ind(struct FsmInst *fi, int event, void *arg) 1771b2b03f8SKarsten Keil { 1781b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1791b2b03f8SKarsten Keil 1801b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F7); 1811b2b03f8SKarsten Keil l1->dcb(l1->dch, INFO3_P8); 1821b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags)) 1831b2b03f8SKarsten Keil mISDN_FsmDelTimer(&l1->timer, 4); 1841b2b03f8SKarsten Keil if (!test_bit(FLG_L1_ACTIVATED, &l1->Flags)) { 1851b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags)) 1861b2b03f8SKarsten Keil mISDN_FsmDelTimer(&l1->timer, 3); 1871b2b03f8SKarsten Keil mISDN_FsmRestartTimer(&l1->timer, 110, EV_TIMER_ACT, NULL, 2); 1881b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_ACTTIMER, &l1->Flags); 1891b2b03f8SKarsten Keil } 1901b2b03f8SKarsten Keil } 1911b2b03f8SKarsten Keil 1921b2b03f8SKarsten Keil static void 1931b2b03f8SKarsten Keil l1_timer3(struct FsmInst *fi, int event, void *arg) 1941b2b03f8SKarsten Keil { 1951b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 1961b2b03f8SKarsten Keil 1971b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_T3RUN, &l1->Flags); 1981b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags)) { 1991b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2001b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2011b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2021b2b03f8SKarsten Keil } 2031b2b03f8SKarsten Keil if (l1->l1m.state != ST_L1_F6) { 2041b2b03f8SKarsten Keil mISDN_FsmChangeState(fi, ST_L1_F3); 2051b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_POWERUP_REQ); 2061b2b03f8SKarsten Keil } 2071b2b03f8SKarsten Keil } 2081b2b03f8SKarsten Keil 2091b2b03f8SKarsten Keil static void 2101b2b03f8SKarsten Keil l1_timer_act(struct FsmInst *fi, int event, void *arg) 2111b2b03f8SKarsten Keil { 2121b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2131b2b03f8SKarsten Keil 2141b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_ACTTIMER, &l1->Flags); 2151b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_ACTIVATED, &l1->Flags); 2161b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 2171b2b03f8SKarsten Keil } 2181b2b03f8SKarsten Keil 2191b2b03f8SKarsten Keil static void 2201b2b03f8SKarsten Keil l1_timer_deact(struct FsmInst *fi, int event, void *arg) 2211b2b03f8SKarsten Keil { 2221b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2231b2b03f8SKarsten Keil 2241b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_DEACTTIMER, &l1->Flags); 2251b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATED, &l1->Flags); 2261b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2271b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2281b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2291b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_DEACT_REQ); 2301b2b03f8SKarsten Keil } 2311b2b03f8SKarsten Keil 2321b2b03f8SKarsten Keil static void 2331b2b03f8SKarsten Keil l1_activate_s(struct FsmInst *fi, int event, void *arg) 2341b2b03f8SKarsten Keil { 2351b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2361b2b03f8SKarsten Keil 237c626c127SKarsten Keil mISDN_FsmRestartTimer(&l1->timer, l1->t3_value, EV_TIMER3, NULL, 2); 2381b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_T3RUN, &l1->Flags); 2391b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_RESET_REQ); 2401b2b03f8SKarsten Keil } 2411b2b03f8SKarsten Keil 2421b2b03f8SKarsten Keil static void 2431b2b03f8SKarsten Keil l1_activate_no(struct FsmInst *fi, int event, void *arg) 2441b2b03f8SKarsten Keil { 2451b2b03f8SKarsten Keil struct layer1 *l1 = fi->userdata; 2461b2b03f8SKarsten Keil 2471b2b03f8SKarsten Keil if ((!test_bit(FLG_L1_DEACTTIMER, &l1->Flags)) && 2481b2b03f8SKarsten Keil (!test_bit(FLG_L1_T3RUN, &l1->Flags))) { 2491b2b03f8SKarsten Keil test_and_clear_bit(FLG_L1_ACTIVATING, &l1->Flags); 2501b2b03f8SKarsten Keil if (test_and_clear_bit(FLG_L1_DBLOCKED, &l1->Flags)) 2511b2b03f8SKarsten Keil l1->dcb(l1->dch, HW_D_NOBLOCKED); 2521b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_DEACTIVATE_IND); 2531b2b03f8SKarsten Keil } 2541b2b03f8SKarsten Keil } 2551b2b03f8SKarsten Keil 2561b2b03f8SKarsten Keil static struct FsmNode L1SFnList[] = 2571b2b03f8SKarsten Keil { 2581b2b03f8SKarsten Keil {ST_L1_F3, EV_PH_ACTIVATE, l1_activate_s}, 2591b2b03f8SKarsten Keil {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no}, 2601b2b03f8SKarsten Keil {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no}, 2611b2b03f8SKarsten Keil {ST_L1_F3, EV_RESET_IND, l1_reset}, 2621b2b03f8SKarsten Keil {ST_L1_F4, EV_RESET_IND, l1_reset}, 2631b2b03f8SKarsten Keil {ST_L1_F5, EV_RESET_IND, l1_reset}, 2641b2b03f8SKarsten Keil {ST_L1_F6, EV_RESET_IND, l1_reset}, 2651b2b03f8SKarsten Keil {ST_L1_F7, EV_RESET_IND, l1_reset}, 2661b2b03f8SKarsten Keil {ST_L1_F8, EV_RESET_IND, l1_reset}, 2671b2b03f8SKarsten Keil {ST_L1_F3, EV_DEACT_CNF, l1_deact_cnf}, 2681b2b03f8SKarsten Keil {ST_L1_F4, EV_DEACT_CNF, l1_deact_cnf}, 2691b2b03f8SKarsten Keil {ST_L1_F5, EV_DEACT_CNF, l1_deact_cnf}, 2701b2b03f8SKarsten Keil {ST_L1_F6, EV_DEACT_CNF, l1_deact_cnf}, 2711b2b03f8SKarsten Keil {ST_L1_F7, EV_DEACT_CNF, l1_deact_cnf}, 2721b2b03f8SKarsten Keil {ST_L1_F8, EV_DEACT_CNF, l1_deact_cnf}, 2731b2b03f8SKarsten Keil {ST_L1_F6, EV_DEACT_IND, l1_deact_req_s}, 2741b2b03f8SKarsten Keil {ST_L1_F7, EV_DEACT_IND, l1_deact_req_s}, 2751b2b03f8SKarsten Keil {ST_L1_F8, EV_DEACT_IND, l1_deact_req_s}, 2761b2b03f8SKarsten Keil {ST_L1_F3, EV_POWER_UP, l1_power_up_s}, 2771b2b03f8SKarsten Keil {ST_L1_F4, EV_ANYSIG_IND, l1_go_F5}, 2781b2b03f8SKarsten Keil {ST_L1_F6, EV_ANYSIG_IND, l1_go_F8}, 2791b2b03f8SKarsten Keil {ST_L1_F7, EV_ANYSIG_IND, l1_go_F8}, 2801b2b03f8SKarsten Keil {ST_L1_F3, EV_INFO2_IND, l1_info2_ind}, 2811b2b03f8SKarsten Keil {ST_L1_F4, EV_INFO2_IND, l1_info2_ind}, 2821b2b03f8SKarsten Keil {ST_L1_F5, EV_INFO2_IND, l1_info2_ind}, 2831b2b03f8SKarsten Keil {ST_L1_F7, EV_INFO2_IND, l1_info2_ind}, 2841b2b03f8SKarsten Keil {ST_L1_F8, EV_INFO2_IND, l1_info2_ind}, 2851b2b03f8SKarsten Keil {ST_L1_F3, EV_INFO4_IND, l1_info4_ind}, 2861b2b03f8SKarsten Keil {ST_L1_F4, EV_INFO4_IND, l1_info4_ind}, 2871b2b03f8SKarsten Keil {ST_L1_F5, EV_INFO4_IND, l1_info4_ind}, 2881b2b03f8SKarsten Keil {ST_L1_F6, EV_INFO4_IND, l1_info4_ind}, 2891b2b03f8SKarsten Keil {ST_L1_F8, EV_INFO4_IND, l1_info4_ind}, 2901b2b03f8SKarsten Keil {ST_L1_F3, EV_TIMER3, l1_timer3}, 2911b2b03f8SKarsten Keil {ST_L1_F4, EV_TIMER3, l1_timer3}, 2921b2b03f8SKarsten Keil {ST_L1_F5, EV_TIMER3, l1_timer3}, 2931b2b03f8SKarsten Keil {ST_L1_F6, EV_TIMER3, l1_timer3}, 2941b2b03f8SKarsten Keil {ST_L1_F8, EV_TIMER3, l1_timer3}, 2951b2b03f8SKarsten Keil {ST_L1_F7, EV_TIMER_ACT, l1_timer_act}, 2961b2b03f8SKarsten Keil {ST_L1_F3, EV_TIMER_DEACT, l1_timer_deact}, 2971b2b03f8SKarsten Keil {ST_L1_F4, EV_TIMER_DEACT, l1_timer_deact}, 2981b2b03f8SKarsten Keil {ST_L1_F5, EV_TIMER_DEACT, l1_timer_deact}, 2991b2b03f8SKarsten Keil {ST_L1_F6, EV_TIMER_DEACT, l1_timer_deact}, 3001b2b03f8SKarsten Keil {ST_L1_F7, EV_TIMER_DEACT, l1_timer_deact}, 3011b2b03f8SKarsten Keil {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 3021b2b03f8SKarsten Keil }; 3031b2b03f8SKarsten Keil 3041b2b03f8SKarsten Keil static void 3051b2b03f8SKarsten Keil release_l1(struct layer1 *l1) { 3061b2b03f8SKarsten Keil mISDN_FsmDelTimer(&l1->timer, 0); 3071b2b03f8SKarsten Keil if (l1->dch) 3081b2b03f8SKarsten Keil l1->dch->l1 = NULL; 3091b2b03f8SKarsten Keil module_put(THIS_MODULE); 3101b2b03f8SKarsten Keil kfree(l1); 3111b2b03f8SKarsten Keil } 3121b2b03f8SKarsten Keil 3131b2b03f8SKarsten Keil int 3141b2b03f8SKarsten Keil l1_event(struct layer1 *l1, u_int event) 3151b2b03f8SKarsten Keil { 3161b2b03f8SKarsten Keil int err = 0; 3171b2b03f8SKarsten Keil 3181b2b03f8SKarsten Keil if (!l1) 3191b2b03f8SKarsten Keil return -EINVAL; 3201b2b03f8SKarsten Keil switch (event) { 3211b2b03f8SKarsten Keil case HW_RESET_IND: 3221b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_RESET_IND, NULL); 3231b2b03f8SKarsten Keil break; 3241b2b03f8SKarsten Keil case HW_DEACT_IND: 3251b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_IND, NULL); 3261b2b03f8SKarsten Keil break; 3271b2b03f8SKarsten Keil case HW_POWERUP_IND: 3281b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_POWER_UP, NULL); 3291b2b03f8SKarsten Keil break; 3301b2b03f8SKarsten Keil case HW_DEACT_CNF: 3311b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_DEACT_CNF, NULL); 3321b2b03f8SKarsten Keil break; 3331b2b03f8SKarsten Keil case ANYSIGNAL: 3341b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3351b2b03f8SKarsten Keil break; 3361b2b03f8SKarsten Keil case LOSTFRAMING: 3371b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_ANYSIG_IND, NULL); 3381b2b03f8SKarsten Keil break; 3391b2b03f8SKarsten Keil case INFO2: 3401b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO2_IND, NULL); 3411b2b03f8SKarsten Keil break; 3421b2b03f8SKarsten Keil case INFO4_P8: 3431b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3441b2b03f8SKarsten Keil break; 3451b2b03f8SKarsten Keil case INFO4_P10: 3461b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_INFO4_IND, NULL); 3471b2b03f8SKarsten Keil break; 3481b2b03f8SKarsten Keil case PH_ACTIVATE_REQ: 3491b2b03f8SKarsten Keil if (test_bit(FLG_L1_ACTIVATED, &l1->Flags)) 3501b2b03f8SKarsten Keil l1->dcb(l1->dch, PH_ACTIVATE_IND); 3511b2b03f8SKarsten Keil else { 3521b2b03f8SKarsten Keil test_and_set_bit(FLG_L1_ACTIVATING, &l1->Flags); 3531b2b03f8SKarsten Keil mISDN_FsmEvent(&l1->l1m, EV_PH_ACTIVATE, NULL); 3541b2b03f8SKarsten Keil } 3551b2b03f8SKarsten Keil break; 3561b2b03f8SKarsten Keil case CLOSE_CHANNEL: 3571b2b03f8SKarsten Keil release_l1(l1); 3581b2b03f8SKarsten Keil break; 3591b2b03f8SKarsten Keil default: 360c626c127SKarsten Keil if ((event & ~HW_TIMER3_VMASK) == HW_TIMER3_VALUE) { 361c626c127SKarsten Keil int val = event & HW_TIMER3_VMASK; 362c626c127SKarsten Keil 363c626c127SKarsten Keil if (val < 5) 364c626c127SKarsten Keil val = 5; 365c626c127SKarsten Keil if (val > 30) 366c626c127SKarsten Keil val = 30; 367c626c127SKarsten Keil l1->t3_value = val; 368c626c127SKarsten Keil break; 369c626c127SKarsten Keil } 3701b2b03f8SKarsten Keil if (*debug & DEBUG_L1) 3711b2b03f8SKarsten Keil printk(KERN_DEBUG "%s %x unhandled\n", 3721b2b03f8SKarsten Keil __func__, event); 3731b2b03f8SKarsten Keil err = -EINVAL; 3741b2b03f8SKarsten Keil } 3751b2b03f8SKarsten Keil return err; 3761b2b03f8SKarsten Keil } 3771b2b03f8SKarsten Keil EXPORT_SYMBOL(l1_event); 3781b2b03f8SKarsten Keil 3791b2b03f8SKarsten Keil int 3801b2b03f8SKarsten Keil create_l1(struct dchannel *dch, dchannel_l1callback *dcb) { 3811b2b03f8SKarsten Keil struct layer1 *nl1; 3821b2b03f8SKarsten Keil 3831b2b03f8SKarsten Keil nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); 3841b2b03f8SKarsten Keil if (!nl1) { 3851b2b03f8SKarsten Keil printk(KERN_ERR "kmalloc struct layer1 failed\n"); 3861b2b03f8SKarsten Keil return -ENOMEM; 3871b2b03f8SKarsten Keil } 3881b2b03f8SKarsten Keil nl1->l1m.fsm = &l1fsm_s; 3891b2b03f8SKarsten Keil nl1->l1m.state = ST_L1_F3; 3901b2b03f8SKarsten Keil nl1->Flags = 0; 391c626c127SKarsten Keil nl1->t3_value = TIMER3_DEFAULT_VALUE; 3921b2b03f8SKarsten Keil nl1->l1m.debug = *debug & DEBUG_L1_FSM; 3931b2b03f8SKarsten Keil nl1->l1m.userdata = nl1; 3941b2b03f8SKarsten Keil nl1->l1m.userint = 0; 3951b2b03f8SKarsten Keil nl1->l1m.printdebug = l1m_debug; 3961b2b03f8SKarsten Keil nl1->dch = dch; 3971b2b03f8SKarsten Keil nl1->dcb = dcb; 3981b2b03f8SKarsten Keil mISDN_FsmInitTimer(&nl1->l1m, &nl1->timer); 3991b2b03f8SKarsten Keil __module_get(THIS_MODULE); 4001b2b03f8SKarsten Keil dch->l1 = nl1; 4011b2b03f8SKarsten Keil return 0; 4021b2b03f8SKarsten Keil } 4031b2b03f8SKarsten Keil EXPORT_SYMBOL(create_l1); 4041b2b03f8SKarsten Keil 4051b2b03f8SKarsten Keil int 4061b2b03f8SKarsten Keil l1_init(u_int *deb) 4071b2b03f8SKarsten Keil { 4081b2b03f8SKarsten Keil debug = deb; 4091b2b03f8SKarsten Keil l1fsm_s.state_count = L1S_STATE_COUNT; 4101b2b03f8SKarsten Keil l1fsm_s.event_count = L1_EVENT_COUNT; 4111b2b03f8SKarsten Keil l1fsm_s.strEvent = strL1Event; 4121b2b03f8SKarsten Keil l1fsm_s.strState = strL1SState; 4131b2b03f8SKarsten Keil mISDN_FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList)); 4141b2b03f8SKarsten Keil return 0; 4151b2b03f8SKarsten Keil } 4161b2b03f8SKarsten Keil 4171b2b03f8SKarsten Keil void 4181b2b03f8SKarsten Keil l1_cleanup(void) 4191b2b03f8SKarsten Keil { 4201b2b03f8SKarsten Keil mISDN_FsmFree(&l1fsm_s); 4211b2b03f8SKarsten Keil } 422