|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * MACE Device-dependent code (some still lives in if_en.c):
27: *
28: * MACE Multicast Address scheme -
29: * Compute Enet CRC for each Mcast address; take high 6 bits of 32-bit
30: * crc, giving a "bit index" into a 64-bit register. On packet receipt,
31: * if corresponding bit is set, accept packet.
32: * We keep track of requests in a per-hash-value table (16-bit counters
33: * should be sufficient). Since we're hashing, we only care about the
34: * hash value of each address.
35: *
36: * Apple Confidential
37: *
38: * (C) COPYRIGHT Apple Computer, Inc., 1994-1997
39: * All Rights Reserved
40: *
41: * Justin C. Walker
42: */
43: #include <machdep/ppc/dbdma.h>
44:
45: #import <sys/types.h>
46: #import <sys/param.h>
47: #import <sys/errno.h>
48: #import <sys/socket.h>
49: #import <net/if.h>
50: #import <net/etherdefs.h>
51: #import <netinet/if_ether.h>
52: #import <sys/sockio.h>
53: #import <netinet/in_var.h>
54: #import <netinet/in.h>
55: #import <sys/mbuf.h>
56: #import <mach/mach_types.h>
57: #import <ppc/powermac.h>
58: #import <ppc/interrupts.h>
59: #import <ppc/proc_reg.h>
60: #include <libkern/libkern.h>
61: #import "if_en.h"
62: #import "mace.h"
63:
64: extern mace_t mace;
65:
66: #define ENET_CRCPOLY 0x04c11db7
67:
68: /* Real fast bit-reversal algorithm, 6-bit values */
69: int reverse6[] =
70: { 0x0,0x20,0x10,0x30,0x8,0x28,0x18,0x38,
71: 0x4,0x24,0x14,0x34,0xc,0x2c,0x1c,0x3c,
72: 0x2,0x22,0x12,0x32,0xa,0x2a,0x1a,0x3a,
73: 0x6,0x26,0x16,0x36,0xe,0x2e,0x1e,0x3e,
74: 0x1,0x21,0x11,0x31,0x9,0x29,0x19,0x39,
75: 0x5,0x25,0x15,0x35,0xd,0x2d,0x1d,0x3d,
76: 0x3,0x23,0x13,0x33,0xb,0x2b,0x1b,0x3b,
77: 0x7,0x27,0x17,0x37,0xf,0x2f,0x1f,0x3f
78: };
79:
80: unsigned int crc416(current, nxtval)
81: register unsigned int current;
82: register unsigned short nxtval;
83: { register unsigned int counter;
84: register int highCRCBitSet, lowDataBitSet;
85:
86: /* Swap bytes */
87: nxtval = ((nxtval & 0x00FF) << 8) | (nxtval >> 8);
88:
89: /* Compute bit-by-bit */
90: for (counter = 0; counter != 16; ++counter)
91: { /* is high CRC bit set? */
92: if ((current & 0x80000000) == NULL)
93: highCRCBitSet = 0;
94: else
95: highCRCBitSet = 1;
96:
97: current = current << 1;
98:
99: if ((nxtval & 0x0001) == NULL)
100: lowDataBitSet = 0;
101: else
102: lowDataBitSet = 1;
103:
104: nxtval = nxtval >> 1;
105:
106: /* do the XOR */
107: if (highCRCBitSet ^ lowDataBitSet)
108: current = current ^ ENET_CRCPOLY;
109: }
110: return current;
111: }
112:
113: unsigned int mace_crc(unsigned short *address)
114: { register unsigned int newcrc;
115:
116: newcrc = crc416(0xffffffff, *address); /* address bits 47 - 32 */
117: newcrc = crc416(newcrc, address[1]); /* address bits 31 - 16 */
118: newcrc = crc416(newcrc, address[2]); /* address bits 15 - 0 */
119:
120: return(newcrc);
121: }
122:
123: /*
124: * Add requested mcast addr to Mace's filter. Assume that the first
125: * address in the arpcom ac_multiaddrs list is the one we're interested in.
126: */
127: int
128: mace_addmulti(register struct ifreq *ifr, register struct arpcom *ar)
129: { register unsigned char *addr;
130: unsigned int crc;
131: unsigned char mask;
132:
133: addr = ar->ac_multiaddrs->enm_addrlo;
134:
135: crc = mace_crc((unsigned short *)addr)&0x3f; /* Big-endian alert! */
136: crc = reverse6[crc]; /* Hyperfast bit-reversing algorithm */
137: if (mace.multi_use[crc]++)
138: return(0); /* This bit is already set */
139: mask = crc % 8;
140: mask = (unsigned char)1 << mask;
141: mace.multi_mask[crc/8] |= mask;
142: return(1);
143: }
144:
145: int
146: mace_delmulti(register struct ifreq *ifr, register struct arpcom *ar,
147: struct ether_addr * enaddr)
148: { register unsigned char *addr;
149: unsigned int crc;
150: unsigned char mask;
151:
152: addr = (char *)enaddr; /* XXX assumes addrlo == addrhi */
153:
154: /* Now, delete the address from the filter copy, as indicated */
155: crc = mace_crc((unsigned short *)addr)&0x3f; /* Big-endian alert! */
156: crc = reverse6[crc]; /* Hyperfast bit-reversing algorithm */
157: if (mace.multi_use[crc] == 0)
158: return(EINVAL); /* That bit wasn't in use! */
159:
160: if (--mace.multi_use[crc])
161: return(0); /* That bit is still in use */
162:
163: mask = crc % 8;
164: mask = ((unsigned char)1 << mask) ^ 0xff; /* To turn off bit */
165: mace.multi_mask[crc/8] &= mask;
166: return(1);
167: }
168:
169: /*
170: * Sync the adapter with the software copy of the multicast mask
171: * (logical address filter).
172: * If we want all m-cast addresses, we just blast 1's into the filter.
173: * When we reverse this, we can use the current state of the (software)
174: * filter, which should have been kept up to date.
175: */
176: void
177: mace_sync_mcast(register struct ifnet * ifp)
178: { register unsigned long temp, temp1;
179: register int i;
180: register char *p;
181: register struct mace_board *ereg = mace.ereg;
182:
183: temp = ereg->maccc;
184:
185: /*
186: * Have to deal with early rev of chip for updating LAF
187: * Don't know if any Rhapsody systems still run this rev.
188: */
189: if (mace.chip_id == MACERevA2)
190: { /* First, turn off receiver */
191: temp1 = temp&~MACCC_ENRCV;
192: ereg->maccc = temp1;
193: eieio();
194:
195: /* Then, check FIFO - frame being received will complete */
196: temp1 = ereg->fifofc;
197:
198: mace.ereg->iac = IAC_LOGADDR;
199: eieio();
200: } else
201: { ereg->iac = IAC_ADDRCHG|IAC_LOGADDR;
202: eieio();
203:
204: while (temp1 = ereg->iac)
205: { eieio();
206: if ((temp1&IAC_ADDRCHG) == 0)
207: break;
208: }
209: }
210:
211: if (ifp->if_flags & IFF_ALLMULTI) /* Then want ALL m-cast pkts */
212: { /* set mask to all 1's */
213: for (i=0;i<8;i++)
214: { ereg->ladrf = 0xff;
215: eieio();
216: }
217: } else
218: {
219: /* Assuming everything is big-endian */
220: for (i=0, p = &mace.multi_mask[0];i<8;i++)
221: { ereg->ladrf = *p++;
222: eieio();
223: }
224: }
225:
226: ereg->maccc = temp; /* Reset config ctrlr */
227: eieio();
228:
229: }
230:
231: void
232: mace_sync_promisc(register struct ifnet *ifp)
233: {
234: register u_long o_maccc, n_maccc;
235: register struct mace_board *ereg = mace.ereg;
236:
237: /*
238: * Save current state and disable receive.
239: */
240: o_maccc = ereg->maccc;
241: n_maccc = o_maccc & ~MACCC_ENRCV;
242: ereg->maccc = n_maccc;
243: eieio();
244:
245: /*
246: * Calculate new desired state
247: */
248: if (ifp->if_flags & IFF_PROMISC) {
249: /* set PROMISC bit */
250: o_maccc |= MACCC_PROM;
251: } else {
252: /* clear PROMISC bit */
253: o_maccc &= ~MACCC_PROM;
254: }
255:
256: /*
257: * Note that the "old" mode includes the new promiscuous state now.
258: */
259: ereg->maccc = o_maccc;
260: eieio();
261: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.