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