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