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/skaddr.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/skaddr.c')
-rw-r--r-- | drivers/net/sk98lin/skaddr.c | 1788 |
1 files changed, 0 insertions, 1788 deletions
diff --git a/drivers/net/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c deleted file mode 100644 index 6e6c56aa6d6f..000000000000 --- a/drivers/net/sk98lin/skaddr.c +++ /dev/null | |||
@@ -1,1788 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Name: skaddr.c | ||
4 | * Project: Gigabit Ethernet Adapters, ADDR-Module | ||
5 | * Version: $Revision: 1.52 $ | ||
6 | * Date: $Date: 2003/06/02 13:46:15 $ | ||
7 | * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. | ||
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 is intended to manage multicast addresses, address override, | ||
30 | * and promiscuous mode on GEnesis and Yukon adapters. | ||
31 | * | ||
32 | * Address Layout: | ||
33 | * port address: physical MAC address | ||
34 | * 1st exact match: logical MAC address (GEnesis only) | ||
35 | * 2nd exact match: RLMT multicast (GEnesis only) | ||
36 | * exact match 3-13: OS-specific multicasts (GEnesis only) | ||
37 | * | ||
38 | * Include File Hierarchy: | ||
39 | * | ||
40 | * "skdrv1st.h" | ||
41 | * "skdrv2nd.h" | ||
42 | * | ||
43 | ******************************************************************************/ | ||
44 | |||
45 | #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) | ||
46 | static const char SysKonnectFileId[] = | ||
47 | "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell."; | ||
48 | #endif /* DEBUG ||!LINT || !SK_SLIM */ | ||
49 | |||
50 | #define __SKADDR_C | ||
51 | |||
52 | #ifdef __cplusplus | ||
53 | extern "C" { | ||
54 | #endif /* cplusplus */ | ||
55 | |||
56 | #include "h/skdrv1st.h" | ||
57 | #include "h/skdrv2nd.h" | ||
58 | |||
59 | /* defines ********************************************************************/ | ||
60 | |||
61 | |||
62 | #define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */ | ||
63 | #define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */ | ||
64 | #define HASH_BITS 6 /* #bits in hash */ | ||
65 | #define SK_MC_BIT 0x01 | ||
66 | |||
67 | /* Error numbers and messages. */ | ||
68 | |||
69 | #define SKERR_ADDR_E001 (SK_ERRBASE_ADDR + 0) | ||
70 | #define SKERR_ADDR_E001MSG "Bad Flags." | ||
71 | #define SKERR_ADDR_E002 (SKERR_ADDR_E001 + 1) | ||
72 | #define SKERR_ADDR_E002MSG "New Error." | ||
73 | |||
74 | /* typedefs *******************************************************************/ | ||
75 | |||
76 | /* None. */ | ||
77 | |||
78 | /* global variables ***********************************************************/ | ||
79 | |||
80 | /* 64-bit hash values with all bits set. */ | ||
81 | |||
82 | static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; | ||
83 | |||
84 | /* local variables ************************************************************/ | ||
85 | |||
86 | #ifdef DEBUG | ||
87 | static int Next0[SK_MAX_MACS] = {0}; | ||
88 | #endif /* DEBUG */ | ||
89 | |||
90 | static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
91 | SK_MAC_ADDR *pMc, int Flags); | ||
92 | static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
93 | int Flags); | ||
94 | static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); | ||
95 | static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, | ||
96 | SK_U32 PortNumber, int NewPromMode); | ||
97 | static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
98 | SK_MAC_ADDR *pMc, int Flags); | ||
99 | static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, | ||
100 | int Flags); | ||
101 | static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); | ||
102 | static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, | ||
103 | SK_U32 PortNumber, int NewPromMode); | ||
104 | |||
105 | /* functions ******************************************************************/ | ||
106 | |||
107 | /****************************************************************************** | ||
108 | * | ||
109 | * SkAddrInit - initialize data, set state to init | ||
110 | * | ||
111 | * Description: | ||
112 | * | ||
113 | * SK_INIT_DATA | ||
114 | * ============ | ||
115 | * | ||
116 | * This routine clears the multicast tables and resets promiscuous mode. | ||
117 | * Some entries are reserved for the "logical MAC address", the | ||
118 | * SK-RLMT multicast address, and the BPDU multicast address. | ||
119 | * | ||
120 | * | ||
121 | * SK_INIT_IO | ||
122 | * ========== | ||
123 | * | ||
124 | * All permanent MAC addresses are read from EPROM. | ||
125 | * If the current MAC addresses are not already set in software, | ||
126 | * they are set to the values of the permanent addresses. | ||
127 | * The current addresses are written to the corresponding MAC. | ||
128 | * | ||
129 | * | ||
130 | * SK_INIT_RUN | ||
131 | * =========== | ||
132 | * | ||
133 | * Nothing. | ||
134 | * | ||
135 | * Context: | ||
136 | * init, pageable | ||
137 | * | ||
138 | * Returns: | ||
139 | * SK_ADDR_SUCCESS | ||
140 | */ | ||
141 | int SkAddrInit( | ||
142 | SK_AC *pAC, /* the adapter context */ | ||
143 | SK_IOC IoC, /* I/O context */ | ||
144 | int Level) /* initialization level */ | ||
145 | { | ||
146 | int j; | ||
147 | SK_U32 i; | ||
148 | SK_U8 *InAddr; | ||
149 | SK_U16 *OutAddr; | ||
150 | SK_ADDR_PORT *pAPort; | ||
151 | |||
152 | switch (Level) { | ||
153 | case SK_INIT_DATA: | ||
154 | SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0, | ||
155 | (SK_U16) sizeof(SK_ADDR)); | ||
156 | |||
157 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
158 | pAPort = &pAC->Addr.Port[i]; | ||
159 | pAPort->PromMode = SK_PROM_MODE_NONE; | ||
160 | |||
161 | pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; | ||
162 | pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; | ||
163 | pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; | ||
164 | pAPort->NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; | ||
165 | } | ||
166 | #ifdef xDEBUG | ||
167 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
168 | if (pAC->Addr.Port[i].NextExactMatchRlmt < | ||
169 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
170 | Next0[i] |= 4; | ||
171 | } | ||
172 | } | ||
173 | #endif /* DEBUG */ | ||
174 | /* pAC->Addr.InitDone = SK_INIT_DATA; */ | ||
175 | break; | ||
176 | |||
177 | case SK_INIT_IO: | ||
178 | #ifndef SK_NO_RLMT | ||
179 | for (i = 0; i < SK_MAX_NETS; i++) { | ||
180 | pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; | ||
181 | } | ||
182 | #endif /* !SK_NO_RLMT */ | ||
183 | #ifdef xDEBUG | ||
184 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
185 | if (pAC->Addr.Port[i].NextExactMatchRlmt < | ||
186 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
187 | Next0[i] |= 8; | ||
188 | } | ||
189 | } | ||
190 | #endif /* DEBUG */ | ||
191 | |||
192 | /* Read permanent logical MAC address from Control Register File. */ | ||
193 | for (j = 0; j < SK_MAC_ADDR_LEN; j++) { | ||
194 | InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j]; | ||
195 | SK_IN8(IoC, B2_MAC_1 + j, InAddr); | ||
196 | } | ||
197 | |||
198 | if (!pAC->Addr.Net[0].CurrentMacAddressSet) { | ||
199 | /* Set the current logical MAC address to the permanent one. */ | ||
200 | pAC->Addr.Net[0].CurrentMacAddress = | ||
201 | pAC->Addr.Net[0].PermanentMacAddress; | ||
202 | pAC->Addr.Net[0].CurrentMacAddressSet = SK_TRUE; | ||
203 | } | ||
204 | |||
205 | /* Set the current logical MAC address. */ | ||
206 | pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] = | ||
207 | pAC->Addr.Net[0].CurrentMacAddress; | ||
208 | #if SK_MAX_NETS > 1 | ||
209 | /* Set logical MAC address for net 2 to (log | 3). */ | ||
210 | if (!pAC->Addr.Net[1].CurrentMacAddressSet) { | ||
211 | pAC->Addr.Net[1].PermanentMacAddress = | ||
212 | pAC->Addr.Net[0].PermanentMacAddress; | ||
213 | pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3; | ||
214 | /* Set the current logical MAC address to the permanent one. */ | ||
215 | pAC->Addr.Net[1].CurrentMacAddress = | ||
216 | pAC->Addr.Net[1].PermanentMacAddress; | ||
217 | pAC->Addr.Net[1].CurrentMacAddressSet = SK_TRUE; | ||
218 | } | ||
219 | #endif /* SK_MAX_NETS > 1 */ | ||
220 | |||
221 | #ifdef DEBUG | ||
222 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
223 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
224 | ("Permanent MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", | ||
225 | i, | ||
226 | pAC->Addr.Net[i].PermanentMacAddress.a[0], | ||
227 | pAC->Addr.Net[i].PermanentMacAddress.a[1], | ||
228 | pAC->Addr.Net[i].PermanentMacAddress.a[2], | ||
229 | pAC->Addr.Net[i].PermanentMacAddress.a[3], | ||
230 | pAC->Addr.Net[i].PermanentMacAddress.a[4], | ||
231 | pAC->Addr.Net[i].PermanentMacAddress.a[5])) | ||
232 | |||
233 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
234 | ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", | ||
235 | i, | ||
236 | pAC->Addr.Net[i].CurrentMacAddress.a[0], | ||
237 | pAC->Addr.Net[i].CurrentMacAddress.a[1], | ||
238 | pAC->Addr.Net[i].CurrentMacAddress.a[2], | ||
239 | pAC->Addr.Net[i].CurrentMacAddress.a[3], | ||
240 | pAC->Addr.Net[i].CurrentMacAddress.a[4], | ||
241 | pAC->Addr.Net[i].CurrentMacAddress.a[5])) | ||
242 | } | ||
243 | #endif /* DEBUG */ | ||
244 | |||
245 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
246 | pAPort = &pAC->Addr.Port[i]; | ||
247 | |||
248 | /* Read permanent port addresses from Control Register File. */ | ||
249 | for (j = 0; j < SK_MAC_ADDR_LEN; j++) { | ||
250 | InAddr = (SK_U8 *) &pAPort->PermanentMacAddress.a[j]; | ||
251 | SK_IN8(IoC, B2_MAC_2 + 8 * i + j, InAddr); | ||
252 | } | ||
253 | |||
254 | if (!pAPort->CurrentMacAddressSet) { | ||
255 | /* | ||
256 | * Set the current and previous physical MAC address | ||
257 | * of this port to its permanent MAC address. | ||
258 | */ | ||
259 | pAPort->CurrentMacAddress = pAPort->PermanentMacAddress; | ||
260 | pAPort->PreviousMacAddress = pAPort->PermanentMacAddress; | ||
261 | pAPort->CurrentMacAddressSet = SK_TRUE; | ||
262 | } | ||
263 | |||
264 | /* Set port's current physical MAC address. */ | ||
265 | OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; | ||
266 | #ifdef GENESIS | ||
267 | if (pAC->GIni.GIGenesis) { | ||
268 | XM_OUTADDR(IoC, i, XM_SA, OutAddr); | ||
269 | } | ||
270 | #endif /* GENESIS */ | ||
271 | #ifdef YUKON | ||
272 | if (!pAC->GIni.GIGenesis) { | ||
273 | GM_OUTADDR(IoC, i, GM_SRC_ADDR_1L, OutAddr); | ||
274 | } | ||
275 | #endif /* YUKON */ | ||
276 | #ifdef DEBUG | ||
277 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
278 | ("SkAddrInit: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
279 | pAPort->PermanentMacAddress.a[0], | ||
280 | pAPort->PermanentMacAddress.a[1], | ||
281 | pAPort->PermanentMacAddress.a[2], | ||
282 | pAPort->PermanentMacAddress.a[3], | ||
283 | pAPort->PermanentMacAddress.a[4], | ||
284 | pAPort->PermanentMacAddress.a[5])) | ||
285 | |||
286 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, | ||
287 | ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
288 | pAPort->CurrentMacAddress.a[0], | ||
289 | pAPort->CurrentMacAddress.a[1], | ||
290 | pAPort->CurrentMacAddress.a[2], | ||
291 | pAPort->CurrentMacAddress.a[3], | ||
292 | pAPort->CurrentMacAddress.a[4], | ||
293 | pAPort->CurrentMacAddress.a[5])) | ||
294 | #endif /* DEBUG */ | ||
295 | } | ||
296 | /* pAC->Addr.InitDone = SK_INIT_IO; */ | ||
297 | break; | ||
298 | |||
299 | case SK_INIT_RUN: | ||
300 | #ifdef xDEBUG | ||
301 | for (i = 0; i < SK_MAX_MACS; i++) { | ||
302 | if (pAC->Addr.Port[i].NextExactMatchRlmt < | ||
303 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
304 | Next0[i] |= 16; | ||
305 | } | ||
306 | } | ||
307 | #endif /* DEBUG */ | ||
308 | |||
309 | /* pAC->Addr.InitDone = SK_INIT_RUN; */ | ||
310 | break; | ||
311 | |||
312 | default: /* error */ | ||
313 | break; | ||
314 | } | ||
315 | |||
316 | return (SK_ADDR_SUCCESS); | ||
317 | |||
318 | } /* SkAddrInit */ | ||
319 | |||
320 | #ifndef SK_SLIM | ||
321 | |||
322 | /****************************************************************************** | ||
323 | * | ||
324 | * SkAddrMcClear - clear the multicast table | ||
325 | * | ||
326 | * Description: | ||
327 | * This routine clears the multicast table. | ||
328 | * | ||
329 | * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated | ||
330 | * immediately. | ||
331 | * | ||
332 | * It calls either SkAddrXmacMcClear or SkAddrGmacMcClear, according | ||
333 | * to the adapter in use. The real work is done there. | ||
334 | * | ||
335 | * Context: | ||
336 | * runtime, pageable | ||
337 | * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY | ||
338 | * may be called after SK_INIT_IO without limitation | ||
339 | * | ||
340 | * Returns: | ||
341 | * SK_ADDR_SUCCESS | ||
342 | * SK_ADDR_ILLEGAL_PORT | ||
343 | */ | ||
344 | int SkAddrMcClear( | ||
345 | SK_AC *pAC, /* adapter context */ | ||
346 | SK_IOC IoC, /* I/O context */ | ||
347 | SK_U32 PortNumber, /* Index of affected port */ | ||
348 | int Flags) /* permanent/non-perm, sw-only */ | ||
349 | { | ||
350 | int ReturnCode; | ||
351 | |||
352 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
353 | return (SK_ADDR_ILLEGAL_PORT); | ||
354 | } | ||
355 | |||
356 | if (pAC->GIni.GIGenesis) { | ||
357 | ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); | ||
358 | } | ||
359 | else { | ||
360 | ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); | ||
361 | } | ||
362 | |||
363 | return (ReturnCode); | ||
364 | |||
365 | } /* SkAddrMcClear */ | ||
366 | |||
367 | #endif /* !SK_SLIM */ | ||
368 | |||
369 | #ifndef SK_SLIM | ||
370 | |||
371 | /****************************************************************************** | ||
372 | * | ||
373 | * SkAddrXmacMcClear - clear the multicast table | ||
374 | * | ||
375 | * Description: | ||
376 | * This routine clears the multicast table | ||
377 | * (either entry 2 or entries 3-16 and InexactFilter) of the given port. | ||
378 | * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated | ||
379 | * immediately. | ||
380 | * | ||
381 | * Context: | ||
382 | * runtime, pageable | ||
383 | * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY | ||
384 | * may be called after SK_INIT_IO without limitation | ||
385 | * | ||
386 | * Returns: | ||
387 | * SK_ADDR_SUCCESS | ||
388 | * SK_ADDR_ILLEGAL_PORT | ||
389 | */ | ||
390 | static int SkAddrXmacMcClear( | ||
391 | SK_AC *pAC, /* adapter context */ | ||
392 | SK_IOC IoC, /* I/O context */ | ||
393 | SK_U32 PortNumber, /* Index of affected port */ | ||
394 | int Flags) /* permanent/non-perm, sw-only */ | ||
395 | { | ||
396 | int i; | ||
397 | |||
398 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
399 | |||
400 | /* Clear RLMT multicast addresses. */ | ||
401 | pAC->Addr.Port[PortNumber].NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; | ||
402 | } | ||
403 | else { /* not permanent => DRV */ | ||
404 | |||
405 | /* Clear InexactFilter */ | ||
406 | for (i = 0; i < 8; i++) { | ||
407 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; | ||
408 | } | ||
409 | |||
410 | /* Clear DRV multicast addresses. */ | ||
411 | |||
412 | pAC->Addr.Port[PortNumber].NextExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; | ||
413 | } | ||
414 | |||
415 | if (!(Flags & SK_MC_SW_ONLY)) { | ||
416 | (void) SkAddrXmacMcUpdate(pAC, IoC, PortNumber); | ||
417 | } | ||
418 | |||
419 | return (SK_ADDR_SUCCESS); | ||
420 | |||
421 | } /* SkAddrXmacMcClear */ | ||
422 | |||
423 | #endif /* !SK_SLIM */ | ||
424 | |||
425 | #ifndef SK_SLIM | ||
426 | |||
427 | /****************************************************************************** | ||
428 | * | ||
429 | * SkAddrGmacMcClear - clear the multicast table | ||
430 | * | ||
431 | * Description: | ||
432 | * This routine clears the multicast hashing table (InexactFilter) | ||
433 | * (either the RLMT or the driver bits) of the given port. | ||
434 | * | ||
435 | * If not suppressed by Flag SK_MC_SW_ONLY, the hardware is updated | ||
436 | * immediately. | ||
437 | * | ||
438 | * Context: | ||
439 | * runtime, pageable | ||
440 | * may be called starting with SK_INIT_DATA with flag SK_MC_SW_ONLY | ||
441 | * may be called after SK_INIT_IO without limitation | ||
442 | * | ||
443 | * Returns: | ||
444 | * SK_ADDR_SUCCESS | ||
445 | * SK_ADDR_ILLEGAL_PORT | ||
446 | */ | ||
447 | static int SkAddrGmacMcClear( | ||
448 | SK_AC *pAC, /* adapter context */ | ||
449 | SK_IOC IoC, /* I/O context */ | ||
450 | SK_U32 PortNumber, /* Index of affected port */ | ||
451 | int Flags) /* permanent/non-perm, sw-only */ | ||
452 | { | ||
453 | int i; | ||
454 | |||
455 | #ifdef DEBUG | ||
456 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
457 | ("GMAC InexactFilter (not cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
458 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], | ||
459 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], | ||
460 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], | ||
461 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], | ||
462 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], | ||
463 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], | ||
464 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], | ||
465 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) | ||
466 | #endif /* DEBUG */ | ||
467 | |||
468 | /* Clear InexactFilter */ | ||
469 | for (i = 0; i < 8; i++) { | ||
470 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; | ||
471 | } | ||
472 | |||
473 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
474 | |||
475 | /* Copy DRV bits to InexactFilter. */ | ||
476 | for (i = 0; i < 8; i++) { | ||
477 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
478 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; | ||
479 | |||
480 | /* Clear InexactRlmtFilter. */ | ||
481 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; | ||
482 | |||
483 | } | ||
484 | } | ||
485 | else { /* not permanent => DRV */ | ||
486 | |||
487 | /* Copy RLMT bits to InexactFilter. */ | ||
488 | for (i = 0; i < 8; i++) { | ||
489 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
490 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; | ||
491 | |||
492 | /* Clear InexactDrvFilter. */ | ||
493 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | #ifdef DEBUG | ||
498 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
499 | ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
500 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0], | ||
501 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[1], | ||
502 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[2], | ||
503 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[3], | ||
504 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], | ||
505 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], | ||
506 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], | ||
507 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) | ||
508 | #endif /* DEBUG */ | ||
509 | |||
510 | if (!(Flags & SK_MC_SW_ONLY)) { | ||
511 | (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber); | ||
512 | } | ||
513 | |||
514 | return (SK_ADDR_SUCCESS); | ||
515 | |||
516 | } /* SkAddrGmacMcClear */ | ||
517 | |||
518 | #ifndef SK_ADDR_CHEAT | ||
519 | |||
520 | /****************************************************************************** | ||
521 | * | ||
522 | * SkXmacMcHash - hash multicast address | ||
523 | * | ||
524 | * Description: | ||
525 | * This routine computes the hash value for a multicast address. | ||
526 | * A CRC32 algorithm is used. | ||
527 | * | ||
528 | * Notes: | ||
529 | * The code was adapted from the XaQti data sheet. | ||
530 | * | ||
531 | * Context: | ||
532 | * runtime, pageable | ||
533 | * | ||
534 | * Returns: | ||
535 | * Hash value of multicast address. | ||
536 | */ | ||
537 | static SK_U32 SkXmacMcHash( | ||
538 | unsigned char *pMc) /* Multicast address */ | ||
539 | { | ||
540 | SK_U32 Idx; | ||
541 | SK_U32 Bit; | ||
542 | SK_U32 Data; | ||
543 | SK_U32 Crc; | ||
544 | |||
545 | Crc = 0xFFFFFFFFUL; | ||
546 | for (Idx = 0; Idx < SK_MAC_ADDR_LEN; Idx++) { | ||
547 | Data = *pMc++; | ||
548 | for (Bit = 0; Bit < 8; Bit++, Data >>= 1) { | ||
549 | Crc = (Crc >> 1) ^ (((Crc ^ Data) & 1) ? XMAC_POLY : 0); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | return (Crc & ((1 << HASH_BITS) - 1)); | ||
554 | |||
555 | } /* SkXmacMcHash */ | ||
556 | |||
557 | |||
558 | /****************************************************************************** | ||
559 | * | ||
560 | * SkGmacMcHash - hash multicast address | ||
561 | * | ||
562 | * Description: | ||
563 | * This routine computes the hash value for a multicast address. | ||
564 | * A CRC16 algorithm is used. | ||
565 | * | ||
566 | * Notes: | ||
567 | * | ||
568 | * | ||
569 | * Context: | ||
570 | * runtime, pageable | ||
571 | * | ||
572 | * Returns: | ||
573 | * Hash value of multicast address. | ||
574 | */ | ||
575 | static SK_U32 SkGmacMcHash( | ||
576 | unsigned char *pMc) /* Multicast address */ | ||
577 | { | ||
578 | SK_U32 Data; | ||
579 | SK_U32 TmpData; | ||
580 | SK_U32 Crc; | ||
581 | int Byte; | ||
582 | int Bit; | ||
583 | |||
584 | Crc = 0xFFFFFFFFUL; | ||
585 | for (Byte = 0; Byte < 6; Byte++) { | ||
586 | /* Get next byte. */ | ||
587 | Data = (SK_U32) pMc[Byte]; | ||
588 | |||
589 | /* Change bit order in byte. */ | ||
590 | TmpData = Data; | ||
591 | for (Bit = 0; Bit < 8; Bit++) { | ||
592 | if (TmpData & 1L) { | ||
593 | Data |= 1L << (7 - Bit); | ||
594 | } | ||
595 | else { | ||
596 | Data &= ~(1L << (7 - Bit)); | ||
597 | } | ||
598 | TmpData >>= 1; | ||
599 | } | ||
600 | |||
601 | Crc ^= (Data << 24); | ||
602 | for (Bit = 0; Bit < 8; Bit++) { | ||
603 | if (Crc & 0x80000000) { | ||
604 | Crc = (Crc << 1) ^ GMAC_POLY; | ||
605 | } | ||
606 | else { | ||
607 | Crc <<= 1; | ||
608 | } | ||
609 | } | ||
610 | } | ||
611 | |||
612 | return (Crc & ((1 << HASH_BITS) - 1)); | ||
613 | |||
614 | } /* SkGmacMcHash */ | ||
615 | |||
616 | #endif /* !SK_ADDR_CHEAT */ | ||
617 | |||
618 | /****************************************************************************** | ||
619 | * | ||
620 | * SkAddrMcAdd - add a multicast address to a port | ||
621 | * | ||
622 | * Description: | ||
623 | * This routine enables reception for a given address on the given port. | ||
624 | * | ||
625 | * It calls either SkAddrXmacMcAdd or SkAddrGmacMcAdd, according to the | ||
626 | * adapter in use. The real work is done there. | ||
627 | * | ||
628 | * Notes: | ||
629 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
630 | * | ||
631 | * Context: | ||
632 | * runtime, pageable | ||
633 | * may be called after SK_INIT_DATA | ||
634 | * | ||
635 | * Returns: | ||
636 | * SK_MC_FILTERING_EXACT | ||
637 | * SK_MC_FILTERING_INEXACT | ||
638 | * SK_MC_ILLEGAL_ADDRESS | ||
639 | * SK_MC_ILLEGAL_PORT | ||
640 | * SK_MC_RLMT_OVERFLOW | ||
641 | */ | ||
642 | int SkAddrMcAdd( | ||
643 | SK_AC *pAC, /* adapter context */ | ||
644 | SK_IOC IoC, /* I/O context */ | ||
645 | SK_U32 PortNumber, /* Port Number */ | ||
646 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
647 | int Flags) /* permanent/non-permanent */ | ||
648 | { | ||
649 | int ReturnCode; | ||
650 | |||
651 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
652 | return (SK_ADDR_ILLEGAL_PORT); | ||
653 | } | ||
654 | |||
655 | if (pAC->GIni.GIGenesis) { | ||
656 | ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); | ||
657 | } | ||
658 | else { | ||
659 | ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); | ||
660 | } | ||
661 | |||
662 | return (ReturnCode); | ||
663 | |||
664 | } /* SkAddrMcAdd */ | ||
665 | |||
666 | |||
667 | /****************************************************************************** | ||
668 | * | ||
669 | * SkAddrXmacMcAdd - add a multicast address to a port | ||
670 | * | ||
671 | * Description: | ||
672 | * This routine enables reception for a given address on the given port. | ||
673 | * | ||
674 | * Notes: | ||
675 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
676 | * | ||
677 | * The multicast bit is only checked if there are no free exact match | ||
678 | * entries. | ||
679 | * | ||
680 | * Context: | ||
681 | * runtime, pageable | ||
682 | * may be called after SK_INIT_DATA | ||
683 | * | ||
684 | * Returns: | ||
685 | * SK_MC_FILTERING_EXACT | ||
686 | * SK_MC_FILTERING_INEXACT | ||
687 | * SK_MC_ILLEGAL_ADDRESS | ||
688 | * SK_MC_RLMT_OVERFLOW | ||
689 | */ | ||
690 | static int SkAddrXmacMcAdd( | ||
691 | SK_AC *pAC, /* adapter context */ | ||
692 | SK_IOC IoC, /* I/O context */ | ||
693 | SK_U32 PortNumber, /* Port Number */ | ||
694 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
695 | int Flags) /* permanent/non-permanent */ | ||
696 | { | ||
697 | int i; | ||
698 | SK_U8 Inexact; | ||
699 | #ifndef SK_ADDR_CHEAT | ||
700 | SK_U32 HashBit; | ||
701 | #endif /* !defined(SK_ADDR_CHEAT) */ | ||
702 | |||
703 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
704 | #ifdef xDEBUG | ||
705 | if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt < | ||
706 | SK_ADDR_FIRST_MATCH_RLMT) { | ||
707 | Next0[PortNumber] |= 1; | ||
708 | return (SK_MC_RLMT_OVERFLOW); | ||
709 | } | ||
710 | #endif /* DEBUG */ | ||
711 | |||
712 | if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt > | ||
713 | SK_ADDR_LAST_MATCH_RLMT) { | ||
714 | return (SK_MC_RLMT_OVERFLOW); | ||
715 | } | ||
716 | |||
717 | /* Set a RLMT multicast address. */ | ||
718 | |||
719 | pAC->Addr.Port[PortNumber].Exact[ | ||
720 | pAC->Addr.Port[PortNumber].NextExactMatchRlmt++] = *pMc; | ||
721 | |||
722 | return (SK_MC_FILTERING_EXACT); | ||
723 | } | ||
724 | |||
725 | #ifdef xDEBUG | ||
726 | if (pAC->Addr.Port[PortNumber].NextExactMatchDrv < | ||
727 | SK_ADDR_FIRST_MATCH_DRV) { | ||
728 | Next0[PortNumber] |= 2; | ||
729 | return (SK_MC_RLMT_OVERFLOW); | ||
730 | } | ||
731 | #endif /* DEBUG */ | ||
732 | |||
733 | if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { | ||
734 | |||
735 | /* Set exact match entry. */ | ||
736 | pAC->Addr.Port[PortNumber].Exact[ | ||
737 | pAC->Addr.Port[PortNumber].NextExactMatchDrv++] = *pMc; | ||
738 | |||
739 | /* Clear InexactFilter */ | ||
740 | for (i = 0; i < 8; i++) { | ||
741 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; | ||
742 | } | ||
743 | } | ||
744 | else { | ||
745 | if (!(pMc->a[0] & SK_MC_BIT)) { | ||
746 | /* Hashing only possible with multicast addresses */ | ||
747 | return (SK_MC_ILLEGAL_ADDRESS); | ||
748 | } | ||
749 | #ifndef SK_ADDR_CHEAT | ||
750 | /* Compute hash value of address. */ | ||
751 | HashBit = 63 - SkXmacMcHash(&pMc->a[0]); | ||
752 | |||
753 | /* Add bit to InexactFilter. */ | ||
754 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[HashBit / 8] |= | ||
755 | 1 << (HashBit % 8); | ||
756 | #else /* SK_ADDR_CHEAT */ | ||
757 | /* Set all bits in InexactFilter. */ | ||
758 | for (i = 0; i < 8; i++) { | ||
759 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; | ||
760 | } | ||
761 | #endif /* SK_ADDR_CHEAT */ | ||
762 | } | ||
763 | |||
764 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
765 | Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; | ||
766 | } | ||
767 | |||
768 | if (Inexact == 0 && pAC->Addr.Port[PortNumber].PromMode == 0) { | ||
769 | return (SK_MC_FILTERING_EXACT); | ||
770 | } | ||
771 | else { | ||
772 | return (SK_MC_FILTERING_INEXACT); | ||
773 | } | ||
774 | |||
775 | } /* SkAddrXmacMcAdd */ | ||
776 | |||
777 | |||
778 | /****************************************************************************** | ||
779 | * | ||
780 | * SkAddrGmacMcAdd - add a multicast address to a port | ||
781 | * | ||
782 | * Description: | ||
783 | * This routine enables reception for a given address on the given port. | ||
784 | * | ||
785 | * Notes: | ||
786 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
787 | * | ||
788 | * Context: | ||
789 | * runtime, pageable | ||
790 | * may be called after SK_INIT_DATA | ||
791 | * | ||
792 | * Returns: | ||
793 | * SK_MC_FILTERING_INEXACT | ||
794 | * SK_MC_ILLEGAL_ADDRESS | ||
795 | */ | ||
796 | static int SkAddrGmacMcAdd( | ||
797 | SK_AC *pAC, /* adapter context */ | ||
798 | SK_IOC IoC, /* I/O context */ | ||
799 | SK_U32 PortNumber, /* Port Number */ | ||
800 | SK_MAC_ADDR *pMc, /* multicast address to be added */ | ||
801 | int Flags) /* permanent/non-permanent */ | ||
802 | { | ||
803 | int i; | ||
804 | #ifndef SK_ADDR_CHEAT | ||
805 | SK_U32 HashBit; | ||
806 | #endif /* !defined(SK_ADDR_CHEAT) */ | ||
807 | |||
808 | if (!(pMc->a[0] & SK_MC_BIT)) { | ||
809 | /* Hashing only possible with multicast addresses */ | ||
810 | return (SK_MC_ILLEGAL_ADDRESS); | ||
811 | } | ||
812 | |||
813 | #ifndef SK_ADDR_CHEAT | ||
814 | |||
815 | /* Compute hash value of address. */ | ||
816 | HashBit = SkGmacMcHash(&pMc->a[0]); | ||
817 | |||
818 | if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ | ||
819 | |||
820 | /* Add bit to InexactRlmtFilter. */ | ||
821 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |= | ||
822 | 1 << (HashBit % 8); | ||
823 | |||
824 | /* Copy bit to InexactFilter. */ | ||
825 | for (i = 0; i < 8; i++) { | ||
826 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
827 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; | ||
828 | } | ||
829 | #ifdef DEBUG | ||
830 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
831 | ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
832 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[0], | ||
833 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[1], | ||
834 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[2], | ||
835 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[3], | ||
836 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4], | ||
837 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5], | ||
838 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6], | ||
839 | pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7])) | ||
840 | #endif /* DEBUG */ | ||
841 | } | ||
842 | else { /* not permanent => DRV */ | ||
843 | |||
844 | /* Add bit to InexactDrvFilter. */ | ||
845 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |= | ||
846 | 1 << (HashBit % 8); | ||
847 | |||
848 | /* Copy bit to InexactFilter. */ | ||
849 | for (i = 0; i < 8; i++) { | ||
850 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= | ||
851 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; | ||
852 | } | ||
853 | #ifdef DEBUG | ||
854 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
855 | ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", | ||
856 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[0], | ||
857 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[1], | ||
858 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[2], | ||
859 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[3], | ||
860 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4], | ||
861 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5], | ||
862 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6], | ||
863 | pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7])) | ||
864 | #endif /* DEBUG */ | ||
865 | } | ||
866 | |||
867 | #else /* SK_ADDR_CHEAT */ | ||
868 | |||
869 | /* Set all bits in InexactFilter. */ | ||
870 | for (i = 0; i < 8; i++) { | ||
871 | pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; | ||
872 | } | ||
873 | #endif /* SK_ADDR_CHEAT */ | ||
874 | |||
875 | return (SK_MC_FILTERING_INEXACT); | ||
876 | |||
877 | } /* SkAddrGmacMcAdd */ | ||
878 | |||
879 | #endif /* !SK_SLIM */ | ||
880 | |||
881 | /****************************************************************************** | ||
882 | * | ||
883 | * SkAddrMcUpdate - update the HW MC address table and set the MAC address | ||
884 | * | ||
885 | * Description: | ||
886 | * This routine enables reception of the addresses contained in a local | ||
887 | * table for a given port. | ||
888 | * It also programs the port's current physical MAC address. | ||
889 | * | ||
890 | * It calls either SkAddrXmacMcUpdate or SkAddrGmacMcUpdate, according | ||
891 | * to the adapter in use. The real work is done there. | ||
892 | * | ||
893 | * Notes: | ||
894 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
895 | * | ||
896 | * Context: | ||
897 | * runtime, pageable | ||
898 | * may be called after SK_INIT_IO | ||
899 | * | ||
900 | * Returns: | ||
901 | * SK_MC_FILTERING_EXACT | ||
902 | * SK_MC_FILTERING_INEXACT | ||
903 | * SK_ADDR_ILLEGAL_PORT | ||
904 | */ | ||
905 | int SkAddrMcUpdate( | ||
906 | SK_AC *pAC, /* adapter context */ | ||
907 | SK_IOC IoC, /* I/O context */ | ||
908 | SK_U32 PortNumber) /* Port Number */ | ||
909 | { | ||
910 | int ReturnCode = 0; | ||
911 | #if (!defined(SK_SLIM) || defined(DEBUG)) | ||
912 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
913 | return (SK_ADDR_ILLEGAL_PORT); | ||
914 | } | ||
915 | #endif /* !SK_SLIM || DEBUG */ | ||
916 | |||
917 | #ifdef GENESIS | ||
918 | if (pAC->GIni.GIGenesis) { | ||
919 | ReturnCode = SkAddrXmacMcUpdate(pAC, IoC, PortNumber); | ||
920 | } | ||
921 | #endif /* GENESIS */ | ||
922 | #ifdef YUKON | ||
923 | if (!pAC->GIni.GIGenesis) { | ||
924 | ReturnCode = SkAddrGmacMcUpdate(pAC, IoC, PortNumber); | ||
925 | } | ||
926 | #endif /* YUKON */ | ||
927 | return (ReturnCode); | ||
928 | |||
929 | } /* SkAddrMcUpdate */ | ||
930 | |||
931 | |||
932 | #ifdef GENESIS | ||
933 | |||
934 | /****************************************************************************** | ||
935 | * | ||
936 | * SkAddrXmacMcUpdate - update the HW MC address table and set the MAC address | ||
937 | * | ||
938 | * Description: | ||
939 | * This routine enables reception of the addresses contained in a local | ||
940 | * table for a given port. | ||
941 | * It also programs the port's current physical MAC address. | ||
942 | * | ||
943 | * Notes: | ||
944 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
945 | * | ||
946 | * Context: | ||
947 | * runtime, pageable | ||
948 | * may be called after SK_INIT_IO | ||
949 | * | ||
950 | * Returns: | ||
951 | * SK_MC_FILTERING_EXACT | ||
952 | * SK_MC_FILTERING_INEXACT | ||
953 | * SK_ADDR_ILLEGAL_PORT | ||
954 | */ | ||
955 | static int SkAddrXmacMcUpdate( | ||
956 | SK_AC *pAC, /* adapter context */ | ||
957 | SK_IOC IoC, /* I/O context */ | ||
958 | SK_U32 PortNumber) /* Port Number */ | ||
959 | { | ||
960 | SK_U32 i; | ||
961 | SK_U8 Inexact; | ||
962 | SK_U16 *OutAddr; | ||
963 | SK_ADDR_PORT *pAPort; | ||
964 | |||
965 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
966 | ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)) | ||
967 | |||
968 | pAPort = &pAC->Addr.Port[PortNumber]; | ||
969 | |||
970 | #ifdef DEBUG | ||
971 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
972 | ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) | ||
973 | #endif /* DEBUG */ | ||
974 | |||
975 | /* Start with 0 to also program the logical MAC address. */ | ||
976 | for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { | ||
977 | /* Set exact match address i on XMAC */ | ||
978 | OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; | ||
979 | XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); | ||
980 | } | ||
981 | |||
982 | /* Clear other permanent exact match addresses on XMAC */ | ||
983 | if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) { | ||
984 | |||
985 | SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt, | ||
986 | SK_ADDR_LAST_MATCH_RLMT); | ||
987 | } | ||
988 | |||
989 | for (i = pAPort->FirstExactMatchDrv; i < pAPort->NextExactMatchDrv; i++) { | ||
990 | OutAddr = (SK_U16 *) &pAPort->Exact[i].a[0]; | ||
991 | XM_OUTADDR(IoC, PortNumber, XM_EXM(i), OutAddr); | ||
992 | } | ||
993 | |||
994 | /* Clear other non-permanent exact match addresses on XMAC */ | ||
995 | if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { | ||
996 | |||
997 | SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv, | ||
998 | SK_ADDR_LAST_MATCH_DRV); | ||
999 | } | ||
1000 | |||
1001 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
1002 | Inexact |= pAPort->InexactFilter.Bytes[i]; | ||
1003 | } | ||
1004 | |||
1005 | if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { | ||
1006 | |||
1007 | /* Set all bits in 64-bit hash register. */ | ||
1008 | XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); | ||
1009 | |||
1010 | /* Enable Hashing */ | ||
1011 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1012 | } | ||
1013 | else if (Inexact != 0) { | ||
1014 | |||
1015 | /* Set 64-bit hash register to InexactFilter. */ | ||
1016 | XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]); | ||
1017 | |||
1018 | /* Enable Hashing */ | ||
1019 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1020 | } | ||
1021 | else { | ||
1022 | /* Disable Hashing */ | ||
1023 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1024 | } | ||
1025 | |||
1026 | if (pAPort->PromMode != SK_PROM_MODE_NONE) { | ||
1027 | (void) SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); | ||
1028 | } | ||
1029 | |||
1030 | /* Set port's current physical MAC address. */ | ||
1031 | OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; | ||
1032 | |||
1033 | XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); | ||
1034 | |||
1035 | #ifdef xDEBUG | ||
1036 | for (i = 0; i < pAPort->NextExactMatchRlmt; i++) { | ||
1037 | SK_U8 InAddr8[6]; | ||
1038 | SK_U16 *InAddr; | ||
1039 | |||
1040 | /* Get exact match address i from port PortNumber. */ | ||
1041 | InAddr = (SK_U16 *) &InAddr8[0]; | ||
1042 | |||
1043 | XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr); | ||
1044 | |||
1045 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1046 | ("SkAddrXmacMcUpdate: MC address %d on Port %u: ", | ||
1047 | "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n", | ||
1048 | i, | ||
1049 | PortNumber, | ||
1050 | InAddr8[0], | ||
1051 | InAddr8[1], | ||
1052 | InAddr8[2], | ||
1053 | InAddr8[3], | ||
1054 | InAddr8[4], | ||
1055 | InAddr8[5], | ||
1056 | pAPort->Exact[i].a[0], | ||
1057 | pAPort->Exact[i].a[1], | ||
1058 | pAPort->Exact[i].a[2], | ||
1059 | pAPort->Exact[i].a[3], | ||
1060 | pAPort->Exact[i].a[4], | ||
1061 | pAPort->Exact[i].a[5])) | ||
1062 | } | ||
1063 | #endif /* DEBUG */ | ||
1064 | |||
1065 | /* Determine return value. */ | ||
1066 | if (Inexact == 0 && pAPort->PromMode == 0) { | ||
1067 | return (SK_MC_FILTERING_EXACT); | ||
1068 | } | ||
1069 | else { | ||
1070 | return (SK_MC_FILTERING_INEXACT); | ||
1071 | } | ||
1072 | |||
1073 | } /* SkAddrXmacMcUpdate */ | ||
1074 | |||
1075 | #endif /* GENESIS */ | ||
1076 | |||
1077 | #ifdef YUKON | ||
1078 | |||
1079 | /****************************************************************************** | ||
1080 | * | ||
1081 | * SkAddrGmacMcUpdate - update the HW MC address table and set the MAC address | ||
1082 | * | ||
1083 | * Description: | ||
1084 | * This routine enables reception of the addresses contained in a local | ||
1085 | * table for a given port. | ||
1086 | * It also programs the port's current physical MAC address. | ||
1087 | * | ||
1088 | * Notes: | ||
1089 | * The return code is only valid for SK_PROM_MODE_NONE. | ||
1090 | * | ||
1091 | * Context: | ||
1092 | * runtime, pageable | ||
1093 | * may be called after SK_INIT_IO | ||
1094 | * | ||
1095 | * Returns: | ||
1096 | * SK_MC_FILTERING_EXACT | ||
1097 | * SK_MC_FILTERING_INEXACT | ||
1098 | * SK_ADDR_ILLEGAL_PORT | ||
1099 | */ | ||
1100 | static int SkAddrGmacMcUpdate( | ||
1101 | SK_AC *pAC, /* adapter context */ | ||
1102 | SK_IOC IoC, /* I/O context */ | ||
1103 | SK_U32 PortNumber) /* Port Number */ | ||
1104 | { | ||
1105 | #ifndef SK_SLIM | ||
1106 | SK_U32 i; | ||
1107 | SK_U8 Inexact; | ||
1108 | #endif /* not SK_SLIM */ | ||
1109 | SK_U16 *OutAddr; | ||
1110 | SK_ADDR_PORT *pAPort; | ||
1111 | |||
1112 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1113 | ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)) | ||
1114 | |||
1115 | pAPort = &pAC->Addr.Port[PortNumber]; | ||
1116 | |||
1117 | #ifdef DEBUG | ||
1118 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1119 | ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) | ||
1120 | #endif /* DEBUG */ | ||
1121 | |||
1122 | #ifndef SK_SLIM | ||
1123 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
1124 | Inexact |= pAPort->InexactFilter.Bytes[i]; | ||
1125 | } | ||
1126 | |||
1127 | /* Set 64-bit hash register to InexactFilter. */ | ||
1128 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, | ||
1129 | &pAPort->InexactFilter.Bytes[0]); | ||
1130 | |||
1131 | if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { | ||
1132 | |||
1133 | /* Set all bits in 64-bit hash register. */ | ||
1134 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); | ||
1135 | |||
1136 | /* Enable Hashing */ | ||
1137 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1138 | } | ||
1139 | else { | ||
1140 | /* Enable Hashing. */ | ||
1141 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1142 | } | ||
1143 | |||
1144 | if (pAPort->PromMode != SK_PROM_MODE_NONE) { | ||
1145 | (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); | ||
1146 | } | ||
1147 | #else /* SK_SLIM */ | ||
1148 | |||
1149 | /* Set all bits in 64-bit hash register. */ | ||
1150 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); | ||
1151 | |||
1152 | /* Enable Hashing */ | ||
1153 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1154 | |||
1155 | (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); | ||
1156 | |||
1157 | #endif /* SK_SLIM */ | ||
1158 | |||
1159 | /* Set port's current physical MAC address. */ | ||
1160 | OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; | ||
1161 | GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); | ||
1162 | |||
1163 | /* Set port's current logical MAC address. */ | ||
1164 | OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0]; | ||
1165 | GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr); | ||
1166 | |||
1167 | #ifdef DEBUG | ||
1168 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1169 | ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1170 | pAPort->Exact[0].a[0], | ||
1171 | pAPort->Exact[0].a[1], | ||
1172 | pAPort->Exact[0].a[2], | ||
1173 | pAPort->Exact[0].a[3], | ||
1174 | pAPort->Exact[0].a[4], | ||
1175 | pAPort->Exact[0].a[5])) | ||
1176 | |||
1177 | SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1178 | ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1179 | pAPort->CurrentMacAddress.a[0], | ||
1180 | pAPort->CurrentMacAddress.a[1], | ||
1181 | pAPort->CurrentMacAddress.a[2], | ||
1182 | pAPort->CurrentMacAddress.a[3], | ||
1183 | pAPort->CurrentMacAddress.a[4], | ||
1184 | pAPort->CurrentMacAddress.a[5])) | ||
1185 | #endif /* DEBUG */ | ||
1186 | |||
1187 | #ifndef SK_SLIM | ||
1188 | /* Determine return value. */ | ||
1189 | if (Inexact == 0 && pAPort->PromMode == 0) { | ||
1190 | return (SK_MC_FILTERING_EXACT); | ||
1191 | } | ||
1192 | else { | ||
1193 | return (SK_MC_FILTERING_INEXACT); | ||
1194 | } | ||
1195 | #else /* SK_SLIM */ | ||
1196 | return (SK_MC_FILTERING_INEXACT); | ||
1197 | #endif /* SK_SLIM */ | ||
1198 | |||
1199 | } /* SkAddrGmacMcUpdate */ | ||
1200 | |||
1201 | #endif /* YUKON */ | ||
1202 | |||
1203 | #ifndef SK_NO_MAO | ||
1204 | |||
1205 | /****************************************************************************** | ||
1206 | * | ||
1207 | * SkAddrOverride - override a port's MAC address | ||
1208 | * | ||
1209 | * Description: | ||
1210 | * This routine overrides the MAC address of one port. | ||
1211 | * | ||
1212 | * Context: | ||
1213 | * runtime, pageable | ||
1214 | * may be called after SK_INIT_IO | ||
1215 | * | ||
1216 | * Returns: | ||
1217 | * SK_ADDR_SUCCESS if successful. | ||
1218 | * SK_ADDR_DUPLICATE_ADDRESS if duplicate MAC address. | ||
1219 | * SK_ADDR_MULTICAST_ADDRESS if multicast or broadcast address. | ||
1220 | * SK_ADDR_TOO_EARLY if SK_INIT_IO was not executed before. | ||
1221 | */ | ||
1222 | int SkAddrOverride( | ||
1223 | SK_AC *pAC, /* adapter context */ | ||
1224 | SK_IOC IoC, /* I/O context */ | ||
1225 | SK_U32 PortNumber, /* Port Number */ | ||
1226 | SK_MAC_ADDR SK_FAR *pNewAddr, /* new MAC address */ | ||
1227 | int Flags) /* logical/physical MAC address */ | ||
1228 | { | ||
1229 | #ifndef SK_NO_RLMT | ||
1230 | SK_EVPARA Para; | ||
1231 | #endif /* !SK_NO_RLMT */ | ||
1232 | SK_U32 NetNumber; | ||
1233 | SK_U32 i; | ||
1234 | SK_U16 SK_FAR *OutAddr; | ||
1235 | |||
1236 | #ifndef SK_NO_RLMT | ||
1237 | NetNumber = pAC->Rlmt.Port[PortNumber].Net->NetNumber; | ||
1238 | #else | ||
1239 | NetNumber = 0; | ||
1240 | #endif /* SK_NO_RLMT */ | ||
1241 | #if (!defined(SK_SLIM) || defined(DEBUG)) | ||
1242 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1243 | return (SK_ADDR_ILLEGAL_PORT); | ||
1244 | } | ||
1245 | #endif /* !SK_SLIM || DEBUG */ | ||
1246 | if (pNewAddr != NULL && (pNewAddr->a[0] & SK_MC_BIT) != 0) { | ||
1247 | return (SK_ADDR_MULTICAST_ADDRESS); | ||
1248 | } | ||
1249 | |||
1250 | if (!pAC->Addr.Net[NetNumber].CurrentMacAddressSet) { | ||
1251 | return (SK_ADDR_TOO_EARLY); | ||
1252 | } | ||
1253 | |||
1254 | if (Flags & SK_ADDR_SET_LOGICAL) { /* Activate logical MAC address. */ | ||
1255 | /* Parameter *pNewAddr is ignored. */ | ||
1256 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1257 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1258 | return (SK_ADDR_TOO_EARLY); | ||
1259 | } | ||
1260 | } | ||
1261 | #ifndef SK_NO_RLMT | ||
1262 | /* Set PortNumber to number of net's active port. */ | ||
1263 | PortNumber = pAC->Rlmt.Net[NetNumber]. | ||
1264 | Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; | ||
1265 | #endif /* !SK_NO_RLMT */ | ||
1266 | pAC->Addr.Port[PortNumber].Exact[0] = | ||
1267 | pAC->Addr.Net[NetNumber].CurrentMacAddress; | ||
1268 | |||
1269 | /* Write address to first exact match entry of active port. */ | ||
1270 | (void) SkAddrMcUpdate(pAC, IoC, PortNumber); | ||
1271 | } | ||
1272 | else if (Flags & SK_ADDR_CLEAR_LOGICAL) { | ||
1273 | /* Deactivate logical MAC address. */ | ||
1274 | /* Parameter *pNewAddr is ignored. */ | ||
1275 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1276 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1277 | return (SK_ADDR_TOO_EARLY); | ||
1278 | } | ||
1279 | } | ||
1280 | #ifndef SK_NO_RLMT | ||
1281 | /* Set PortNumber to number of net's active port. */ | ||
1282 | PortNumber = pAC->Rlmt.Net[NetNumber]. | ||
1283 | Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; | ||
1284 | #endif /* !SK_NO_RLMT */ | ||
1285 | for (i = 0; i < SK_MAC_ADDR_LEN; i++ ) { | ||
1286 | pAC->Addr.Port[PortNumber].Exact[0].a[i] = 0; | ||
1287 | } | ||
1288 | |||
1289 | /* Write address to first exact match entry of active port. */ | ||
1290 | (void) SkAddrMcUpdate(pAC, IoC, PortNumber); | ||
1291 | } | ||
1292 | else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */ | ||
1293 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1294 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { | ||
1295 | return (SK_ADDR_DUPLICATE_ADDRESS); | ||
1296 | } | ||
1297 | |||
1298 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1299 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1300 | return (SK_ADDR_TOO_EARLY); | ||
1301 | } | ||
1302 | |||
1303 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1304 | pAC->Addr.Port[i].CurrentMacAddress.a)) { | ||
1305 | if (i == PortNumber) { | ||
1306 | return (SK_ADDR_SUCCESS); | ||
1307 | } | ||
1308 | else { | ||
1309 | return (SK_ADDR_DUPLICATE_ADDRESS); | ||
1310 | } | ||
1311 | } | ||
1312 | } | ||
1313 | |||
1314 | pAC->Addr.Port[PortNumber].PreviousMacAddress = | ||
1315 | pAC->Addr.Port[PortNumber].CurrentMacAddress; | ||
1316 | pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; | ||
1317 | |||
1318 | /* Change port's physical MAC address. */ | ||
1319 | OutAddr = (SK_U16 SK_FAR *) pNewAddr; | ||
1320 | #ifdef GENESIS | ||
1321 | if (pAC->GIni.GIGenesis) { | ||
1322 | XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); | ||
1323 | } | ||
1324 | #endif /* GENESIS */ | ||
1325 | #ifdef YUKON | ||
1326 | if (!pAC->GIni.GIGenesis) { | ||
1327 | GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); | ||
1328 | } | ||
1329 | #endif /* YUKON */ | ||
1330 | |||
1331 | #ifndef SK_NO_RLMT | ||
1332 | /* Report address change to RLMT. */ | ||
1333 | Para.Para32[0] = PortNumber; | ||
1334 | Para.Para32[0] = -1; | ||
1335 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); | ||
1336 | #endif /* !SK_NO_RLMT */ | ||
1337 | } | ||
1338 | else { /* Logical MAC address. */ | ||
1339 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1340 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { | ||
1341 | return (SK_ADDR_SUCCESS); | ||
1342 | } | ||
1343 | |||
1344 | for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { | ||
1345 | if (!pAC->Addr.Port[i].CurrentMacAddressSet) { | ||
1346 | return (SK_ADDR_TOO_EARLY); | ||
1347 | } | ||
1348 | |||
1349 | if (SK_ADDR_EQUAL(pNewAddr->a, | ||
1350 | pAC->Addr.Port[i].CurrentMacAddress.a)) { | ||
1351 | return (SK_ADDR_DUPLICATE_ADDRESS); | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1355 | /* | ||
1356 | * In case that the physical and the logical MAC addresses are equal | ||
1357 | * we must also change the physical MAC address here. | ||
1358 | * In this case we have an adapter which initially was programmed with | ||
1359 | * two identical MAC addresses. | ||
1360 | */ | ||
1361 | if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a, | ||
1362 | pAC->Addr.Port[PortNumber].Exact[0].a)) { | ||
1363 | |||
1364 | pAC->Addr.Port[PortNumber].PreviousMacAddress = | ||
1365 | pAC->Addr.Port[PortNumber].CurrentMacAddress; | ||
1366 | pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; | ||
1367 | |||
1368 | #ifndef SK_NO_RLMT | ||
1369 | /* Report address change to RLMT. */ | ||
1370 | Para.Para32[0] = PortNumber; | ||
1371 | Para.Para32[0] = -1; | ||
1372 | SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); | ||
1373 | #endif /* !SK_NO_RLMT */ | ||
1374 | } | ||
1375 | |||
1376 | #ifndef SK_NO_RLMT | ||
1377 | /* Set PortNumber to number of net's active port. */ | ||
1378 | PortNumber = pAC->Rlmt.Net[NetNumber]. | ||
1379 | Port[pAC->Addr.Net[NetNumber].ActivePort]->PortNumber; | ||
1380 | #endif /* !SK_NO_RLMT */ | ||
1381 | pAC->Addr.Net[NetNumber].CurrentMacAddress = *pNewAddr; | ||
1382 | pAC->Addr.Port[PortNumber].Exact[0] = *pNewAddr; | ||
1383 | #ifdef DEBUG | ||
1384 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1385 | ("SkAddrOverride: Permanent MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1386 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[0], | ||
1387 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[1], | ||
1388 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2], | ||
1389 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3], | ||
1390 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4], | ||
1391 | pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])) | ||
1392 | |||
1393 | SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, | ||
1394 | ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", | ||
1395 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0], | ||
1396 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[1], | ||
1397 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2], | ||
1398 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3], | ||
1399 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4], | ||
1400 | pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])) | ||
1401 | #endif /* DEBUG */ | ||
1402 | |||
1403 | /* Write address to first exact match entry of active port. */ | ||
1404 | (void) SkAddrMcUpdate(pAC, IoC, PortNumber); | ||
1405 | } | ||
1406 | |||
1407 | return (SK_ADDR_SUCCESS); | ||
1408 | |||
1409 | } /* SkAddrOverride */ | ||
1410 | |||
1411 | |||
1412 | #endif /* SK_NO_MAO */ | ||
1413 | |||
1414 | /****************************************************************************** | ||
1415 | * | ||
1416 | * SkAddrPromiscuousChange - set promiscuous mode for given port | ||
1417 | * | ||
1418 | * Description: | ||
1419 | * This routine manages promiscuous mode: | ||
1420 | * - none | ||
1421 | * - all LLC frames | ||
1422 | * - all MC frames | ||
1423 | * | ||
1424 | * It calls either SkAddrXmacPromiscuousChange or | ||
1425 | * SkAddrGmacPromiscuousChange, according to the adapter in use. | ||
1426 | * The real work is done there. | ||
1427 | * | ||
1428 | * Context: | ||
1429 | * runtime, pageable | ||
1430 | * may be called after SK_INIT_IO | ||
1431 | * | ||
1432 | * Returns: | ||
1433 | * SK_ADDR_SUCCESS | ||
1434 | * SK_ADDR_ILLEGAL_PORT | ||
1435 | */ | ||
1436 | int SkAddrPromiscuousChange( | ||
1437 | SK_AC *pAC, /* adapter context */ | ||
1438 | SK_IOC IoC, /* I/O context */ | ||
1439 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1440 | int NewPromMode) /* new promiscuous mode */ | ||
1441 | { | ||
1442 | int ReturnCode = 0; | ||
1443 | #if (!defined(SK_SLIM) || defined(DEBUG)) | ||
1444 | if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1445 | return (SK_ADDR_ILLEGAL_PORT); | ||
1446 | } | ||
1447 | #endif /* !SK_SLIM || DEBUG */ | ||
1448 | |||
1449 | #ifdef GENESIS | ||
1450 | if (pAC->GIni.GIGenesis) { | ||
1451 | ReturnCode = | ||
1452 | SkAddrXmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); | ||
1453 | } | ||
1454 | #endif /* GENESIS */ | ||
1455 | #ifdef YUKON | ||
1456 | if (!pAC->GIni.GIGenesis) { | ||
1457 | ReturnCode = | ||
1458 | SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, NewPromMode); | ||
1459 | } | ||
1460 | #endif /* YUKON */ | ||
1461 | |||
1462 | return (ReturnCode); | ||
1463 | |||
1464 | } /* SkAddrPromiscuousChange */ | ||
1465 | |||
1466 | #ifdef GENESIS | ||
1467 | |||
1468 | /****************************************************************************** | ||
1469 | * | ||
1470 | * SkAddrXmacPromiscuousChange - set promiscuous mode for given port | ||
1471 | * | ||
1472 | * Description: | ||
1473 | * This routine manages promiscuous mode: | ||
1474 | * - none | ||
1475 | * - all LLC frames | ||
1476 | * - all MC frames | ||
1477 | * | ||
1478 | * Context: | ||
1479 | * runtime, pageable | ||
1480 | * may be called after SK_INIT_IO | ||
1481 | * | ||
1482 | * Returns: | ||
1483 | * SK_ADDR_SUCCESS | ||
1484 | * SK_ADDR_ILLEGAL_PORT | ||
1485 | */ | ||
1486 | static int SkAddrXmacPromiscuousChange( | ||
1487 | SK_AC *pAC, /* adapter context */ | ||
1488 | SK_IOC IoC, /* I/O context */ | ||
1489 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1490 | int NewPromMode) /* new promiscuous mode */ | ||
1491 | { | ||
1492 | int i; | ||
1493 | SK_BOOL InexactModeBit; | ||
1494 | SK_U8 Inexact; | ||
1495 | SK_U8 HwInexact; | ||
1496 | SK_FILTER64 HwInexactFilter; | ||
1497 | SK_U16 LoMode; /* Lower 16 bits of XMAC Mode Register. */ | ||
1498 | int CurPromMode = SK_PROM_MODE_NONE; | ||
1499 | |||
1500 | /* Read CurPromMode from Hardware. */ | ||
1501 | XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); | ||
1502 | |||
1503 | if ((LoMode & XM_MD_ENA_PROM) != 0) { | ||
1504 | /* Promiscuous mode! */ | ||
1505 | CurPromMode |= SK_PROM_MODE_LLC; | ||
1506 | } | ||
1507 | |||
1508 | for (Inexact = 0xFF, i = 0; i < 8; i++) { | ||
1509 | Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; | ||
1510 | } | ||
1511 | if (Inexact == 0xFF) { | ||
1512 | CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); | ||
1513 | } | ||
1514 | else { | ||
1515 | /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */ | ||
1516 | XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); | ||
1517 | |||
1518 | InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0; | ||
1519 | |||
1520 | /* Read 64-bit hash register from XMAC */ | ||
1521 | XM_INHASH(IoC, PortNumber, XM_HSM, &HwInexactFilter.Bytes[0]); | ||
1522 | |||
1523 | for (HwInexact = 0xFF, i = 0; i < 8; i++) { | ||
1524 | HwInexact &= HwInexactFilter.Bytes[i]; | ||
1525 | } | ||
1526 | |||
1527 | if (InexactModeBit && (HwInexact == 0xFF)) { | ||
1528 | CurPromMode |= SK_PROM_MODE_ALL_MC; | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | pAC->Addr.Port[PortNumber].PromMode = NewPromMode; | ||
1533 | |||
1534 | if (NewPromMode == CurPromMode) { | ||
1535 | return (SK_ADDR_SUCCESS); | ||
1536 | } | ||
1537 | |||
1538 | if ((NewPromMode & SK_PROM_MODE_ALL_MC) && | ||
1539 | !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */ | ||
1540 | |||
1541 | /* Set all bits in 64-bit hash register. */ | ||
1542 | XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); | ||
1543 | |||
1544 | /* Enable Hashing */ | ||
1545 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1546 | } | ||
1547 | else if ((CurPromMode & SK_PROM_MODE_ALL_MC) && | ||
1548 | !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm MC. */ | ||
1549 | for (Inexact = 0, i = 0; i < 8; i++) { | ||
1550 | Inexact |= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; | ||
1551 | } | ||
1552 | if (Inexact == 0) { | ||
1553 | /* Disable Hashing */ | ||
1554 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1555 | } | ||
1556 | else { | ||
1557 | /* Set 64-bit hash register to InexactFilter. */ | ||
1558 | XM_OUTHASH(IoC, PortNumber, XM_HSM, | ||
1559 | &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); | ||
1560 | |||
1561 | /* Enable Hashing */ | ||
1562 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1563 | } | ||
1564 | } | ||
1565 | |||
1566 | if ((NewPromMode & SK_PROM_MODE_LLC) && | ||
1567 | !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ | ||
1568 | /* Set the MAC in Promiscuous Mode */ | ||
1569 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1570 | } | ||
1571 | else if ((CurPromMode & SK_PROM_MODE_LLC) && | ||
1572 | !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC. */ | ||
1573 | /* Clear Promiscuous Mode */ | ||
1574 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1575 | } | ||
1576 | |||
1577 | return (SK_ADDR_SUCCESS); | ||
1578 | |||
1579 | } /* SkAddrXmacPromiscuousChange */ | ||
1580 | |||
1581 | #endif /* GENESIS */ | ||
1582 | |||
1583 | #ifdef YUKON | ||
1584 | |||
1585 | /****************************************************************************** | ||
1586 | * | ||
1587 | * SkAddrGmacPromiscuousChange - set promiscuous mode for given port | ||
1588 | * | ||
1589 | * Description: | ||
1590 | * This routine manages promiscuous mode: | ||
1591 | * - none | ||
1592 | * - all LLC frames | ||
1593 | * - all MC frames | ||
1594 | * | ||
1595 | * Context: | ||
1596 | * runtime, pageable | ||
1597 | * may be called after SK_INIT_IO | ||
1598 | * | ||
1599 | * Returns: | ||
1600 | * SK_ADDR_SUCCESS | ||
1601 | * SK_ADDR_ILLEGAL_PORT | ||
1602 | */ | ||
1603 | static int SkAddrGmacPromiscuousChange( | ||
1604 | SK_AC *pAC, /* adapter context */ | ||
1605 | SK_IOC IoC, /* I/O context */ | ||
1606 | SK_U32 PortNumber, /* port whose promiscuous mode changes */ | ||
1607 | int NewPromMode) /* new promiscuous mode */ | ||
1608 | { | ||
1609 | SK_U16 ReceiveControl; /* GMAC Receive Control Register */ | ||
1610 | int CurPromMode = SK_PROM_MODE_NONE; | ||
1611 | |||
1612 | /* Read CurPromMode from Hardware. */ | ||
1613 | GM_IN16(IoC, PortNumber, GM_RX_CTRL, &ReceiveControl); | ||
1614 | |||
1615 | if ((ReceiveControl & (GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)) == 0) { | ||
1616 | /* Promiscuous mode! */ | ||
1617 | CurPromMode |= SK_PROM_MODE_LLC; | ||
1618 | } | ||
1619 | |||
1620 | if ((ReceiveControl & GM_RXCR_MCF_ENA) == 0) { | ||
1621 | /* All Multicast mode! */ | ||
1622 | CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); | ||
1623 | } | ||
1624 | |||
1625 | pAC->Addr.Port[PortNumber].PromMode = NewPromMode; | ||
1626 | |||
1627 | if (NewPromMode == CurPromMode) { | ||
1628 | return (SK_ADDR_SUCCESS); | ||
1629 | } | ||
1630 | |||
1631 | if ((NewPromMode & SK_PROM_MODE_ALL_MC) && | ||
1632 | !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */ | ||
1633 | |||
1634 | /* Set all bits in 64-bit hash register. */ | ||
1635 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); | ||
1636 | |||
1637 | /* Enable Hashing */ | ||
1638 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1639 | } | ||
1640 | |||
1641 | if ((CurPromMode & SK_PROM_MODE_ALL_MC) && | ||
1642 | !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */ | ||
1643 | |||
1644 | /* Set 64-bit hash register to InexactFilter. */ | ||
1645 | GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, | ||
1646 | &pAC->Addr.Port[PortNumber].InexactFilter.Bytes[0]); | ||
1647 | |||
1648 | /* Enable Hashing. */ | ||
1649 | SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1650 | } | ||
1651 | |||
1652 | if ((NewPromMode & SK_PROM_MODE_LLC) && | ||
1653 | !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ | ||
1654 | |||
1655 | /* Set the MAC to Promiscuous Mode. */ | ||
1656 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); | ||
1657 | } | ||
1658 | else if ((CurPromMode & SK_PROM_MODE_LLC) && | ||
1659 | !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ | ||
1660 | |||
1661 | /* Clear Promiscuous Mode. */ | ||
1662 | SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); | ||
1663 | } | ||
1664 | |||
1665 | return (SK_ADDR_SUCCESS); | ||
1666 | |||
1667 | } /* SkAddrGmacPromiscuousChange */ | ||
1668 | |||
1669 | #endif /* YUKON */ | ||
1670 | |||
1671 | #ifndef SK_SLIM | ||
1672 | |||
1673 | /****************************************************************************** | ||
1674 | * | ||
1675 | * SkAddrSwap - swap address info | ||
1676 | * | ||
1677 | * Description: | ||
1678 | * This routine swaps address info of two ports. | ||
1679 | * | ||
1680 | * Context: | ||
1681 | * runtime, pageable | ||
1682 | * may be called after SK_INIT_IO | ||
1683 | * | ||
1684 | * Returns: | ||
1685 | * SK_ADDR_SUCCESS | ||
1686 | * SK_ADDR_ILLEGAL_PORT | ||
1687 | */ | ||
1688 | int SkAddrSwap( | ||
1689 | SK_AC *pAC, /* adapter context */ | ||
1690 | SK_IOC IoC, /* I/O context */ | ||
1691 | SK_U32 FromPortNumber, /* Port1 Index */ | ||
1692 | SK_U32 ToPortNumber) /* Port2 Index */ | ||
1693 | { | ||
1694 | int i; | ||
1695 | SK_U8 Byte; | ||
1696 | SK_MAC_ADDR MacAddr; | ||
1697 | SK_U32 DWord; | ||
1698 | |||
1699 | if (FromPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1700 | return (SK_ADDR_ILLEGAL_PORT); | ||
1701 | } | ||
1702 | |||
1703 | if (ToPortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { | ||
1704 | return (SK_ADDR_ILLEGAL_PORT); | ||
1705 | } | ||
1706 | |||
1707 | if (pAC->Rlmt.Port[FromPortNumber].Net != pAC->Rlmt.Port[ToPortNumber].Net) { | ||
1708 | return (SK_ADDR_ILLEGAL_PORT); | ||
1709 | } | ||
1710 | |||
1711 | /* | ||
1712 | * Swap: | ||
1713 | * - Exact Match Entries (GEnesis and Yukon) | ||
1714 | * Yukon uses first entry for the logical MAC | ||
1715 | * address (stored in the second GMAC register). | ||
1716 | * - FirstExactMatchRlmt (GEnesis only) | ||
1717 | * - NextExactMatchRlmt (GEnesis only) | ||
1718 | * - FirstExactMatchDrv (GEnesis only) | ||
1719 | * - NextExactMatchDrv (GEnesis only) | ||
1720 | * - 64-bit filter (InexactFilter) | ||
1721 | * - Promiscuous Mode | ||
1722 | * of ports. | ||
1723 | */ | ||
1724 | |||
1725 | for (i = 0; i < SK_ADDR_EXACT_MATCHES; i++) { | ||
1726 | MacAddr = pAC->Addr.Port[FromPortNumber].Exact[i]; | ||
1727 | pAC->Addr.Port[FromPortNumber].Exact[i] = | ||
1728 | pAC->Addr.Port[ToPortNumber].Exact[i]; | ||
1729 | pAC->Addr.Port[ToPortNumber].Exact[i] = MacAddr; | ||
1730 | } | ||
1731 | |||
1732 | for (i = 0; i < 8; i++) { | ||
1733 | Byte = pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i]; | ||
1734 | pAC->Addr.Port[FromPortNumber].InexactFilter.Bytes[i] = | ||
1735 | pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i]; | ||
1736 | pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte; | ||
1737 | } | ||
1738 | |||
1739 | i = pAC->Addr.Port[FromPortNumber].PromMode; | ||
1740 | pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode; | ||
1741 | pAC->Addr.Port[ToPortNumber].PromMode = i; | ||
1742 | |||
1743 | if (pAC->GIni.GIGenesis) { | ||
1744 | DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; | ||
1745 | pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = | ||
1746 | pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; | ||
1747 | pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord; | ||
1748 | |||
1749 | DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt; | ||
1750 | pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt = | ||
1751 | pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt; | ||
1752 | pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord; | ||
1753 | |||
1754 | DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv; | ||
1755 | pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv = | ||
1756 | pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv; | ||
1757 | pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord; | ||
1758 | |||
1759 | DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv; | ||
1760 | pAC->Addr.Port[FromPortNumber].NextExactMatchDrv = | ||
1761 | pAC->Addr.Port[ToPortNumber].NextExactMatchDrv; | ||
1762 | pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord; | ||
1763 | } | ||
1764 | |||
1765 | /* CAUTION: Solution works if only ports of one adapter are in use. */ | ||
1766 | for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber]. | ||
1767 | Net->NetNumber].NumPorts; i++) { | ||
1768 | if (pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. | ||
1769 | Port[i]->PortNumber == ToPortNumber) { | ||
1770 | pAC->Addr.Net[pAC->Rlmt.Port[ToPortNumber].Net->NetNumber]. | ||
1771 | ActivePort = i; | ||
1772 | /* 20001207 RA: Was "ToPortNumber;". */ | ||
1773 | } | ||
1774 | } | ||
1775 | |||
1776 | (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber); | ||
1777 | (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber); | ||
1778 | |||
1779 | return (SK_ADDR_SUCCESS); | ||
1780 | |||
1781 | } /* SkAddrSwap */ | ||
1782 | |||
1783 | #endif /* !SK_SLIM */ | ||
1784 | |||
1785 | #ifdef __cplusplus | ||
1786 | } | ||
1787 | #endif /* __cplusplus */ | ||
1788 | |||