xref: /netbsd-src/sys/dev/ic/awi.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /*	$NetBSD: awi.c,v 1.81 2008/11/07 00:20:02 dyoung Exp $	*/
2 
3 /*-
4  * Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Bill Sommerfeld
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*
32  * Driver for AMD 802.11 firmware.
33  * Uses am79c930 chip driver to talk to firmware running on the am79c930.
34  *
35  * More-or-less a generic ethernet-like if driver, with 802.11 gorp added.
36  */
37 
38 /*
39  * todo:
40  *	- flush tx queue on resynch.
41  *	- clear oactive on "down".
42  *	- rewrite copy-into-mbuf code
43  *	- mgmt state machine gets stuck retransmitting assoc requests.
44  *	- multicast filter.
45  *	- fix device reset so it's more likely to work
46  *	- show status goo through ifmedia.
47  *
48  * more todo:
49  *	- deal with more 802.11 frames.
50  *		- send reassoc request
51  *		- deal with reassoc response
52  *		- send/deal with disassociation
53  *	- deal with "full" access points (no room for me).
54  *	- power save mode
55  *
56  * later:
57  *	- SSID preferences
58  *	- need ioctls for poking at the MIBs
59  *	- implement ad-hoc mode (including bss creation).
60  *	- decide when to do "ad hoc" vs. infrastructure mode (IFF_LINK flags?)
61  *		(focus on inf. mode since that will be needed for ietf)
62  *	- deal with DH vs. FH versions of the card
63  *	- deal with faster cards (2mb/s)
64  *	- ?WEP goo (mmm, rc4) (it looks not particularly useful).
65  *	- ifmedia revision.
66  *	- common 802.11 mibish things.
67  *	- common 802.11 media layer.
68  */
69 
70 /*
71  * Driver for AMD 802.11 PCnetMobile firmware.
72  * Uses am79c930 chip driver to talk to firmware running on the am79c930.
73  *
74  * The initial version of the driver was written by
75  * Bill Sommerfeld <sommerfeld@NetBSD.org>.
76  * Then the driver module completely rewritten to support cards with DS phy
77  * and to support adhoc mode by Atsushi Onoe <onoe@NetBSD.org>
78  */
79 
80 #include <sys/cdefs.h>
81 #ifdef __NetBSD__
82 __KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.81 2008/11/07 00:20:02 dyoung Exp $");
83 #endif
84 #ifdef __FreeBSD__
85 __FBSDID("$FreeBSD: src/sys/dev/awi/awi.c,v 1.30 2004/01/15 13:30:06 onoe Exp $");
86 #endif
87 
88 #include "opt_inet.h"
89 #ifdef __NetBSD__
90 #include "bpfilter.h"
91 #endif
92 #ifdef __FreeBSD__
93 #define	NBPFILTER	1
94 #endif
95 
96 #include <sys/param.h>
97 #include <sys/systm.h>
98 #include <sys/kernel.h>
99 #include <sys/mbuf.h>
100 #include <sys/malloc.h>
101 #include <sys/proc.h>
102 #include <sys/socket.h>
103 #include <sys/sockio.h>
104 #include <sys/errno.h>
105 #include <sys/endian.h>
106 #ifdef __FreeBSD__
107 #include <sys/bus.h>
108 #endif
109 #ifdef __NetBSD__
110 #include <sys/device.h>
111 #endif
112 
113 #include <net/if.h>
114 #include <net/if_dl.h>
115 #ifdef __NetBSD__
116 #include <net/if_ether.h>
117 #endif
118 #ifdef __FreeBSD__
119 #include <net/ethernet.h>
120 #include <net/if_arp.h>
121 #endif
122 #include <net/if_media.h>
123 #include <net/if_llc.h>
124 
125 #include <net80211/ieee80211_netbsd.h>
126 #include <net80211/ieee80211_var.h>
127 
128 #if NBPFILTER > 0
129 #include <net/bpf.h>
130 #endif
131 
132 #include <sys/cpu.h>
133 #include <sys/bus.h>
134 
135 #ifdef __NetBSD__
136 #include <dev/ic/am79c930reg.h>
137 #include <dev/ic/am79c930var.h>
138 #include <dev/ic/awireg.h>
139 #include <dev/ic/awivar.h>
140 #endif
141 #ifdef __FreeBSD__
142 #include <dev/awi/am79c930reg.h>
143 #include <dev/awi/am79c930var.h>
144 #include <dev/awi/awireg.h>
145 #include <dev/awi/awivar.h>
146 #endif
147 
148 #ifdef __FreeBSD__
149 static void awi_init0(void *);
150 #endif
151 static int  awi_init(struct ifnet *);
152 static void awi_stop(struct ifnet *, int);
153 static void awi_start(struct ifnet *);
154 static void awi_watchdog(struct ifnet *);
155 static int  awi_ioctl(struct ifnet *, u_long, void *);
156 static int  awi_media_change(struct ifnet *);
157 static void awi_media_status(struct ifnet *, struct ifmediareq *);
158 static int  awi_mode_init(struct awi_softc *);
159 static void awi_rx_int(struct awi_softc *);
160 static void awi_tx_int(struct awi_softc *);
161 static struct mbuf *awi_devget(struct awi_softc *, u_int32_t, u_int16_t);
162 static int  awi_hw_init(struct awi_softc *);
163 static int  awi_init_mibs(struct awi_softc *);
164 static int  awi_mib(struct awi_softc *, u_int8_t, u_int8_t, int);
165 static int  awi_cmd(struct awi_softc *, u_int8_t, int);
166 static int  awi_cmd_wait(struct awi_softc *);
167 static void awi_cmd_done(struct awi_softc *);
168 static int  awi_next_txd(struct awi_softc *, int, u_int32_t *, u_int32_t *);
169 static int  awi_lock(struct awi_softc *);
170 static void awi_unlock(struct awi_softc *);
171 static int  awi_intr_lock(struct awi_softc *);
172 static void awi_intr_unlock(struct awi_softc *);
173 static int  awi_newstate(struct ieee80211com *, enum ieee80211_state, int);
174 static void awi_recv_mgmt(struct ieee80211com *, struct mbuf *,
175     struct ieee80211_node *, int, int, u_int32_t);
176 static int  awi_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int,
177     int);
178 static struct mbuf *awi_ether_encap(struct awi_softc *, struct mbuf *);
179 static struct mbuf *awi_ether_modcap(struct awi_softc *, struct mbuf *);
180 
181 /* unaligned little endian access */
182 #define LE_READ_2(p)							\
183 	((((u_int8_t *)(p))[0]      ) | (((u_int8_t *)(p))[1] <<  8))
184 #define LE_READ_4(p)							\
185 	((((u_int8_t *)(p))[0]      ) | (((u_int8_t *)(p))[1] <<  8) |	\
186 	 (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24))
187 #define LE_WRITE_2(p, v)						\
188 	((((u_int8_t *)(p))[0] = (((u_int32_t)(v)      ) & 0xff)),	\
189 	 (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >>  8) & 0xff)))
190 #define LE_WRITE_4(p, v)						\
191 	((((u_int8_t *)(p))[0] = (((u_int32_t)(v)      ) & 0xff)),	\
192 	 (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >>  8) & 0xff)),	\
193 	 (((u_int8_t *)(p))[2] = (((u_int32_t)(v) >> 16) & 0xff)),	\
194 	 (((u_int8_t *)(p))[3] = (((u_int32_t)(v) >> 24) & 0xff)))
195 
196 struct awi_chanset awi_chanset[] = {
197     /* PHY type        domain            min max def */
198     { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_JP,  6, 17,  6 },
199     { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_ES,  0, 26,  1 },
200     { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_FR,  0, 32,  1 },
201     { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_US,  0, 77,  1 },
202     { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_CA,  0, 77,  1 },
203     { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_EU,  0, 77,  1 },
204     { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_JP, 14, 14, 14 },
205     { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_ES, 10, 11, 10 },
206     { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_FR, 10, 13, 10 },
207     { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_US,  1, 11,  3 },
208     { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_CA,  1, 11,  3 },
209     { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_EU,  1, 13,  3 },
210     { 0, 0, 0, 0, 0 }
211 };
212 
213 #ifdef AWI_DEBUG
214 int awi_debug = 0;
215 
216 #define	DPRINTF(X)	if (awi_debug) printf X
217 #define	DPRINTF2(X)	if (awi_debug > 1) printf X
218 #else
219 #define	DPRINTF(X)
220 #define	DPRINTF2(X)
221 #endif
222 
223 int
224 awi_attach(struct awi_softc *sc)
225 {
226 	struct ieee80211com *ic = &sc->sc_ic;
227 	struct ifnet *ifp = &sc->sc_if;
228 	int s, i, error, nrate;
229 	int mword;
230 	enum ieee80211_phymode mode;
231 
232 	s = splnet();
233 	sc->sc_busy = 1;
234 	sc->sc_attached = 0;
235 	sc->sc_substate = AWI_ST_NONE;
236 	if ((error = awi_hw_init(sc)) != 0) {
237 		sc->sc_invalid = 1;
238 		splx(s);
239 		return error;
240 	}
241 	error = awi_init_mibs(sc);
242 	if (error != 0) {
243 		sc->sc_invalid = 1;
244 		splx(s);
245 		return error;
246 	}
247 	ifp->if_softc = sc;
248 	ifp->if_flags =
249 #ifdef IFF_NOTRAILERS
250 	    IFF_NOTRAILERS |
251 #endif
252 	    IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
253 	ifp->if_ioctl = awi_ioctl;
254 	ifp->if_start = awi_start;
255 	ifp->if_watchdog = awi_watchdog;
256 #ifdef __NetBSD__
257 	ifp->if_init = awi_init;
258 	ifp->if_stop = awi_stop;
259 	IFQ_SET_READY(&ifp->if_snd);
260 	memcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ);
261 #endif
262 #ifdef __FreeBSD__
263 	ifp->if_init = awi_init0;
264 	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
265 	if_initname(ifp, device_get_name(sc->sc_dev),
266 	    device_get_unit(sc->sc_dev));
267 #endif
268 
269 	ic->ic_ifp = ifp;
270 	ic->ic_caps = IEEE80211_C_WEP | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP;
271 	if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
272 		ic->ic_phytype = IEEE80211_T_FH;
273 		mode = IEEE80211_MODE_FH;
274 	} else {
275 		ic->ic_phytype = IEEE80211_T_DS;
276 		ic->ic_caps |= IEEE80211_C_AHDEMO;
277 		mode = IEEE80211_MODE_11B;
278 	}
279 	ic->ic_opmode = IEEE80211_M_STA;
280 	nrate = sc->sc_mib_phy.aSuprt_Data_Rates[1];
281 	memcpy(ic->ic_sup_rates[mode].rs_rates,
282 	    sc->sc_mib_phy.aSuprt_Data_Rates + 2, nrate);
283 	ic->ic_sup_rates[mode].rs_nrates = nrate;
284 	IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address);
285 
286 	printf("%s: IEEE802.11 %s (firmware %s)\n", ifp->if_xname,
287 	    (ic->ic_phytype == IEEE80211_T_FH) ? "FH" : "DS", sc->sc_banner);
288 	printf("%s: 802.11 address: %s\n", ifp->if_xname,
289 	    ether_sprintf(ic->ic_myaddr));
290 
291 #ifdef __NetBSD__
292 	if_attach(ifp);
293 #endif
294 	ieee80211_ifattach(ic);
295 
296 	sc->sc_newstate = ic->ic_newstate;
297 	ic->ic_newstate = awi_newstate;
298 
299 	sc->sc_recv_mgmt = ic->ic_recv_mgmt;
300 	ic->ic_recv_mgmt = awi_recv_mgmt;
301 
302 	sc->sc_send_mgmt = ic->ic_send_mgmt;
303 	ic->ic_send_mgmt = awi_send_mgmt;
304 
305 	ieee80211_media_init(ic, awi_media_change, awi_media_status);
306 
307 	/* Melco compatibility mode. */
308 #define	ADD(s, o)	ifmedia_add(&ic->ic_media, \
309 	IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL)
310 	ADD(IFM_AUTO, IFM_FLAG0);
311 
312 	for (i = 0; i < nrate; i++) {
313 		mword = ieee80211_rate2media(ic,
314 		    ic->ic_sup_rates[mode].rs_rates[i], mode);
315 		if (mword == 0)
316 			continue;
317 		ADD(mword, IFM_FLAG0);
318 	}
319 #undef	ADD
320 
321 #ifdef __NetBSD__
322 	if ((sc->sc_sdhook = shutdownhook_establish(awi_shutdown, sc)) == NULL)
323 		printf("%s: WARNING: unable to establish shutdown hook\n",
324 		    ifp->if_xname);
325 	if ((sc->sc_powerhook =
326 	     powerhook_establish(ifp->if_xname, awi_power, sc)) == NULL)
327 		printf("%s: WARNING: unable to establish power hook\n",
328 		    ifp->if_xname);
329 #endif
330 	sc->sc_attached = 1;
331 	splx(s);
332 
333 	/* ready to accept ioctl */
334 	awi_unlock(sc);
335 
336 	return 0;
337 }
338 
339 int
340 awi_detach(struct awi_softc *sc)
341 {
342 	struct ieee80211com *ic = &sc->sc_ic;
343 	struct ifnet *ifp = &sc->sc_if;
344 	int s;
345 
346 	if (!sc->sc_attached)
347 		return 0;
348 
349 	s = splnet();
350 	sc->sc_invalid = 1;
351 	awi_stop(ifp, 1);
352 
353 	while (sc->sc_sleep_cnt > 0) {
354 		wakeup(sc);
355 		(void)tsleep(sc, PWAIT, "awidet", 1);
356 	}
357 	sc->sc_attached = 0;
358 	ieee80211_ifdetach(ic);
359 #ifdef __NetBSD__
360 	if_detach(ifp);
361 	shutdownhook_disestablish(sc->sc_sdhook);
362 	powerhook_disestablish(sc->sc_powerhook);
363 #endif
364 	splx(s);
365 	return 0;
366 }
367 
368 #ifdef __NetBSD__
369 int
370 awi_activate(struct device *self, enum devact act)
371 {
372 	struct awi_softc *sc = (struct awi_softc *)self;
373 	struct ifnet *ifp = &sc->sc_if;
374 	int s, error = 0;
375 
376 	s = splnet();
377 	switch (act) {
378 	case DVACT_ACTIVATE:
379 		error = EOPNOTSUPP;
380 		break;
381 	case DVACT_DEACTIVATE:
382 		sc->sc_invalid = 1;
383 		if_deactivate(ifp);
384 		break;
385 	}
386 	splx(s);
387 	return error;
388 }
389 
390 void
391 awi_power(int why, void *arg)
392 {
393 	struct awi_softc *sc = arg;
394 	struct ifnet *ifp = &sc->sc_if;
395 	int s;
396 	int ocansleep;
397 
398 	DPRINTF(("awi_power: %d\n", why));
399 	s = splnet();
400 	ocansleep = sc->sc_cansleep;
401 	sc->sc_cansleep = 0;
402 	switch (why) {
403 	case PWR_SUSPEND:
404 	case PWR_STANDBY:
405 		awi_stop(ifp, 1);
406 		break;
407 	case PWR_RESUME:
408 		if (ifp->if_flags & IFF_UP) {
409 			awi_init(ifp);
410 			(void)awi_intr(sc);	/* make sure */
411 		}
412 		break;
413 	case PWR_SOFTSUSPEND:
414 	case PWR_SOFTSTANDBY:
415 	case PWR_SOFTRESUME:
416 		break;
417 	}
418 	sc->sc_cansleep = ocansleep;
419 	splx(s);
420 }
421 #endif /* __NetBSD__ */
422 
423 void
424 awi_shutdown(void *arg)
425 {
426 	struct awi_softc *sc = arg;
427 	struct ifnet *ifp = &sc->sc_if;
428 
429 	if (sc->sc_attached)
430 		awi_stop(ifp, 1);
431 }
432 
433 int
434 awi_intr(void *arg)
435 {
436 	struct awi_softc *sc = arg;
437 	u_int16_t status;
438 	int handled = 0, ocansleep;
439 #ifdef AWI_DEBUG
440 	static const char *intname[] = {
441 	    "CMD", "RX", "TX", "SCAN_CMPLT",
442 	    "CFP_START", "DTIM", "CFP_ENDING", "GROGGY",
443 	    "TXDATA", "TXBCAST", "TXPS", "TXCF",
444 	    "TXMGT", "#13", "RXDATA", "RXMGT"
445 	};
446 #endif
447 
448 	if (!sc->sc_enabled || !sc->sc_enab_intr || sc->sc_invalid) {
449 		DPRINTF(("awi_intr: stray interrupt: "
450 		    "enabled %d enab_intr %d invalid %d\n",
451 		    sc->sc_enabled, sc->sc_enab_intr, sc->sc_invalid));
452 		return 0;
453 	}
454 
455 	am79c930_gcr_setbits(&sc->sc_chip,
456 	    AM79C930_GCR_DISPWDN | AM79C930_GCR_ECINT);
457 	awi_write_1(sc, AWI_DIS_PWRDN, 1);
458 	ocansleep = sc->sc_cansleep;
459 	sc->sc_cansleep = 0;
460 
461 	for (;;) {
462 		if (awi_intr_lock(sc) != 0)
463 			break;
464 		status = awi_read_1(sc, AWI_INTSTAT);
465 		awi_write_1(sc, AWI_INTSTAT, 0);
466 		awi_write_1(sc, AWI_INTSTAT, 0);
467 		status |= awi_read_1(sc, AWI_INTSTAT2) << 8;
468 		awi_write_1(sc, AWI_INTSTAT2, 0);
469 		DELAY(10);
470 		awi_intr_unlock(sc);
471 		if (!sc->sc_cmd_inprog)
472 			status &= ~AWI_INT_CMD;	/* make sure */
473 		if (status == 0)
474 			break;
475 #ifdef AWI_DEBUG
476 		if (awi_debug > 1) {
477 			int i;
478 
479 			printf("awi_intr: status 0x%04x", status);
480 			for (i = 0; i < sizeof(intname)/sizeof(intname[0]);
481 			    i++) {
482 				if (status & (1 << i))
483 					printf(" %s", intname[i]);
484 			}
485 			printf("\n");
486 		}
487 #endif
488 		handled = 1;
489 		if (status & AWI_INT_RX)
490 			awi_rx_int(sc);
491 		if (status & AWI_INT_TX)
492 			awi_tx_int(sc);
493 		if (status & AWI_INT_CMD)
494 			awi_cmd_done(sc);
495 		if (status & AWI_INT_SCAN_CMPLT) {
496 			if (sc->sc_ic.ic_state == IEEE80211_S_SCAN &&
497 			    sc->sc_substate == AWI_ST_NONE)
498 				ieee80211_next_scan(&sc->sc_ic);
499 		}
500 	}
501 	sc->sc_cansleep = ocansleep;
502 	am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_DISPWDN);
503 	awi_write_1(sc, AWI_DIS_PWRDN, 0);
504 	return handled;
505 }
506 
507 #ifdef __FreeBSD__
508 static void
509 awi_init0(void *arg)
510 {
511 	struct awi_softc *sc = arg;
512 
513 	(void)awi_init(&sc->sc_if);
514 }
515 #endif
516 
517 static int
518 awi_init(struct ifnet *ifp)
519 {
520 	struct awi_softc *sc = ifp->if_softc;
521 	struct ieee80211com *ic = &sc->sc_ic;
522 	struct ieee80211_node *ni = ic->ic_bss;
523 	struct ieee80211_rateset *rs;
524 	int error, rate, i;
525 
526 	DPRINTF(("awi_init: enabled=%d\n", sc->sc_enabled));
527 	if (sc->sc_enabled) {
528 		awi_stop(ifp, 0);
529 	} else {
530 		if (sc->sc_enable)
531 			(*sc->sc_enable)(sc);
532 		sc->sc_enabled = 1;
533 		if ((error = awi_hw_init(sc)) != 0) {
534 			if (sc->sc_disable)
535 				(*sc->sc_disable)(sc);
536 			sc->sc_enabled = 0;
537 			return error;
538 		}
539 	}
540 	ic->ic_state = IEEE80211_S_INIT;
541 
542 	ic->ic_flags &= ~IEEE80211_F_IBSSON;
543 	switch (ic->ic_opmode) {
544 	case IEEE80211_M_STA:
545 		sc->sc_mib_local.Network_Mode = 1;
546 		sc->sc_mib_local.Acting_as_AP = 0;
547 		break;
548 	case IEEE80211_M_IBSS:
549 		ic->ic_flags |= IEEE80211_F_IBSSON;
550 		/* FALLTHRU */
551 	case IEEE80211_M_AHDEMO:
552 		sc->sc_mib_local.Network_Mode = 0;
553 		sc->sc_mib_local.Acting_as_AP = 0;
554 		break;
555 	case IEEE80211_M_HOSTAP:
556 		sc->sc_mib_local.Network_Mode = 1;
557 		sc->sc_mib_local.Acting_as_AP = 1;
558 		break;
559 	case IEEE80211_M_MONITOR:
560 		return ENODEV;
561 	}
562 #if 0
563 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
564 #endif
565 	memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
566 	sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
567 	sc->sc_mib_mac.aDesired_ESS_ID[1] = ic->ic_des_esslen;
568 	memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], ic->ic_des_essid,
569 	    ic->ic_des_esslen);
570 
571 	/* configure basic rate */
572 	if (ic->ic_phytype == IEEE80211_T_FH)
573 		rs = &ic->ic_sup_rates[IEEE80211_MODE_FH];
574 	else
575 		rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
576 	if (ic->ic_fixed_rate != -1) {
577 		rate = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
578 	} else {
579 		rate = 0;
580 		for (i = 0; i < rs->rs_nrates; i++) {
581 			if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) &&
582 			    rate < (rs->rs_rates[i] & IEEE80211_RATE_VAL))
583 				rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
584 		}
585 	}
586 	rate *= 5;
587 	LE_WRITE_2(&sc->sc_mib_mac.aStation_Basic_Rate, rate);
588 
589 	if ((error = awi_mode_init(sc)) != 0) {
590 		DPRINTF(("awi_init: awi_mode_init failed %d\n", error));
591 		awi_stop(ifp, 1);
592 		return error;
593 	}
594 
595 	/* start transmitter */
596 	sc->sc_txdone = sc->sc_txnext = sc->sc_txbase;
597 	awi_write_4(sc, sc->sc_txbase + AWI_TXD_START, 0);
598 	awi_write_4(sc, sc->sc_txbase + AWI_TXD_NEXT, 0);
599 	awi_write_4(sc, sc->sc_txbase + AWI_TXD_LENGTH, 0);
600 	awi_write_1(sc, sc->sc_txbase + AWI_TXD_RATE, 0);
601 	awi_write_4(sc, sc->sc_txbase + AWI_TXD_NDA, 0);
602 	awi_write_4(sc, sc->sc_txbase + AWI_TXD_NRA, 0);
603 	awi_write_1(sc, sc->sc_txbase + AWI_TXD_STATE, 0);
604 	awi_write_4(sc, AWI_CA_TX_DATA, sc->sc_txbase);
605 	awi_write_4(sc, AWI_CA_TX_MGT, 0);
606 	awi_write_4(sc, AWI_CA_TX_BCAST, 0);
607 	awi_write_4(sc, AWI_CA_TX_PS, 0);
608 	awi_write_4(sc, AWI_CA_TX_CF, 0);
609 	if ((error = awi_cmd(sc, AWI_CMD_INIT_TX, AWI_WAIT)) != 0) {
610 		DPRINTF(("awi_init: failed to start transmitter: %d\n", error));
611 		awi_stop(ifp, 1);
612 		return error;
613 	}
614 
615 	/* start receiver */
616 	if ((error = awi_cmd(sc, AWI_CMD_INIT_RX, AWI_WAIT)) != 0) {
617 		DPRINTF(("awi_init: failed to start receiver: %d\n", error));
618 		awi_stop(ifp, 1);
619 		return error;
620 	}
621 	sc->sc_rxdoff = awi_read_4(sc, AWI_CA_IRX_DATA_DESC);
622 	sc->sc_rxmoff = awi_read_4(sc, AWI_CA_IRX_PS_DESC);
623 
624 	ifp->if_flags |= IFF_RUNNING;
625 	ifp->if_flags &= ~IFF_OACTIVE;
626 	ic->ic_state = IEEE80211_S_INIT;
627 
628 	if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
629 	    ic->ic_opmode == IEEE80211_M_HOSTAP) {
630 		ni->ni_chan = ic->ic_ibss_chan;
631 		ni->ni_intval = ic->ic_lintval;
632 		ni->ni_rssi = 0;
633 		ni->ni_rstamp = 0;
634 		memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp));
635 		ni->ni_rates =
636 		    ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
637 		IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr);
638 		if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
639 			IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr);
640 			ni->ni_esslen = ic->ic_des_esslen;
641 			memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen);
642 			ni->ni_capinfo = IEEE80211_CAPINFO_ESS;
643 			if (ic->ic_phytype == IEEE80211_T_FH) {
644 				ni->ni_fhdwell = 200;   /* XXX */
645 				ni->ni_fhindex = 1;
646 			}
647 		} else {
648 			ni->ni_capinfo = IEEE80211_CAPINFO_IBSS;
649 			memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN);
650 			ni->ni_esslen = 0;
651 		}
652 		if (ic->ic_flags & IEEE80211_F_PRIVACY)
653 			ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY;
654 		if (ic->ic_opmode != IEEE80211_M_AHDEMO)
655 			ic->ic_flags |= IEEE80211_F_SIBSS;
656 		ic->ic_state = IEEE80211_S_SCAN;	/*XXX*/
657 		sc->sc_substate = AWI_ST_NONE;
658 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
659 	} else {
660 		/* XXX check sc->sc_cur_chan */
661 		ni->ni_chan = &ic->ic_channels[sc->sc_cur_chan];
662 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
663 	}
664 	return 0;
665 }
666 
667 static void
668 awi_stop(struct ifnet *ifp, int disable)
669 {
670 	struct awi_softc *sc = ifp->if_softc;
671 
672 	if (!sc->sc_enabled)
673 		return;
674 
675 	DPRINTF(("awi_stop(%d)\n", disable));
676 
677 	ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1);
678 
679 	if (!sc->sc_invalid) {
680 		if (sc->sc_cmd_inprog)
681 			(void)awi_cmd_wait(sc);
682 		(void)awi_cmd(sc, AWI_CMD_KILL_RX, AWI_WAIT);
683 		sc->sc_cmd_inprog = AWI_CMD_FLUSH_TX;
684 		awi_write_1(sc, AWI_CA_FTX_DATA, 1);
685 		awi_write_1(sc, AWI_CA_FTX_MGT, 0);
686 		awi_write_1(sc, AWI_CA_FTX_BCAST, 0);
687 		awi_write_1(sc, AWI_CA_FTX_PS, 0);
688 		awi_write_1(sc, AWI_CA_FTX_CF, 0);
689 		(void)awi_cmd(sc, AWI_CMD_FLUSH_TX, AWI_WAIT);
690 	}
691 	ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
692 	ifp->if_timer = 0;
693 	sc->sc_tx_timer = sc->sc_rx_timer = 0;
694 	if (sc->sc_rxpend != NULL) {
695 		m_freem(sc->sc_rxpend);
696 		sc->sc_rxpend = NULL;
697 	}
698 	IFQ_PURGE(&ifp->if_snd);
699 
700 	if (disable) {
701 		if (!sc->sc_invalid)
702 			am79c930_gcr_setbits(&sc->sc_chip,
703 			    AM79C930_GCR_CORESET);
704 		if (sc->sc_disable)
705 			(*sc->sc_disable)(sc);
706 		sc->sc_enabled = 0;
707 	}
708 }
709 
710 static void
711 awi_start(struct ifnet *ifp)
712 {
713 	struct awi_softc *sc = ifp->if_softc;
714 	struct ieee80211com *ic = &sc->sc_ic;
715 	struct ether_header *eh;
716 	struct ieee80211_node *ni;
717 	struct ieee80211_frame *wh;
718 	struct mbuf *m, *m0;
719 	int len, dowep;
720 	u_int32_t txd, frame, ntxd;
721 	u_int8_t rate;
722 
723 	if (!sc->sc_enabled || sc->sc_invalid)
724 		return;
725 
726 	for (;;) {
727 		txd = sc->sc_txnext;
728 		IF_POLL(&ic->ic_mgtq, m0);
729 		dowep = 0;
730 		if (m0 != NULL) {
731 			len = m0->m_pkthdr.len;
732 			if (awi_next_txd(sc, len, &frame, &ntxd)) {
733 				ifp->if_flags |= IFF_OACTIVE;
734 				break;
735 			}
736 			IF_DEQUEUE(&ic->ic_mgtq, m0);
737 			ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
738 		} else {
739 			if (ic->ic_state != IEEE80211_S_RUN)
740 				break;
741 			IFQ_POLL(&ifp->if_snd, m0);
742 			if (m0 == NULL)
743 				break;
744 			/*
745 			 * Need to calculate the real length to determine
746 			 * if the transmit buffer has a room for the packet.
747 			 */
748 			len = m0->m_pkthdr.len + sizeof(struct ieee80211_frame);
749 			if (!(ifp->if_flags & IFF_LINK0) && !sc->sc_adhoc_ap)
750 				len += sizeof(struct llc) -
751 				    sizeof(struct ether_header);
752 			if (ic->ic_flags & IEEE80211_F_PRIVACY) {
753 				dowep = 1;
754 				len += IEEE80211_WEP_IVLEN +
755 				    IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN;
756 			}
757 			if (awi_next_txd(sc, len, &frame, &ntxd)) {
758 				ifp->if_flags |= IFF_OACTIVE;
759 				break;
760 			}
761 			IFQ_DEQUEUE(&ifp->if_snd, m0);
762 			ifp->if_opackets++;
763 #if NBPFILTER > 0
764 			if (ifp->if_bpf)
765 				bpf_mtap(ifp->if_bpf, m0);
766 #endif
767 			eh = mtod(m0, struct ether_header *);
768 			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
769 			if (ni == NULL) {
770 				ifp->if_oerrors++;
771 				continue;
772 			}
773 			if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap)
774 				m0 = awi_ether_encap(sc, m0);
775 			else {
776 				m0 = ieee80211_encap(ic, m0, ni);
777 			}
778 			if (m0 == NULL) {
779 				ieee80211_free_node(ni);
780 				ifp->if_oerrors++;
781 				continue;
782 			}
783 			wh = mtod(m0, struct ieee80211_frame *);
784 			if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
785 			    (ic->ic_opmode == IEEE80211_M_HOSTAP ||
786 			     ic->ic_opmode == IEEE80211_M_IBSS) &&
787 			    sc->sc_adhoc_ap == 0 &&
788 			    (ifp->if_flags & IFF_LINK0) == 0 &&
789 			    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
790 			    IEEE80211_FC0_TYPE_DATA) {
791 				m_freem(m0);
792 				ieee80211_free_node(ni);
793 				ifp->if_oerrors++;
794 				continue;
795 			}
796 		}
797 #if NBPFILTER > 0
798 		if (ic->ic_rawbpf)
799 			bpf_mtap(ic->ic_rawbpf, m0);
800 #endif
801 		if (dowep) {
802 			if ((ieee80211_crypto_encap(ic, ni, m0)) == NULL) {
803 				m_freem(m0);
804 				ieee80211_free_node(ni);
805 				ifp->if_oerrors++;
806 				continue;
807 			}
808 		}
809 		ieee80211_free_node(ni);
810 #ifdef DIAGNOSTIC
811 		if (m0->m_pkthdr.len != len) {
812 			printf("%s: length %d should be %d\n",
813 			    sc->sc_if.if_xname, m0->m_pkthdr.len, len);
814 			m_freem(m0);
815 			ifp->if_oerrors++;
816 			continue;
817 		}
818 #endif
819 
820 		if ((ifp->if_flags & IFF_DEBUG) && (ifp->if_flags & IFF_LINK2))
821 			ieee80211_dump_pkt(m0->m_data, m0->m_len,
822 			    ic->ic_bss->ni_rates.
823 			        rs_rates[ic->ic_bss->ni_txrate] &
824 			    IEEE80211_RATE_VAL, -1);
825 
826 		for (m = m0, len = 0; m != NULL; m = m->m_next) {
827 			awi_write_bytes(sc, frame + len, mtod(m, u_int8_t *),
828 			    m->m_len);
829 			len += m->m_len;
830 		}
831 		m_freem(m0);
832 		rate = (ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] &
833 		    IEEE80211_RATE_VAL) * 5;
834 		awi_write_1(sc, ntxd + AWI_TXD_STATE, 0);
835 		awi_write_4(sc, txd + AWI_TXD_START, frame);
836 		awi_write_4(sc, txd + AWI_TXD_NEXT, ntxd);
837 		awi_write_4(sc, txd + AWI_TXD_LENGTH, len);
838 		awi_write_1(sc, txd + AWI_TXD_RATE, rate);
839 		awi_write_4(sc, txd + AWI_TXD_NDA, 0);
840 		awi_write_4(sc, txd + AWI_TXD_NRA, 0);
841 		awi_write_1(sc, txd + AWI_TXD_STATE, AWI_TXD_ST_OWN);
842 		sc->sc_txnext = ntxd;
843 
844 		sc->sc_tx_timer = 5;
845 		ifp->if_timer = 1;
846 	}
847 }
848 
849 static void
850 awi_watchdog(struct ifnet *ifp)
851 {
852 	struct awi_softc *sc = ifp->if_softc;
853 	u_int32_t prevdone;
854 	int ocansleep;
855 
856 	ifp->if_timer = 0;
857 	if (!sc->sc_enabled || sc->sc_invalid)
858 		return;
859 
860 	ocansleep = sc->sc_cansleep;
861 	sc->sc_cansleep = 0;
862 	if (sc->sc_tx_timer) {
863 		if (--sc->sc_tx_timer == 0) {
864 			printf("%s: device timeout\n", ifp->if_xname);
865 			prevdone = sc->sc_txdone;
866 			awi_tx_int(sc);
867 			if (sc->sc_txdone == prevdone) {
868 				ifp->if_oerrors++;
869 				awi_init(ifp);
870 				goto out;
871 			}
872 		}
873 		ifp->if_timer = 1;
874 	}
875 	if (sc->sc_rx_timer) {
876 		if (--sc->sc_rx_timer == 0) {
877 			if (sc->sc_ic.ic_state == IEEE80211_S_RUN) {
878 				ieee80211_new_state(&sc->sc_ic,
879 				    IEEE80211_S_SCAN, -1);
880 				goto out;
881 			}
882 		} else
883 			ifp->if_timer = 1;
884 	}
885 	/* TODO: rate control */
886 	ieee80211_watchdog(&sc->sc_ic);
887   out:
888 	sc->sc_cansleep = ocansleep;
889 }
890 
891 static int
892 awi_ioctl(struct ifnet *ifp, u_long cmd, void *data)
893 {
894 	struct awi_softc *sc = ifp->if_softc;
895 	struct ifreq *ifr = (struct ifreq *)data;
896 	int s, error;
897 
898 	s = splnet();
899 	/* serialize ioctl, since we may sleep */
900 	if ((error = awi_lock(sc)) != 0)
901 		goto cantlock;
902 
903 	switch (cmd) {
904 	case SIOCSIFFLAGS:
905 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
906 			break;
907 		if (ifp->if_flags & IFF_UP) {
908 			if (sc->sc_enabled) {
909 				/*
910 				 * To avoid rescanning another access point,
911 				 * do not call awi_init() here.  Instead,
912 				 * only reflect promisc mode settings.
913 				 */
914 				error = awi_mode_init(sc);
915 			} else
916 				error = awi_init(ifp);
917 		} else if (sc->sc_enabled)
918 			awi_stop(ifp, 1);
919 		break;
920 	case SIOCSIFMEDIA:
921 	case SIOCGIFMEDIA:
922 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ic.ic_media, cmd);
923 		break;
924 	case SIOCADDMULTI:
925 	case SIOCDELMULTI:
926 #ifdef __FreeBSD__
927 		error = ENETRESET;	/* XXX */
928 #else
929 		error = ether_ioctl(ifp, cmd, data);
930 #endif
931 		if (error == ENETRESET) {
932 			/* do not rescan */
933 			if (ifp->if_flags & IFF_RUNNING)
934 				error = awi_mode_init(sc);
935 			else
936 				error = 0;
937 		}
938 		break;
939 	default:
940 		error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
941 		if (error == ENETRESET) {
942 			if (sc->sc_enabled)
943 				error = awi_init(ifp);
944 			else
945 				error = 0;
946 		}
947 		break;
948 	}
949 	awi_unlock(sc);
950   cantlock:
951 	splx(s);
952 	return error;
953 }
954 
955 /*
956  * Called from ifmedia_ioctl via awi_ioctl with lock obtained.
957  *
958  * TBD factor with ieee80211_media_change
959  */
960 static int
961 awi_media_change(struct ifnet *ifp)
962 {
963 	struct awi_softc *sc = ifp->if_softc;
964 	struct ieee80211com *ic = &sc->sc_ic;
965 	struct ifmedia_entry *ime;
966 	enum ieee80211_opmode newmode;
967 	int i, rate, newadhoc_ap, error = 0;
968 
969 	ime = ic->ic_media.ifm_cur;
970 	if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) {
971 		i = -1;
972 	} else {
973 		struct ieee80211_rateset *rs =
974 		    &ic->ic_sup_rates[(ic->ic_phytype == IEEE80211_T_FH)
975 		    ? IEEE80211_MODE_FH : IEEE80211_MODE_11B];
976 		rate = ieee80211_media2rate(ime->ifm_media);
977 		if (rate == 0)
978 			return EINVAL;
979 		for (i = 0; i < rs->rs_nrates; i++) {
980 			if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate)
981 				break;
982 		}
983 		if (i == rs->rs_nrates)
984 			return EINVAL;
985 	}
986 	if (ic->ic_fixed_rate != i) {
987 		ic->ic_fixed_rate = i;
988 		error = ENETRESET;
989 	}
990 
991 	/*
992 	 * combination of mediaopt
993 	 *
994 	 * hostap adhoc flag0	opmode  adhoc_ap	comment
995 	 *   +      -     -	HOSTAP      0		HostAP
996 	 *   -      +     -	IBSS        0		IBSS
997 	 *   -      +     +	AHDEMO      0		WaveLAN adhoc
998 	 *   -      -     +	IBSS        1		Melco old Sta
999 	 *							also LINK0
1000 	 *   -      -     -	STA         0		Infra Station
1001 	 */
1002 	newadhoc_ap = 0;
1003 	if (ime->ifm_media & IFM_IEEE80211_HOSTAP)
1004 		newmode = IEEE80211_M_HOSTAP;
1005 	else if (ime->ifm_media & IFM_IEEE80211_ADHOC) {
1006 		if (ic->ic_phytype == IEEE80211_T_DS &&
1007 		    (ime->ifm_media & IFM_FLAG0))
1008 			newmode = IEEE80211_M_AHDEMO;
1009 		else
1010 			newmode = IEEE80211_M_IBSS;
1011 	} else if (ime->ifm_media & IFM_FLAG0) {
1012 		newmode = IEEE80211_M_IBSS;
1013 		newadhoc_ap = 1;
1014 	} else
1015 		newmode = IEEE80211_M_STA;
1016 	if (ic->ic_opmode != newmode || sc->sc_adhoc_ap != newadhoc_ap) {
1017 		ic->ic_opmode = newmode;
1018 		sc->sc_adhoc_ap = newadhoc_ap;
1019 		error = ENETRESET;
1020 	}
1021 
1022 	if (error == ENETRESET) {
1023 		if (sc->sc_enabled)
1024 			error = awi_init(ifp);
1025 		else
1026 			error = 0;
1027 	}
1028 	return error;
1029 }
1030 
1031 static void
1032 awi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1033 {
1034 	struct awi_softc *sc = ifp->if_softc;
1035 	struct ieee80211com *ic = &sc->sc_ic;
1036 	int rate;
1037 	enum ieee80211_phymode mode;
1038 
1039 	imr->ifm_status = IFM_AVALID;
1040 	if (ic->ic_state == IEEE80211_S_RUN)
1041 		imr->ifm_status |= IFM_ACTIVE;
1042 	imr->ifm_active = IFM_IEEE80211;
1043 	if (ic->ic_phytype == IEEE80211_T_FH)
1044 		mode = IEEE80211_MODE_FH;
1045 	else
1046 		mode = IEEE80211_MODE_11B;
1047 	if (ic->ic_state == IEEE80211_S_RUN) {
1048 		rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] &
1049 		    IEEE80211_RATE_VAL;
1050 	} else {
1051 		if (ic->ic_fixed_rate == -1)
1052 			rate = 0;
1053 		else
1054 			rate = ic->ic_sup_rates[mode].
1055 			    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
1056 	}
1057 	imr->ifm_active |= ieee80211_rate2media(ic, rate, mode);
1058 	switch (ic->ic_opmode) {
1059 	case IEEE80211_M_MONITOR: /* we should never reach here */
1060 		break;
1061 	case IEEE80211_M_STA:
1062 		break;
1063 	case IEEE80211_M_IBSS:
1064 		if (sc->sc_adhoc_ap)
1065 			imr->ifm_active |= IFM_FLAG0;
1066 		else
1067 			imr->ifm_active |= IFM_IEEE80211_ADHOC;
1068 		break;
1069 	case IEEE80211_M_AHDEMO:
1070 		imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1071 		break;
1072 	case IEEE80211_M_HOSTAP:
1073 		imr->ifm_active |= IFM_IEEE80211_HOSTAP;
1074 		break;
1075 	}
1076 }
1077 
1078 static int
1079 awi_mode_init(struct awi_softc *sc)
1080 {
1081 	struct ifnet *ifp = &sc->sc_if;
1082 	int n, error;
1083 #ifdef __FreeBSD__
1084 	struct ifmultiaddr *ifma;
1085 #else
1086 	struct ether_multi *enm;
1087 	struct ether_multistep step;
1088 #endif
1089 
1090 	/* reinitialize muticast filter */
1091 	n = 0;
1092 	sc->sc_mib_local.Accept_All_Multicast_Dis = 0;
1093 	if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP &&
1094 	    (ifp->if_flags & IFF_PROMISC)) {
1095 		sc->sc_mib_mac.aPromiscuous_Enable = 1;
1096 		goto set_mib;
1097 	}
1098 	sc->sc_mib_mac.aPromiscuous_Enable = 0;
1099 #ifdef __FreeBSD__
1100 	if (ifp->if_amcount != 0)
1101 		goto set_mib;
1102 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1103 		if (ifma->ifma_addr->sa_family != AF_LINK)
1104 			continue;
1105 		if (n == AWI_GROUP_ADDR_SIZE)
1106 			goto set_mib;
1107 		IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n],
1108 		    CLLADDR(satocsdl(ifma->ifma_addr)));
1109 		n++;
1110 	}
1111 #else
1112 	ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
1113 	while (enm != NULL) {
1114 		if (n == AWI_GROUP_ADDR_SIZE ||
1115 		    !IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi))
1116 			goto set_mib;
1117 		IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n],
1118 		    enm->enm_addrlo);
1119 		n++;
1120 		ETHER_NEXT_MULTI(step, enm);
1121 	}
1122 #endif
1123 	for (; n < AWI_GROUP_ADDR_SIZE; n++)
1124 		memset(sc->sc_mib_addr.aGroup_Addresses[n], 0,
1125 		    IEEE80211_ADDR_LEN);
1126 	sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
1127 
1128   set_mib:
1129 	if (sc->sc_mib_local.Accept_All_Multicast_Dis)
1130 		ifp->if_flags &= ~IFF_ALLMULTI;
1131 	else
1132 		ifp->if_flags |= IFF_ALLMULTI;
1133 	sc->sc_mib_mgt.Wep_Required =
1134 	    (sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) ? AWI_WEP_ON : AWI_WEP_OFF;
1135 
1136 	if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) ||
1137 	    (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_ADDR, AWI_WAIT)) ||
1138 	    (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MAC, AWI_WAIT)) ||
1139 	    (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT, AWI_WAIT)) ||
1140 	    (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_PHY, AWI_WAIT))) {
1141 		DPRINTF(("awi_mode_init: MIB set failed: %d\n", error));
1142 		return error;
1143 	}
1144 	return 0;
1145 }
1146 
1147 static void
1148 awi_rx_int(struct awi_softc *sc)
1149 {
1150 	struct ieee80211com *ic = &sc->sc_ic;
1151 	struct ifnet *ifp = &sc->sc_if;
1152 	struct ieee80211_frame_min *wh;
1153 	struct ieee80211_node *ni;
1154 	u_int8_t state, rate, rssi;
1155 	u_int16_t len;
1156 	u_int32_t frame, next, rstamp, rxoff;
1157 	struct mbuf *m;
1158 
1159 	rxoff = sc->sc_rxdoff;
1160 	for (;;) {
1161 		state = awi_read_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE);
1162 		if (state & AWI_RXD_ST_OWN)
1163 			break;
1164 		if (!(state & AWI_RXD_ST_CONSUMED)) {
1165 			if (sc->sc_substate != AWI_ST_NONE)
1166 				goto rx_next;
1167 			if (state & AWI_RXD_ST_RXERROR) {
1168 				ifp->if_ierrors++;
1169 				goto rx_next;
1170 			}
1171 			len    = awi_read_2(sc, rxoff + AWI_RXD_LEN);
1172 			rate   = awi_read_1(sc, rxoff + AWI_RXD_RATE);
1173 			rssi   = awi_read_1(sc, rxoff + AWI_RXD_RSSI);
1174 			frame  = awi_read_4(sc, rxoff + AWI_RXD_START_FRAME) &
1175 			    0x7fff;
1176 			rstamp = awi_read_4(sc, rxoff + AWI_RXD_LOCALTIME);
1177 			m = awi_devget(sc, frame, len);
1178 			if (m == NULL) {
1179 				ifp->if_ierrors++;
1180 				goto rx_next;
1181 			}
1182 			if (state & AWI_RXD_ST_LF) {
1183 				/* TODO check my bss */
1184 				if (!(sc->sc_ic.ic_flags & IEEE80211_F_SIBSS) &&
1185 				    sc->sc_ic.ic_state == IEEE80211_S_RUN) {
1186 					sc->sc_rx_timer = 10;
1187 					ifp->if_timer = 1;
1188 				}
1189 				if ((ifp->if_flags & IFF_DEBUG) &&
1190 				    (ifp->if_flags & IFF_LINK2))
1191 					ieee80211_dump_pkt(m->m_data, m->m_len,
1192 					    rate / 5, rssi);
1193 				if ((ifp->if_flags & IFF_LINK0) ||
1194 				    sc->sc_adhoc_ap)
1195 					m = awi_ether_modcap(sc, m);
1196 				else
1197 					m = m_pullup(m, sizeof(*wh));
1198 				if (m == NULL) {
1199 					ifp->if_ierrors++;
1200 					goto rx_next;
1201 				}
1202 				wh = mtod(m, struct ieee80211_frame_min *);
1203 				ni = ieee80211_find_rxnode(ic, wh);
1204 				ieee80211_input(ic, m, ni, rssi, rstamp);
1205 				/*
1206 				 * The frame may have caused the
1207 				 * node to be marked for reclamation
1208 				 * (e.g. in response to a DEAUTH
1209 				 * message) so use release_node here
1210 				 * instead of unref_node.
1211 				 */
1212 				ieee80211_free_node(ni);
1213 			} else
1214 				sc->sc_rxpend = m;
1215   rx_next:
1216 			state |= AWI_RXD_ST_CONSUMED;
1217 			awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state);
1218 		}
1219 		next = awi_read_4(sc, rxoff + AWI_RXD_NEXT);
1220 		if (next & AWI_RXD_NEXT_LAST)
1221 			break;
1222 		/* make sure the next pointer is correct */
1223 		if (next != awi_read_4(sc, rxoff + AWI_RXD_NEXT))
1224 			break;
1225 		state |= AWI_RXD_ST_OWN;
1226 		awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state);
1227 		rxoff = next & 0x7fff;
1228 	}
1229 	sc->sc_rxdoff = rxoff;
1230 }
1231 
1232 static void
1233 awi_tx_int(struct awi_softc *sc)
1234 {
1235 	struct ifnet *ifp = &sc->sc_if;
1236 	u_int8_t flags;
1237 
1238 	while (sc->sc_txdone != sc->sc_txnext) {
1239 		flags = awi_read_1(sc, sc->sc_txdone + AWI_TXD_STATE);
1240 		if ((flags & AWI_TXD_ST_OWN) || !(flags & AWI_TXD_ST_DONE))
1241 			break;
1242 		if (flags & AWI_TXD_ST_ERROR)
1243 			ifp->if_oerrors++;
1244 		sc->sc_txdone = awi_read_4(sc, sc->sc_txdone + AWI_TXD_NEXT) &
1245 		    0x7fff;
1246 	}
1247 	DPRINTF2(("awi_txint: txdone %d txnext %d txbase %d txend %d\n",
1248 	    sc->sc_txdone, sc->sc_txnext, sc->sc_txbase, sc->sc_txend));
1249 	sc->sc_tx_timer = 0;
1250 	ifp->if_flags &= ~IFF_OACTIVE;
1251 	awi_start(ifp);
1252 }
1253 
1254 static struct mbuf *
1255 awi_devget(struct awi_softc *sc, u_int32_t off, u_int16_t len)
1256 {
1257 	struct ifnet *ifp = &sc->sc_if;
1258 	struct mbuf *m;
1259 	struct mbuf *top, **mp;
1260 	u_int tlen;
1261 
1262 	top = sc->sc_rxpend;
1263 	mp = &top;
1264 	if (top != NULL) {
1265 		sc->sc_rxpend = NULL;
1266 		top->m_pkthdr.len += len;
1267 		m = top;
1268 		while (*mp != NULL) {
1269 			m = *mp;
1270 			mp = &m->m_next;
1271 		}
1272 		if (m->m_flags & M_EXT)
1273 			tlen = m->m_ext.ext_size;
1274 		else if (m->m_flags & M_PKTHDR)
1275 			tlen = MHLEN;
1276 		else
1277 			tlen = MLEN;
1278 		tlen -= m->m_len;
1279 		if (tlen > len)
1280 			tlen = len;
1281 		awi_read_bytes(sc, off, mtod(m, u_int8_t *) + m->m_len, tlen);
1282 		off += tlen;
1283 		len -= tlen;
1284 	}
1285 
1286 	while (len > 0) {
1287 		if (top == NULL) {
1288 			MGETHDR(m, M_DONTWAIT, MT_DATA);
1289 			if (m == NULL)
1290 				return NULL;
1291 			m->m_pkthdr.rcvif = ifp;
1292 			m->m_pkthdr.len = len;
1293 			m->m_len = MHLEN;
1294 			m->m_flags |= M_HASFCS;
1295 		} else {
1296 			MGET(m, M_DONTWAIT, MT_DATA);
1297 			if (m == NULL) {
1298 				m_freem(top);
1299 				return NULL;
1300 			}
1301 			m->m_len = MLEN;
1302 		}
1303 		if (len >= MINCLSIZE) {
1304 			MCLGET(m, M_DONTWAIT);
1305 			if (m->m_flags & M_EXT)
1306 				m->m_len = m->m_ext.ext_size;
1307 		}
1308 		if (top == NULL) {
1309 			int hdrlen = sizeof(struct ieee80211_frame) +
1310 			    sizeof(struct llc);
1311 			char *newdata = (char *)
1312 			    ALIGN(m->m_data + hdrlen) - hdrlen;
1313 			m->m_len -= newdata - m->m_data;
1314 			m->m_data = newdata;
1315 		}
1316 		if (m->m_len > len)
1317 			m->m_len = len;
1318 		awi_read_bytes(sc, off, mtod(m, u_int8_t *), m->m_len);
1319 		off += m->m_len;
1320 		len -= m->m_len;
1321 		*mp = m;
1322 		mp = &m->m_next;
1323 	}
1324 	return top;
1325 }
1326 
1327 /*
1328  * Initialize hardware and start firmware to accept commands.
1329  * Called everytime after power on firmware.
1330  */
1331 
1332 static int
1333 awi_hw_init(struct awi_softc *sc)
1334 {
1335 	u_int8_t status;
1336 	u_int16_t intmask;
1337 	int i, error;
1338 
1339 	sc->sc_enab_intr = 0;
1340 	sc->sc_invalid = 0;	/* XXX: really? */
1341 	awi_drvstate(sc, AWI_DRV_RESET);
1342 
1343 	/* reset firmware */
1344 	am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_CORESET);
1345 	DELAY(100);
1346 	awi_write_1(sc, AWI_SELFTEST, 0);
1347 	awi_write_1(sc, AWI_CMD, 0);
1348 	awi_write_1(sc, AWI_BANNER, 0);
1349 	am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_CORESET);
1350 	DELAY(100);
1351 
1352 	/* wait for selftest completion */
1353 	for (i = 0; ; i++) {
1354 		if (sc->sc_invalid)
1355 			return ENXIO;
1356 		if (i >= AWI_SELFTEST_TIMEOUT*hz/1000) {
1357 			printf("%s: failed to complete selftest (timeout)\n",
1358 			    sc->sc_if.if_xname);
1359 			return ENXIO;
1360 		}
1361 		status = awi_read_1(sc, AWI_SELFTEST);
1362 		if ((status & 0xf0) == 0xf0)
1363 			break;
1364 		if (sc->sc_cansleep) {
1365 			sc->sc_sleep_cnt++;
1366 			(void)tsleep(sc, PWAIT, "awitst", 1);
1367 			sc->sc_sleep_cnt--;
1368 		} else {
1369 			DELAY(1000*1000/hz);
1370 		}
1371 	}
1372 	if (status != AWI_SELFTEST_PASSED) {
1373 		printf("%s: failed to complete selftest (code %x)\n",
1374 		    sc->sc_if.if_xname, status);
1375 		return ENXIO;
1376 	}
1377 
1378 	/* check banner to confirm firmware write it */
1379 	awi_read_bytes(sc, AWI_BANNER, sc->sc_banner, AWI_BANNER_LEN);
1380 	if (memcmp(sc->sc_banner, "PCnetMobile:", 12) != 0) {
1381 		printf("%s: failed to complete selftest (bad banner)\n",
1382 		    sc->sc_if.if_xname);
1383 		for (i = 0; i < AWI_BANNER_LEN; i++)
1384 			printf("%s%02x", i ? ":" : "\t", sc->sc_banner[i]);
1385 		printf("\n");
1386 		return ENXIO;
1387 	}
1388 
1389 	/* initializing interrupt */
1390 	sc->sc_enab_intr = 1;
1391 	error = awi_intr_lock(sc);
1392 	if (error)
1393 		return error;
1394 	intmask = AWI_INT_GROGGY | AWI_INT_SCAN_CMPLT |
1395 	    AWI_INT_TX | AWI_INT_RX | AWI_INT_CMD;
1396 	awi_write_1(sc, AWI_INTMASK, ~intmask & 0xff);
1397 	awi_write_1(sc, AWI_INTMASK2, 0);
1398 	awi_write_1(sc, AWI_INTSTAT, 0);
1399 	awi_write_1(sc, AWI_INTSTAT2, 0);
1400 	awi_intr_unlock(sc);
1401 	am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_ENECINT);
1402 
1403 	/* issuing interface test command */
1404 	error = awi_cmd(sc, AWI_CMD_NOP, AWI_WAIT);
1405 	if (error) {
1406 		printf("%s: failed to complete selftest",
1407 		    sc->sc_if.if_xname);
1408 		if (error == ENXIO)
1409 			printf(" (no hardware)\n");
1410 		else if (error != EWOULDBLOCK)
1411 			printf(" (error %d)\n", error);
1412 		else if (sc->sc_cansleep)
1413 			printf(" (lost interrupt)\n");
1414 		else
1415 			printf(" (command timeout)\n");
1416 		return error;
1417 	}
1418 
1419 	/* Initialize VBM */
1420 	awi_write_1(sc, AWI_VBM_OFFSET, 0);
1421 	awi_write_1(sc, AWI_VBM_LENGTH, 1);
1422 	awi_write_1(sc, AWI_VBM_BITMAP, 0);
1423 	return 0;
1424 }
1425 
1426 /*
1427  * Extract the factory default MIB value from firmware and assign the driver
1428  * default value.
1429  * Called once at attaching the interface.
1430  */
1431 
1432 static int
1433 awi_init_mibs(struct awi_softc *sc)
1434 {
1435 	int chan, i, error;
1436 	struct ieee80211com *ic = &sc->sc_ic;
1437 	struct awi_chanset *cs;
1438 
1439 	if ((error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) ||
1440 	    (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_ADDR, AWI_WAIT)) ||
1441 	    (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MAC, AWI_WAIT)) ||
1442 	    (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MGT, AWI_WAIT)) ||
1443 	    (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_PHY, AWI_WAIT))) {
1444 		printf("%s: failed to get default mib value (error %d)\n",
1445 		    sc->sc_if.if_xname, error);
1446 		return error;
1447 	}
1448 
1449 	memset(&sc->sc_ic.ic_chan_avail, 0, sizeof(sc->sc_ic.ic_chan_avail));
1450 	for (cs = awi_chanset; ; cs++) {
1451 		if (cs->cs_type == 0) {
1452 			printf("%s: failed to set available channel\n",
1453 			    sc->sc_if.if_xname);
1454 			return ENXIO;
1455 		}
1456 		if (cs->cs_type == sc->sc_mib_phy.IEEE_PHY_Type &&
1457 		    cs->cs_region == sc->sc_mib_phy.aCurrent_Reg_Domain)
1458 			break;
1459 	}
1460 	if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
1461 		for (i = cs->cs_min; i <= cs->cs_max; i++) {
1462 			chan = IEEE80211_FH_CHAN(i % 3 + 1, i);
1463 			setbit(sc->sc_ic.ic_chan_avail, chan);
1464 			/* XXX for FHSS, does frequency matter? */
1465 			ic->ic_channels[chan].ic_freq = 0;
1466 			ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS;
1467 			/*
1468 			 * According to the IEEE 802.11 specification,
1469 			 * hop pattern parameter for FH phy should be
1470 			 * incremented by 3 for given hop chanset, i.e.,
1471 			 * the chanset parameter is calculated for given
1472 			 * hop patter.  However, BayStack 650 Access Points
1473 			 * apparently use fixed hop chanset parameter value
1474 			 * 1 for any hop pattern.  So we also try this
1475 			 * combination of hop chanset and pattern.
1476 			 */
1477 			chan = IEEE80211_FH_CHAN(1, i);
1478 			setbit(sc->sc_ic.ic_chan_avail, chan);
1479 			ic->ic_channels[chan].ic_freq = 0; /* XXX */
1480 			ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS;
1481 		}
1482 	} else {
1483 		for (i = cs->cs_min; i <= cs->cs_max; i++) {
1484 			setbit(sc->sc_ic.ic_chan_avail, i);
1485 			ic->ic_channels[i].ic_freq =
1486 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
1487 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B;
1488 		}
1489 	}
1490 	sc->sc_cur_chan = cs->cs_def;
1491 	ic->ic_ibss_chan = &ic->ic_channels[cs->cs_def];
1492 
1493 	sc->sc_mib_local.Fragmentation_Dis = 1;
1494 	sc->sc_mib_local.Add_PLCP_Dis = 0;
1495 	sc->sc_mib_local.MAC_Hdr_Prsv = 0;
1496 	sc->sc_mib_local.Rx_Mgmt_Que_En = 0;
1497 	sc->sc_mib_local.Re_Assembly_Dis = 1;
1498 	sc->sc_mib_local.Strip_PLCP_Dis = 0;
1499 	sc->sc_mib_local.Power_Saving_Mode_Dis = 1;
1500 	sc->sc_mib_local.Accept_All_Multicast_Dis = 1;
1501 	sc->sc_mib_local.Check_Seq_Cntl_Dis = 0;
1502 	sc->sc_mib_local.Flush_CFP_Queue_On_CF_End = 0;
1503 	sc->sc_mib_local.Network_Mode = 1;
1504 	sc->sc_mib_local.PWD_Lvl = 0;
1505 	sc->sc_mib_local.CFP_Mode = 0;
1506 
1507 	/* allocate buffers */
1508 	sc->sc_txbase = AWI_BUFFERS;
1509 	sc->sc_txend = sc->sc_txbase +
1510 	    (AWI_TXD_SIZE + sizeof(struct ieee80211_frame) +
1511 	    sizeof(struct ether_header) + ETHERMTU) * AWI_NTXBUFS;
1512 	LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Offset, sc->sc_txbase);
1513 	LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Size,
1514 	    sc->sc_txend - sc->sc_txbase);
1515 	LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend);
1516 	LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size,
1517 	    AWI_BUFFERS_END - sc->sc_txend);
1518 	sc->sc_mib_local.Acting_as_AP = 0;
1519 	sc->sc_mib_local.Fill_CFP = 0;
1520 
1521 	memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE);
1522 	sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID;
1523 
1524 	sc->sc_mib_mgt.aPower_Mgt_Mode = 0;
1525 	sc->sc_mib_mgt.aDTIM_Period = 1;
1526 	LE_WRITE_2(&sc->sc_mib_mgt.aATIM_Window, 0);
1527 	return 0;
1528 }
1529 
1530 static int
1531 awi_mib(struct awi_softc *sc, u_int8_t cmd, u_int8_t mib, int wflag)
1532 {
1533 	int error;
1534 	u_int8_t size, *ptr;
1535 
1536 	switch (mib) {
1537 	case AWI_MIB_LOCAL:
1538 		ptr = (u_int8_t *)&sc->sc_mib_local;
1539 		size = sizeof(sc->sc_mib_local);
1540 		break;
1541 	case AWI_MIB_ADDR:
1542 		ptr = (u_int8_t *)&sc->sc_mib_addr;
1543 		size = sizeof(sc->sc_mib_addr);
1544 		break;
1545 	case AWI_MIB_MAC:
1546 		ptr = (u_int8_t *)&sc->sc_mib_mac;
1547 		size = sizeof(sc->sc_mib_mac);
1548 		break;
1549 	case AWI_MIB_STAT:
1550 		ptr = (u_int8_t *)&sc->sc_mib_stat;
1551 		size = sizeof(sc->sc_mib_stat);
1552 		break;
1553 	case AWI_MIB_MGT:
1554 		ptr = (u_int8_t *)&sc->sc_mib_mgt;
1555 		size = sizeof(sc->sc_mib_mgt);
1556 		break;
1557 	case AWI_MIB_PHY:
1558 		ptr = (u_int8_t *)&sc->sc_mib_phy;
1559 		size = sizeof(sc->sc_mib_phy);
1560 		break;
1561 	default:
1562 		return EINVAL;
1563 	}
1564 	if (sc->sc_cmd_inprog) {
1565 		if ((error = awi_cmd_wait(sc)) != 0) {
1566 			if (error == EWOULDBLOCK) {
1567 				DPRINTF(("awi_mib: cmd %d inprog",
1568 				    sc->sc_cmd_inprog));
1569 			}
1570 			return error;
1571 		}
1572 	}
1573 	sc->sc_cmd_inprog = cmd;
1574 	if (cmd == AWI_CMD_SET_MIB)
1575 		awi_write_bytes(sc, AWI_CA_MIB_DATA, ptr, size);
1576 	awi_write_1(sc, AWI_CA_MIB_TYPE, mib);
1577 	awi_write_1(sc, AWI_CA_MIB_SIZE, size);
1578 	awi_write_1(sc, AWI_CA_MIB_INDEX, 0);
1579 	if ((error = awi_cmd(sc, cmd, wflag)) != 0)
1580 		return error;
1581 	if (cmd == AWI_CMD_GET_MIB) {
1582 		awi_read_bytes(sc, AWI_CA_MIB_DATA, ptr, size);
1583 #ifdef AWI_DEBUG
1584 		if (awi_debug) {
1585 			int i;
1586 
1587 			printf("awi_mib: #%d:", mib);
1588 			for (i = 0; i < size; i++)
1589 				printf(" %02x", ptr[i]);
1590 			printf("\n");
1591 		}
1592 #endif
1593 	}
1594 	return 0;
1595 }
1596 
1597 static int
1598 awi_cmd(struct awi_softc *sc, u_int8_t cmd, int wflag)
1599 {
1600 	u_int8_t status;
1601 	int error = 0;
1602 #ifdef AWI_DEBUG
1603 	static const char *cmdname[] = {
1604 	    "IDLE", "NOP", "SET_MIB", "INIT_TX", "FLUSH_TX", "INIT_RX",
1605 	    "KILL_RX", "SLEEP", "WAKE", "GET_MIB", "SCAN", "SYNC", "RESUME"
1606 	};
1607 #endif
1608 
1609 #ifdef AWI_DEBUG
1610 	if (awi_debug > 1) {
1611 		if (cmd >= sizeof(cmdname)/sizeof(cmdname[0]))
1612 			printf("awi_cmd: #%d", cmd);
1613 		else
1614 			printf("awi_cmd: %s", cmdname[cmd]);
1615 		printf(" %s\n", wflag == AWI_NOWAIT ? "nowait" : "wait");
1616 	}
1617 #endif
1618 	sc->sc_cmd_inprog = cmd;
1619 	awi_write_1(sc, AWI_CMD_STATUS, AWI_STAT_IDLE);
1620 	awi_write_1(sc, AWI_CMD, cmd);
1621 	if (wflag == AWI_NOWAIT)
1622 		return EINPROGRESS;
1623 	if ((error = awi_cmd_wait(sc)) != 0)
1624 		return error;
1625 	status = awi_read_1(sc, AWI_CMD_STATUS);
1626 	awi_write_1(sc, AWI_CMD, 0);
1627 	switch (status) {
1628 	case AWI_STAT_OK:
1629 		break;
1630 	case AWI_STAT_BADPARM:
1631 		return EINVAL;
1632 	default:
1633 		printf("%s: command %d failed %x\n",
1634 		    sc->sc_if.if_xname, cmd, status);
1635 		return ENXIO;
1636 	}
1637 	return 0;
1638 }
1639 
1640 static int
1641 awi_cmd_wait(struct awi_softc *sc)
1642 {
1643 	int i, error = 0;
1644 
1645 	i = 0;
1646 	while (sc->sc_cmd_inprog) {
1647 		if (sc->sc_invalid)
1648 			return ENXIO;
1649 		if (awi_read_1(sc, AWI_CMD) != sc->sc_cmd_inprog) {
1650 			printf("%s: failed to access hardware\n",
1651 			    sc->sc_if.if_xname);
1652 			sc->sc_invalid = 1;
1653 			return ENXIO;
1654 		}
1655 		if (sc->sc_cansleep) {
1656 			sc->sc_sleep_cnt++;
1657 			error = tsleep(sc, PWAIT, "awicmd",
1658 			    AWI_CMD_TIMEOUT*hz/1000);
1659 			sc->sc_sleep_cnt--;
1660 		} else {
1661 			if (awi_read_1(sc, AWI_CMD_STATUS) != AWI_STAT_IDLE) {
1662 				awi_cmd_done(sc);
1663 				break;
1664 			}
1665 			if (i++ >= AWI_CMD_TIMEOUT*1000/10)
1666 				error = EWOULDBLOCK;
1667 			else
1668 				DELAY(10);
1669 		}
1670 		if (error)
1671 			break;
1672 	}
1673 	if (error) {
1674 		DPRINTF(("awi_cmd_wait: cmd 0x%x, error %d\n",
1675 		    sc->sc_cmd_inprog, error));
1676 	}
1677 	return error;
1678 }
1679 
1680 static void
1681 awi_cmd_done(struct awi_softc *sc)
1682 {
1683 	u_int8_t cmd, status;
1684 
1685 	status = awi_read_1(sc, AWI_CMD_STATUS);
1686 	if (status == AWI_STAT_IDLE)
1687 		return;		/* stray interrupt */
1688 
1689 	cmd = sc->sc_cmd_inprog;
1690 	sc->sc_cmd_inprog = 0;
1691 	wakeup(sc);
1692 	awi_write_1(sc, AWI_CMD, 0);
1693 
1694 	if (status != AWI_STAT_OK) {
1695 		printf("%s: command %d failed %x\n",
1696 		    sc->sc_if.if_xname, cmd, status);
1697 		sc->sc_substate = AWI_ST_NONE;
1698 		return;
1699 	}
1700 	if (sc->sc_substate != AWI_ST_NONE)
1701 		(void)ieee80211_new_state(&sc->sc_ic, sc->sc_nstate, -1);
1702 }
1703 
1704 static int
1705 awi_next_txd(struct awi_softc *sc, int len, u_int32_t *framep, u_int32_t *ntxdp)
1706 {
1707 	u_int32_t txd, ntxd, frame;
1708 
1709 	txd = sc->sc_txnext;
1710 	frame = txd + AWI_TXD_SIZE;
1711 	if (frame + len > sc->sc_txend)
1712 		frame = sc->sc_txbase;
1713 	ntxd = frame + len;
1714 	if (ntxd + AWI_TXD_SIZE > sc->sc_txend)
1715 		ntxd = sc->sc_txbase;
1716 	*framep = frame;
1717 	*ntxdp = ntxd;
1718 	/*
1719 	 * Determine if there are any room in ring buffer.
1720 	 *		--- send wait,  === new data,  +++ conflict (ENOBUFS)
1721 	 *   base........................end
1722 	 *	   done----txd=====ntxd		OK
1723 	 *	 --txd=====done++++ntxd--	full
1724 	 *	 --txd=====ntxd    done--	OK
1725 	 *	 ==ntxd    done----txd===	OK
1726 	 *	 ==done++++ntxd----txd===	full
1727 	 *	 ++ntxd    txd=====done++	full
1728 	 */
1729 	if (txd < ntxd) {
1730 		if (txd < sc->sc_txdone && ntxd + AWI_TXD_SIZE > sc->sc_txdone)
1731 			return ENOBUFS;
1732 	} else {
1733 		if (txd < sc->sc_txdone || ntxd + AWI_TXD_SIZE > sc->sc_txdone)
1734 			return ENOBUFS;
1735 	}
1736 	return 0;
1737 }
1738 
1739 static int
1740 awi_lock(struct awi_softc *sc)
1741 {
1742 	int error = 0;
1743 
1744 #ifdef __NetBSD__
1745 	if (curlwp == NULL)
1746 #else
1747 	if (curproc == NULL)
1748 #endif
1749 	{
1750 		/*
1751 		 * XXX
1752 		 * Though driver ioctl should be called with context,
1753 		 * KAME ipv6 stack calls ioctl in interrupt for now.
1754 		 * We simply abort the request if there are other
1755 		 * ioctl requests in progress.
1756 		 */
1757 		if (sc->sc_busy) {
1758 			if (sc->sc_invalid)
1759 				return ENXIO;
1760 			return EWOULDBLOCK;
1761 		}
1762 		sc->sc_busy = 1;
1763 		sc->sc_cansleep = 0;
1764 		return 0;
1765 	}
1766 	while (sc->sc_busy) {
1767 		if (sc->sc_invalid)
1768 			return ENXIO;
1769 		sc->sc_sleep_cnt++;
1770 		error = tsleep(sc, PWAIT | PCATCH, "awilck", 0);
1771 		sc->sc_sleep_cnt--;
1772 		if (error)
1773 			return error;
1774 	}
1775 	sc->sc_busy = 1;
1776 	sc->sc_cansleep = 1;
1777 	return 0;
1778 }
1779 
1780 static void
1781 awi_unlock(struct awi_softc *sc)
1782 {
1783 	sc->sc_busy = 0;
1784 	sc->sc_cansleep = 0;
1785 	if (sc->sc_sleep_cnt)
1786 		wakeup(sc);
1787 }
1788 
1789 static int
1790 awi_intr_lock(struct awi_softc *sc)
1791 {
1792 	u_int8_t status;
1793 	int i, retry;
1794 
1795 	status = 1;
1796 	for (retry = 0; retry < 10; retry++) {
1797 		for (i = 0; i < AWI_LOCKOUT_TIMEOUT*1000/5; i++) {
1798 			if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0)
1799 				break;
1800 			DELAY(5);
1801 		}
1802 		if (status != 0)
1803 			break;
1804 		awi_write_1(sc, AWI_LOCKOUT_MAC, 1);
1805 		if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0)
1806 			break;
1807 		awi_write_1(sc, AWI_LOCKOUT_MAC, 0);
1808 	}
1809 	if (status != 0) {
1810 		printf("%s: failed to lock interrupt\n",
1811 		    sc->sc_if.if_xname);
1812 		return ENXIO;
1813 	}
1814 	return 0;
1815 }
1816 
1817 static void
1818 awi_intr_unlock(struct awi_softc *sc)
1819 {
1820 
1821 	awi_write_1(sc, AWI_LOCKOUT_MAC, 0);
1822 }
1823 
1824 static int
1825 awi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1826 {
1827 	struct ifnet *ifp = ic->ic_ifp;
1828 	struct awi_softc *sc = ifp->if_softc;
1829 	struct ieee80211_node *ni;
1830 	int error;
1831 	u_int8_t newmode;
1832 	enum ieee80211_state ostate;
1833 #ifdef AWI_DEBUG
1834 	static const char *stname[] =
1835 	    { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" };
1836 	static const char *substname[] =
1837 	    { "NONE", "SCAN_INIT", "SCAN_SETMIB", "SCAN_SCCMD",
1838 	      "SUB_INIT", "SUB_SETSS", "SUB_SYNC" };
1839 #endif /* AWI_DEBUG */
1840 
1841 	ostate = ic->ic_state;
1842 	DPRINTF(("awi_newstate: %s (%s/%s) -> %s\n", stname[ostate],
1843 	    stname[sc->sc_nstate], substname[sc->sc_substate], stname[nstate]));
1844 
1845 	/* set LED */
1846 	switch (nstate) {
1847 	case IEEE80211_S_INIT:
1848 		awi_drvstate(sc, AWI_DRV_RESET);
1849 		break;
1850 	case IEEE80211_S_SCAN:
1851 		if (ic->ic_opmode == IEEE80211_M_IBSS ||
1852 		    ic->ic_opmode == IEEE80211_M_AHDEMO)
1853 			awi_drvstate(sc, AWI_DRV_ADHSC);
1854 		else
1855 			awi_drvstate(sc, AWI_DRV_INFSY);
1856 		break;
1857 	case IEEE80211_S_AUTH:
1858 		awi_drvstate(sc, AWI_DRV_INFSY);
1859 		break;
1860 	case IEEE80211_S_ASSOC:
1861 		awi_drvstate(sc, AWI_DRV_INFAUTH);
1862 		break;
1863 	case IEEE80211_S_RUN:
1864 		if (ic->ic_opmode == IEEE80211_M_IBSS ||
1865 		    ic->ic_opmode == IEEE80211_M_AHDEMO)
1866 			awi_drvstate(sc, AWI_DRV_ADHSY);
1867 		else
1868 			awi_drvstate(sc, AWI_DRV_INFASSOC);
1869 		break;
1870 	}
1871 
1872 	if (nstate == IEEE80211_S_INIT) {
1873 		sc->sc_substate = AWI_ST_NONE;
1874 		ic->ic_flags &= ~IEEE80211_F_SIBSS;
1875 		return (*sc->sc_newstate)(ic, nstate, arg);
1876 	}
1877 
1878 	/* state transition */
1879 	if (nstate == IEEE80211_S_SCAN) {
1880 		/* SCAN substate */
1881 		if (sc->sc_substate == AWI_ST_NONE) {
1882 			sc->sc_nstate = nstate;	/* next state in transition */
1883 			sc->sc_substate = AWI_ST_SCAN_INIT;
1884 		}
1885 		switch (sc->sc_substate) {
1886 		case AWI_ST_SCAN_INIT:
1887 			sc->sc_substate = AWI_ST_SCAN_SETMIB;
1888 			switch (ostate) {
1889 			case IEEE80211_S_RUN:
1890 				/* beacon miss */
1891 				if (ifp->if_flags & IFF_DEBUG)
1892 					printf("%s: no recent beacons from %s;"
1893 					    " rescanning\n",
1894 					    ifp->if_xname,
1895 					    ether_sprintf(ic->ic_bss->ni_bssid));
1896 				/* FALLTHRU */
1897 			case IEEE80211_S_AUTH:
1898 			case IEEE80211_S_ASSOC:
1899 			case IEEE80211_S_INIT:
1900 				ieee80211_begin_scan(ic, 1);
1901 				/* FALLTHRU */
1902 			case IEEE80211_S_SCAN:
1903 				/* scan next */
1904 				break;
1905 			}
1906 			if (ic->ic_flags & IEEE80211_F_ASCAN)
1907 				newmode = AWI_SCAN_ACTIVE;
1908 			else
1909 				newmode = AWI_SCAN_PASSIVE;
1910 			if (sc->sc_mib_mgt.aScan_Mode != newmode) {
1911 				sc->sc_mib_mgt.aScan_Mode = newmode;
1912 				if ((error = awi_mib(sc, AWI_CMD_SET_MIB,
1913 				    AWI_MIB_MGT, AWI_NOWAIT)) != 0)
1914 					break;
1915 			}
1916 			/* FALLTHRU */
1917 		case AWI_ST_SCAN_SETMIB:
1918 			sc->sc_substate = AWI_ST_SCAN_SCCMD;
1919 			if (sc->sc_cmd_inprog) {
1920 				if ((error = awi_cmd_wait(sc)) != 0)
1921 					break;
1922 			}
1923 			sc->sc_cmd_inprog = AWI_CMD_SCAN;
1924 			ni = ic->ic_bss;
1925 			awi_write_2(sc, AWI_CA_SCAN_DURATION,
1926 			    (ic->ic_flags & IEEE80211_F_ASCAN) ?
1927 			    AWI_ASCAN_DURATION : AWI_PSCAN_DURATION);
1928 			if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
1929 				awi_write_1(sc, AWI_CA_SCAN_SET,
1930 				    IEEE80211_FH_CHANSET(
1931 				        ieee80211_chan2ieee(ic, ni->ni_chan)));
1932 				awi_write_1(sc, AWI_CA_SCAN_PATTERN,
1933 				    IEEE80211_FH_CHANPAT(
1934 				        ieee80211_chan2ieee(ic, ni->ni_chan)));
1935 				awi_write_1(sc, AWI_CA_SCAN_IDX, 1);
1936 			} else {
1937 				awi_write_1(sc, AWI_CA_SCAN_SET,
1938 				    ieee80211_chan2ieee(ic, ni->ni_chan));
1939 				awi_write_1(sc, AWI_CA_SCAN_PATTERN, 0);
1940 				awi_write_1(sc, AWI_CA_SCAN_IDX, 0);
1941 			}
1942 			awi_write_1(sc, AWI_CA_SCAN_SUSP, 0);
1943 			sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan);
1944 			if ((error = awi_cmd(sc, AWI_CMD_SCAN, AWI_NOWAIT))
1945 			    != 0)
1946 				break;
1947 			/* FALLTHRU */
1948 		case AWI_ST_SCAN_SCCMD:
1949 			ic->ic_state = nstate;
1950 			sc->sc_substate = AWI_ST_NONE;
1951 			error = EINPROGRESS;
1952 			break;
1953 		default:
1954 			DPRINTF(("awi_newstate: unexpected state %s/%s\n",
1955 			    stname[nstate], substname[sc->sc_substate]));
1956 			sc->sc_substate = AWI_ST_NONE;
1957 			error = EIO;
1958 			break;
1959 		}
1960 		goto out;
1961 	}
1962 
1963 	if (ostate == IEEE80211_S_SCAN) {
1964 		/* set SSID and channel */
1965 		/* substate */
1966 		if (sc->sc_substate == AWI_ST_NONE) {
1967 			sc->sc_nstate = nstate;	/* next state in transition */
1968 			sc->sc_substate = AWI_ST_SUB_INIT;
1969 		}
1970 		ni = ic->ic_bss;
1971 		switch (sc->sc_substate) {
1972 		case AWI_ST_SUB_INIT:
1973 			sc->sc_substate = AWI_ST_SUB_SETSS;
1974 			IEEE80211_ADDR_COPY(&sc->sc_mib_mgt.aCurrent_BSS_ID,
1975 			    ni->ni_bssid);
1976 			memset(&sc->sc_mib_mgt.aCurrent_ESS_ID, 0,
1977 			    AWI_ESS_ID_SIZE);
1978 			sc->sc_mib_mgt.aCurrent_ESS_ID[0] =
1979 			    IEEE80211_ELEMID_SSID;
1980 			sc->sc_mib_mgt.aCurrent_ESS_ID[1] = ni->ni_esslen;
1981 			memcpy(&sc->sc_mib_mgt.aCurrent_ESS_ID[2],
1982 			    ni->ni_essid, ni->ni_esslen);
1983 			LE_WRITE_2(&sc->sc_mib_mgt.aBeacon_Period,
1984 			    ni->ni_intval);
1985 			if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT,
1986 			    AWI_NOWAIT)) != 0)
1987 				break;
1988 			/* FALLTHRU */
1989 		case AWI_ST_SUB_SETSS:
1990 			sc->sc_substate = AWI_ST_SUB_SYNC;
1991 			if (sc->sc_cmd_inprog) {
1992 				if ((error = awi_cmd_wait(sc)) != 0)
1993 					break;
1994 			}
1995 			sc->sc_cmd_inprog = AWI_CMD_SYNC;
1996 			if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) {
1997 				awi_write_1(sc, AWI_CA_SYNC_SET,
1998 				    IEEE80211_FH_CHANSET(
1999 				        ieee80211_chan2ieee(ic, ni->ni_chan)));
2000 				awi_write_1(sc, AWI_CA_SYNC_PATTERN,
2001 				    IEEE80211_FH_CHANPAT(
2002 				        ieee80211_chan2ieee(ic, ni->ni_chan)));
2003 				awi_write_1(sc, AWI_CA_SYNC_IDX,
2004 				    ni->ni_fhindex);
2005 				awi_write_2(sc, AWI_CA_SYNC_DWELL,
2006 				    ni->ni_fhdwell);
2007 			} else {
2008 				awi_write_1(sc, AWI_CA_SYNC_SET,
2009 				    ieee80211_chan2ieee(ic, ni->ni_chan));
2010 				awi_write_1(sc, AWI_CA_SYNC_PATTERN, 0);
2011 				awi_write_1(sc, AWI_CA_SYNC_IDX, 0);
2012 				awi_write_2(sc, AWI_CA_SYNC_DWELL, 0);
2013 			}
2014 			if (ic->ic_flags & IEEE80211_F_SIBSS) {
2015 				memset(&ni->ni_tstamp, 0,
2016 				    sizeof(ni->ni_tstamp));
2017 				ni->ni_rstamp = 0;
2018 				awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 1);
2019 			} else
2020 				awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 0);
2021 			awi_write_2(sc, AWI_CA_SYNC_MBZ, 0);
2022 			awi_write_bytes(sc, AWI_CA_SYNC_TIMESTAMP,
2023 			    ni->ni_tstamp.data, sizeof(ni->ni_tstamp.data));
2024 			awi_write_4(sc, AWI_CA_SYNC_REFTIME, ni->ni_rstamp);
2025 			sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan);
2026 			if ((error = awi_cmd(sc, AWI_CMD_SYNC, AWI_NOWAIT))
2027 			    != 0)
2028 				break;
2029 			/* FALLTHRU */
2030 		case AWI_ST_SUB_SYNC:
2031 			sc->sc_substate = AWI_ST_NONE;
2032 			if (ic->ic_flags & IEEE80211_F_SIBSS) {
2033 				if ((error = awi_mib(sc, AWI_CMD_GET_MIB,
2034 				    AWI_MIB_MGT, AWI_WAIT)) != 0)
2035 					break;
2036 				IEEE80211_ADDR_COPY(ni->ni_bssid,
2037 				    &sc->sc_mib_mgt.aCurrent_BSS_ID);
2038 			} else {
2039 				if (nstate == IEEE80211_S_RUN) {
2040 					sc->sc_rx_timer = 10;
2041 					ifp->if_timer = 1;
2042 				}
2043 			}
2044 			error = 0;
2045 			break;
2046 		default:
2047 			DPRINTF(("awi_newstate: unexpected state %s/%s\n",
2048 			    stname[nstate], substname[sc->sc_substate]));
2049 			sc->sc_substate = AWI_ST_NONE;
2050 			error = EIO;
2051 			break;
2052 		}
2053 		goto out;
2054 	}
2055 
2056 	sc->sc_substate = AWI_ST_NONE;
2057 
2058 	return (*sc->sc_newstate)(ic, nstate, arg);
2059 out:
2060 	if (error != 0) {
2061 		if (error == EINPROGRESS)
2062 			error = 0;
2063 		return error;
2064 	}
2065 	return (*sc->sc_newstate)(ic, nstate, arg);
2066 }
2067 
2068 static void
2069 awi_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0,
2070 	struct ieee80211_node *ni,
2071 	int subtype, int rssi, u_int32_t rstamp)
2072 {
2073 	struct awi_softc *sc = ic->ic_ifp->if_softc;
2074 
2075 	/* probe request is handled by hardware */
2076 	if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ)
2077 		return;
2078 	(*sc->sc_recv_mgmt)(ic, m0, ni, subtype, rssi, rstamp);
2079 }
2080 
2081 static int
2082 awi_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
2083 	int type, int arg)
2084 {
2085 	struct awi_softc *sc = ic->ic_ifp->if_softc;
2086 
2087 	/* probe request is handled by hardware */
2088 	if (type == IEEE80211_FC0_SUBTYPE_PROBE_REQ)
2089 		return 0;
2090 	return (*sc->sc_send_mgmt)(ic, ni, type, arg);
2091 }
2092 
2093 static struct mbuf *
2094 awi_ether_encap(struct awi_softc *sc, struct mbuf *m)
2095 {
2096 	struct ieee80211com *ic = &sc->sc_ic;
2097 	struct ieee80211_node *ni = ic->ic_bss;
2098 	struct ether_header *eh;
2099 	struct ieee80211_frame *wh;
2100 
2101 	if (m->m_len < sizeof(struct ether_header)) {
2102 		m = m_pullup(m, sizeof(struct ether_header));
2103 		if (m == NULL)
2104 			return NULL;
2105 	}
2106 	eh = mtod(m, struct ether_header *);
2107 	M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
2108 	if (m == NULL)
2109 		return NULL;
2110 	wh = mtod(m, struct ieee80211_frame *);
2111 	wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
2112 	*(u_int16_t *)wh->i_dur = 0;
2113 	*(u_int16_t *)wh->i_seq =
2114 	    htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT);
2115 	ni->ni_txseqs[0]++;
2116 	if (ic->ic_opmode == IEEE80211_M_IBSS ||
2117 	    ic->ic_opmode == IEEE80211_M_AHDEMO) {
2118 		wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
2119 		if (sc->sc_adhoc_ap)
2120 			IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
2121 		else
2122 			IEEE80211_ADDR_COPY(wh->i_addr1, eh->ether_dhost);
2123 		IEEE80211_ADDR_COPY(wh->i_addr2, eh->ether_shost);
2124 		IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
2125 	} else {
2126 		wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
2127 		IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
2128 		IEEE80211_ADDR_COPY(wh->i_addr2, eh->ether_shost);
2129 		IEEE80211_ADDR_COPY(wh->i_addr3, eh->ether_dhost);
2130 	}
2131 	return m;
2132 }
2133 
2134 static struct mbuf *
2135 awi_ether_modcap(struct awi_softc *sc, struct mbuf *m)
2136 {
2137 	struct ieee80211com *ic = &sc->sc_ic;
2138 	struct ether_header eh;
2139 	struct ieee80211_frame wh;
2140 	struct llc *llc;
2141 
2142 	if (m->m_len < sizeof(wh) + sizeof(eh)) {
2143 		m = m_pullup(m, sizeof(wh) + sizeof(eh));
2144 		if (m == NULL)
2145 			return NULL;
2146 	}
2147 	memcpy(&wh, mtod(m, void *), sizeof(wh));
2148 	if (wh.i_fc[0] != (IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA))
2149 		return m;
2150 	memcpy(&eh, mtod(m, char *) + sizeof(wh), sizeof(eh));
2151 	m_adj(m, sizeof(eh) - sizeof(*llc));
2152 	if (ic->ic_opmode == IEEE80211_M_IBSS ||
2153 	    ic->ic_opmode == IEEE80211_M_AHDEMO)
2154 		IEEE80211_ADDR_COPY(wh.i_addr2, eh.ether_shost);
2155 	memcpy(mtod(m, void *), &wh, sizeof(wh));
2156 	llc = (struct llc *)(mtod(m, char *) + sizeof(wh));
2157 	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
2158 	llc->llc_control = LLC_UI;
2159 	llc->llc_snap.org_code[0] = 0;
2160 	llc->llc_snap.org_code[1] = 0;
2161 	llc->llc_snap.org_code[2] = 0;
2162 	llc->llc_snap.ether_type = eh.ether_type;
2163 	return m;
2164 }
2165