This source file includes following definitions.
- rmt_init
- rmt
- rmt_fsm
- rmt_dup_actions
- rmt_reinsert_actions
- rmt_new_dup_actions
- rmt_leave_actions
- start_rmt_timer0
- start_rmt_timer1
- start_rmt_timer2
- stop_rmt_timer0
- stop_rmt_timer1
- stop_rmt_timer2
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 #include "h/types.h"
  42 #include "h/fddi.h"
  43 #include "h/smc.h"
  44 
  45 #define KERNEL
  46 #include "h/smtstate.h"
  47 
  48 #ifndef lint
  49 static const char ID_sccs[] = "@(#)rmt.c        2.13 99/07/02 (C) SK " ;
  50 #endif
  51 
  52 
  53 
  54 
  55 #define AFLAG   0x10
  56 #define GO_STATE(x)     (smc->mib.m[MAC0].fddiMACRMTState = (x)|AFLAG)
  57 #define ACTIONS_DONE()  (smc->mib.m[MAC0].fddiMACRMTState &= ~AFLAG)
  58 #define ACTIONS(x)      (x|AFLAG)
  59 
  60 #define RM0_ISOLATED    0
  61 #define RM1_NON_OP      1               
  62 #define RM2_RING_OP     2               
  63 #define RM3_DETECT      3               
  64 #define RM4_NON_OP_DUP  4               
  65 #define RM5_RING_OP_DUP 5               
  66 #define RM6_DIRECTED    6               
  67 #define RM7_TRACE       7               
  68 
  69 
  70 
  71 
  72 static const char * const rmt_states[] = {
  73         "RM0_ISOLATED","RM1_NON_OP","RM2_RING_OP","RM3_DETECT",
  74         "RM4_NON_OP_DUP","RM5_RING_OP_DUP","RM6_DIRECTED",
  75         "RM7_TRACE"
  76 } ;
  77 
  78 
  79 
  80 
  81 static const char * const rmt_events[] = {
  82         "NONE","RM_RING_OP","RM_RING_NON_OP","RM_MY_BEACON",
  83         "RM_OTHER_BEACON","RM_MY_CLAIM","RM_TRT_EXP","RM_VALID_CLAIM",
  84         "RM_JOIN","RM_LOOP","RM_DUP_ADDR","RM_ENABLE_FLAG",
  85         "RM_TIMEOUT_NON_OP","RM_TIMEOUT_T_STUCK",
  86         "RM_TIMEOUT_ANNOUNCE","RM_TIMEOUT_T_DIRECT",
  87         "RM_TIMEOUT_D_MAX","RM_TIMEOUT_POLL","RM_TX_STATE_CHANGE"
  88 } ;
  89 
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 static void rmt_fsm(struct s_smc *smc, int cmd);
 100 static void start_rmt_timer0(struct s_smc *smc, u_long value, int event);
 101 static void start_rmt_timer1(struct s_smc *smc, u_long value, int event);
 102 static void start_rmt_timer2(struct s_smc *smc, u_long value, int event);
 103 static void stop_rmt_timer0(struct s_smc *smc);
 104 static void stop_rmt_timer1(struct s_smc *smc);
 105 static void stop_rmt_timer2(struct s_smc *smc);
 106 static void rmt_dup_actions(struct s_smc *smc);
 107 static void rmt_reinsert_actions(struct s_smc *smc);
 108 static void rmt_leave_actions(struct s_smc *smc);
 109 static void rmt_new_dup_actions(struct s_smc *smc);
 110 
 111 #ifndef SUPERNET_3
 112 extern void restart_trt_for_dbcn() ;
 113 #endif 
 114 
 115 
 116 
 117 
 118 
 119 void rmt_init(struct s_smc *smc)
 120 {
 121         smc->mib.m[MAC0].fddiMACRMTState = ACTIONS(RM0_ISOLATED) ;
 122         smc->r.dup_addr_test = DA_NONE ;
 123         smc->r.da_flag = 0 ;
 124         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
 125         smc->r.sm_ma_avail = FALSE ;
 126         smc->r.loop_avail = 0 ;
 127         smc->r.bn_flag = 0 ;
 128         smc->r.jm_flag = 0 ;
 129         smc->r.no_flag = TRUE ;
 130 }
 131 
 132 
 133 
 134 
 135 
 136 
 137 
 138 
 139 
 140 
 141 void rmt(struct s_smc *smc, int event)
 142 {
 143         int     state ;
 144 
 145         do {
 146                 DB_RMT("RMT : state %s%s event %s",
 147                        smc->mib.m[MAC0].fddiMACRMTState & AFLAG ? "ACTIONS " : "",
 148                        rmt_states[smc->mib.m[MAC0].fddiMACRMTState & ~AFLAG],
 149                        rmt_events[event]);
 150                 state = smc->mib.m[MAC0].fddiMACRMTState ;
 151                 rmt_fsm(smc,event) ;
 152                 event = 0 ;
 153         } while (state != smc->mib.m[MAC0].fddiMACRMTState) ;
 154         rmt_state_change(smc,(int)smc->mib.m[MAC0].fddiMACRMTState) ;
 155 }
 156 
 157 
 158 
 159 
 160 static void rmt_fsm(struct s_smc *smc, int cmd)
 161 {
 162         
 163 
 164 
 165         if (!smc->r.rm_join && !smc->r.rm_loop &&
 166                 smc->mib.m[MAC0].fddiMACRMTState != ACTIONS(RM0_ISOLATED) &&
 167                 smc->mib.m[MAC0].fddiMACRMTState != RM0_ISOLATED) {
 168                 RS_SET(smc,RS_NORINGOP) ;
 169                 rmt_indication(smc,0) ;
 170                 GO_STATE(RM0_ISOLATED) ;
 171                 return ;
 172         }
 173 
 174         switch(smc->mib.m[MAC0].fddiMACRMTState) {
 175         case ACTIONS(RM0_ISOLATED) :
 176                 stop_rmt_timer0(smc) ;
 177                 stop_rmt_timer1(smc) ;
 178                 stop_rmt_timer2(smc) ;
 179 
 180                 
 181 
 182 
 183                 sm_ma_control(smc,MA_OFFLINE) ;
 184                 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
 185                 smc->r.loop_avail = FALSE ;
 186                 smc->r.sm_ma_avail = FALSE ;
 187                 smc->r.no_flag = TRUE ;
 188                 DB_RMTN(1, "RMT : ISOLATED");
 189                 ACTIONS_DONE() ;
 190                 break ;
 191         case RM0_ISOLATED :
 192                 
 193                 if (smc->r.rm_join || smc->r.rm_loop) {
 194                         
 195 
 196 
 197 
 198 
 199 
 200                         sm_ma_control(smc,MA_RESET) ;
 201                         GO_STATE(RM1_NON_OP) ;
 202                         break ;
 203                 }
 204                 break ;
 205         case ACTIONS(RM1_NON_OP) :
 206                 start_rmt_timer0(smc,smc->s.rmt_t_non_op,RM_TIMEOUT_NON_OP) ;
 207                 stop_rmt_timer1(smc) ;
 208                 stop_rmt_timer2(smc) ;
 209                 sm_ma_control(smc,MA_BEACON) ;
 210                 DB_RMTN(1, "RMT : RING DOWN");
 211                 RS_SET(smc,RS_NORINGOP) ;
 212                 smc->r.sm_ma_avail = FALSE ;
 213                 rmt_indication(smc,0) ;
 214                 ACTIONS_DONE() ;
 215                 break ;
 216         case RM1_NON_OP :
 217                 
 218                 if (cmd == RM_RING_OP) {
 219                         RS_SET(smc,RS_RINGOPCHANGE) ;
 220                         GO_STATE(RM2_RING_OP) ;
 221                         break ;
 222                 }
 223                 
 224                 else if (cmd == RM_TIMEOUT_NON_OP) {
 225                         smc->r.bn_flag = FALSE ;
 226                         smc->r.no_flag = TRUE ;
 227                         GO_STATE(RM3_DETECT) ;
 228                         break ;
 229                 }
 230                 break ;
 231         case ACTIONS(RM2_RING_OP) :
 232                 stop_rmt_timer0(smc) ;
 233                 stop_rmt_timer1(smc) ;
 234                 stop_rmt_timer2(smc) ;
 235                 smc->r.no_flag = FALSE ;
 236                 if (smc->r.rm_loop)
 237                         smc->r.loop_avail = TRUE ;
 238                 if (smc->r.rm_join) {
 239                         smc->r.sm_ma_avail = TRUE ;
 240                         if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
 241                         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
 242                                 else
 243                         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
 244                 }
 245                 DB_RMTN(1, "RMT : RING UP");
 246                 RS_CLEAR(smc,RS_NORINGOP) ;
 247                 RS_SET(smc,RS_RINGOPCHANGE) ;
 248                 rmt_indication(smc,1) ;
 249                 smt_stat_counter(smc,0) ;
 250                 ACTIONS_DONE() ;
 251                 break ;
 252         case RM2_RING_OP :
 253                 
 254                 if (cmd == RM_RING_NON_OP) {
 255                         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
 256                         smc->r.loop_avail = FALSE ;
 257                         RS_SET(smc,RS_RINGOPCHANGE) ;
 258                         GO_STATE(RM1_NON_OP) ;
 259                         break ;
 260                 }
 261                 
 262                 else if (cmd == RM_ENABLE_FLAG) {
 263                         if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
 264                         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
 265                                 else
 266                         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
 267                 }
 268                 
 269                 else if (smc->r.dup_addr_test == DA_FAILED) {
 270                         smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
 271                         smc->r.loop_avail = FALSE ;
 272                         smc->r.da_flag = TRUE ;
 273                         GO_STATE(RM5_RING_OP_DUP) ;
 274                         break ;
 275                 }
 276                 break ;
 277         case ACTIONS(RM3_DETECT) :
 278                 start_rmt_timer0(smc,smc->s.mac_d_max*2,RM_TIMEOUT_D_MAX) ;
 279                 start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
 280                 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
 281                 sm_mac_check_beacon_claim(smc) ;
 282                 DB_RMTN(1, "RMT : RM3_DETECT");
 283                 ACTIONS_DONE() ;
 284                 break ;
 285         case RM3_DETECT :
 286                 if (cmd == RM_TIMEOUT_POLL) {
 287                         start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
 288                         sm_mac_check_beacon_claim(smc) ;
 289                         break ;
 290                 }
 291                 if (cmd == RM_TIMEOUT_D_MAX) {
 292                         smc->r.timer0_exp = TRUE ;
 293                 }
 294                 
 295 
 296 
 297 
 298 
 299 
 300                 if (cmd == RM_TX_STATE_CHANGE) {
 301                         start_rmt_timer0(smc,
 302                                          smc->s.mac_d_max*2,
 303                                          RM_TIMEOUT_D_MAX) ;
 304                 }
 305                 
 306                 if (cmd == RM_RING_OP) {
 307                         GO_STATE(RM2_RING_OP) ;
 308                         break ;
 309                 }
 310                 
 311                 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON)
 312                         && smc->r.bn_flag) {
 313                         smc->r.bn_flag = FALSE ;
 314                 }
 315                 
 316                 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
 317                         int     tx ;
 318                         
 319 
 320 
 321 
 322 
 323                         if ((tx =  sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
 324                         DB_RMTN(2, "RMT : DETECT && TRT_EXPIRED && T4/T5");
 325                                 smc->r.bn_flag = TRUE ;
 326                                 
 327 
 328 
 329 
 330 
 331 
 332                                 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
 333                                         RM_TIMEOUT_T_STUCK) ;
 334                         }
 335                         
 336 
 337 
 338 
 339 
 340 
 341                         DB_RMTN(2, "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)",
 342                                 tx, smc->r.bn_flag);
 343                 }
 344                 
 345                 else if (cmd == RM_MY_CLAIM && smc->r.timer0_exp) {
 346                         rmt_new_dup_actions(smc) ;
 347                         GO_STATE(RM4_NON_OP_DUP) ;
 348                         break ;
 349                 }
 350                 
 351                 else if (cmd == RM_MY_BEACON && smc->r.timer0_exp) {
 352                         rmt_new_dup_actions(smc) ;
 353                         GO_STATE(RM4_NON_OP_DUP) ;
 354                         break ;
 355                 }
 356                 
 357                 else if (cmd == RM_VALID_CLAIM) {
 358                         rmt_new_dup_actions(smc) ;
 359                         GO_STATE(RM4_NON_OP_DUP) ;
 360                         break ;
 361                 }
 362                 
 363                 else if (cmd == RM_TIMEOUT_T_STUCK &&
 364                         smc->r.rm_join && smc->r.bn_flag) {
 365                         GO_STATE(RM6_DIRECTED) ;
 366                         break ;
 367                 }
 368                 break ;
 369         case ACTIONS(RM4_NON_OP_DUP) :
 370                 start_rmt_timer0(smc,smc->s.rmt_t_announce,RM_TIMEOUT_ANNOUNCE);
 371                 start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
 372                 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
 373                 sm_mac_check_beacon_claim(smc) ;
 374                 DB_RMTN(1, "RMT : RM4_NON_OP_DUP");
 375                 ACTIONS_DONE() ;
 376                 break ;
 377         case RM4_NON_OP_DUP :
 378                 if (cmd == RM_TIMEOUT_POLL) {
 379                         start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
 380                         sm_mac_check_beacon_claim(smc) ;
 381                         break ;
 382                 }
 383                 
 384                 if (!smc->r.da_flag) {
 385                         GO_STATE(RM1_NON_OP) ;
 386                         break ;
 387                 }
 388                 
 389                 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
 390                         smc->r.bn_flag) {
 391                         smc->r.bn_flag = FALSE ;
 392                 }
 393                 
 394                 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
 395                         int     tx ;
 396                         
 397 
 398 
 399 
 400 
 401                         if ((tx =  sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
 402                         DB_RMTN(2, "RMT : NOPDUP && TRT_EXPIRED && T4/T5");
 403                                 smc->r.bn_flag = TRUE ;
 404                                 
 405 
 406 
 407 
 408 
 409 
 410                                 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
 411                                         RM_TIMEOUT_T_STUCK) ;
 412                         }
 413                         
 414 
 415 
 416 
 417 
 418 
 419                         DB_RMTN(2, "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)",
 420                                 tx, smc->r.bn_flag);
 421                 }
 422                 
 423                 else if (cmd == RM_TIMEOUT_ANNOUNCE && !smc->r.bn_flag) {
 424                         rmt_dup_actions(smc) ;
 425                 }
 426                 
 427                 else if (cmd == RM_RING_OP) {
 428                         smc->r.no_flag = FALSE ;
 429                         GO_STATE(RM5_RING_OP_DUP) ;
 430                         break ;
 431                 }
 432                 
 433                 else if (cmd == RM_TIMEOUT_T_STUCK &&
 434                         smc->r.rm_join && smc->r.bn_flag) {
 435                         GO_STATE(RM6_DIRECTED) ;
 436                         break ;
 437                 }
 438                 break ;
 439         case ACTIONS(RM5_RING_OP_DUP) :
 440                 stop_rmt_timer0(smc) ;
 441                 stop_rmt_timer1(smc) ;
 442                 stop_rmt_timer2(smc) ;
 443                 DB_RMTN(1, "RMT : RM5_RING_OP_DUP");
 444                 ACTIONS_DONE() ;
 445                 break;
 446         case RM5_RING_OP_DUP :
 447                 
 448                 if (smc->r.dup_addr_test == DA_PASSED) {
 449                         smc->r.da_flag = FALSE ;
 450                         GO_STATE(RM2_RING_OP) ;
 451                         break ;
 452                 }
 453                 
 454                 else if (cmd == RM_RING_NON_OP) {
 455                         smc->r.jm_flag = FALSE ;
 456                         smc->r.bn_flag = FALSE ;
 457                         GO_STATE(RM4_NON_OP_DUP) ;
 458                         break ;
 459                 }
 460                 break ;
 461         case ACTIONS(RM6_DIRECTED) :
 462                 start_rmt_timer0(smc,smc->s.rmt_t_direct,RM_TIMEOUT_T_DIRECT) ;
 463                 stop_rmt_timer1(smc) ;
 464                 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
 465                 sm_ma_control(smc,MA_DIRECTED) ;
 466                 RS_SET(smc,RS_BEACON) ;
 467                 DB_RMTN(1, "RMT : RM6_DIRECTED");
 468                 ACTIONS_DONE() ;
 469                 break ;
 470         case RM6_DIRECTED :
 471                 
 472                 if (cmd == RM_TIMEOUT_POLL) {
 473                         start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
 474                         sm_mac_check_beacon_claim(smc) ;
 475 #ifndef SUPERNET_3
 476                         
 477 
 478 
 479 
 480 
 481                         restart_trt_for_dbcn(smc) ;
 482 #endif 
 483                         break ;
 484                 }
 485                 if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
 486                         !smc->r.da_flag) {
 487                         smc->r.bn_flag = FALSE ;
 488                         GO_STATE(RM3_DETECT) ;
 489                         break ;
 490                 }
 491                 
 492                 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
 493                         smc->r.da_flag) {
 494                         smc->r.bn_flag = FALSE ;
 495                         GO_STATE(RM4_NON_OP_DUP) ;
 496                         break ;
 497                 }
 498                 
 499                 else if (cmd == RM_TIMEOUT_T_DIRECT) {
 500                         GO_STATE(RM7_TRACE) ;
 501                         break ;
 502                 }
 503                 break ;
 504         case ACTIONS(RM7_TRACE) :
 505                 stop_rmt_timer0(smc) ;
 506                 stop_rmt_timer1(smc) ;
 507                 stop_rmt_timer2(smc) ;
 508                 smc->e.trace_prop |= ENTITY_BIT(ENTITY_MAC) ;
 509                 queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ;
 510                 DB_RMTN(1, "RMT : RM7_TRACE");
 511                 ACTIONS_DONE() ;
 512                 break ;
 513         case RM7_TRACE :
 514                 break ;
 515         default:
 516                 SMT_PANIC(smc,SMT_E0122, SMT_E0122_MSG) ;
 517                 break;
 518         }
 519 }
 520 
 521 
 522 
 523 
 524 
 525 static void rmt_dup_actions(struct s_smc *smc)
 526 {
 527         if (smc->r.jm_flag) {
 528         }
 529         else {
 530                 if (smc->s.rmt_dup_mac_behavior) {
 531                         SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
 532                         rmt_reinsert_actions(smc) ;
 533                 }
 534                 else {
 535                         SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
 536                         rmt_leave_actions(smc) ;
 537                 }
 538         }
 539 }
 540 
 541 
 542 
 543 
 544 static void rmt_reinsert_actions(struct s_smc *smc)
 545 {
 546         queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
 547         queue_event(smc,EVENT_ECM,EC_CONNECT) ;
 548 }
 549 
 550 
 551 
 552 
 553 static void rmt_new_dup_actions(struct s_smc *smc)
 554 {
 555         smc->r.da_flag = TRUE ;
 556         smc->r.bn_flag = FALSE ;
 557         smc->r.jm_flag = FALSE ;
 558         
 559 
 560 
 561 
 562 
 563 
 564         if (smc->s.rmt_dup_mac_behavior) {
 565                 SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
 566                 rmt_reinsert_actions(smc) ;
 567         }
 568         else {
 569                 SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
 570                 rmt_leave_actions(smc) ;
 571         }
 572 }
 573 
 574 
 575 
 576 
 577 
 578 static void rmt_leave_actions(struct s_smc *smc)
 579 {
 580         queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
 581         
 582 
 583 
 584 
 585 }
 586 
 587 
 588 
 589 
 590 
 591 static void start_rmt_timer0(struct s_smc *smc, u_long value, int event)
 592 {
 593         smc->r.timer0_exp = FALSE ;             
 594         smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event));
 595 }
 596 
 597 
 598 
 599 
 600 
 601 static void start_rmt_timer1(struct s_smc *smc, u_long value, int event)
 602 {
 603         smc->r.timer1_exp = FALSE ;     
 604         smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event));
 605 }
 606 
 607 
 608 
 609 
 610 
 611 static void start_rmt_timer2(struct s_smc *smc, u_long value, int event)
 612 {
 613         smc->r.timer2_exp = FALSE ;             
 614         smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event));
 615 }
 616 
 617 
 618 
 619 
 620 
 621 static void stop_rmt_timer0(struct s_smc *smc)
 622 {
 623         if (smc->r.rmt_timer0.tm_active)
 624                 smt_timer_stop(smc,&smc->r.rmt_timer0) ;
 625 }
 626 
 627 
 628 
 629 
 630 
 631 static void stop_rmt_timer1(struct s_smc *smc)
 632 {
 633         if (smc->r.rmt_timer1.tm_active)
 634                 smt_timer_stop(smc,&smc->r.rmt_timer1) ;
 635 }
 636 
 637 
 638 
 639 
 640 
 641 static void stop_rmt_timer2(struct s_smc *smc)
 642 {
 643         if (smc->r.rmt_timer2.tm_active)
 644                 smt_timer_stop(smc,&smc->r.rmt_timer2) ;
 645 }
 646