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 647