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