OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [skfp/] [rmt.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/******************************************************************************
2
 *
3
 *      (C)Copyright 1998,1999 SysKonnect,
4
 *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5
 *
6
 *      See the file "skfddi.c" for further information.
7
 *
8
 *      This program is free software; you can redistribute it and/or modify
9
 *      it under the terms of the GNU General Public License as published by
10
 *      the Free Software Foundation; either version 2 of the License, or
11
 *      (at your option) any later version.
12
 *
13
 *      The information in this file is provided "AS IS" without warranty.
14
 *
15
 ******************************************************************************/
16
 
17
/*
18
        SMT RMT
19
        Ring Management
20
*/
21
 
22
/*
23
 * Hardware independent state machine implemantation
24
 * The following external SMT functions are referenced :
25
 *
26
 *              queue_event()
27
 *              smt_timer_start()
28
 *              smt_timer_stop()
29
 *
30
 *      The following external HW dependent functions are referenced :
31
 *              sm_ma_control()
32
 *              sm_mac_check_beacon_claim()
33
 *
34
 *      The following HW dependent events are required :
35
 *              RM_RING_OP
36
 *              RM_RING_NON_OP
37
 *              RM_MY_BEACON
38
 *              RM_OTHER_BEACON
39
 *              RM_MY_CLAIM
40
 *              RM_TRT_EXP
41
 *              RM_VALID_CLAIM
42
 *
43
 */
44
 
45
#include "h/types.h"
46
#include "h/fddi.h"
47
#include "h/smc.h"
48
 
49
#define KERNEL
50
#include "h/smtstate.h"
51
 
52
#ifndef lint
53
static const char ID_sccs[] = "@(#)rmt.c        2.13 99/07/02 (C) SK " ;
54
#endif
55
 
56
/*
57
 * FSM Macros
58
 */
59
#define AFLAG   0x10
60
#define GO_STATE(x)     (smc->mib.m[MAC0].fddiMACRMTState = (x)|AFLAG)
61
#define ACTIONS_DONE()  (smc->mib.m[MAC0].fddiMACRMTState &= ~AFLAG)
62
#define ACTIONS(x)      (x|AFLAG)
63
 
64
#define RM0_ISOLATED    0
65
#define RM1_NON_OP      1               /* not operational */
66
#define RM2_RING_OP     2               /* ring operational */
67
#define RM3_DETECT      3               /* detect dupl addresses */
68
#define RM4_NON_OP_DUP  4               /* dupl. addr detected */
69
#define RM5_RING_OP_DUP 5               /* ring oper. with dupl. addr */
70
#define RM6_DIRECTED    6               /* sending directed beacons */
71
#define RM7_TRACE       7               /* trace initiated */
72
 
73
#ifdef  DEBUG
74
/*
75
 * symbolic state names
76
 */
77
static const char * const rmt_states[] = {
78
        "RM0_ISOLATED","RM1_NON_OP","RM2_RING_OP","RM3_DETECT",
79
        "RM4_NON_OP_DUP","RM5_RING_OP_DUP","RM6_DIRECTED",
80
        "RM7_TRACE"
81
} ;
82
 
83
/*
84
 * symbolic event names
85
 */
86
static const char * const rmt_events[] = {
87
        "NONE","RM_RING_OP","RM_RING_NON_OP","RM_MY_BEACON",
88
        "RM_OTHER_BEACON","RM_MY_CLAIM","RM_TRT_EXP","RM_VALID_CLAIM",
89
        "RM_JOIN","RM_LOOP","RM_DUP_ADDR","RM_ENABLE_FLAG",
90
        "RM_TIMEOUT_NON_OP","RM_TIMEOUT_T_STUCK",
91
        "RM_TIMEOUT_ANNOUNCE","RM_TIMEOUT_T_DIRECT",
92
        "RM_TIMEOUT_D_MAX","RM_TIMEOUT_POLL","RM_TX_STATE_CHANGE"
93
} ;
94
#endif
95
 
96
/*
97
 * Globals
98
 * in struct s_rmt
99
 */
100
 
101
 
102
/*
103
 * function declarations
104
 */
105
static void rmt_fsm(struct s_smc *smc, int cmd);
106
static void start_rmt_timer0(struct s_smc *smc, u_long value, int event);
107
static void start_rmt_timer1(struct s_smc *smc, u_long value, int event);
108
static void start_rmt_timer2(struct s_smc *smc, u_long value, int event);
109
static void stop_rmt_timer0(struct s_smc *smc);
110
static void stop_rmt_timer1(struct s_smc *smc);
111
static void stop_rmt_timer2(struct s_smc *smc);
112
static void rmt_dup_actions(struct s_smc *smc);
113
static void rmt_reinsert_actions(struct s_smc *smc);
114
static void rmt_leave_actions(struct s_smc *smc);
115
static void rmt_new_dup_actions(struct s_smc *smc);
116
 
117
#ifndef SUPERNET_3
118
extern void restart_trt_for_dbcn() ;
119
#endif /*SUPERNET_3*/
120
 
121
/*
122
        init RMT state machine
123
        clear all RMT vars and flags
124
*/
125
void rmt_init(struct s_smc *smc)
126
{
127
        smc->mib.m[MAC0].fddiMACRMTState = ACTIONS(RM0_ISOLATED) ;
128
        smc->r.dup_addr_test = DA_NONE ;
129
        smc->r.da_flag = 0 ;
130
        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
131
        smc->r.sm_ma_avail = FALSE ;
132
        smc->r.loop_avail = 0 ;
133
        smc->r.bn_flag = 0 ;
134
        smc->r.jm_flag = 0 ;
135
        smc->r.no_flag = TRUE ;
136
}
137
 
138
/*
139
        RMT state machine
140
        called by dispatcher
141
 
142
        do
143
                display state change
144
                process event
145
        until SM is stable
146
*/
147
void rmt(struct s_smc *smc, int event)
148
{
149
        int     state ;
150
 
151
        do {
152
                DB_RMT("RMT : state %s%s",
153
                        (smc->mib.m[MAC0].fddiMACRMTState & AFLAG) ? "ACTIONS " : "",
154
                        rmt_states[smc->mib.m[MAC0].fddiMACRMTState & ~AFLAG]) ;
155
                DB_RMT(" event %s\n",rmt_events[event],0) ;
156
                state = smc->mib.m[MAC0].fddiMACRMTState ;
157
                rmt_fsm(smc,event) ;
158
                event = 0 ;
159
        } while (state != smc->mib.m[MAC0].fddiMACRMTState) ;
160
        rmt_state_change(smc,(int)smc->mib.m[MAC0].fddiMACRMTState) ;
161
}
162
 
163
/*
164
        process RMT event
165
*/
166
static void rmt_fsm(struct s_smc *smc, int cmd)
167
{
168
        /*
169
         * RM00-RM70 : from all states
170
         */
171
        if (!smc->r.rm_join && !smc->r.rm_loop &&
172
                smc->mib.m[MAC0].fddiMACRMTState != ACTIONS(RM0_ISOLATED) &&
173
                smc->mib.m[MAC0].fddiMACRMTState != RM0_ISOLATED) {
174
                RS_SET(smc,RS_NORINGOP) ;
175
                rmt_indication(smc,0) ;
176
                GO_STATE(RM0_ISOLATED) ;
177
                return ;
178
        }
179
 
180
        switch(smc->mib.m[MAC0].fddiMACRMTState) {
181
        case ACTIONS(RM0_ISOLATED) :
182
                stop_rmt_timer0(smc) ;
183
                stop_rmt_timer1(smc) ;
184
                stop_rmt_timer2(smc) ;
185
 
186
                /*
187
                 * Disable MAC.
188
                 */
189
                sm_ma_control(smc,MA_OFFLINE) ;
190
                smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
191
                smc->r.loop_avail = FALSE ;
192
                smc->r.sm_ma_avail = FALSE ;
193
                smc->r.no_flag = TRUE ;
194
                DB_RMTN(1,"RMT : ISOLATED\n",0,0) ;
195
                ACTIONS_DONE() ;
196
                break ;
197
        case RM0_ISOLATED :
198
                /*RM01*/
199
                if (smc->r.rm_join || smc->r.rm_loop) {
200
                        /*
201
                         * According to the standard the MAC must be reset
202
                         * here. The FORMAC will be initialized and Claim
203
                         * and Beacon Frames will be uploaded to the MAC.
204
                         * So any change of Treq will take effect NOW.
205
                         */
206
                        sm_ma_control(smc,MA_RESET) ;
207
                        GO_STATE(RM1_NON_OP) ;
208
                        break ;
209
                }
210
                break ;
211
        case ACTIONS(RM1_NON_OP) :
212
                start_rmt_timer0(smc,smc->s.rmt_t_non_op,RM_TIMEOUT_NON_OP) ;
213
                stop_rmt_timer1(smc) ;
214
                stop_rmt_timer2(smc) ;
215
                sm_ma_control(smc,MA_BEACON) ;
216
                DB_RMTN(1,"RMT : RING DOWN\n",0,0) ;
217
                RS_SET(smc,RS_NORINGOP) ;
218
                smc->r.sm_ma_avail = FALSE ;
219
                rmt_indication(smc,0) ;
220
                ACTIONS_DONE() ;
221
                break ;
222
        case RM1_NON_OP :
223
                /*RM12*/
224
                if (cmd == RM_RING_OP) {
225
                        RS_SET(smc,RS_RINGOPCHANGE) ;
226
                        GO_STATE(RM2_RING_OP) ;
227
                        break ;
228
                }
229
                /*RM13*/
230
                else if (cmd == RM_TIMEOUT_NON_OP) {
231
                        smc->r.bn_flag = FALSE ;
232
                        smc->r.no_flag = TRUE ;
233
                        GO_STATE(RM3_DETECT) ;
234
                        break ;
235
                }
236
                break ;
237
        case ACTIONS(RM2_RING_OP) :
238
                stop_rmt_timer0(smc) ;
239
                stop_rmt_timer1(smc) ;
240
                stop_rmt_timer2(smc) ;
241
                smc->r.no_flag = FALSE ;
242
                if (smc->r.rm_loop)
243
                        smc->r.loop_avail = TRUE ;
244
                if (smc->r.rm_join) {
245
                        smc->r.sm_ma_avail = TRUE ;
246
                        if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
247
                        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
248
                                else
249
                        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
250
                }
251
                DB_RMTN(1,"RMT : RING UP\n",0,0) ;
252
                RS_CLEAR(smc,RS_NORINGOP) ;
253
                RS_SET(smc,RS_RINGOPCHANGE) ;
254
                rmt_indication(smc,1) ;
255
                smt_stat_counter(smc,0) ;
256
                ACTIONS_DONE() ;
257
                break ;
258
        case RM2_RING_OP :
259
                /*RM21*/
260
                if (cmd == RM_RING_NON_OP) {
261
                        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
262
                        smc->r.loop_avail = FALSE ;
263
                        RS_SET(smc,RS_RINGOPCHANGE) ;
264
                        GO_STATE(RM1_NON_OP) ;
265
                        break ;
266
                }
267
                /*RM22a*/
268
                else if (cmd == RM_ENABLE_FLAG) {
269
                        if (smc->mib.m[MAC0].fddiMACMA_UnitdataEnable)
270
                        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = TRUE ;
271
                                else
272
                        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
273
                }
274
                /*RM25*/
275
                else if (smc->r.dup_addr_test == DA_FAILED) {
276
                        smc->mib.m[MAC0].fddiMACMA_UnitdataAvailable = FALSE ;
277
                        smc->r.loop_avail = FALSE ;
278
                        smc->r.da_flag = TRUE ;
279
                        GO_STATE(RM5_RING_OP_DUP) ;
280
                        break ;
281
                }
282
                break ;
283
        case ACTIONS(RM3_DETECT) :
284
                start_rmt_timer0(smc,smc->s.mac_d_max*2,RM_TIMEOUT_D_MAX) ;
285
                start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
286
                start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
287
                sm_mac_check_beacon_claim(smc) ;
288
                DB_RMTN(1,"RMT : RM3_DETECT\n",0,0) ;
289
                ACTIONS_DONE() ;
290
                break ;
291
        case RM3_DETECT :
292
                if (cmd == RM_TIMEOUT_POLL) {
293
                        start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
294
                        sm_mac_check_beacon_claim(smc) ;
295
                        break ;
296
                }
297
                if (cmd == RM_TIMEOUT_D_MAX) {
298
                        smc->r.timer0_exp = TRUE ;
299
                }
300
                /*
301
                 *jd(22-Feb-1999)
302
                 * We need a time ">= 2*mac_d_max" since we had finished
303
                 * Claim or Beacon state. So we will restart timer0 at
304
                 * every state change.
305
                 */
306
                if (cmd == RM_TX_STATE_CHANGE) {
307
                        start_rmt_timer0(smc,
308
                                         smc->s.mac_d_max*2,
309
                                         RM_TIMEOUT_D_MAX) ;
310
                }
311
                /*RM32*/
312
                if (cmd == RM_RING_OP) {
313
                        GO_STATE(RM2_RING_OP) ;
314
                        break ;
315
                }
316
                /*RM33a*/
317
                else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON)
318
                        && smc->r.bn_flag) {
319
                        smc->r.bn_flag = FALSE ;
320
                }
321
                /*RM33b*/
322
                else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
323
                        int     tx ;
324
                        /*
325
                         * set bn_flag only if in state T4 or T5:
326
                         * only if we're the beaconer should we start the
327
                         * trace !
328
                         */
329
                        if ((tx =  sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
330
                        DB_RMTN(2,"RMT : DETECT && TRT_EXPIRED && T4/T5\n",0,0);
331
                                smc->r.bn_flag = TRUE ;
332
                                /*
333
                                 * If one of the upstream stations beaconed
334
                                 * and the link to the upstream neighbor is
335
                                 * lost we need to restart the stuck timer to
336
                                 * check the "stuck beacon" condition.
337
                                 */
338
                                start_rmt_timer1(smc,smc->s.rmt_t_stuck,
339
                                        RM_TIMEOUT_T_STUCK) ;
340
                        }
341
                        /*
342
                         * We do NOT need to clear smc->r.bn_flag in case of
343
                         * not being in state T4 or T5, because the flag
344
                         * must be cleared in order to get in this condition.
345
                         */
346
 
347
                        DB_RMTN(2,
348
                        "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)\n",
349
                        tx,smc->r.bn_flag) ;
350
                }
351
                /*RM34a*/
352
                else if (cmd == RM_MY_CLAIM && smc->r.timer0_exp) {
353
                        rmt_new_dup_actions(smc) ;
354
                        GO_STATE(RM4_NON_OP_DUP) ;
355
                        break ;
356
                }
357
                /*RM34b*/
358
                else if (cmd == RM_MY_BEACON && smc->r.timer0_exp) {
359
                        rmt_new_dup_actions(smc) ;
360
                        GO_STATE(RM4_NON_OP_DUP) ;
361
                        break ;
362
                }
363
                /*RM34c*/
364
                else if (cmd == RM_VALID_CLAIM) {
365
                        rmt_new_dup_actions(smc) ;
366
                        GO_STATE(RM4_NON_OP_DUP) ;
367
                        break ;
368
                }
369
                /*RM36*/
370
                else if (cmd == RM_TIMEOUT_T_STUCK &&
371
                        smc->r.rm_join && smc->r.bn_flag) {
372
                        GO_STATE(RM6_DIRECTED) ;
373
                        break ;
374
                }
375
                break ;
376
        case ACTIONS(RM4_NON_OP_DUP) :
377
                start_rmt_timer0(smc,smc->s.rmt_t_announce,RM_TIMEOUT_ANNOUNCE);
378
                start_rmt_timer1(smc,smc->s.rmt_t_stuck,RM_TIMEOUT_T_STUCK) ;
379
                start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
380
                sm_mac_check_beacon_claim(smc) ;
381
                DB_RMTN(1,"RMT : RM4_NON_OP_DUP\n",0,0) ;
382
                ACTIONS_DONE() ;
383
                break ;
384
        case RM4_NON_OP_DUP :
385
                if (cmd == RM_TIMEOUT_POLL) {
386
                        start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
387
                        sm_mac_check_beacon_claim(smc) ;
388
                        break ;
389
                }
390
                /*RM41*/
391
                if (!smc->r.da_flag) {
392
                        GO_STATE(RM1_NON_OP) ;
393
                        break ;
394
                }
395
                /*RM44a*/
396
                else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
397
                        smc->r.bn_flag) {
398
                        smc->r.bn_flag = FALSE ;
399
                }
400
                /*RM44b*/
401
                else if (cmd == RM_TRT_EXP && !smc->r.bn_flag) {
402
                        int     tx ;
403
                        /*
404
                         * set bn_flag only if in state T4 or T5:
405
                         * only if we're the beaconer should we start the
406
                         * trace !
407
                         */
408
                        if ((tx =  sm_mac_get_tx_state(smc)) == 4 || tx == 5) {
409
                        DB_RMTN(2,"RMT : NOPDUP && TRT_EXPIRED && T4/T5\n",0,0);
410
                                smc->r.bn_flag = TRUE ;
411
                                /*
412
                                 * If one of the upstream stations beaconed
413
                                 * and the link to the upstream neighbor is
414
                                 * lost we need to restart the stuck timer to
415
                                 * check the "stuck beacon" condition.
416
                                 */
417
                                start_rmt_timer1(smc,smc->s.rmt_t_stuck,
418
                                        RM_TIMEOUT_T_STUCK) ;
419
                        }
420
                        /*
421
                         * We do NOT need to clear smc->r.bn_flag in case of
422
                         * not being in state T4 or T5, because the flag
423
                         * must be cleared in order to get in this condition.
424
                         */
425
 
426
                        DB_RMTN(2,
427
                        "RMT : sm_mac_get_tx_state() = %d (bn_flag = %d)\n",
428
                        tx,smc->r.bn_flag) ;
429
                }
430
                /*RM44c*/
431
                else if (cmd == RM_TIMEOUT_ANNOUNCE && !smc->r.bn_flag) {
432
                        rmt_dup_actions(smc) ;
433
                }
434
                /*RM45*/
435
                else if (cmd == RM_RING_OP) {
436
                        smc->r.no_flag = FALSE ;
437
                        GO_STATE(RM5_RING_OP_DUP) ;
438
                        break ;
439
                }
440
                /*RM46*/
441
                else if (cmd == RM_TIMEOUT_T_STUCK &&
442
                        smc->r.rm_join && smc->r.bn_flag) {
443
                        GO_STATE(RM6_DIRECTED) ;
444
                        break ;
445
                }
446
                break ;
447
        case ACTIONS(RM5_RING_OP_DUP) :
448
                stop_rmt_timer0(smc) ;
449
                stop_rmt_timer1(smc) ;
450
                stop_rmt_timer2(smc) ;
451
                DB_RMTN(1,"RMT : RM5_RING_OP_DUP\n",0,0) ;
452
                ACTIONS_DONE() ;
453
                break;
454
        case RM5_RING_OP_DUP :
455
                /*RM52*/
456
                if (smc->r.dup_addr_test == DA_PASSED) {
457
                        smc->r.da_flag = FALSE ;
458
                        GO_STATE(RM2_RING_OP) ;
459
                        break ;
460
                }
461
                /*RM54*/
462
                else if (cmd == RM_RING_NON_OP) {
463
                        smc->r.jm_flag = FALSE ;
464
                        smc->r.bn_flag = FALSE ;
465
                        GO_STATE(RM4_NON_OP_DUP) ;
466
                        break ;
467
                }
468
                break ;
469
        case ACTIONS(RM6_DIRECTED) :
470
                start_rmt_timer0(smc,smc->s.rmt_t_direct,RM_TIMEOUT_T_DIRECT) ;
471
                stop_rmt_timer1(smc) ;
472
                start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL) ;
473
                sm_ma_control(smc,MA_DIRECTED) ;
474
                RS_SET(smc,RS_BEACON) ;
475
                DB_RMTN(1,"RMT : RM6_DIRECTED\n",0,0) ;
476
                ACTIONS_DONE() ;
477
                break ;
478
        case RM6_DIRECTED :
479
                /*RM63*/
480
                if (cmd == RM_TIMEOUT_POLL) {
481
                        start_rmt_timer2(smc,smc->s.rmt_t_poll,RM_TIMEOUT_POLL);
482
                        sm_mac_check_beacon_claim(smc) ;
483
#ifndef SUPERNET_3
484
                        /* Because of problems with the Supernet II chip set
485
                         * sending of Directed Beacon will stop after 165ms
486
                         * therefore restart_trt_for_dbcn(smc) will be called
487
                         * to prevent this.
488
                         */
489
                        restart_trt_for_dbcn(smc) ;
490
#endif /*SUPERNET_3*/
491
                        break ;
492
                }
493
                if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
494
                        !smc->r.da_flag) {
495
                        smc->r.bn_flag = FALSE ;
496
                        GO_STATE(RM3_DETECT) ;
497
                        break ;
498
                }
499
                /*RM64*/
500
                else if ((cmd == RM_MY_BEACON || cmd == RM_OTHER_BEACON) &&
501
                        smc->r.da_flag) {
502
                        smc->r.bn_flag = FALSE ;
503
                        GO_STATE(RM4_NON_OP_DUP) ;
504
                        break ;
505
                }
506
                /*RM67*/
507
                else if (cmd == RM_TIMEOUT_T_DIRECT) {
508
                        GO_STATE(RM7_TRACE) ;
509
                        break ;
510
                }
511
                break ;
512
        case ACTIONS(RM7_TRACE) :
513
                stop_rmt_timer0(smc) ;
514
                stop_rmt_timer1(smc) ;
515
                stop_rmt_timer2(smc) ;
516
                smc->e.trace_prop |= ENTITY_BIT(ENTITY_MAC) ;
517
                queue_event(smc,EVENT_ECM,EC_TRACE_PROP) ;
518
                DB_RMTN(1,"RMT : RM7_TRACE\n",0,0) ;
519
                ACTIONS_DONE() ;
520
                break ;
521
        case RM7_TRACE :
522
                break ;
523
        default:
524
                SMT_PANIC(smc,SMT_E0122, SMT_E0122_MSG) ;
525
                break;
526
        }
527
}
528
 
529
/*
530
 * (jd) RMT duplicate address actions
531
 * leave the ring or reinsert just as configured
532
 */
533
static void rmt_dup_actions(struct s_smc *smc)
534
{
535
        if (smc->r.jm_flag) {
536
        }
537
        else {
538
                if (smc->s.rmt_dup_mac_behavior) {
539
                        SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
540
                        rmt_reinsert_actions(smc) ;
541
                }
542
                else {
543
                        SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
544
                        rmt_leave_actions(smc) ;
545
                }
546
        }
547
}
548
 
549
/*
550
 * Reconnect to the Ring
551
 */
552
static void rmt_reinsert_actions(struct s_smc *smc)
553
{
554
        queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
555
        queue_event(smc,EVENT_ECM,EC_CONNECT) ;
556
}
557
 
558
/*
559
 * duplicate address detected
560
 */
561
static void rmt_new_dup_actions(struct s_smc *smc)
562
{
563
        smc->r.da_flag = TRUE ;
564
        smc->r.bn_flag = FALSE ;
565
        smc->r.jm_flag = FALSE ;
566
        /*
567
         * we have three options : change address, jam or leave
568
         * we leave the ring as default
569
         * Optionally it's possible to reinsert after leaving the Ring
570
         * but this will not conform with SMT Spec.
571
         */
572
        if (smc->s.rmt_dup_mac_behavior) {
573
                SMT_ERR_LOG(smc,SMT_E0138, SMT_E0138_MSG) ;
574
                rmt_reinsert_actions(smc) ;
575
        }
576
        else {
577
                SMT_ERR_LOG(smc,SMT_E0135, SMT_E0135_MSG) ;
578
                rmt_leave_actions(smc) ;
579
        }
580
}
581
 
582
 
583
/*
584
 * leave the ring
585
 */
586
static void rmt_leave_actions(struct s_smc *smc)
587
{
588
        queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
589
        /*
590
         * Note: Do NOT try again later. (with please reconnect)
591
         * The station must be left from the ring!
592
         */
593
}
594
 
595
/*
596
 * SMT timer interface
597
 *      start RMT timer 0
598
 */
599
static void start_rmt_timer0(struct s_smc *smc, u_long value, int event)
600
{
601
        smc->r.timer0_exp = FALSE ;             /* clear timer event flag */
602
        smt_timer_start(smc,&smc->r.rmt_timer0,value,EV_TOKEN(EVENT_RMT,event));
603
}
604
 
605
/*
606
 * SMT timer interface
607
 *      start RMT timer 1
608
 */
609
static void start_rmt_timer1(struct s_smc *smc, u_long value, int event)
610
{
611
        smc->r.timer1_exp = FALSE ;     /* clear timer event flag */
612
        smt_timer_start(smc,&smc->r.rmt_timer1,value,EV_TOKEN(EVENT_RMT,event));
613
}
614
 
615
/*
616
 * SMT timer interface
617
 *      start RMT timer 2
618
 */
619
static void start_rmt_timer2(struct s_smc *smc, u_long value, int event)
620
{
621
        smc->r.timer2_exp = FALSE ;             /* clear timer event flag */
622
        smt_timer_start(smc,&smc->r.rmt_timer2,value,EV_TOKEN(EVENT_RMT,event));
623
}
624
 
625
/*
626
 * SMT timer interface
627
 *      stop RMT timer 0
628
 */
629
static void stop_rmt_timer0(struct s_smc *smc)
630
{
631
        if (smc->r.rmt_timer0.tm_active)
632
                smt_timer_stop(smc,&smc->r.rmt_timer0) ;
633
}
634
 
635
/*
636
 * SMT timer interface
637
 *      stop RMT timer 1
638
 */
639
static void stop_rmt_timer1(struct s_smc *smc)
640
{
641
        if (smc->r.rmt_timer1.tm_active)
642
                smt_timer_stop(smc,&smc->r.rmt_timer1) ;
643
}
644
 
645
/*
646
 * SMT timer interface
647
 *      stop RMT timer 2
648
 */
649
static void stop_rmt_timer2(struct s_smc *smc)
650
{
651
        if (smc->r.rmt_timer2.tm_active)
652
                smt_timer_stop(smc,&smc->r.rmt_timer2) ;
653
}
654
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.