40921aeff31f99f35c8e33714eb591b800ac8599
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * MACE Device-dependent code (some still lives in if_en.c):
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.
38 * (C) COPYRIGHT Apple Computer, Inc., 1994-1997
43 #include <machdep/ppc/dbdma.h>
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/errno.h>
48 #include <sys/socket.h>
50 #include <net/etherdefs.h>
51 #include <netinet/if_ether.h>
52 #include <sys/sockio.h>
53 #include <netinet/in_var.h>
54 #include <netinet/in.h>
56 #include <mach/mach_types.h>
57 #include <ppc/powermac.h>
58 #include <ppc/interrupts.h>
59 #include <ppc/proc_reg.h>
60 #include <libkern/libkern.h>
66 #define ENET_CRCPOLY 0x04c11db7
68 /* Real fast bit-reversal algorithm, 6-bit values */
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
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
;
87 nxtval
= ((nxtval
& 0x00FF) << 8) | (nxtval
>> 8);
89 /* Compute bit-by-bit */
90 for (counter
= 0; counter
!= 16; ++counter
)
91 { /* is high CRC bit set? */
92 if ((current
& 0x80000000) == NULL
)
97 current
= current
<< 1;
99 if ((nxtval
& 0x0001) == NULL
)
104 nxtval
= nxtval
>> 1;
107 if (highCRCBitSet
^ lowDataBitSet
)
108 current
= current
^ ENET_CRCPOLY
;
113 unsigned int mace_crc(unsigned short *address
)
114 { register unsigned int newcrc
;
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 */
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.
128 mace_addmulti(register struct ifreq
*ifr
, register struct arpcom
*ar
)
129 { register unsigned char *addr
;
133 addr
= ar
->ac_multiaddrs
->enm_addrlo
;
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 */
140 mask
= (unsigned char)1 << mask
;
141 mace
.multi_mask
[crc
/8] |= mask
;
146 mace_delmulti(register struct ifreq
*ifr
, register struct arpcom
*ar
,
147 struct ether_addr
* enaddr
)
148 { register unsigned char *addr
;
152 addr
= (char *)enaddr
; /* XXX assumes addrlo == addrhi */
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! */
160 if (--mace
.multi_use
[crc
])
161 return(0); /* That bit is still in use */
164 mask
= ((unsigned char)1 << mask
) ^ 0xff; /* To turn off bit */
165 mace
.multi_mask
[crc
/8] &= mask
;
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.
177 mace_sync_mcast(register struct ifnet
* ifp
)
178 { register unsigned long temp
, temp1
;
181 register struct mace_board
*ereg
= mace
.ereg
;
186 * Have to deal with early rev of chip for updating LAF
187 * Don't know if any MacOSX systems still run this rev.
189 if (mace
.chip_id
== MACERevA2
)
190 { /* First, turn off receiver */
191 temp1
= temp
&~MACCC_ENRCV
;
195 /* Then, check FIFO - frame being received will complete */
196 temp1
= ereg
->fifofc
;
198 mace
.ereg
->iac
= IAC_LOGADDR
;
201 { ereg
->iac
= IAC_ADDRCHG
|IAC_LOGADDR
;
204 while (temp1
= ereg
->iac
)
206 if ((temp1
&IAC_ADDRCHG
) == 0)
211 if (ifp
->if_flags
& IFF_ALLMULTI
) /* Then want ALL m-cast pkts */
212 { /* set mask to all 1's */
214 { ereg
->ladrf
= 0xff;
219 /* Assuming everything is big-endian */
220 for (i
=0, p
= &mace
.multi_mask
[0];i
<8;i
++)
221 { ereg
->ladrf
= *p
++;
226 ereg
->maccc
= temp
; /* Reset config ctrlr */
232 mace_sync_promisc(register struct ifnet
*ifp
)
234 register u_long o_maccc
, n_maccc
;
235 register struct mace_board
*ereg
= mace
.ereg
;
238 * Save current state and disable receive.
240 o_maccc
= ereg
->maccc
;
241 n_maccc
= o_maccc
& ~MACCC_ENRCV
;
242 ereg
->maccc
= n_maccc
;
246 * Calculate new desired state
248 if (ifp
->if_flags
& IFF_PROMISC
) {
249 /* set PROMISC bit */
250 o_maccc
|= MACCC_PROM
;
252 /* clear PROMISC bit */
253 o_maccc
&= ~MACCC_PROM
;
257 * Note that the "old" mode includes the new promiscuous state now.
259 ereg
->maccc
= o_maccc
;