0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #include "h/types.h"
0042 #include "h/fddi.h"
0043 #include "h/smc.h"
0044
0045 #define KERNEL
0046 #include "h/smtstate.h"
0047
0048
0049
0050
0051 #define AFLAG 0x10
0052 #define GO_STATE(x) (smc->mib.m[MAC0].fddiMACRMTState = (x)|AFLAG)
0053 #define ACTIONS_DONE() (smc->mib.m[MAC0].fddiMACRMTState &= ~AFLAG)
0054 #define ACTIONS(x) (x|AFLAG)
0055
0056 #define RM0_ISOLATED 0
0057 #define RM1_NON_OP 1
0058 #define RM2_RING_OP 2
0059 #define RM3_DETECT 3
0060 #define RM4_NON_OP_DUP 4
0061 #define RM5_RING_OP_DUP 5
0062 #define RM6_DIRECTED 6
0063 #define RM7_TRACE 7
0064
0065
0066
0067
0068 static const char * const rmt_states[] = {
0069 "RM0_ISOLATED","RM1_NON_OP","RM2_RING_OP","RM3_DETECT",
0070 "RM4_NON_OP_DUP","RM5_RING_OP_DUP","RM6_DIRECTED",
0071 "RM7_TRACE"
0072 } ;
0073
0074
0075
0076
0077 static const char * const rmt_events[] = {
0078 "NONE","RM_RING_OP","RM_RING_NON_OP","RM_MY_BEACON",
0079 "RM_OTHER_BEACON","RM_MY_CLAIM","RM_TRT_EXP","RM_VALID_CLAIM",
0080 "RM_JOIN","RM_LOOP","RM_DUP_ADDR","RM_ENABLE_FLAG",
0081 "RM_TIMEOUT_NON_OP","RM_TIMEOUT_T_STUCK",
0082 "RM_TIMEOUT_ANNOUNCE","RM_TIMEOUT_T_DIRECT",
0083 "RM_TIMEOUT_D_MAX","RM_TIMEOUT_POLL","RM_TX_STATE_CHANGE"
0084 } ;
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 static void rmt_fsm(struct s_smc *smc, int cmd);
0096 static void start_rmt_timer0(struct s_smc *smc, u_long value, int event);
0097 static void start_rmt_timer1(struct s_smc *smc, u_long value, int event);
0098 static void start_rmt_timer2(struct s_smc *smc, u_long value, int event);
0099 static void stop_rmt_timer0(struct s_smc *smc);
0100 static void stop_rmt_timer1(struct s_smc *smc);
0101 static void stop_rmt_timer2(struct s_smc *smc);
0102 static void rmt_dup_actions(struct s_smc *smc);
0103 static void rmt_reinsert_actions(struct s_smc *smc);
0104 static void rmt_leave_actions(struct s_smc *smc);
0105 static void rmt_new_dup_actions(struct s_smc *smc);
0106
0107 #ifndef SUPERNET_3
0108 extern void restart_trt_for_dbcn() ;
0109 #endif
0110
0111
0112
0113
0114
0115 void rmt_init(struct s_smc *smc)
0116 {
0117 smc->mib.m[MAC0].fddiMACRMTState = ACTIONS(RM0_ISOLATED) ;
0118 smc->r.dup_addr_test = DA_NONE ;
0119 smc->r.da_flag = 0 ;
0120 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
0121 smc->r.sm_ma_avail = FALSE ;
0122 smc->r.loop_avail = 0 ;
0123 smc->r.bn_flag = 0 ;
0124 smc->r.jm_flag = 0 ;
0125 smc->r.no_flag = TRUE ;
0126 }
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 void rmt(struct s_smc *smc, int event)
0138 {
0139 int state ;
0140
0141 do {
0142 DB_RMT("RMT : state %s%s event %s",
0143 smc->mib.m[MAC0].fddiMACRMTState & AFLAG ? "ACTIONS " : "",
0144 rmt_states[smc->mib.m[MAC0].fddiMACRMTState & ~AFLAG],
0145 rmt_events[event]);
0146 state = smc->mib.m[MAC0].fddiMACRMTState ;
0147 rmt_fsm(smc,event) ;
0148 event = 0 ;
0149 } while (state != smc->mib.m[MAC0].fddiMACRMTState) ;
0150 rmt_state_change(smc,(int)smc->mib.m[MAC0].fddiMACRMTState) ;
0151 }
0152
0153
0154
0155
0156 static void rmt_fsm(struct s_smc *smc, int cmd)
0157 {
0158
0159
0160
0161 if (!smc->r.rm_join && !smc->r.rm_loop &&
0162 smc->mib.m[MAC0].fddiMACRMTState != ACTIONS(RM0_ISOLATED) &&
0163 smc->mib.m[MAC0].fddiMACRMTState != RM0_ISOLATED) {
0164 RS_SET(smc,RS_NORINGOP) ;
0165 rmt_indication(smc,0) ;
0166 GO_STATE(RM0_ISOLATED) ;
0167 return ;
0168 }
0169
0170 switch(smc->mib.m[MAC0].fddiMACRMTState) {
0171 case ACTIONS(RM0_ISOLATED) :
0172 stop_rmt_timer0(smc) ;
0173 stop_rmt_timer1(smc) ;
0174 stop_rmt_timer2(smc) ;
0175
0176
0177
0178
0179 sm_ma_control(smc,MA_OFFLINE) ;
0180 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
0181 smc->r.loop_avail = FALSE ;
0182 smc->r.sm_ma_avail = FALSE ;
0183 smc->r.no_flag = TRUE ;
0184 DB_RMTN(1, "RMT : ISOLATED");
0185 ACTIONS_DONE() ;
0186 break ;
0187 case RM0_ISOLATED :
0188
0189 if (smc->r.rm_join || smc->r.rm_loop) {
0190
0191
0192
0193
0194
0195
0196 sm_ma_control(smc,MA_RESET) ;
0197 GO_STATE(RM1_NON_OP) ;
0198 break ;
0199 }
0200 break ;
0201 case ACTIONS(RM1_NON_OP) :
0202 start_rmt_timer0(smc,smc->s.rmt_t_non_op,RM_TIMEOUT_NON_OP) ;
0203 stop_rmt_timer1(smc) ;
0204 stop_rmt_timer2(smc) ;
0205 sm_ma_control(smc,MA_BEACON) ;
0206 DB_RMTN(1, "RMT : RING DOWN");
0207 RS_SET(smc,RS_NORINGOP) ;
0208 smc->r.sm_ma_avail = FALSE ;
0209 rmt_indication(smc,0) ;
0210 ACTIONS_DONE() ;
0211 break ;
0212 case RM1_NON_OP :
0213
0214 if (cmd == RM_RING_OP) {
0215 RS_SET(smc,RS_RINGOPCHANGE) ;
0216 GO_STATE(RM2_RING_OP) ;
0217 break ;
0218 }
0219
0220 else if (cmd == RM_TIMEOUT_NON_OP) {
0221 smc->r.bn_flag = FALSE ;
0222 smc->r.no_flag = TRUE ;
0223 GO_STATE(RM3_DETECT) ;
0224 break ;
0225 }
0226 break ;
0227 case ACTIONS(RM2_RING_OP) :
0228 stop_rmt_timer0(smc) ;
0229 stop_rmt_timer1(smc) ;
0230 stop_rmt_timer2(smc) ;
0231 smc->r.no_flag = FALSE ;
0232 if (smc->r.rm_loop)
0233 smc->r.loop_avail = TRUE ;
0234 if (smc->r.rm_join) {
0235 smc->r.sm_ma_avail = TRUE ;
0236 if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
0237 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
0238 else
0239 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
0240 }
0241 DB_RMTN(1, "RMT : RING UP");
0242 RS_CLEAR(smc,RS_NORINGOP) ;
0243 RS_SET(smc,RS_RINGOPCHANGE) ;
0244 rmt_indication(smc,1) ;
0245 smt_stat_counter(smc,0) ;
0246 ACTIONS_DONE() ;
0247 break ;
0248 case RM2_RING_OP :
0249
0250 if (cmd == RM_RING_NON_OP) {
0251 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
0252 smc->r.loop_avail = FALSE ;
0253 RS_SET(smc,RS_RINGOPCHANGE) ;
0254 GO_STATE(RM1_NON_OP) ;
0255 break ;
0256 }
0257
0258 else if (cmd == RM_ENABLE_FLAG) {
0259 if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
0260 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
0261 else
0262 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
0263 }
0264
0265 else if (smc->r.dup_addr_test == DA_FAILED) {
0266 smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
0267 smc->r.loop_avail = FALSE ;
0268 smc->r.da_flag = TRUE ;
0269 GO_STATE(RM5_RING_OP_DUP) ;
0270 break ;
0271 }
0272 break ;
0273 case ACTIONS(RM3_DETECT) :
0274 start_rmt_timer0(smc,smc->s.mac_d_max*2,RM_TIMEOUT_D_MAX) ;
0275 start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
0276 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
0277 sm_mac_check_beacon_claim(smc) ;
0278 DB_RMTN(1, "RMT : RM3_DETECT");
0279 ACTIONS_DONE() ;
0280 break ;
0281 case RM3_DETECT :
0282 if (cmd == RM_TIMEOUT_POLL) {
0283 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
0284 sm_mac_check_beacon_claim(smc) ;
0285 break ;
0286 }
0287 if (cmd == RM_TIMEOUT_D_MAX) {
0288 smc->r.timer0_exp = TRUE ;
0289 }
0290
0291
0292
0293
0294
0295
0296 if (cmd == RM_TX_STATE_CHANGE) {
0297 start_rmt_timer0(smc,
0298 smc->s.mac_d_max*2,
0299 RM_TIMEOUT_D_MAX) ;
0300 }
0301
0302 if (cmd == RM_RING_OP) {
0303 GO_STATE(RM2_RING_OP) ;
0304 break ;
0305 }
0306
0307 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON)
0308 && smc->r.bn_flag) {
0309 smc->r.bn_flag = FALSE ;
0310 }
0311
0312 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
0313 int tx ;
0314
0315
0316
0317
0318
0319 if ((tx = sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
0320 DB_RMTN(2, "RMT : DETECT && TRT_EXPIRED && T4/T5");
0321 smc->r.bn_flag = TRUE ;
0322
0323
0324
0325
0326
0327
0328 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
0329 RM_TIMEOUT_T_STUCK) ;
0330 }
0331
0332
0333
0334
0335
0336
0337 DB_RMTN(2, "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)",
0338 tx, smc->r.bn_flag);
0339 }
0340
0341 else if (cmd == RM_MY_CLAIM && smc->r.timer0_exp) {
0342 rmt_new_dup_actions(smc) ;
0343 GO_STATE(RM4_NON_OP_DUP) ;
0344 break ;
0345 }
0346
0347 else if (cmd == RM_MY_BEACON && smc->r.timer0_exp) {
0348 rmt_new_dup_actions(smc) ;
0349 GO_STATE(RM4_NON_OP_DUP) ;
0350 break ;
0351 }
0352
0353 else if (cmd == RM_VALID_CLAIM) {
0354 rmt_new_dup_actions(smc) ;
0355 GO_STATE(RM4_NON_OP_DUP) ;
0356 break ;
0357 }
0358
0359 else if (cmd == RM_TIMEOUT_T_STUCK &&
0360 smc->r.rm_join && smc->r.bn_flag) {
0361 GO_STATE(RM6_DIRECTED) ;
0362 break ;
0363 }
0364 break ;
0365 case ACTIONS(RM4_NON_OP_DUP) :
0366 start_rmt_timer0(smc,smc->s.rmt_t_announce,RM_TIMEOUT_ANNOUNCE);
0367 start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
0368 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
0369 sm_mac_check_beacon_claim(smc) ;
0370 DB_RMTN(1, "RMT : RM4_NON_OP_DUP");
0371 ACTIONS_DONE() ;
0372 break ;
0373 case RM4_NON_OP_DUP :
0374 if (cmd == RM_TIMEOUT_POLL) {
0375 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
0376 sm_mac_check_beacon_claim(smc) ;
0377 break ;
0378 }
0379
0380 if (!smc->r.da_flag) {
0381 GO_STATE(RM1_NON_OP) ;
0382 break ;
0383 }
0384
0385 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
0386 smc->r.bn_flag) {
0387 smc->r.bn_flag = FALSE ;
0388 }
0389
0390 else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
0391 int tx ;
0392
0393
0394
0395
0396
0397 if ((tx = sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
0398 DB_RMTN(2, "RMT : NOPDUP && TRT_EXPIRED && T4/T5");
0399 smc->r.bn_flag = TRUE ;
0400
0401
0402
0403
0404
0405
0406 start_rmt_timer1(smc,smc->s.rmt_t_stuck,
0407 RM_TIMEOUT_T_STUCK) ;
0408 }
0409
0410
0411
0412
0413
0414
0415 DB_RMTN(2, "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)",
0416 tx, smc->r.bn_flag);
0417 }
0418
0419 else if (cmd == RM_TIMEOUT_ANNOUNCE && !smc->r.bn_flag) {
0420 rmt_dup_actions(smc) ;
0421 }
0422
0423 else if (cmd == RM_RING_OP) {
0424 smc->r.no_flag = FALSE ;
0425 GO_STATE(RM5_RING_OP_DUP) ;
0426 break ;
0427 }
0428
0429 else if (cmd == RM_TIMEOUT_T_STUCK &&
0430 smc->r.rm_join && smc->r.bn_flag) {
0431 GO_STATE(RM6_DIRECTED) ;
0432 break ;
0433 }
0434 break ;
0435 case ACTIONS(RM5_RING_OP_DUP) :
0436 stop_rmt_timer0(smc) ;
0437 stop_rmt_timer1(smc) ;
0438 stop_rmt_timer2(smc) ;
0439 DB_RMTN(1, "RMT : RM5_RING_OP_DUP");
0440 ACTIONS_DONE() ;
0441 break;
0442 case RM5_RING_OP_DUP :
0443
0444 if (smc->r.dup_addr_test == DA_PASSED) {
0445 smc->r.da_flag = FALSE ;
0446 GO_STATE(RM2_RING_OP) ;
0447 break ;
0448 }
0449
0450 else if (cmd == RM_RING_NON_OP) {
0451 smc->r.jm_flag = FALSE ;
0452 smc->r.bn_flag = FALSE ;
0453 GO_STATE(RM4_NON_OP_DUP) ;
0454 break ;
0455 }
0456 break ;
0457 case ACTIONS(RM6_DIRECTED) :
0458 start_rmt_timer0(smc,smc->s.rmt_t_direct,RM_TIMEOUT_T_DIRECT) ;
0459 stop_rmt_timer1(smc) ;
0460 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
0461 sm_ma_control(smc,MA_DIRECTED) ;
0462 RS_SET(smc,RS_BEACON) ;
0463 DB_RMTN(1, "RMT : RM6_DIRECTED");
0464 ACTIONS_DONE() ;
0465 break ;
0466 case RM6_DIRECTED :
0467
0468 if (cmd == RM_TIMEOUT_POLL) {
0469 start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
0470 sm_mac_check_beacon_claim(smc) ;
0471 #ifndef SUPERNET_3
0472
0473
0474
0475
0476
0477 restart_trt_for_dbcn(smc) ;
0478 #endif
0479 break ;
0480 }
0481 if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
0482 !smc->r.da_flag) {
0483 smc->r.bn_flag = FALSE ;
0484 GO_STATE(RM3_DETECT) ;
0485 break ;
0486 }
0487
0488 else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
0489 smc->r.da_flag) {
0490 smc->r.bn_flag = FALSE ;
0491 GO_STATE(RM4_NON_OP_DUP) ;
0492 break ;
0493 }
0494
0495 else if (cmd == RM_TIMEOUT_T_DIRECT) {
0496 GO_STATE(RM7_TRACE) ;
0497 break ;
0498 }
0499 break ;
0500 case ACTIONS(RM7_TRACE) :
0501 stop_rmt_timer0(smc) ;
0502 stop_rmt_timer1(smc) ;
0503 stop_rmt_timer2(smc) ;
0504 smc->e.trace_prop |= ENTITY_BIT(ENTITY_MAC) ;
0505 queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ;
0506 DB_RMTN(1, "RMT : RM7_TRACE");
0507 ACTIONS_DONE() ;
0508 break ;
0509 case RM7_TRACE :
0510 break ;
0511 default:
0512 SMT_PANIC(smc,SMT_E0122, SMT_E0122_MSG) ;
0513 break;
0514 }
0515 }
0516
0517
0518
0519
0520
0521 static void rmt_dup_actions(struct s_smc *smc)
0522 {
0523 if (smc->r.jm_flag) {
0524 }
0525 else {
0526 if (smc->s.rmt_dup_mac_behavior) {
0527 SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
0528 rmt_reinsert_actions(smc) ;
0529 }
0530 else {
0531 SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
0532 rmt_leave_actions(smc) ;
0533 }
0534 }
0535 }
0536
0537
0538
0539
0540 static void rmt_reinsert_actions(struct s_smc *smc)
0541 {
0542 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
0543 queue_event(smc,EVENT_ECM,EC_CONNECT) ;
0544 }
0545
0546
0547
0548
0549 static void rmt_new_dup_actions(struct s_smc *smc)
0550 {
0551 smc->r.da_flag = TRUE ;
0552 smc->r.bn_flag = FALSE ;
0553 smc->r.jm_flag = FALSE ;
0554
0555
0556
0557
0558
0559
0560 if (smc->s.rmt_dup_mac_behavior) {
0561 SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
0562 rmt_reinsert_actions(smc) ;
0563 }
0564 else {
0565 SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
0566 rmt_leave_actions(smc) ;
0567 }
0568 }
0569
0570
0571
0572
0573
0574 static void rmt_leave_actions(struct s_smc *smc)
0575 {
0576 queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
0577
0578
0579
0580
0581 }
0582
0583
0584
0585
0586
0587 static void start_rmt_timer0(struct s_smc *smc, u_long value, int event)
0588 {
0589 smc->r.timer0_exp = FALSE ;
0590 smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event));
0591 }
0592
0593
0594
0595
0596
0597 static void start_rmt_timer1(struct s_smc *smc, u_long value, int event)
0598 {
0599 smc->r.timer1_exp = FALSE ;
0600 smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event));
0601 }
0602
0603
0604
0605
0606
0607 static void start_rmt_timer2(struct s_smc *smc, u_long value, int event)
0608 {
0609 smc->r.timer2_exp = FALSE ;
0610 smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event));
0611 }
0612
0613
0614
0615
0616
0617 static void stop_rmt_timer0(struct s_smc *smc)
0618 {
0619 if (smc->r.rmt_timer0.tm_active)
0620 smt_timer_stop(smc,&smc->r.rmt_timer0) ;
0621 }
0622
0623
0624
0625
0626
0627 static void stop_rmt_timer1(struct s_smc *smc)
0628 {
0629 if (smc->r.rmt_timer1.tm_active)
0630 smt_timer_stop(smc,&smc->r.rmt_timer1) ;
0631 }
0632
0633
0634
0635
0636
0637 static void stop_rmt_timer2(struct s_smc *smc)
0638 {
0639 if (smc->r.rmt_timer2.tm_active)
0640 smt_timer_stop(smc,&smc->r.rmt_timer2) ;
0641 }
0642