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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283#include <config.h>
284
285#ifndef lint
286static const char SysKonnectFileId[] =
287 "@(#) $Id: skrlmt.c,v 1.68 2003/01/31 15:26:56 rschmidt Exp $ (C) SysKonnect.";
288#endif
289
290#define __SKRLMT_C
291
292#ifdef __cplusplus
293#error C++ is not yet supported.
294extern "C" {
295#endif
296
297#include "h/skdrv1st.h"
298#include "h/skdrv2nd.h"
299
300
301
302#ifndef SK_HWAC_LINK_LED
303#define SK_HWAC_LINK_LED(a,b,c,d)
304#endif
305
306#ifndef DEBUG
307#define RLMT_STATIC static
308#else
309#define RLMT_STATIC
310
311#ifndef SK_LITTLE_ENDIAN
312
313#define OFFS_LO32 1
314
315
316#define OFFS_HI32 0
317#else
318
319#define OFFS_LO32 0
320
321
322#define OFFS_HI32 1
323#endif
324
325#endif
326
327
328
329#define SK_RLMT_MIN_TO_VAL 125000
330#define SK_RLMT_DEF_TO_VAL 1000000
331#define SK_RLMT_PORTDOWN_TIM_VAL 900000
332#define SK_RLMT_PORTSTART_TIM_VAL 100000
333#define SK_RLMT_PORTUP_TIM_VAL 2500000
334#define SK_RLMT_SEG_TO_VAL 900000000
335
336
337#ifndef SK_TICK_INCR
338#define SK_TICK_INCR SK_CONSTU64(1)
339#endif
340
341
342
343
344
345#define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \
346 (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR))
347
348
349
350#define SK_RLMT_DEF_PREF_PORT 0
351#define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK
352
353
354
355#define SK_RLMT_RCS_SEG 1
356#define SK_RLMT_RCS_START_SEG 2
357#define SK_RLMT_RCS_SEND_SEG 4
358#define SK_RLMT_RCS_REPORT_SEG 8
359
360
361
362#define SK_RLMT_PCS_TX 1
363#define SK_RLMT_PCS_RX 2
364
365
366
367
368#define SK_RLMT_PORTSTART_TIM 1100
369#define SK_RLMT_PORTUP_TIM 1101
370#define SK_RLMT_PORTDOWN_RX_TIM 1102
371#define SK_RLMT_PORTDOWN 1103
372#define SK_RLMT_PORTDOWN_TX_TIM 1104
373
374
375
376
377#define SK_RLMT_TIM 2100
378#define SK_RLMT_SEG_TIM 2101
379
380#define TO_SHORTEN(tim) ((tim) / 2)
381
382
383#define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0)
384#define SKERR_RLMT_E001_MSG "No Packet."
385#define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1)
386#define SKERR_RLMT_E002_MSG "Short Packet."
387#define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1)
388#define SKERR_RLMT_E003_MSG "Unknown RLMT event."
389#define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1)
390#define SKERR_RLMT_E004_MSG "PortsUp incorrect."
391#define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1)
392#define SKERR_RLMT_E005_MSG \
393 "Net seems to be segmented (different root bridges are reported on the ports)."
394#define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1)
395#define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected."
396#define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1)
397#define SKERR_RLMT_E007_MSG "LinksUp incorrect."
398#define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1)
399#define SKERR_RLMT_E008_MSG "Port not started but link came up."
400#define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1)
401#define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port."
402#define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1)
403#define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port."
404
405
406#define LLC_COMMAND_RESPONSE_BIT 1
407#define LLC_TEST_COMMAND 0xE3
408#define LLC_UI 0x03
409
410
411#define SK_RLMT_DSAP 0
412#define SK_RLMT_SSAP 0
413#define SK_RLMT_CTRL (LLC_TEST_COMMAND)
414#define SK_RLMT_INDICATOR0 0x53
415#define SK_RLMT_INDICATOR1 0x4B
416#define SK_RLMT_INDICATOR2 0x2D
417#define SK_RLMT_INDICATOR3 0x52
418#define SK_RLMT_INDICATOR4 0x4C
419#define SK_RLMT_INDICATOR5 0x4D
420#define SK_RLMT_INDICATOR6 0x54
421#define SK_RLMT_PACKET_VERSION 0
422
423
424#define SK_RLMT_SPT_FLAG_CHANGE 0x01
425#define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80
426
427
428#define SK_RLMT_SPT_DSAP 0x42
429#define SK_RLMT_SPT_SSAP 0x42
430#define SK_RLMT_SPT_CTRL (LLC_UI)
431#define SK_RLMT_SPT_PROTOCOL_ID0 0x00
432#define SK_RLMT_SPT_PROTOCOL_ID1 0x00
433#define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00
434#define SK_RLMT_SPT_BPDU_TYPE 0x00
435#define SK_RLMT_SPT_FLAGS 0x00
436#define SK_RLMT_SPT_ROOT_ID0 0xFF
437#define SK_RLMT_SPT_ROOT_ID1 0xFF
438
439
440#define SK_RLMT_SPT_ROOT_PATH_COST0 0x00
441#define SK_RLMT_SPT_ROOT_PATH_COST1 0x00
442#define SK_RLMT_SPT_ROOT_PATH_COST2 0x00
443#define SK_RLMT_SPT_ROOT_PATH_COST3 0x00
444#define SK_RLMT_SPT_BRIDGE_ID0 0xFF
445#define SK_RLMT_SPT_BRIDGE_ID1 0xFF
446
447
448#define SK_RLMT_SPT_PORT_ID0 0xFF
449#define SK_RLMT_SPT_PORT_ID1 0xFF
450#define SK_RLMT_SPT_MSG_AGE0 0x00
451#define SK_RLMT_SPT_MSG_AGE1 0x00
452#define SK_RLMT_SPT_MAX_AGE0 0x00
453#define SK_RLMT_SPT_MAX_AGE1 0xFF
454#define SK_RLMT_SPT_HELLO_TIME0 0x00
455#define SK_RLMT_SPT_HELLO_TIME1 0xFF
456#define SK_RLMT_SPT_FWD_DELAY0 0x00
457#define SK_RLMT_SPT_FWD_DELAY1 0x40
458
459
460#define SK_RLMT_MIN_PACKET_SIZE 34
461#define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE)
462#define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \
463 SK_RLMT_MIN_PACKET_SIZE)
464
465
466#define SK_PACKET_ANNOUNCE 1
467#define SK_PACKET_ALIVE 2
468#define SK_PACKET_ADDR_CHANGED 3
469#define SK_PACKET_CHECK_TX 4
470
471#ifdef SK_LITTLE_ENDIAN
472#define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \
473 SK_U8 *_Addr = (SK_U8*)(Addr); \
474 SK_U16 _Val = (SK_U16)(Val); \
475 *_Addr++ = (SK_U8)(_Val >> 8); \
476 *_Addr = (SK_U8)(_Val & 0xFF); \
477}
478#endif
479
480#ifdef SK_BIG_ENDIAN
481#define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val))
482#endif
483
484#define AUTONEG_FAILED SK_FALSE
485#define AUTONEG_SUCCESS SK_TRUE
486
487
488
489
490
491typedef struct s_RlmtPacket {
492 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
493 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
494 SK_U8 TypeLen[2];
495 SK_U8 DSap;
496 SK_U8 SSap;
497 SK_U8 Ctrl;
498 SK_U8 Indicator[7];
499 SK_U8 RlmtPacketType[2];
500 SK_U8 Align1[2];
501 SK_U8 Random[4];
502 SK_U8 RlmtPacketVersion[2];
503 SK_U8 Data[SK_PACKET_DATA_LEN];
504} SK_RLMT_PACKET;
505
506typedef struct s_SpTreeRlmtPacket {
507 SK_U8 DstAddr[SK_MAC_ADDR_LEN];
508 SK_U8 SrcAddr[SK_MAC_ADDR_LEN];
509 SK_U8 TypeLen[2];
510 SK_U8 DSap;
511 SK_U8 SSap;
512 SK_U8 Ctrl;
513 SK_U8 ProtocolId[2];
514 SK_U8 ProtocolVersionId;
515 SK_U8 BpduType;
516 SK_U8 Flags;
517 SK_U8 RootId[8];
518 SK_U8 RootPathCost[4];
519 SK_U8 BridgeId[8];
520 SK_U8 PortId[2];
521 SK_U8 MessageAge[2];
522 SK_U8 MaxAge[2];
523 SK_U8 HelloTime[2];
524 SK_U8 ForwardDelay[2];
525} SK_SPTREE_PACKET;
526
527
528
529SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}};
530SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}};
531SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
532
533
534
535
536
537
538
539RLMT_STATIC void SkRlmtCheckSwitch(
540 SK_AC *pAC,
541 SK_IOC IoC,
542 SK_U32 NetIdx);
543RLMT_STATIC void SkRlmtCheckSeg(
544 SK_AC *pAC,
545 SK_IOC IoC,
546 SK_U32 NetIdx);
547RLMT_STATIC void SkRlmtEvtSetNets(
548 SK_AC *pAC,
549 SK_IOC IoC,
550 SK_EVPARA Para);
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585void SkRlmtInit(
586SK_AC *pAC,
587SK_IOC IoC,
588int Level)
589{
590 SK_U32 i, j;
591 SK_U64 Random;
592 SK_EVPARA Para;
593 SK_MAC_ADDR VirtualMacAddress;
594 SK_MAC_ADDR PhysicalAMacAddress;
595 SK_BOOL VirtualMacAddressSet;
596 SK_BOOL PhysicalAMacAddressSet;
597
598 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
599 ("RLMT Init level %d.\n", Level))
600
601 switch (Level) {
602 case SK_INIT_DATA:
603 SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT));
604
605 for (i = 0; i < SK_MAX_MACS; i++) {
606 pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT;
607 pAC->Rlmt.Port[i].LinkDown = SK_TRUE;
608 pAC->Rlmt.Port[i].PortDown = SK_TRUE;
609 pAC->Rlmt.Port[i].PortStarted = SK_FALSE;
610 pAC->Rlmt.Port[i].PortNoRx = SK_FALSE;
611 pAC->Rlmt.Port[i].RootIdSet = SK_FALSE;
612 pAC->Rlmt.Port[i].PortNumber = i;
613 pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0];
614 pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i];
615 }
616
617 pAC->Rlmt.NumNets = 1;
618 for (i = 0; i < SK_MAX_NETS; i++) {
619 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
620 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
621 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
622 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;
623
624 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
625 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
626 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
627 pAC->Rlmt.Net[i].NetNumber = i;
628 }
629
630 pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0];
631 pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1];
632#if SK_MAX_NETS > 1
633 pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1];
634#endif
635 break;
636
637 case SK_INIT_IO:
638 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT,
639 ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound))
640
641 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
642
643
644 if (pAC->GIni.GIMacsFound == 1) {
645 Para.Para32[0] = SK_RLMT_MODE_CLS;
646 Para.Para32[1] = 0;
647 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para);
648 }
649 break;
650
651 case SK_INIT_RUN:
652
653 if (pAC->Rlmt.NumNets > 1) {
654 Para.Para32[0] = 1;
655 Para.Para32[1] = -1;
656 SkRlmtEvtSetNets(pAC, IoC, Para);
657 }
658
659 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
660 Random = SkOsGetTime(pAC);
661 *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random;
662
663 for (j = 0; j < 4; j++) {
664 pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort->
665 CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j];
666 }
667
668 (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
669
670
671 (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT);
672
673 if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) {
674
675 (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT);
676 }
677
678 (void)SkAddrMcUpdate(pAC, IoC, i);
679 }
680
681 VirtualMacAddressSet = SK_FALSE;
682
683 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
684
685 SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]);
686 VirtualMacAddressSet |= VirtualMacAddress.a[j];
687 }
688
689 PhysicalAMacAddressSet = SK_FALSE;
690
691 for (j = 0; j < SK_MAC_ADDR_LEN; j++) {
692
693 SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]);
694 PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j];
695 }
696
697
698 if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) {
699
700 pAC->Rlmt.RlmtOff = SK_TRUE;
701 }
702
703
704
705 else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) {
706
707 pAC->Rlmt.RlmtOff = SK_TRUE;
708 }
709 else {
710 pAC->Rlmt.RlmtOff = SK_FALSE;
711 }
712 break;
713
714 default:
715 break;
716 }
717 return;
718}
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741RLMT_STATIC void SkRlmtBuildCheckChain(
742SK_AC *pAC,
743SK_U32 NetIdx)
744{
745 SK_U32 i;
746 SK_U32 NumMacsUp;
747 SK_RLMT_PORT * FirstMacUp;
748 SK_RLMT_PORT * PrevMacUp;
749
750 FirstMacUp = NULL;
751 PrevMacUp = NULL;
752
753 if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
754 for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) {
755 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
756 }
757 return;
758 }
759
760 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
761 ("SkRlmtBuildCheckChain.\n"))
762
763 NumMacsUp = 0;
764
765 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
766 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0;
767 pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0;
768 pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &=
769 ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX);
770
771
772
773
774
775
776
777 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
778 if (NumMacsUp == 0) {
779 FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
780 }
781 else {
782 PrevMacUp->PortCheck[
783 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr =
784 pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress;
785 PrevMacUp->PortCheck[
786 PrevMacUp->PortsChecked].SuspectTx = SK_FALSE;
787 PrevMacUp->PortsChecked++;
788 }
789 PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i];
790 NumMacsUp++;
791 }
792 }
793
794 if (NumMacsUp > 1) {
795 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr =
796 FirstMacUp->AddrPort->CurrentMacAddress;
797 PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx =
798 SK_FALSE;
799 PrevMacUp->PortsChecked++;
800 }
801
802#ifdef DEBUG
803 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
804 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
805 ("Port %d checks %d other ports: %2X.\n", i,
806 pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked,
807 pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5]))
808 }
809#endif
810
811 return;
812}
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828RLMT_STATIC SK_MBUF *SkRlmtBuildPacket(
829SK_AC *pAC,
830SK_IOC IoC,
831SK_U32 PortNumber,
832SK_U16 PacketType,
833SK_MAC_ADDR *SrcAddr,
834SK_MAC_ADDR *DestAddr)
835{
836 int i;
837 SK_U16 Length;
838 SK_MBUF *pMb;
839 SK_RLMT_PACKET *pPacket;
840
841#ifdef DEBUG
842 SK_U8 CheckSrc = 0;
843 SK_U8 CheckDest = 0;
844
845 for (i = 0; i < SK_MAC_ADDR_LEN; ++i) {
846 CheckSrc |= SrcAddr->a[i];
847 CheckDest |= DestAddr->a[i];
848 }
849
850 if ((CheckSrc == 0) || (CheckDest == 0)) {
851 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR,
852 ("SkRlmtBuildPacket: Invalid %s%saddr.\n",
853 (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : "")))
854 }
855#endif
856
857 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) {
858 pPacket = (SK_RLMT_PACKET*)pMb->pData;
859 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
860 pPacket->DstAddr[i] = DestAddr->a[i];
861 pPacket->SrcAddr[i] = SrcAddr->a[i];
862 }
863 pPacket->DSap = SK_RLMT_DSAP;
864 pPacket->SSap = SK_RLMT_SSAP;
865 pPacket->Ctrl = SK_RLMT_CTRL;
866 pPacket->Indicator[0] = SK_RLMT_INDICATOR0;
867 pPacket->Indicator[1] = SK_RLMT_INDICATOR1;
868 pPacket->Indicator[2] = SK_RLMT_INDICATOR2;
869 pPacket->Indicator[3] = SK_RLMT_INDICATOR3;
870 pPacket->Indicator[4] = SK_RLMT_INDICATOR4;
871 pPacket->Indicator[5] = SK_RLMT_INDICATOR5;
872 pPacket->Indicator[6] = SK_RLMT_INDICATOR6;
873
874 SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]);
875
876 for (i = 0; i < 4; i++) {
877 pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i];
878 }
879
880 SK_U16_TO_NETWORK_ORDER(
881 SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]);
882
883 for (i = 0; i < SK_PACKET_DATA_LEN; i++) {
884 pPacket->Data[i] = 0x00;
885 }
886
887 Length = SK_RLMT_MAX_PACKET_SIZE;
888 pMb->Length = Length;
889 pMb->PortIdx = PortNumber;
890 Length -= 14;
891 SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]);
892
893 if (PacketType == SK_PACKET_ALIVE) {
894 pAC->Rlmt.Port[PortNumber].TxHelloCts++;
895 }
896 }
897
898 return (pMb);
899}
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket(
916SK_AC *pAC,
917SK_IOC IoC,
918SK_U32 PortNumber)
919{
920 unsigned i;
921 SK_U16 Length;
922 SK_MBUF *pMb;
923 SK_SPTREE_PACKET *pSPacket;
924
925 if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) !=
926 NULL) {
927 pSPacket = (SK_SPTREE_PACKET*)pMb->pData;
928 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
929 pSPacket->DstAddr[i] = BridgeMcAddr.a[i];
930 pSPacket->SrcAddr[i] =
931 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
932 }
933 pSPacket->DSap = SK_RLMT_SPT_DSAP;
934 pSPacket->SSap = SK_RLMT_SPT_SSAP;
935 pSPacket->Ctrl = SK_RLMT_SPT_CTRL;
936
937 pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0;
938 pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1;
939 pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID;
940 pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE;
941 pSPacket->Flags = SK_RLMT_SPT_FLAGS;
942 pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0;
943 pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1;
944 pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0;
945 pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1;
946 pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2;
947 pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3;
948 pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0;
949 pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1;
950
951
952
953
954
955 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
956 pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] =
957 pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber].
958 CurrentMacAddress.a[i];
959 }
960 pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0;
961 pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1;
962 pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0;
963 pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1;
964 pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0;
965 pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1;
966 pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0;
967 pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1;
968 pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0;
969 pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1;
970
971 Length = SK_RLMT_MAX_PACKET_SIZE;
972 pMb->Length = Length;
973 pMb->PortIdx = PortNumber;
974 Length -= 14;
975 SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]);
976
977 pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++;
978 }
979
980 return (pMb);
981}
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998RLMT_STATIC void SkRlmtSend(
999SK_AC *pAC,
1000SK_IOC IoC,
1001SK_U32 PortNumber)
1002{
1003 unsigned j;
1004 SK_EVPARA Para;
1005 SK_RLMT_PORT *pRPort;
1006
1007 pRPort = &pAC->Rlmt.Port[PortNumber];
1008 if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
1009 if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) {
1010
1011 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
1012 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1013 &SkRlmtMcAddr)) != NULL) {
1014 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1015 }
1016 }
1017 else {
1018
1019
1020
1021
1022 for (j = 0; j < pRPort->PortsChecked; j++) {
1023 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
1024 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1025 &pRPort->PortCheck[j].CheckAddr)) != NULL) {
1026 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1027 }
1028 }
1029 }
1030 }
1031
1032 if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
1033 (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) {
1034
1035
1036
1037
1038 if ((Para.pParaPtr =
1039 SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) {
1040 pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG;
1041 pRPort->RootIdSet = SK_FALSE;
1042
1043 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1044 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX,
1045 ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber))
1046 }
1047 }
1048 return;
1049}
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066RLMT_STATIC void SkRlmtPortReceives(
1067SK_AC *pAC,
1068SK_IOC IoC,
1069SK_U32 PortNumber)
1070{
1071 SK_RLMT_PORT *pRPort;
1072 SK_EVPARA Para;
1073
1074 pRPort = &pAC->Rlmt.Port[PortNumber];
1075 pRPort->PortNoRx = SK_FALSE;
1076
1077 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
1078 !(pRPort->CheckingState & SK_RLMT_PCS_TX)) {
1079
1080
1081
1082
1083 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1084 ("SkRlmtPacketReceive: Received on PortDown.\n"))
1085
1086 pRPort->PortState = SK_RLMT_PS_GOING_UP;
1087 pRPort->GuTimeStamp = SkOsGetTime(pAC);
1088 Para.Para32[0] = PortNumber;
1089 Para.Para32[1] = (SK_U32)-1;
1090 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
1091 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para);
1092 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
1093
1094 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
1095 }
1096 else if (pRPort->CheckingState & SK_RLMT_PCS_RX) {
1097 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1098 ("SkRlmtPacketReceive: Stop bringing port down.\n"))
1099 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
1100 pRPort->CheckingState &= ~SK_RLMT_PCS_RX;
1101
1102 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
1103 }
1104
1105 return;
1106}
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122RLMT_STATIC void SkRlmtPacketReceive(
1123SK_AC *pAC,
1124SK_IOC IoC,
1125SK_MBUF *pMb)
1126{
1127#ifdef xDEBUG
1128 extern void DumpData(char *p, int size);
1129#endif
1130 int i;
1131 unsigned j;
1132 SK_U16 PacketType;
1133 SK_U32 PortNumber;
1134 SK_ADDR_PORT *pAPort;
1135 SK_RLMT_PORT *pRPort;
1136 SK_RLMT_PACKET *pRPacket;
1137 SK_SPTREE_PACKET *pSPacket;
1138 SK_EVPARA Para;
1139
1140 PortNumber = pMb->PortIdx;
1141 pAPort = &pAC->Addr.Port[PortNumber];
1142 pRPort = &pAC->Rlmt.Port[PortNumber];
1143
1144 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1145 ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber))
1146
1147 pRPacket = (SK_RLMT_PACKET*)pMb->pData;
1148 pSPacket = (SK_SPTREE_PACKET*)pRPacket;
1149
1150#ifdef xDEBUG
1151 DumpData((char *)pRPacket, 32);
1152#endif
1153
1154 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) {
1155 SkRlmtPortReceives(pAC, IoC, PortNumber);
1156 }
1157
1158
1159
1160 if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) &&
1161 !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) &&
1162 !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) {
1163
1164
1165 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1166 ("SkRlmtPacketReceive: Not for me.\n"))
1167
1168 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1169 return;
1170 }
1171 else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) {
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 for (i = 3; i >= 0; i--) {
1183 if (pRPort->Random[i] != pRPacket->Random[i]) {
1184 break;
1185 }
1186 }
1187
1188
1189
1190
1191
1192
1193 if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP &&
1194 pRPacket->Ctrl == SK_RLMT_CTRL &&
1195 pRPacket->SSap == SK_RLMT_SSAP &&
1196 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
1197 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
1198 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
1199 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
1200 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
1201 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
1202 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
1203 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1204 ("SkRlmtPacketReceive: Duplicate MAC Address.\n"))
1205
1206
1207 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG);
1208 }
1209 else {
1210
1211 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1212 ("SkRlmtPacketReceive: Sent by me.\n"))
1213 }
1214
1215 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1216 return;
1217 }
1218
1219
1220 if (pRPort->PortsSuspect > 0) {
1221 for (j = 0; j < pRPort->PortsChecked; j++) {
1222 if (pRPort->PortCheck[j].SuspectTx &&
1223 SK_ADDR_EQUAL(
1224 pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) {
1225 pRPort->PortCheck[j].SuspectTx = SK_FALSE;
1226 pRPort->PortsSuspect--;
1227 break;
1228 }
1229 }
1230 }
1231
1232
1233 if (pRPacket->DSap == SK_RLMT_DSAP &&
1234 pRPacket->Ctrl == SK_RLMT_CTRL &&
1235 (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP &&
1236 pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 &&
1237 pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 &&
1238 pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 &&
1239 pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 &&
1240 pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 &&
1241 pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 &&
1242 pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) {
1243
1244
1245 PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) |
1246 pRPacket->RlmtPacketType[1]);
1247
1248 switch (PacketType) {
1249 case SK_PACKET_ANNOUNCE:
1250#if 0
1251
1252 SkRlmtBuildCheckChain(pAC);
1253#endif
1254
1255 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1256 ("SkRlmtPacketReceive: Announce.\n"))
1257
1258 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1259 break;
1260
1261 case SK_PACKET_ALIVE:
1262 if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) {
1263 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1264 ("SkRlmtPacketReceive: Alive Reply.\n"))
1265
1266 if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) ||
1267 SK_ADDR_EQUAL(
1268 pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) {
1269
1270 if (pRPort->CheckingState & SK_RLMT_PCS_TX) {
1271 pRPort->CheckingState &= ~SK_RLMT_PCS_TX;
1272 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1273 }
1274
1275 if ((pRPort->PortState == SK_RLMT_PS_DOWN) &&
1276 !(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1277 pRPort->PortState = SK_RLMT_PS_GOING_UP;
1278 pRPort->GuTimeStamp = SkOsGetTime(pAC);
1279
1280 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
1281
1282 Para.Para32[0] = PortNumber;
1283 Para.Para32[1] = (SK_U32)-1;
1284 SkTimerStart(pAC, IoC, &pRPort->UpTimer,
1285 SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT,
1286 SK_RLMT_PORTUP_TIM, Para);
1287 }
1288 }
1289
1290
1291 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1292 }
1293 else {
1294 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1295 ("SkRlmtPacketReceive: Alive Request.\n"))
1296
1297 pRPort->RxHelloCts++;
1298
1299
1300 for (i = 0; i < SK_MAC_ADDR_LEN; i++) {
1301 pRPacket->DstAddr[i] = pRPacket->SrcAddr[i];
1302 pRPacket->SrcAddr[i] =
1303 pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i];
1304 }
1305 pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT;
1306
1307 Para.pParaPtr = pMb;
1308 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1309 }
1310 break;
1311
1312 case SK_PACKET_CHECK_TX:
1313 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1314 ("SkRlmtPacketReceive: Check your tx line.\n"))
1315
1316
1317 pRPort->CheckingState |= SK_RLMT_PCS_TX;
1318
1319
1320 Para.Para32[0] = PortNumber;
1321 Para.Para32[1] = (SK_U32)-1;
1322 SkTimerStart(pAC, IoC, &pRPort->DownTxTimer,
1323 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1324 SK_RLMT_PORTDOWN_TX_TIM, Para);
1325
1326 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1327
1328 if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber,
1329 SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1330 &SkRlmtMcAddr)) != NULL) {
1331 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1332 }
1333 break;
1334
1335 case SK_PACKET_ADDR_CHANGED:
1336 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1337 ("SkRlmtPacketReceive: Address Change.\n"))
1338
1339
1340 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
1341 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1342 break;
1343
1344 default:
1345 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1346 ("SkRlmtPacketReceive: Unknown RLMT packet.\n"))
1347
1348
1349 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1350 }
1351 }
1352 else if (pSPacket->DSap == SK_RLMT_SPT_DSAP &&
1353 pSPacket->Ctrl == SK_RLMT_SPT_CTRL &&
1354 (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) {
1355 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1356 ("SkRlmtPacketReceive: BPDU Packet.\n"))
1357
1358
1359 pRPort->RxSpHelloCts++;
1360
1361 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt.
1362 Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) {
1363
1364
1365
1366
1367 if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) &&
1368 (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1369 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG)
1370 != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1371 SK_RLMT_RCS_SEG) == 0) {
1372 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1373 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1374 }
1375
1376
1377 for (i = 0; i < 8; i++) {
1378 pRPort->Root.Id[i] = pSPacket->RootId[i];
1379 }
1380 pRPort->RootIdSet = SK_TRUE;
1381
1382 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
1383 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
1384 PortNumber,
1385 pRPort->Root.Id[0], pRPort->Root.Id[1],
1386 pRPort->Root.Id[2], pRPort->Root.Id[3],
1387 pRPort->Root.Id[4], pRPort->Root.Id[5],
1388 pRPort->Root.Id[6], pRPort->Root.Id[7]))
1389 }
1390
1391 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1392 if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState &
1393 SK_RLMT_RCS_REPORT_SEG) != 0) {
1394 SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber);
1395 }
1396 }
1397 else {
1398 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX,
1399 ("SkRlmtPacketReceive: Unknown Packet Type.\n"))
1400
1401
1402 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
1403 }
1404 return;
1405}
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466RLMT_STATIC SK_U32 SkRlmtCheckPort(
1467SK_AC *pAC,
1468SK_IOC IoC,
1469SK_U32 PortNumber)
1470{
1471 unsigned i;
1472 SK_U32 NewTimeout;
1473 SK_RLMT_PORT *pRPort;
1474 SK_EVPARA Para;
1475
1476 pRPort = &pAC->Rlmt.Port[PortNumber];
1477
1478 if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) {
1479 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1480 ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n",
1481 PortNumber, pRPort->PacketsPerTimeSlot))
1482
1483
1484
1485
1486
1487
1488
1489 if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) &&
1490 (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) &&
1491 !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) {
1492 pAC->Rlmt.Port[PortNumber].Net->CheckingState |=
1493 SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG;
1494 }
1495
1496 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1497 ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n",
1498 pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX))
1499
1500 if (pRPort->PortState != SK_RLMT_PS_DOWN) {
1501 NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue);
1502 if (NewTimeout < SK_RLMT_MIN_TO_VAL) {
1503 NewTimeout = SK_RLMT_MIN_TO_VAL;
1504 }
1505
1506 if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) {
1507 Para.Para32[0] = PortNumber;
1508 pRPort->CheckingState |= SK_RLMT_PCS_RX;
1509
1510
1511
1512
1513
1514 Para.Para32[1] = (SK_U32)-1;
1515 SkTimerStart(pAC, IoC, &pRPort->DownRxTimer,
1516 SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT,
1517 SK_RLMT_PORTDOWN_RX_TIM, Para);
1518
1519 for (i = 0; i < pRPort->PortsChecked; i++) {
1520 if (pRPort->PortCheck[i].SuspectTx) {
1521 continue;
1522 }
1523 pRPort->PortCheck[i].SuspectTx = SK_TRUE;
1524 pRPort->PortsSuspect++;
1525 if ((Para.pParaPtr =
1526 SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX,
1527 &pAC->Addr.Port[PortNumber].CurrentMacAddress,
1528 &pRPort->PortCheck[i].CheckAddr)) != NULL) {
1529 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1530 }
1531 }
1532 }
1533 }
1534 else {
1535 NewTimeout = SK_RLMT_DEF_TO_VAL;
1536 }
1537 pRPort->PortNoRx = SK_TRUE;
1538 }
1539 else {
1540 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1541 ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n",
1542 PortNumber,
1543 pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot,
1544 pRPort->PacketsPerTimeSlot))
1545
1546 SkRlmtPortReceives(pAC, IoC, PortNumber);
1547 if (pAC->Rlmt.CheckSwitch) {
1548 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
1549 }
1550
1551 NewTimeout = SK_RLMT_DEF_TO_VAL;
1552 }
1553
1554 return (NewTimeout);
1555}
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572RLMT_STATIC SK_BOOL SkRlmtSelectBcRx(
1573SK_AC *pAC,
1574SK_IOC IoC,
1575SK_U32 Active,
1576SK_U32 PrefPort,
1577SK_U32 *pSelect)
1578{
1579 SK_U64 BcTimeStamp;
1580 SK_U32 i;
1581 SK_BOOL PortFound;
1582
1583 BcTimeStamp = 0;
1584 PortFound = SK_FALSE;
1585
1586
1587 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1588
1589 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1590 ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n",
1591 i,
1592 pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx,
1593 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32),
1594 *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32)))
1595
1596 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) {
1597 if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) {
1598 BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp;
1599 *pSelect = i;
1600 PortFound = SK_TRUE;
1601 }
1602 }
1603 }
1604
1605 if (PortFound) {
1606 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1607 ("Port %d received the last broadcast.\n", *pSelect))
1608
1609
1610 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1611 if (i == *pSelect) {
1612 continue;
1613 }
1614 if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx &&
1615 (pAC->Rlmt.Port[i].BcTimeStamp >
1616 BcTimeStamp - SK_RLMT_BC_DELTA ||
1617 pAC->Rlmt.Port[i].BcTimeStamp +
1618 SK_RLMT_BC_DELTA > BcTimeStamp)) {
1619 PortFound = SK_FALSE;
1620
1621 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1622 ("Port %d received a broadcast at a similar time.\n", i))
1623 break;
1624 }
1625 }
1626 }
1627
1628#ifdef DEBUG
1629 if (PortFound) {
1630 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1631 ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially "
1632 "latest broadcast (%u).\n",
1633 *pSelect,
1634 BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp))
1635 }
1636#endif
1637
1638 return (PortFound);
1639}
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect(
1656SK_AC *pAC,
1657SK_IOC IoC,
1658SK_U32 Active,
1659SK_U32 PrefPort,
1660SK_U32 *pSelect)
1661{
1662 SK_U32 i;
1663 SK_BOOL PortFound;
1664
1665 PortFound = SK_FALSE;
1666
1667
1668 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1669 if (!pAC->Rlmt.Port[i].PortDown &&
1670 !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) {
1671 *pSelect = i;
1672 if (!pAC->Rlmt.Port[Active].PortDown &&
1673 !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) {
1674 *pSelect = Active;
1675 }
1676 if (!pAC->Rlmt.Port[PrefPort].PortDown &&
1677 !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) {
1678 *pSelect = PrefPort;
1679 }
1680 PortFound = SK_TRUE;
1681 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1682 ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n",
1683 *pSelect))
1684 break;
1685 }
1686 }
1687 return (PortFound);
1688}
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704RLMT_STATIC SK_BOOL SkRlmtSelectUp(
1705SK_AC *pAC,
1706SK_IOC IoC,
1707SK_U32 Active,
1708SK_U32 PrefPort,
1709SK_U32 *pSelect,
1710SK_BOOL AutoNegDone)
1711{
1712 SK_U32 i;
1713 SK_BOOL PortFound;
1714
1715 PortFound = SK_FALSE;
1716
1717
1718 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1719 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP &&
1720 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1721 *pSelect = i;
1722 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP &&
1723 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1724 *pSelect = Active;
1725 }
1726 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP &&
1727 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1728 *pSelect = PrefPort;
1729 }
1730 PortFound = SK_TRUE;
1731 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1732 ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect))
1733 break;
1734 }
1735 }
1736 return (PortFound);
1737}
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp(
1754SK_AC *pAC,
1755SK_IOC IoC,
1756SK_U32 Active,
1757SK_U32 PrefPort,
1758SK_U32 *pSelect,
1759SK_BOOL AutoNegDone)
1760{
1761 SK_U64 GuTimeStamp;
1762 SK_U32 i;
1763 SK_BOOL PortFound;
1764
1765 GuTimeStamp = 0;
1766 PortFound = SK_FALSE;
1767
1768
1769 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1770 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1771 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1772 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1773 *pSelect = i;
1774 PortFound = SK_TRUE;
1775 break;
1776 }
1777 }
1778
1779 if (!PortFound) {
1780 return (SK_FALSE);
1781 }
1782
1783 for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1784 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP &&
1785 pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp &&
1786 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1787 GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp;
1788 *pSelect = i;
1789 }
1790 }
1791
1792 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1793 ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect))
1794 return (SK_TRUE);
1795}
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811RLMT_STATIC SK_BOOL SkRlmtSelectDown(
1812SK_AC *pAC,
1813SK_IOC IoC,
1814SK_U32 Active,
1815SK_U32 PrefPort,
1816SK_U32 *pSelect,
1817SK_BOOL AutoNegDone)
1818{
1819 SK_U32 i;
1820 SK_BOOL PortFound;
1821
1822 PortFound = SK_FALSE;
1823
1824
1825 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
1826 if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN &&
1827 pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) {
1828 *pSelect = i;
1829 if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN &&
1830 pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) {
1831 *pSelect = Active;
1832 }
1833 if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN &&
1834 pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) {
1835 *pSelect = PrefPort;
1836 }
1837 PortFound = SK_TRUE;
1838 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
1839 ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect))
1840 break;
1841 }
1842 }
1843 return (PortFound);
1844}
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861RLMT_STATIC void SkRlmtCheckSwitch(
1862SK_AC *pAC,
1863SK_IOC IoC,
1864SK_U32 NetIdx)
1865{
1866 SK_EVPARA Para;
1867 SK_U32 Active;
1868 SK_U32 PrefPort;
1869 SK_U32 i;
1870 SK_BOOL PortFound;
1871
1872 Active = pAC->Rlmt.Net[NetIdx].ActivePort;
1873 PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort;
1874 PortFound = SK_FALSE;
1875 pAC->Rlmt.CheckSwitch = SK_FALSE;
1876
1877#if 0
1878 if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) {
1879
1880 PrefPort = Active;
1881 }
1882#endif
1883
1884 if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) {
1885
1886 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN;
1887 Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP;
1888 Para.Para32[1] = NetIdx;
1889 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para);
1890
1891 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
1892 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
1893 Para.Para32[1] = NetIdx;
1894 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
1895 return;
1896 }
1897 else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 &&
1898 pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) {
1899
1900 pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP;
1901
1902
1903
1904
1905
1906 for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) {
1907 if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) {
1908 if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) {
1909 i = Active;
1910 }
1911 if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) {
1912 i = PrefPort;
1913 }
1914 PortFound = SK_TRUE;
1915 break;
1916 }
1917 }
1918
1919 if (PortFound) {
1920 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1921 Para.Para32[1] = NetIdx;
1922 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
1923
1924 pAC->Rlmt.Net[NetIdx].ActivePort = i;
1925 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber;
1926 Para.Para32[1] = NetIdx;
1927 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para);
1928
1929 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
1930 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC,
1931 pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber,
1932 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].
1933 CurrentMacAddress, &SkRlmtMcAddr)) != NULL) {
1934
1935
1936
1937
1938 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
1939 }
1940 }
1941 else {
1942 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG);
1943 }
1944
1945 return;
1946 }
1947 else {
1948 Para.Para32[0] = Active;
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1974 (!pAC->Rlmt.Net[0].ChgBcPrio)) {
1975
1976 if (!PortFound) {
1977 PortFound = SkRlmtSelectBcRx(
1978 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1979 }
1980
1981 if (!PortFound) {
1982 PortFound = SkRlmtSelectNotSuspect(
1983 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1984 }
1985 }
1986
1987
1988 if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) &&
1989 (pAC->Rlmt.Net[0].ChgBcPrio)) {
1990 if (!PortFound) {
1991 PortFound = SkRlmtSelectNotSuspect(
1992 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1993 }
1994
1995 if (!PortFound) {
1996 PortFound = SkRlmtSelectBcRx(
1997 pAC, IoC, Active, PrefPort, &Para.Para32[1]);
1998 }
1999 }
2000
2001 if (!PortFound) {
2002 PortFound = SkRlmtSelectUp(
2003 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
2004 }
2005
2006 if (!PortFound) {
2007 PortFound = SkRlmtSelectUp(
2008 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
2009 }
2010
2011 if (!PortFound) {
2012 PortFound = SkRlmtSelectGoingUp(
2013 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
2014 }
2015
2016 if (!PortFound) {
2017 PortFound = SkRlmtSelectGoingUp(
2018 pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
2019 }
2020
2021 if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) {
2022 if (!PortFound) {
2023 PortFound = SkRlmtSelectDown(pAC, IoC,
2024 Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS);
2025 }
2026
2027 if (!PortFound) {
2028 PortFound = SkRlmtSelectDown(pAC, IoC,
2029 Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED);
2030 }
2031 }
2032
2033 if (PortFound) {
2034
2035 if (Para.Para32[1] != Active) {
2036 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2037 ("Active: %d, Para1: %d.\n", Active, Para.Para32[1]))
2038 pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1];
2039 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
2040 Port[Para.Para32[0]]->PortNumber;
2041 Para.Para32[1] = pAC->Rlmt.Net[NetIdx].
2042 Port[Para.Para32[1]]->PortNumber;
2043 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE);
2044 if (pAC->Rlmt.Port[Active].LinkDown) {
2045 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para);
2046 }
2047 else {
2048 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
2049 SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para);
2050 }
2051 Para.Para32[1] = NetIdx;
2052 Para.Para32[0] =
2053 pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber;
2054 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para);
2055 Para.Para32[0] = pAC->Rlmt.Net[NetIdx].
2056 Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber;
2057 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para);
2058 if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
2059 (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0],
2060 SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress,
2061 &SkRlmtMcAddr)) != NULL) {
2062
2063
2064
2065
2066
2067 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para);
2068 }
2069 }
2070 }
2071 else {
2072 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG);
2073 }
2074 }
2075 return;
2076}
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093RLMT_STATIC void SkRlmtCheckSeg(
2094SK_AC *pAC,
2095SK_IOC IoC,
2096SK_U32 NetIdx)
2097{
2098 SK_EVPARA Para;
2099 SK_RLMT_NET *pNet;
2100 SK_U32 i, j;
2101 SK_BOOL Equal;
2102
2103 pNet = &pAC->Rlmt.Net[NetIdx];
2104 pNet->RootIdSet = SK_FALSE;
2105 Equal = SK_TRUE;
2106
2107 for (i = 0; i < pNet->NumPorts; i++) {
2108 if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) {
2109 continue;
2110 }
2111
2112 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP,
2113 ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i,
2114 pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1],
2115 pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3],
2116 pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5],
2117 pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7]))
2118
2119 if (!pNet->RootIdSet) {
2120 pNet->Root = pNet->Port[i]->Root;
2121 pNet->RootIdSet = SK_TRUE;
2122 continue;
2123 }
2124
2125 for (j = 0; j < 8; j ++) {
2126 Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j];
2127 if (!Equal) {
2128 break;
2129 }
2130 }
2131
2132 if (!Equal) {
2133 SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG);
2134 Para.Para32[0] = NetIdx;
2135 Para.Para32[1] = (SK_U32)-1;
2136 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para);
2137
2138 pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG;
2139
2140
2141 Para.Para32[0] = NetIdx;
2142 Para.Para32[1] = (SK_U32)-1;
2143 SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL,
2144 SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2145 break;
2146 }
2147 }
2148
2149
2150
2151 pNet->CheckingState &= ~SK_RLMT_RCS_SEG;
2152
2153}
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171RLMT_STATIC void SkRlmtPortStart(
2172SK_AC *pAC,
2173SK_IOC IoC,
2174SK_U32 PortNumber)
2175{
2176 SK_EVPARA Para;
2177
2178 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN;
2179 pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE;
2180 pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE;
2181 pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE;
2182 pAC->Rlmt.Port[PortNumber].CheckingState = 0;
2183 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
2184 Para.Para32[0] = PortNumber;
2185 Para.Para32[1] = (SK_U32)-1;
2186 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para);
2187}
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204RLMT_STATIC void SkRlmtEvtPortStartTim(
2205SK_AC *pAC,
2206SK_IOC IoC,
2207SK_EVPARA Para)
2208{
2209 SK_U32 i;
2210
2211 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2212 ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0]))
2213
2214 if (Para.Para32[1] != (SK_U32)-1) {
2215 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2216 ("Bad Parameter.\n"))
2217 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2218 ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n"))
2219 return;
2220 }
2221
2222
2223
2224
2225
2226
2227
2228 if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
2229
2230 for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) {
2231 if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) {
2232 SkRlmtPortStart(pAC, IoC,
2233 pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber);
2234 }
2235 }
2236 }
2237
2238 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2239 ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n"))
2240}
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257RLMT_STATIC void SkRlmtEvtLinkUp(
2258SK_AC *pAC,
2259SK_IOC IoC,
2260SK_EVPARA Para)
2261{
2262 SK_U32 i;
2263 SK_RLMT_PORT *pRPort;
2264 SK_EVPARA Para2;
2265
2266 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2267 ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0]))
2268
2269 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2270 if (!pRPort->PortStarted) {
2271 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG);
2272
2273 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2274 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2275 return;
2276 }
2277
2278 if (!pRPort->LinkDown) {
2279
2280 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2281 ("SK_RLMT_LINK_UP Event EMPTY.\n"))
2282 return;
2283 }
2284
2285 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2286 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2287 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2288
2289
2290
2291 pRPort->LinkDown = SK_FALSE;
2292 pRPort->PortState = SK_RLMT_PS_GOING_UP;
2293 pRPort->GuTimeStamp = SkOsGetTime(pAC);
2294 pRPort->BcTimeStamp = 0;
2295 pRPort->Net->LinksUp++;
2296 if (pRPort->Net->LinksUp == 1) {
2297 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE);
2298 }
2299 else {
2300 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY);
2301 }
2302
2303 for (i = 0; i < pRPort->Net->NumPorts; i++) {
2304 if (!pRPort->Net->Port[i]->PortStarted) {
2305 SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber);
2306 }
2307 }
2308
2309 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2310
2311 if (pRPort->Net->LinksUp >= 2) {
2312 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) {
2313
2314 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2315 }
2316 }
2317
2318
2319 if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 &&
2320 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) {
2321 Para2.Para32[0] = pRPort->Net->NetNumber;
2322 Para2.Para32[1] = (SK_U32)-1;
2323 SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer,
2324 pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2);
2325 }
2326
2327 Para2 = Para;
2328 Para2.Para32[1] = (SK_U32)-1;
2329 SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL,
2330 SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2);
2331
2332
2333 if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 &&
2334 (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 &&
2335 (Para2.pParaPtr =
2336 SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE,
2337 &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr)
2338 ) != NULL) {
2339
2340 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2341 }
2342
2343 if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) {
2344 if ((Para2.pParaPtr =
2345 SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) {
2346 pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE;
2347 pRPort->Net->CheckingState |=
2348 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2349
2350 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
2351
2352 Para.Para32[1] = (SK_U32)-1;
2353 SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer,
2354 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2355 }
2356 }
2357
2358 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2359 ("SK_RLMT_LINK_UP Event END.\n"))
2360}
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377RLMT_STATIC void SkRlmtEvtPortUpTim(
2378SK_AC *pAC,
2379SK_IOC IoC,
2380SK_EVPARA Para)
2381{
2382 SK_RLMT_PORT *pRPort;
2383
2384 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2385 ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0]))
2386
2387 if (Para.Para32[1] != (SK_U32)-1) {
2388 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2389 ("Bad Parameter.\n"))
2390 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2391 ("SK_RLMT_PORTUP_TIM Event EMPTY.\n"))
2392 return;
2393 }
2394
2395 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2396 if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) {
2397 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2398 ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0]))
2399 return;
2400 }
2401
2402 pRPort->PortDown = SK_FALSE;
2403 pRPort->PortState = SK_RLMT_PS_UP;
2404 pRPort->Net->PortsUp++;
2405 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2406 if (pAC->Rlmt.NumNets <= 1) {
2407 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2408 }
2409 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para);
2410 }
2411
2412 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2413 ("SK_RLMT_PORTUP_TIM Event END.\n"))
2414}
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431RLMT_STATIC void SkRlmtEvtPortDownX(
2432SK_AC *pAC,
2433SK_IOC IoC,
2434SK_U32 Event,
2435SK_EVPARA Para)
2436{
2437 SK_RLMT_PORT *pRPort;
2438
2439 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2440 ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n",
2441 Para.Para32[0], Event))
2442
2443 if (Para.Para32[1] != (SK_U32)-1) {
2444 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2445 ("Bad Parameter.\n"))
2446 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2447 ("SK_RLMT_PORTDOWN* Event EMPTY.\n"))
2448 return;
2449 }
2450
2451 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2452 if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM &&
2453 !(pRPort->CheckingState & SK_RLMT_PCS_TX))) {
2454 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2455 ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event))
2456 return;
2457 }
2458
2459
2460 SkTimerStop(pAC, IoC, &pRPort->UpTimer);
2461 SkTimerStop(pAC, IoC, &pRPort->DownRxTimer);
2462 SkTimerStop(pAC, IoC, &pRPort->DownTxTimer);
2463
2464 if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) {
2465 pRPort->PortState = SK_RLMT_PS_DOWN;
2466 }
2467
2468 if (!pRPort->PortDown) {
2469 pRPort->Net->PortsUp--;
2470 pRPort->PortDown = SK_TRUE;
2471 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para);
2472 }
2473
2474 pRPort->PacketsPerTimeSlot = 0;
2475
2476 pRPort->BpduPacketsPerTimeSlot = 0;
2477 pRPort->BcTimeStamp = 0;
2478
2479
2480
2481
2482
2483 if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) {
2484 if (Para.Para32[0] ==
2485 pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) {
2486
2487 SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber);
2488 }
2489 }
2490
2491 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2492 ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event))
2493}
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510RLMT_STATIC void SkRlmtEvtLinkDown(
2511SK_AC *pAC,
2512SK_IOC IoC,
2513SK_EVPARA Para)
2514{
2515 SK_RLMT_PORT *pRPort;
2516
2517 pRPort = &pAC->Rlmt.Port[Para.Para32[0]];
2518 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2519 ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0]))
2520
2521 if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) {
2522 pRPort->Net->LinksUp--;
2523 pRPort->LinkDown = SK_TRUE;
2524 pRPort->PortState = SK_RLMT_PS_LINK_DOWN;
2525 SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF);
2526
2527 if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) {
2528
2529 SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber);
2530 }
2531
2532
2533 Para.Para32[1] = -1;
2534 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para);
2535 }
2536
2537 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2538 ("SK_RLMT_LINK_DOWN Event END.\n"))
2539}
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556RLMT_STATIC void SkRlmtEvtPortAddr(
2557SK_AC *pAC,
2558SK_IOC IoC,
2559SK_EVPARA Para)
2560{
2561 SK_U32 i, j;
2562 SK_RLMT_PORT *pRPort;
2563 SK_MAC_ADDR *pOldMacAddr;
2564 SK_MAC_ADDR *pNewMacAddr;
2565
2566 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2567 ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0]))
2568
2569 if (Para.Para32[1] != (SK_U32)-1) {
2570 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2571 ("Bad Parameter.\n"))
2572 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2573 ("SK_RLMT_PORT_ADDR Event EMPTY.\n"))
2574 return;
2575 }
2576
2577
2578 pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress;
2579 pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress;
2580
2581
2582
2583
2584
2585
2586 for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) {
2587 pRPort = &pAC->Rlmt.Port[i];
2588 for (j = 0; j < pRPort->PortsChecked; j++) {
2589 if (SK_ADDR_EQUAL(
2590 pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) {
2591 pRPort->PortCheck[j].CheckAddr = *pNewMacAddr;
2592 }
2593 }
2594 }
2595
2596 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2597 ("SK_RLMT_PORT_ADDR Event END.\n"))
2598}
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615RLMT_STATIC void SkRlmtEvtStart(
2616SK_AC *pAC,
2617SK_IOC IoC,
2618SK_EVPARA Para)
2619{
2620 SK_EVPARA Para2;
2621 SK_U32 PortIdx;
2622 SK_U32 PortNumber;
2623
2624 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2625 ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0]))
2626
2627 if (Para.Para32[1] != (SK_U32)-1) {
2628 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2629 ("Bad Parameter.\n"))
2630 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2631 ("SK_RLMT_START Event EMPTY.\n"))
2632 return;
2633 }
2634
2635 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2636 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2637 ("Bad NetNumber %d.\n", Para.Para32[0]))
2638 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2639 ("SK_RLMT_START Event EMPTY.\n"))
2640 return;
2641 }
2642
2643 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) {
2644 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2645 ("SK_RLMT_START Event EMPTY.\n"))
2646 return;
2647 }
2648
2649 if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) {
2650 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2651 ("All nets should have been started.\n"))
2652 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2653 ("SK_RLMT_START Event EMPTY.\n"))
2654 return;
2655 }
2656
2657 if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >=
2658 pAC->Rlmt.Net[Para.Para32[0]].NumPorts) {
2659 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG);
2660
2661
2662 Para2.Para32[0] = 0xFFFFFFFF;
2663 Para2.Para32[1] = Para.Para32[0];
2664 (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2);
2665 }
2666
2667 PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort;
2668 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;
2669
2670 pAC->Rlmt.Net[Para.Para32[0]].LinksUp = 0;
2671 pAC->Rlmt.Net[Para.Para32[0]].PortsUp = 0;
2672 pAC->Rlmt.Net[Para.Para32[0]].CheckingState = 0;
2673 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_NET_DOWN;
2674
2675
2676 SkRlmtPortStart(pAC, IoC, PortNumber);
2677
2678
2679 Para2.Para32[0] = PortNumber;
2680 Para2.Para32[1] = (SK_U32)-1;
2681 SkTimerStart(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer,
2682 SK_RLMT_PORTSTART_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTSTART_TIM, Para2);
2683
2684 pAC->Rlmt.NetsStarted++;
2685
2686 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2687 ("SK_RLMT_START Event END.\n"))
2688}
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705RLMT_STATIC void SkRlmtEvtStop(
2706SK_AC *pAC,
2707SK_IOC IoC,
2708SK_EVPARA Para)
2709{
2710 SK_EVPARA Para2;
2711 SK_U32 PortNumber;
2712 SK_U32 i;
2713
2714 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2715 ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0]))
2716
2717 if (Para.Para32[1] != (SK_U32)-1) {
2718 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2719 ("Bad Parameter.\n"))
2720 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2721 ("SK_RLMT_STOP Event EMPTY.\n"))
2722 return;
2723 }
2724
2725 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
2726 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2727 ("Bad NetNumber %d.\n", Para.Para32[0]))
2728 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2729 ("SK_RLMT_STOP Event EMPTY.\n"))
2730 return;
2731 }
2732
2733 if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) {
2734 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2735 ("SK_RLMT_STOP Event EMPTY.\n"))
2736 return;
2737 }
2738
2739 if (pAC->Rlmt.NetsStarted == 0) {
2740 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2741 ("All nets are stopped.\n"))
2742 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2743 ("SK_RLMT_STOP Event EMPTY.\n"))
2744 return;
2745 }
2746
2747
2748 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer);
2749 SkTimerStop(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer);
2750
2751
2752 pAC->Rlmt.Net[Para.Para32[0]].RlmtState = SK_RLMT_RS_INIT;
2753 pAC->Rlmt.Net[Para.Para32[0]].RootIdSet = SK_FALSE;
2754 Para2.Para32[0] = SK_RLMT_NET_DOWN_FINAL;
2755 Para2.Para32[1] = Para.Para32[0];
2756 SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para2);
2757
2758
2759 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2760 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2761 if (pAC->Rlmt.Port[PortNumber].PortState != SK_RLMT_PS_INIT) {
2762 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].UpTimer);
2763 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownRxTimer);
2764 SkTimerStop(pAC, IoC, &pAC->Rlmt.Port[PortNumber].DownTxTimer);
2765
2766 pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_INIT;
2767 pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE;
2768 pAC->Rlmt.Port[PortNumber].PortStarted = SK_FALSE;
2769 Para2.Para32[0] = PortNumber;
2770 Para2.Para32[1] = (SK_U32)-1;
2771 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_STOP, Para2);
2772 }
2773 }
2774
2775 pAC->Rlmt.NetsStarted--;
2776
2777 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2778 ("SK_RLMT_STOP Event END.\n"))
2779}
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796RLMT_STATIC void SkRlmtEvtTim(
2797SK_AC *pAC,
2798SK_IOC IoC,
2799SK_EVPARA Para)
2800{
2801 SK_RLMT_PORT *pRPort;
2802 SK_U32 Timeout;
2803 SK_U32 NewTimeout;
2804 SK_U32 PortNumber;
2805 SK_U32 i;
2806
2807 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2808 ("SK_RLMT_TIM Event BEGIN.\n"))
2809
2810 if (Para.Para32[1] != (SK_U32)-1) {
2811 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2812 ("Bad Parameter.\n"))
2813 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2814 ("SK_RLMT_TIM Event EMPTY.\n"))
2815 return;
2816 }
2817
2818 if ((pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_OTHERS) == 0 ||
2819 pAC->Rlmt.Net[Para.Para32[0]].LinksUp == 0) {
2820
2821 return;
2822 }
2823
2824#if 0
2825 pAC->Rlmt.SwitchCheckCounter--;
2826 if (pAC->Rlmt.SwitchCheckCounter == 0) {
2827 pAC->Rlmt.SwitchCheckCounter;
2828 }
2829#endif
2830
2831 NewTimeout = SK_RLMT_DEF_TO_VAL;
2832 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2833 PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber;
2834 pRPort = &pAC->Rlmt.Port[PortNumber];
2835 if (!pRPort->LinkDown) {
2836 Timeout = SkRlmtCheckPort(pAC, IoC, PortNumber);
2837 if (Timeout < NewTimeout) {
2838 NewTimeout = Timeout;
2839 }
2840
2841
2842
2843
2844
2845 pRPort->PacketsPerTimeSlot = 0;
2846
2847 pRPort->BpduPacketsPerTimeSlot = 0;
2848 }
2849 }
2850 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue = NewTimeout;
2851
2852 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1) {
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
2864 if (!pAC->Rlmt.Net[Para.Para32[0]].Port[i]->LinkDown) {
2865 SkRlmtSend(pAC, IoC,
2866 pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber);
2867 }
2868 }
2869 }
2870
2871 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].LocTimer,
2872 pAC->Rlmt.Net[Para.Para32[0]].TimeoutValue, SKGE_RLMT, SK_RLMT_TIM,
2873 Para);
2874
2875 if (pAC->Rlmt.Net[Para.Para32[0]].LinksUp > 1 &&
2876 (pAC->Rlmt.Net[Para.Para32[0]].RlmtMode & SK_RLMT_CHECK_SEG) &&
2877 (pAC->Rlmt.Net[Para.Para32[0]].CheckingState & SK_RLMT_RCS_START_SEG)) {
2878 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[0]].SegTimer,
2879 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para);
2880 pAC->Rlmt.Net[Para.Para32[0]].CheckingState &= ~SK_RLMT_RCS_START_SEG;
2881 pAC->Rlmt.Net[Para.Para32[0]].CheckingState |=
2882 SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG;
2883 }
2884
2885 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2886 ("SK_RLMT_TIM Event END.\n"))
2887}
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904RLMT_STATIC void SkRlmtEvtSegTim(
2905SK_AC *pAC,
2906SK_IOC IoC,
2907SK_EVPARA Para)
2908{
2909#ifdef xDEBUG
2910 int j;
2911#endif
2912
2913 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2914 ("SK_RLMT_SEG_TIM Event BEGIN.\n"))
2915
2916 if (Para.Para32[1] != (SK_U32)-1) {
2917 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2918 ("Bad Parameter.\n"))
2919 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2920 ("SK_RLMT_SEG_TIM Event EMPTY.\n"))
2921 return;
2922 }
2923
2924#ifdef xDEBUG
2925 for (j = 0; j < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; j++) {
2926 SK_ADDR_PORT *pAPort;
2927 SK_U32 k;
2928 SK_U16 *InAddr;
2929 SK_U8 InAddr8[6];
2930
2931 InAddr = (SK_U16 *)&InAddr8[0];
2932 pAPort = pAC->Rlmt.Net[Para.Para32[0]].Port[j]->AddrPort;
2933 for (k = 0; k < pAPort->NextExactMatchRlmt; k++) {
2934
2935 XM_INADDR(IoC, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2936 XM_EXM(k), InAddr);
2937 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2938 ("MC address %d on Port %u: %02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x.\n",
2939 k, pAC->Rlmt.Net[Para.Para32[0]].Port[j]->PortNumber,
2940 InAddr8[0], InAddr8[1], InAddr8[2],
2941 InAddr8[3], InAddr8[4], InAddr8[5],
2942 pAPort->Exact[k].a[0], pAPort->Exact[k].a[1],
2943 pAPort->Exact[k].a[2], pAPort->Exact[k].a[3],
2944 pAPort->Exact[k].a[4], pAPort->Exact[k].a[5]))
2945 }
2946 }
2947#endif
2948
2949 SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]);
2950
2951 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2952 ("SK_RLMT_SEG_TIM Event END.\n"))
2953}
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970RLMT_STATIC void SkRlmtEvtPacketRx(
2971SK_AC *pAC,
2972SK_IOC IoC,
2973SK_EVPARA Para)
2974{
2975 SK_MBUF *pMb;
2976 SK_MBUF *pNextMb;
2977 SK_U32 NetNumber;
2978
2979
2980 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2981 ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n"))
2982
2983
2984
2985#ifdef DEBUG
2986 pMb = Para.pParaPtr;
2987 if (pMb == NULL) {
2988 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n"))
2989 }
2990 else if (pMb->pNext != NULL) {
2991 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
2992 ("More than one mbuf or pMb->pNext not set.\n"))
2993 }
2994#endif
2995
2996 for (pMb = Para.pParaPtr; pMb != NULL; pMb = pNextMb) {
2997 pNextMb = pMb->pNext;
2998 pMb->pNext = NULL;
2999
3000 NetNumber = pAC->Rlmt.Port[pMb->PortIdx].Net->NetNumber;
3001 if (pAC->Rlmt.Net[NetNumber].RlmtState == SK_RLMT_RS_INIT) {
3002 SkDrvFreeRlmtMbuf(pAC, IoC, pMb);
3003 }
3004 else {
3005 SkRlmtPacketReceive(pAC, IoC, pMb);
3006 }
3007 }
3008
3009 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3010 ("SK_RLMT_PACKET_RECEIVED Event END.\n"))
3011}
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028RLMT_STATIC void SkRlmtEvtStatsClear(
3029SK_AC *pAC,
3030SK_IOC IoC,
3031SK_EVPARA Para)
3032{
3033 SK_U32 i;
3034 SK_RLMT_PORT *pRPort;
3035
3036 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3037 ("SK_RLMT_STATS_CLEAR Event BEGIN.\n"))
3038
3039 if (Para.Para32[1] != (SK_U32)-1) {
3040 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3041 ("Bad Parameter.\n"))
3042 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3043 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
3044 return;
3045 }
3046
3047 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
3048 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3049 ("Bad NetNumber %d.\n", Para.Para32[0]))
3050 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3051 ("SK_RLMT_STATS_CLEAR Event EMPTY.\n"))
3052 return;
3053 }
3054
3055
3056 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[0]].NumPorts; i++) {
3057 pRPort =
3058 &pAC->Rlmt.Port[pAC->Rlmt.Net[Para.Para32[0]].Port[i]->PortNumber];
3059 pRPort->TxHelloCts = 0;
3060 pRPort->RxHelloCts = 0;
3061 pRPort->TxSpHelloReqCts = 0;
3062 pRPort->RxSpHelloCts = 0;
3063 }
3064
3065 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3066 ("SK_RLMT_STATS_CLEAR Event END.\n"))
3067}
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084RLMT_STATIC void SkRlmtEvtStatsUpdate(
3085SK_AC *pAC,
3086SK_IOC IoC,
3087SK_EVPARA Para)
3088{
3089 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3090 ("SK_RLMT_STATS_UPDATE Event BEGIN.\n"))
3091
3092 if (Para.Para32[1] != (SK_U32)-1) {
3093 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3094 ("Bad Parameter.\n"))
3095 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3096 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
3097 return;
3098 }
3099
3100 if (Para.Para32[0] >= pAC->Rlmt.NumNets) {
3101 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3102 ("Bad NetNumber %d.\n", Para.Para32[0]))
3103 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3104 ("SK_RLMT_STATS_UPDATE Event EMPTY.\n"))
3105 return;
3106 }
3107
3108
3109
3110 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3111 ("SK_RLMT_STATS_UPDATE Event END.\n"))
3112}
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129RLMT_STATIC void SkRlmtEvtPrefportChange(
3130SK_AC *pAC,
3131SK_IOC IoC,
3132SK_EVPARA Para)
3133{
3134 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3135 ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0]))
3136
3137 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
3138 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3139 ("Bad NetNumber %d.\n", Para.Para32[1]))
3140 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3141 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
3142 return;
3143 }
3144
3145
3146 if (Para.Para32[0] == 0xFFFFFFFF) {
3147 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = SK_RLMT_DEF_PREF_PORT;
3148 }
3149 else {
3150 if (Para.Para32[0] >= pAC->Rlmt.Net[Para.Para32[1]].NumPorts) {
3151 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG);
3152
3153 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3154 ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n"))
3155 return;
3156 }
3157
3158 pAC->Rlmt.Net[Para.Para32[1]].PrefPort = Para.Para32[0];
3159 }
3160
3161 pAC->Rlmt.Net[Para.Para32[1]].Preference = Para.Para32[0];
3162
3163 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
3164 SkRlmtCheckSwitch(pAC, IoC, Para.Para32[1]);
3165 }
3166
3167 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3168 ("SK_RLMT_PREFPORT_CHANGE Event END.\n"))
3169}
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186RLMT_STATIC void SkRlmtEvtSetNets(
3187SK_AC *pAC,
3188SK_IOC IoC,
3189SK_EVPARA Para)
3190{
3191 int i;
3192
3193 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3194 ("SK_RLMT_SET_NETS Event BEGIN.\n"))
3195
3196 if (Para.Para32[1] != (SK_U32)-1) {
3197 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3198 ("Bad Parameter.\n"))
3199 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3200 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3201 return;
3202 }
3203
3204 if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS ||
3205 Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) {
3206 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3207 ("Bad number of nets: %d.\n", Para.Para32[0]))
3208 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3209 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3210 return;
3211 }
3212
3213 if (Para.Para32[0] == pAC->Rlmt.NumNets) {
3214 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3215 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3216 return;
3217 }
3218
3219
3220 if (pAC->Rlmt.NetsStarted > 0) {
3221 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3222 ("Changing dual mode only allowed while all nets are stopped.\n"))
3223 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3224 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3225 return;
3226 }
3227
3228 if (Para.Para32[0] == 1) {
3229 if (pAC->Rlmt.NumNets > 1) {
3230
3231 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
3232 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_CLEAR_LOGICAL);
3233 pAC->Rlmt.Net[1].NumPorts = 0;
3234 }
3235
3236 pAC->Rlmt.NumNets = Para.Para32[0];
3237 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
3238 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
3239 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
3240 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;
3241 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
3242
3243 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
3244 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
3245 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
3246 pAC->Rlmt.Net[i].NetNumber = i;
3247 }
3248
3249 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[0];
3250 pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound;
3251
3252 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3253
3254 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3255 ("RLMT: Changed to one net with two ports.\n"))
3256 }
3257 else if (Para.Para32[0] == 2) {
3258 pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1];
3259 pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1;
3260 pAC->Rlmt.Net[0].NumPorts =
3261 pAC->GIni.GIMacsFound - pAC->Rlmt.Net[1].NumPorts;
3262
3263 pAC->Rlmt.NumNets = Para.Para32[0];
3264 for (i = 0; (SK_U32)i < pAC->Rlmt.NumNets; i++) {
3265 pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT;
3266 pAC->Rlmt.Net[i].RootIdSet = SK_FALSE;
3267 pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF;
3268 pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT;
3269
3270 pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort;
3271 pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE;
3272 pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL;
3273
3274 pAC->Rlmt.Net[i].NetNumber = i;
3275 }
3276
3277
3278 (void)SkAddrOverride(pAC, IoC, pAC->Rlmt.Net[1].Port[pAC->Addr.
3279 Net[1].ActivePort]->PortNumber, NULL, SK_ADDR_SET_LOGICAL);
3280
3281 SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para);
3282
3283 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3284 ("RLMT: Changed to two nets with one port each.\n"))
3285 }
3286 else {
3287
3288 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3289 ("SetNets not implemented for more than two nets.\n"))
3290 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3291 ("SK_RLMT_SET_NETS Event EMPTY.\n"))
3292 return;
3293 }
3294
3295 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3296 ("SK_RLMT_SET_NETS Event END.\n"))
3297}
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314RLMT_STATIC void SkRlmtEvtModeChange(
3315SK_AC *pAC,
3316SK_IOC IoC,
3317SK_EVPARA Para)
3318{
3319 SK_EVPARA Para2;
3320 SK_U32 i;
3321 SK_U32 PrevRlmtMode;
3322
3323 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3324 ("SK_RLMT_MODE_CHANGE Event BEGIN.\n"))
3325
3326 if (Para.Para32[1] >= pAC->Rlmt.NumNets) {
3327 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3328 ("Bad NetNumber %d.\n", Para.Para32[1]))
3329 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3330 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3331 return;
3332 }
3333
3334 Para.Para32[0] |= SK_RLMT_CHECK_LINK;
3335
3336 if ((pAC->Rlmt.Net[Para.Para32[1]].NumPorts == 1) &&
3337 Para.Para32[0] != SK_RLMT_MODE_CLS) {
3338 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS;
3339 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3340 ("Forced RLMT mode to CLS on single port net.\n"))
3341 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3342 ("SK_RLMT_MODE_CHANGE Event EMPTY.\n"))
3343 return;
3344 }
3345
3346
3347 PrevRlmtMode = pAC->Rlmt.Net[Para.Para32[1]].RlmtMode;
3348 pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = Para.Para32[0];
3349
3350 if ((PrevRlmtMode & SK_RLMT_CHECK_LOC_LINK) !=
3351 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) {
3352
3353 if ((PrevRlmtMode & SK_RLMT_CHECK_OTHERS) == 0 &&
3354 pAC->Rlmt.Net[Para.Para32[1]].NumPorts > 1 &&
3355 pAC->Rlmt.Net[Para.Para32[1]].PortsUp >= 1) {
3356
3357 Para2.Para32[0] = Para.Para32[1];
3358 Para2.Para32[1] = (SK_U32)-1;
3359 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].LocTimer,
3360 pAC->Rlmt.Net[Para.Para32[1]].TimeoutValue,
3361 SKGE_RLMT, SK_RLMT_TIM, Para2);
3362 }
3363 }
3364
3365 if ((PrevRlmtMode & SK_RLMT_CHECK_SEG) !=
3366 (pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG)) {
3367
3368 for (i = 0; i < pAC->Rlmt.Net[Para.Para32[1]].NumPorts; i++) {
3369 (void)SkAddrMcClear(pAC, IoC,
3370 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3371 SK_ADDR_PERMANENT | SK_MC_SW_ONLY);
3372
3373
3374 (void)SkAddrMcAdd(pAC, IoC,
3375 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3376 &SkRlmtMcAddr, SK_ADDR_PERMANENT);
3377
3378 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode &
3379 SK_RLMT_CHECK_SEG) != 0) {
3380
3381 (void)SkAddrMcAdd(pAC, IoC,
3382 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber,
3383 &BridgeMcAddr, SK_ADDR_PERMANENT);
3384
3385 if (pAC->Rlmt.Net[Para.Para32[1]].RlmtState != SK_RLMT_RS_INIT) {
3386 if (!pAC->Rlmt.Net[Para.Para32[1]].Port[i]->LinkDown &&
3387 (Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(
3388 pAC, IoC, i)) != NULL) {
3389 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->RootIdSet =
3390 SK_FALSE;
3391 SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2);
3392 }
3393 }
3394 }
3395 (void)SkAddrMcUpdate(pAC, IoC,
3396 pAC->Rlmt.Net[Para.Para32[1]].Port[i]->PortNumber);
3397 }
3398
3399 if ((pAC->Rlmt.Net[Para.Para32[1]].RlmtMode & SK_RLMT_CHECK_SEG) != 0) {
3400 Para2.Para32[0] = Para.Para32[1];
3401 Para2.Para32[1] = (SK_U32)-1;
3402 SkTimerStart(pAC, IoC, &pAC->Rlmt.Net[Para.Para32[1]].SegTimer,
3403 SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para2);
3404 }
3405 }
3406
3407 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3408 ("SK_RLMT_MODE_CHANGE Event END.\n"))
3409}
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426int SkRlmtEvent(
3427SK_AC *pAC,
3428SK_IOC IoC,
3429SK_U32 Event,
3430SK_EVPARA Para)
3431{
3432 switch (Event) {
3433
3434
3435
3436 case SK_RLMT_PORTSTART_TIM:
3437 SkRlmtEvtPortStartTim(pAC, IoC, Para);
3438 break;
3439 case SK_RLMT_LINK_UP:
3440 SkRlmtEvtLinkUp(pAC, IoC, Para);
3441 break;
3442 case SK_RLMT_PORTUP_TIM:
3443 SkRlmtEvtPortUpTim(pAC, IoC, Para);
3444 break;
3445 case SK_RLMT_PORTDOWN:
3446 case SK_RLMT_PORTDOWN_RX_TIM:
3447 case SK_RLMT_PORTDOWN_TX_TIM:
3448 SkRlmtEvtPortDownX(pAC, IoC, Event, Para);
3449 break;
3450 case SK_RLMT_LINK_DOWN:
3451 SkRlmtEvtLinkDown(pAC, IoC, Para);
3452 break;
3453 case SK_RLMT_PORT_ADDR:
3454 SkRlmtEvtPortAddr(pAC, IoC, Para);
3455 break;
3456
3457
3458
3459 case SK_RLMT_START:
3460 SkRlmtEvtStart(pAC, IoC, Para);
3461 break;
3462 case SK_RLMT_STOP:
3463 SkRlmtEvtStop(pAC, IoC, Para);
3464 break;
3465 case SK_RLMT_TIM:
3466 SkRlmtEvtTim(pAC, IoC, Para);
3467 break;
3468 case SK_RLMT_SEG_TIM:
3469 SkRlmtEvtSegTim(pAC, IoC, Para);
3470 break;
3471 case SK_RLMT_PACKET_RECEIVED:
3472 SkRlmtEvtPacketRx(pAC, IoC, Para);
3473 break;
3474 case SK_RLMT_STATS_CLEAR:
3475 SkRlmtEvtStatsClear(pAC, IoC, Para);
3476 break;
3477 case SK_RLMT_STATS_UPDATE:
3478 SkRlmtEvtStatsUpdate(pAC, IoC, Para);
3479 break;
3480 case SK_RLMT_PREFPORT_CHANGE:
3481 SkRlmtEvtPrefportChange(pAC, IoC, Para);
3482 break;
3483 case SK_RLMT_MODE_CHANGE:
3484 SkRlmtEvtModeChange(pAC, IoC, Para);
3485 break;
3486 case SK_RLMT_SET_NETS:
3487 SkRlmtEvtSetNets(pAC, IoC, Para);
3488 break;
3489
3490
3491
3492 default:
3493 SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL,
3494 ("Unknown RLMT Event %d.\n", Event))
3495 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG);
3496 break;
3497 }
3498
3499 return (0);
3500}
3501
3502#ifdef __cplusplus
3503}
3504#endif
3505