if_wi.c revision 165089
1/*	$NetBSD: wi.c,v 1.109 2003/01/09 08:52:19 dyoung Exp $	*/
2
3/*-
4 * Copyright (c) 1997, 1998, 1999
5 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by Bill Paul.
18 * 4. Neither the name of the author nor the names of any co-contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35/*
36 * Lucent WaveLAN/IEEE 802.11 PCMCIA driver.
37 *
38 * Original FreeBSD driver written by Bill Paul <wpaul@ctr.columbia.edu>
39 * Electrical Engineering Department
40 * Columbia University, New York City
41 */
42
43/*
44 * The WaveLAN/IEEE adapter is the second generation of the WaveLAN
45 * from Lucent. Unlike the older cards, the new ones are programmed
46 * entirely via a firmware-driven controller called the Hermes.
47 * Unfortunately, Lucent will not release the Hermes programming manual
48 * without an NDA (if at all). What they do release is an API library
49 * called the HCF (Hardware Control Functions) which is supposed to
50 * do the device-specific operations of a device driver for you. The
51 * publically available version of the HCF library (the 'HCF Light') is
52 * a) extremely gross, b) lacks certain features, particularly support
53 * for 802.11 frames, and c) is contaminated by the GNU Public License.
54 *
55 * This driver does not use the HCF or HCF Light at all. Instead, it
56 * programs the Hermes controller directly, using information gleaned
57 * from the HCF Light code and corresponding documentation.
58 *
59 * This driver supports the ISA, PCMCIA and PCI versions of the Lucent
60 * WaveLan cards (based on the Hermes chipset), as well as the newer
61 * Prism 2 chipsets with firmware from Intersil and Symbol.
62 */
63
64#include <sys/cdefs.h>
65__FBSDID("$FreeBSD: head/sys/dev/wi/if_wi.c 165089 2006-12-11 00:41:22Z sam $");
66
67#define WI_HERMES_AUTOINC_WAR	/* Work around data write autoinc bug. */
68#define WI_HERMES_STATS_WAR	/* Work around stats counter bug. */
69
70#define	NBPFILTER	1
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/endian.h>
75#include <sys/sockio.h>
76#include <sys/mbuf.h>
77#include <sys/priv.h>
78#include <sys/proc.h>
79#include <sys/kernel.h>
80#include <sys/socket.h>
81#include <sys/module.h>
82#include <sys/bus.h>
83#include <sys/random.h>
84#include <sys/syslog.h>
85#include <sys/sysctl.h>
86
87#include <machine/bus.h>
88#include <machine/resource.h>
89#include <machine/atomic.h>
90#include <sys/rman.h>
91
92#include <net/if.h>
93#include <net/if_arp.h>
94#include <net/ethernet.h>
95#include <net/if_dl.h>
96#include <net/if_media.h>
97#include <net/if_types.h>
98
99#include <net80211/ieee80211_var.h>
100#include <net80211/ieee80211_ioctl.h>
101#include <net80211/ieee80211_radiotap.h>
102
103#include <netinet/in.h>
104#include <netinet/in_systm.h>
105#include <netinet/in_var.h>
106#include <netinet/ip.h>
107#include <netinet/if_ether.h>
108
109#include <net/bpf.h>
110
111#include <dev/wi/if_wavelan_ieee.h>
112#include <dev/wi/if_wireg.h>
113#include <dev/wi/if_wivar.h>
114
115static void wi_start_locked(struct ifnet *);
116static void wi_start(struct ifnet *);
117static int  wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr,
118		struct mbuf *m0);
119static int  wi_raw_xmit(struct ieee80211_node *, struct mbuf *,
120		const struct ieee80211_bpf_params *);
121static int  wi_reset(struct wi_softc *);
122static void wi_watchdog(void *);
123static int  wi_ioctl(struct ifnet *, u_long, caddr_t);
124static int  wi_media_change(struct ifnet *);
125static void wi_media_status(struct ifnet *, struct ifmediareq *);
126
127static void wi_rx_intr(struct wi_softc *);
128static void wi_tx_intr(struct wi_softc *);
129static void wi_tx_ex_intr(struct wi_softc *);
130static void wi_info_intr(struct wi_softc *);
131
132static int  wi_key_alloc(struct ieee80211com *, const struct ieee80211_key *,
133		ieee80211_keyix *, ieee80211_keyix *);
134
135static int  wi_get_cfg(struct ifnet *, u_long, caddr_t);
136static int  wi_set_cfg(struct ifnet *, u_long, caddr_t);
137static int  wi_write_txrate(struct wi_softc *);
138static int  wi_write_wep(struct wi_softc *);
139static int  wi_write_multi(struct wi_softc *);
140static int  wi_alloc_fid(struct wi_softc *, int, int *);
141static void wi_read_nicid(struct wi_softc *);
142static int  wi_write_ssid(struct wi_softc *, int, u_int8_t *, int);
143
144static int  wi_cmd(struct wi_softc *, int, int, int, int);
145static int  wi_seek_bap(struct wi_softc *, int, int);
146static int  wi_read_bap(struct wi_softc *, int, int, void *, int);
147static int  wi_write_bap(struct wi_softc *, int, int, void *, int);
148static int  wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int);
149static int  wi_read_rid(struct wi_softc *, int, void *, int *);
150static int  wi_write_rid(struct wi_softc *, int, void *, int);
151
152static int  wi_newstate(struct ieee80211com *, enum ieee80211_state, int);
153
154static int  wi_scan_ap(struct wi_softc *, u_int16_t, u_int16_t);
155static void wi_scan_result(struct wi_softc *, int, int);
156
157static void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi);
158
159static int wi_get_debug(struct wi_softc *, struct wi_req *);
160static int wi_set_debug(struct wi_softc *, struct wi_req *);
161
162/* support to download firmware for symbol CF card */
163static int wi_symbol_write_firm(struct wi_softc *, const void *, int,
164		const void *, int);
165static int wi_symbol_set_hcr(struct wi_softc *, int);
166
167static __inline int
168wi_write_val(struct wi_softc *sc, int rid, u_int16_t val)
169{
170
171	val = htole16(val);
172	return wi_write_rid(sc, rid, &val, sizeof(val));
173}
174
175SYSCTL_NODE(_hw, OID_AUTO, wi, CTLFLAG_RD, 0, "Wireless driver parameters");
176
177static	struct timeval lasttxerror;	/* time of last tx error msg */
178static	int curtxeps;			/* current tx error msgs/sec */
179static	int wi_txerate = 0;		/* tx error rate: max msgs/sec */
180SYSCTL_INT(_hw_wi, OID_AUTO, txerate, CTLFLAG_RW, &wi_txerate,
181	    0, "max tx error msgs/sec; 0 to disable msgs");
182
183#define	WI_DEBUG
184#ifdef WI_DEBUG
185static	int wi_debug = 0;
186SYSCTL_INT(_hw_wi, OID_AUTO, debug, CTLFLAG_RW, &wi_debug,
187	    0, "control debugging printfs");
188
189#define	DPRINTF(X)	if (wi_debug) printf X
190#define	DPRINTF2(X)	if (wi_debug > 1) printf X
191#define	IFF_DUMPPKTS(_ifp) \
192	(((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
193#else
194#define	DPRINTF(X)
195#define	DPRINTF2(X)
196#define	IFF_DUMPPKTS(_ifp)	0
197#endif
198
199#define WI_INTRS	(WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO)
200
201struct wi_card_ident wi_card_ident[] = {
202	/* CARD_ID			CARD_NAME		FIRM_TYPE */
203	{ WI_NIC_LUCENT_ID,		WI_NIC_LUCENT_STR,	WI_LUCENT },
204	{ WI_NIC_SONY_ID,		WI_NIC_SONY_STR,	WI_LUCENT },
205	{ WI_NIC_LUCENT_EMB_ID,		WI_NIC_LUCENT_EMB_STR,	WI_LUCENT },
206	{ WI_NIC_EVB2_ID,		WI_NIC_EVB2_STR,	WI_INTERSIL },
207	{ WI_NIC_HWB3763_ID,		WI_NIC_HWB3763_STR,	WI_INTERSIL },
208	{ WI_NIC_HWB3163_ID,		WI_NIC_HWB3163_STR,	WI_INTERSIL },
209	{ WI_NIC_HWB3163B_ID,		WI_NIC_HWB3163B_STR,	WI_INTERSIL },
210	{ WI_NIC_EVB3_ID,		WI_NIC_EVB3_STR,	WI_INTERSIL },
211	{ WI_NIC_HWB1153_ID,		WI_NIC_HWB1153_STR,	WI_INTERSIL },
212	{ WI_NIC_P2_SST_ID,		WI_NIC_P2_SST_STR,	WI_INTERSIL },
213	{ WI_NIC_EVB2_SST_ID,		WI_NIC_EVB2_SST_STR,	WI_INTERSIL },
214	{ WI_NIC_3842_EVA_ID,		WI_NIC_3842_EVA_STR,	WI_INTERSIL },
215	{ WI_NIC_3842_PCMCIA_AMD_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
216	{ WI_NIC_3842_PCMCIA_SST_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
217	{ WI_NIC_3842_PCMCIA_ATL_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
218	{ WI_NIC_3842_PCMCIA_ATS_ID,	WI_NIC_3842_PCMCIA_STR,	WI_INTERSIL },
219	{ WI_NIC_3842_MINI_AMD_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
220	{ WI_NIC_3842_MINI_SST_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
221	{ WI_NIC_3842_MINI_ATL_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
222	{ WI_NIC_3842_MINI_ATS_ID,	WI_NIC_3842_MINI_STR,	WI_INTERSIL },
223	{ WI_NIC_3842_PCI_AMD_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
224	{ WI_NIC_3842_PCI_SST_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
225	{ WI_NIC_3842_PCI_ATS_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
226	{ WI_NIC_3842_PCI_ATL_ID,	WI_NIC_3842_PCI_STR,	WI_INTERSIL },
227	{ WI_NIC_P3_PCMCIA_AMD_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
228	{ WI_NIC_P3_PCMCIA_SST_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
229	{ WI_NIC_P3_PCMCIA_ATL_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
230	{ WI_NIC_P3_PCMCIA_ATS_ID,	WI_NIC_P3_PCMCIA_STR,	WI_INTERSIL },
231	{ WI_NIC_P3_MINI_AMD_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
232	{ WI_NIC_P3_MINI_SST_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
233	{ WI_NIC_P3_MINI_ATL_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
234	{ WI_NIC_P3_MINI_ATS_ID,	WI_NIC_P3_MINI_STR,	WI_INTERSIL },
235	{ 0,	NULL,	0 },
236};
237
238devclass_t wi_devclass;
239
240int
241wi_attach(device_t dev)
242{
243	struct wi_softc	*sc = device_get_softc(dev);
244	struct ieee80211com *ic = &sc->sc_ic;
245	struct ifnet *ifp;
246	int i, nrates, buflen;
247	u_int16_t val;
248	u_int8_t ratebuf[2 + IEEE80211_RATE_SIZE];
249	struct ieee80211_rateset *rs;
250	static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
251		0x00, 0x00, 0x00, 0x00, 0x00, 0x00
252	};
253	int error;
254
255	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
256	if (ifp == NULL) {
257		device_printf(dev, "can not if_alloc\n");
258		wi_free(dev);
259		return (ENOSPC);
260	}
261
262	/*
263	 * NB: no locking is needed here; don't put it here
264	 *     unless you can prove it!
265	 */
266	error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
267	    wi_intr, sc, &sc->wi_intrhand);
268
269	if (error) {
270		device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
271		wi_free(dev);
272		return (error);
273	}
274
275	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
276	    MTX_DEF | MTX_RECURSE);
277	callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0);
278
279	sc->sc_firmware_type = WI_NOTYPE;
280	sc->wi_cmd_count = 500;
281	/* Reset the NIC. */
282	if (wi_reset(sc) != 0)
283		return ENXIO;		/* XXX */
284
285	/*
286	 * Read the station address.
287	 * And do it twice. I've seen PRISM-based cards that return
288	 * an error when trying to read it the first time, which causes
289	 * the probe to fail.
290	 */
291	buflen = IEEE80211_ADDR_LEN;
292	error = wi_read_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, &buflen);
293	if (error != 0) {
294		buflen = IEEE80211_ADDR_LEN;
295		error = wi_read_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, &buflen);
296	}
297	if (error || IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
298		if (error != 0)
299			device_printf(dev, "mac read failed %d\n", error);
300		else {
301			device_printf(dev, "mac read failed (all zeros)\n");
302			error = ENXIO;
303		}
304		wi_free(dev);
305		return (error);
306	}
307
308	/* Read NIC identification */
309	wi_read_nicid(sc);
310
311	ifp->if_softc = sc;
312	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
313	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
314	ifp->if_ioctl = wi_ioctl;
315	ifp->if_start = wi_start;
316	ifp->if_init = wi_init;
317	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
318	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
319	IFQ_SET_READY(&ifp->if_snd);
320
321	ic->ic_ifp = ifp;
322	ic->ic_phytype = IEEE80211_T_DS;
323	ic->ic_opmode = IEEE80211_M_STA;
324	ic->ic_state = IEEE80211_S_INIT;
325	ic->ic_caps = IEEE80211_C_PMGT
326		    | IEEE80211_C_WEP		/* everyone supports WEP */
327		    ;
328	ic->ic_max_aid = WI_MAX_AID;
329
330	/*
331	 * Query the card for available channels and setup the
332	 * channel table.  We assume these are all 11b channels.
333	 */
334	buflen = sizeof(val);
335	if (wi_read_rid(sc, WI_RID_CHANNEL_LIST, &val, &buflen) != 0)
336		val = htole16(0x1fff);	/* assume 1-11 */
337	KASSERT(val != 0, ("wi_attach: no available channels listed!"));
338
339	val <<= 1;			/* shift for base 1 indices */
340	for (i = 1; i < 16; i++) {
341		if (!isset((u_int8_t*)&val, i))
342			continue;
343		ic->ic_channels[i].ic_freq =
344			ieee80211_ieee2mhz(i, IEEE80211_CHAN_B);
345		ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B;
346	}
347
348	/*
349	 * Read the default channel from the NIC. This may vary
350	 * depending on the country where the NIC was purchased, so
351	 * we can't hard-code a default and expect it to work for
352	 * everyone.
353	 *
354	 * If no channel is specified, let the 802.11 code select.
355	 */
356	buflen = sizeof(val);
357	if (wi_read_rid(sc, WI_RID_OWN_CHNL, &val, &buflen) == 0) {
358		val = le16toh(val);
359		KASSERT(val < IEEE80211_CHAN_MAX &&
360			ic->ic_channels[val].ic_flags != 0,
361			("wi_attach: invalid own channel %u!", val));
362		ic->ic_ibss_chan = &ic->ic_channels[val];
363	} else {
364		device_printf(dev,
365			"WI_RID_OWN_CHNL failed, using first channel!\n");
366		ic->ic_ibss_chan = &ic->ic_channels[0];
367	}
368
369	/*
370	 * Set flags based on firmware version.
371	 */
372	switch (sc->sc_firmware_type) {
373	case WI_LUCENT:
374		sc->sc_ntxbuf = 1;
375		sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
376#ifdef WI_HERMES_AUTOINC_WAR
377		/* XXX: not confirmed, but never seen for recent firmware */
378		if (sc->sc_sta_firmware_ver <  40000) {
379			sc->sc_flags |= WI_FLAGS_BUG_AUTOINC;
380		}
381#endif
382		if (sc->sc_sta_firmware_ver >= 60000)
383			sc->sc_flags |= WI_FLAGS_HAS_MOR;
384		if (sc->sc_sta_firmware_ver >= 60006) {
385			ic->ic_caps |= IEEE80211_C_IBSS;
386			ic->ic_caps |= IEEE80211_C_MONITOR;
387		}
388		sc->sc_ibss_port = htole16(1);
389
390		sc->sc_min_rssi = WI_LUCENT_MIN_RSSI;
391		sc->sc_max_rssi = WI_LUCENT_MAX_RSSI;
392		sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET;
393		break;
394
395	case WI_INTERSIL:
396		sc->sc_ntxbuf = WI_NTXBUF;
397		sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;
398		sc->sc_flags |= WI_FLAGS_HAS_ROAMING;
399		sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
400		/*
401		 * Old firmware are slow, so give peace a chance.
402		 */
403		if (sc->sc_sta_firmware_ver < 10000)
404			sc->wi_cmd_count = 5000;
405		if (sc->sc_sta_firmware_ver > 10101)
406			sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST;
407		if (sc->sc_sta_firmware_ver >= 800) {
408			ic->ic_caps |= IEEE80211_C_IBSS;
409			ic->ic_caps |= IEEE80211_C_MONITOR;
410		}
411		/*
412		 * version 0.8.3 and newer are the only ones that are known
413		 * to currently work.  Earlier versions can be made to work,
414		 * at least according to the Linux driver.
415		 */
416		if (sc->sc_sta_firmware_ver >= 803)
417			ic->ic_caps |= IEEE80211_C_HOSTAP;
418		sc->sc_ibss_port = htole16(0);
419
420		sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
421		sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
422		sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
423		break;
424
425	case WI_SYMBOL:
426		sc->sc_ntxbuf = 1;
427		sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
428		if (sc->sc_sta_firmware_ver >= 25000)
429			ic->ic_caps |= IEEE80211_C_IBSS;
430		sc->sc_ibss_port = htole16(4);
431
432		sc->sc_min_rssi = WI_PRISM_MIN_RSSI;
433		sc->sc_max_rssi = WI_PRISM_MAX_RSSI;
434		sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET;
435		break;
436	}
437
438	/*
439	 * Find out if we support WEP on this card.
440	 */
441	buflen = sizeof(val);
442	if (wi_read_rid(sc, WI_RID_WEP_AVAIL, &val, &buflen) == 0 &&
443	    val != htole16(0))
444		ic->ic_caps |= IEEE80211_C_WEP;
445
446	/* Find supported rates. */
447	buflen = sizeof(ratebuf);
448	rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
449	if (wi_read_rid(sc, WI_RID_DATA_RATES, ratebuf, &buflen) == 0) {
450		nrates = le16toh(*(u_int16_t *)ratebuf);
451		if (nrates > IEEE80211_RATE_MAXSIZE)
452			nrates = IEEE80211_RATE_MAXSIZE;
453		rs->rs_nrates = 0;
454		for (i = 0; i < nrates; i++)
455			if (ratebuf[2+i])
456				rs->rs_rates[rs->rs_nrates++] = ratebuf[2+i];
457	} else {
458		/* XXX fallback on error? */
459		rs->rs_nrates = 0;
460	}
461
462	buflen = sizeof(val);
463	if ((sc->sc_flags & WI_FLAGS_HAS_DBMADJUST) &&
464	    wi_read_rid(sc, WI_RID_DBM_ADJUST, &val, &buflen) == 0) {
465		sc->sc_dbm_offset = le16toh(val);
466	}
467
468	sc->sc_max_datalen = 2304;
469	sc->sc_system_scale = 1;
470	sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN;
471	sc->sc_roaming_mode = 1;
472
473	sc->sc_portnum = WI_DEFAULT_PORT;
474	sc->sc_authtype = WI_DEFAULT_AUTHTYPE;
475
476	bzero(sc->sc_nodename, sizeof(sc->sc_nodename));
477	sc->sc_nodelen = sizeof(WI_DEFAULT_NODENAME) - 1;
478	bcopy(WI_DEFAULT_NODENAME, sc->sc_nodename, sc->sc_nodelen);
479
480	bzero(sc->sc_net_name, sizeof(sc->sc_net_name));
481	bcopy(WI_DEFAULT_NETNAME, sc->sc_net_name,
482	    sizeof(WI_DEFAULT_NETNAME) - 1);
483
484	/*
485	 * Call MI attach routine.
486	 */
487	ieee80211_ifattach(ic);
488	/* override state transition method */
489	sc->sc_newstate = ic->ic_newstate;
490	sc->sc_key_alloc = ic->ic_crypto.cs_key_alloc;
491	ic->ic_crypto.cs_key_alloc = wi_key_alloc;
492	ic->ic_newstate = wi_newstate;
493	ic->ic_raw_xmit = wi_raw_xmit;
494	ieee80211_media_init(ic, wi_media_change, wi_media_status);
495
496#if NBPFILTER > 0
497	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
498		sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th),
499		&sc->sc_drvbpf);
500	/*
501	 * Initialize constant fields.
502	 * XXX make header lengths a multiple of 32-bits so subsequent
503	 *     headers are properly aligned; this is a kludge to keep
504	 *     certain applications happy.
505	 *
506	 * NB: the channel is setup each time we transition to the
507	 *     RUN state to avoid filling it in for each frame.
508	 */
509	sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t));
510	sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
511	sc->sc_tx_th.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT);
512
513	sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t));
514	sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
515	sc->sc_rx_th.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT);
516#endif
517
518	if (bootverbose)
519		ieee80211_announce(ic);
520
521	return (0);
522}
523
524int
525wi_detach(device_t dev)
526{
527	struct wi_softc	*sc = device_get_softc(dev);
528	struct ifnet *ifp = sc->sc_ifp;
529
530	WI_LOCK(sc);
531
532	/* check if device was removed */
533	sc->wi_gone |= !bus_child_present(dev);
534
535	wi_stop(ifp, 0);
536	WI_UNLOCK(sc);
537
538#if NBPFILTER > 0
539	bpfdetach(ifp);
540#endif
541	ieee80211_ifdetach(&sc->sc_ic);
542	bus_teardown_intr(dev, sc->irq, sc->wi_intrhand);
543	if_free(sc->sc_ifp);
544	wi_free(dev);
545	mtx_destroy(&sc->sc_mtx);
546	return (0);
547}
548
549#ifdef __NetBSD__
550int
551wi_activate(struct device *self, enum devact act)
552{
553	struct wi_softc *sc = (struct wi_softc *)self;
554	int rv = 0, s;
555
556	s = splnet();
557	switch (act) {
558	case DVACT_ACTIVATE:
559		rv = EOPNOTSUPP;
560		break;
561
562	case DVACT_DEACTIVATE:
563		if_deactivate(sc->sc_ifp);
564		break;
565	}
566	splx(s);
567	return rv;
568}
569
570void
571wi_power(struct wi_softc *sc, int why)
572{
573	struct ifnet *ifp = sc->sc_ifp;
574	int s;
575
576	s = splnet();
577	switch (why) {
578	case PWR_SUSPEND:
579	case PWR_STANDBY:
580		wi_stop(ifp, 1);
581		break;
582	case PWR_RESUME:
583		if (ifp->if_flags & IFF_UP) {
584			wi_init(ifp);
585			(void)wi_intr(sc);
586		}
587		break;
588	case PWR_SOFTSUSPEND:
589	case PWR_SOFTSTANDBY:
590	case PWR_SOFTRESUME:
591		break;
592	}
593	splx(s);
594}
595#endif /* __NetBSD__ */
596
597void
598wi_shutdown(device_t dev)
599{
600	struct wi_softc *sc = device_get_softc(dev);
601
602	wi_stop(sc->sc_ifp, 1);
603}
604
605void
606wi_intr(void *arg)
607{
608	struct wi_softc *sc = arg;
609	struct ifnet *ifp = sc->sc_ifp;
610	u_int16_t status;
611
612	WI_LOCK(sc);
613
614	if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) {
615		CSR_WRITE_2(sc, WI_INT_EN, 0);
616		CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
617		WI_UNLOCK(sc);
618		return;
619	}
620
621	/* Disable interrupts. */
622	CSR_WRITE_2(sc, WI_INT_EN, 0);
623
624	status = CSR_READ_2(sc, WI_EVENT_STAT);
625	if (status & WI_EV_RX)
626		wi_rx_intr(sc);
627	if (status & WI_EV_ALLOC)
628		wi_tx_intr(sc);
629	if (status & WI_EV_TX_EXC)
630		wi_tx_ex_intr(sc);
631	if (status & WI_EV_INFO)
632		wi_info_intr(sc);
633	if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 &&
634	    (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 &&
635	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
636		wi_start_locked(ifp);
637
638	/* Re-enable interrupts. */
639	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
640
641	WI_UNLOCK(sc);
642
643	return;
644}
645
646void
647wi_init(void *arg)
648{
649	struct wi_softc *sc = arg;
650	struct ifnet *ifp = sc->sc_ifp;
651	struct ieee80211com *ic = &sc->sc_ic;
652	struct wi_joinreq join;
653	int i;
654	int error = 0, wasenabled;
655
656	WI_LOCK(sc);
657
658	if (sc->wi_gone) {
659		WI_UNLOCK(sc);
660		return;
661	}
662
663	if ((wasenabled = sc->sc_enabled))
664		wi_stop(ifp, 1);
665	wi_reset(sc);
666
667	/* common 802.11 configuration */
668	ic->ic_flags &= ~IEEE80211_F_IBSSON;
669	sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
670	switch (ic->ic_opmode) {
671	case IEEE80211_M_STA:
672		wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS);
673		break;
674	case IEEE80211_M_IBSS:
675		wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port);
676		ic->ic_flags |= IEEE80211_F_IBSSON;
677		break;
678	case IEEE80211_M_AHDEMO:
679		wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
680		break;
681	case IEEE80211_M_HOSTAP:
682		/*
683		 * For PRISM cards, override the empty SSID, because in
684		 * HostAP mode the controller will lock up otherwise.
685		 */
686		if (sc->sc_firmware_type == WI_INTERSIL &&
687		    ic->ic_des_esslen == 0) {
688			ic->ic_des_essid[0] = ' ';
689			ic->ic_des_esslen = 1;
690		}
691		wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP);
692		break;
693	case IEEE80211_M_MONITOR:
694		switch (sc->sc_firmware_type) {
695		case WI_LUCENT:
696			wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC);
697			break;
698
699		case WI_INTERSIL:
700			wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_APSILENT);
701			break;
702		}
703
704		wi_cmd(sc, WI_CMD_DEBUG | (WI_TEST_MONITOR << 8), 0, 0, 0);
705		break;
706	}
707
708	/* Intersil interprets this RID as joining ESS even in IBSS mode */
709	if (sc->sc_firmware_type == WI_LUCENT &&
710	    (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_esslen > 0)
711		wi_write_val(sc, WI_RID_CREATE_IBSS, 1);
712	else
713		wi_write_val(sc, WI_RID_CREATE_IBSS, 0);
714	wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval);
715	wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_essid,
716	    ic->ic_des_esslen);
717	wi_write_val(sc, WI_RID_OWN_CHNL,
718		ieee80211_chan2ieee(ic, ic->ic_ibss_chan));
719	wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_essid, ic->ic_des_esslen);
720
721	IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
722	wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN);
723
724	if (ic->ic_caps & IEEE80211_C_PMGT)
725		wi_write_val(sc, WI_RID_PM_ENABLED,
726		    (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0);
727
728	/* not yet common 802.11 configuration */
729	wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen);
730	wi_write_val(sc, WI_RID_RTS_THRESH, ic->ic_rtsthreshold);
731	if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)
732		wi_write_val(sc, WI_RID_FRAG_THRESH, ic->ic_fragthreshold);
733
734	/* driver specific 802.11 configuration */
735	if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)
736		wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale);
737	if (sc->sc_flags & WI_FLAGS_HAS_ROAMING)
738		wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode);
739	if (sc->sc_flags & WI_FLAGS_HAS_MOR)
740		wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven);
741	wi_write_txrate(sc);
742	wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen);
743	wi_write_val(sc, WI_RID_ALT_RETRY_CNT, 0); /* for IEEE80211_BPF_NOACK */
744
745	if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
746	    sc->sc_firmware_type == WI_INTERSIL) {
747		wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_bintval);
748		wi_write_val(sc, WI_RID_BASIC_RATE, 0x03);   /* 1, 2 */
749		wi_write_val(sc, WI_RID_SUPPORT_RATE, 0x0f); /* 1, 2, 5.5, 11 */
750		wi_write_val(sc, WI_RID_DTIM_PERIOD, ic->ic_dtim_period);
751	}
752
753	/*
754	 * Initialize promisc mode.
755	 *	Being in the Host-AP mode causes a great
756	 *	deal of pain if primisc mode is set.
757	 *	Therefore we avoid confusing the firmware
758	 *	and always reset promisc mode in Host-AP
759	 *	mode.  Host-AP sees all the packets anyway.
760	 */
761	if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
762	    (ifp->if_flags & IFF_PROMISC) != 0) {
763		wi_write_val(sc, WI_RID_PROMISC, 1);
764	} else {
765		wi_write_val(sc, WI_RID_PROMISC, 0);
766	}
767
768	/* Configure WEP. */
769	if (ic->ic_caps & IEEE80211_C_WEP) {
770		sc->sc_cnfauthmode = ic->ic_bss->ni_authmode;
771		wi_write_wep(sc);
772	} else
773		sc->sc_encryption = 0;
774
775	/* Set multicast filter. */
776	wi_write_multi(sc);
777
778	/* Allocate fids for the card */
779	if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) {
780		sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
781		if (sc->sc_firmware_type == WI_SYMBOL)
782			sc->sc_buflen = 1585;	/* XXX */
783		for (i = 0; i < sc->sc_ntxbuf; i++) {
784			error = wi_alloc_fid(sc, sc->sc_buflen,
785			    &sc->sc_txd[i].d_fid);
786			if (error) {
787				device_printf(sc->sc_dev,
788				    "tx buffer allocation failed (error %u)\n",
789				    error);
790				goto out;
791			}
792			sc->sc_txd[i].d_len = 0;
793		}
794	}
795	sc->sc_txcur = sc->sc_txnext = 0;
796
797	/* Enable desired port */
798	wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0);
799
800	sc->sc_enabled = 1;
801	ifp->if_drv_flags |= IFF_DRV_RUNNING;
802	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
803	if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
804	    ic->ic_opmode == IEEE80211_M_IBSS ||
805	    ic->ic_opmode == IEEE80211_M_MONITOR ||
806	    ic->ic_opmode == IEEE80211_M_HOSTAP)
807		ieee80211_create_ibss(ic, ic->ic_ibss_chan);
808
809	/* Enable interrupts */
810	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
811
812	if (!wasenabled &&
813	    ic->ic_opmode == IEEE80211_M_HOSTAP &&
814	    sc->sc_firmware_type == WI_INTERSIL) {
815		/* XXX: some card need to be re-enabled for hostap */
816		wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0);
817		wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0);
818	}
819
820	if (ic->ic_opmode == IEEE80211_M_STA &&
821	    ((ic->ic_flags & IEEE80211_F_DESBSSID) ||
822	    ic->ic_des_chan != IEEE80211_CHAN_ANYC)) {
823		memset(&join, 0, sizeof(join));
824		if (ic->ic_flags & IEEE80211_F_DESBSSID)
825			IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid);
826		if (ic->ic_des_chan != IEEE80211_CHAN_ANYC)
827			join.wi_chan = htole16(
828				ieee80211_chan2ieee(ic, ic->ic_des_chan));
829		/* Lucent firmware does not support the JOIN RID. */
830		if (sc->sc_firmware_type != WI_LUCENT)
831			wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join));
832	}
833
834	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
835
836	WI_UNLOCK(sc);
837	return;
838out:
839	if (error) {
840		if_printf(ifp, "interface not running\n");
841		wi_stop(ifp, 1);
842	}
843	WI_UNLOCK(sc);
844	DPRINTF(("wi_init: return %d\n", error));
845	return;
846}
847
848void
849wi_stop(struct ifnet *ifp, int disable)
850{
851	struct wi_softc *sc = ifp->if_softc;
852	struct ieee80211com *ic = &sc->sc_ic;
853
854	WI_LOCK(sc);
855
856	DELAY(100000);
857
858	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
859	if (sc->sc_enabled && !sc->wi_gone) {
860		CSR_WRITE_2(sc, WI_INT_EN, 0);
861		wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0);
862		if (disable) {
863#ifdef __NetBSD__
864			if (sc->sc_disable)
865				(*sc->sc_disable)(sc);
866#endif
867			sc->sc_enabled = 0;
868		}
869	} else if (sc->wi_gone && disable)	/* gone --> not enabled */
870	    sc->sc_enabled = 0;
871
872	callout_stop(&sc->sc_watchdog);		/* XXX drain */
873	sc->sc_tx_timer = 0;
874	sc->sc_scan_timer = 0;
875	sc->sc_false_syns = 0;
876	sc->sc_naps = 0;
877	ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
878
879	WI_UNLOCK(sc);
880}
881
882static void
883wi_start_locked(struct ifnet *ifp)
884{
885	struct wi_softc	*sc = ifp->if_softc;
886	struct ieee80211com *ic = &sc->sc_ic;
887	struct ieee80211_node *ni;
888	struct ieee80211_frame *wh;
889	struct ether_header *eh;
890	struct mbuf *m0;
891	struct wi_frame frmhdr;
892	int cur;
893
894	WI_LOCK_ASSERT(sc);
895
896	if (sc->wi_gone)
897		return;
898	if (sc->sc_flags & WI_FLAGS_OUTRANGE)
899		return;
900
901	memset(&frmhdr, 0, sizeof(frmhdr));
902	cur = sc->sc_txnext;
903	for (;;) {
904		IF_POLL(&ic->ic_mgtq, m0);
905		if (m0 != NULL) {
906			if (sc->sc_txd[cur].d_len != 0) {
907				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
908				break;
909			}
910			IF_DEQUEUE(&ic->ic_mgtq, m0);
911			/*
912			 * Hack!  The referenced node pointer is in the
913			 * rcvif field of the packet header.  This is
914			 * placed there by ieee80211_mgmt_output because
915			 * we need to hold the reference with the frame
916			 * and there's no other way (other than packet
917			 * tags which we consider too expensive to use)
918			 * to pass it along.
919			 */
920			ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif;
921			m0->m_pkthdr.rcvif = NULL;
922
923			m_copydata(m0, 4, ETHER_ADDR_LEN * 2,
924			    (caddr_t)&frmhdr.wi_ehdr);
925			frmhdr.wi_ehdr.ether_type = 0;
926                        wh = mtod(m0, struct ieee80211_frame *);
927		} else {
928			if (ic->ic_state != IEEE80211_S_RUN)
929				break;
930			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
931			if (m0 == NULL)
932				break;
933			if (sc->sc_txd[cur].d_len != 0) {
934				IFQ_DRV_PREPEND(&ifp->if_snd, m0);
935				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
936				break;
937			}
938			if (m0->m_len < sizeof(struct ether_header) &&
939			    (m0 = m_pullup(m0, sizeof(struct ether_header))) == NULL) {
940				ifp->if_oerrors++;
941				continue;
942			}
943			eh = mtod(m0, struct ether_header *);
944			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
945			if (ni == NULL) {
946				m_freem(m0);
947				continue;
948			}
949			ifp->if_opackets++;
950			m_copydata(m0, 0, ETHER_HDR_LEN,
951			    (caddr_t)&frmhdr.wi_ehdr);
952#if NBPFILTER > 0
953			BPF_MTAP(ifp, m0);
954#endif
955
956			m0 = ieee80211_encap(ic, m0, ni);
957			if (m0 == NULL) {
958				ifp->if_oerrors++;
959				ieee80211_free_node(ni);
960				continue;
961			}
962                        wh = mtod(m0, struct ieee80211_frame *);
963		}
964#if NBPFILTER > 0
965		if (bpf_peers_present(ic->ic_rawbpf))
966			bpf_mtap(ic->ic_rawbpf, m0);
967#endif
968		frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
969		/* XXX check key for SWCRYPT instead of using operating mode */
970		if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
971		    (sc->sc_encryption & HOST_ENCRYPT)) {
972			struct ieee80211_key *k;
973
974			k = ieee80211_crypto_encap(ic, ni, m0);
975			if (k == NULL) {
976				if (ni != NULL)
977					ieee80211_free_node(ni);
978				m_freem(m0);
979				continue;
980			}
981			frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
982		}
983#if NBPFILTER > 0
984		if (bpf_peers_present(sc->sc_drvbpf)) {
985			sc->sc_tx_th.wt_rate =
986				ni->ni_rates.rs_rates[ni->ni_txrate];
987			bpf_mtap2(sc->sc_drvbpf,
988				&sc->sc_tx_th, sc->sc_tx_th_len, m0);
989		}
990#endif
991		m_copydata(m0, 0, sizeof(struct ieee80211_frame),
992		    (caddr_t)&frmhdr.wi_whdr);
993		m_adj(m0, sizeof(struct ieee80211_frame));
994		frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
995		if (IFF_DUMPPKTS(ifp))
996			wi_dump_pkt(&frmhdr, NULL, -1);
997		if (ni != NULL)
998			ieee80211_free_node(ni);
999		if (wi_start_tx(ifp, &frmhdr, m0))
1000			continue;
1001		sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
1002	}
1003}
1004
1005static void
1006wi_start(struct ifnet *ifp)
1007{
1008	struct wi_softc	*sc = ifp->if_softc;
1009
1010	WI_LOCK(sc);
1011	wi_start_locked(ifp);
1012	WI_UNLOCK(sc);
1013}
1014
1015static int
1016wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0)
1017{
1018	struct wi_softc	*sc = ifp->if_softc;
1019	int cur = sc->sc_txnext;
1020	int fid, off, error;
1021
1022	fid = sc->sc_txd[cur].d_fid;
1023	off = sizeof(*frmhdr);
1024	error = wi_write_bap(sc, fid, 0, frmhdr, sizeof(*frmhdr)) != 0
1025	     || wi_mwrite_bap(sc, fid, off, m0, m0->m_pkthdr.len) != 0;
1026	m_freem(m0);
1027	if (error) {
1028		ifp->if_oerrors++;
1029		return -1;
1030	}
1031	sc->sc_txd[cur].d_len = off;
1032	if (sc->sc_txcur == cur) {
1033		if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, fid, 0, 0)) {
1034			if_printf(ifp, "xmit failed\n");
1035			sc->sc_txd[cur].d_len = 0;
1036			return -1;
1037		}
1038		sc->sc_tx_timer = 5;
1039	}
1040	return 0;
1041}
1042
1043static int
1044wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0,
1045	    const struct ieee80211_bpf_params *params)
1046{
1047	struct ieee80211com *ic = ni->ni_ic;
1048	struct ifnet *ifp = ic->ic_ifp;
1049	struct wi_softc	*sc = ifp->if_softc;
1050	struct ieee80211_frame *wh;
1051	struct wi_frame frmhdr;
1052	int cur;
1053	int rc = 0;
1054
1055	WI_LOCK(sc);
1056
1057	if (sc->wi_gone) {
1058		rc = ENETDOWN;
1059		goto out;
1060	}
1061	if (sc->sc_flags & WI_FLAGS_OUTRANGE) {
1062		rc = ENETDOWN;
1063		goto out;
1064	}
1065
1066	memset(&frmhdr, 0, sizeof(frmhdr));
1067	cur = sc->sc_txnext;
1068	if (sc->sc_txd[cur].d_len != 0) {
1069		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1070		rc = ENOBUFS;
1071		goto out;
1072	}
1073	m0->m_pkthdr.rcvif = NULL;
1074
1075	m_copydata(m0, 4, ETHER_ADDR_LEN * 2,
1076	    (caddr_t)&frmhdr.wi_ehdr);
1077	frmhdr.wi_ehdr.ether_type = 0;
1078	wh = mtod(m0, struct ieee80211_frame *);
1079
1080#if NBPFILTER > 0
1081	if (bpf_peers_present(ic->ic_rawbpf))
1082		bpf_mtap(ic->ic_rawbpf, m0);
1083#endif
1084	frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX);
1085	if (params && (params->ibp_flags & IEEE80211_BPF_NOACK))
1086		frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY);
1087	/* XXX check key for SWCRYPT instead of using operating mode */
1088	if ((wh->i_fc[1] & IEEE80211_FC1_WEP) &&
1089	    (sc->sc_encryption & HOST_ENCRYPT)) {
1090	    	if (!params ||
1091		    (params && (params->ibp_flags & IEEE80211_BPF_CRYPTO))) {
1092			struct ieee80211_key *k;
1093
1094			k = ieee80211_crypto_encap(ic, ni, m0);
1095			if (k == NULL) {
1096				if (ni != NULL)
1097					ieee80211_free_node(ni);
1098				m_freem(m0);
1099				rc = ENOMEM;
1100				goto out;
1101			}
1102			frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT);
1103		}
1104	}
1105#if NBPFILTER > 0
1106	if (bpf_peers_present(sc->sc_drvbpf)) {
1107		sc->sc_tx_th.wt_rate =
1108			ni->ni_rates.rs_rates[ni->ni_txrate];
1109		bpf_mtap2(sc->sc_drvbpf,
1110			&sc->sc_tx_th, sc->sc_tx_th_len, m0);
1111	}
1112#endif
1113	m_copydata(m0, 0, sizeof(struct ieee80211_frame),
1114	    (caddr_t)&frmhdr.wi_whdr);
1115	m_adj(m0, sizeof(struct ieee80211_frame));
1116	frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len);
1117	if (IFF_DUMPPKTS(ifp))
1118		wi_dump_pkt(&frmhdr, NULL, -1);
1119	if (ni != NULL)
1120		ieee80211_free_node(ni);
1121	rc = wi_start_tx(ifp, &frmhdr, m0);
1122	if (rc)
1123		goto out;
1124
1125	sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
1126out:
1127	WI_UNLOCK(sc);
1128
1129	return rc;
1130}
1131
1132static int
1133wi_reset(struct wi_softc *sc)
1134{
1135	struct ifnet *ifp = sc->sc_ifp;
1136#define WI_INIT_TRIES 3
1137	int i;
1138	int error = 0;
1139	int tries;
1140
1141	/* Symbol firmware cannot be initialized more than once */
1142	if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_reset)
1143		return (0);
1144	if (sc->sc_firmware_type == WI_SYMBOL)
1145		tries = 1;
1146	else
1147		tries = WI_INIT_TRIES;
1148
1149	for (i = 0; i < tries; i++) {
1150		if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0)
1151			break;
1152		DELAY(WI_DELAY * 1000);
1153	}
1154	sc->sc_reset = 1;
1155
1156	if (i == tries) {
1157		if_printf(ifp, "init failed\n");
1158		return (error);
1159	}
1160
1161	CSR_WRITE_2(sc, WI_INT_EN, 0);
1162	CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
1163
1164	/* Calibrate timer. */
1165	wi_write_val(sc, WI_RID_TICK_TIME, 8);
1166
1167	return (0);
1168#undef WI_INIT_TRIES
1169}
1170
1171static void
1172wi_watchdog(void *arg)
1173{
1174	struct wi_softc	*sc = arg;
1175	struct ifnet *ifp = sc->sc_ifp;
1176
1177	if (!sc->sc_enabled)
1178		return;
1179
1180	if (sc->sc_tx_timer) {
1181		if (--sc->sc_tx_timer == 0) {
1182			if_printf(ifp, "device timeout\n");
1183			ifp->if_oerrors++;
1184			wi_init(ifp->if_softc);
1185			return;
1186		}
1187	}
1188
1189	if (sc->sc_scan_timer) {
1190		if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT &&
1191		    sc->sc_firmware_type == WI_INTERSIL) {
1192			DPRINTF(("wi_watchdog: inquire scan\n"));
1193			wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
1194		}
1195	}
1196
1197	/* TODO: rate control */
1198	ieee80211_watchdog(&sc->sc_ic);
1199
1200	callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc);
1201}
1202
1203static int
1204wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1205{
1206	struct wi_softc *sc = ifp->if_softc;
1207	struct ieee80211com *ic = &sc->sc_ic;
1208	struct ifreq *ifr = (struct ifreq *)data;
1209	struct ieee80211req *ireq;
1210	u_int8_t nodename[IEEE80211_NWID_LEN];
1211	int error = 0;
1212	struct thread *td = curthread;
1213	struct wi_req wreq;
1214
1215	if (sc->wi_gone)
1216		return (ENODEV);
1217
1218	switch (cmd) {
1219	case SIOCSIFFLAGS:
1220		/*
1221		 * Can't do promisc and hostap at the same time.  If all that's
1222		 * changing is the promisc flag, try to short-circuit a call to
1223		 * wi_init() by just setting PROMISC in the hardware.
1224		 */
1225		WI_LOCK(sc);
1226		if (ifp->if_flags & IFF_UP) {
1227			if (ic->ic_opmode != IEEE80211_M_HOSTAP &&
1228			    ifp->if_drv_flags & IFF_DRV_RUNNING) {
1229				if (ifp->if_flags & IFF_PROMISC &&
1230				    !(sc->sc_if_flags & IFF_PROMISC)) {
1231					wi_write_val(sc, WI_RID_PROMISC, 1);
1232				} else if (!(ifp->if_flags & IFF_PROMISC) &&
1233				    sc->sc_if_flags & IFF_PROMISC) {
1234					wi_write_val(sc, WI_RID_PROMISC, 0);
1235				} else {
1236					wi_init(sc);
1237				}
1238			} else {
1239				wi_init(sc);
1240			}
1241		} else {
1242			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1243				wi_stop(ifp, 1);
1244			}
1245			sc->wi_gone = 0;
1246		}
1247		sc->sc_if_flags = ifp->if_flags;
1248		WI_UNLOCK(sc);
1249		error = 0;
1250		break;
1251	case SIOCADDMULTI:
1252	case SIOCDELMULTI:
1253		WI_LOCK(sc);
1254		error = wi_write_multi(sc);
1255		WI_UNLOCK(sc);
1256		break;
1257	case SIOCGIFGENERIC:
1258		WI_LOCK(sc);
1259		error = wi_get_cfg(ifp, cmd, data);
1260		WI_UNLOCK(sc);
1261		break;
1262	case SIOCSIFGENERIC:
1263		error = priv_check(td, PRIV_DRIVER);
1264		if (error == 0)
1265			error = wi_set_cfg(ifp, cmd, data);
1266		break;
1267	case SIOCGPRISM2DEBUG:
1268		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1269		if (error)
1270			break;
1271		if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) ||
1272		    sc->sc_firmware_type == WI_LUCENT) {
1273			error = EIO;
1274			break;
1275		}
1276		error = wi_get_debug(sc, &wreq);
1277		if (error == 0)
1278			error = copyout(&wreq, ifr->ifr_data, sizeof(wreq));
1279		break;
1280	case SIOCSPRISM2DEBUG:
1281		if ((error = priv_check(td, PRIV_DRIVER)))
1282			return (error);
1283		error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1284		if (error)
1285			break;
1286		WI_LOCK(sc);
1287		error = wi_set_debug(sc, &wreq);
1288		WI_UNLOCK(sc);
1289		break;
1290	case SIOCG80211:
1291		ireq = (struct ieee80211req *) data;
1292		if (ireq->i_type == IEEE80211_IOC_STATIONNAME) {
1293			ireq->i_len = sc->sc_nodelen + 1;
1294			error = copyout(sc->sc_nodename, ireq->i_data,
1295					ireq->i_len);
1296			break;
1297		}
1298		goto ioctl_common;
1299	case SIOCS80211:
1300		ireq = (struct ieee80211req *) data;
1301		if (ireq->i_type == IEEE80211_IOC_STATIONNAME) {
1302			error = priv_check(td, PRIV_NET80211_MANAGE);
1303			if (error)
1304				break;
1305			if (ireq->i_val != 0 ||
1306			    ireq->i_len > IEEE80211_NWID_LEN) {
1307				error = EINVAL;
1308				break;
1309			}
1310			memset(nodename, 0, IEEE80211_NWID_LEN);
1311			error = copyin(ireq->i_data, nodename, ireq->i_len);
1312			if (error)
1313				break;
1314			WI_LOCK(sc);
1315			if (sc->sc_enabled) {
1316				error = wi_write_ssid(sc, WI_RID_NODENAME,
1317					nodename, ireq->i_len);
1318			}
1319			if (error == 0) {
1320				memcpy(sc->sc_nodename, nodename,
1321					IEEE80211_NWID_LEN);
1322				sc->sc_nodelen = ireq->i_len;
1323			}
1324			WI_UNLOCK(sc);
1325			break;
1326		}
1327		goto ioctl_common;
1328	default:
1329	ioctl_common:
1330		WI_LOCK(sc);
1331		error = ieee80211_ioctl(ic, cmd, data);
1332		if (error == ENETRESET) {
1333			if (sc->sc_enabled)
1334				wi_init(sc);	/* XXX no error return */
1335			error = 0;
1336		}
1337		WI_UNLOCK(sc);
1338		break;
1339	}
1340	return (error);
1341}
1342
1343static int
1344wi_media_change(struct ifnet *ifp)
1345{
1346	struct wi_softc *sc = ifp->if_softc;
1347	int error;
1348
1349	error = ieee80211_media_change(ifp);
1350	if (error == ENETRESET) {
1351		if (sc->sc_enabled)
1352			wi_init(sc);	/* XXX no error return */
1353		error = 0;
1354	}
1355	return error;
1356}
1357
1358static void
1359wi_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1360{
1361	struct wi_softc *sc = ifp->if_softc;
1362	struct ieee80211com *ic = &sc->sc_ic;
1363	u_int16_t val;
1364	int rate, len;
1365
1366	if (sc->wi_gone) {		/* hardware gone (e.g. ejected) */
1367		imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
1368		imr->ifm_status = 0;
1369		return;
1370	}
1371
1372	imr->ifm_status = IFM_AVALID;
1373	imr->ifm_active = IFM_IEEE80211;
1374	if (!sc->sc_enabled) {		/* port !enabled, have no status */
1375		imr->ifm_active |= IFM_NONE;
1376		imr->ifm_status = IFM_AVALID;
1377		return;
1378	}
1379	if (ic->ic_state == IEEE80211_S_RUN &&
1380	    (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0)
1381		imr->ifm_status |= IFM_ACTIVE;
1382	len = sizeof(val);
1383	if (wi_read_rid(sc, WI_RID_CUR_TX_RATE, &val, &len) == 0 &&
1384	    len == sizeof(val)) {
1385		/* convert to 802.11 rate */
1386		val = le16toh(val);
1387		rate = val * 2;
1388		if (sc->sc_firmware_type == WI_LUCENT) {
1389			if (rate == 10)
1390				rate = 11;	/* 5.5Mbps */
1391		} else {
1392			if (rate == 4*2)
1393				rate = 11;	/* 5.5Mbps */
1394			else if (rate == 8*2)
1395				rate = 22;	/* 11Mbps */
1396		}
1397	} else
1398		rate = 0;
1399	imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B);
1400	switch (ic->ic_opmode) {
1401	case IEEE80211_M_STA:
1402		break;
1403	case IEEE80211_M_IBSS:
1404		imr->ifm_active |= IFM_IEEE80211_ADHOC;
1405		break;
1406	case IEEE80211_M_AHDEMO:
1407		imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0;
1408		break;
1409	case IEEE80211_M_HOSTAP:
1410		imr->ifm_active |= IFM_IEEE80211_HOSTAP;
1411		break;
1412	case IEEE80211_M_MONITOR:
1413		imr->ifm_active |= IFM_IEEE80211_MONITOR;
1414		break;
1415	}
1416}
1417
1418static void
1419wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN])
1420{
1421	struct ieee80211com *ic = &sc->sc_ic;
1422	struct ieee80211_node *ni = ic->ic_bss;
1423	struct ifnet *ifp = sc->sc_ifp;
1424
1425	if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid))
1426		return;
1427
1428	DPRINTF(("wi_sync_bssid: bssid %s -> ", ether_sprintf(ni->ni_bssid)));
1429	DPRINTF(("%s ?\n", ether_sprintf(new_bssid)));
1430
1431	/* In promiscuous mode, the BSSID field is not a reliable
1432	 * indicator of the firmware's BSSID. Damp spurious
1433	 * change-of-BSSID indications.
1434	 */
1435	if ((ifp->if_flags & IFF_PROMISC) != 0 &&
1436	    !ppsratecheck(&sc->sc_last_syn, &sc->sc_false_syns,
1437	                 WI_MAX_FALSE_SYNS))
1438		return;
1439
1440	sc->sc_false_syns = MAX(0, sc->sc_false_syns - 1);
1441	/*
1442	 * XXX hack; we should create a new node with the new bssid
1443	 * and replace the existing ic_bss with it but since we don't
1444	 * process management frames to collect state we cheat by
1445	 * reusing the existing node as we know wi_newstate will be
1446	 * called and it will overwrite the node state.
1447	 */
1448	ieee80211_sta_join(ic, ieee80211_ref_node(ni));
1449}
1450
1451static void
1452wi_rx_monitor(struct wi_softc *sc, int fid)
1453{
1454	struct ifnet *ifp = sc->sc_ifp;
1455	struct wi_frame *rx_frame;
1456	struct mbuf *m;
1457	int datlen, hdrlen;
1458
1459	/* first allocate mbuf for packet storage */
1460	m = m_getcl(M_DONTWAIT, MT_DATA, 0);
1461	if (m == NULL) {
1462		ifp->if_ierrors++;
1463		return;
1464	}
1465
1466	m->m_pkthdr.rcvif = ifp;
1467
1468	/* now read wi_frame first so we know how much data to read */
1469	if (wi_read_bap(sc, fid, 0, mtod(m, caddr_t), sizeof(*rx_frame))) {
1470		ifp->if_ierrors++;
1471		goto done;
1472	}
1473
1474	rx_frame = mtod(m, struct wi_frame *);
1475
1476	switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) {
1477	case 7:
1478		switch (rx_frame->wi_whdr.i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1479		case IEEE80211_FC0_TYPE_DATA:
1480			hdrlen = WI_DATA_HDRLEN;
1481			datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
1482			break;
1483		case IEEE80211_FC0_TYPE_MGT:
1484			hdrlen = WI_MGMT_HDRLEN;
1485			datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
1486			break;
1487		case IEEE80211_FC0_TYPE_CTL:
1488			/*
1489			 * prism2 cards don't pass control packets
1490			 * down properly or consistently, so we'll only
1491			 * pass down the header.
1492			 */
1493			hdrlen = WI_CTL_HDRLEN;
1494			datlen = 0;
1495			break;
1496		default:
1497			if_printf(ifp, "received packet of unknown type "
1498				"on port 7\n");
1499			ifp->if_ierrors++;
1500			goto done;
1501		}
1502		break;
1503	case 0:
1504		hdrlen = WI_DATA_HDRLEN;
1505		datlen = rx_frame->wi_dat_len + WI_FCS_LEN;
1506		break;
1507	default:
1508		if_printf(ifp, "received packet on invalid "
1509		    "port (wi_status=0x%x)\n", rx_frame->wi_status);
1510		ifp->if_ierrors++;
1511		goto done;
1512	}
1513
1514	if (hdrlen + datlen + 2 > MCLBYTES) {
1515		if_printf(ifp, "oversized packet received "
1516		    "(wi_dat_len=%d, wi_status=0x%x)\n",
1517		    datlen, rx_frame->wi_status);
1518		ifp->if_ierrors++;
1519		goto done;
1520	}
1521
1522	if (wi_read_bap(sc, fid, hdrlen, mtod(m, caddr_t) + hdrlen,
1523	    datlen + 2) == 0) {
1524		m->m_pkthdr.len = m->m_len = hdrlen + datlen;
1525		ifp->if_ipackets++;
1526		BPF_MTAP(ifp, m);	/* Handle BPF listeners. */
1527	} else
1528		ifp->if_ierrors++;
1529done:
1530	m_freem(m);
1531}
1532
1533static void
1534wi_rx_intr(struct wi_softc *sc)
1535{
1536	struct ieee80211com *ic = &sc->sc_ic;
1537	struct ifnet *ifp = sc->sc_ifp;
1538	struct wi_frame frmhdr;
1539	struct mbuf *m;
1540	struct ieee80211_frame *wh;
1541	struct ieee80211_node *ni;
1542	int fid, len, off, rssi;
1543	u_int8_t dir;
1544	u_int16_t status;
1545	u_int32_t rstamp;
1546
1547	fid = CSR_READ_2(sc, WI_RX_FID);
1548
1549	if (sc->wi_debug.wi_monitor) {
1550		/*
1551		 * If we are in monitor mode just
1552		 * read the data from the device.
1553		 */
1554		wi_rx_monitor(sc, fid);
1555		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1556		return;
1557	}
1558
1559	/* First read in the frame header */
1560	if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) {
1561		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1562		ifp->if_ierrors++;
1563		DPRINTF(("wi_rx_intr: read fid %x failed\n", fid));
1564		return;
1565	}
1566
1567	if (IFF_DUMPPKTS(ifp))
1568		wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal);
1569
1570	/*
1571	 * Drop undecryptable or packets with receive errors here
1572	 */
1573	status = le16toh(frmhdr.wi_status);
1574	if (status & WI_STAT_ERRSTAT) {
1575		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1576		ifp->if_ierrors++;
1577		DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status));
1578		return;
1579	}
1580	rssi = frmhdr.wi_rx_signal;
1581	rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) |
1582	    le16toh(frmhdr.wi_rx_tstamp1);
1583
1584	len = le16toh(frmhdr.wi_dat_len);
1585	off = ALIGN(sizeof(struct ieee80211_frame));
1586
1587	/*
1588	 * Sometimes the PRISM2.x returns bogusly large frames. Except
1589	 * in monitor mode, just throw them away.
1590	 */
1591	if (off + len > MCLBYTES) {
1592		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
1593			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1594			ifp->if_ierrors++;
1595			DPRINTF(("wi_rx_intr: oversized packet\n"));
1596			return;
1597		} else
1598			len = 0;
1599	}
1600
1601	MGETHDR(m, M_DONTWAIT, MT_DATA);
1602	if (m == NULL) {
1603		CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1604		ifp->if_ierrors++;
1605		DPRINTF(("wi_rx_intr: MGET failed\n"));
1606		return;
1607	}
1608	if (off + len > MHLEN) {
1609		MCLGET(m, M_DONTWAIT);
1610		if ((m->m_flags & M_EXT) == 0) {
1611			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1612			m_freem(m);
1613			ifp->if_ierrors++;
1614			DPRINTF(("wi_rx_intr: MCLGET failed\n"));
1615			return;
1616		}
1617	}
1618
1619	m->m_data += off - sizeof(struct ieee80211_frame);
1620	memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame));
1621	wi_read_bap(sc, fid, sizeof(frmhdr),
1622	    m->m_data + sizeof(struct ieee80211_frame), len);
1623	m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame) + len;
1624	m->m_pkthdr.rcvif = ifp;
1625
1626	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX);
1627
1628#if NBPFILTER > 0
1629	if (bpf_peers_present(sc->sc_drvbpf)) {
1630		/* XXX replace divide by table */
1631		sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5;
1632		sc->sc_rx_th.wr_antsignal = frmhdr.wi_rx_signal;
1633		sc->sc_rx_th.wr_antnoise = frmhdr.wi_rx_silence;
1634		sc->sc_rx_th.wr_flags = 0;
1635		if (frmhdr.wi_status & WI_STAT_PCF)
1636			sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_CFP;
1637		/* XXX IEEE80211_RADIOTAP_F_WEP */
1638		bpf_mtap2(sc->sc_drvbpf,
1639			&sc->sc_rx_th, sc->sc_rx_th_len, m);
1640	}
1641#endif
1642	wh = mtod(m, struct ieee80211_frame *);
1643	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1644		/*
1645		 * WEP is decrypted by hardware and the IV
1646		 * is stripped.  Clear WEP bit so we don't
1647		 * try to process it in ieee80211_input.
1648		 * XXX fix for TKIP, et. al.
1649		 */
1650		wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1651	}
1652
1653	/* synchronize driver's BSSID with firmware's BSSID */
1654	dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
1655	if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS)
1656		wi_sync_bssid(sc, wh->i_addr3);
1657
1658	WI_UNLOCK(sc);
1659	/*
1660	 * Locate the node for sender, track state, and
1661	 * then pass this node (referenced) up to the 802.11
1662	 * layer for its use.
1663	 */
1664	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh);
1665	/*
1666	 * Send frame up for processing.
1667	 */
1668	ieee80211_input(ic, m, ni, rssi, rstamp);
1669	/*
1670	 * The frame may have caused the node to be marked for
1671	 * reclamation (e.g. in response to a DEAUTH message)
1672	 * so use free_node here instead of unref_node.
1673	 */
1674	ieee80211_free_node(ni);
1675
1676	WI_LOCK(sc);
1677}
1678
1679static void
1680wi_tx_ex_intr(struct wi_softc *sc)
1681{
1682	struct ifnet *ifp = sc->sc_ifp;
1683	struct wi_frame frmhdr;
1684	int fid;
1685
1686	fid = CSR_READ_2(sc, WI_TX_CMP_FID);
1687	/* Read in the frame header */
1688	if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) == 0) {
1689		u_int16_t status = le16toh(frmhdr.wi_status);
1690
1691		/*
1692		 * Spontaneous station disconnects appear as xmit
1693		 * errors.  Don't announce them and/or count them
1694		 * as an output error.
1695		 */
1696		if ((status & WI_TXSTAT_DISCONNECT) == 0) {
1697			if (ppsratecheck(&lasttxerror, &curtxeps, wi_txerate)) {
1698				if_printf(ifp, "tx failed");
1699				if (status & WI_TXSTAT_RET_ERR)
1700					printf(", retry limit exceeded");
1701				if (status & WI_TXSTAT_AGED_ERR)
1702					printf(", max transmit lifetime exceeded");
1703				if (status & WI_TXSTAT_DISCONNECT)
1704					printf(", port disconnected");
1705				if (status & WI_TXSTAT_FORM_ERR)
1706					printf(", invalid format (data len %u src %6D)",
1707						le16toh(frmhdr.wi_dat_len),
1708						frmhdr.wi_ehdr.ether_shost, ":");
1709				if (status & ~0xf)
1710					printf(", status=0x%x", status);
1711				printf("\n");
1712			}
1713			ifp->if_oerrors++;
1714		} else {
1715			DPRINTF(("port disconnected\n"));
1716			ifp->if_collisions++;	/* XXX */
1717		}
1718	} else
1719		DPRINTF(("wi_tx_ex_intr: read fid %x failed\n", fid));
1720	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC);
1721}
1722
1723static void
1724wi_tx_intr(struct wi_softc *sc)
1725{
1726	struct ifnet *ifp = sc->sc_ifp;
1727	int fid, cur;
1728
1729	if (sc->wi_gone)
1730		return;
1731
1732	fid = CSR_READ_2(sc, WI_ALLOC_FID);
1733	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
1734
1735	cur = sc->sc_txcur;
1736	if (sc->sc_txd[cur].d_fid != fid) {
1737		if_printf(ifp, "bad alloc %x != %x, cur %d nxt %d\n",
1738		    fid, sc->sc_txd[cur].d_fid, cur, sc->sc_txnext);
1739		return;
1740	}
1741	sc->sc_tx_timer = 0;
1742	sc->sc_txd[cur].d_len = 0;
1743	sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf;
1744	if (sc->sc_txd[cur].d_len == 0)
1745		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1746	else {
1747		if (wi_cmd(sc, WI_CMD_TX | WI_RECLAIM, sc->sc_txd[cur].d_fid,
1748		    0, 0)) {
1749			if_printf(ifp, "xmit failed\n");
1750			sc->sc_txd[cur].d_len = 0;
1751		} else {
1752			sc->sc_tx_timer = 5;
1753		}
1754	}
1755}
1756
1757static void
1758wi_info_intr(struct wi_softc *sc)
1759{
1760	struct ieee80211com *ic = &sc->sc_ic;
1761	struct ifnet *ifp = sc->sc_ifp;
1762	int i, fid, len, off;
1763	u_int16_t ltbuf[2];
1764	u_int16_t stat;
1765	u_int32_t *ptr;
1766
1767	fid = CSR_READ_2(sc, WI_INFO_FID);
1768	wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf));
1769
1770	switch (le16toh(ltbuf[1])) {
1771
1772	case WI_INFO_LINK_STAT:
1773		wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat));
1774		DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat)));
1775		switch (le16toh(stat)) {
1776		case WI_INFO_LINK_STAT_CONNECTED:
1777			sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
1778			if (ic->ic_state == IEEE80211_S_RUN &&
1779			    ic->ic_opmode != IEEE80211_M_IBSS)
1780				break;
1781			/* FALLTHROUGH */
1782		case WI_INFO_LINK_STAT_AP_CHG:
1783			ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1784			break;
1785		case WI_INFO_LINK_STAT_AP_INR:
1786			sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
1787			break;
1788		case WI_INFO_LINK_STAT_AP_OOR:
1789			if (sc->sc_firmware_type == WI_SYMBOL &&
1790			    sc->sc_scan_timer > 0) {
1791				if (wi_cmd(sc, WI_CMD_INQUIRE,
1792				    WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0)
1793					sc->sc_scan_timer = 0;
1794				break;
1795			}
1796			if (ic->ic_opmode == IEEE80211_M_STA)
1797				sc->sc_flags |= WI_FLAGS_OUTRANGE;
1798			break;
1799		case WI_INFO_LINK_STAT_DISCONNECTED:
1800		case WI_INFO_LINK_STAT_ASSOC_FAILED:
1801			if (ic->ic_opmode == IEEE80211_M_STA)
1802				ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1803			break;
1804		}
1805		break;
1806
1807	case WI_INFO_COUNTERS:
1808		/* some card versions have a larger stats structure */
1809		len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4);
1810		ptr = (u_int32_t *)&sc->sc_stats;
1811		off = sizeof(ltbuf);
1812		for (i = 0; i < len; i++, off += 2, ptr++) {
1813			wi_read_bap(sc, fid, off, &stat, sizeof(stat));
1814#ifdef WI_HERMES_STATS_WAR
1815			if (stat & 0xf000)
1816				stat = ~stat;
1817#endif
1818			*ptr += stat;
1819		}
1820		ifp->if_collisions = sc->sc_stats.wi_tx_single_retries +
1821		    sc->sc_stats.wi_tx_multi_retries +
1822		    sc->sc_stats.wi_tx_retry_limit;
1823		break;
1824
1825	case WI_INFO_SCAN_RESULTS:
1826	case WI_INFO_HOST_SCAN_RESULTS:
1827		wi_scan_result(sc, fid, le16toh(ltbuf[0]));
1828		break;
1829
1830	default:
1831		DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid,
1832		    le16toh(ltbuf[1]), le16toh(ltbuf[0])));
1833		break;
1834	}
1835	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_INFO);
1836}
1837
1838static int
1839wi_write_multi(struct wi_softc *sc)
1840{
1841	struct ifnet *ifp = sc->sc_ifp;
1842	int n;
1843	struct ifmultiaddr *ifma;
1844	struct wi_mcast mlist;
1845
1846	if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
1847allmulti:
1848		memset(&mlist, 0, sizeof(mlist));
1849		return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
1850		    sizeof(mlist));
1851	}
1852
1853	n = 0;
1854	IF_ADDR_LOCK(ifp);
1855	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1856		if (ifma->ifma_addr->sa_family != AF_LINK)
1857			continue;
1858		if (n >= 16)
1859			goto allmulti;
1860		IEEE80211_ADDR_COPY(&mlist.wi_mcast[n],
1861		    (LLADDR((struct sockaddr_dl *)ifma->ifma_addr)));
1862		n++;
1863	}
1864	IF_ADDR_UNLOCK(ifp);
1865	return wi_write_rid(sc, WI_RID_MCAST_LIST, &mlist,
1866	    IEEE80211_ADDR_LEN * n);
1867}
1868
1869static void
1870wi_read_nicid(struct wi_softc *sc)
1871{
1872	struct wi_card_ident *id;
1873	char *p;
1874	int len;
1875	u_int16_t ver[4];
1876
1877	/* getting chip identity */
1878	memset(ver, 0, sizeof(ver));
1879	len = sizeof(ver);
1880	wi_read_rid(sc, WI_RID_CARD_ID, ver, &len);
1881	device_printf(sc->sc_dev, "using ");
1882
1883	sc->sc_firmware_type = WI_NOTYPE;
1884	for (id = wi_card_ident; id->card_name != NULL; id++) {
1885		if (le16toh(ver[0]) == id->card_id) {
1886			printf("%s", id->card_name);
1887			sc->sc_firmware_type = id->firm_type;
1888			break;
1889		}
1890	}
1891	if (sc->sc_firmware_type == WI_NOTYPE) {
1892		if (le16toh(ver[0]) & 0x8000) {
1893			printf("Unknown PRISM2 chip");
1894			sc->sc_firmware_type = WI_INTERSIL;
1895		} else {
1896			printf("Unknown Lucent chip");
1897			sc->sc_firmware_type = WI_LUCENT;
1898		}
1899	}
1900
1901	/* get primary firmware version (Only Prism chips) */
1902	if (sc->sc_firmware_type != WI_LUCENT) {
1903		memset(ver, 0, sizeof(ver));
1904		len = sizeof(ver);
1905		wi_read_rid(sc, WI_RID_PRI_IDENTITY, ver, &len);
1906		sc->sc_pri_firmware_ver = le16toh(ver[2]) * 10000 +
1907		    le16toh(ver[3]) * 100 + le16toh(ver[1]);
1908	}
1909
1910	/* get station firmware version */
1911	memset(ver, 0, sizeof(ver));
1912	len = sizeof(ver);
1913	wi_read_rid(sc, WI_RID_STA_IDENTITY, ver, &len);
1914	sc->sc_sta_firmware_ver = le16toh(ver[2]) * 10000 +
1915	    le16toh(ver[3]) * 100 + le16toh(ver[1]);
1916	if (sc->sc_firmware_type == WI_INTERSIL &&
1917	    (sc->sc_sta_firmware_ver == 10102 ||
1918	     sc->sc_sta_firmware_ver == 20102)) {
1919		char ident[12];
1920		memset(ident, 0, sizeof(ident));
1921		len = sizeof(ident);
1922		/* value should be the format like "V2.00-11" */
1923		if (wi_read_rid(sc, WI_RID_SYMBOL_IDENTITY, ident, &len) == 0 &&
1924		    *(p = (char *)ident) >= 'A' &&
1925		    p[2] == '.' && p[5] == '-' && p[8] == '\0') {
1926			sc->sc_firmware_type = WI_SYMBOL;
1927			sc->sc_sta_firmware_ver = (p[1] - '0') * 10000 +
1928			    (p[3] - '0') * 1000 + (p[4] - '0') * 100 +
1929			    (p[6] - '0') * 10 + (p[7] - '0');
1930		}
1931	}
1932	printf("\n");
1933	device_printf(sc->sc_dev, "%s Firmware: ",
1934	     sc->sc_firmware_type == WI_LUCENT ? "Lucent" :
1935	    (sc->sc_firmware_type == WI_SYMBOL ? "Symbol" : "Intersil"));
1936	if (sc->sc_firmware_type != WI_LUCENT)	/* XXX */
1937		printf("Primary (%u.%u.%u), ",
1938		    sc->sc_pri_firmware_ver / 10000,
1939		    (sc->sc_pri_firmware_ver % 10000) / 100,
1940		    sc->sc_pri_firmware_ver % 100);
1941	printf("Station (%u.%u.%u)\n",
1942	    sc->sc_sta_firmware_ver / 10000,
1943	    (sc->sc_sta_firmware_ver % 10000) / 100,
1944	    sc->sc_sta_firmware_ver % 100);
1945}
1946
1947static int
1948wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t *buf, int buflen)
1949{
1950	struct wi_ssid ssid;
1951
1952	if (buflen > IEEE80211_NWID_LEN)
1953		return ENOBUFS;
1954	memset(&ssid, 0, sizeof(ssid));
1955	ssid.wi_len = htole16(buflen);
1956	memcpy(ssid.wi_ssid, buf, buflen);
1957	return wi_write_rid(sc, rid, &ssid, sizeof(ssid));
1958}
1959
1960static int
1961wi_get_cfg(struct ifnet *ifp, u_long cmd, caddr_t data)
1962{
1963	struct wi_softc *sc = ifp->if_softc;
1964	struct ieee80211com *ic = &sc->sc_ic;
1965	struct ifreq *ifr = (struct ifreq *)data;
1966	struct wi_req wreq;
1967	struct wi_scan_res *res;
1968	size_t reslen;
1969	int len, n, error, mif, val, off, i;
1970
1971	error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
1972	if (error)
1973		return error;
1974	len = (wreq.wi_len - 1) * 2;
1975	if (len < sizeof(u_int16_t))
1976		return ENOSPC;
1977	if (len > sizeof(wreq.wi_val))
1978		len = sizeof(wreq.wi_val);
1979
1980	switch (wreq.wi_type) {
1981
1982	case WI_RID_IFACE_STATS:
1983		memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats));
1984		if (len < sizeof(sc->sc_stats))
1985			error = ENOSPC;
1986		else
1987			len = sizeof(sc->sc_stats);
1988		break;
1989
1990	case WI_RID_ENCRYPTION:
1991	case WI_RID_TX_CRYPT_KEY:
1992	case WI_RID_DEFLT_CRYPT_KEYS:
1993	case WI_RID_TX_RATE:
1994		return ieee80211_cfgget(ic, cmd, data);
1995
1996	case WI_RID_MICROWAVE_OVEN:
1997		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) {
1998			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
1999			    &len);
2000			break;
2001		}
2002		wreq.wi_val[0] = htole16(sc->sc_microwave_oven);
2003		len = sizeof(u_int16_t);
2004		break;
2005
2006	case WI_RID_DBM_ADJUST:
2007		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) {
2008			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2009			    &len);
2010			break;
2011		}
2012		wreq.wi_val[0] = htole16(sc->sc_dbm_offset);
2013		len = sizeof(u_int16_t);
2014		break;
2015
2016	case WI_RID_ROAMING_MODE:
2017		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) {
2018			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2019			    &len);
2020			break;
2021		}
2022		wreq.wi_val[0] = htole16(sc->sc_roaming_mode);
2023		len = sizeof(u_int16_t);
2024		break;
2025
2026	case WI_RID_SYSTEM_SCALE:
2027		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) {
2028			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2029			    &len);
2030			break;
2031		}
2032		wreq.wi_val[0] = htole16(sc->sc_system_scale);
2033		len = sizeof(u_int16_t);
2034		break;
2035
2036	case WI_RID_FRAG_THRESH:
2037		if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) {
2038			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2039			    &len);
2040			break;
2041		}
2042		wreq.wi_val[0] = htole16(ic->ic_fragthreshold);
2043		len = sizeof(u_int16_t);
2044		break;
2045
2046	case WI_RID_READ_APS:
2047		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
2048			return ieee80211_cfgget(ic, cmd, data);
2049		if (sc->sc_scan_timer > 0) {
2050			error = EINPROGRESS;
2051			break;
2052		}
2053		n = sc->sc_naps;
2054		if (len < sizeof(n)) {
2055			error = ENOSPC;
2056			break;
2057		}
2058		if (len < sizeof(n) + sizeof(struct wi_apinfo) * n)
2059			n = (len - sizeof(n)) / sizeof(struct wi_apinfo);
2060		len = sizeof(n) + sizeof(struct wi_apinfo) * n;
2061		memcpy(wreq.wi_val, &n, sizeof(n));
2062		memcpy((caddr_t)wreq.wi_val + sizeof(n), sc->sc_aps,
2063		    sizeof(struct wi_apinfo) * n);
2064		break;
2065
2066	case WI_RID_PRISM2:
2067		wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT;
2068		len = sizeof(u_int16_t);
2069		break;
2070
2071	case WI_RID_MIF:
2072		mif = wreq.wi_val[0];
2073		error = wi_cmd(sc, WI_CMD_READMIF, mif, 0, 0);
2074		val = CSR_READ_2(sc, WI_RESP0);
2075		wreq.wi_val[0] = val;
2076		len = sizeof(u_int16_t);
2077		break;
2078
2079	case WI_RID_ZERO_CACHE:
2080	case WI_RID_PROCFRAME:		/* ignore for compatibility */
2081		/* XXX ??? */
2082		break;
2083
2084	case WI_RID_READ_CACHE:
2085		return ieee80211_cfgget(ic, cmd, data);
2086
2087	case WI_RID_SCAN_RES:		/* compatibility interface */
2088		if (ic->ic_opmode == IEEE80211_M_HOSTAP)
2089			return ieee80211_cfgget(ic, cmd, data);
2090		if (sc->sc_scan_timer > 0) {
2091			error = EINPROGRESS;
2092			break;
2093		}
2094		n = sc->sc_naps;
2095		if (sc->sc_firmware_type == WI_LUCENT) {
2096			off = 0;
2097			reslen = WI_WAVELAN_RES_SIZE;
2098		} else {
2099			off = sizeof(struct wi_scan_p2_hdr);
2100			reslen = WI_PRISM2_RES_SIZE;
2101		}
2102		if (len < off + reslen * n)
2103			n = (len - off) / reslen;
2104		len = off + reslen * n;
2105		if (off != 0) {
2106			struct wi_scan_p2_hdr *p2 = (struct wi_scan_p2_hdr *)wreq.wi_val;
2107			/*
2108			 * Prepend Prism-specific header.
2109			 */
2110			if (len < sizeof(struct wi_scan_p2_hdr)) {
2111				error = ENOSPC;
2112				break;
2113			}
2114			p2 = (struct wi_scan_p2_hdr *)wreq.wi_val;
2115			p2->wi_rsvd = 0;
2116			p2->wi_reason = n;	/* XXX */
2117		}
2118		for (i = 0; i < n; i++, off += reslen) {
2119			const struct wi_apinfo *ap = &sc->sc_aps[i];
2120
2121			res = (struct wi_scan_res *)((char *)wreq.wi_val + off);
2122			res->wi_chan = ap->channel;
2123			res->wi_noise = ap->noise;
2124			res->wi_signal = ap->signal;
2125			IEEE80211_ADDR_COPY(res->wi_bssid, ap->bssid);
2126			res->wi_interval = ap->interval;
2127			res->wi_capinfo = ap->capinfo;
2128			res->wi_ssid_len = ap->namelen;
2129			memcpy(res->wi_ssid, ap->name,
2130				IEEE80211_NWID_LEN);
2131			if (sc->sc_firmware_type != WI_LUCENT) {
2132				/* XXX not saved from Prism cards */
2133				memset(res->wi_srates, 0,
2134					sizeof(res->wi_srates));
2135				res->wi_rate = ap->rate;
2136				res->wi_rsvd = 0;
2137			}
2138		}
2139		break;
2140
2141	default:
2142		if (sc->sc_enabled) {
2143			error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val,
2144			    &len);
2145			break;
2146		}
2147		switch (wreq.wi_type) {
2148		case WI_RID_MAX_DATALEN:
2149			wreq.wi_val[0] = htole16(sc->sc_max_datalen);
2150			len = sizeof(u_int16_t);
2151			break;
2152		case WI_RID_RTS_THRESH:
2153			wreq.wi_val[0] = htole16(ic->ic_rtsthreshold);
2154			len = sizeof(u_int16_t);
2155			break;
2156		case WI_RID_CNFAUTHMODE:
2157			wreq.wi_val[0] = htole16(sc->sc_cnfauthmode);
2158			len = sizeof(u_int16_t);
2159			break;
2160		case WI_RID_NODENAME:
2161			if (len < sc->sc_nodelen + sizeof(u_int16_t)) {
2162				error = ENOSPC;
2163				break;
2164			}
2165			len = sc->sc_nodelen + sizeof(u_int16_t);
2166			wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2);
2167			memcpy(&wreq.wi_val[1], sc->sc_nodename,
2168			    sc->sc_nodelen);
2169			break;
2170		default:
2171			return ieee80211_cfgget(ic, cmd, data);
2172		}
2173		break;
2174	}
2175	if (error)
2176		return error;
2177	wreq.wi_len = (len + 1) / 2 + 1;
2178	return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2);
2179}
2180
2181static int
2182wi_set_cfg(struct ifnet *ifp, u_long cmd, caddr_t data)
2183{
2184	struct wi_softc *sc = ifp->if_softc;
2185	struct ieee80211com *ic = &sc->sc_ic;
2186	struct ifreq *ifr = (struct ifreq *)data;
2187	struct wi_req wreq;
2188	struct mbuf *m;
2189	int i, len, error, mif, val;
2190	struct ieee80211_rateset *rs;
2191
2192	error = copyin(ifr->ifr_data, &wreq, sizeof(wreq));
2193	if (error)
2194		return error;
2195	len = wreq.wi_len ? (wreq.wi_len - 1) * 2 : 0;
2196	switch (wreq.wi_type) {
2197	case WI_RID_DBM_ADJUST:
2198		return ENODEV;
2199
2200	case WI_RID_NODENAME:
2201		if (le16toh(wreq.wi_val[0]) * 2 > len ||
2202		    le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) {
2203			error = ENOSPC;
2204			break;
2205		}
2206		WI_LOCK(sc);
2207		if (sc->sc_enabled)
2208			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2209			    len);
2210		if (error == 0) {
2211			sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2;
2212			memcpy(sc->sc_nodename, &wreq.wi_val[1],
2213				sc->sc_nodelen);
2214		}
2215		WI_UNLOCK(sc);
2216		break;
2217
2218	case WI_RID_MICROWAVE_OVEN:
2219	case WI_RID_ROAMING_MODE:
2220	case WI_RID_SYSTEM_SCALE:
2221	case WI_RID_FRAG_THRESH:
2222		/* XXX unlocked reads */
2223		if (wreq.wi_type == WI_RID_MICROWAVE_OVEN &&
2224		    (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0)
2225			break;
2226		if (wreq.wi_type == WI_RID_ROAMING_MODE &&
2227		    (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0)
2228			break;
2229		if (wreq.wi_type == WI_RID_SYSTEM_SCALE &&
2230		    (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0)
2231			break;
2232		if (wreq.wi_type == WI_RID_FRAG_THRESH &&
2233		    (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0)
2234			break;
2235		/* FALLTHROUGH */
2236	case WI_RID_RTS_THRESH:
2237	case WI_RID_CNFAUTHMODE:
2238	case WI_RID_MAX_DATALEN:
2239		WI_LOCK(sc);
2240		if (sc->sc_enabled) {
2241			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2242			    sizeof(u_int16_t));
2243			if (error != 0) {
2244				WI_UNLOCK(sc);
2245				break;
2246			}
2247		}
2248		switch (wreq.wi_type) {
2249		case WI_RID_FRAG_THRESH:
2250			ic->ic_fragthreshold = le16toh(wreq.wi_val[0]);
2251			break;
2252		case WI_RID_RTS_THRESH:
2253			ic->ic_rtsthreshold = le16toh(wreq.wi_val[0]);
2254			break;
2255		case WI_RID_MICROWAVE_OVEN:
2256			sc->sc_microwave_oven = le16toh(wreq.wi_val[0]);
2257			break;
2258		case WI_RID_ROAMING_MODE:
2259			sc->sc_roaming_mode = le16toh(wreq.wi_val[0]);
2260			break;
2261		case WI_RID_SYSTEM_SCALE:
2262			sc->sc_system_scale = le16toh(wreq.wi_val[0]);
2263			break;
2264		case WI_RID_CNFAUTHMODE:
2265			sc->sc_cnfauthmode = le16toh(wreq.wi_val[0]);
2266			break;
2267		case WI_RID_MAX_DATALEN:
2268			sc->sc_max_datalen = le16toh(wreq.wi_val[0]);
2269			break;
2270		}
2271		WI_UNLOCK(sc);
2272		break;
2273
2274	case WI_RID_TX_RATE:
2275		WI_LOCK(sc);
2276		switch (le16toh(wreq.wi_val[0])) {
2277		case 3:
2278			ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE;
2279			break;
2280		default:
2281			rs = &ic->ic_sup_rates[IEEE80211_MODE_11B];
2282			for (i = 0; i < rs->rs_nrates; i++) {
2283				if ((rs->rs_rates[i] & IEEE80211_RATE_VAL)
2284				    / 2 == le16toh(wreq.wi_val[0]))
2285					break;
2286			}
2287			if (i == rs->rs_nrates) {
2288				WI_UNLOCK(sc);
2289				return EINVAL;
2290			}
2291			ic->ic_fixed_rate = i;
2292		}
2293		if (sc->sc_enabled)
2294			error = wi_write_txrate(sc);
2295		WI_UNLOCK(sc);
2296		break;
2297
2298	case WI_RID_SCAN_APS:
2299		WI_LOCK(sc);
2300		if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP)
2301			error = wi_scan_ap(sc, 0x3fff, 0x000f);
2302		WI_UNLOCK(sc);
2303		break;
2304
2305	case WI_RID_SCAN_REQ:		/* compatibility interface */
2306		WI_LOCK(sc);
2307		if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP)
2308			error = wi_scan_ap(sc, wreq.wi_val[0], wreq.wi_val[1]);
2309		WI_UNLOCK(sc);
2310		break;
2311
2312	case WI_RID_MGMT_XMIT:
2313		WI_LOCK(sc);
2314		if (!sc->sc_enabled)
2315			error = ENETDOWN;
2316		else if (ic->ic_mgtq.ifq_len > 5)
2317			error = EAGAIN;
2318		else {
2319			/* NB: m_devget uses M_DONTWAIT so can hold the lock */
2320			/* XXX wi_len looks in u_int8_t, not in u_int16_t */
2321			m = m_devget((char *)&wreq.wi_val, wreq.wi_len, 0,
2322				ifp, NULL);
2323			if (m != NULL)
2324				IF_ENQUEUE(&ic->ic_mgtq, m);
2325			else
2326				error = ENOMEM;
2327		}
2328		WI_UNLOCK(sc);
2329		break;
2330
2331	case WI_RID_MIF:
2332		mif = wreq.wi_val[0];
2333		val = wreq.wi_val[1];
2334		WI_LOCK(sc);
2335		error = wi_cmd(sc, WI_CMD_WRITEMIF, mif, val, 0);
2336		WI_UNLOCK(sc);
2337		break;
2338
2339	case WI_RID_PROCFRAME:		/* ignore for compatibility */
2340		break;
2341
2342	case WI_RID_OWN_SSID:
2343		if (le16toh(wreq.wi_val[0]) * 2 > len ||
2344		    le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN) {
2345			error = ENOSPC;
2346			break;
2347		}
2348		WI_LOCK(sc);
2349		memset(ic->ic_des_essid, 0, IEEE80211_NWID_LEN);
2350		ic->ic_des_esslen = le16toh(wreq.wi_val[0]) * 2;
2351		memcpy(ic->ic_des_essid, &wreq.wi_val[1], ic->ic_des_esslen);
2352		if (sc->sc_enabled)
2353			wi_init(sc);	/* XXX no error return */
2354		WI_UNLOCK(sc);
2355		break;
2356
2357	default:
2358		WI_LOCK(sc);
2359		if (sc->sc_enabled)
2360			error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val,
2361			    len);
2362		if (error == 0) {
2363			/* XXX ieee80211_cfgset does a copyin */
2364			error = ieee80211_cfgset(ic, cmd, data);
2365			if (error == ENETRESET) {
2366				if (sc->sc_enabled)
2367					wi_init(sc);
2368				error = 0;
2369			}
2370		}
2371		WI_UNLOCK(sc);
2372		break;
2373	}
2374	return error;
2375}
2376
2377static int
2378wi_write_txrate(struct wi_softc *sc)
2379{
2380	struct ieee80211com *ic = &sc->sc_ic;
2381	int i;
2382	u_int16_t rate;
2383
2384	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
2385		rate = 0;	/* auto */
2386	else
2387		rate = (ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[ic->ic_fixed_rate] &
2388		    IEEE80211_RATE_VAL) / 2;
2389
2390	/* rate: 0, 1, 2, 5, 11 */
2391
2392	switch (sc->sc_firmware_type) {
2393	case WI_LUCENT:
2394		switch (rate) {
2395		case 0:			/* auto == 11mbps auto */
2396			rate = 3;
2397			break;
2398		/* case 1, 2 map to 1, 2*/
2399		case 5:			/* 5.5Mbps -> 4 */
2400			rate = 4;
2401			break;
2402		case 11:		/* 11mbps -> 5 */
2403			rate = 5;
2404			break;
2405		default:
2406			break;
2407		}
2408		break;
2409	default:
2410		/* Choose a bit according to this table.
2411		 *
2412		 * bit | data rate
2413		 * ----+-------------------
2414		 * 0   | 1Mbps
2415		 * 1   | 2Mbps
2416		 * 2   | 5.5Mbps
2417		 * 3   | 11Mbps
2418		 */
2419		for (i = 8; i > 0; i >>= 1) {
2420			if (rate >= i)
2421				break;
2422		}
2423		if (i == 0)
2424			rate = 0xf;	/* auto */
2425		else
2426			rate = i;
2427		break;
2428	}
2429	return wi_write_val(sc, WI_RID_TX_RATE, rate);
2430}
2431
2432static int
2433wi_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k,
2434	ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
2435{
2436	struct wi_softc *sc = ic->ic_ifp->if_softc;
2437
2438	/*
2439	 * When doing host encryption of outbound frames fail requests
2440	 * for keys that are not marked w/ the SWCRYPT flag so the
2441	 * net80211 layer falls back to s/w crypto.  Note that we also
2442	 * fixup existing keys below to handle mode changes.
2443	 */
2444	if ((sc->sc_encryption & HOST_ENCRYPT) &&
2445	    (k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0)
2446		return 0;
2447	return sc->sc_key_alloc(ic, k, keyix, rxkeyix);
2448}
2449
2450static int
2451wi_write_wep(struct wi_softc *sc)
2452{
2453	struct ieee80211com *ic = &sc->sc_ic;
2454	int error = 0;
2455	int i, keylen;
2456	u_int16_t val;
2457	struct wi_key wkey[IEEE80211_WEP_NKID];
2458
2459	switch (sc->sc_firmware_type) {
2460	case WI_LUCENT:
2461		val = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0;
2462		error = wi_write_val(sc, WI_RID_ENCRYPTION, val);
2463		if (error)
2464			break;
2465		if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0)
2466			break;
2467		error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_def_txkey);
2468		if (error)
2469			break;
2470		memset(wkey, 0, sizeof(wkey));
2471		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2472			keylen = ic->ic_nw_keys[i].wk_keylen;
2473			wkey[i].wi_keylen = htole16(keylen);
2474			memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key,
2475			    keylen);
2476		}
2477		error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS,
2478		    wkey, sizeof(wkey));
2479		sc->sc_encryption = 0;
2480		break;
2481
2482	case WI_INTERSIL:
2483	case WI_SYMBOL:
2484		if (ic->ic_flags & IEEE80211_F_PRIVACY) {
2485			/*
2486			 * ONLY HWB3163 EVAL-CARD Firmware version
2487			 * less than 0.8 variant2
2488			 *
2489			 *   If promiscuous mode disable, Prism2 chip
2490			 *  does not work with WEP .
2491			 * It is under investigation for details.
2492			 * (ichiro@netbsd.org)
2493			 */
2494			if (sc->sc_firmware_type == WI_INTERSIL &&
2495			    sc->sc_sta_firmware_ver < 802 ) {
2496				/* firm ver < 0.8 variant 2 */
2497				wi_write_val(sc, WI_RID_PROMISC, 1);
2498			}
2499			wi_write_val(sc, WI_RID_CNFAUTHMODE,
2500			    sc->sc_cnfauthmode);
2501			/* XXX should honor IEEE80211_F_DROPUNENC */
2502			val = PRIVACY_INVOKED | EXCLUDE_UNENCRYPTED;
2503			/*
2504			 * Encryption firmware has a bug for HostAP mode.
2505			 */
2506			if (sc->sc_firmware_type == WI_INTERSIL &&
2507			    ic->ic_opmode == IEEE80211_M_HOSTAP)
2508				val |= HOST_ENCRYPT;
2509		} else {
2510			wi_write_val(sc, WI_RID_CNFAUTHMODE,
2511			    IEEE80211_AUTH_OPEN);
2512			val = HOST_ENCRYPT | HOST_DECRYPT;
2513		}
2514		error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val);
2515		if (error)
2516			break;
2517		sc->sc_encryption = val;
2518		if ((val & PRIVACY_INVOKED) == 0)
2519			break;
2520		error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY,
2521		    ic->ic_def_txkey);
2522		if (error)
2523			break;
2524		if (val & HOST_DECRYPT)
2525			break;
2526		/*
2527		 * It seems that the firmware accept 104bit key only if
2528		 * all the keys have 104bit length.  We get the length of
2529		 * the transmit key and use it for all other keys.
2530		 * Perhaps we should use software WEP for such situation.
2531		 */
2532		if (ic->ic_def_txkey != IEEE80211_KEYIX_NONE)
2533			keylen = ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen;
2534		else	/* XXX should not hapen */
2535			keylen = IEEE80211_WEP_KEYLEN;
2536		if (keylen > IEEE80211_WEP_KEYLEN)
2537			keylen = 13;	/* 104bit keys */
2538		else
2539			keylen = IEEE80211_WEP_KEYLEN;
2540		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2541			error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i,
2542			    ic->ic_nw_keys[i].wk_key, keylen);
2543			if (error)
2544				break;
2545		}
2546		break;
2547	}
2548	/*
2549	 * XXX horrible hack; insure pre-existing keys are
2550	 * setup properly to do s/w crypto.
2551	 */
2552	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
2553		struct ieee80211_key *k = &ic->ic_nw_keys[i];
2554		if (k->wk_flags & IEEE80211_KEY_XMIT) {
2555			if (sc->sc_encryption & HOST_ENCRYPT)
2556				k->wk_flags |= IEEE80211_KEY_SWCRYPT;
2557			else
2558				k->wk_flags &= ~IEEE80211_KEY_SWCRYPT;
2559		}
2560	}
2561	return error;
2562}
2563
2564static int
2565wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
2566{
2567	int			i, s = 0;
2568
2569	if (sc->wi_gone)
2570		return (ENODEV);
2571
2572	/* wait for the busy bit to clear */
2573	for (i = sc->wi_cmd_count; i > 0; i--) {	/* 500ms */
2574		if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
2575			break;
2576		DELAY(1*1000);	/* 1ms */
2577	}
2578	if (i == 0) {
2579		device_printf(sc->sc_dev, "wi_cmd: busy bit won't clear.\n" );
2580		sc->wi_gone = 1;
2581		return(ETIMEDOUT);
2582	}
2583
2584	CSR_WRITE_2(sc, WI_PARAM0, val0);
2585	CSR_WRITE_2(sc, WI_PARAM1, val1);
2586	CSR_WRITE_2(sc, WI_PARAM2, val2);
2587	CSR_WRITE_2(sc, WI_COMMAND, cmd);
2588
2589	if (cmd == WI_CMD_INI) {
2590		/* XXX: should sleep here. */
2591		DELAY(100*1000);		/* 100ms delay for init */
2592	}
2593	for (i = 0; i < WI_TIMEOUT; i++) {
2594		/*
2595		 * Wait for 'command complete' bit to be
2596		 * set in the event status register.
2597		 */
2598		s = CSR_READ_2(sc, WI_EVENT_STAT);
2599		if (s & WI_EV_CMD) {
2600			/* Ack the event and read result code. */
2601			s = CSR_READ_2(sc, WI_STATUS);
2602			CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
2603			if (s & WI_STAT_CMD_RESULT) {
2604				return(EIO);
2605			}
2606			break;
2607		}
2608		DELAY(WI_DELAY);
2609	}
2610
2611	if (i == WI_TIMEOUT) {
2612		device_printf(sc->sc_dev,
2613		    "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s);
2614		if (s == 0xffff)
2615			sc->wi_gone = 1;
2616		return(ETIMEDOUT);
2617	}
2618	return (0);
2619}
2620
2621static int
2622wi_seek_bap(struct wi_softc *sc, int id, int off)
2623{
2624	int i, status;
2625
2626	CSR_WRITE_2(sc, WI_SEL0, id);
2627	CSR_WRITE_2(sc, WI_OFF0, off);
2628
2629	for (i = 0; ; i++) {
2630		status = CSR_READ_2(sc, WI_OFF0);
2631		if ((status & WI_OFF_BUSY) == 0)
2632			break;
2633		if (i == WI_TIMEOUT) {
2634			device_printf(sc->sc_dev, "timeout in wi_seek to %x/%x\n",
2635			    id, off);
2636			sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
2637			if (status == 0xffff)
2638				sc->wi_gone = 1;
2639			return ETIMEDOUT;
2640		}
2641		DELAY(1);
2642	}
2643	if (status & WI_OFF_ERR) {
2644		device_printf(sc->sc_dev, "failed in wi_seek to %x/%x\n", id, off);
2645		sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
2646		return EIO;
2647	}
2648	sc->sc_bap_id = id;
2649	sc->sc_bap_off = off;
2650	return 0;
2651}
2652
2653static int
2654wi_read_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
2655{
2656	u_int16_t *ptr;
2657	int i, error, cnt;
2658
2659	if (buflen == 0)
2660		return 0;
2661	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
2662		if ((error = wi_seek_bap(sc, id, off)) != 0)
2663			return error;
2664	}
2665	cnt = (buflen + 1) / 2;
2666	ptr = (u_int16_t *)buf;
2667	for (i = 0; i < cnt; i++)
2668		*ptr++ = CSR_READ_2(sc, WI_DATA0);
2669	sc->sc_bap_off += cnt * 2;
2670	return 0;
2671}
2672
2673static int
2674wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen)
2675{
2676	u_int16_t *ptr;
2677	int i, error, cnt;
2678
2679	if (buflen == 0)
2680		return 0;
2681
2682#ifdef WI_HERMES_AUTOINC_WAR
2683  again:
2684#endif
2685	if (id != sc->sc_bap_id || off != sc->sc_bap_off) {
2686		if ((error = wi_seek_bap(sc, id, off)) != 0)
2687			return error;
2688	}
2689	cnt = (buflen + 1) / 2;
2690	ptr = (u_int16_t *)buf;
2691	for (i = 0; i < cnt; i++)
2692		CSR_WRITE_2(sc, WI_DATA0, ptr[i]);
2693	sc->sc_bap_off += cnt * 2;
2694
2695#ifdef WI_HERMES_AUTOINC_WAR
2696	/*
2697	 * According to the comments in the HCF Light code, there is a bug
2698	 * in the Hermes (or possibly in certain Hermes firmware revisions)
2699	 * where the chip's internal autoincrement counter gets thrown off
2700	 * during data writes:  the autoincrement is missed, causing one
2701	 * data word to be overwritten and subsequent words to be written to
2702	 * the wrong memory locations. The end result is that we could end
2703	 * up transmitting bogus frames without realizing it. The workaround
2704	 * for this is to write a couple of extra guard words after the end
2705	 * of the transfer, then attempt to read then back. If we fail to
2706	 * locate the guard words where we expect them, we preform the
2707	 * transfer over again.
2708	 */
2709	if ((sc->sc_flags & WI_FLAGS_BUG_AUTOINC) && (id & 0xf000) == 0) {
2710		CSR_WRITE_2(sc, WI_DATA0, 0x1234);
2711		CSR_WRITE_2(sc, WI_DATA0, 0x5678);
2712		wi_seek_bap(sc, id, sc->sc_bap_off);
2713		sc->sc_bap_off = WI_OFF_ERR;	/* invalidate */
2714		if (CSR_READ_2(sc, WI_DATA0) != 0x1234 ||
2715		    CSR_READ_2(sc, WI_DATA0) != 0x5678) {
2716			device_printf(sc->sc_dev,
2717				"detect auto increment bug, try again\n");
2718			goto again;
2719		}
2720	}
2721#endif
2722	return 0;
2723}
2724
2725static int
2726wi_mwrite_bap(struct wi_softc *sc, int id, int off, struct mbuf *m0, int totlen)
2727{
2728	int error, len;
2729	struct mbuf *m;
2730
2731	for (m = m0; m != NULL && totlen > 0; m = m->m_next) {
2732		if (m->m_len == 0)
2733			continue;
2734
2735		len = min(m->m_len, totlen);
2736
2737		if (((u_long)m->m_data) % 2 != 0 || len % 2 != 0) {
2738			m_copydata(m, 0, totlen, (caddr_t)&sc->sc_txbuf);
2739			return wi_write_bap(sc, id, off, (caddr_t)&sc->sc_txbuf,
2740			    totlen);
2741		}
2742
2743		if ((error = wi_write_bap(sc, id, off, m->m_data, len)) != 0)
2744			return error;
2745
2746		off += m->m_len;
2747		totlen -= len;
2748	}
2749	return 0;
2750}
2751
2752static int
2753wi_alloc_fid(struct wi_softc *sc, int len, int *idp)
2754{
2755	int i;
2756
2757	if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) {
2758		device_printf(sc->sc_dev, "failed to allocate %d bytes on NIC\n",
2759		    len);
2760		return ENOMEM;
2761	}
2762
2763	for (i = 0; i < WI_TIMEOUT; i++) {
2764		if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_ALLOC)
2765			break;
2766		DELAY(1);
2767	}
2768	if (i == WI_TIMEOUT) {
2769		device_printf(sc->sc_dev, "timeout in alloc\n");
2770		return ETIMEDOUT;
2771	}
2772	*idp = CSR_READ_2(sc, WI_ALLOC_FID);
2773	CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
2774	return 0;
2775}
2776
2777static int
2778wi_read_rid(struct wi_softc *sc, int rid, void *buf, int *buflenp)
2779{
2780	int error, len;
2781	u_int16_t ltbuf[2];
2782
2783	/* Tell the NIC to enter record read mode. */
2784	error = wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_READ, rid, 0, 0);
2785	if (error)
2786		return error;
2787
2788	error = wi_read_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
2789	if (error)
2790		return error;
2791
2792	if (le16toh(ltbuf[1]) != rid) {
2793		device_printf(sc->sc_dev, "record read mismatch, rid=%x, got=%x\n",
2794		    rid, le16toh(ltbuf[1]));
2795		return EIO;
2796	}
2797	len = (le16toh(ltbuf[0]) - 1) * 2;	 /* already got rid */
2798	if (*buflenp < len) {
2799		device_printf(sc->sc_dev, "record buffer is too small, "
2800		    "rid=%x, size=%d, len=%d\n",
2801		    rid, *buflenp, len);
2802		return ENOSPC;
2803	}
2804	*buflenp = len;
2805	return wi_read_bap(sc, rid, sizeof(ltbuf), buf, len);
2806}
2807
2808static int
2809wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen)
2810{
2811	int error;
2812	u_int16_t ltbuf[2];
2813
2814	ltbuf[0] = htole16((buflen + 1) / 2 + 1);	 /* includes rid */
2815	ltbuf[1] = htole16(rid);
2816
2817	error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf));
2818	if (error)
2819		return error;
2820	error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen);
2821	if (error)
2822		return error;
2823
2824	return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0);
2825}
2826
2827static int
2828wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
2829{
2830	struct ifnet *ifp = ic->ic_ifp;
2831	struct wi_softc *sc = ifp->if_softc;
2832	struct ieee80211_node *ni;
2833	int buflen;
2834	u_int16_t val;
2835	struct wi_ssid ssid;
2836	u_int8_t old_bssid[IEEE80211_ADDR_LEN];
2837
2838	DPRINTF(("%s: %s -> %s\n", __func__,
2839		ieee80211_state_name[ic->ic_state],
2840		ieee80211_state_name[nstate]));
2841
2842	/*
2843	 * Internal to the driver the INIT and RUN states are used
2844	 * so bypass the net80211 state machine for other states.
2845	 * Beware however that this requires use to net80211 state
2846	 * management that otherwise would be handled for us.
2847	 */
2848	switch (nstate) {
2849	case IEEE80211_S_INIT:
2850		sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
2851		return (*sc->sc_newstate)(ic, nstate, arg);
2852
2853	case IEEE80211_S_SCAN:
2854	case IEEE80211_S_AUTH:
2855	case IEEE80211_S_ASSOC:
2856		ic->ic_state = nstate;	/* NB: skip normal ieee80211 handling */
2857		break;
2858
2859	case IEEE80211_S_RUN:
2860		ni = ic->ic_bss;
2861		sc->sc_flags &= ~WI_FLAGS_OUTRANGE;
2862		buflen = IEEE80211_ADDR_LEN;
2863		IEEE80211_ADDR_COPY(old_bssid, ni->ni_bssid);
2864		wi_read_rid(sc, WI_RID_CURRENT_BSSID, ni->ni_bssid, &buflen);
2865		IEEE80211_ADDR_COPY(ni->ni_macaddr, ni->ni_bssid);
2866		buflen = sizeof(val);
2867		wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen);
2868		/* XXX validate channel */
2869		ni->ni_chan = &ic->ic_channels[le16toh(val)];
2870		ic->ic_curchan = ni->ni_chan;
2871		ic->ic_ibss_chan = ni->ni_chan;
2872#if NBPFILTER > 0
2873		sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq =
2874			htole16(ni->ni_chan->ic_freq);
2875		sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags =
2876			htole16(ni->ni_chan->ic_flags);
2877#endif
2878		/*
2879		 * XXX hack; unceremoniously clear
2880		 * IEEE80211_F_DROPUNENC when operating with
2881		 * wep enabled so we don't drop unencoded frames
2882		 * at the 802.11 layer.  This is necessary because
2883		 * we must strip the WEP bit from the 802.11 header
2884		 * before passing frames to ieee80211_input because
2885		 * the card has already stripped the WEP crypto
2886		 * header from the packet.
2887		 */
2888		if (ic->ic_flags & IEEE80211_F_PRIVACY)
2889			ic->ic_flags &= ~IEEE80211_F_DROPUNENC;
2890		if (ic->ic_opmode != IEEE80211_M_HOSTAP) {
2891			/* XXX check return value */
2892			buflen = sizeof(ssid);
2893			wi_read_rid(sc, WI_RID_CURRENT_SSID, &ssid, &buflen);
2894			ni->ni_esslen = le16toh(ssid.wi_len);
2895			if (ni->ni_esslen > IEEE80211_NWID_LEN)
2896				ni->ni_esslen = IEEE80211_NWID_LEN;	/*XXX*/
2897			memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen);
2898		}
2899		return (*sc->sc_newstate)(ic, nstate, arg);
2900	}
2901	return 0;
2902}
2903
2904static int
2905wi_scan_ap(struct wi_softc *sc, u_int16_t chanmask, u_int16_t txrate)
2906{
2907	int error = 0;
2908	u_int16_t val[2];
2909
2910	if (!sc->sc_enabled)
2911		return ENXIO;
2912	switch (sc->sc_firmware_type) {
2913	case WI_LUCENT:
2914		(void)wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0);
2915		break;
2916	case WI_INTERSIL:
2917		val[0] = htole16(chanmask);	/* channel */
2918		val[1] = htole16(txrate);	/* tx rate */
2919		error = wi_write_rid(sc, WI_RID_SCAN_REQ, val, sizeof(val));
2920		break;
2921	case WI_SYMBOL:
2922		/*
2923		 * XXX only supported on 3.x ?
2924		 */
2925		val[0] = BSCAN_BCAST | BSCAN_ONETIME;
2926		error = wi_write_rid(sc, WI_RID_BCAST_SCAN_REQ,
2927		    val, sizeof(val[0]));
2928		break;
2929	}
2930	if (error == 0) {
2931		sc->sc_scan_timer = WI_SCAN_WAIT;
2932		DPRINTF(("wi_scan_ap: start scanning, "
2933			"chamask 0x%x txrate 0x%x\n", chanmask, txrate));
2934	}
2935	return error;
2936}
2937
2938static void
2939wi_scan_result(struct wi_softc *sc, int fid, int cnt)
2940{
2941#define	N(a)	(sizeof (a) / sizeof (a[0]))
2942	int i, naps, off, szbuf;
2943	struct wi_scan_header ws_hdr;	/* Prism2 header */
2944	struct wi_scan_data_p2 ws_dat;	/* Prism2 scantable*/
2945	struct wi_apinfo *ap;
2946
2947	off = sizeof(u_int16_t) * 2;
2948	memset(&ws_hdr, 0, sizeof(ws_hdr));
2949	switch (sc->sc_firmware_type) {
2950	case WI_INTERSIL:
2951		wi_read_bap(sc, fid, off, &ws_hdr, sizeof(ws_hdr));
2952		off += sizeof(ws_hdr);
2953		szbuf = sizeof(struct wi_scan_data_p2);
2954		break;
2955	case WI_SYMBOL:
2956		szbuf = sizeof(struct wi_scan_data_p2) + 6;
2957		break;
2958	case WI_LUCENT:
2959		szbuf = sizeof(struct wi_scan_data);
2960		break;
2961	default:
2962		device_printf(sc->sc_dev,
2963			"wi_scan_result: unknown firmware type %u\n",
2964			sc->sc_firmware_type);
2965		naps = 0;
2966		goto done;
2967	}
2968	naps = (cnt * 2 + 2 - off) / szbuf;
2969	if (naps > N(sc->sc_aps))
2970		naps = N(sc->sc_aps);
2971	sc->sc_naps = naps;
2972	/* Read Data */
2973	ap = sc->sc_aps;
2974	memset(&ws_dat, 0, sizeof(ws_dat));
2975	for (i = 0; i < naps; i++, ap++) {
2976		wi_read_bap(sc, fid, off, &ws_dat,
2977		    (sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf));
2978		DPRINTF2(("wi_scan_result: #%d: off %d bssid %s\n", i, off,
2979		    ether_sprintf(ws_dat.wi_bssid)));
2980		off += szbuf;
2981		ap->scanreason = le16toh(ws_hdr.wi_reason);
2982		memcpy(ap->bssid, ws_dat.wi_bssid, sizeof(ap->bssid));
2983		ap->channel = le16toh(ws_dat.wi_chid);
2984		ap->signal  = le16toh(ws_dat.wi_signal);
2985		ap->noise   = le16toh(ws_dat.wi_noise);
2986		ap->quality = ap->signal - ap->noise;
2987		ap->capinfo = le16toh(ws_dat.wi_capinfo);
2988		ap->interval = le16toh(ws_dat.wi_interval);
2989		ap->rate    = le16toh(ws_dat.wi_rate);
2990		ap->namelen = le16toh(ws_dat.wi_namelen);
2991		if (ap->namelen > sizeof(ap->name))
2992			ap->namelen = sizeof(ap->name);
2993		memcpy(ap->name, ws_dat.wi_name, ap->namelen);
2994	}
2995done:
2996	/* Done scanning */
2997	sc->sc_scan_timer = 0;
2998	DPRINTF(("wi_scan_result: scan complete: ap %d\n", naps));
2999#undef N
3000}
3001
3002static void
3003wi_dump_pkt(struct wi_frame *wh, struct ieee80211_node *ni, int rssi)
3004{
3005	ieee80211_dump_pkt((u_int8_t *) &wh->wi_whdr, sizeof(wh->wi_whdr),
3006	    ni ? ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL : -1, rssi);
3007	printf(" status 0x%x rx_tstamp1 %u rx_tstamp0 0x%u rx_silence %u\n",
3008		le16toh(wh->wi_status), le16toh(wh->wi_rx_tstamp1),
3009		le16toh(wh->wi_rx_tstamp0), wh->wi_rx_silence);
3010	printf(" rx_signal %u rx_rate %u rx_flow %u\n",
3011		wh->wi_rx_signal, wh->wi_rx_rate, wh->wi_rx_flow);
3012	printf(" tx_rtry %u tx_rate %u tx_ctl 0x%x dat_len %u\n",
3013		wh->wi_tx_rtry, wh->wi_tx_rate,
3014		le16toh(wh->wi_tx_ctl), le16toh(wh->wi_dat_len));
3015	printf(" ehdr dst %6D src %6D type 0x%x\n",
3016		wh->wi_ehdr.ether_dhost, ":", wh->wi_ehdr.ether_shost, ":",
3017		wh->wi_ehdr.ether_type);
3018}
3019
3020int
3021wi_alloc(device_t dev, int rid)
3022{
3023	struct wi_softc	*sc = device_get_softc(dev);
3024
3025	if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) {
3026		sc->iobase_rid = rid;
3027		sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT,
3028		    &sc->iobase_rid, 0, ~0, (1 << 6),
3029		    rman_make_alignment_flags(1 << 6) | RF_ACTIVE);
3030		if (!sc->iobase) {
3031			device_printf(dev, "No I/O space?!\n");
3032			return (ENXIO);
3033		}
3034
3035		sc->wi_io_addr = rman_get_start(sc->iobase);
3036		sc->wi_btag = rman_get_bustag(sc->iobase);
3037		sc->wi_bhandle = rman_get_bushandle(sc->iobase);
3038	} else {
3039		sc->mem_rid = rid;
3040		sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
3041		    &sc->mem_rid, RF_ACTIVE);
3042
3043		if (!sc->mem) {
3044			device_printf(dev, "No Mem space on prism2.5?\n");
3045			return (ENXIO);
3046		}
3047
3048		sc->wi_btag = rman_get_bustag(sc->mem);
3049		sc->wi_bhandle = rman_get_bushandle(sc->mem);
3050	}
3051
3052
3053	sc->irq_rid = 0;
3054	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
3055	    RF_ACTIVE |
3056	    ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE));
3057
3058	if (!sc->irq) {
3059		wi_free(dev);
3060		device_printf(dev, "No irq?!\n");
3061		return (ENXIO);
3062	}
3063
3064	sc->sc_dev = dev;
3065	sc->sc_unit = device_get_unit(dev);
3066
3067	return (0);
3068}
3069
3070void
3071wi_free(device_t dev)
3072{
3073	struct wi_softc	*sc = device_get_softc(dev);
3074
3075	if (sc->iobase != NULL) {
3076		bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase);
3077		sc->iobase = NULL;
3078	}
3079	if (sc->irq != NULL) {
3080		bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
3081		sc->irq = NULL;
3082	}
3083	if (sc->mem != NULL) {
3084		bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
3085		sc->mem = NULL;
3086	}
3087
3088	return;
3089}
3090
3091static int
3092wi_get_debug(struct wi_softc *sc, struct wi_req *wreq)
3093{
3094	int error = 0;
3095
3096	wreq->wi_len = 1;
3097
3098	switch (wreq->wi_type) {
3099	case WI_DEBUG_SLEEP:
3100		wreq->wi_len++;
3101		wreq->wi_val[0] = sc->wi_debug.wi_sleep;
3102		break;
3103	case WI_DEBUG_DELAYSUPP:
3104		wreq->wi_len++;
3105		wreq->wi_val[0] = sc->wi_debug.wi_delaysupp;
3106		break;
3107	case WI_DEBUG_TXSUPP:
3108		wreq->wi_len++;
3109		wreq->wi_val[0] = sc->wi_debug.wi_txsupp;
3110		break;
3111	case WI_DEBUG_MONITOR:
3112		wreq->wi_len++;
3113		wreq->wi_val[0] = sc->wi_debug.wi_monitor;
3114		break;
3115	case WI_DEBUG_LEDTEST:
3116		wreq->wi_len += 3;
3117		wreq->wi_val[0] = sc->wi_debug.wi_ledtest;
3118		wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0;
3119		wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1;
3120		break;
3121	case WI_DEBUG_CONTTX:
3122		wreq->wi_len += 2;
3123		wreq->wi_val[0] = sc->wi_debug.wi_conttx;
3124		wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0;
3125		break;
3126	case WI_DEBUG_CONTRX:
3127		wreq->wi_len++;
3128		wreq->wi_val[0] = sc->wi_debug.wi_contrx;
3129		break;
3130	case WI_DEBUG_SIGSTATE:
3131		wreq->wi_len += 2;
3132		wreq->wi_val[0] = sc->wi_debug.wi_sigstate;
3133		wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0;
3134		break;
3135	case WI_DEBUG_CONFBITS:
3136		wreq->wi_len += 2;
3137		wreq->wi_val[0] = sc->wi_debug.wi_confbits;
3138		wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0;
3139		break;
3140	default:
3141		error = EIO;
3142		break;
3143	}
3144
3145	return (error);
3146}
3147
3148static int
3149wi_set_debug(struct wi_softc *sc, struct wi_req *wreq)
3150{
3151	int error = 0;
3152	u_int16_t		cmd, param0 = 0, param1 = 0;
3153
3154	switch (wreq->wi_type) {
3155	case WI_DEBUG_RESET:
3156	case WI_DEBUG_INIT:
3157	case WI_DEBUG_CALENABLE:
3158		break;
3159	case WI_DEBUG_SLEEP:
3160		sc->wi_debug.wi_sleep = 1;
3161		break;
3162	case WI_DEBUG_WAKE:
3163		sc->wi_debug.wi_sleep = 0;
3164		break;
3165	case WI_DEBUG_CHAN:
3166		param0 = wreq->wi_val[0];
3167		break;
3168	case WI_DEBUG_DELAYSUPP:
3169		sc->wi_debug.wi_delaysupp = 1;
3170		break;
3171	case WI_DEBUG_TXSUPP:
3172		sc->wi_debug.wi_txsupp = 1;
3173		break;
3174	case WI_DEBUG_MONITOR:
3175		sc->wi_debug.wi_monitor = 1;
3176		break;
3177	case WI_DEBUG_LEDTEST:
3178		param0 = wreq->wi_val[0];
3179		param1 = wreq->wi_val[1];
3180		sc->wi_debug.wi_ledtest = 1;
3181		sc->wi_debug.wi_ledtest_param0 = param0;
3182		sc->wi_debug.wi_ledtest_param1 = param1;
3183		break;
3184	case WI_DEBUG_CONTTX:
3185		param0 = wreq->wi_val[0];
3186		sc->wi_debug.wi_conttx = 1;
3187		sc->wi_debug.wi_conttx_param0 = param0;
3188		break;
3189	case WI_DEBUG_STOPTEST:
3190		sc->wi_debug.wi_delaysupp = 0;
3191		sc->wi_debug.wi_txsupp = 0;
3192		sc->wi_debug.wi_monitor = 0;
3193		sc->wi_debug.wi_ledtest = 0;
3194		sc->wi_debug.wi_ledtest_param0 = 0;
3195		sc->wi_debug.wi_ledtest_param1 = 0;
3196		sc->wi_debug.wi_conttx = 0;
3197		sc->wi_debug.wi_conttx_param0 = 0;
3198		sc->wi_debug.wi_contrx = 0;
3199		sc->wi_debug.wi_sigstate = 0;
3200		sc->wi_debug.wi_sigstate_param0 = 0;
3201		break;
3202	case WI_DEBUG_CONTRX:
3203		sc->wi_debug.wi_contrx = 1;
3204		break;
3205	case WI_DEBUG_SIGSTATE:
3206		param0 = wreq->wi_val[0];
3207		sc->wi_debug.wi_sigstate = 1;
3208		sc->wi_debug.wi_sigstate_param0 = param0;
3209		break;
3210	case WI_DEBUG_CONFBITS:
3211		param0 = wreq->wi_val[0];
3212		param1 = wreq->wi_val[1];
3213		sc->wi_debug.wi_confbits = param0;
3214		sc->wi_debug.wi_confbits_param0 = param1;
3215		break;
3216	default:
3217		error = EIO;
3218		break;
3219	}
3220
3221	if (error)
3222		return (error);
3223
3224	cmd = WI_CMD_DEBUG | (wreq->wi_type << 8);
3225	error = wi_cmd(sc, cmd, param0, param1, 0);
3226
3227	return (error);
3228}
3229
3230/*
3231 * Special routines to download firmware for Symbol CF card.
3232 * XXX: This should be modified generic into any PRISM-2 based card.
3233 */
3234
3235#define	WI_SBCF_PDIADDR		0x3100
3236
3237/* unaligned load little endian */
3238#define	GETLE32(p)	((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24))
3239#define	GETLE16(p)	((p)[0] | ((p)[1]<<8))
3240
3241int
3242wi_symbol_load_firm(struct wi_softc *sc, const void *primsym, int primlen,
3243    const void *secsym, int seclen)
3244{
3245	uint8_t ebuf[256];
3246	int i;
3247
3248	/* load primary code and run it */
3249	wi_symbol_set_hcr(sc, WI_HCR_EEHOLD);
3250	if (wi_symbol_write_firm(sc, primsym, primlen, NULL, 0))
3251		return EIO;
3252	wi_symbol_set_hcr(sc, WI_HCR_RUN);
3253	for (i = 0; ; i++) {
3254		if (i == 10)
3255			return ETIMEDOUT;
3256		tsleep(sc, PWAIT, "wiinit", 1);
3257		if (CSR_READ_2(sc, WI_CNTL) == WI_CNTL_AUX_ENA_STAT)
3258			break;
3259		/* write the magic key value to unlock aux port */
3260		CSR_WRITE_2(sc, WI_PARAM0, WI_AUX_KEY0);
3261		CSR_WRITE_2(sc, WI_PARAM1, WI_AUX_KEY1);
3262		CSR_WRITE_2(sc, WI_PARAM2, WI_AUX_KEY2);
3263		CSR_WRITE_2(sc, WI_CNTL, WI_CNTL_AUX_ENA_CNTL);
3264	}
3265
3266	/* issue read EEPROM command: XXX copied from wi_cmd() */
3267	CSR_WRITE_2(sc, WI_PARAM0, 0);
3268	CSR_WRITE_2(sc, WI_PARAM1, 0);
3269	CSR_WRITE_2(sc, WI_PARAM2, 0);
3270	CSR_WRITE_2(sc, WI_COMMAND, WI_CMD_READEE);
3271        for (i = 0; i < WI_TIMEOUT; i++) {
3272                if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD)
3273                        break;
3274                DELAY(1);
3275        }
3276        CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD);
3277
3278	CSR_WRITE_2(sc, WI_AUX_PAGE, WI_SBCF_PDIADDR / WI_AUX_PGSZ);
3279	CSR_WRITE_2(sc, WI_AUX_OFFSET, WI_SBCF_PDIADDR % WI_AUX_PGSZ);
3280	CSR_READ_MULTI_STREAM_2(sc, WI_AUX_DATA,
3281	    (uint16_t *)ebuf, sizeof(ebuf) / 2);
3282	if (GETLE16(ebuf) > sizeof(ebuf))
3283		return EIO;
3284	if (wi_symbol_write_firm(sc, secsym, seclen, ebuf + 4, GETLE16(ebuf)))
3285		return EIO;
3286	return 0;
3287}
3288
3289static int
3290wi_symbol_write_firm(struct wi_softc *sc, const void *buf, int buflen,
3291    const void *ebuf, int ebuflen)
3292{
3293	const uint8_t *p, *ep, *q, *eq;
3294	char *tp;
3295	uint32_t addr, id, eid;
3296	int i, len, elen, nblk, pdrlen;
3297
3298	/*
3299	 * Parse the header of the firmware image.
3300	 */
3301	p = buf;
3302	ep = p + buflen;
3303	while (p < ep && *p++ != ' ');	/* FILE: */
3304	while (p < ep && *p++ != ' ');	/* filename */
3305	while (p < ep && *p++ != ' ');	/* type of the firmware */
3306	nblk = strtoul(p, &tp, 10);
3307	p = tp;
3308	pdrlen = strtoul(p + 1, &tp, 10);
3309	p = tp;
3310	while (p < ep && *p++ != 0x1a);	/* skip rest of header */
3311
3312	/*
3313	 * Block records: address[4], length[2], data[length];
3314	 */
3315	for (i = 0; i < nblk; i++) {
3316		addr = GETLE32(p);	p += 4;
3317		len  = GETLE16(p);	p += 2;
3318		CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ);
3319		CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ);
3320		CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA,
3321		    (const uint16_t *)p, len / 2);
3322		p += len;
3323	}
3324
3325	/*
3326	 * PDR: id[4], address[4], length[4];
3327	 */
3328	for (i = 0; i < pdrlen; ) {
3329		id   = GETLE32(p);	p += 4; i += 4;
3330		addr = GETLE32(p);	p += 4; i += 4;
3331		len  = GETLE32(p);	p += 4; i += 4;
3332		/* replace PDR entry with the values from EEPROM, if any */
3333		for (q = ebuf, eq = q + ebuflen; q < eq; q += elen * 2) {
3334			elen = GETLE16(q);	q += 2;
3335			eid  = GETLE16(q);	q += 2;
3336			elen--;		/* elen includes eid */
3337			if (eid == 0)
3338				break;
3339			if (eid != id)
3340				continue;
3341			CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ);
3342			CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ);
3343			CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA,
3344			    (const uint16_t *)q, len / 2);
3345			break;
3346		}
3347	}
3348	return 0;
3349}
3350
3351static int
3352wi_symbol_set_hcr(struct wi_softc *sc, int mode)
3353{
3354	uint16_t hcr;
3355
3356	CSR_WRITE_2(sc, WI_COR, WI_COR_RESET);
3357	tsleep(sc, PWAIT, "wiinit", 1);
3358	hcr = CSR_READ_2(sc, WI_HCR);
3359	hcr = (hcr & WI_HCR_4WIRE) | (mode & ~WI_HCR_4WIRE);
3360	CSR_WRITE_2(sc, WI_HCR, hcr);
3361	tsleep(sc, PWAIT, "wiinit", 1);
3362	CSR_WRITE_2(sc, WI_COR, WI_COR_IOMODE);
3363	tsleep(sc, PWAIT, "wiinit", 1);
3364	return 0;
3365}
3366