Thu Jan 30 06:28:46 2020 UTC ()
Fix typo


(martin)
diff -r1.53 -r1.54 src/sys/arch/mac68k/dev/if_mc.c

cvs diff -r1.53 -r1.54 src/sys/arch/mac68k/dev/if_mc.c (switch to unified diff)

--- src/sys/arch/mac68k/dev/if_mc.c 2020/01/29 05:25:41 1.53
+++ src/sys/arch/mac68k/dev/if_mc.c 2020/01/30 06:28:46 1.54
@@ -1,728 +1,728 @@ @@ -1,728 +1,728 @@
1/* $NetBSD: if_mc.c,v 1.53 2020/01/29 05:25:41 thorpej Exp $ */ 1/* $NetBSD: if_mc.c,v 1.54 2020/01/30 06:28:46 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997 David Huang <khym@azeotrope.org> 4 * Copyright (c) 1997 David Huang <khym@azeotrope.org>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Portions of this code are based on code by Denton Gentry <denny1@home.com>, 7 * Portions of this code are based on code by Denton Gentry <denny1@home.com>,
8 * Charles M. Hannum, Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp>, and 8 * Charles M. Hannum, Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp>, and
9 * Jason R. Thorpe. 9 * Jason R. Thorpe.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. The name of the author may not be used to endorse or promote products 16 * 2. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission 17 * derived from this software without specific prior written permission
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * 29 *
30 */ 30 */
31 31
32/* 32/*
33 * Driver for the AMD Am79C940 (MACE) ethernet chip, used for onboard 33 * Driver for the AMD Am79C940 (MACE) ethernet chip, used for onboard
34 * ethernet on the Centris/Quadra 660av and Quadra 840av. 34 * ethernet on the Centris/Quadra 660av and Quadra 840av.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: if_mc.c,v 1.53 2020/01/29 05:25:41 thorpej Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: if_mc.c,v 1.54 2020/01/30 06:28:46 martin Exp $");
39 39
40#include "opt_ddb.h" 40#include "opt_ddb.h"
41#include "opt_inet.h" 41#include "opt_inet.h"
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/mbuf.h> 45#include <sys/mbuf.h>
46#include <sys/buf.h> 46#include <sys/buf.h>
47#include <sys/protosw.h> 47#include <sys/protosw.h>
48#include <sys/socket.h> 48#include <sys/socket.h>
49#include <sys/syslog.h> 49#include <sys/syslog.h>
50#include <sys/ioctl.h> 50#include <sys/ioctl.h>
51#include <sys/errno.h> 51#include <sys/errno.h>
52#include <sys/device.h> 52#include <sys/device.h>
53 53
54#include <uvm/uvm_extern.h> 54#include <uvm/uvm_extern.h>
55 55
56#include <net/if.h> 56#include <net/if.h>
57#include <net/if_dl.h> 57#include <net/if_dl.h>
58#include <net/if_ether.h> 58#include <net/if_ether.h>
59#include <net/bpf.h> 59#include <net/bpf.h>
60 60
61#ifdef INET 61#ifdef INET
62#include <netinet/in.h> 62#include <netinet/in.h>
63#include <netinet/if_inarp.h> 63#include <netinet/if_inarp.h>
64#include <netinet/in_systm.h> 64#include <netinet/in_systm.h>
65#include <netinet/in_var.h> 65#include <netinet/in_var.h>
66#include <netinet/ip.h> 66#include <netinet/ip.h>
67#endif 67#endif
68 68
69#include <machine/bus.h> 69#include <machine/bus.h>
70#include <mac68k/dev/if_mcreg.h> 70#include <mac68k/dev/if_mcreg.h>
71#include <mac68k/dev/if_mcvar.h> 71#include <mac68k/dev/if_mcvar.h>
72 72
73hide void mcwatchdog(struct ifnet *); 73hide void mcwatchdog(struct ifnet *);
74hide int mcinit(struct mc_softc *); 74hide int mcinit(struct mc_softc *);
75hide int mcstop(struct mc_softc *); 75hide int mcstop(struct mc_softc *);
76hide int mcioctl(struct ifnet *, u_long, void *); 76hide int mcioctl(struct ifnet *, u_long, void *);
77hide void mcstart(struct ifnet *); 77hide void mcstart(struct ifnet *);
78hide void mcreset(struct mc_softc *); 78hide void mcreset(struct mc_softc *);
79 79
80integrate u_int maceput(struct mc_softc *, struct mbuf *); 80integrate u_int maceput(struct mc_softc *, struct mbuf *);
81integrate void mc_tint(struct mc_softc *); 81integrate void mc_tint(struct mc_softc *);
82integrate void mace_read(struct mc_softc *, void *, int); 82integrate void mace_read(struct mc_softc *, void *, int);
83integrate struct mbuf *mace_get(struct mc_softc *, void *, int); 83integrate struct mbuf *mace_get(struct mc_softc *, void *, int);
84static void mace_calcladrf(struct ethercom *, uint8_t *); 84static void mace_calcladrf(struct ethercom *, uint8_t *);
85static inline uint16_t ether_cmp(void *, void *); 85static inline uint16_t ether_cmp(void *, void *);
86 86
87 87
88/* 88/*
89 * Compare two Ether/802 addresses for equality, inlined and 89 * Compare two Ether/802 addresses for equality, inlined and
90 * unrolled for speed. Use this like memcmp(). 90 * unrolled for speed. Use this like memcmp().
91 * 91 *
92 * XXX: Add <machine/inlines.h> for stuff like this? 92 * XXX: Add <machine/inlines.h> for stuff like this?
93 * XXX: or maybe add it to libkern.h instead? 93 * XXX: or maybe add it to libkern.h instead?
94 * 94 *
95 * "I'd love to have an inline assembler version of this." 95 * "I'd love to have an inline assembler version of this."
96 * XXX: Who wanted that? mycroft? I wrote one, but this 96 * XXX: Who wanted that? mycroft? I wrote one, but this
97 * version in C is as good as hand-coded assembly. -gwr 97 * version in C is as good as hand-coded assembly. -gwr
98 * 98 *
99 * Please do NOT tweak this without looking at the actual 99 * Please do NOT tweak this without looking at the actual
100 * assembly code generated before and after your tweaks! 100 * assembly code generated before and after your tweaks!
101 */ 101 */
102static inline uint16_t 102static inline uint16_t
103ether_cmp(void *one, void *two) 103ether_cmp(void *one, void *two)
104{ 104{
105 uint16_t *a = (u_short *) one; 105 uint16_t *a = (u_short *) one;
106 uint16_t *b = (u_short *) two; 106 uint16_t *b = (u_short *) two;
107 uint16_t diff; 107 uint16_t diff;
108 108
109#ifdef m68k 109#ifdef m68k
110 /* 110 /*
111 * The post-increment-pointer form produces the best 111 * The post-increment-pointer form produces the best
112 * machine code for m68k. This was carefully tuned 112 * machine code for m68k. This was carefully tuned
113 * so it compiles to just 8 short (2-byte) op-codes! 113 * so it compiles to just 8 short (2-byte) op-codes!
114 */ 114 */
115 diff = *a++ - *b++; 115 diff = *a++ - *b++;
116 diff |= *a++ - *b++; 116 diff |= *a++ - *b++;
117 diff |= *a++ - *b++; 117 diff |= *a++ - *b++;
118#else 118#else
119 /* 119 /*
120 * Most modern CPUs do better with a single expression. 120 * Most modern CPUs do better with a single expression.
121 * Note that short-cut evaluation is NOT helpful here, 121 * Note that short-cut evaluation is NOT helpful here,
122 * because it just makes the code longer, not faster! 122 * because it just makes the code longer, not faster!
123 */ 123 */
124 diff = (a[0] - b[0]) | (a[1] - b[1]) | (a[2] - b[2]); 124 diff = (a[0] - b[0]) | (a[1] - b[1]) | (a[2] - b[2]);
125#endif 125#endif
126 126
127 return diff; 127 return diff;
128} 128}
129 129
130#define ETHER_CMP ether_cmp 130#define ETHER_CMP ether_cmp
131 131
132/* 132/*
133 * Interface exists: make available by filling in network interface 133 * Interface exists: make available by filling in network interface
134 * record. System will initialize the interface when it is ready 134 * record. System will initialize the interface when it is ready
135 * to accept packets. 135 * to accept packets.
136 */ 136 */
137int 137int
138mcsetup(struct mc_softc *sc, uint8_t *lladdr) 138mcsetup(struct mc_softc *sc, uint8_t *lladdr)
139{ 139{
140 struct ifnet *ifp = &sc->sc_if; 140 struct ifnet *ifp = &sc->sc_if;
141 141
142 /* reset the chip and disable all interrupts */ 142 /* reset the chip and disable all interrupts */
143 NIC_PUT(sc, MACE_BIUCC, SWRST); 143 NIC_PUT(sc, MACE_BIUCC, SWRST);
144 DELAY(100); 144 DELAY(100);
145 NIC_PUT(sc, MACE_IMR, ~0); 145 NIC_PUT(sc, MACE_IMR, ~0);
146 146
147 memcpy(sc->sc_enaddr, lladdr, ETHER_ADDR_LEN); 147 memcpy(sc->sc_enaddr, lladdr, ETHER_ADDR_LEN);
148 printf(": address %s\n", ether_sprintf(lladdr)); 148 printf(": address %s\n", ether_sprintf(lladdr));
149 149
150 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 150 memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
151 ifp->if_softc = sc; 151 ifp->if_softc = sc;
152 ifp->if_ioctl = mcioctl; 152 ifp->if_ioctl = mcioctl;
153 ifp->if_start = mcstart; 153 ifp->if_start = mcstart;
154 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 154 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
155 ifp->if_watchdog = mcwatchdog; 155 ifp->if_watchdog = mcwatchdog;
156 156
157 if_attach(ifp); 157 if_attach(ifp);
158 if_deferred_start_init(ifp, NULL); 158 if_deferred_start_init(ifp, NULL);
159 ether_ifattach(ifp, lladdr); 159 ether_ifattach(ifp, lladdr);
160 160
161 return 0; 161 return 0;
162} 162}
163 163
164hide int 164hide int
165mcioctl(struct ifnet *ifp, u_long cmd, void *data) 165mcioctl(struct ifnet *ifp, u_long cmd, void *data)
166{ 166{
167 struct mc_softc *sc = ifp->if_softc; 167 struct mc_softc *sc = ifp->if_softc;
168 struct ifaddr *ifa; 168 struct ifaddr *ifa;
169 169
170 int s = splnet(), err = 0; 170 int s = splnet(), err = 0;
171 171
172 switch (cmd) { 172 switch (cmd) {
173 173
174 case SIOCINITIFADDR: 174 case SIOCINITIFADDR:
175 ifa = (struct ifaddr *)data; 175 ifa = (struct ifaddr *)data;
176 ifp->if_flags |= IFF_UP; 176 ifp->if_flags |= IFF_UP;
177 mcinit(sc); 177 mcinit(sc);
178 switch (ifa->ifa_addr->sa_family) { 178 switch (ifa->ifa_addr->sa_family) {
179#ifdef INET 179#ifdef INET
180 case AF_INET: 180 case AF_INET:
181 arp_ifinit(ifp, ifa); 181 arp_ifinit(ifp, ifa);
182 break; 182 break;
183#endif 183#endif
184 default: 184 default:
185 break; 185 break;
186 } 186 }
187 break; 187 break;
188 188
189 case SIOCSIFFLAGS: 189 case SIOCSIFFLAGS:
190 if ((err = ifioctl_common(ifp, cmd, data)) != 0) 190 if ((err = ifioctl_common(ifp, cmd, data)) != 0)
191 break; 191 break;
192 /* XXX see the comment in ed_ioctl() about code re-use */ 192 /* XXX see the comment in ed_ioctl() about code re-use */
193 if ((ifp->if_flags & IFF_UP) == 0 && 193 if ((ifp->if_flags & IFF_UP) == 0 &&
194 (ifp->if_flags & IFF_RUNNING) != 0) { 194 (ifp->if_flags & IFF_RUNNING) != 0) {
195 /* 195 /*
196 * If interface is marked down and it is running, 196 * If interface is marked down and it is running,
197 * then stop it. 197 * then stop it.
198 */ 198 */
199 mcstop(sc); 199 mcstop(sc);
200 ifp->if_flags &= ~IFF_RUNNING; 200 ifp->if_flags &= ~IFF_RUNNING;
201 } else if ((ifp->if_flags & IFF_UP) != 0 && 201 } else if ((ifp->if_flags & IFF_UP) != 0 &&
202 (ifp->if_flags & IFF_RUNNING) == 0) { 202 (ifp->if_flags & IFF_RUNNING) == 0) {
203 /* 203 /*
204 * If interface is marked up and it is stopped, 204 * If interface is marked up and it is stopped,
205 * then start it. 205 * then start it.
206 */ 206 */
207 (void)mcinit(sc); 207 (void)mcinit(sc);
208 } else { 208 } else {
209 /* 209 /*
210 * reset the interface to pick up any other changes 210 * reset the interface to pick up any other changes
211 * in flags 211 * in flags
212 */ 212 */
213 mcreset(sc); 213 mcreset(sc);
214 mcstart(ifp); 214 mcstart(ifp);
215 } 215 }
216 break; 216 break;
217 217
218 case SIOCADDMULTI: 218 case SIOCADDMULTI:
219 case SIOCDELMULTI: 219 case SIOCDELMULTI:
220 if ((err = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 220 if ((err = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
221 /* 221 /*
222 * Multicast list has changed; set the hardware 222 * Multicast list has changed; set the hardware
223 * filter accordingly. But remember UP flag! 223 * filter accordingly. But remember UP flag!
224 */ 224 */
225 if (ifp->if_flags & IFF_RUNNING) 225 if (ifp->if_flags & IFF_RUNNING)
226 mcreset(sc); 226 mcreset(sc);
227 err = 0; 227 err = 0;
228 } 228 }
229 break; 229 break;
230 default: 230 default:
231 err = ether_ioctl(ifp, cmd, data); 231 err = ether_ioctl(ifp, cmd, data);
232 } 232 }
233 splx(s); 233 splx(s);
234 return err; 234 return err;
235} 235}
236 236
237/* 237/*
238 * Encapsulate a packet of type family for the local net. 238 * Encapsulate a packet of type family for the local net.
239 */ 239 */
240hide void 240hide void
241mcstart(struct ifnet *ifp) 241mcstart(struct ifnet *ifp)
242{ 242{
243 struct mc_softc *sc = ifp->if_softc; 243 struct mc_softc *sc = ifp->if_softc;
244 struct mbuf *m; 244 struct mbuf *m;
245 245
246 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 246 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
247 return; 247 return;
248 248
249 while (1) { 249 while (1) {
250 if (ifp->if_flags & IFF_OACTIVE) 250 if (ifp->if_flags & IFF_OACTIVE)
251 return; 251 return;
252 252
253 IF_DEQUEUE(&ifp->if_snd, m); 253 IF_DEQUEUE(&ifp->if_snd, m);
254 if (m == 0) 254 if (m == 0)
255 return; 255 return;
256 256
257 /* 257 /*
258 * If bpf is listening on this interface, let it 258 * If bpf is listening on this interface, let it
259 * see the packet before we commit it to the wire. 259 * see the packet before we commit it to the wire.
260 */ 260 */
261 bpf_mtap(ifp, m, BPF_D_OUT); 261 bpf_mtap(ifp, m, BPF_D_OUT);
262 262
263 /* 263 /*
264 * Copy the mbuf chain into the transmit buffer. 264 * Copy the mbuf chain into the transmit buffer.
265 */ 265 */
266 ifp->if_flags |= IFF_OACTIVE; 266 ifp->if_flags |= IFF_OACTIVE;
267 maceput(sc, m); 267 maceput(sc, m);
268 268
269 if_statinc(ifp, if_opackets); /* # of pkts */ 269 if_statinc(ifp, if_opackets); /* # of pkts */
270 } 270 }
271} 271}
272 272
273/* 273/*
274 * reset and restart the MACE. Called in case of fatal 274 * reset and restart the MACE. Called in case of fatal
275 * hardware/software errors. 275 * hardware/software errors.
276 */ 276 */
277hide void 277hide void
278mcreset(struct mc_softc *sc) 278mcreset(struct mc_softc *sc)
279{ 279{
280 mcstop(sc); 280 mcstop(sc);
281 mcinit(sc); 281 mcinit(sc);
282} 282}
283 283
284hide int 284hide int
285mcinit(struct mc_softc *sc) 285mcinit(struct mc_softc *sc)
286{ 286{
287 int s; 287 int s;
288 uint8_t maccc, ladrf[8]; 288 uint8_t maccc, ladrf[8];
289 289
290 if (sc->sc_if.if_flags & IFF_RUNNING) 290 if (sc->sc_if.if_flags & IFF_RUNNING)
291 /* already running */ 291 /* already running */
292 return 0; 292 return 0;
293 293
294 s = splnet(); 294 s = splnet();
295 295
296 NIC_PUT(sc, MACE_BIUCC, sc->sc_biucc); 296 NIC_PUT(sc, MACE_BIUCC, sc->sc_biucc);
297 NIC_PUT(sc, MACE_FIFOCC, sc->sc_fifocc); 297 NIC_PUT(sc, MACE_FIFOCC, sc->sc_fifocc);
298 NIC_PUT(sc, MACE_IMR, ~0); /* disable all interrupts */ 298 NIC_PUT(sc, MACE_IMR, ~0); /* disable all interrupts */
299 NIC_PUT(sc, MACE_PLSCC, sc->sc_plscc); 299 NIC_PUT(sc, MACE_PLSCC, sc->sc_plscc);
300 300
301 NIC_PUT(sc, MACE_UTR, RTRD); /* disable reserved test registers */ 301 NIC_PUT(sc, MACE_UTR, RTRD); /* disable reserved test registers */
302 302
303 /* set MAC address */ 303 /* set MAC address */
304 NIC_PUT(sc, MACE_IAC, ADDRCHG); 304 NIC_PUT(sc, MACE_IAC, ADDRCHG);
305 while (NIC_GET(sc, MACE_IAC) & ADDRCHG) 305 while (NIC_GET(sc, MACE_IAC) & ADDRCHG)
306 ; 306 ;
307 NIC_PUT(sc, MACE_IAC, PHYADDR); 307 NIC_PUT(sc, MACE_IAC, PHYADDR);
308 bus_space_write_multi_1(sc->sc_regt, sc->sc_regh, MACE_REG(MACE_PADR), 308 bus_space_write_multi_1(sc->sc_regt, sc->sc_regh, MACE_REG(MACE_PADR),
309 sc->sc_enaddr, ETHER_ADDR_LEN); 309 sc->sc_enaddr, ETHER_ADDR_LEN);
310 310
311 /* set logical address filter */ 311 /* set logical address filter */
312 mace_calcladrf(&sc->sc_ethercom, ladrf); 312 mace_calcladrf(&sc->sc_ethercom, ladrf);
313 313
314 NIC_PUT(sc, MACE_IAC, ADDRCHG); 314 NIC_PUT(sc, MACE_IAC, ADDRCHG);
315 while (NIC_GET(sc, MACE_IAC) & ADDRCHG) 315 while (NIC_GET(sc, MACE_IAC) & ADDRCHG)
316 ; 316 ;
317 NIC_PUT(sc, MACE_IAC, LOGADDR); 317 NIC_PUT(sc, MACE_IAC, LOGADDR);
318 bus_space_write_multi_1(sc->sc_regt, sc->sc_regh, MACE_REG(MACE_LADRF), 318 bus_space_write_multi_1(sc->sc_regt, sc->sc_regh, MACE_REG(MACE_LADRF),
319 ladrf, 8); 319 ladrf, 8);
320 320
321 NIC_PUT(sc, MACE_XMTFC, APADXMT); 321 NIC_PUT(sc, MACE_XMTFC, APADXMT);
322 /* 322 /*
323 * No need to autostrip padding on receive... Ethernet frames 323 * No need to autostrip padding on receive... Ethernet frames
324 * don't have a length field, unlike 802.3 frames, so the MACE 324 * don't have a length field, unlike 802.3 frames, so the MACE
325 * can't figure out the length of the packet anyways. 325 * can't figure out the length of the packet anyways.
326 */ 326 */
327 NIC_PUT(sc, MACE_RCVFC, 0); 327 NIC_PUT(sc, MACE_RCVFC, 0);
328 328
329 maccc = ENXMT | ENRCV; 329 maccc = ENXMT | ENRCV;
330 if (sc->sc_if.if_flags & IFF_PROMISC) 330 if (sc->sc_if.if_flags & IFF_PROMISC)
331 maccc |= PROM; 331 maccc |= PROM;
332 332
333 NIC_PUT(sc, MACE_MACCC, maccc); 333 NIC_PUT(sc, MACE_MACCC, maccc);
334 334
335 if (sc->sc_bus_init) 335 if (sc->sc_bus_init)
336 (*sc->sc_bus_init)(sc); 336 (*sc->sc_bus_init)(sc);
337 337
338 /* 338 /*
339 * Enable all interrupts except receive, since we use the DMA 339 * Enable all interrupts except receive, since we use the DMA
340 * completion interrupt for that. 340 * completion interrupt for that.
341 */ 341 */
342 NIC_PUT(sc, MACE_IMR, RCVINTM); 342 NIC_PUT(sc, MACE_IMR, RCVINTM);
343 343
344 /* flag interface as "running" */ 344 /* flag interface as "running" */
345 sc->sc_if.if_flags |= IFF_RUNNING; 345 sc->sc_if.if_flags |= IFF_RUNNING;
346 sc->sc_if.if_flags &= ~IFF_OACTIVE; 346 sc->sc_if.if_flags &= ~IFF_OACTIVE;
347 347
348 splx(s); 348 splx(s);
349 return 0; 349 return 0;
350} 350}
351 351
352/* 352/*
353 * close down an interface and free its buffers 353 * close down an interface and free its buffers
354 * Called on final close of device, or if mcinit() fails 354 * Called on final close of device, or if mcinit() fails
355 * part way through. 355 * part way through.
356 */ 356 */
357hide int 357hide int
358mcstop(struct mc_softc *sc) 358mcstop(struct mc_softc *sc)
359{ 359{
360 int s; 360 int s;
361 361
362 s = splnet(); 362 s = splnet();
363 363
364 NIC_PUT(sc, MACE_BIUCC, SWRST); 364 NIC_PUT(sc, MACE_BIUCC, SWRST);
365 DELAY(100); 365 DELAY(100);
366 366
367 sc->sc_if.if_timer = 0; 367 sc->sc_if.if_timer = 0;
368 sc->sc_if.if_flags &= ~IFF_RUNNING; 368 sc->sc_if.if_flags &= ~IFF_RUNNING;
369 369
370 splx(s); 370 splx(s);
371 return 0; 371 return 0;
372} 372}
373 373
374/* 374/*
375 * Called if any Tx packets remain unsent after 5 seconds, 375 * Called if any Tx packets remain unsent after 5 seconds,
376 * In all cases we just reset the chip, and any retransmission 376 * In all cases we just reset the chip, and any retransmission
377 * will be handled by higher level protocol timeouts. 377 * will be handled by higher level protocol timeouts.
378 */ 378 */
379hide void 379hide void
380mcwatchdog(struct ifnet *ifp) 380mcwatchdog(struct ifnet *ifp)
381{ 381{
382 struct mc_softc *sc = ifp->if_softc; 382 struct mc_softc *sc = ifp->if_softc;
383 383
384 printf("mcwatchdog: resetting chip\n"); 384 printf("mcwatchdog: resetting chip\n");
385 mcreset(sc); 385 mcreset(sc);
386} 386}
387 387
388/* 388/*
389 * stuff packet into MACE (at splnet) 389 * stuff packet into MACE (at splnet)
390 */ 390 */
391integrate u_int 391integrate u_int
392maceput(struct mc_softc *sc, struct mbuf *m) 392maceput(struct mc_softc *sc, struct mbuf *m)
393{ 393{
394 struct mbuf *n; 394 struct mbuf *n;
395 u_int len, totlen = 0; 395 u_int len, totlen = 0;
396 u_char *buff; 396 u_char *buff;
397 397
398 buff = (u_char*)sc->sc_txbuf + (sc->sc_txset == 0 ? 0 : 0x800); 398 buff = (u_char*)sc->sc_txbuf + (sc->sc_txset == 0 ? 0 : 0x800);
399 399
400 for (; m; m = n) { 400 for (; m; m = n) {
401 u_char *data = mtod(m, u_char *); 401 u_char *data = mtod(m, u_char *);
402 len = m->m_len; 402 len = m->m_len;
403 totlen += len; 403 totlen += len;
404 memcpy(buff, data, len); 404 memcpy(buff, data, len);
405 buff += len; 405 buff += len;
406 n = m_free(m); 406 n = m_free(m);
407 } 407 }
408 408
409 if (totlen > PAGE_SIZE) 409 if (totlen > PAGE_SIZE)
410 panic("%s: maceput: packet overflow", device_xname(sc->sc_dev)); 410 panic("%s: maceput: packet overflow", device_xname(sc->sc_dev));
411 411
412#if 0 412#if 0
413 if (totlen < ETHERMIN + sizeof(struct ether_header)) { 413 if (totlen < ETHERMIN + sizeof(struct ether_header)) {
414 int pad = ETHERMIN + sizeof(struct ether_header) - totlen; 414 int pad = ETHERMIN + sizeof(struct ether_header) - totlen;
415 memset(sc->sc_txbuf + totlen, 0, pad); 415 memset(sc->sc_txbuf + totlen, 0, pad);
416 totlen = ETHERMIN + sizeof(struct ether_header); 416 totlen = ETHERMIN + sizeof(struct ether_header);
417 } 417 }
418#endif 418#endif
419 419
420 (*sc->sc_putpacket)(sc, totlen); 420 (*sc->sc_putpacket)(sc, totlen);
421 421
422 sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */ 422 sc->sc_if.if_timer = 5; /* 5 seconds to watch for failing to transmit */
423 return totlen; 423 return totlen;
424} 424}
425 425
426void 426void
427mcintr(void *arg) 427mcintr(void *arg)
428{ 428{
429struct mc_softc *sc = arg; 429struct mc_softc *sc = arg;
430 uint8_t ir; 430 uint8_t ir;
431 431
432 ir = NIC_GET(sc, MACE_IR) & ~NIC_GET(sc, MACE_IMR); 432 ir = NIC_GET(sc, MACE_IR) & ~NIC_GET(sc, MACE_IMR);
433 if (ir & JAB) { 433 if (ir & JAB) {
434#ifdef MCDEBUG 434#ifdef MCDEBUG
435 printf("%s: jabber error\n", device_xname(sc->sc_dev)); 435 printf("%s: jabber error\n", device_xname(sc->sc_dev));
436#endif 436#endif
437 if_statinc(&sc->sc_if, if_oerrors); 437 if_statinc(&sc->sc_if, if_oerrors);
438 } 438 }
439 439
440 if (ir & BABL) { 440 if (ir & BABL) {
441#ifdef MCDEBUG 441#ifdef MCDEBUG
442 printf("%s: babble\n", device_xname(sc->sc_dev)); 442 printf("%s: babble\n", device_xname(sc->sc_dev));
443#endif 443#endif
444 if_statinc(&sc->sc_if, if_oerrors); 444 if_statinc(&sc->sc_if, if_oerrors);
445 } 445 }
446 446
447 if (ir & CERR) { 447 if (ir & CERR) {
448#ifdef MCDEBUG 448#ifdef MCDEBUG
449 printf("%s: collision error\n", device_xname(sc->sc_dev)); 449 printf("%s: collision error\n", device_xname(sc->sc_dev));
450#endif 450#endif
451 if_statinc(&sc->sc_if, if_collisions); 451 if_statinc(&sc->sc_if, if_collisions);
452 } 452 }
453 453
454 /* 454 /*
455 * Pretend we have carrier; if we don't this will be cleared 455 * Pretend we have carrier; if we don't this will be cleared
456 * shortly. 456 * shortly.
457 */ 457 */
458 sc->sc_havecarrier = 1; 458 sc->sc_havecarrier = 1;
459 459
460 if (ir & XMTINT) 460 if (ir & XMTINT)
461 mc_tint(sc); 461 mc_tint(sc);
462 462
463 if (ir & RCVINT) 463 if (ir & RCVINT)
464 mc_rint(sc); 464 mc_rint(sc);
465} 465}
466 466
467integrate void 467integrate void
468mc_tint(struct mc_softc *sc) 468mc_tint(struct mc_softc *sc)
469{ 469{
470 uint8_t /* xmtrc,*/ xmtfs; 470 uint8_t /* xmtrc,*/ xmtfs;
471 471
472 /* xmtrc = */ NIC_GET(sc, MACE_XMTRC); 472 /* xmtrc = */ NIC_GET(sc, MACE_XMTRC);
473 xmtfs = NIC_GET(sc, MACE_XMTFS); 473 xmtfs = NIC_GET(sc, MACE_XMTFS);
474 474
475 if ((xmtfs & XMTSV) == 0) 475 if ((xmtfs & XMTSV) == 0)
476 return; 476 return;
477 477
478 if (xmtfs & UFLO) { 478 if (xmtfs & UFLO) {
479 printf("%s: underflow\n", device_xname(sc->sc_dev)); 479 printf("%s: underflow\n", device_xname(sc->sc_dev));
480 mcreset(sc); 480 mcreset(sc);
481 return; 481 return;
482 } 482 }
483 483
484 net_stat_ref_t nsr = IF_STAT_GETREF(&sc->sc_if); 484 net_stat_ref_t nsr = IF_STAT_GETREF(&sc->sc_if);
485 485
486 if (xmtfs & LCOL) { 486 if (xmtfs & LCOL) {
487 printf("%s: late collision\n", device_xname(sc->sc_dev)); 487 printf("%s: late collision\n", device_xname(sc->sc_dev));
488 if_statinc_ref(nsr, if_oerrors); 488 if_statinc_ref(nsr, if_oerrors);
489 if_statinc_ref(nsr, if_collisions); 489 if_statinc_ref(nsr, if_collisions);
490 } 490 }
491 491
492 if (xmtfs & MORE) 492 if (xmtfs & MORE)
493 /* Real number is unknown. */ 493 /* Real number is unknown. */
494 if_statadd_ref(nsr, if_collsions, 2); 494 if_statadd_ref(nsr, if_collisons, 2);
495 else if (xmtfs & ONE) 495 else if (xmtfs & ONE)
496 if_statinc_ref(nsr, if_collisions); 496 if_statinc_ref(nsr, if_collisions);
497 else if (xmtfs & RTRY) { 497 else if (xmtfs & RTRY) {
498 printf("%s: excessive collisions\n", device_xname(sc->sc_dev)); 498 printf("%s: excessive collisions\n", device_xname(sc->sc_dev));
499 if_statadd_ref(nsr, if_collsions, 16); 499 if_statadd_ref(nsr, if_collsions, 16);
500 if_statinc_ref(nsr, if_oerrors); 500 if_statinc_ref(nsr, if_oerrors);
501 } 501 }
502 502
503 if (xmtfs & LCAR) { 503 if (xmtfs & LCAR) {
504 sc->sc_havecarrier = 0; 504 sc->sc_havecarrier = 0;
505 printf("%s: lost carrier\n", device_xname(sc->sc_dev)); 505 printf("%s: lost carrier\n", device_xname(sc->sc_dev));
506 if_statinc_ref(nsr, if_oerrors); 506 if_statinc_ref(nsr, if_oerrors);
507 } 507 }
508 508
509 IF_STAT_PUTREF(&sc->sc_if); 509 IF_STAT_PUTREF(&sc->sc_if);
510 510
511 sc->sc_if.if_flags &= ~IFF_OACTIVE; 511 sc->sc_if.if_flags &= ~IFF_OACTIVE;
512 sc->sc_if.if_timer = 0; 512 sc->sc_if.if_timer = 0;
513 if_schedule_deferred_start(&sc->sc_if); 513 if_schedule_deferred_start(&sc->sc_if);
514} 514}
515 515
516void 516void
517mc_rint(struct mc_softc *sc) 517mc_rint(struct mc_softc *sc)
518{ 518{
519#define rxf sc->sc_rxframe 519#define rxf sc->sc_rxframe
520 u_int len; 520 u_int len;
521 521
522 len = (rxf.rx_rcvcnt | ((rxf.rx_rcvsts & 0xf) << 8)) - 4; 522 len = (rxf.rx_rcvcnt | ((rxf.rx_rcvsts & 0xf) << 8)) - 4;
523 523
524#ifdef MCDEBUG 524#ifdef MCDEBUG
525 if (rxf.rx_rcvsts & 0xf0) 525 if (rxf.rx_rcvsts & 0xf0)
526 printf("%s: rcvcnt %02x rcvsts %02x rntpc 0x%02x rcvcc 0x%02x\n", 526 printf("%s: rcvcnt %02x rcvsts %02x rntpc 0x%02x rcvcc 0x%02x\n",
527 device_xname(sc->sc_dev), rxf.rx_rcvcnt, rxf.rx_rcvsts, 527 device_xname(sc->sc_dev), rxf.rx_rcvcnt, rxf.rx_rcvsts,
528 rxf.rx_rntpc, rxf.rx_rcvcc); 528 rxf.rx_rntpc, rxf.rx_rcvcc);
529#endif 529#endif
530 530
531 if (rxf.rx_rcvsts & OFLO) { 531 if (rxf.rx_rcvsts & OFLO) {
532 printf("%s: receive FIFO overflow\n", device_xname(sc->sc_dev)); 532 printf("%s: receive FIFO overflow\n", device_xname(sc->sc_dev));
533 if_statinc(&sc->sc_if, if_ierrors); 533 if_statinc(&sc->sc_if, if_ierrors);
534 return; 534 return;
535 } 535 }
536 536
537 if (rxf.rx_rcvsts & CLSN) 537 if (rxf.rx_rcvsts & CLSN)
538 if_statinc(&sc->sc_if, if_collisions); 538 if_statinc(&sc->sc_if, if_collisions);
539 539
540 if (rxf.rx_rcvsts & FRAM) { 540 if (rxf.rx_rcvsts & FRAM) {
541#ifdef MCDEBUG 541#ifdef MCDEBUG
542 printf("%s: framing error\n", device_xname(sc->sc_dev)); 542 printf("%s: framing error\n", device_xname(sc->sc_dev));
543#endif 543#endif
544 if_statinc(&sc->sc_if, if_ierrors); 544 if_statinc(&sc->sc_if, if_ierrors);
545 return; 545 return;
546 } 546 }
547 547
548 if (rxf.rx_rcvsts & FCS) { 548 if (rxf.rx_rcvsts & FCS) {
549#ifdef MCDEBUG 549#ifdef MCDEBUG
550 printf("%s: frame control checksum error\n", device_xname(sc->sc_dev)); 550 printf("%s: frame control checksum error\n", device_xname(sc->sc_dev));
551#endif 551#endif
552 if_statinc(&sc->sc_if, if_ierrors); 552 if_statinc(&sc->sc_if, if_ierrors);
553 return; 553 return;
554 } 554 }
555 555
556 mace_read(sc, rxf.rx_frame, len); 556 mace_read(sc, rxf.rx_frame, len);
557#undef rxf 557#undef rxf
558} 558}
559 559
560integrate void 560integrate void
561mace_read(struct mc_softc *sc, void *pkt, int len) 561mace_read(struct mc_softc *sc, void *pkt, int len)
562{ 562{
563 struct ifnet *ifp = &sc->sc_if; 563 struct ifnet *ifp = &sc->sc_if;
564 struct mbuf *m; 564 struct mbuf *m;
565 565
566 if (len <= sizeof(struct ether_header) || 566 if (len <= sizeof(struct ether_header) ||
567 len > ETHERMTU + sizeof(struct ether_header)) { 567 len > ETHERMTU + sizeof(struct ether_header)) {
568#ifdef MCDEBUG 568#ifdef MCDEBUG
569 printf("%s: invalid packet size %d; dropping\n", 569 printf("%s: invalid packet size %d; dropping\n",
570 device_xname(sc->sc_dev), len); 570 device_xname(sc->sc_dev), len);
571#endif 571#endif
572 if_statinc(ifp, if_ierrors); 572 if_statinc(ifp, if_ierrors);
573 return; 573 return;
574 } 574 }
575 575
576 m = mace_get(sc, pkt, len); 576 m = mace_get(sc, pkt, len);
577 if (m == NULL) { 577 if (m == NULL) {
578 if_statinc(ifp, if_ierrors); 578 if_statinc(ifp, if_ierrors);
579 return; 579 return;
580 } 580 }
581 581
582 /* Pass the packet up. */ 582 /* Pass the packet up. */
583 if_percpuq_enqueue(ifp->if_percpuq, m); 583 if_percpuq_enqueue(ifp->if_percpuq, m);
584} 584}
585 585
586/* 586/*
587 * Pull data off an interface. 587 * Pull data off an interface.
588 * Len is length of data, with local net header stripped. 588 * Len is length of data, with local net header stripped.
589 * We copy the data into mbufs. When full cluster sized units are present 589 * We copy the data into mbufs. When full cluster sized units are present
590 * we copy into clusters. 590 * we copy into clusters.
591 */ 591 */
592integrate struct mbuf * 592integrate struct mbuf *
593mace_get(struct mc_softc *sc, void *pkt, int totlen) 593mace_get(struct mc_softc *sc, void *pkt, int totlen)
594{ 594{
595 struct mbuf *m; 595 struct mbuf *m;
596 struct mbuf *top, **mp; 596 struct mbuf *top, **mp;
597 int len; 597 int len;
598 598
599 MGETHDR(m, M_DONTWAIT, MT_DATA); 599 MGETHDR(m, M_DONTWAIT, MT_DATA);
600 if (m == 0) 600 if (m == 0)
601 return 0; 601 return 0;
602 m_set_rcvif(m, &sc->sc_if); 602 m_set_rcvif(m, &sc->sc_if);
603 m->m_pkthdr.len = totlen; 603 m->m_pkthdr.len = totlen;
604 len = MHLEN; 604 len = MHLEN;
605 top = 0; 605 top = 0;
606 mp = &top; 606 mp = &top;
607 607
608 while (totlen > 0) { 608 while (totlen > 0) {
609 if (top) { 609 if (top) {
610 MGET(m, M_DONTWAIT, MT_DATA); 610 MGET(m, M_DONTWAIT, MT_DATA);
611 if (m == 0) { 611 if (m == 0) {
612 m_freem(top); 612 m_freem(top);
613 return 0; 613 return 0;
614 } 614 }
615 len = MLEN; 615 len = MLEN;
616 } 616 }
617 if (totlen >= MINCLSIZE) { 617 if (totlen >= MINCLSIZE) {
618 MCLGET(m, M_DONTWAIT); 618 MCLGET(m, M_DONTWAIT);
619 if ((m->m_flags & M_EXT) == 0) { 619 if ((m->m_flags & M_EXT) == 0) {
620 m_free(m); 620 m_free(m);
621 m_freem(top); 621 m_freem(top);
622 return 0; 622 return 0;
623 } 623 }
624 len = MCLBYTES; 624 len = MCLBYTES;
625 } 625 }
626 m->m_len = len = uimin(totlen, len); 626 m->m_len = len = uimin(totlen, len);
627 memcpy(mtod(m, void *), pkt, len); 627 memcpy(mtod(m, void *), pkt, len);
628 pkt = (char*)pkt + len; 628 pkt = (char*)pkt + len;
629 totlen -= len; 629 totlen -= len;
630 *mp = m; 630 *mp = m;
631 mp = &m->m_next; 631 mp = &m->m_next;
632 } 632 }
633 633
634 return top; 634 return top;
635} 635}
636 636
637/* 637/*
638 * Go through the list of multicast addresses and calculate the logical 638 * Go through the list of multicast addresses and calculate the logical
639 * address filter. 639 * address filter.
640 */ 640 */
641void 641void
642mace_calcladrf(struct ethercom *ec, uint8_t *af) 642mace_calcladrf(struct ethercom *ec, uint8_t *af)
643{ 643{
644 struct ifnet *ifp = &ec->ec_if; 644 struct ifnet *ifp = &ec->ec_if;
645 struct ether_multi *enm; 645 struct ether_multi *enm;
646 u_char *cp; 646 u_char *cp;
647 uint32_t crc; 647 uint32_t crc;
648 static const uint32_t crctab[] = { 648 static const uint32_t crctab[] = {
649 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 649 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
650 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 650 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
651 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 651 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
652 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 652 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
653 }; 653 };
654 int len; 654 int len;
655 struct ether_multistep step; 655 struct ether_multistep step;
656 656
657 /* 657 /*
658 * Set up multicast address filter by passing all multicast addresses 658 * Set up multicast address filter by passing all multicast addresses
659 * through a crc generator, and then using the high order 6 bits as an 659 * through a crc generator, and then using the high order 6 bits as an
660 * index into the 64 bit logical address filter. The high order bit 660 * index into the 64 bit logical address filter. The high order bit
661 * selects the word, while the rest of the bits select the bit within 661 * selects the word, while the rest of the bits select the bit within
662 * the word. 662 * the word.
663 */ 663 */
664 664
665 *((uint32_t *)af) = *((uint32_t *)af + 1) = 0; 665 *((uint32_t *)af) = *((uint32_t *)af + 1) = 0;
666 ETHER_LOCK(ec); 666 ETHER_LOCK(ec);
667 ETHER_FIRST_MULTI(step, ec, enm); 667 ETHER_FIRST_MULTI(step, ec, enm);
668 while (enm != NULL) { 668 while (enm != NULL) {
669 if (ETHER_CMP(enm->enm_addrlo, enm->enm_addrhi)) { 669 if (ETHER_CMP(enm->enm_addrlo, enm->enm_addrhi)) {
670 /* 670 /*
671 * We must listen to a range of multicast addresses. 671 * We must listen to a range of multicast addresses.
672 * For now, just accept all multicasts, rather than 672 * For now, just accept all multicasts, rather than
673 * trying to set only those filter bits needed to match 673 * trying to set only those filter bits needed to match
674 * the range. (At this time, the only use of address 674 * the range. (At this time, the only use of address
675 * ranges is for IP multicast routing, for which the 675 * ranges is for IP multicast routing, for which the
676 * range is big enough to require all bits set.) 676 * range is big enough to require all bits set.)
677 */ 677 */
678 ETHER_UNLOCK(ec); 678 ETHER_UNLOCK(ec);
679 goto allmulti; 679 goto allmulti;
680 } 680 }
681 681
682 cp = enm->enm_addrlo; 682 cp = enm->enm_addrlo;
683 crc = 0xffffffff; 683 crc = 0xffffffff;
684 for (len = sizeof(enm->enm_addrlo); --len >= 0;) { 684 for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
685 crc ^= *cp++; 685 crc ^= *cp++;
686 crc = (crc >> 4) ^ crctab[crc & 0xf]; 686 crc = (crc >> 4) ^ crctab[crc & 0xf];
687 crc = (crc >> 4) ^ crctab[crc & 0xf]; 687 crc = (crc >> 4) ^ crctab[crc & 0xf];
688 } 688 }
689 /* Just want the 6 most significant bits. */ 689 /* Just want the 6 most significant bits. */
690 crc >>= 26; 690 crc >>= 26;
691 691
692 /* Set the corresponding bit in the filter. */ 692 /* Set the corresponding bit in the filter. */
693 af[crc >> 3] |= 1 << (crc & 7); 693 af[crc >> 3] |= 1 << (crc & 7);
694 694
695 ETHER_NEXT_MULTI(step, enm); 695 ETHER_NEXT_MULTI(step, enm);
696 } 696 }
697 ETHER_UNLOCK(ec); 697 ETHER_UNLOCK(ec);
698 ifp->if_flags &= ~IFF_ALLMULTI; 698 ifp->if_flags &= ~IFF_ALLMULTI;
699 return; 699 return;
700 700
701allmulti: 701allmulti:
702 ifp->if_flags |= IFF_ALLMULTI; 702 ifp->if_flags |= IFF_ALLMULTI;
703 *((uint32_t *)af) = *((uint32_t *)af + 1) = 0xffffffff; 703 *((uint32_t *)af) = *((uint32_t *)af + 1) = 0xffffffff;
704} 704}
705 705
706static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}; 706static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
707#define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf]) 707#define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
708 708
709u_char 709u_char
710mc_get_enaddr(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, 710mc_get_enaddr(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
711 u_char *dst) 711 u_char *dst)
712{ 712{
713 int i; 713 int i;
714 u_char b, csum; 714 u_char b, csum;
715 715
716 /* 716 /*
717 * The XOR of the 8 bytes of the ROM must be 0xff for it to be 717 * The XOR of the 8 bytes of the ROM must be 0xff for it to be
718 * valid 718 * valid
719 */ 719 */
720 for (i = 0, csum = 0; i < 8; i++) { 720 for (i = 0, csum = 0; i < 8; i++) {
721 b = bus_space_read_1(t, h, o+16*i); 721 b = bus_space_read_1(t, h, o+16*i);
722 if (i < ETHER_ADDR_LEN) 722 if (i < ETHER_ADDR_LEN)
723 dst[i] = bbr(b); 723 dst[i] = bbr(b);
724 csum ^= b; 724 csum ^= b;
725 } 725 }
726 726
727 return csum; 727 return csum;
728} 728}