root/drivers/isdn/mISDN/layer1.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. l1m_debug
  2. l1_reset
  3. l1_deact_cnf
  4. l1_deact_req_s
  5. l1_power_up_s
  6. l1_go_F5
  7. l1_go_F8
  8. l1_info2_ind
  9. l1_info4_ind
  10. l1_timer3
  11. l1_timer_act
  12. l1_timer_deact
  13. l1_activate_s
  14. l1_activate_no
  15. release_l1
  16. l1_event
  17. create_l1
  18. l1_init
  19. l1_cleanup

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

/* [<][>][^][v][top][bottom][index][help] */