root/drivers/net/fddi/skfp/rmt.c

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

DEFINITIONS

This source file includes following definitions.
  1. rmt_init
  2. rmt
  3. rmt_fsm
  4. rmt_dup_actions
  5. rmt_reinsert_actions
  6. rmt_new_dup_actions
  7. rmt_leave_actions
  8. start_rmt_timer0
  9. start_rmt_timer1
  10. start_rmt_timer2
  11. stop_rmt_timer0
  12. stop_rmt_timer1
  13. stop_rmt_timer2

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /******************************************************************************
   3  *
   4  *      (C)Copyright 1998,1999 SysKonnect,
   5  *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
   6  *
   7  *      See the file "skfddi.c" for further information.
   8  *
   9  *      The information in this file is provided "AS IS" without warranty.
  10  *
  11  ******************************************************************************/
  12 
  13 /*
  14         SMT RMT
  15         Ring Management
  16 */
  17 
  18 /*
  19  * Hardware independent state machine implemantation
  20  * The following external SMT functions are referenced :
  21  *
  22  *              queue_event()
  23  *              smt_timer_start()
  24  *              smt_timer_stop()
  25  *
  26  *      The following external HW dependent functions are referenced :
  27  *              sm_ma_control()
  28  *              sm_mac_check_beacon_claim()
  29  *
  30  *      The following HW dependent events are required :
  31  *              RM_RING_OP
  32  *              RM_RING_NON_OP
  33  *              RM_MY_BEACON
  34  *              RM_OTHER_BEACON
  35  *              RM_MY_CLAIM
  36  *              RM_TRT_EXP
  37  *              RM_VALID_CLAIM
  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  * FSM Macros
  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               /* not operational */
  62 #define RM2_RING_OP     2               /* ring operational */
  63 #define RM3_DETECT      3               /* detect dupl addresses */
  64 #define RM4_NON_OP_DUP  4               /* dupl. addr detected */
  65 #define RM5_RING_OP_DUP 5               /* ring oper. with dupl. addr */
  66 #define RM6_DIRECTED    6               /* sending directed beacons */
  67 #define RM7_TRACE       7               /* trace initiated */
  68 
  69 /*
  70  * symbolic state names
  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  * symbolic event names
  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  * Globals
  92  * in struct s_rmt
  93  */
  94 
  95 
  96 /*
  97  * function declarations
  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 /*SUPERNET_3*/
 114 
 115 /*
 116         init RMT state machine
 117         clear all RMT vars and flags
 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         RMT state machine
 134         called by dispatcher
 135 
 136         do
 137                 display state change
 138                 process event
 139         until SM is stable
 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         process RMT event
 159 */
 160 static void rmt_fsm(struct s_smc *smc, int cmd)
 161 {
 162         /*
 163          * RM00-RM70 : from all states
 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                  * Disable MAC.
 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                 /*RM01*/
 193                 if (smc->r.rm_join || smc->r.rm_loop) {
 194                         /*
 195                          * According to the standard the MAC must be reset
 196                          * here. The FORMAC will be initialized and Claim
 197                          * and Beacon Frames will be uploaded to the MAC.
 198                          * So any change of Treq will take effect NOW.
 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                 /*RM12*/
 218                 if (cmd == RM_RING_OP) {
 219                         RS_SET(smc,RS_RINGOPCHANGE) ;
 220                         GO_STATE(RM2_RING_OP) ;
 221                         break ;
 222                 }
 223                 /*RM13*/
 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                 /*RM21*/
 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                 /*RM22a*/
 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                 /*RM25*/
 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                  *jd(22-Feb-1999)
 296                  * We need a time ">= 2*mac_d_max" since we had finished
 297                  * Claim or Beacon state. So we will restart timer0 at
 298                  * every state change.
 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                 /*RM32*/
 306                 if (cmd == RM_RING_OP) {
 307                         GO_STATE(RM2_RING_OP) ;
 308                         break ;
 309                 }
 310                 /*RM33a*/
 311                 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON)
 312                         && smc->r.bn_flag) {
 313                         smc->r.bn_flag = FALSE ;
 314                 }
 315                 /*RM33b*/
 316                 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
 317                         int     tx ;
 318                         /*
 319                          * set bn_flag only if in state T4 or T5:
 320                          * only if we're the beaconer should we start the
 321                          * trace !
 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                                  * If one of the upstream stations beaconed
 328                                  * and the link to the upstream neighbor is
 329                                  * lost we need to restart the stuck timer to
 330                                  * check the "stuck beacon" condition.
 331                                  */
 332                                 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
 333                                         RM_TIMEOUT_T_STUCK) ;
 334                         }
 335                         /*
 336                          * We do NOT need to clear smc->r.bn_flag in case of
 337                          * not being in state T4 or T5, because the flag
 338                          * must be cleared in order to get in this condition.
 339                          */
 340 
 341                         DB_RMTN(2, "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)",
 342                                 tx, smc->r.bn_flag);
 343                 }
 344                 /*RM34a*/
 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                 /*RM34b*/
 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                 /*RM34c*/
 357                 else if (cmd == RM_VALID_CLAIM) {
 358                         rmt_new_dup_actions(smc) ;
 359                         GO_STATE(RM4_NON_OP_DUP) ;
 360                         break ;
 361                 }
 362                 /*RM36*/
 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                 /*RM41*/
 384                 if (!smc->r.da_flag) {
 385                         GO_STATE(RM1_NON_OP) ;
 386                         break ;
 387                 }
 388                 /*RM44a*/
 389                 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
 390                         smc->r.bn_flag) {
 391                         smc->r.bn_flag = FALSE ;
 392                 }
 393                 /*RM44b*/
 394                 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
 395                         int     tx ;
 396                         /*
 397                          * set bn_flag only if in state T4 or T5:
 398                          * only if we're the beaconer should we start the
 399                          * trace !
 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                                  * If one of the upstream stations beaconed
 406                                  * and the link to the upstream neighbor is
 407                                  * lost we need to restart the stuck timer to
 408                                  * check the "stuck beacon" condition.
 409                                  */
 410                                 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
 411                                         RM_TIMEOUT_T_STUCK) ;
 412                         }
 413                         /*
 414                          * We do NOT need to clear smc->r.bn_flag in case of
 415                          * not being in state T4 or T5, because the flag
 416                          * must be cleared in order to get in this condition.
 417                          */
 418 
 419                         DB_RMTN(2, "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)",
 420                                 tx, smc->r.bn_flag);
 421                 }
 422                 /*RM44c*/
 423                 else if (cmd == RM_TIMEOUT_ANNOUNCE && !smc->r.bn_flag) {
 424                         rmt_dup_actions(smc) ;
 425                 }
 426                 /*RM45*/
 427                 else if (cmd == RM_RING_OP) {
 428                         smc->r.no_flag = FALSE ;
 429                         GO_STATE(RM5_RING_OP_DUP) ;
 430                         break ;
 431                 }
 432                 /*RM46*/
 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                 /*RM52*/
 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                 /*RM54*/
 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                 /*RM63*/
 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                         /* Because of problems with the Supernet II chip set
 477                          * sending of Directed Beacon will stop after 165ms
 478                          * therefore restart_trt_for_dbcn(smc) will be called
 479                          * to prevent this.
 480                          */
 481                         restart_trt_for_dbcn(smc) ;
 482 #endif /*SUPERNET_3*/
 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                 /*RM64*/
 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                 /*RM67*/
 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  * (jd) RMT duplicate address actions
 523  * leave the ring or reinsert just as configured
 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  * Reconnect to the Ring
 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  * duplicate address detected
 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          * we have three options : change address, jam or leave
 560          * we leave the ring as default 
 561          * Optionally it's possible to reinsert after leaving the Ring
 562          * but this will not conform with SMT Spec.
 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  * leave the ring
 577  */
 578 static void rmt_leave_actions(struct s_smc *smc)
 579 {
 580         queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
 581         /*
 582          * Note: Do NOT try again later. (with please reconnect)
 583          * The station must be left from the ring!
 584          */
 585 }
 586 
 587 /*
 588  * SMT timer interface
 589  *      start RMT timer 0
 590  */
 591 static void start_rmt_timer0(struct s_smc *smc, u_long value, int event)
 592 {
 593         smc->r.timer0_exp = FALSE ;             /* clear timer event flag */
 594         smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event));
 595 }
 596 
 597 /*
 598  * SMT timer interface
 599  *      start RMT timer 1
 600  */
 601 static void start_rmt_timer1(struct s_smc *smc, u_long value, int event)
 602 {
 603         smc->r.timer1_exp = FALSE ;     /* clear timer event flag */
 604         smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event));
 605 }
 606 
 607 /*
 608  * SMT timer interface
 609  *      start RMT timer 2
 610  */
 611 static void start_rmt_timer2(struct s_smc *smc, u_long value, int event)
 612 {
 613         smc->r.timer2_exp = FALSE ;             /* clear timer event flag */
 614         smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event));
 615 }
 616 
 617 /*
 618  * SMT timer interface
 619  *      stop RMT timer 0
 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  * SMT timer interface
 629  *      stop RMT timer 1
 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  * SMT timer interface
 639  *      stop RMT timer 2
 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 

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